comparison gen/passes/SimplifyDRuntimeCalls.cpp @ 1650:40bd4a0d4870

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.
author Tomas Lindquist Olsen
date Wed, 19 May 2010 12:42:32 +0200
parents 8d086d552909
children
comparison
equal deleted inserted replaced
1649:36da40ecbbe0 1650:40bd4a0d4870
16 16
17 #define DEBUG_TYPE "simplify-drtcalls" 17 #define DEBUG_TYPE "simplify-drtcalls"
18 18
19 #include "Passes.h" 19 #include "Passes.h"
20 20
21 #include "llvm/Function.h"
21 #include "llvm/Pass.h" 22 #include "llvm/Pass.h"
22 #include "llvm/Intrinsics.h" 23 #include "llvm/Intrinsics.h"
23 #include "llvm/Support/IRBuilder.h" 24 #include "llvm/Support/IRBuilder.h"
24 #include "llvm/Analysis/AliasAnalysis.h" 25 #include "llvm/Analysis/AliasAnalysis.h"
25 #include "llvm/Analysis/ValueTracking.h" 26 #include "llvm/Analysis/ValueTracking.h"
46 Function *Caller; 47 Function *Caller;
47 bool* Changed; 48 bool* Changed;
48 const TargetData *TD; 49 const TargetData *TD;
49 AliasAnalysis *AA; 50 AliasAnalysis *AA;
50 LLVMContext *Context; 51 LLVMContext *Context;
51 52
52 /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*. 53 /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
53 Value *CastToCStr(Value *V, IRBuilder<> &B); 54 Value *CastToCStr(Value *V, IRBuilder<> &B);
54 55
55 /// EmitMemCpy - Emit a call to the memcpy function to the builder. This 56 /// EmitMemCpy - Emit a call to the memcpy function to the builder. This
56 /// always expects that the size has type 'intptr_t' and Dst/Src are pointers. 57 /// always expects that the size has type 'intptr_t' and Dst/Src are pointers.
57 Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len, 58 Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len,
58 unsigned Align, IRBuilder<> &B); 59 unsigned Align, IRBuilder<> &B);
59 public: 60 public:
60 LibCallOptimization() { } 61 LibCallOptimization() { }
61 virtual ~LibCallOptimization() {} 62 virtual ~LibCallOptimization() {}
62 63
63 /// CallOptimizer - This pure virtual method is implemented by base classes to 64 /// CallOptimizer - This pure virtual method is implemented by base classes to
64 /// do various optimizations. If this returns null then no transformation was 65 /// do various optimizations. If this returns null then no transformation was
65 /// performed. If it returns CI, then it transformed the call and CI is to be 66 /// performed. If it returns CI, then it transformed the call and CI is to be
66 /// deleted. If it returns something else, replace CI with the new value and 67 /// deleted. If it returns something else, replace CI with the new value and
67 /// delete CI. 68 /// delete CI.
68 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)=0; 69 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)=0;
69 70
70 Value *OptimizeCall(CallInst *CI, bool& Changed, const TargetData &TD, 71 Value *OptimizeCall(CallInst *CI, bool& Changed, const TargetData &TD,
71 AliasAnalysis& AA, IRBuilder<> &B) { 72 AliasAnalysis& AA, IRBuilder<> &B) {
72 Caller = CI->getParent()->getParent(); 73 Caller = CI->getParent()->getParent();
73 this->Changed = &Changed; 74 this->Changed = &Changed;
74 this->TD = &TD; 75 this->TD = &TD;
114 if (Callee->arg_size() != 4 || !isa<PointerType>(FT->getReturnType()) || 115 if (Callee->arg_size() != 4 || !isa<PointerType>(FT->getReturnType()) ||
115 !isa<IntegerType>(FT->getParamType(1)) || 116 !isa<IntegerType>(FT->getParamType(1)) ||
116 FT->getParamType(1) != FT->getParamType(2) || 117 FT->getParamType(1) != FT->getParamType(2) ||
117 FT->getParamType(3) != FT->getReturnType()) 118 FT->getParamType(3) != FT->getReturnType())
118 return 0; 119 return 0;
119 120
120 // Whether or not this allocates is irrelevant if the result isn't used. 121 // Whether or not this allocates is irrelevant if the result isn't used.
121 // Just delete if that's the case. 122 // Just delete if that's the case.
122 if (CI->use_empty()) 123 if (CI->use_empty())
123 return CI; 124 return CI;
124 125
125 Value* NewLen = CI->getOperand(2); 126 Value* NewLen = CI->getOperand(2);
126 if (Constant* NewCst = dyn_cast<Constant>(NewLen)) { 127 if (Constant* NewCst = dyn_cast<Constant>(NewLen)) {
127 Value* Data = CI->getOperand(4); 128 Value* Data = CI->getOperand(4);
128 129
129 // For now, we just catch the simplest of cases. 130 // For now, we just catch the simplest of cases.
130 // 131 //
131 // TODO: Implement a more general way to compare old and new 132 // TODO: Implement a more general way to compare old and new
132 // lengths, to catch cases like "arr.length = arr.length - 1;" 133 // lengths, to catch cases like "arr.length = arr.length - 1;"
133 // (But beware of unsigned overflow! For example, we can't 134 // (But beware of unsigned overflow! For example, we can't
134 // safely transform that example if arr.length may be 0) 135 // safely transform that example if arr.length may be 0)
135 136
136 // Setting length to 0 never reallocates, so replace by data argument 137 // Setting length to 0 never reallocates, so replace by data argument
137 if (NewCst->isNullValue()) 138 if (NewCst->isNullValue())
138 return Data; 139 return Data;
139 140
140 // If both lengths are constant integers, see if NewLen <= OldLen 141 // If both lengths are constant integers, see if NewLen <= OldLen
141 Value* OldLen = CI->getOperand(3); 142 Value* OldLen = CI->getOperand(3);
142 if (ConstantInt* OldInt = dyn_cast<ConstantInt>(OldLen)) 143 if (ConstantInt* OldInt = dyn_cast<ConstantInt>(OldLen))
143 if (ConstantInt* NewInt = dyn_cast<ConstantInt>(NewCst)) 144 if (ConstantInt* NewInt = dyn_cast<ConstantInt>(NewCst))
144 if (NewInt->getValue().ule(OldInt->getValue())) 145 if (NewInt->getValue().ule(OldInt->getValue()))
155 const FunctionType *FT = Callee->getFunctionType(); 156 const FunctionType *FT = Callee->getFunctionType();
156 const Type* RetTy = FT->getReturnType(); 157 const Type* RetTy = FT->getReturnType();
157 if (Callee->arg_size() != 3 || !isa<IntegerType>(RetTy) || 158 if (Callee->arg_size() != 3 || !isa<IntegerType>(RetTy) ||
158 FT->getParamType(1) != RetTy || FT->getParamType(2) != RetTy) 159 FT->getParamType(1) != RetTy || FT->getParamType(2) != RetTy)
159 return 0; 160 return 0;
160 161
161 Value* OldLen = CI->getOperand(1); 162 Value* OldLen = CI->getOperand(1);
162 Value* OldSize = CI->getOperand(2); 163 Value* OldSize = CI->getOperand(2);
163 Value* NewSize = CI->getOperand(3); 164 Value* NewSize = CI->getOperand(3);
164 165
165 // If the old length was zero, always return zero. 166 // If the old length was zero, always return zero.
166 if (Constant* LenCst = dyn_cast<Constant>(OldLen)) 167 if (Constant* LenCst = dyn_cast<Constant>(OldLen))
167 if (LenCst->isNullValue()) 168 if (LenCst->isNullValue())
168 return OldLen; 169 return OldLen;
169 170
170 // Equal sizes are much faster to check for, so do so now. 171 // Equal sizes are much faster to check for, so do so now.
171 if (OldSize == NewSize) 172 if (OldSize == NewSize)
172 return OldLen; 173 return OldLen;
173 174
174 // If both sizes are constant integers, see if OldSize is a multiple of NewSize 175 // If both sizes are constant integers, see if OldSize is a multiple of NewSize
175 if (ConstantInt* OldInt = dyn_cast<ConstantInt>(OldSize)) 176 if (ConstantInt* OldInt = dyn_cast<ConstantInt>(OldSize))
176 if (ConstantInt* NewInt = dyn_cast<ConstantInt>(NewSize)) { 177 if (ConstantInt* NewInt = dyn_cast<ConstantInt>(NewSize)) {
177 // Don't crash on NewSize == 0, even though it shouldn't happen. 178 // Don't crash on NewSize == 0, even though it shouldn't happen.
178 if (NewInt->isNullValue()) 179 if (NewInt->isNullValue())
179 return 0; 180 return 0;
180 181
181 APInt Quot, Rem; 182 APInt Quot, Rem;
182 APInt::udivrem(OldInt->getValue(), NewInt->getValue(), Quot, Rem); 183 APInt::udivrem(OldInt->getValue(), NewInt->getValue(), Quot, Rem);
183 if (Rem == 0) 184 if (Rem == 0)
184 return B.CreateMul(OldLen, ConstantInt::get(*Context, Quot)); 185 return B.CreateMul(OldLen, ConstantInt::get(*Context, Quot));
185 } 186 }
193 // Allocations are never equal to constants, so remove any equality 194 // Allocations are never equal to constants, so remove any equality
194 // comparisons to constants. (Most importantly comparisons to null at 195 // comparisons to constants. (Most importantly comparisons to null at
195 // the start of inlined member functions) 196 // the start of inlined member functions)
196 for (CallInst::use_iterator I = CI->use_begin(), E = CI->use_end() ; I != E;) { 197 for (CallInst::use_iterator I = CI->use_begin(), E = CI->use_end() ; I != E;) {
197 Instruction* User = cast<Instruction>(*I++); 198 Instruction* User = cast<Instruction>(*I++);
198 199
199 if (ICmpInst* Cmp = dyn_cast<ICmpInst>(User)) { 200 if (ICmpInst* Cmp = dyn_cast<ICmpInst>(User)) {
200 if (!Cmp->isEquality()) 201 if (!Cmp->isEquality())
201 continue; 202 continue;
202 Constant* C = 0; 203 Constant* C = 0;
203 if ((C = dyn_cast<Constant>(Cmp->getOperand(0))) 204 if ((C = dyn_cast<Constant>(Cmp->getOperand(0)))
213 Cmp->setOperand(1, C); 214 Cmp->setOperand(1, C);
214 *Changed = true; 215 *Changed = true;
215 } 216 }
216 } 217 }
217 } 218 }
218 219
219 // If it's not used (anymore), pre-emptively GC it. 220 // If it's not used (anymore), pre-emptively GC it.
220 if (CI->use_empty()) 221 if (CI->use_empty())
221 return CI; 222 return CI;
222 return 0; 223 return 0;
223 } 224 }
233 FT->getParamType(0) != VoidPtrTy || 234 FT->getParamType(0) != VoidPtrTy ||
234 !isa<IntegerType>(FT->getParamType(1)) || 235 !isa<IntegerType>(FT->getParamType(1)) ||
235 FT->getParamType(2) != VoidPtrTy || 236 FT->getParamType(2) != VoidPtrTy ||
236 FT->getParamType(3) != FT->getParamType(1)) 237 FT->getParamType(3) != FT->getParamType(1))
237 return 0; 238 return 0;
238 239
239 Value* Size = CI->getOperand(2); 240 Value* Size = CI->getOperand(2);
240 241
241 // Check the lengths match 242 // Check the lengths match
242 if (CI->getOperand(4) != Size) 243 if (CI->getOperand(4) != Size)
243 return 0; 244 return 0;
244 245
245 // Assume unknown size unless we have constant size (that fits in an uint) 246 // Assume unknown size unless we have constant size (that fits in an uint)
246 unsigned Sz = ~0U; 247 unsigned Sz = ~0U;
247 if (ConstantInt* Int = dyn_cast<ConstantInt>(Size)) 248 if (ConstantInt* Int = dyn_cast<ConstantInt>(Size))
248 if (Int->getValue().isIntN(32)) 249 if (Int->getValue().isIntN(32))
249 Sz = Int->getValue().getZExtValue(); 250 Sz = Int->getValue().getZExtValue();
250 251
251 // Check if the pointers may alias 252 // Check if the pointers may alias
252 if (AA->alias(CI->getOperand(1), Sz, CI->getOperand(3), Sz)) 253 if (AA->alias(CI->getOperand(1), Sz, CI->getOperand(3), Sz))
253 return 0; 254 return 0;
254 255
255 // Equal length and the pointers definitely don't alias, so it's safe to 256 // Equal length and the pointers definitely don't alias, so it's safe to
256 // replace the call with memcpy 257 // replace the call with memcpy
257 return EmitMemCpy(CI->getOperand(1), CI->getOperand(3), Size, 0, B); 258 return EmitMemCpy(CI->getOperand(1), CI->getOperand(3), Size, 0, B);
258 } 259 }
259 }; 260 };
269 namespace { 270 namespace {
270 /// This pass optimizes library functions from the D runtime as used by LDC. 271 /// This pass optimizes library functions from the D runtime as used by LDC.
271 /// 272 ///
272 class VISIBILITY_HIDDEN SimplifyDRuntimeCalls : public FunctionPass { 273 class VISIBILITY_HIDDEN SimplifyDRuntimeCalls : public FunctionPass {
273 StringMap<LibCallOptimization*> Optimizations; 274 StringMap<LibCallOptimization*> Optimizations;
274 275
275 // Array operations 276 // Array operations
276 ArraySetLengthOpt ArraySetLength; 277 ArraySetLengthOpt ArraySetLength;
277 ArrayCastLenOpt ArrayCastLen; 278 ArrayCastLenOpt ArrayCastLen;
278 ArraySliceCopyOpt ArraySliceCopy; 279 ArraySliceCopyOpt ArraySliceCopy;
279 280
280 // GC allocations 281 // GC allocations
281 AllocationOpt Allocation; 282 AllocationOpt Allocation;
282 283
283 public: 284 public:
284 static char ID; // Pass identification 285 static char ID; // Pass identification
285 SimplifyDRuntimeCalls() : FunctionPass(&ID) {} 286 SimplifyDRuntimeCalls() : FunctionPass(&ID) {}
286 287
287 void InitOptimizations(); 288 void InitOptimizations();
288 bool runOnFunction(Function &F); 289 bool runOnFunction(Function &F);
289 290
290 bool runOnce(Function &F, const TargetData& TD, AliasAnalysis& AA); 291 bool runOnce(Function &F, const TargetData& TD, AliasAnalysis& AA);
291 292
292 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 293 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
293 AU.addRequired<TargetData>(); 294 AU.addRequired<TargetData>();
294 AU.addRequired<AliasAnalysis>(); 295 AU.addRequired<AliasAnalysis>();
295 } 296 }
296 }; 297 };
300 static RegisterPass<SimplifyDRuntimeCalls> 301 static RegisterPass<SimplifyDRuntimeCalls>
301 X("simplify-drtcalls", "Simplify calls to D runtime"); 302 X("simplify-drtcalls", "Simplify calls to D runtime");
302 303
303 // Public interface to the pass. 304 // Public interface to the pass.
304 FunctionPass *createSimplifyDRuntimeCalls() { 305 FunctionPass *createSimplifyDRuntimeCalls() {
305 return new SimplifyDRuntimeCalls(); 306 return new SimplifyDRuntimeCalls();
306 } 307 }
307 308
308 /// Optimizations - Populate the Optimizations map with all the optimizations 309 /// Optimizations - Populate the Optimizations map with all the optimizations
309 /// we know. 310 /// we know.
310 void SimplifyDRuntimeCalls::InitOptimizations() { 311 void SimplifyDRuntimeCalls::InitOptimizations() {
311 // Some array-related optimizations 312 // Some array-related optimizations
312 Optimizations["_d_arraysetlengthT"] = &ArraySetLength; 313 Optimizations["_d_arraysetlengthT"] = &ArraySetLength;
313 Optimizations["_d_arraysetlengthiT"] = &ArraySetLength; 314 Optimizations["_d_arraysetlengthiT"] = &ArraySetLength;
314 Optimizations["_d_array_cast_len"] = &ArrayCastLen; 315 Optimizations["_d_array_cast_len"] = &ArrayCastLen;
315 Optimizations["_d_array_slice_copy"] = &ArraySliceCopy; 316 Optimizations["_d_array_slice_copy"] = &ArraySliceCopy;
316 317
317 /* Delete calls to runtime functions which aren't needed if their result is 318 /* Delete calls to runtime functions which aren't needed if their result is
318 * unused. That comes down to functions that don't do anything but 319 * unused. That comes down to functions that don't do anything but
319 * GC-allocate and initialize some memory. 320 * GC-allocate and initialize some memory.
320 * We don't need to do this for functions which are marked 'readnone' or 321 * We don't need to do this for functions which are marked 'readnone' or
321 * 'readonly', since LLVM doesn't need our help figuring out when those can 322 * 'readonly', since LLVM doesn't need our help figuring out when those can
337 /// runOnFunction - Top level algorithm. 338 /// runOnFunction - Top level algorithm.
338 /// 339 ///
339 bool SimplifyDRuntimeCalls::runOnFunction(Function &F) { 340 bool SimplifyDRuntimeCalls::runOnFunction(Function &F) {
340 if (Optimizations.empty()) 341 if (Optimizations.empty())
341 InitOptimizations(); 342 InitOptimizations();
342 343
343 const TargetData &TD = getAnalysis<TargetData>(); 344 const TargetData &TD = getAnalysis<TargetData>();
344 AliasAnalysis &AA = getAnalysis<AliasAnalysis>(); 345 AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
345 346
346 // Iterate to catch opportunities opened up by other optimizations, 347 // Iterate to catch opportunities opened up by other optimizations,
347 // such as calls that are only used as arguments to unused calls: 348 // such as calls that are only used as arguments to unused calls:
348 // When the second call gets deleted the first call will become unused, but 349 // When the second call gets deleted the first call will become unused, but
349 // without iteration we wouldn't notice if we inspected the first call 350 // without iteration we wouldn't notice if we inspected the first call
350 // before the second one. 351 // before the second one.
352 bool Changed; 353 bool Changed;
353 do { 354 do {
354 Changed = runOnce(F, TD, AA); 355 Changed = runOnce(F, TD, AA);
355 EverChanged |= Changed; 356 EverChanged |= Changed;
356 } while (Changed); 357 } while (Changed);
357 358
358 return EverChanged; 359 return EverChanged;
359 } 360 }
360 361
361 bool SimplifyDRuntimeCalls::runOnce(Function &F, const TargetData& TD, AliasAnalysis& AA) { 362 bool SimplifyDRuntimeCalls::runOnce(Function &F, const TargetData& TD, AliasAnalysis& AA) {
362 IRBuilder<> Builder(F.getContext()); 363 IRBuilder<> Builder(F.getContext());
365 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { 366 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
366 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { 367 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
367 // Ignore non-calls. 368 // Ignore non-calls.
368 CallInst *CI = dyn_cast<CallInst>(I++); 369 CallInst *CI = dyn_cast<CallInst>(I++);
369 if (!CI) continue; 370 if (!CI) continue;
370 371
371 // Ignore indirect calls and calls to non-external functions. 372 // Ignore indirect calls and calls to non-external functions.
372 Function *Callee = CI->getCalledFunction(); 373 Function *Callee = CI->getCalledFunction();
373 if (Callee == 0 || !Callee->isDeclaration() || 374 if (Callee == 0 || !Callee->isDeclaration() ||
374 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage())) 375 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage()))
375 continue; 376 continue;
376 377
377 // Ignore unknown calls. 378 // Ignore unknown calls.
378 StringMap<LibCallOptimization*>::iterator OMI = 379 StringMap<LibCallOptimization*>::iterator OMI =
379 Optimizations.find(Callee->getName()); 380 Optimizations.find(Callee->getName());
380 if (OMI == Optimizations.end()) continue; 381 if (OMI == Optimizations.end()) continue;
381 382
382 DEBUG(errs() << "SimplifyDRuntimeCalls inspecting: " << *CI); 383 DEBUG(errs() << "SimplifyDRuntimeCalls inspecting: " << *CI);
383 384
384 // Set the builder to the instruction after the call. 385 // Set the builder to the instruction after the call.
385 Builder.SetInsertPoint(BB, I); 386 Builder.SetInsertPoint(BB, I);
386 387
387 // Try to optimize this call. 388 // Try to optimize this call.
388 Value *Result = OMI->second->OptimizeCall(CI, Changed, TD, AA, Builder); 389 Value *Result = OMI->second->OptimizeCall(CI, Changed, TD, AA, Builder);
389 if (Result == 0) continue; 390 if (Result == 0) continue;
390 391
391 DEBUG(errs() << "SimplifyDRuntimeCalls simplified: " << *CI; 392 DEBUG(errs() << "SimplifyDRuntimeCalls simplified: " << *CI;
392 errs() << " into: " << *Result << "\n"); 393 errs() << " into: " << *Result << "\n");
393 394
394 // Something changed! 395 // Something changed!
395 Changed = true; 396 Changed = true;
396 397
397 if (Result == CI) { 398 if (Result == CI) {
398 assert(CI->use_empty()); 399 assert(CI->use_empty());
399 ++NumDeleted; 400 ++NumDeleted;
400 AA.deleteValue(CI); 401 AA.deleteValue(CI);
401 } else { 402 } else {
402 ++NumSimplified; 403 ++NumSimplified;
403 AA.replaceWithNewValue(CI, Result); 404 AA.replaceWithNewValue(CI, Result);
404 405
405 if (!CI->use_empty()) 406 if (!CI->use_empty())
406 CI->replaceAllUsesWith(Result); 407 CI->replaceAllUsesWith(Result);
407 408
408 if (!Result->hasName()) 409 if (!Result->hasName())
409 Result->takeName(CI); 410 Result->takeName(CI);
410 } 411 }
411 412
412 // Inspect the instruction after the call (which was potentially just 413 // Inspect the instruction after the call (which was potentially just
413 // added) next. 414 // added) next.
414 I = CI; ++I; 415 I = CI; ++I;
415 416
416 CI->eraseFromParent(); 417 CI->eraseFromParent();
417 } 418 }
418 } 419 }
419 return Changed; 420 return Changed;
420 } 421 }