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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }