mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-04 06:09:05 +00:00
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
This commit is contained in:
parent
e1feeb9da4
commit
e95cc25a22
@ -23,6 +23,7 @@
|
|||||||
#include "llvm/Analysis/InstructionSimplify.h"
|
#include "llvm/Analysis/InstructionSimplify.h"
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
#include "llvm/Transforms/Scalar.h"
|
#include "llvm/Transforms/Scalar.h"
|
||||||
|
#include "llvm/Transforms/Utils/Local.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
STATISTIC(NumSimplified, "Number of redundant instructions removed");
|
STATISTIC(NumSimplified, "Number of redundant instructions removed");
|
||||||
@ -40,19 +41,46 @@ namespace {
|
|||||||
|
|
||||||
/// runOnFunction - Remove instructions that simplify.
|
/// runOnFunction - Remove instructions that simplify.
|
||||||
bool runOnFunction(Function &F) {
|
bool runOnFunction(Function &F) {
|
||||||
bool Changed = false;
|
|
||||||
const TargetData *TD = getAnalysisIfAvailable<TargetData>();
|
const TargetData *TD = getAnalysisIfAvailable<TargetData>();
|
||||||
const DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>();
|
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 (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
|
||||||
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
|
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
|
||||||
Instruction *I = BI++;
|
Instruction *I = BI++;
|
||||||
if (Value *V = SimplifyInstruction(I, TD, DT)) {
|
// Zap any dead instructions.
|
||||||
I->replaceAllUsesWith(V);
|
if (isInstructionTriviallyDead(I)) {
|
||||||
I->eraseFromParent();
|
I->eraseFromParent();
|
||||||
Changed = true;
|
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;
|
return Changed;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user