Some tweaks to -simplify-drtcalls.

This commit is contained in:
Frits van Bommel
2009-05-09 02:34:27 +02:00
parent 039edd5cd4
commit 634d623b34

View File

@@ -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 @@ struct VISIBILITY_HIDDEN ArraySetLengthOpt : public LibCallOptimization {
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 @@ namespace {
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 @@ bool SimplifyDRuntimeCalls::runOnFunction(Function &F) {
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 @@ bool SimplifyDRuntimeCalls::runOnFunction(Function &F) {
// 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();
}
}