mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-05 19:29:01 +00:00
Comment-ize the functions in GVNPRE.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37681 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
562ef78df2
commit
9cb56014ce
@ -42,7 +42,9 @@ using namespace llvm;
|
|||||||
// ValueTable Class
|
// ValueTable Class
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// This class holds the mapping between values and value numbers.
|
/// This class holds the mapping between values and value numbers. It is used
|
||||||
|
/// as an efficient mechanism to determine the expression-wise equivalence of
|
||||||
|
/// two values.
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class VISIBILITY_HIDDEN ValueTable {
|
class VISIBILITY_HIDDEN ValueTable {
|
||||||
@ -89,6 +91,8 @@ namespace {
|
|||||||
|
|
||||||
Expression::ExpressionOpcode getOpcode(BinaryOperator* BO);
|
Expression::ExpressionOpcode getOpcode(BinaryOperator* BO);
|
||||||
Expression::ExpressionOpcode getOpcode(CmpInst* C);
|
Expression::ExpressionOpcode getOpcode(CmpInst* C);
|
||||||
|
Expression create_expression(BinaryOperator* BO);
|
||||||
|
Expression create_expression(CmpInst* C);
|
||||||
public:
|
public:
|
||||||
ValueTable() { nextValueNumber = 1; }
|
ValueTable() { nextValueNumber = 1; }
|
||||||
uint32_t lookup_or_add(Value* V);
|
uint32_t lookup_or_add(Value* V);
|
||||||
@ -100,14 +104,15 @@ namespace {
|
|||||||
|
|
||||||
}
|
}
|
||||||
std::set<Value*>& getMaximalValues() { return maximalValues; }
|
std::set<Value*>& getMaximalValues() { return maximalValues; }
|
||||||
Expression create_expression(BinaryOperator* BO);
|
|
||||||
Expression create_expression(CmpInst* C);
|
|
||||||
void erase(Value* v);
|
void erase(Value* v);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// ValueTable Internal Functions
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
ValueTable::Expression::ExpressionOpcode
|
ValueTable::Expression::ExpressionOpcode
|
||||||
ValueTable::getOpcode(BinaryOperator* BO) {
|
ValueTable::getOpcode(BinaryOperator* BO) {
|
||||||
switch(BO->getOpcode()) {
|
switch(BO->getOpcode()) {
|
||||||
case Instruction::Add:
|
case Instruction::Add:
|
||||||
return Expression::ADD;
|
return Expression::ADD;
|
||||||
@ -215,6 +220,36 @@ ValueTable::Expression::ExpressionOpcode ValueTable::getOpcode(CmpInst* C) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ValueTable::Expression ValueTable::create_expression(BinaryOperator* BO) {
|
||||||
|
Expression e;
|
||||||
|
|
||||||
|
e.leftVN = lookup_or_add(BO->getOperand(0));
|
||||||
|
e.rightVN = lookup_or_add(BO->getOperand(1));
|
||||||
|
e.opcode = getOpcode(BO);
|
||||||
|
|
||||||
|
maximalExpressions.insert(e);
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueTable::Expression ValueTable::create_expression(CmpInst* C) {
|
||||||
|
Expression e;
|
||||||
|
|
||||||
|
e.leftVN = lookup_or_add(C->getOperand(0));
|
||||||
|
e.rightVN = lookup_or_add(C->getOperand(1));
|
||||||
|
e.opcode = getOpcode(C);
|
||||||
|
|
||||||
|
maximalExpressions.insert(e);
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// ValueTable External Functions
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/// lookup_or_add - Returns the value number for the specified value, assigning
|
||||||
|
/// it a new number if it did not have one before.
|
||||||
uint32_t ValueTable::lookup_or_add(Value* V) {
|
uint32_t ValueTable::lookup_or_add(Value* V) {
|
||||||
maximalValues.insert(V);
|
maximalValues.insert(V);
|
||||||
|
|
||||||
@ -255,6 +290,8 @@ uint32_t ValueTable::lookup_or_add(Value* V) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// lookup - Returns the value number of the specified value. Fails if
|
||||||
|
/// the value has not yet been numbered.
|
||||||
uint32_t ValueTable::lookup(Value* V) {
|
uint32_t ValueTable::lookup(Value* V) {
|
||||||
DenseMap<Value*, uint32_t>::iterator VI = valueNumbering.find(V);
|
DenseMap<Value*, uint32_t>::iterator VI = valueNumbering.find(V);
|
||||||
if (VI != valueNumbering.end())
|
if (VI != valueNumbering.end())
|
||||||
@ -265,6 +302,8 @@ uint32_t ValueTable::lookup(Value* V) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// add - Add the specified value with the given value number, removing
|
||||||
|
/// its old number, if any
|
||||||
void ValueTable::add(Value* V, uint32_t num) {
|
void ValueTable::add(Value* V, uint32_t num) {
|
||||||
DenseMap<Value*, uint32_t>::iterator VI = valueNumbering.find(V);
|
DenseMap<Value*, uint32_t>::iterator VI = valueNumbering.find(V);
|
||||||
if (VI != valueNumbering.end())
|
if (VI != valueNumbering.end())
|
||||||
@ -272,30 +311,7 @@ void ValueTable::add(Value* V, uint32_t num) {
|
|||||||
valueNumbering.insert(std::make_pair(V, num));
|
valueNumbering.insert(std::make_pair(V, num));
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueTable::Expression ValueTable::create_expression(BinaryOperator* BO) {
|
/// clear - Remove all entries from the ValueTable and the maximal sets
|
||||||
Expression e;
|
|
||||||
|
|
||||||
e.leftVN = lookup_or_add(BO->getOperand(0));
|
|
||||||
e.rightVN = lookup_or_add(BO->getOperand(1));
|
|
||||||
e.opcode = getOpcode(BO);
|
|
||||||
|
|
||||||
maximalExpressions.insert(e);
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
ValueTable::Expression ValueTable::create_expression(CmpInst* C) {
|
|
||||||
Expression e;
|
|
||||||
|
|
||||||
e.leftVN = lookup_or_add(C->getOperand(0));
|
|
||||||
e.rightVN = lookup_or_add(C->getOperand(1));
|
|
||||||
e.opcode = getOpcode(C);
|
|
||||||
|
|
||||||
maximalExpressions.insert(e);
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ValueTable::clear() {
|
void ValueTable::clear() {
|
||||||
valueNumbering.clear();
|
valueNumbering.clear();
|
||||||
expressionNumbering.clear();
|
expressionNumbering.clear();
|
||||||
@ -304,6 +320,7 @@ void ValueTable::clear() {
|
|||||||
nextValueNumber = 1;
|
nextValueNumber = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// erase - Remove a value from the value numbering and maximal sets
|
||||||
void ValueTable::erase(Value* V) {
|
void ValueTable::erase(Value* V) {
|
||||||
maximalValues.erase(V);
|
maximalValues.erase(V);
|
||||||
valueNumbering.erase(V);
|
valueNumbering.erase(V);
|
||||||
@ -313,6 +330,10 @@ void ValueTable::erase(Value* V) {
|
|||||||
maximalExpressions.erase(create_expression(C));
|
maximalExpressions.erase(create_expression(C));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// GVNPRE Pass
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class VISIBILITY_HIDDEN GVNPRE : public FunctionPass {
|
class VISIBILITY_HIDDEN GVNPRE : public FunctionPass {
|
||||||
@ -328,6 +349,7 @@ namespace {
|
|||||||
std::map<BasicBlock*, std::set<Value*> > availableOut;
|
std::map<BasicBlock*, std::set<Value*> > availableOut;
|
||||||
std::map<BasicBlock*, std::set<Value*> > anticipatedIn;
|
std::map<BasicBlock*, std::set<Value*> > anticipatedIn;
|
||||||
|
|
||||||
|
// This transformation requires dominator postdominator info
|
||||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
AU.setPreservesCFG();
|
AU.setPreservesCFG();
|
||||||
AU.addRequired<DominatorTree>();
|
AU.addRequired<DominatorTree>();
|
||||||
@ -382,6 +404,7 @@ namespace {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// createGVNPREPass - The public interface to this file...
|
||||||
FunctionPass *llvm::createGVNPREPass() { return new GVNPRE(); }
|
FunctionPass *llvm::createGVNPREPass() { return new GVNPRE(); }
|
||||||
|
|
||||||
RegisterPass<GVNPRE> X("gvnpre",
|
RegisterPass<GVNPRE> X("gvnpre",
|
||||||
@ -392,6 +415,9 @@ STATISTIC(NumInsertedVals, "Number of values inserted");
|
|||||||
STATISTIC(NumInsertedPhis, "Number of PHI nodes inserted");
|
STATISTIC(NumInsertedPhis, "Number of PHI nodes inserted");
|
||||||
STATISTIC(NumEliminated, "Number of redundant instructions eliminated");
|
STATISTIC(NumEliminated, "Number of redundant instructions eliminated");
|
||||||
|
|
||||||
|
/// find_leader - Given a set and a value number, return the first
|
||||||
|
/// element of the set with that value number, or 0 if no such element
|
||||||
|
/// is present
|
||||||
Value* GVNPRE::find_leader(std::set<Value*>& vals, uint32_t v) {
|
Value* GVNPRE::find_leader(std::set<Value*>& vals, uint32_t v) {
|
||||||
for (std::set<Value*>::iterator I = vals.begin(), E = vals.end();
|
for (std::set<Value*>::iterator I = vals.begin(), E = vals.end();
|
||||||
I != E; ++I)
|
I != E; ++I)
|
||||||
@ -401,6 +427,8 @@ Value* GVNPRE::find_leader(std::set<Value*>& vals, uint32_t v) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// val_insert - Insert a value into a set only if there is not a value
|
||||||
|
/// with the same value number already in the set
|
||||||
void GVNPRE::val_insert(std::set<Value*>& s, Value* v) {
|
void GVNPRE::val_insert(std::set<Value*>& s, Value* v) {
|
||||||
uint32_t num = VN.lookup(v);
|
uint32_t num = VN.lookup(v);
|
||||||
Value* leader = find_leader(s, num);
|
Value* leader = find_leader(s, num);
|
||||||
@ -408,6 +436,8 @@ void GVNPRE::val_insert(std::set<Value*>& s, Value* v) {
|
|||||||
s.insert(v);
|
s.insert(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// val_replace - Insert a value into a set, replacing any values already in
|
||||||
|
/// the set that have the same value number
|
||||||
void GVNPRE::val_replace(std::set<Value*>& s, Value* v) {
|
void GVNPRE::val_replace(std::set<Value*>& s, Value* v) {
|
||||||
uint32_t num = VN.lookup(v);
|
uint32_t num = VN.lookup(v);
|
||||||
Value* leader = find_leader(s, num);
|
Value* leader = find_leader(s, num);
|
||||||
@ -418,6 +448,10 @@ void GVNPRE::val_replace(std::set<Value*>& s, Value* v) {
|
|||||||
s.insert(v);
|
s.insert(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// phi_translate - Given a value, its parent block, and a predecessor of its
|
||||||
|
/// parent, translate the value into legal for the predecessor block. This
|
||||||
|
/// means translating its operands (and recursively, their operands) through
|
||||||
|
/// any phi nodes in the parent into values available in the predecessor
|
||||||
Value* GVNPRE::phi_translate(Value* V, BasicBlock* pred, BasicBlock* succ) {
|
Value* GVNPRE::phi_translate(Value* V, BasicBlock* pred, BasicBlock* succ) {
|
||||||
if (V == 0)
|
if (V == 0)
|
||||||
return 0;
|
return 0;
|
||||||
@ -511,6 +545,7 @@ Value* GVNPRE::phi_translate(Value* V, BasicBlock* pred, BasicBlock* succ) {
|
|||||||
return V;
|
return V;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// phi_translate_set - Perform phi translation on every element of a set
|
||||||
void GVNPRE::phi_translate_set(std::set<Value*>& anticIn,
|
void GVNPRE::phi_translate_set(std::set<Value*>& anticIn,
|
||||||
BasicBlock* pred, BasicBlock* succ,
|
BasicBlock* pred, BasicBlock* succ,
|
||||||
std::set<Value*>& out) {
|
std::set<Value*>& out) {
|
||||||
@ -522,6 +557,9 @@ void GVNPRE::phi_translate_set(std::set<Value*>& anticIn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// dependsOnInvoke - Test if a value has an phi node as an operand, any of
|
||||||
|
/// whose inputs is an invoke instruction. If this is true, we cannot safely
|
||||||
|
/// PRE the instruction or anything that depends on it.
|
||||||
bool GVNPRE::dependsOnInvoke(Value* V) {
|
bool GVNPRE::dependsOnInvoke(Value* V) {
|
||||||
if (PHINode* p = dyn_cast<PHINode>(V)) {
|
if (PHINode* p = dyn_cast<PHINode>(V)) {
|
||||||
for (PHINode::op_iterator I = p->op_begin(), E = p->op_end(); I != E; ++I)
|
for (PHINode::op_iterator I = p->op_begin(), E = p->op_end(); I != E; ++I)
|
||||||
@ -533,7 +571,9 @@ bool GVNPRE::dependsOnInvoke(Value* V) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove all expressions whose operands are not themselves in the set
|
/// clean - Remove all non-opaque values from the set whose operands are not
|
||||||
|
/// themselves in the set, as well as all values that depend on invokes (see
|
||||||
|
/// above)
|
||||||
void GVNPRE::clean(std::set<Value*>& set) {
|
void GVNPRE::clean(std::set<Value*>& set) {
|
||||||
std::vector<Value*> worklist;
|
std::vector<Value*> worklist;
|
||||||
topo_sort(set, worklist);
|
topo_sort(set, worklist);
|
||||||
@ -595,8 +635,9 @@ void GVNPRE::clean(std::set<Value*>& set) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GVNPRE::topo_sort(std::set<Value*>& set,
|
/// topo_sort - Given a set of values, sort them by topological
|
||||||
std::vector<Value*>& vec) {
|
/// order into the provided vector.
|
||||||
|
void GVNPRE::topo_sort(std::set<Value*>& set, std::vector<Value*>& vec) {
|
||||||
std::set<Value*> toErase;
|
std::set<Value*> toErase;
|
||||||
for (std::set<Value*>::iterator I = set.begin(), E = set.end();
|
for (std::set<Value*>::iterator I = set.begin(), E = set.end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
@ -665,7 +706,7 @@ void GVNPRE::topo_sort(std::set<Value*>& set,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// dump - Dump a set of values to standard error
|
||||||
void GVNPRE::dump(const std::set<Value*>& s) const {
|
void GVNPRE::dump(const std::set<Value*>& s) const {
|
||||||
DOUT << "{ ";
|
DOUT << "{ ";
|
||||||
for (std::set<Value*>::iterator I = s.begin(), E = s.end();
|
for (std::set<Value*>::iterator I = s.begin(), E = s.end();
|
||||||
@ -675,6 +716,9 @@ void GVNPRE::dump(const std::set<Value*>& s) const {
|
|||||||
DOUT << "}\n\n";
|
DOUT << "}\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// elimination - Phase 3 of the main algorithm. Perform full redundancy
|
||||||
|
/// elimination by walking the dominator tree and removing any instruction that
|
||||||
|
/// is dominated by another instruction with the same value number.
|
||||||
bool GVNPRE::elimination() {
|
bool GVNPRE::elimination() {
|
||||||
DOUT << "\n\nPhase 3: Elimination\n\n";
|
DOUT << "\n\nPhase 3: Elimination\n\n";
|
||||||
|
|
||||||
@ -724,7 +768,8 @@ bool GVNPRE::elimination() {
|
|||||||
return changed_function;
|
return changed_function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// cleanup - Delete any extraneous values that were created to represent
|
||||||
|
/// expressions without leaders.
|
||||||
void GVNPRE::cleanup() {
|
void GVNPRE::cleanup() {
|
||||||
while (!createdExpressions.empty()) {
|
while (!createdExpressions.empty()) {
|
||||||
Instruction* I = createdExpressions.back();
|
Instruction* I = createdExpressions.back();
|
||||||
@ -734,6 +779,8 @@ void GVNPRE::cleanup() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// buildsets_availout - When calculating availability, handle an instruction
|
||||||
|
/// by inserting it into the appropriate sets
|
||||||
void GVNPRE::buildsets_availout(BasicBlock::iterator I,
|
void GVNPRE::buildsets_availout(BasicBlock::iterator I,
|
||||||
std::set<Value*>& currAvail,
|
std::set<Value*>& currAvail,
|
||||||
std::set<PHINode*>& currPhis,
|
std::set<PHINode*>& currPhis,
|
||||||
@ -780,6 +827,8 @@ void GVNPRE::buildsets_availout(BasicBlock::iterator I,
|
|||||||
val_insert(currAvail, I);
|
val_insert(currAvail, I);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// buildsets_anticout - When walking the postdom tree, calculate the ANTIC_OUT
|
||||||
|
/// set as a function of the ANTIC_IN set of the block's predecessors
|
||||||
void GVNPRE::buildsets_anticout(BasicBlock* BB,
|
void GVNPRE::buildsets_anticout(BasicBlock* BB,
|
||||||
std::set<Value*>& anticOut,
|
std::set<Value*>& anticOut,
|
||||||
std::set<BasicBlock*>& visited) {
|
std::set<BasicBlock*>& visited) {
|
||||||
@ -809,6 +858,9 @@ void GVNPRE::buildsets_anticout(BasicBlock* BB,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// buildsets_anticin - Walk the postdom tree, calculating ANTIC_OUT for
|
||||||
|
/// each block. ANTIC_IN is then a function of ANTIC_OUT and the GEN
|
||||||
|
/// sets populated in buildsets_availout
|
||||||
bool GVNPRE::buildsets_anticin(BasicBlock* BB,
|
bool GVNPRE::buildsets_anticin(BasicBlock* BB,
|
||||||
std::set<Value*>& anticOut,
|
std::set<Value*>& anticOut,
|
||||||
std::set<Value*>& currExps,
|
std::set<Value*>& currExps,
|
||||||
@ -853,6 +905,8 @@ bool GVNPRE::buildsets_anticin(BasicBlock* BB,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// buildsets - Phase 1 of the main algorithm. Construct the AVAIL_OUT
|
||||||
|
/// and the ANTIC_IN sets.
|
||||||
unsigned GVNPRE::buildsets(Function& F) {
|
unsigned GVNPRE::buildsets(Function& F) {
|
||||||
std::map<BasicBlock*, std::set<Value*> > generatedExpressions;
|
std::map<BasicBlock*, std::set<Value*> > generatedExpressions;
|
||||||
std::map<BasicBlock*, std::set<PHINode*> > generatedPhis;
|
std::map<BasicBlock*, std::set<PHINode*> > generatedPhis;
|
||||||
@ -926,38 +980,15 @@ unsigned GVNPRE::buildsets(Function& F) {
|
|||||||
iterations++;
|
iterations++;
|
||||||
}
|
}
|
||||||
|
|
||||||
DOUT << "Iterations: " << iterations << "\n";
|
|
||||||
|
|
||||||
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
|
|
||||||
DOUT << "Name: " << I->getName().c_str() << "\n";
|
|
||||||
|
|
||||||
DOUT << "TMP_GEN: ";
|
|
||||||
dump(generatedTemporaries[I]);
|
|
||||||
DOUT << "\n";
|
|
||||||
|
|
||||||
DOUT << "EXP_GEN: ";
|
|
||||||
dump(generatedExpressions[I]);
|
|
||||||
DOUT << "\n";
|
|
||||||
|
|
||||||
DOUT << "ANTIC_IN: ";
|
|
||||||
dump(anticipatedIn[I]);
|
|
||||||
DOUT << "\n";
|
|
||||||
|
|
||||||
DOUT << "AVAIL_OUT: ";
|
|
||||||
dump(availableOut[I]);
|
|
||||||
DOUT << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0; // No bail, no changes
|
return 0; // No bail, no changes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// insertion_pre - When a partial redundancy has been identified, eliminate it
|
||||||
|
/// by inserting appropriate values into the predecessors and a phi node in
|
||||||
|
/// the main block
|
||||||
void GVNPRE::insertion_pre(Value* e, BasicBlock* BB,
|
void GVNPRE::insertion_pre(Value* e, BasicBlock* BB,
|
||||||
std::map<BasicBlock*, Value*>& avail,
|
std::map<BasicBlock*, Value*>& avail,
|
||||||
std::set<Value*>& new_set) {
|
std::set<Value*>& new_set) {
|
||||||
DOUT << "Processing Value: ";
|
|
||||||
DEBUG(e->dump());
|
|
||||||
DOUT << "\n\n";
|
|
||||||
|
|
||||||
for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) {
|
for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) {
|
||||||
Value* e2 = avail[*PI];
|
Value* e2 = avail[*PI];
|
||||||
if (!find_leader(availableOut[*PI], VN.lookup(e2))) {
|
if (!find_leader(availableOut[*PI], VN.lookup(e2))) {
|
||||||
@ -991,9 +1022,7 @@ void GVNPRE::insertion_pre(Value* e, BasicBlock* BB,
|
|||||||
|
|
||||||
std::set<Value*>& predAvail = availableOut[*PI];
|
std::set<Value*>& predAvail = availableOut[*PI];
|
||||||
val_replace(predAvail, newVal);
|
val_replace(predAvail, newVal);
|
||||||
|
|
||||||
DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n";
|
|
||||||
|
|
||||||
std::map<BasicBlock*, Value*>::iterator av = avail.find(*PI);
|
std::map<BasicBlock*, Value*>::iterator av = avail.find(*PI);
|
||||||
if (av != avail.end())
|
if (av != avail.end())
|
||||||
avail.erase(av);
|
avail.erase(av);
|
||||||
@ -1013,24 +1042,14 @@ void GVNPRE::insertion_pre(Value* e, BasicBlock* BB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
VN.add(p, VN.lookup(e));
|
VN.add(p, VN.lookup(e));
|
||||||
DOUT << "Creating value: " << std::hex << p << std::dec << "\n";
|
|
||||||
|
|
||||||
val_replace(availableOut[BB], p);
|
val_replace(availableOut[BB], p);
|
||||||
|
|
||||||
DOUT << "Preds After Processing: ";
|
|
||||||
for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI)
|
|
||||||
DEBUG((*PI)->dump());
|
|
||||||
DOUT << "\n\n";
|
|
||||||
|
|
||||||
DOUT << "Merge Block After Processing: ";
|
|
||||||
DEBUG(BB->dump());
|
|
||||||
DOUT << "\n\n";
|
|
||||||
|
|
||||||
new_set.insert(p);
|
new_set.insert(p);
|
||||||
|
|
||||||
++NumInsertedPhis;
|
++NumInsertedPhis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// insertion_mergepoint - When walking the dom tree, check at each merge
|
||||||
|
/// block for the possibility of a partial redundancy. If present, eliminate it
|
||||||
unsigned GVNPRE::insertion_mergepoint(std::vector<Value*>& workList,
|
unsigned GVNPRE::insertion_mergepoint(std::vector<Value*>& workList,
|
||||||
df_iterator<DomTreeNode*> D,
|
df_iterator<DomTreeNode*> D,
|
||||||
std::set<Value*>& new_set) {
|
std::set<Value*>& new_set) {
|
||||||
@ -1089,6 +1108,9 @@ unsigned GVNPRE::insertion_mergepoint(std::vector<Value*>& workList,
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// insert - Phase 2 of the main algorithm. Walk the dominator tree looking for
|
||||||
|
/// merge points. When one is found, check for a partial redundancy. If one is
|
||||||
|
/// present, eliminate it. Repeat this walk until no changes are made.
|
||||||
bool GVNPRE::insertion(Function& F) {
|
bool GVNPRE::insertion(Function& F) {
|
||||||
bool changed_function = false;
|
bool changed_function = false;
|
||||||
|
|
||||||
@ -1143,7 +1165,11 @@ bool GVNPRE::insertion(Function& F) {
|
|||||||
return changed_function;
|
return changed_function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GVNPRE::runOnFunction - This is the main transformation entry point for a
|
||||||
|
// function.
|
||||||
|
//
|
||||||
bool GVNPRE::runOnFunction(Function &F) {
|
bool GVNPRE::runOnFunction(Function &F) {
|
||||||
|
// Clean out global sets from any previous functions
|
||||||
VN.clear();
|
VN.clear();
|
||||||
createdExpressions.clear();
|
createdExpressions.clear();
|
||||||
availableOut.clear();
|
availableOut.clear();
|
||||||
@ -1152,20 +1178,26 @@ bool GVNPRE::runOnFunction(Function &F) {
|
|||||||
bool changed_function = false;
|
bool changed_function = false;
|
||||||
|
|
||||||
// Phase 1: BuildSets
|
// Phase 1: BuildSets
|
||||||
|
// This phase calculates the AVAIL_OUT and ANTIC_IN sets
|
||||||
|
// NOTE: If full postdom information is no available, this will bail
|
||||||
|
// early, performing GVN but not PRE
|
||||||
unsigned bail = buildsets(F);
|
unsigned bail = buildsets(F);
|
||||||
//If a bail occurred, terminate early
|
//If a bail occurred, terminate early
|
||||||
if (bail != 0)
|
if (bail != 0)
|
||||||
return (bail == 2);
|
return (bail == 2);
|
||||||
|
|
||||||
// Phase 2: Insert
|
// Phase 2: Insert
|
||||||
DOUT<< "\nPhase 2: Insertion\n";
|
// This phase inserts values to make partially redundant values
|
||||||
|
// fully redundant
|
||||||
changed_function |= insertion(F);
|
changed_function |= insertion(F);
|
||||||
|
|
||||||
// Phase 3: Eliminate
|
// Phase 3: Eliminate
|
||||||
|
// This phase performs trivial full redundancy elimination
|
||||||
changed_function |= elimination();
|
changed_function |= elimination();
|
||||||
|
|
||||||
// Phase 4: Cleanup
|
// Phase 4: Cleanup
|
||||||
|
// This phase cleans up values that were created solely
|
||||||
|
// as leaders for expressions
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
return changed_function;
|
return changed_function;
|
||||||
|
Loading…
Reference in New Issue
Block a user