Mercurial > projects > ldc
annotate gen/passes/SimplifyDRuntimeCalls.cpp @ 1507:f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
`assert(this !is null)`s when member functions get inlined.
Also tweak pass order a bit.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Sat, 20 Jun 2009 14:28:59 +0200 |
parents | e5b57fd8307c |
children | ad7f2f1862d6 |
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" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
31 using namespace llvm; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
32 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
33 STATISTIC(NumSimplified, "Number of runtime calls simplified"); |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
34 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
|
35 |
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 // Optimizer Base Class |
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 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
40 /// 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
|
41 /// corresponds to one library call. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
42 namespace { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
43 class VISIBILITY_HIDDEN LibCallOptimization { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
44 protected: |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
45 Function *Caller; |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
46 bool* Changed; |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
47 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
|
48 AliasAnalysis *AA; |
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 |
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 /// 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
|
51 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
|
52 |
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 /// 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
|
54 /// 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
|
55 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
|
56 unsigned Align, IRBuilder<> &B); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
57 public: |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
58 LibCallOptimization() { } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
59 virtual ~LibCallOptimization() {} |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
60 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
61 /// 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
|
62 /// 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
|
63 /// 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
|
64 /// 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
|
65 /// delete CI. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
66 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
|
67 |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
68 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
|
69 AliasAnalysis& AA, IRBuilder<> &B) { |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
70 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
|
71 this->Changed = &Changed; |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
72 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
|
73 this->AA = &AA; |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
74 return CallOptimizer(CI->getCalledFunction(), CI, B); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
75 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
76 }; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
77 } // End anonymous namespace. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
78 |
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
|
79 /// 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
|
80 Value *LibCallOptimization::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
|
81 return B.CreateBitCast(V, PointerType::getUnqual(Type::Int8Ty), "cstr"); |
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
|
82 } |
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 |
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 /// 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
|
85 /// 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
|
86 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
|
87 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
|
88 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
|
89 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
|
90 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
|
91 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
|
92 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
|
93 return B.CreateCall4(MemCpy, CastToCStr(Dst, B), CastToCStr(Src, B), 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
|
94 ConstantInt::get(Type::Int32Ty, Align)); |
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 } |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
96 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
97 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
98 // Miscellaneous LibCall Optimizations |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
99 //===----------------------------------------------------------------------===// |
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 namespace { |
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 // '_d_arraysetlengthT'/'_d_arraysetlengthiT' 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 /// 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
|
106 struct VISIBILITY_HIDDEN ArraySetLengthOpt : public LibCallOptimization { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
107 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
|
108 // 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
|
109 const FunctionType *FT = Callee->getFunctionType(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
110 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
|
111 !isa<IntegerType>(FT->getParamType(1)) || |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
112 FT->getParamType(1) != FT->getParamType(2) || |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
113 FT->getParamType(3) != FT->getReturnType()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
114 return 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
115 |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
116 // 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
|
117 // Just delete if that's the case. |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
118 if (CI->use_empty()) |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
119 return CI; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
120 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
121 Value* NewLen = CI->getOperand(2); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
122 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
|
123 Value* Data = CI->getOperand(4); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
124 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
125 // 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
|
126 // |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
127 // 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
|
128 // 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
|
129 // (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
|
130 // 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
|
131 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
132 // 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
|
133 if (NewCst->isNullValue()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
134 return Data; |
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 // 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
|
137 Value* OldLen = CI->getOperand(3); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
138 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
|
139 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
|
140 if (NewInt->getValue().ule(OldInt->getValue())) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
141 return Data; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
142 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
143 return 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
144 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
145 }; |
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 /// 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
|
148 struct VISIBILITY_HIDDEN ArrayCastLenOpt : public LibCallOptimization { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
149 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
|
150 // 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
|
151 const FunctionType *FT = Callee->getFunctionType(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
152 const Type* RetTy = FT->getReturnType(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
153 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
|
154 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
|
155 return 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
156 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
157 Value* OldLen = CI->getOperand(1); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
158 Value* OldSize = CI->getOperand(2); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
159 Value* NewSize = CI->getOperand(3); |
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 // 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
|
162 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
|
163 if (LenCst->isNullValue()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
164 return OldLen; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
165 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
166 // 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
|
167 if (OldSize == NewSize) |
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 // 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
|
171 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
|
172 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
|
173 // 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
|
174 if (NewInt->isNullValue()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
175 return 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
176 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
177 APInt Quot, Rem; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
178 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
|
179 if (Rem == 0) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
180 return B.CreateMul(OldLen, ConstantInt::get(Quot)); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
181 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
182 return 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
183 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
184 }; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
185 |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
186 /// 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
|
187 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
|
188 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
|
189 // 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
|
190 // 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
|
191 // 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
|
192 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
|
193 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
|
194 |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
195 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
|
196 if (!Cmp->isEquality()) |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
197 continue; |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
198 Constant* C = 0; |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
199 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
|
200 || (C = dyn_cast<Constant>(Cmp->getOperand(1)))) { |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
201 Value* Result = ConstantInt::get(Type::Int1Ty, !Cmp->isTrueWhenEqual()); |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
202 Cmp->replaceAllUsesWith(Result); |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
203 // 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
|
204 // 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
|
205 // 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
|
206 // (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
|
207 // 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
|
208 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
|
209 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
|
210 *Changed = true; |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
211 } |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
212 } |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
213 } |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
214 |
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
215 // 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
|
216 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
|
217 return CI; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
218 return 0; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
219 } |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
220 }; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
221 |
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
|
222 /// 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
|
223 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
|
224 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
|
225 // 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
|
226 const FunctionType *FT = Callee->getFunctionType(); |
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 const Type* VoidPtrTy = PointerType::getUnqual(Type::Int8Ty); |
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 if (Callee->arg_size() != 4 || FT->getReturnType() != Type::VoidTy || |
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 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
|
230 !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
|
231 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
|
232 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
|
233 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
|
234 |
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 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
|
236 |
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 // 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
|
238 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
|
239 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
|
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 // 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
|
242 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
|
243 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
|
244 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
|
245 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
|
246 |
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 // 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
|
248 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
|
249 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
|
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 // 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
|
252 // 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
|
253 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
|
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 }; |
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 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
257 // TODO: More optimizations! :) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
258 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
259 } // end anonymous namespace. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
260 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
261 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
262 // SimplifyDRuntimeCalls Pass Implementation |
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 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
265 namespace { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
266 /// 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
|
267 /// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
268 class VISIBILITY_HIDDEN SimplifyDRuntimeCalls : public FunctionPass { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
269 StringMap<LibCallOptimization*> Optimizations; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
270 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
271 // Array operations |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
272 ArraySetLengthOpt ArraySetLength; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
273 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
|
274 ArraySliceCopyOpt ArraySliceCopy; |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
275 |
1286
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
276 // GC allocations |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
277 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
|
278 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
279 public: |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
280 static char ID; // Pass identification |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
281 SimplifyDRuntimeCalls() : FunctionPass(&ID) {} |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
282 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
283 void InitOptimizations(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
284 bool runOnFunction(Function &F); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
285 |
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
|
286 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
|
287 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
288 virtual void getAnalysisUsage(AnalysisUsage &AU) const { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
289 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
|
290 AU.addRequired<AliasAnalysis>(); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
291 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
292 }; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
293 char SimplifyDRuntimeCalls::ID = 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
294 } // end anonymous namespace. |
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 static RegisterPass<SimplifyDRuntimeCalls> |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
297 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
|
298 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
299 // Public interface to the pass. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
300 FunctionPass *createSimplifyDRuntimeCalls() { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
301 return new SimplifyDRuntimeCalls(); |
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 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
304 /// 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
|
305 /// we know. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
306 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
|
307 // Some array-related optimizations |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
308 Optimizations["_d_arraysetlengthT"] = &ArraySetLength; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
309 Optimizations["_d_arraysetlengthiT"] = &ArraySetLength; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
310 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
|
311 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
|
312 |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
313 /* 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
|
314 * 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
|
315 * 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
|
316 * 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
|
317 * '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
|
318 * be deleted. |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
319 * (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
|
320 * 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
|
321 */ |
1507
f86fd3b77285
Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents:
1329
diff
changeset
|
322 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
|
323 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
|
324 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
|
325 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
|
326 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
|
327 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
|
328 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
|
329 Optimizations["_d_allocclass"] = &Allocation; |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
330 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
331 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
332 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
333 /// runOnFunction - Top level algorithm. |
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 bool SimplifyDRuntimeCalls::runOnFunction(Function &F) { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
336 if (Optimizations.empty()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
337 InitOptimizations(); |
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 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
|
340 AliasAnalysis &AA = getAnalysis<AliasAnalysis>(); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
341 |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
342 // 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
|
343 // 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
|
344 // 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
|
345 // 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
|
346 // before the second one. |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
347 bool EverChanged = false; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
348 bool Changed; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
349 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
|
350 Changed = runOnce(F, TD, AA); |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
351 EverChanged |= Changed; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
352 } while (Changed); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
353 |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
354 return EverChanged; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
355 } |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
356 |
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
|
357 bool SimplifyDRuntimeCalls::runOnce(Function &F, const TargetData& TD, AliasAnalysis& AA) { |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
358 IRBuilder<> Builder; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
359 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
360 bool Changed = false; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
361 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
|
362 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
|
363 // Ignore non-calls. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
364 CallInst *CI = dyn_cast<CallInst>(I++); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
365 if (!CI) continue; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
366 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
367 // 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
|
368 Function *Callee = CI->getCalledFunction(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
369 if (Callee == 0 || !Callee->isDeclaration() || |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
370 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage())) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
371 continue; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
372 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
373 // Ignore unknown calls. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
374 const char *CalleeName = Callee->getNameStart(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
375 StringMap<LibCallOptimization*>::iterator OMI = |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
376 Optimizations.find(CalleeName, CalleeName+Callee->getNameLen()); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
377 if (OMI == Optimizations.end()) continue; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
378 |
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
|
379 DEBUG(DOUT << "SimplifyDRuntimeCalls inspecting: " << *CI); |
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
|
380 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
381 // 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
|
382 Builder.SetInsertPoint(BB, I); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
383 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
384 // 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
|
385 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
|
386 if (Result == 0) continue; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
387 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
388 DEBUG(DOUT << "SimplifyDRuntimeCalls simplified: " << *CI; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
389 DOUT << " into: " << *Result << "\n"); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
390 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
391 // Something changed! |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
392 Changed = true; |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
393 |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
394 if (Result == CI) { |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
395 assert(CI->use_empty()); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
396 ++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
|
397 AA.deleteValue(CI); |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
398 } else { |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
399 ++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
|
400 AA.replaceWithNewValue(CI, Result); |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
401 |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
402 if (!CI->use_empty()) |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
403 CI->replaceAllUsesWith(Result); |
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 (!Result->hasName()) |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
406 Result->takeName(CI); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
407 } |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
408 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
409 // 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
|
410 // added) next. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
411 I = CI; ++I; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
412 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
413 CI->eraseFromParent(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
414 } |
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 return Changed; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
417 } |