comparison 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
comparison
equal deleted inserted replaced
1318:bac742d3a72d 1319:c32e27f9a61d
27 #include "llvm/Support/Compiler.h" 27 #include "llvm/Support/Compiler.h"
28 #include "llvm/Support/Debug.h" 28 #include "llvm/Support/Debug.h"
29 using namespace llvm; 29 using namespace llvm;
30 30
31 STATISTIC(NumSimplified, "Number of runtime calls simplified"); 31 STATISTIC(NumSimplified, "Number of runtime calls simplified");
32 STATISTIC(NumDeleted, "Number of runtime calls deleted");
32 33
33 //===----------------------------------------------------------------------===// 34 //===----------------------------------------------------------------------===//
34 // Optimizer Base Class 35 // Optimizer Base Class
35 //===----------------------------------------------------------------------===// 36 //===----------------------------------------------------------------------===//
36 37
77 if (Callee->arg_size() != 4 || !isa<PointerType>(FT->getReturnType()) || 78 if (Callee->arg_size() != 4 || !isa<PointerType>(FT->getReturnType()) ||
78 !isa<IntegerType>(FT->getParamType(1)) || 79 !isa<IntegerType>(FT->getParamType(1)) ||
79 FT->getParamType(1) != FT->getParamType(2) || 80 FT->getParamType(1) != FT->getParamType(2) ||
80 FT->getParamType(3) != FT->getReturnType()) 81 FT->getParamType(3) != FT->getReturnType())
81 return 0; 82 return 0;
83
84 // Whether or not this allocates is irrelevant if the result isn't used.
85 // Just delete if that's the case.
86 if (CI->use_empty())
87 return CI;
82 88
83 Value* NewLen = CI->getOperand(2); 89 Value* NewLen = CI->getOperand(2);
84 if (Constant* NewCst = dyn_cast<Constant>(NewLen)) { 90 if (Constant* NewCst = dyn_cast<Constant>(NewLen)) {
85 Value* Data = CI->getOperand(4); 91 Value* Data = CI->getOperand(4);
86 92
180 SimplifyDRuntimeCalls() : FunctionPass(&ID) {} 186 SimplifyDRuntimeCalls() : FunctionPass(&ID) {}
181 187
182 void InitOptimizations(); 188 void InitOptimizations();
183 bool runOnFunction(Function &F); 189 bool runOnFunction(Function &F);
184 190
191 bool runOnce(Function &F, const TargetData& TD);
192
185 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 193 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
186 AU.addRequired<TargetData>(); 194 AU.addRequired<TargetData>();
187 } 195 }
188 }; 196 };
189 char SimplifyDRuntimeCalls::ID = 0; 197 char SimplifyDRuntimeCalls::ID = 0;
231 if (Optimizations.empty()) 239 if (Optimizations.empty())
232 InitOptimizations(); 240 InitOptimizations();
233 241
234 const TargetData &TD = getAnalysis<TargetData>(); 242 const TargetData &TD = getAnalysis<TargetData>();
235 243
244 // Iterate to catch opportunities opened up by other optimizations,
245 // such as calls that are only used as arguments to unused calls:
246 // When the second call gets deleted the first call will become unused, but
247 // without iteration we wouldn't notice if we inspected the first call
248 // before the second one.
249 bool EverChanged = false;
250 bool Changed;
251 do {
252 Changed = runOnce(F, TD);
253 EverChanged |= Changed;
254 } while (Changed);
255
256 return EverChanged;
257 }
258
259 bool SimplifyDRuntimeCalls::runOnce(Function &F, const TargetData& TD) {
236 IRBuilder<> Builder; 260 IRBuilder<> Builder;
237 261
238 bool Changed = false; 262 bool Changed = false;
239 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { 263 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
240 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { 264 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
266 DEBUG(DOUT << "SimplifyDRuntimeCalls simplified: " << *CI; 290 DEBUG(DOUT << "SimplifyDRuntimeCalls simplified: " << *CI;
267 DOUT << " into: " << *Result << "\n"); 291 DOUT << " into: " << *Result << "\n");
268 292
269 // Something changed! 293 // Something changed!
270 Changed = true; 294 Changed = true;
271 ++NumSimplified; 295
296 if (Result == CI) {
297 assert(CI->use_empty());
298 ++NumDeleted;
299 } else {
300 ++NumSimplified;
301
302 if (!CI->use_empty())
303 CI->replaceAllUsesWith(Result);
304
305 if (!Result->hasName())
306 Result->takeName(CI);
307 }
272 308
273 // Inspect the instruction after the call (which was potentially just 309 // Inspect the instruction after the call (which was potentially just
274 // added) next. 310 // added) next.
275 I = CI; ++I; 311 I = CI; ++I;
276 312
277 if (CI != Result && !CI->use_empty()) {
278 CI->replaceAllUsesWith(Result);
279 if (!Result->hasName())
280 Result->takeName(CI);
281 }
282 CI->eraseFromParent(); 313 CI->eraseFromParent();
283 } 314 }
284 } 315 }
285 return Changed; 316 return Changed;
286 } 317 }