Mercurial > projects > ldc
changeset 1319:c32e27f9a61d
Some tweaks to -simplify-drtcalls.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Sat, 09 May 2009 02:34:27 +0200 |
parents | bac742d3a72d |
children | d55945bcb02d |
files | gen/passes/SimplifyDRuntimeCalls.cpp |
diffstat | 1 files changed, 37 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- 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<Constant>(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<TargetData>(); } @@ -233,6 +241,22 @@ const TargetData &TD = getAnalysis<TargetData>(); + // 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(); } }