mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-23 14:25:07 +00:00
Fix bug: test/Regression/Transforms/ADCE/2002-01-31-UseStuckAround.ll
Cleanup code a lot git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2547 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1,12 +1,13 @@
|
|||||||
//===- ADCE.cpp - Code to perform agressive dead code elimination ---------===//
|
//===- ADCE.cpp - Code to perform aggressive dead code elimination --------===//
|
||||||
//
|
//
|
||||||
// This file implements "agressive" dead code elimination. ADCE is DCe where
|
// This file implements "aggressive" dead code elimination. ADCE is DCe where
|
||||||
// values are assumed to be dead until proven otherwise. This is similar to
|
// values are assumed to be dead until proven otherwise. This is similar to
|
||||||
// SCCP, except applied to the liveness of values.
|
// SCCP, except applied to the liveness of values.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/Transforms/Scalar.h"
|
#include "llvm/Transforms/Scalar.h"
|
||||||
|
#include "llvm/Transforms/Utils/Local.h"
|
||||||
#include "llvm/Type.h"
|
#include "llvm/Type.h"
|
||||||
#include "llvm/Analysis/Dominators.h"
|
#include "llvm/Analysis/Dominators.h"
|
||||||
#include "llvm/Analysis/Writer.h"
|
#include "llvm/Analysis/Writer.h"
|
||||||
@@ -26,7 +27,7 @@ namespace {
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// ADCE Class
|
// ADCE Class
|
||||||
//
|
//
|
||||||
// This class does all of the work of Agressive Dead Code Elimination.
|
// This class does all of the work of Aggressive Dead Code Elimination.
|
||||||
// It's public interface consists of a constructor and a doADCE() method.
|
// It's public interface consists of a constructor and a doADCE() method.
|
||||||
//
|
//
|
||||||
class ADCE : public FunctionPass {
|
class ADCE : public FunctionPass {
|
||||||
@@ -41,7 +42,7 @@ class ADCE : public FunctionPass {
|
|||||||
public:
|
public:
|
||||||
const char *getPassName() const { return "Aggressive Dead Code Elimination"; }
|
const char *getPassName() const { return "Aggressive Dead Code Elimination"; }
|
||||||
|
|
||||||
// doADCE - Execute the Agressive Dead Code Elimination Algorithm
|
// doADCE - Execute the Aggressive Dead Code Elimination Algorithm
|
||||||
//
|
//
|
||||||
virtual bool runOnFunction(Function *F) {
|
virtual bool runOnFunction(Function *F) {
|
||||||
Func = F; MadeChanges = false;
|
Func = F; MadeChanges = false;
|
||||||
@@ -61,7 +62,7 @@ public:
|
|||||||
// The implementation of this class
|
// The implementation of this class
|
||||||
//
|
//
|
||||||
private:
|
private:
|
||||||
// doADCE() - Run the Agressive Dead Code Elimination algorithm, returning
|
// doADCE() - Run the Aggressive Dead Code Elimination algorithm, returning
|
||||||
// true if the function was modified.
|
// true if the function was modified.
|
||||||
//
|
//
|
||||||
void doADCE(DominanceFrontier &CDG);
|
void doADCE(DominanceFrontier &CDG);
|
||||||
@@ -91,12 +92,12 @@ private:
|
|||||||
|
|
||||||
} // End of anonymous namespace
|
} // End of anonymous namespace
|
||||||
|
|
||||||
Pass *createAgressiveDCEPass() {
|
Pass *createAggressiveDCEPass() {
|
||||||
return new ADCE();
|
return new ADCE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// doADCE() - Run the Agressive Dead Code Elimination algorithm, returning
|
// doADCE() - Run the Aggressive Dead Code Elimination algorithm, returning
|
||||||
// true if the function was modified.
|
// true if the function was modified.
|
||||||
//
|
//
|
||||||
void ADCE::doADCE(DominanceFrontier &CDG) {
|
void ADCE::doADCE(DominanceFrontier &CDG) {
|
||||||
@@ -118,17 +119,14 @@ void ADCE::doADCE(DominanceFrontier &CDG) {
|
|||||||
|
|
||||||
if (I->hasSideEffects() || I->getOpcode() == Instruction::Ret) {
|
if (I->hasSideEffects() || I->getOpcode() == Instruction::Ret) {
|
||||||
markInstructionLive(I);
|
markInstructionLive(I);
|
||||||
|
++II; // Increment the inst iterator if the inst wasn't deleted
|
||||||
|
} else if (isInstructionTriviallyDead(I)) {
|
||||||
|
// Remove the instruction from it's basic block...
|
||||||
|
delete BB->getInstList().remove(II);
|
||||||
|
MadeChanges = true;
|
||||||
} else {
|
} else {
|
||||||
// Check to see if anything is trivially dead
|
++II; // Increment the inst iterator if the inst wasn't deleted
|
||||||
if (I->use_size() == 0 && I->getType() != Type::VoidTy) {
|
|
||||||
// Remove the instruction from it's basic block...
|
|
||||||
delete BB->getInstList().remove(II);
|
|
||||||
MadeChanges = true;
|
|
||||||
continue; // Don't increment the iterator past the current slot
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
++II; // Increment the inst iterator if the inst wasn't deleted
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,10 +168,9 @@ void ADCE::doADCE(DominanceFrontier &CDG) {
|
|||||||
// Loop over all of the operands of the live instruction, making sure that
|
// Loop over all of the operands of the live instruction, making sure that
|
||||||
// they are known to be alive as well...
|
// they are known to be alive as well...
|
||||||
//
|
//
|
||||||
for (unsigned op = 0, End = I->getNumOperands(); op != End; ++op) {
|
for (unsigned op = 0, End = I->getNumOperands(); op != End; ++op)
|
||||||
if (Instruction *Operand = dyn_cast<Instruction>(I->getOperand(op)))
|
if (Instruction *Operand = dyn_cast<Instruction>(I->getOperand(op)))
|
||||||
markInstructionLive(Operand);
|
markInstructionLive(Operand);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_ADCE
|
#ifdef DEBUG_ADCE
|
||||||
@@ -192,30 +189,20 @@ void ADCE::doADCE(DominanceFrontier &CDG) {
|
|||||||
std::set<BasicBlock*> VisitedBlocks;
|
std::set<BasicBlock*> VisitedBlocks;
|
||||||
BasicBlock *EntryBlock = fixupCFG(Func->front(), VisitedBlocks, AliveBlocks);
|
BasicBlock *EntryBlock = fixupCFG(Func->front(), VisitedBlocks, AliveBlocks);
|
||||||
if (EntryBlock && EntryBlock != Func->front()) {
|
if (EntryBlock && EntryBlock != Func->front()) {
|
||||||
if (isa<PHINode>(EntryBlock->front())) {
|
// We need to move the new entry block to be the first bb of the function
|
||||||
// Cannot make the first block be a block with a PHI node in it! Instead,
|
Function::iterator EBI = find(Func->begin(), Func->end(), EntryBlock);
|
||||||
// strip the first basic block of the function to contain no instructions,
|
std::swap(*EBI, *Func->begin()); // Exchange old location with start of fn
|
||||||
// then add a simple branch to the "real" entry node...
|
|
||||||
|
while (PHINode *PN = dyn_cast<PHINode>(EntryBlock->front())) {
|
||||||
|
assert(PN->getNumIncomingValues() == 1 &&
|
||||||
|
"Can only have a single incoming value at this point...");
|
||||||
|
// The incoming value must be outside of the scope of the function, a
|
||||||
|
// global variable, constant or parameter maybe...
|
||||||
//
|
//
|
||||||
BasicBlock *E = Func->front();
|
PN->replaceAllUsesWith(PN->getIncomingValue(0));
|
||||||
if (!isa<TerminatorInst>(E->front()) || // Check for an actual change...
|
|
||||||
cast<TerminatorInst>(E->front())->getNumSuccessors() != 1 ||
|
|
||||||
cast<TerminatorInst>(E->front())->getSuccessor(0) != EntryBlock) {
|
|
||||||
E->getInstList().delete_all(); // Delete all instructions in block
|
|
||||||
E->getInstList().push_back(new BranchInst(EntryBlock));
|
|
||||||
MadeChanges = true;
|
|
||||||
}
|
|
||||||
AliveBlocks.insert(E);
|
|
||||||
|
|
||||||
// Next we need to change any PHI nodes in the entry block to refer to the
|
// Nuke the phi node...
|
||||||
// new predecessor node...
|
delete EntryBlock->getInstList().remove(EntryBlock->begin());
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// We need to move the new entry block to be the first bb of the function
|
|
||||||
Function::iterator EBI = find(Func->begin(), Func->end(), EntryBlock);
|
|
||||||
std::swap(*EBI, *Func->begin()); // Exchange old location with start of fn
|
|
||||||
MadeChanges = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,16 +258,14 @@ BasicBlock *ADCE::fixupCFG(BasicBlock *BB, std::set<BasicBlock*> &VisitedBlocks,
|
|||||||
|
|
||||||
if (AliveBlocks.count(BB)) { // Is the block alive?
|
if (AliveBlocks.count(BB)) { // Is the block alive?
|
||||||
// Yes it's alive: loop through and eliminate all dead instructions in block
|
// Yes it's alive: loop through and eliminate all dead instructions in block
|
||||||
for (BasicBlock::iterator II = BB->begin(); II != BB->end()-1; ) {
|
for (BasicBlock::iterator II = BB->begin(); II != BB->end()-1; )
|
||||||
Instruction *I = *II;
|
if (!LiveSet.count(*II)) { // Is this instruction alive?
|
||||||
if (!LiveSet.count(I)) { // Is this instruction alive?
|
|
||||||
// Nope... remove the instruction from it's basic block...
|
// Nope... remove the instruction from it's basic block...
|
||||||
delete BB->getInstList().remove(II);
|
delete BB->getInstList().remove(II);
|
||||||
MadeChanges = true;
|
MadeChanges = true;
|
||||||
continue; // Don't increment II
|
} else {
|
||||||
|
++II;
|
||||||
}
|
}
|
||||||
++II;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recursively traverse successors of this basic block.
|
// Recursively traverse successors of this basic block.
|
||||||
for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI) {
|
for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI) {
|
||||||
|
Reference in New Issue
Block a user