# HG changeset patch # User Frits van Bommel # Date 1241829267 -7200 # Node ID c32e27f9a61d002c8a69e528c45b373129dc9dd4 # Parent bac742d3a72db66d7af21f8d05ee49352e35a507 Some tweaks to -simplify-drtcalls. diff -r bac742d3a72d -r c32e27f9a61d gen/passes/SimplifyDRuntimeCalls.cpp --- a/gen/passes/SimplifyDRuntimeCalls.cpp Sat May 09 00:55:47 2009 +0200 +++ b/gen/passes/SimplifyDRuntimeCalls.cpp Sat May 09 02:34:27 2009 +0200 @@ -29,6 +29,7 @@ using namespace llvm; STATISTIC(NumSimplified, "Number of runtime calls simplified"); +STATISTIC(NumDeleted, "Number of runtime calls deleted"); //===----------------------------------------------------------------------===// // Optimizer Base Class @@ -80,6 +81,11 @@ FT->getParamType(3) != FT->getReturnType()) return 0; + // Whether or not this allocates is irrelevant if the result isn't used. + // Just delete if that's the case. + if (CI->use_empty()) + return CI; + Value* NewLen = CI->getOperand(2); if (Constant* NewCst = dyn_cast(NewLen)) { Value* Data = CI->getOperand(4); @@ -182,6 +188,8 @@ void InitOptimizations(); bool runOnFunction(Function &F); + bool runOnce(Function &F, const TargetData& TD); + virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); } @@ -233,6 +241,22 @@ const TargetData &TD = getAnalysis(); + // Iterate to catch opportunities opened up by other optimizations, + // such as calls that are only used as arguments to unused calls: + // When the second call gets deleted the first call will become unused, but + // without iteration we wouldn't notice if we inspected the first call + // before the second one. + bool EverChanged = false; + bool Changed; + do { + Changed = runOnce(F, TD); + EverChanged |= Changed; + } while (Changed); + + return EverChanged; +} + +bool SimplifyDRuntimeCalls::runOnce(Function &F, const TargetData& TD) { IRBuilder<> Builder; bool Changed = false; @@ -268,17 +292,24 @@ // Something changed! Changed = true; - ++NumSimplified; + + if (Result == CI) { + assert(CI->use_empty()); + ++NumDeleted; + } else { + ++NumSimplified; + + if (!CI->use_empty()) + CI->replaceAllUsesWith(Result); + + if (!Result->hasName()) + Result->takeName(CI); + } // Inspect the instruction after the call (which was potentially just // added) next. I = CI; ++I; - if (CI != Result && !CI->use_empty()) { - CI->replaceAllUsesWith(Result); - if (!Result->hasName()) - Result->takeName(CI); - } CI->eraseFromParent(); } }