Mercurial > projects > ldc
annotate gen/passes/SimplifyDRuntimeCalls.cpp @ 1351:8d501abecd24
Initial (but disabled) fix for ticket #294 , the actual part that fixes the bug is in a #if 0 block as I'm afraid it will cause regressions. I'm most likely not going to be around tonight, and maybe not tomorrow as well, so I'm pushing it in case someone wants to run some serious testing/investigate the problem noted in llvmhelpers.cpp : realignOffset .
author | Tomas Lindquist Olsen <tomas.l.olsen gmail com> |
---|---|
date | Thu, 14 May 2009 17:20:17 +0200 |
parents | e5b57fd8307c |
children | f86fd3b77285 |
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; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
46 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
|
47 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
|
48 |
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 /// 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
|
50 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
|
51 |
e5b57fd8307c
Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents:
1319
diff
changeset
|
52 /// 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
|
53 /// 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
|
54 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
|
55 unsigned Align, IRBuilder<> &B); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
56 public: |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
57 LibCallOptimization() { } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
58 virtual ~LibCallOptimization() {} |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
59 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
60 /// 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
|
61 /// 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
|
62 /// 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
|
63 /// 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
|
64 /// delete CI. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
65 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
|
66 |
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
|
67 Value *OptimizeCall(CallInst *CI, const TargetData &TD, |
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
|
68 AliasAnalysis& AA, IRBuilder<> &B) { |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
69 Caller = CI->getParent()->getParent(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
70 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
|
71 this->AA = &AA; |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
72 return CallOptimizer(CI->getCalledFunction(), CI, B); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
73 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
74 }; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
75 } // End anonymous namespace. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
76 |
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
|
77 /// 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
|
78 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
|
79 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
|
80 } |
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 |
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 /// 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
|
83 /// 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
|
84 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
|
85 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
|
86 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
|
87 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
|
88 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
|
89 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
|
90 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
|
91 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
|
92 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
|
93 } |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
94 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
95 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
96 // Miscellaneous LibCall Optimizations |
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 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
99 namespace { |
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 // '_d_arraysetlengthT'/'_d_arraysetlengthiT' Optimizations |
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 /// 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
|
104 struct VISIBILITY_HIDDEN ArraySetLengthOpt : public LibCallOptimization { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
105 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
|
106 // 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
|
107 const FunctionType *FT = Callee->getFunctionType(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
108 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
|
109 !isa<IntegerType>(FT->getParamType(1)) || |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
110 FT->getParamType(1) != FT->getParamType(2) || |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
111 FT->getParamType(3) != FT->getReturnType()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
112 return 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
113 |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
114 // 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
|
115 // Just delete if that's the case. |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
116 if (CI->use_empty()) |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
117 return CI; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
118 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
119 Value* NewLen = CI->getOperand(2); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
120 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
|
121 Value* Data = CI->getOperand(4); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
122 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
123 // 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
|
124 // |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
125 // 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
|
126 // 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
|
127 // (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
|
128 // 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
|
129 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
130 // 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
|
131 if (NewCst->isNullValue()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
132 return Data; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
133 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
134 // 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
|
135 Value* OldLen = CI->getOperand(3); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
136 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
|
137 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
|
138 if (NewInt->getValue().ule(OldInt->getValue())) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
139 return Data; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
140 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
141 return 0; |
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 }; |
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 /// 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
|
146 struct VISIBILITY_HIDDEN ArrayCastLenOpt : public LibCallOptimization { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
147 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
|
148 // 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
|
149 const FunctionType *FT = Callee->getFunctionType(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
150 const Type* RetTy = FT->getReturnType(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
151 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
|
152 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
|
153 return 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
154 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
155 Value* OldLen = CI->getOperand(1); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
156 Value* OldSize = CI->getOperand(2); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
157 Value* NewSize = CI->getOperand(3); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
158 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
159 // 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
|
160 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
|
161 if (LenCst->isNullValue()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
162 return OldLen; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
163 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
164 // 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
|
165 if (OldSize == NewSize) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
166 return OldLen; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
167 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
168 // 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
|
169 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
|
170 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
|
171 // 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
|
172 if (NewInt->isNullValue()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
173 return 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
174 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
175 APInt Quot, Rem; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
176 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
|
177 if (Rem == 0) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
178 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
|
179 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
180 return 0; |
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 }; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
183 |
1286
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
184 /// DeleteUnusedOpt - remove libcall if the return value is unused. |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
185 struct VISIBILITY_HIDDEN DeleteUnusedOpt : public LibCallOptimization { |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
186 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
187 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
|
188 return CI; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
189 return 0; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
190 } |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
191 }; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
192 |
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
|
193 /// 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
|
194 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
|
195 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
|
196 // 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
|
197 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
|
198 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
|
199 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
|
200 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
|
201 !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
|
202 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
|
203 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
|
204 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
|
205 |
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
|
206 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
|
207 |
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
|
208 // 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
|
209 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
|
210 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
|
211 |
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
|
212 // 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
|
213 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
|
214 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
|
215 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
|
216 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
|
217 |
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
|
218 // 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
|
219 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
|
220 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
|
221 |
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 // 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
|
223 // 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
|
224 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
|
225 } |
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 }; |
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 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
228 // TODO: More optimizations! :) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
229 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
230 } // end anonymous namespace. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
231 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
232 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
233 // SimplifyDRuntimeCalls Pass Implementation |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
234 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
235 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
236 namespace { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
237 /// 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
|
238 /// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
239 class VISIBILITY_HIDDEN SimplifyDRuntimeCalls : public FunctionPass { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
240 StringMap<LibCallOptimization*> Optimizations; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
241 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
242 // Array operations |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
243 ArraySetLengthOpt ArraySetLength; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
244 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
|
245 ArraySliceCopyOpt ArraySliceCopy; |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
246 |
1286
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
247 // GC allocations |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
248 DeleteUnusedOpt DeleteUnused; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
249 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
250 public: |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
251 static char ID; // Pass identification |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
252 SimplifyDRuntimeCalls() : FunctionPass(&ID) {} |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
253 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
254 void InitOptimizations(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
255 bool runOnFunction(Function &F); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
256 |
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
|
257 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
|
258 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
259 virtual void getAnalysisUsage(AnalysisUsage &AU) const { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
260 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
|
261 AU.addRequired<AliasAnalysis>(); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
262 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
263 }; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
264 char SimplifyDRuntimeCalls::ID = 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
265 } // end anonymous namespace. |
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 static RegisterPass<SimplifyDRuntimeCalls> |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
268 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
|
269 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
270 // Public interface to the pass. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
271 FunctionPass *createSimplifyDRuntimeCalls() { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
272 return new SimplifyDRuntimeCalls(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
273 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
274 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
275 /// 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
|
276 /// we know. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
277 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
|
278 // Some array-related optimizations |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
279 Optimizations["_d_arraysetlengthT"] = &ArraySetLength; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
280 Optimizations["_d_arraysetlengthiT"] = &ArraySetLength; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
281 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
|
282 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
|
283 |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
284 /* 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
|
285 * 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
|
286 * 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
|
287 * 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
|
288 * '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
|
289 * be deleted. |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
290 * (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
|
291 * 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
|
292 */ |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
293 Optimizations["_d_allocmemoryT"] = &DeleteUnused; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
294 Optimizations["_d_newarrayT"] = &DeleteUnused; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
295 Optimizations["_d_newarrayiT"] = &DeleteUnused; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
296 Optimizations["_d_newarrayvT"] = &DeleteUnused; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
297 Optimizations["_d_newarraymT"] = &DeleteUnused; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
298 Optimizations["_d_newarraymiT"] = &DeleteUnused; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
299 Optimizations["_d_newarraymvT"] = &DeleteUnused; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
300 Optimizations["_d_allocclass"] = &DeleteUnused; |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
301 } |
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 /// runOnFunction - Top level algorithm. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
305 /// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
306 bool SimplifyDRuntimeCalls::runOnFunction(Function &F) { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
307 if (Optimizations.empty()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
308 InitOptimizations(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
309 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
310 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
|
311 AliasAnalysis &AA = getAnalysis<AliasAnalysis>(); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
312 |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
313 // 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
|
314 // 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
|
315 // 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
|
316 // 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
|
317 // before the second one. |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
318 bool EverChanged = false; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
319 bool Changed; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
320 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
|
321 Changed = runOnce(F, TD, AA); |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
322 EverChanged |= Changed; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
323 } while (Changed); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
324 |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
325 return EverChanged; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
326 } |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
327 |
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
|
328 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
|
329 IRBuilder<> Builder; |
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 bool Changed = false; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
332 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
|
333 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
|
334 // Ignore non-calls. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
335 CallInst *CI = dyn_cast<CallInst>(I++); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
336 if (!CI) continue; |
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 // 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
|
339 Function *Callee = CI->getCalledFunction(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
340 if (Callee == 0 || !Callee->isDeclaration() || |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
341 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage())) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
342 continue; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
343 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
344 // Ignore unknown calls. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
345 const char *CalleeName = Callee->getNameStart(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
346 StringMap<LibCallOptimization*>::iterator OMI = |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
347 Optimizations.find(CalleeName, CalleeName+Callee->getNameLen()); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
348 if (OMI == Optimizations.end()) continue; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
349 |
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 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
|
351 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
352 // 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
|
353 Builder.SetInsertPoint(BB, I); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
354 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
355 // Try to optimize this call. |
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
|
356 Value *Result = OMI->second->OptimizeCall(CI, TD, AA, Builder); |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
357 if (Result == 0) continue; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
358 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
359 DEBUG(DOUT << "SimplifyDRuntimeCalls simplified: " << *CI; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
360 DOUT << " into: " << *Result << "\n"); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
361 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
362 // Something changed! |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
363 Changed = true; |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
364 |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
365 if (Result == CI) { |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
366 assert(CI->use_empty()); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
367 ++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
|
368 AA.deleteValue(CI); |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
369 } else { |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
370 ++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
|
371 AA.replaceWithNewValue(CI, Result); |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
372 |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
373 if (!CI->use_empty()) |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
374 CI->replaceAllUsesWith(Result); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
375 |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
376 if (!Result->hasName()) |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
377 Result->takeName(CI); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
378 } |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
379 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
380 // 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
|
381 // added) next. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
382 I = CI; ++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 CI->eraseFromParent(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
385 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
386 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
387 return Changed; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
388 } |