[llvm-commits] CVS: llvm/lib/Transforms/Scalar/SCCP.cpp
Chris Lattner
lattner at cs.uiuc.edu
Thu Apr 24 21:51:01 PDT 2003
Changes in directory llvm/lib/Transforms/Scalar:
SCCP.cpp updated: 1.65 -> 1.66
---
Log message:
Minor non-functional changes:
* Spell propagate right
* Improve performance of phi node handling
* Delete using directive
* Other minor changes
---
Diffs of the changes:
Index: llvm/lib/Transforms/Scalar/SCCP.cpp
diff -u llvm/lib/Transforms/Scalar/SCCP.cpp:1.65 llvm/lib/Transforms/Scalar/SCCP.cpp:1.66
--- llvm/lib/Transforms/Scalar/SCCP.cpp:1.65 Wed Apr 23 11:37:42 2003
+++ llvm/lib/Transforms/Scalar/SCCP.cpp Thu Apr 24 21:50:03 2003
@@ -17,17 +17,13 @@
#include "llvm/Transforms/Scalar.h"
#include "llvm/ConstantHandling.h"
#include "llvm/Function.h"
-#include "llvm/iPHINode.h"
-#include "llvm/iMemory.h"
-#include "llvm/iTerminators.h"
-#include "llvm/iOther.h"
+#include "llvm/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/Support/InstVisitor.h"
#include "Support/STLExtras.h"
#include "Support/Statistic.h"
#include <algorithm>
#include <set>
-using std::cerr;
// InstVal class - This class represents the different lattice values that an
// instruction may occupy. It is a simple class with value semantics.
@@ -111,9 +107,8 @@
// the users of the instruction are updated later.
//
inline bool markConstant(Instruction *I, Constant *V) {
- DEBUG(cerr << "markConstant: " << V << " = " << I);
-
if (ValueState[I].markConstant(V)) {
+ DEBUG(std::cerr << "markConstant: " << V << " = " << I);
InstWorkList.push_back(I);
return true;
}
@@ -127,7 +122,7 @@
inline bool markOverdefined(Value *V) {
if (ValueState[V].markOverdefined()) {
if (Instruction *I = dyn_cast<Instruction>(V)) {
- DEBUG(cerr << "markOverdefined: " << V);
+ DEBUG(std::cerr << "markOverdefined: " << V);
InstWorkList.push_back(I); // Only instructions go on the work list
}
return true;
@@ -161,10 +156,19 @@
// work list if it is not already executable...
//
void markExecutable(BasicBlock *BB) {
- if (BBExecutable.count(BB)) return;
- DEBUG(cerr << "Marking BB Executable: " << *BB);
- BBExecutable.insert(BB); // Basic block is executable!
- BBWorkList.push_back(BB); // Add the block to the work list!
+ if (BBExecutable.count(BB)) {
+ // BB is already executable, but we may have just made an edge feasible
+ // that wasn't before. Add the PHI nodes to the work list so that they
+ // can be rechecked.
+ for (BasicBlock::iterator I = BB->begin();
+ PHINode *PN = dyn_cast<PHINode>(I); ++I)
+ InstWorkList.push_back(PN);
+
+ } else {
+ DEBUG(std::cerr << "Marking BB Executable: " << *BB);
+ BBExecutable.insert(BB); // Basic block is executable!
+ BBWorkList.push_back(BB); // Add the block to the work list!
+ }
}
@@ -193,7 +197,7 @@
void visitInstruction(Instruction &I) {
// If a new instruction is added to LLVM that we don't handle...
- cerr << "SCCP: Don't know how to handle: " << I;
+ std::cerr << "SCCP: Don't know how to handle: " << I;
markOverdefined(&I); // Just in case
}
@@ -214,12 +218,12 @@
void OperandChangedState(User *U) {
// Only instructions use other variable values!
Instruction &I = cast<Instruction>(*U);
- if (!BBExecutable.count(I.getParent())) return;// Inst not executable yet!
- visit(I);
+ if (BBExecutable.count(I.getParent())) // Inst is executable?
+ visit(I);
}
};
- RegisterOpt<SCCP> X("sccp", "Sparse Conditional Constant Propogation");
+ RegisterOpt<SCCP> X("sccp", "Sparse Conditional Constant Propagation");
} // end anonymous namespace
@@ -248,8 +252,7 @@
Instruction *I = InstWorkList.back();
InstWorkList.pop_back();
- DEBUG(cerr << "\nPopped off I-WL: " << I);
-
+ DEBUG(std::cerr << "\nPopped off I-WL: " << I);
// "I" got into the work list because it either made the transition from
// bottom to constant, or to Overdefined.
@@ -265,13 +268,7 @@
BasicBlock *BB = BBWorkList.back();
BBWorkList.pop_back();
- DEBUG(cerr << "\nPopped off BBWL: " << BB);
-
- // If this block only has a single successor, mark it as executable as
- // well... if not, terminate the do loop.
- //
- if (BB->getTerminator()->getNumSuccessors() == 1)
- markExecutable(BB->getTerminator()->getSuccessor(0));
+ DEBUG(std::cerr << "\nPopped off BBWL: " << BB);
// Notify all instructions in this basic block that they are newly
// executable.
@@ -282,7 +279,7 @@
if (DebugFlag) {
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
if (!BBExecutable.count(I))
- cerr << "BasicBlock Dead:" << *I;
+ std::cerr << "BasicBlock Dead:" << *I;
}
// Iterate over all of the instructions in a function, replacing them with
@@ -295,7 +292,7 @@
InstVal &IV = ValueState[&Inst];
if (IV.isConstant()) {
Constant *Const = IV.getConstant();
- DEBUG(cerr << "Constant: " << Const << " = " << Inst);
+ DEBUG(std::cerr << "Constant: " << Const << " = " << Inst);
// Replaces all of the uses of a variable with uses of the constant.
Inst.replaceAllUsesWith(Const);
@@ -325,7 +322,7 @@
// successors are reachable from a given terminator instruction.
//
void SCCP::getFeasibleSuccessors(TerminatorInst &TI, std::vector<bool> &Succs) {
- assert(Succs.size() == TI.getNumSuccessors() && "Succs vector wrong size!");
+ Succs.resize(TI.getNumSuccessors());
if (BranchInst *BI = dyn_cast<BranchInst>(&TI)) {
if (BI->isUnconditional()) {
Succs[0] = true;
@@ -362,7 +359,7 @@
Succs[0] = true;
}
} else {
- cerr << "SCCP: Don't know how to handle: " << TI;
+ std::cerr << "SCCP: Don't know how to handle: " << TI;
Succs.assign(TI.getNumSuccessors(), true);
}
}
@@ -379,7 +376,7 @@
// Check to make sure this edge itself is actually feasible now...
TerminatorInst *FT = From->getTerminator();
- std::vector<bool> SuccFeasible(FT->getNumSuccessors());
+ std::vector<bool> SuccFeasible;
getFeasibleSuccessors(*FT, SuccFeasible);
// Check all edges from From to To. If any are feasible, return true.
@@ -409,10 +406,8 @@
// 7. If a conditional branch has a value that is overdefined, make all
// successors executable.
//
-
void SCCP::visitPHINode(PHINode &PN) {
- unsigned NumValues = PN.getNumIncomingValues(), i;
- InstVal *OperandIV = 0;
+ if (getValueState(&PN).isOverdefined()) return; // Quick exit
// Look at all of the executable operands of the PHI node. If any of them
// are overdefined, the PHI becomes overdefined as well. If they are all
@@ -420,24 +415,25 @@
// constant. If they are constant and don't agree, the PHI is overdefined.
// If there are no executable operands, the PHI remains undefined.
//
- for (i = 0; i < NumValues; ++i) {
+ Constant *OperandVal = 0;
+ for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
+ InstVal &IV = getValueState(PN.getIncomingValue(i));
+ if (IV.isUndefined()) continue; // Doesn't influence PHI node.
+ if (IV.isOverdefined()) { // PHI node becomes overdefined!
+ markOverdefined(&PN);
+ return;
+ }
+
if (isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent())) {
- InstVal &IV = getValueState(PN.getIncomingValue(i));
- if (IV.isUndefined()) continue; // Doesn't influence PHI node.
- if (IV.isOverdefined()) { // PHI node becomes overdefined!
- markOverdefined(&PN);
- return;
- }
-
- if (OperandIV == 0) { // Grab the first value...
- OperandIV = &IV;
+ if (OperandVal == 0) { // Grab the first value...
+ OperandVal = IV.getConstant();
} else { // Another value is being merged in!
// There is already a reachable operand. If we conflict with it,
// then the PHI node becomes overdefined. If we agree with it, we
// can continue on.
-
+
// Check to see if there are two different constants merging...
- if (IV.getConstant() != OperandIV->getConstant()) {
+ if (IV.getConstant() != OperandVal) {
// Yes there is. This means the PHI node is not constant.
// You must be overdefined poor PHI.
//
@@ -449,18 +445,16 @@
}
// If we exited the loop, this means that the PHI node only has constant
- // arguments that agree with each other(and OperandIV is a pointer to one
- // of their InstVal's) or OperandIV is null because there are no defined
- // incoming arguments. If this is the case, the PHI remains undefined.
- //
- if (OperandIV) {
- assert(OperandIV->isConstant() && "Should only be here for constants!");
- markConstant(&PN, OperandIV->getConstant()); // Aquire operand value
- }
+ // arguments that agree with each other(and OperandVal is the constant) or
+ // OperandVal is null because there are no defined incoming arguments. If
+ // this is the case, the PHI remains undefined.
+ //
+ if (OperandVal)
+ markConstant(&PN, OperandVal); // Aquire operand value
}
void SCCP::visitTerminatorInst(TerminatorInst &TI) {
- std::vector<bool> SuccFeasible(TI.getNumSuccessors());
+ std::vector<bool> SuccFeasible;
getFeasibleSuccessors(TI, SuccFeasible);
// Mark all feasible successors executable...
@@ -468,14 +462,6 @@
if (SuccFeasible[i]) {
BasicBlock *Succ = TI.getSuccessor(i);
markExecutable(Succ);
-
- // Visit all of the PHI nodes that merge values from this block...
- // Because this edge may be new executable, and PHI nodes that used to be
- // constant now may not be.
- //
- for (BasicBlock::iterator I = Succ->begin();
- PHINode *PN = dyn_cast<PHINode>(I); ++I)
- visitPHINode(*PN);
}
}
More information about the llvm-commits
mailing list