Mercurial > projects > ldc
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 } |