Mercurial > projects > ldc
annotate gen/passes/SimplifyDRuntimeCalls.cpp @ 1319:c32e27f9a61d
Some tweaks to -simplify-drtcalls.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Sat, 09 May 2009 02:34:27 +0200 |
parents | 23b23b74e326 |
children | e5b57fd8307c |
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" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
22 #include "llvm/Support/IRBuilder.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
23 #include "llvm/Analysis/ValueTracking.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
24 #include "llvm/Target/TargetData.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
25 #include "llvm/ADT/StringMap.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
26 #include "llvm/ADT/Statistic.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
27 #include "llvm/Support/Compiler.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
28 #include "llvm/Support/Debug.h" |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
29 using namespace llvm; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
30 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
31 STATISTIC(NumSimplified, "Number of runtime calls simplified"); |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
32 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
|
33 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
34 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
35 // Optimizer Base Class |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
36 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
37 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
38 /// 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
|
39 /// corresponds to one library call. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
40 namespace { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
41 class VISIBILITY_HIDDEN LibCallOptimization { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
42 protected: |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
43 Function *Caller; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
44 const TargetData *TD; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
45 public: |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
46 LibCallOptimization() { } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
47 virtual ~LibCallOptimization() {} |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
48 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
49 /// 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
|
50 /// 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
|
51 /// 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
|
52 /// 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
|
53 /// delete CI. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
54 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
|
55 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
56 Value *OptimizeCall(CallInst *CI, const TargetData &TD, IRBuilder<> &B) { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
57 Caller = CI->getParent()->getParent(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
58 this->TD = &TD; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
59 return CallOptimizer(CI->getCalledFunction(), CI, B); |
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 }; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
62 } // End anonymous namespace. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
63 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
64 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
65 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
66 // Miscellaneous LibCall Optimizations |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
67 //===----------------------------------------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
68 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
69 namespace { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
70 //===---------------------------------------===// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
71 // '_d_arraysetlengthT'/'_d_arraysetlengthiT' Optimizations |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
72 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
73 /// 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
|
74 struct VISIBILITY_HIDDEN ArraySetLengthOpt : public LibCallOptimization { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
75 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
|
76 // 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
|
77 const FunctionType *FT = Callee->getFunctionType(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
78 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
|
79 !isa<IntegerType>(FT->getParamType(1)) || |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
80 FT->getParamType(1) != FT->getParamType(2) || |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
81 FT->getParamType(3) != FT->getReturnType()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
82 return 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
83 |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
84 // 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
|
85 // Just delete if that's the case. |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
86 if (CI->use_empty()) |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
87 return CI; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
88 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
89 Value* NewLen = CI->getOperand(2); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
90 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
|
91 Value* Data = CI->getOperand(4); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
92 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
93 // 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
|
94 // |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
95 // 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
|
96 // 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
|
97 // (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
|
98 // 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
|
99 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
100 // 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
|
101 if (NewCst->isNullValue()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
102 return Data; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
103 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
104 // 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
|
105 Value* OldLen = CI->getOperand(3); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
106 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
|
107 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
|
108 if (NewInt->getValue().ule(OldInt->getValue())) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
109 return Data; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
110 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
111 return 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
112 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
113 }; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
114 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
115 /// 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
|
116 struct VISIBILITY_HIDDEN ArrayCastLenOpt : public LibCallOptimization { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
117 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
|
118 // 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
|
119 const FunctionType *FT = Callee->getFunctionType(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
120 const Type* RetTy = FT->getReturnType(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
121 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
|
122 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
|
123 return 0; |
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 Value* OldLen = CI->getOperand(1); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
126 Value* OldSize = CI->getOperand(2); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
127 Value* NewSize = CI->getOperand(3); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
128 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
129 // 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
|
130 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
|
131 if (LenCst->isNullValue()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
132 return OldLen; |
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 // 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
|
135 if (OldSize == NewSize) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
136 return OldLen; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
137 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
138 // 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
|
139 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
|
140 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
|
141 // 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
|
142 if (NewInt->isNullValue()) |
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 APInt Quot, Rem; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
146 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
|
147 if (Rem == 0) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
148 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
|
149 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
150 return 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
151 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
152 }; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
153 |
1286
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
154 /// 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
|
155 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
|
156 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
|
157 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
|
158 return CI; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
159 return 0; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
160 } |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
161 }; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
162 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
163 // TODO: More optimizations! :) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
164 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
165 } // end anonymous namespace. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
166 |
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 // SimplifyDRuntimeCalls Pass Implementation |
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 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
171 namespace { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
172 /// 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
|
173 /// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
174 class VISIBILITY_HIDDEN SimplifyDRuntimeCalls : public FunctionPass { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
175 StringMap<LibCallOptimization*> Optimizations; |
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 // Array operations |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
178 ArraySetLengthOpt ArraySetLength; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
179 ArrayCastLenOpt ArrayCastLen; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
180 |
1286
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
181 // GC allocations |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
182 DeleteUnusedOpt DeleteUnused; |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
183 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
184 public: |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
185 static char ID; // Pass identification |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
186 SimplifyDRuntimeCalls() : FunctionPass(&ID) {} |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
187 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
188 void InitOptimizations(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
189 bool runOnFunction(Function &F); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
190 |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
191 bool runOnce(Function &F, const TargetData& TD); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
192 |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
193 virtual void getAnalysisUsage(AnalysisUsage &AU) const { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
194 AU.addRequired<TargetData>(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
195 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
196 }; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
197 char SimplifyDRuntimeCalls::ID = 0; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
198 } // end anonymous namespace. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
199 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
200 static RegisterPass<SimplifyDRuntimeCalls> |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
201 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
|
202 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
203 // Public interface to the pass. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
204 FunctionPass *createSimplifyDRuntimeCalls() { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
205 return new SimplifyDRuntimeCalls(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
206 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
207 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
208 /// 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
|
209 /// we know. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
210 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
|
211 // Some array-related optimizations |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
212 Optimizations["_d_arraysetlengthT"] = &ArraySetLength; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
213 Optimizations["_d_arraysetlengthiT"] = &ArraySetLength; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
214 Optimizations["_d_array_cast_len"] = &ArrayCastLen; |
1286
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
215 |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
216 /* 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
|
217 * 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
|
218 * 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
|
219 * 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
|
220 * '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
|
221 * be deleted. |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
222 * (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
|
223 * 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
|
224 */ |
23b23b74e326
Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents:
1275
diff
changeset
|
225 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
|
226 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
|
227 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
|
228 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
|
229 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
|
230 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
|
231 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
|
232 Optimizations["_d_allocclass"] = &DeleteUnused; |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
233 } |
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 /// runOnFunction - Top level algorithm. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
237 /// |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
238 bool SimplifyDRuntimeCalls::runOnFunction(Function &F) { |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
239 if (Optimizations.empty()) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
240 InitOptimizations(); |
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 const TargetData &TD = getAnalysis<TargetData>(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
243 |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
244 // 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
|
245 // 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
|
246 // 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
|
247 // 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
|
248 // before the second one. |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
249 bool EverChanged = false; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
250 bool Changed; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
251 do { |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
252 Changed = runOnce(F, TD); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
253 EverChanged |= Changed; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
254 } while (Changed); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
255 |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
256 return EverChanged; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
257 } |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
258 |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
259 bool SimplifyDRuntimeCalls::runOnce(Function &F, const TargetData& TD) { |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
260 IRBuilder<> Builder; |
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 bool Changed = false; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
263 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
|
264 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
|
265 // Ignore non-calls. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
266 CallInst *CI = dyn_cast<CallInst>(I++); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
267 if (!CI) continue; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
268 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
269 // 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
|
270 Function *Callee = CI->getCalledFunction(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
271 if (Callee == 0 || !Callee->isDeclaration() || |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
272 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage())) |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
273 continue; |
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 DEBUG(DOUT << "SimplifyDRuntimeCalls inspecting: " << *CI); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
276 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
277 // Ignore unknown calls. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
278 const char *CalleeName = Callee->getNameStart(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
279 StringMap<LibCallOptimization*>::iterator OMI = |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
280 Optimizations.find(CalleeName, CalleeName+Callee->getNameLen()); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
281 if (OMI == Optimizations.end()) continue; |
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 // 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
|
284 Builder.SetInsertPoint(BB, I); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
285 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
286 // Try to optimize this call. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
287 Value *Result = OMI->second->OptimizeCall(CI, TD, Builder); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
288 if (Result == 0) continue; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
289 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
290 DEBUG(DOUT << "SimplifyDRuntimeCalls simplified: " << *CI; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
291 DOUT << " into: " << *Result << "\n"); |
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 // Something changed! |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
294 Changed = true; |
1319
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
295 |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
296 if (Result == CI) { |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
297 assert(CI->use_empty()); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
298 ++NumDeleted; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
299 } else { |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
300 ++NumSimplified; |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
301 |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
302 if (!CI->use_empty()) |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
303 CI->replaceAllUsesWith(Result); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
304 |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
305 if (!Result->hasName()) |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
306 Result->takeName(CI); |
c32e27f9a61d
Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
1286
diff
changeset
|
307 } |
1275
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
308 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
309 // 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
|
310 // added) next. |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
311 I = CI; ++I; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
312 |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
313 CI->eraseFromParent(); |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
314 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
315 } |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
316 return Changed; |
bedf0bfb8fdb
Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
317 } |