aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2010-12-21 16:12:03 +0000
committerDuncan Sands <baldrick@free.fr>2010-12-21 16:12:03 +0000
commite95cc25a2267128436bb83af6cb57c07323c8693 (patch)
tree49934980f8391ed0c454647e8531867d93c5bf0d
parente1feeb9da41fd48002e363c6dbb0a3d7bf0b7811 (diff)
downloadexternal_llvm-e95cc25a2267128436bb83af6cb57c07323c8693.zip
external_llvm-e95cc25a2267128436bb83af6cb57c07323c8693.tar.gz
external_llvm-e95cc25a2267128436bb83af6cb57c07323c8693.tar.bz2
If an instruction simplifies, try again to simplify any uses of it. This is
not very important since the pass is only used for testing, but it does make it more realistic. Suggested by Frits van Bommel. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122336 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Utils/SimplifyInstructions.cpp36
1 files changed, 32 insertions, 4 deletions
diff --git a/lib/Transforms/Utils/SimplifyInstructions.cpp b/lib/Transforms/Utils/SimplifyInstructions.cpp
index 548bc51..6074a5f 100644
--- a/lib/Transforms/Utils/SimplifyInstructions.cpp
+++ b/lib/Transforms/Utils/SimplifyInstructions.cpp
@@ -23,6 +23,7 @@
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/Local.h"
using namespace llvm;
STATISTIC(NumSimplified, "Number of redundant instructions removed");
@@ -40,19 +41,46 @@ namespace {
/// runOnFunction - Remove instructions that simplify.
bool runOnFunction(Function &F) {
- bool Changed = false;
const TargetData *TD = getAnalysisIfAvailable<TargetData>();
const DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>();
+ bool Changed = false;
+
+ // Add all interesting instructions to the worklist.
+ std::set<Instruction*> Worklist;
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
Instruction *I = BI++;
- if (Value *V = SimplifyInstruction(I, TD, DT)) {
- I->replaceAllUsesWith(V);
+ // Zap any dead instructions.
+ if (isInstructionTriviallyDead(I)) {
I->eraseFromParent();
Changed = true;
- ++NumSimplified;
+ continue;
}
+ // Add all others to the worklist.
+ Worklist.insert(I);
}
+
+ // Simplify everything in the worklist until the cows come home.
+ while (!Worklist.empty()) {
+ Instruction *I = *Worklist.begin();
+ Worklist.erase(Worklist.begin());
+ Value *V = SimplifyInstruction(I, TD, DT);
+ if (!V) continue;
+
+ // This instruction simplifies! Replace it with its simplification and
+ // add all uses to the worklist, since they may now simplify.
+ I->replaceAllUsesWith(V);
+ for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
+ UI != UE; ++UI)
+ // In unreachable code an instruction can use itself, in which case
+ // don't add it to the worklist since we are about to erase it.
+ if (*UI != I) Worklist.insert(cast<Instruction>(*UI));
+ if (isInstructionTriviallyDead(I))
+ I->eraseFromParent();
+ ++NumSimplified;
+ Changed = true;
+ }
+
return Changed;
}
};