Mercurial > projects > ldc
annotate gen/passes/SimplifyDRuntimeCalls.cpp @ 1600:a60e7d1ce3ee
Folded in a patch by Troy Straszheim to better report errors with -run.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Mon, 28 Dec 2009 02:23:41 +0000 |
parents | 8d086d552909 |
children | 40bd4a0d4870 |
rev | line source |
---|---|
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
1 //===- SimplifyDRuntimeCalls - Optimize calls to the D runtime library ----===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
2 // |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
3 // The LLVM D Compiler |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
4 // |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
5 // This file is distributed under the University of Illinois Open Source |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
6 // License. See LICENSE.TXT for details. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
7 // |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
8 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
9 // |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
10 // This file implements a simple pass that applies a variety of small |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
11 // optimizations for calls to specific functions in the D runtime. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
12 // |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
13 // The machinery was copied from the standard -simplify-libcalls LLVM pass. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
14 // |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
15 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
16 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
17 #define DEBUG_TYPE "simplify-drtcalls" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
18 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
19 #include "Passes.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
20 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
21 #include "llvm/Pass.h" |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
22 #include "llvm/Intrinsics.h" |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
23 #include "llvm/Support/IRBuilder.h" |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
24 #include "llvm/Analysis/AliasAnalysis.h" |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
25 #include "llvm/Analysis/ValueTracking.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
26 #include "llvm/Target/TargetData.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
27 #include "llvm/ADT/StringMap.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
28 #include "llvm/ADT/Statistic.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
29 #include "llvm/Support/Compiler.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
30 #include "llvm/Support/Debug.h" |
1551
ed0feda76820
DOUT is deprecated, use DEBUG(errs()) instead
Benjamin Kramer <benny.kra@gmail.com>
parents:
1545
diff
changeset
|
31 #include "llvm/Support/raw_ostream.h" |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
32 using namespace llvm; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
33 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
34 STATISTIC(NumSimplified, "Number of runtime calls simplified"); |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
35 STATISTIC(NumDeleted, "Number of runtime calls deleted"); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
36 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
37 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
38 // Optimizer Base Class |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
39 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
40 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
41 /// This class is the abstract base class for the set of optimizations that |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
42 /// corresponds to one library call. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
43 namespace { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
44 class VISIBILITY_HIDDEN LibCallOptimization { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
45 protected: |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
46 Function *Caller; |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
47 bool* Changed; |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
48 const TargetData *TD; |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
49 AliasAnalysis *AA; |
1545
7fcb72d518f6
More factory methods moved to LLVMContext
Benjamin Kramer <benny.kra@gmail.com>
parents:
1535
diff
changeset
|
50 LLVMContext *Context; |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
51 |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
52 /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*. |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
53 Value *CastToCStr(Value *V, IRBuilder<> &B); |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
54 |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
55 /// EmitMemCpy - Emit a call to the memcpy function to the builder. This |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
56 /// always expects that the size has type 'intptr_t' and Dst/Src are pointers. |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
57 Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len, |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
58 unsigned Align, IRBuilder<> &B); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
59 public: |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
60 LibCallOptimization() { } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
61 virtual ~LibCallOptimization() {} |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
62 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
63 /// CallOptimizer - This pure virtual method is implemented by base classes to |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
64 /// do various optimizations. If this returns null then no transformation was |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
65 /// performed. If it returns CI, then it transformed the call and CI is to be |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
66 /// deleted. If it returns something else, replace CI with the new value and |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
67 /// delete CI. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
68 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)=0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
69 |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
70 Value *OptimizeCall(CallInst *CI, bool& Changed, const TargetData &TD, |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
71 AliasAnalysis& AA, IRBuilder<> &B) { |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
72 Caller = CI->getParent()->getParent(); |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
73 this->Changed = &Changed; |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
74 this->TD = &TD; |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
75 this->AA = &AA; |
1545
7fcb72d518f6
More factory methods moved to LLVMContext
Benjamin Kramer <benny.kra@gmail.com>
parents:
1535
diff
changeset
|
76 if (CI->getCalledFunction()) |
1554
d6e8d5db259f
LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents:
1553
diff
changeset
|
77 Context = &CI->getCalledFunction()->getContext(); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
78 return CallOptimizer(CI->getCalledFunction(), CI, B); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
79 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
80 }; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
81 } // End anonymous namespace. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
82 |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
83 /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*. |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
84 Value *LibCallOptimization::CastToCStr(Value *V, IRBuilder<> &B) { |
1571
8d086d552909
IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents:
1554
diff
changeset
|
85 return B.CreateBitCast(V, PointerType::getUnqual(B.getInt8Ty()), "cstr"); |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
86 } |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
87 |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
88 /// EmitMemCpy - Emit a call to the memcpy function to the builder. This always |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
89 /// expects that the size has type 'intptr_t' and Dst/Src are pointers. |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
90 Value *LibCallOptimization::EmitMemCpy(Value *Dst, Value *Src, Value *Len, |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
91 unsigned Align, IRBuilder<> &B) { |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
92 Module *M = Caller->getParent(); |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
93 Intrinsic::ID IID = Intrinsic::memcpy; |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
94 const Type *Tys[1]; |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
95 Tys[0] = Len->getType(); |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
96 Value *MemCpy = Intrinsic::getDeclaration(M, IID, Tys, 1); |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
97 return B.CreateCall4(MemCpy, CastToCStr(Dst, B), CastToCStr(Src, B), Len, |
1571
8d086d552909
IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents:
1554
diff
changeset
|
98 ConstantInt::get(B.getInt32Ty(), Align)); |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
99 } |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
100 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
101 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
102 // Miscellaneous LibCall Optimizations |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
103 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
104 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
105 namespace { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
106 //===---------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
107 // '_d_arraysetlengthT'/'_d_arraysetlengthiT' Optimizations |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
108 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
109 /// ArraySetLengthOpt - remove libcall for arr.length = N if N <= arr.length |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
110 struct VISIBILITY_HIDDEN ArraySetLengthOpt : public LibCallOptimization { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
111 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
112 // Verify we have a reasonable prototype for _d_arraysetlength[i]T |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
113 const FunctionType *FT = Callee->getFunctionType(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
114 if (Callee->arg_size() != 4 || !isa<PointerType>(FT->getReturnType()) || |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
115 !isa<IntegerType>(FT->getParamType(1)) || |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
116 FT->getParamType(1) != FT->getParamType(2) || |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
117 FT->getParamType(3) != FT->getReturnType()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
118 return 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
119 |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
120 // Whether or not this allocates is irrelevant if the result isn't used. |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
121 // Just delete if that's the case. |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
122 if (CI->use_empty()) |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
123 return CI; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
124 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
125 Value* NewLen = CI->getOperand(2); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
126 if (Constant* NewCst = dyn_cast<Constant>(NewLen)) { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
127 Value* Data = CI->getOperand(4); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
128 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
129 // For now, we just catch the simplest of cases. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
130 // |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
131 // TODO: Implement a more general way to compare old and new |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
132 // lengths, to catch cases like "arr.length = arr.length - 1;" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
133 // (But beware of unsigned overflow! For example, we can't |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
134 // safely transform that example if arr.length may be 0) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
135 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
136 // Setting length to 0 never reallocates, so replace by data argument |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
137 if (NewCst->isNullValue()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
138 return Data; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
139 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
140 // If both lengths are constant integers, see if NewLen <= OldLen |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
141 Value* OldLen = CI->getOperand(3); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
142 if (ConstantInt* OldInt = dyn_cast<ConstantInt>(OldLen)) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
143 if (ConstantInt* NewInt = dyn_cast<ConstantInt>(NewCst)) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
144 if (NewInt->getValue().ule(OldInt->getValue())) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
145 return Data; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
146 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
147 return 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
148 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
149 }; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
150 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
151 /// ArrayCastLenOpt - remove libcall for cast(T[]) arr if it's safe to do so. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
152 struct VISIBILITY_HIDDEN ArrayCastLenOpt : public LibCallOptimization { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
153 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
154 // Verify we have a reasonable prototype for _d_array_cast_len |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
155 const FunctionType *FT = Callee->getFunctionType(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
156 const Type* RetTy = FT->getReturnType(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
157 if (Callee->arg_size() != 3 || !isa<IntegerType>(RetTy) || |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
158 FT->getParamType(1) != RetTy || FT->getParamType(2) != RetTy) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
159 return 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
160 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
161 Value* OldLen = CI->getOperand(1); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
162 Value* OldSize = CI->getOperand(2); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
163 Value* NewSize = CI->getOperand(3); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
164 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
165 // If the old length was zero, always return zero. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
166 if (Constant* LenCst = dyn_cast<Constant>(OldLen)) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
167 if (LenCst->isNullValue()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
168 return OldLen; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
169 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
170 // Equal sizes are much faster to check for, so do so now. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
171 if (OldSize == NewSize) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
172 return OldLen; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
173 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
174 // If both sizes are constant integers, see if OldSize is a multiple of NewSize |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
175 if (ConstantInt* OldInt = dyn_cast<ConstantInt>(OldSize)) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
176 if (ConstantInt* NewInt = dyn_cast<ConstantInt>(NewSize)) { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
177 // Don't crash on NewSize == 0, even though it shouldn't happen. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
178 if (NewInt->isNullValue()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
179 return 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
180 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
181 APInt Quot, Rem; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
182 APInt::udivrem(OldInt->getValue(), NewInt->getValue(), Quot, Rem); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
183 if (Rem == 0) |
1554
d6e8d5db259f
LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents:
1553
diff
changeset
|
184 return B.CreateMul(OldLen, ConstantInt::get(*Context, Quot)); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
185 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
186 return 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
187 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
188 }; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
189 |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
190 /// AllocationOpt - Common optimizations for various GC allocations. |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
191 struct VISIBILITY_HIDDEN AllocationOpt : public LibCallOptimization { |
1286
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
192 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
193 // Allocations are never equal to constants, so remove any equality |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
194 // comparisons to constants. (Most importantly comparisons to null at |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
195 // the start of inlined member functions) |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
196 for (CallInst::use_iterator I = CI->use_begin(), E = CI->use_end() ; I != E;) { |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
197 Instruction* User = cast<Instruction>(*I++); |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
198 |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
199 if (ICmpInst* Cmp = dyn_cast<ICmpInst>(User)) { |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
200 if (!Cmp->isEquality()) |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
201 continue; |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
202 Constant* C = 0; |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
203 if ((C = dyn_cast<Constant>(Cmp->getOperand(0))) |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
204 || (C = dyn_cast<Constant>(Cmp->getOperand(1)))) { |
1571
8d086d552909
IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents:
1554
diff
changeset
|
205 Value* Result = ConstantInt::get(B.getInt1Ty(), !Cmp->isTrueWhenEqual()); |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
206 Cmp->replaceAllUsesWith(Result); |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
207 // Don't delete the comparison because there may be an |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
208 // iterator to it. Instead, set the operands to constants |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
209 // and let dead code elimination clean it up later. |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
210 // (It doesn't matter that this changes the value of the |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
211 // icmp because it's not used anymore anyway) |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
212 Cmp->setOperand(0, C); |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
213 Cmp->setOperand(1, C); |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
214 *Changed = true; |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
215 } |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
216 } |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
217 } |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
218 |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
219 // If it's not used (anymore), pre-emptively GC it. |
1286
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
220 if (CI->use_empty()) |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
221 return CI; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
222 return 0; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
223 } |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
224 }; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
225 |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
226 /// ArraySliceCopyOpt - Turn slice copies into llvm.memcpy when safe |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
227 struct VISIBILITY_HIDDEN ArraySliceCopyOpt : public LibCallOptimization { |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
228 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
229 // Verify we have a reasonable prototype for _d_array_slice_copy |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
230 const FunctionType *FT = Callee->getFunctionType(); |
1571
8d086d552909
IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents:
1554
diff
changeset
|
231 const Type* VoidPtrTy = PointerType::getUnqual(B.getInt8Ty()); |
8d086d552909
IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents:
1554
diff
changeset
|
232 if (Callee->arg_size() != 4 || FT->getReturnType() != B.getVoidTy() || |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
233 FT->getParamType(0) != VoidPtrTy || |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
234 !isa<IntegerType>(FT->getParamType(1)) || |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
235 FT->getParamType(2) != VoidPtrTy || |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
236 FT->getParamType(3) != FT->getParamType(1)) |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
237 return 0; |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
238 |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
239 Value* Size = CI->getOperand(2); |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
240 |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
241 // Check the lengths match |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
242 if (CI->getOperand(4) != Size) |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
243 return 0; |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
244 |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
245 // Assume unknown size unless we have constant size (that fits in an uint) |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
246 unsigned Sz = ~0U; |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
247 if (ConstantInt* Int = dyn_cast<ConstantInt>(Size)) |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
248 if (Int->getValue().isIntN(32)) |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
249 Sz = Int->getValue().getZExtValue(); |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
250 |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
251 // Check if the pointers may alias |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
252 if (AA->alias(CI->getOperand(1), Sz, CI->getOperand(3), Sz)) |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
253 return 0; |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
254 |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
255 // Equal length and the pointers definitely don't alias, so it's safe to |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
256 // replace the call with memcpy |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
257 return EmitMemCpy(CI->getOperand(1), CI->getOperand(3), Size, 0, B); |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
258 } |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
259 }; |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
260 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
261 // TODO: More optimizations! :) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
262 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
263 } // end anonymous namespace. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
264 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
265 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
266 // SimplifyDRuntimeCalls Pass Implementation |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
267 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
268 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
269 namespace { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
270 /// This pass optimizes library functions from the D runtime as used by LDC. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
271 /// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
272 class VISIBILITY_HIDDEN SimplifyDRuntimeCalls : public FunctionPass { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
273 StringMap<LibCallOptimization*> Optimizations; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
274 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
275 // Array operations |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
276 ArraySetLengthOpt ArraySetLength; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
277 ArrayCastLenOpt ArrayCastLen; |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
278 ArraySliceCopyOpt ArraySliceCopy; |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
279 |
1286
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
280 // GC allocations |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
281 AllocationOpt Allocation; |
1286
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
282 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
283 public: |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
284 static char ID; // Pass identification |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
285 SimplifyDRuntimeCalls() : FunctionPass(&ID) {} |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
286 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
287 void InitOptimizations(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
288 bool runOnFunction(Function &F); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
289 |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
290 bool runOnce(Function &F, const TargetData& TD, AliasAnalysis& AA); |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
291 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
292 virtual void getAnalysisUsage(AnalysisUsage &AU) const { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
293 AU.addRequired<TargetData>(); |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
294 AU.addRequired<AliasAnalysis>(); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
295 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
296 }; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
297 char SimplifyDRuntimeCalls::ID = 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
298 } // end anonymous namespace. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
299 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
300 static RegisterPass<SimplifyDRuntimeCalls> |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
301 X("simplify-drtcalls", "Simplify calls to D runtime"); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
302 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
303 // Public interface to the pass. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
304 FunctionPass *createSimplifyDRuntimeCalls() { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
305 return new SimplifyDRuntimeCalls(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
306 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
307 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
308 /// Optimizations - Populate the Optimizations map with all the optimizations |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
309 /// we know. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
310 void SimplifyDRuntimeCalls::InitOptimizations() { |
1286
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
311 // Some array-related optimizations |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
312 Optimizations["_d_arraysetlengthT"] = &ArraySetLength; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
313 Optimizations["_d_arraysetlengthiT"] = &ArraySetLength; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
314 Optimizations["_d_array_cast_len"] = &ArrayCastLen; |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
315 Optimizations["_d_array_slice_copy"] = &ArraySliceCopy; |
1286
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
316 |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
317 /* Delete calls to runtime functions which aren't needed if their result is |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
318 * unused. That comes down to functions that don't do anything but |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
319 * GC-allocate and initialize some memory. |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
320 * We don't need to do this for functions which are marked 'readnone' or |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
321 * 'readonly', since LLVM doesn't need our help figuring out when those can |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
322 * be deleted. |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
323 * (We can't mark allocating calls as readonly/readnone because they don't |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
324 * return the same pointer every time when called with the same arguments) |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
325 */ |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
326 Optimizations["_d_allocmemoryT"] = &Allocation; |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
327 Optimizations["_d_newarrayT"] = &Allocation; |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
328 Optimizations["_d_newarrayiT"] = &Allocation; |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
329 Optimizations["_d_newarrayvT"] = &Allocation; |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
330 Optimizations["_d_newarraymT"] = &Allocation; |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
331 Optimizations["_d_newarraymiT"] = &Allocation; |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
332 Optimizations["_d_newarraymvT"] = &Allocation; |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
333 Optimizations["_d_allocclass"] = &Allocation; |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
334 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
335 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
336 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
337 /// runOnFunction - Top level algorithm. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
338 /// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
339 bool SimplifyDRuntimeCalls::runOnFunction(Function &F) { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
340 if (Optimizations.empty()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
341 InitOptimizations(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
342 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
343 const TargetData &TD = getAnalysis<TargetData>(); |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
344 AliasAnalysis &AA = getAnalysis<AliasAnalysis>(); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
345 |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
346 // Iterate to catch opportunities opened up by other optimizations, |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
347 // such as calls that are only used as arguments to unused calls: |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
348 // When the second call gets deleted the first call will become unused, but |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
349 // without iteration we wouldn't notice if we inspected the first call |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
350 // before the second one. |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
351 bool EverChanged = false; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
352 bool Changed; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
353 do { |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
354 Changed = runOnce(F, TD, AA); |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
355 EverChanged |= Changed; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
356 } while (Changed); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
357 |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
358 return EverChanged; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
359 } |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
360 |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
361 bool SimplifyDRuntimeCalls::runOnce(Function &F, const TargetData& TD, AliasAnalysis& AA) { |
1554
d6e8d5db259f
LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents:
1553
diff
changeset
|
362 IRBuilder<> Builder(F.getContext()); |
d6e8d5db259f
LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents:
1553
diff
changeset
|
363 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
364 bool Changed = false; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
365 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
366 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
367 // Ignore non-calls. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
368 CallInst *CI = dyn_cast<CallInst>(I++); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
369 if (!CI) continue; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
370 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
371 // Ignore indirect calls and calls to non-external functions. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
372 Function *Callee = CI->getCalledFunction(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
373 if (Callee == 0 || !Callee->isDeclaration() || |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
374 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage())) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
375 continue; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
376 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
377 // Ignore unknown calls. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
378 StringMap<LibCallOptimization*>::iterator OMI = |
1553
f55ca8a1598c
Value::getNameStart and Value::getNameLength were removed
Benjamin Kramer <benny.kra@gmail.com>
parents:
1551
diff
changeset
|
379 Optimizations.find(Callee->getName()); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
380 if (OMI == Optimizations.end()) continue; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
381 |
1551
ed0feda76820
DOUT is deprecated, use DEBUG(errs()) instead
Benjamin Kramer <benny.kra@gmail.com>
parents:
1545
diff
changeset
|
382 DEBUG(errs() << "SimplifyDRuntimeCalls inspecting: " << *CI); |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
383 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
384 // Set the builder to the instruction after the call. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
385 Builder.SetInsertPoint(BB, I); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
386 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
387 // Try to optimize this call. |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
388 Value *Result = OMI->second->OptimizeCall(CI, Changed, TD, AA, Builder); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
389 if (Result == 0) continue; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
390 |
1551
ed0feda76820
DOUT is deprecated, use DEBUG(errs()) instead
Benjamin Kramer <benny.kra@gmail.com>
parents:
1545
diff
changeset
|
391 DEBUG(errs() << "SimplifyDRuntimeCalls simplified: " << *CI; |
ed0feda76820
DOUT is deprecated, use DEBUG(errs()) instead
Benjamin Kramer <benny.kra@gmail.com>
parents:
1545
diff
changeset
|
392 errs() << " into: " << *Result << "\n"); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
393 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
394 // Something changed! |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
395 Changed = true; |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
396 |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
397 if (Result == CI) { |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
398 assert(CI->use_empty()); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
399 ++NumDeleted; |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
400 AA.deleteValue(CI); |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
401 } else { |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
402 ++NumSimplified; |
1329
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
403 AA.replaceWithNewValue(CI, Result); |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
404 |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
405 if (!CI->use_empty()) |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
406 CI->replaceAllUsesWith(Result); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
407 |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
408 if (!Result->hasName()) |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
409 Result->takeName(CI); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
410 } |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
411 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
412 // Inspect the instruction after the call (which was potentially just |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
413 // added) next. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
414 I = CI; ++I; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
415 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
416 CI->eraseFromParent(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
417 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
418 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
419 return Changed; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
420 } |