Add code pulled out of TransformInternals.cpp, ConstProp.cpp, and DCE.cpp

llvm-svn: 2513
This commit is contained in:
Chris Lattner 2002-05-07 18:07:59 +00:00
parent d66a6e33e9
commit 28537dff72
3 changed files with 196 additions and 0 deletions

View File

@ -0,0 +1,79 @@
//===-- BasicBlockUtils.cpp - BasicBlock Utilities -------------------------==//
//
// This family of functions perform manipulations on basic blocks, and
// instructions contained within basic blocks.
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Function.h"
#include "llvm/Instruction.h"
#include <algorithm>
// ReplaceInstWithValue - Replace all uses of an instruction (specified by BI)
// with a value, then remove and delete the original instruction.
//
void ReplaceInstWithValue(BasicBlock::InstListType &BIL,
BasicBlock::iterator &BI, Value *V) {
Instruction *I = *BI;
// Replaces all of the uses of the instruction with uses of the value
I->replaceAllUsesWith(V);
// Remove the unneccesary instruction now...
BIL.remove(BI);
// Make sure to propogate a name if there is one already...
if (I->hasName() && !V->hasName())
V->setName(I->getName(), BIL.getParent()->getSymbolTable());
// Remove the dead instruction now...
delete I;
}
// ReplaceInstWithInst - Replace the instruction specified by BI with the
// instruction specified by I. The original instruction is deleted and BI is
// updated to point to the new instruction.
//
void ReplaceInstWithInst(BasicBlock::InstListType &BIL,
BasicBlock::iterator &BI, Instruction *I) {
assert(I->getParent() == 0 &&
"ReplaceInstWithInst: Instruction already inserted into basic block!");
// Insert the new instruction into the basic block...
BI = BIL.insert(BI, I)+1; // Increment BI to point to instruction to delete
// Replace all uses of the old instruction, and delete it.
ReplaceInstWithValue(BIL, BI, I);
// Move BI back to point to the newly inserted instruction
--BI;
}
// ReplaceInstWithInst - Replace the instruction specified by From with the
// instruction specified by To. Note that this is slower than providing an
// iterator directly, because the basic block containing From must be searched
// for the instruction.
//
void ReplaceInstWithInst(Instruction *From, Instruction *To) {
BasicBlock *BB = From->getParent();
BasicBlock::InstListType &BIL = BB->getInstList();
BasicBlock::iterator BI = find(BIL.begin(), BIL.end(), From);
assert(BI != BIL.end() && "Inst not in it's parents BB!");
ReplaceInstWithInst(BIL, BI, To);
}
// InsertInstBeforeInst - Insert 'NewInst' into the basic block that 'Existing'
// is already in, and put it right before 'Existing'. This instruction should
// only be used when there is no iterator to Existing already around. The
// returned iterator points to the new instruction.
//
BasicBlock::iterator InsertInstBeforeInst(Instruction *NewInst,
Instruction *Existing) {
BasicBlock *BB = Existing->getParent();
BasicBlock::InstListType &BIL = BB->getInstList();
BasicBlock::iterator BI = find(BIL.begin(), BIL.end(), Existing);
assert(BI != BIL.end() && "Inst not in it's parents BB!");
return BIL.insert(BI, NewInst);
}

View File

@ -0,0 +1,111 @@
//===-- Local.cpp - Functions to perform local transformations ------------===//
//
// This family of functions perform various local transformations to the
// program.
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/iTerminators.h"
#include "llvm/ConstantHandling.h"
//===----------------------------------------------------------------------===//
// Local constant propogation...
//
// ConstantFoldInstruction - If an instruction references constants, try to fold
// them together...
//
bool doConstantPropogation(BasicBlock *BB, BasicBlock::iterator &II) {
Instruction *Inst = *II;
if (Constant *C = ConstantFoldInstruction(Inst)) {
// Replaces all of the uses of a variable with uses of the constant.
Inst->replaceAllUsesWith(C);
// Remove the instruction from the basic block...
delete BB->getInstList().remove(II);
return true;
}
return false;
}
// ConstantFoldTerminator - If a terminator instruction is predicated on a
// constant value, convert it into an unconditional branch to the constant
// destination.
//
bool ConstantFoldTerminator(BasicBlock *BB, BasicBlock::iterator &II,
TerminatorInst *T) {
// Branch - See if we are conditional jumping on constant
if (BranchInst *BI = dyn_cast<BranchInst>(T)) {
if (BI->isUnconditional()) return false; // Can't optimize uncond branch
BasicBlock *Dest1 = cast<BasicBlock>(BI->getOperand(0));
BasicBlock *Dest2 = cast<BasicBlock>(BI->getOperand(1));
if (ConstantBool *Cond = dyn_cast<ConstantBool>(BI->getCondition())) {
// Are we branching on constant?
// YES. Change to unconditional branch...
BasicBlock *Destination = Cond->getValue() ? Dest1 : Dest2;
BasicBlock *OldDest = Cond->getValue() ? Dest2 : Dest1;
//cerr << "Function: " << T->getParent()->getParent()
// << "\nRemoving branch from " << T->getParent()
// << "\n\nTo: " << OldDest << endl;
// Let the basic block know that we are letting go of it. Based on this,
// it will adjust it's PHI nodes.
assert(BI->getParent() && "Terminator not inserted in block!");
OldDest->removePredecessor(BI->getParent());
// Set the unconditional destination, and change the insn to be an
// unconditional branch.
BI->setUnconditionalDest(Destination);
II = BB->end()-1; // Update instruction iterator!
return true;
}
#if 0
// FIXME: TODO: This doesn't work if the destination has PHI nodes with
// different incoming values on each branch!
//
else if (Dest2 == Dest1) { // Conditional branch to same location?
// This branch matches something like this:
// br bool %cond, label %Dest, label %Dest
// and changes it into: br label %Dest
// Let the basic block know that we are letting go of one copy of it.
assert(BI->getParent() && "Terminator not inserted in block!");
Dest1->removePredecessor(BI->getParent());
// Change a conditional branch to unconditional.
BI->setUnconditionalDest(Dest1);
return true;
}
#endif
}
return false;
}
//===----------------------------------------------------------------------===//
// Local dead code elimination...
//
bool isInstructionTriviallyDead(Instruction *I) {
return I->use_empty() && !I->hasSideEffects() && !isa<TerminatorInst>(I);
}
// dceInstruction - Inspect the instruction at *BBI and figure out if it's
// [trivially] dead. If so, remove the instruction and update the iterator
// to point to the instruction that immediately succeeded the original
// instruction.
//
bool dceInstruction(BasicBlock::InstListType &BBIL,
BasicBlock::iterator &BBI) {
// Look for un"used" definitions...
if (isInstructionTriviallyDead(*BBI)) {
delete BBIL.remove(BBI); // Bye bye
return true;
}
return false;
}

View File

@ -0,0 +1,6 @@
LEVEL = ../../..
LIBRARYNAME = transformutils
include $(LEVEL)/Makefile.common