Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

root/gen/passes/SimplifyDRuntimeCalls.cpp

Revision 1650:40bd4a0d4870, 16.5 kB (checked in by Tomas Lindquist Olsen, 2 years ago)

Update to work with LLVM 2.7.

Removed use of dyn_cast, llvm no compiles
without exceptions and rtti by
default. We do need exceptions for the libconfig stuff, but rtti isn't
necessary (anymore).

Debug info needs to be rewritten, as in LLVM 2.7 the format has
completely changed. To have something to look at while rewriting, the
old code has been wrapped inside #ifndef DISABLE_DEBUG_INFO , this means
that you have to define this to compile at the moment.

Updated tango 0.99.9 patch to include updated EH runtime code, which is
needed for LLVM 2.7 as well.

Line 
1 //===- SimplifyDRuntimeCalls - Optimize calls to the D runtime library ----===//
2 //
3 //                             The LLVM D Compiler
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements a simple pass that applies a variety of small
11 // optimizations for calls to specific functions in the D runtime.
12 //
13 // The machinery was copied from the standard -simplify-libcalls LLVM pass.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #define DEBUG_TYPE "simplify-drtcalls"
18
19 #include "Passes.h"
20
21 #include "llvm/Function.h"
22 #include "llvm/Pass.h"
23 #include "llvm/Intrinsics.h"
24 #include "llvm/Support/IRBuilder.h"
25 #include "llvm/Analysis/AliasAnalysis.h"
26 #include "llvm/Analysis/ValueTracking.h"
27 #include "llvm/Target/TargetData.h"
28 #include "llvm/ADT/StringMap.h"
29 #include "llvm/ADT/Statistic.h"
30 #include "llvm/Support/Compiler.h"
31 #include "llvm/Support/Debug.h"
32 #include "llvm/Support/raw_ostream.h"
33 using namespace llvm;
34
35 STATISTIC(NumSimplified, "Number of runtime calls simplified");
36 STATISTIC(NumDeleted, "Number of runtime calls deleted");
37
38 //===----------------------------------------------------------------------===//
39 // Optimizer Base Class
40 //===----------------------------------------------------------------------===//
41
42 /// This class is the abstract base class for the set of optimizations that
43 /// corresponds to one library call.
44 namespace {
45     class VISIBILITY_HIDDEN LibCallOptimization {
46     protected:
47         Function *Caller;
48         bool* Changed;
49         const TargetData *TD;
50         AliasAnalysis *AA;
51         LLVMContext *Context;
52
53         /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
54         Value *CastToCStr(Value *V, IRBuilder<> &B);
55
56         /// EmitMemCpy - Emit a call to the memcpy function to the builder.  This
57         /// always expects that the size has type 'intptr_t' and Dst/Src are pointers.
58         Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len,
59                           unsigned Align, IRBuilder<> &B);
60     public:
61         LibCallOptimization() { }
62         virtual ~LibCallOptimization() {}
63
64         /// CallOptimizer - This pure virtual method is implemented by base classes to
65         /// do various optimizations.  If this returns null then no transformation was
66         /// performed.  If it returns CI, then it transformed the call and CI is to be
67         /// deleted.  If it returns something else, replace CI with the new value and
68         /// delete CI.
69         virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)=0;
70
71         Value *OptimizeCall(CallInst *CI, bool& Changed, const TargetData &TD,
72                 AliasAnalysis& AA, IRBuilder<> &B) {
73             Caller = CI->getParent()->getParent();
74             this->Changed = &Changed;
75             this->TD = &TD;
76             this->AA = &AA;
77             if (CI->getCalledFunction())
78                 Context = &CI->getCalledFunction()->getContext();
79             return CallOptimizer(CI->getCalledFunction(), CI, B);
80         }
81     };
82 } // End anonymous namespace.
83
84 /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
85 Value *LibCallOptimization::CastToCStr(Value *V, IRBuilder<> &B) {
86   return B.CreateBitCast(V, PointerType::getUnqual(B.getInt8Ty()), "cstr");
87 }
88
89 /// EmitMemCpy - Emit a call to the memcpy function to the builder.  This always
90 /// expects that the size has type 'intptr_t' and Dst/Src are pointers.
91 Value *LibCallOptimization::EmitMemCpy(Value *Dst, Value *Src, Value *Len,
92                                        unsigned Align, IRBuilder<> &B) {
93   Module *M = Caller->getParent();
94   Intrinsic::ID IID = Intrinsic::memcpy;
95   const Type *Tys[1];
96   Tys[0] = Len->getType();
97   Value *MemCpy = Intrinsic::getDeclaration(M, IID, Tys, 1);
98   return B.CreateCall4(MemCpy, CastToCStr(Dst, B), CastToCStr(Src, B), Len,
99                        ConstantInt::get(B.getInt32Ty(), Align));
100 }
101
102 //===----------------------------------------------------------------------===//
103 // Miscellaneous LibCall Optimizations
104 //===----------------------------------------------------------------------===//
105
106 namespace {
107 //===---------------------------------------===//
108 // '_d_arraysetlengthT'/'_d_arraysetlengthiT' Optimizations
109
110 /// ArraySetLengthOpt - remove libcall for arr.length = N if N <= arr.length
111 struct VISIBILITY_HIDDEN ArraySetLengthOpt : public LibCallOptimization {
112     virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
113         // Verify we have a reasonable prototype for _d_arraysetlength[i]T
114         const FunctionType *FT = Callee->getFunctionType();
115         if (Callee->arg_size() != 4 || !isa<PointerType>(FT->getReturnType()) ||
116             !isa<IntegerType>(FT->getParamType(1)) ||
117             FT->getParamType(1) != FT->getParamType(2) ||
118             FT->getParamType(3) != FT->getReturnType())
119           return 0;
120
121         // Whether or not this allocates is irrelevant if the result isn't used.
122         // Just delete if that's the case.
123         if (CI->use_empty())
124             return CI;
125
126         Value* NewLen = CI->getOperand(2);
127         if (Constant* NewCst = dyn_cast<Constant>(NewLen)) {
128             Value* Data = CI->getOperand(4);
129
130             // For now, we just catch the simplest of cases.
131             //
132             // TODO: Implement a more general way to compare old and new
133             //       lengths, to catch cases like "arr.length = arr.length - 1;"
134             //       (But beware of unsigned overflow! For example, we can't
135             //       safely transform that example if arr.length may be 0)
136
137             // Setting length to 0 never reallocates, so replace by data argument
138             if (NewCst->isNullValue())
139                 return Data;
140
141             // If both lengths are constant integers, see if NewLen <= OldLen
142             Value* OldLen = CI->getOperand(3);
143             if (ConstantInt* OldInt = dyn_cast<ConstantInt>(OldLen))
144                 if (ConstantInt* NewInt = dyn_cast<ConstantInt>(NewCst))
145                     if (NewInt->getValue().ule(OldInt->getValue()))
146                         return Data;
147         }
148         return 0;
149     }
150 };
151
152 /// ArrayCastLenOpt - remove libcall for cast(T[]) arr if it's safe to do so.
153 struct VISIBILITY_HIDDEN ArrayCastLenOpt : public LibCallOptimization {
154     virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
155         // Verify we have a reasonable prototype for _d_array_cast_len
156         const FunctionType *FT = Callee->getFunctionType();
157         const Type* RetTy = FT->getReturnType();
158         if (Callee->arg_size() != 3 || !isa<IntegerType>(RetTy) ||
159             FT->getParamType(1) != RetTy || FT->getParamType(2) != RetTy)
160           return 0;
161
162         Value* OldLen = CI->getOperand(1);
163         Value* OldSize = CI->getOperand(2);
164         Value* NewSize = CI->getOperand(3);
165
166         // If the old length was zero, always return zero.
167         if (Constant* LenCst = dyn_cast<Constant>(OldLen))
168             if (LenCst->isNullValue())
169                 return OldLen;
170
171         // Equal sizes are much faster to check for, so do so now.
172         if (OldSize == NewSize)
173             return OldLen;
174
175         // If both sizes are constant integers, see if OldSize is a multiple of NewSize
176         if (ConstantInt* OldInt = dyn_cast<ConstantInt>(OldSize))
177             if (ConstantInt* NewInt = dyn_cast<ConstantInt>(NewSize)) {
178                 // Don't crash on NewSize == 0, even though it shouldn't happen.
179                 if (NewInt->isNullValue())
180                     return 0;
181
182                 APInt Quot, Rem;
183                 APInt::udivrem(OldInt->getValue(), NewInt->getValue(), Quot, Rem);
184                 if (Rem == 0)
185                     return B.CreateMul(OldLen, ConstantInt::get(*Context, Quot));
186             }
187         return 0;
188     }
189 };
190
191 /// AllocationOpt - Common optimizations for various GC allocations.
192 struct VISIBILITY_HIDDEN AllocationOpt : public LibCallOptimization {
193     virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
194         // Allocations are never equal to constants, so remove any equality
195         // comparisons to constants. (Most importantly comparisons to null at
196         // the start of inlined member functions)
197         for (CallInst::use_iterator I = CI->use_begin(), E = CI->use_end() ; I != E;) {
198             Instruction* User = cast<Instruction>(*I++);
199
200             if (ICmpInst* Cmp = dyn_cast<ICmpInst>(User)) {
201                 if (!Cmp->isEquality())
202                     continue;
203                 Constant* C = 0;
204                 if ((C = dyn_cast<Constant>(Cmp->getOperand(0)))
205                     || (C = dyn_cast<Constant>(Cmp->getOperand(1)))) {
206                     Value* Result = ConstantInt::get(B.getInt1Ty(), !Cmp->isTrueWhenEqual());
207                     Cmp->replaceAllUsesWith(Result);
208                     // Don't delete the comparison because there may be an
209                     // iterator to it. Instead, set the operands to constants
210                     // and let dead code elimination clean it up later.
211                     // (It doesn't matter that this changes the value of the
212                     // icmp because it's not used anymore anyway)
213                     Cmp->setOperand(0, C);
214                     Cmp->setOperand(1, C);
215                     *Changed = true;
216                 }
217             }
218         }
219
220         // If it's not used (anymore), pre-emptively GC it.
221         if (CI->use_empty())
222             return CI;
223         return 0;
224     }
225 };
226
227 /// ArraySliceCopyOpt - Turn slice copies into llvm.memcpy when safe
228 struct VISIBILITY_HIDDEN ArraySliceCopyOpt : public LibCallOptimization {
229     virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
230         // Verify we have a reasonable prototype for _d_array_slice_copy
231         const FunctionType *FT = Callee->getFunctionType();
232         const Type* VoidPtrTy = PointerType::getUnqual(B.getInt8Ty());
233         if (Callee->arg_size() != 4 || FT->getReturnType() != B.getVoidTy() ||
234             FT->getParamType(0) != VoidPtrTy ||
235             !isa<IntegerType>(FT->getParamType(1)) ||
236             FT->getParamType(2) != VoidPtrTy ||
237             FT->getParamType(3) != FT->getParamType(1))
238           return 0;
239
240         Value* Size = CI->getOperand(2);
241
242         // Check the lengths match
243         if (CI->getOperand(4) != Size)
244             return 0;
245
246         // Assume unknown size unless we have constant size (that fits in an uint)
247         unsigned Sz = ~0U;
248         if (ConstantInt* Int = dyn_cast<ConstantInt>(Size))
249             if (Int->getValue().isIntN(32))
250                 Sz = Int->getValue().getZExtValue();
251
252         // Check if the pointers may alias
253         if (AA->alias(CI->getOperand(1), Sz, CI->getOperand(3), Sz))
254             return 0;
255
256         // Equal length and the pointers definitely don't alias, so it's safe to
257         // replace the call with memcpy
258         return EmitMemCpy(CI->getOperand(1), CI->getOperand(3), Size, 0, B);
259     }
260 };
261
262 // TODO: More optimizations! :)
263
264 } // end anonymous namespace.
265
266 //===----------------------------------------------------------------------===//
267 // SimplifyDRuntimeCalls Pass Implementation
268 //===----------------------------------------------------------------------===//
269
270 namespace {
271     /// This pass optimizes library functions from the D runtime as used by LDC.
272     ///
273     class VISIBILITY_HIDDEN SimplifyDRuntimeCalls : public FunctionPass {
274         StringMap<LibCallOptimization*> Optimizations;
275
276         // Array operations
277         ArraySetLengthOpt ArraySetLength;
278         ArrayCastLenOpt ArrayCastLen;
279         ArraySliceCopyOpt ArraySliceCopy;
280
281         // GC allocations
282         AllocationOpt Allocation;
283
284         public:
285         static char ID; // Pass identification
286         SimplifyDRuntimeCalls() : FunctionPass(&ID) {}
287
288         void InitOptimizations();
289         bool runOnFunction(Function &F);
290
291         bool runOnce(Function &F, const TargetData& TD, AliasAnalysis& AA);
292
293         virtual void getAnalysisUsage(AnalysisUsage &AU) const {
294           AU.addRequired<TargetData>();
295           AU.addRequired<AliasAnalysis>();
296         }
297     };
298     char SimplifyDRuntimeCalls::ID = 0;
299 } // end anonymous namespace.
300
301 static RegisterPass<SimplifyDRuntimeCalls>
302 X("simplify-drtcalls", "Simplify calls to D runtime");
303
304 // Public interface to the pass.
305 FunctionPass *createSimplifyDRuntimeCalls() {
306   return new SimplifyDRuntimeCalls();
307 }
308
309 /// Optimizations - Populate the Optimizations map with all the optimizations
310 /// we know.
311 void SimplifyDRuntimeCalls::InitOptimizations() {
312     // Some array-related optimizations
313     Optimizations["_d_arraysetlengthT"] = &ArraySetLength;
314     Optimizations["_d_arraysetlengthiT"] = &ArraySetLength;
315     Optimizations["_d_array_cast_len"] = &ArrayCastLen;
316     Optimizations["_d_array_slice_copy"] = &ArraySliceCopy;
317
318     /* Delete calls to runtime functions which aren't needed if their result is
319      * unused. That comes down to functions that don't do anything but
320      * GC-allocate and initialize some memory.
321      * We don't need to do this for functions which are marked 'readnone' or
322      * 'readonly', since LLVM doesn't need our help figuring out when those can
323      * be deleted.
324      * (We can't mark allocating calls as readonly/readnone because they don't
325      * return the same pointer every time when called with the same arguments)
326      */
327     Optimizations["_d_allocmemoryT"] = &Allocation;
328     Optimizations["_d_newarrayT"] = &Allocation;
329     Optimizations["_d_newarrayiT"] = &Allocation;
330     Optimizations["_d_newarrayvT"] = &Allocation;
331     Optimizations["_d_newarraymT"] = &Allocation;
332     Optimizations["_d_newarraymiT"] = &Allocation;
333     Optimizations["_d_newarraymvT"] = &Allocation;
334     Optimizations["_d_allocclass"] = &Allocation;
335 }
336
337
338 /// runOnFunction - Top level algorithm.
339 ///
340 bool SimplifyDRuntimeCalls::runOnFunction(Function &F) {
341     if (Optimizations.empty())
342         InitOptimizations();
343
344     const TargetData &TD = getAnalysis<TargetData>();
345     AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
346
347     // Iterate to catch opportunities opened up by other optimizations,
348     // such as calls that are only used as arguments to unused calls:
349     // When the second call gets deleted the first call will become unused, but
350     // without iteration we wouldn't notice if we inspected the first call
351     // before the second one.
352     bool EverChanged = false;
353     bool Changed;
354     do {
355         Changed = runOnce(F, TD, AA);
356         EverChanged |= Changed;
357     } while (Changed);
358
359     return EverChanged;
360 }
361
362 bool SimplifyDRuntimeCalls::runOnce(Function &F, const TargetData& TD, AliasAnalysis& AA) {
363     IRBuilder<> Builder(F.getContext());
364
365     bool Changed = false;
366     for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
367         for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
368             // Ignore non-calls.
369             CallInst *CI = dyn_cast<CallInst>(I++);
370             if (!CI) continue;
371
372             // Ignore indirect calls and calls to non-external functions.
373             Function *Callee = CI->getCalledFunction();
374             if (Callee == 0 || !Callee->isDeclaration() ||
375                     !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage()))
376                 continue;
377
378             // Ignore unknown calls.
379             StringMap<LibCallOptimization*>::iterator OMI =
380                 Optimizations.find(Callee->getName());
381             if (OMI == Optimizations.end()) continue;
382
383             DEBUG(errs() << "SimplifyDRuntimeCalls inspecting: " << *CI);
384
385             // Set the builder to the instruction after the call.
386             Builder.SetInsertPoint(BB, I);
387
388             // Try to optimize this call.
389             Value *Result = OMI->second->OptimizeCall(CI, Changed, TD, AA, Builder);
390             if (Result == 0) continue;
391
392             DEBUG(errs() << "SimplifyDRuntimeCalls simplified: " << *CI;
393                   errs() << "  into: " << *Result << "\n");
394
395             // Something changed!
396             Changed = true;
397
398             if (Result == CI) {
399                 assert(CI->use_empty());
400                 ++NumDeleted;
401                 AA.deleteValue(CI);
402             } else {
403                 ++NumSimplified;
404                 AA.replaceWithNewValue(CI, Result);
405
406                 if (!CI->use_empty())
407                     CI->replaceAllUsesWith(Result);
408
409                 if (!Result->hasName())
410                     Result->takeName(CI);
411             }
412
413             // Inspect the instruction after the call (which was potentially just
414             // added) next.
415             I = CI; ++I;
416
417             CI->eraseFromParent();
418         }
419     }
420     return Changed;
421 }
Note: See TracBrowser for help on using the browser.
Copyright © 2008, LDC Development Team.