Mercurial > projects > ldc
annotate gen/passes/SimplifyDRuntimeCalls.cpp @ 1650:40bd4a0d4870
Update to work with LLVM 2.7.
Removed use of dyn_cast, llvm no compiles
without exceptions and rtti by
default. We do need exceptions for the libconfig stuff, but rtti isn't
necessary (anymore).
Debug info needs to be rewritten, as in LLVM 2.7 the format has
completely changed. To have something to look at while rewriting, the
old code has been wrapped inside #ifndef DISABLE_DEBUG_INFO , this means
that you have to define this to compile at the moment.
Updated tango 0.99.9 patch to include updated EH runtime code, which is
needed for LLVM 2.7 as well.
author | Tomas Lindquist Olsen |
---|---|
date | Wed, 19 May 2010 12:42:32 +0200 |
parents | 8d086d552909 |
children |
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 |
1650 | 21 #include "llvm/Function.h" |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
22 #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
|
23 #include "llvm/Intrinsics.h" |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
24 #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
|
25 #include "llvm/Analysis/AliasAnalysis.h" |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
26 #include "llvm/Analysis/ValueTracking.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
27 #include "llvm/Target/TargetData.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
28 #include "llvm/ADT/StringMap.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
29 #include "llvm/ADT/Statistic.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
30 #include "llvm/Support/Compiler.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
31 #include "llvm/Support/Debug.h" |
1551
ed0feda76820
DOUT is deprecated, use DEBUG(errs()) instead
Benjamin Kramer <benny.kra@gmail.com>
parents:
1545
diff
changeset
|
32 #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
|
33 using namespace llvm; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
34 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
35 STATISTIC(NumSimplified, "Number of runtime calls simplified"); |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
36 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
|
37 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
38 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
39 // Optimizer Base Class |
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 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
42 /// 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
|
43 /// corresponds to one library call. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
44 namespace { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
45 class VISIBILITY_HIDDEN LibCallOptimization { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
46 protected: |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
47 Function *Caller; |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
48 bool* Changed; |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
49 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
|
50 AliasAnalysis *AA; |
1545
7fcb72d518f6
More factory methods moved to LLVMContext
Benjamin Kramer <benny.kra@gmail.com>
parents:
1535
diff
changeset
|
51 LLVMContext *Context; |
1650 | 52 |
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
|
53 /// 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
|
54 Value *CastToCStr(Value *V, IRBuilder<> &B); |
1650 | 55 |
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
|
56 /// 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
|
57 /// always expects that the size has type 'intptr_t' and Dst/Src are pointers. |
1650 | 58 Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len, |
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
|
59 unsigned Align, IRBuilder<> &B); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
60 public: |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
61 LibCallOptimization() { } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
62 virtual ~LibCallOptimization() {} |
1650 | 63 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
64 /// 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
|
65 /// 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
|
66 /// 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
|
67 /// 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
|
68 /// delete CI. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
69 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)=0; |
1650 | 70 |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
71 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
|
72 AliasAnalysis& AA, IRBuilder<> &B) { |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
73 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
|
74 this->Changed = &Changed; |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
75 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
|
76 this->AA = &AA; |
1545
7fcb72d518f6
More factory methods moved to LLVMContext
Benjamin Kramer <benny.kra@gmail.com>
parents:
1535
diff
changeset
|
77 if (CI->getCalledFunction()) |
1554
d6e8d5db259f
LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents:
1553
diff
changeset
|
78 Context = &CI->getCalledFunction()->getContext(); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
79 return CallOptimizer(CI->getCalledFunction(), CI, B); |
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 }; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
82 } // End anonymous namespace. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
83 |
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
|
84 /// 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
|
85 Value *LibCallOptimization::CastToCStr(Value *V, IRBuilder<> &B) { |
1571
8d086d552909
IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents:
1554
diff
changeset
|
86 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
|
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 |
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 /// 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
|
90 /// 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
|
91 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
|
92 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
|
93 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
|
94 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
|
95 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
|
96 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
|
97 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
|
98 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
|
99 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
|
100 } |
1275
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 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
103 // Miscellaneous LibCall Optimizations |
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 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
106 namespace { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
107 //===---------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
108 // '_d_arraysetlengthT'/'_d_arraysetlengthiT' Optimizations |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
109 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
110 /// 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
|
111 struct VISIBILITY_HIDDEN ArraySetLengthOpt : public LibCallOptimization { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
112 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
|
113 // 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
|
114 const FunctionType *FT = Callee->getFunctionType(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
115 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
|
116 !isa<IntegerType>(FT->getParamType(1)) || |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
117 FT->getParamType(1) != FT->getParamType(2) || |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
118 FT->getParamType(3) != FT->getReturnType()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
119 return 0; |
1650 | 120 |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
121 // 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
|
122 // Just delete if that's the case. |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
123 if (CI->use_empty()) |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
124 return CI; |
1650 | 125 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
126 Value* NewLen = CI->getOperand(2); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
127 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
|
128 Value* Data = CI->getOperand(4); |
1650 | 129 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
130 // 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
|
131 // |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
132 // 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
|
133 // 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
|
134 // (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
|
135 // safely transform that example if arr.length may be 0) |
1650 | 136 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
137 // 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
|
138 if (NewCst->isNullValue()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
139 return Data; |
1650 | 140 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
141 // 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
|
142 Value* OldLen = CI->getOperand(3); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
143 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
|
144 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
|
145 if (NewInt->getValue().ule(OldInt->getValue())) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
146 return Data; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
147 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
148 return 0; |
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 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
152 /// 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
|
153 struct VISIBILITY_HIDDEN ArrayCastLenOpt : public LibCallOptimization { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
154 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
|
155 // 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
|
156 const FunctionType *FT = Callee->getFunctionType(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
157 const Type* RetTy = FT->getReturnType(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
158 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
|
159 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
|
160 return 0; |
1650 | 161 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
162 Value* OldLen = CI->getOperand(1); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
163 Value* OldSize = CI->getOperand(2); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
164 Value* NewSize = CI->getOperand(3); |
1650 | 165 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
166 // 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
|
167 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
|
168 if (LenCst->isNullValue()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
169 return OldLen; |
1650 | 170 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
171 // 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
|
172 if (OldSize == NewSize) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
173 return OldLen; |
1650 | 174 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
175 // 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
|
176 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
|
177 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
|
178 // 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
|
179 if (NewInt->isNullValue()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
180 return 0; |
1650 | 181 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
182 APInt Quot, Rem; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
183 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
|
184 if (Rem == 0) |
1554
d6e8d5db259f
LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents:
1553
diff
changeset
|
185 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
|
186 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
187 return 0; |
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 }; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
190 |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
191 /// 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
|
192 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
|
193 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
|
194 // 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
|
195 // 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
|
196 // 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
|
197 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
|
198 Instruction* User = cast<Instruction>(*I++); |
1650 | 199 |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
200 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
|
201 if (!Cmp->isEquality()) |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
202 continue; |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
203 Constant* C = 0; |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
204 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
|
205 || (C = dyn_cast<Constant>(Cmp->getOperand(1)))) { |
1571
8d086d552909
IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents:
1554
diff
changeset
|
206 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
|
207 Cmp->replaceAllUsesWith(Result); |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
208 // 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
|
209 // 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
|
210 // 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
|
211 // (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
|
212 // 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
|
213 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
|
214 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
|
215 *Changed = true; |
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 } |
1650 | 219 |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
220 // 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
|
221 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
|
222 return CI; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
223 return 0; |
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 }; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
226 |
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
|
227 /// 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
|
228 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
|
229 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
|
230 // 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
|
231 const FunctionType *FT = Callee->getFunctionType(); |
1571
8d086d552909
IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents:
1554
diff
changeset
|
232 const Type* VoidPtrTy = PointerType::getUnqual(B.getInt8Ty()); |
8d086d552909
IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents:
1554
diff
changeset
|
233 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
|
234 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
|
235 !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
|
236 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
|
237 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
|
238 return 0; |
1650 | 239 |
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
|
240 Value* Size = CI->getOperand(2); |
1650 | 241 |
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
|
242 // 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
|
243 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
|
244 return 0; |
1650 | 245 |
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
|
246 // 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
|
247 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
|
248 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
|
249 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
|
250 Sz = Int->getValue().getZExtValue(); |
1650 | 251 |
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
|
252 // 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
|
253 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
|
254 return 0; |
1650 | 255 |
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
|
256 // 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
|
257 // 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
|
258 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
|
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 }; |
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
|
261 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
262 // TODO: More optimizations! :) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
263 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
264 } // end anonymous namespace. |
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 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
267 // SimplifyDRuntimeCalls Pass Implementation |
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 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
270 namespace { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
271 /// 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
|
272 /// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
273 class VISIBILITY_HIDDEN SimplifyDRuntimeCalls : public FunctionPass { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
274 StringMap<LibCallOptimization*> Optimizations; |
1650 | 275 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
276 // Array operations |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
277 ArraySetLengthOpt ArraySetLength; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
278 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
|
279 ArraySliceCopyOpt ArraySliceCopy; |
1650 | 280 |
1286
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
281 // GC allocations |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
282 AllocationOpt Allocation; |
1650 | 283 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
284 public: |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
285 static char ID; // Pass identification |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
286 SimplifyDRuntimeCalls() : FunctionPass(&ID) {} |
1650 | 287 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
288 void InitOptimizations(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
289 bool runOnFunction(Function &F); |
1650 | 290 |
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
|
291 bool runOnce(Function &F, const TargetData& TD, AliasAnalysis& AA); |
1650 | 292 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
293 virtual void getAnalysisUsage(AnalysisUsage &AU) const { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
294 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
|
295 AU.addRequired<AliasAnalysis>(); |
1275
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 }; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
298 char SimplifyDRuntimeCalls::ID = 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
299 } // end anonymous namespace. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
300 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
301 static RegisterPass<SimplifyDRuntimeCalls> |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
302 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
|
303 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
304 // Public interface to the pass. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
305 FunctionPass *createSimplifyDRuntimeCalls() { |
1650 | 306 return new SimplifyDRuntimeCalls(); |
1275
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 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
309 /// 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
|
310 /// we know. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
311 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
|
312 // Some array-related optimizations |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
313 Optimizations["_d_arraysetlengthT"] = &ArraySetLength; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
314 Optimizations["_d_arraysetlengthiT"] = &ArraySetLength; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
315 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
|
316 Optimizations["_d_array_slice_copy"] = &ArraySliceCopy; |
1650 | 317 |
1286
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
318 /* 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
|
319 * 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
|
320 * 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
|
321 * 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
|
322 * '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
|
323 * be deleted. |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
324 * (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
|
325 * 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
|
326 */ |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
327 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
|
328 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
|
329 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
|
330 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
|
331 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
|
332 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
|
333 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
|
334 Optimizations["_d_allocclass"] = &Allocation; |
1275
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 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
338 /// runOnFunction - Top level algorithm. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
339 /// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
340 bool SimplifyDRuntimeCalls::runOnFunction(Function &F) { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
341 if (Optimizations.empty()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
342 InitOptimizations(); |
1650 | 343 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
344 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
|
345 AliasAnalysis &AA = getAnalysis<AliasAnalysis>(); |
1650 | 346 |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
347 // 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
|
348 // 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
|
349 // 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
|
350 // 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
|
351 // before the second one. |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
352 bool EverChanged = false; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
353 bool Changed; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
354 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
|
355 Changed = runOnce(F, TD, AA); |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
356 EverChanged |= Changed; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
357 } while (Changed); |
1650 | 358 |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
359 return EverChanged; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
360 } |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
361 |
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
|
362 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
|
363 IRBuilder<> Builder(F.getContext()); |
d6e8d5db259f
LLVMContext changes up to r77366
Benjamin Kramer <benny.kra@gmail.com>
parents:
1553
diff
changeset
|
364 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
365 bool Changed = false; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
366 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
|
367 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
|
368 // Ignore non-calls. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
369 CallInst *CI = dyn_cast<CallInst>(I++); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
370 if (!CI) continue; |
1650 | 371 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
372 // 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
|
373 Function *Callee = CI->getCalledFunction(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
374 if (Callee == 0 || !Callee->isDeclaration() || |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
375 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage())) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
376 continue; |
1650 | 377 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
378 // Ignore unknown calls. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
379 StringMap<LibCallOptimization*>::iterator OMI = |
1553
f55ca8a1598c
Value::getNameStart and Value::getNameLength were removed
Benjamin Kramer <benny.kra@gmail.com>
parents:
1551
diff
changeset
|
380 Optimizations.find(Callee->getName()); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
381 if (OMI == Optimizations.end()) continue; |
1650 | 382 |
1551
ed0feda76820
DOUT is deprecated, use DEBUG(errs()) instead
Benjamin Kramer <benny.kra@gmail.com>
parents:
1545
diff
changeset
|
383 DEBUG(errs() << "SimplifyDRuntimeCalls inspecting: " << *CI); |
1650 | 384 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
385 // 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
|
386 Builder.SetInsertPoint(BB, I); |
1650 | 387 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
388 // 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
|
389 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
|
390 if (Result == 0) continue; |
1650 | 391 |
1551
ed0feda76820
DOUT is deprecated, use DEBUG(errs()) instead
Benjamin Kramer <benny.kra@gmail.com>
parents:
1545
diff
changeset
|
392 DEBUG(errs() << "SimplifyDRuntimeCalls simplified: " << *CI; |
ed0feda76820
DOUT is deprecated, use DEBUG(errs()) instead
Benjamin Kramer <benny.kra@gmail.com>
parents:
1545
diff
changeset
|
393 errs() << " into: " << *Result << "\n"); |
1650 | 394 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
395 // Something changed! |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
396 Changed = true; |
1650 | 397 |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
398 if (Result == CI) { |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
399 assert(CI->use_empty()); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
400 ++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
|
401 AA.deleteValue(CI); |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
402 } else { |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
403 ++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
|
404 AA.replaceWithNewValue(CI, Result); |
1650 | 405 |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
406 if (!CI->use_empty()) |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
407 CI->replaceAllUsesWith(Result); |
1650 | 408 |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
409 if (!Result->hasName()) |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
410 Result->takeName(CI); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
411 } |
1650 | 412 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
413 // 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
|
414 // added) next. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
415 I = CI; ++I; |
1650 | 416 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
417 CI->eraseFromParent(); |
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 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
420 return Changed; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
421 } |