Newer
Older
//===- SCCP.cpp - Sparse Conditional Constant Propogation -----------------===//
//
// This file implements sparse conditional constant propogation and merging:
//
// Specifically, this:
// * Assumes values are constant unless proven otherwise
// * Assumes BasicBlocks are dead unless proven otherwise
// * Proves values to be constant, and replaces them with constants
// . Proves conditional branches constant, and unconditionalizes them
// * Folds multiple identical constants in the constant pool together
//
// Notice that:
// * This pass has a habit of making definitions be dead. It is a good idea
// to to run a DCE pass sometime after running this pass.
//
//===----------------------------------------------------------------------===//
Chris Lattner
committed
#include "llvm/Transforms/Scalar/ConstantProp.h"
#include "llvm/ConstantHandling.h"
#include "llvm/iPHINode.h"
#include "llvm/iMemory.h"
#include "llvm/iTerminators.h"
#include "llvm/iOther.h"
#include "llvm/Pass.h"
#include "llvm/Support/InstVisitor.h"
#include "Support/STLExtras.h"
#include <algorithm>
#include <set>
#include <iostream>
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.
//
class InstVal {
enum {
undefined, // This instruction has no known value
constant, // This instruction has a constant value
// Range, // This instruction is known to fall within a range
overdefined // This instruction has an unknown value
} LatticeValue; // The current lattice position
Constant *ConstantVal; // If Constant value, the current value
inline InstVal() : LatticeValue(undefined), ConstantVal(0) {}
// markOverdefined - Return true if this is a new status to be in...
inline bool markOverdefined() {
if (LatticeValue != overdefined) {
LatticeValue = overdefined;
return true;
}
return false;
}
// markConstant - Return true if this is a new status for us...
inline bool markConstant(Constant *V) {
if (LatticeValue != constant) {
LatticeValue = constant;
ConstantVal = V;
return true;
} else {
assert(ConstantVal == V && "Marking constant with different value");
}
return false;
}
inline bool isUndefined() const { return LatticeValue == undefined; }
inline bool isConstant() const { return LatticeValue == constant; }
inline bool isOverdefined() const { return LatticeValue == overdefined; }
inline Constant *getConstant() const { return ConstantVal; }
};
//===----------------------------------------------------------------------===//
// SCCP Class
//
// This class does all of the work of Sparse Conditional Constant Propogation.
// It's public interface consists of a constructor and a doSCCP() function.
class SCCP : public InstVisitor<SCCP> {
Function *M; // The function that we are working on
std::set<BasicBlock*> BBExecutable;// The basic blocks that are executable
std::map<Value*, InstVal> ValueState; // The state each value is in...
std::vector<Instruction*> InstWorkList;// The instruction work list
std::vector<BasicBlock*> BBWorkList; // The BasicBlock work list
//===--------------------------------------------------------------------===//
// The public interface for this class
//
public:
// SCCP Ctor - Save the function to operate on...
inline SCCP(Function *f) : M(f) {}
// doSCCP() - Run the Sparse Conditional Constant Propogation algorithm, and
// return true if the function was modified.
bool doSCCP();
//===--------------------------------------------------------------------===//
// The implementation of this class
//
private:
friend class InstVisitor<SCCP>; // Allow callbacks from visitor
// markValueOverdefined - Make a value be marked as "constant". If the value
// is not already a constant, add it to the instruction work list so that
// the users of the instruction are updated later.
//
inline bool markConstant(Instruction *I, Constant *V) {
//cerr << "markConstant: " << V << " = " << I;
if (ValueState[I].markConstant(V)) {
InstWorkList.push_back(I);
return true;
}
return false;
}
// markValueOverdefined - Make a value be marked as "overdefined". If the
// value is not already overdefined, add it to the instruction work list so
// that the users of the instruction are updated later.
//
inline bool markOverdefined(Value *V) {
if (ValueState[V].markOverdefined()) {
if (Instruction *I = dyn_cast<Instruction>(V)) {
//cerr << "markOverdefined: " << V;
InstWorkList.push_back(I); // Only instructions go on the work list
}
return true;
}
return false;
}
// getValueState - Return the InstVal object that corresponds to the value.
// This function is neccesary because not all values should start out in the
// underdefined state... Argument's should be overdefined, and
// constants should be marked as constants. If a value is not known to be an
// Instruction object, then use this accessor to get its value from the map.
//
inline InstVal &getValueState(Value *V) {
std::map<Value*, InstVal>::iterator I = ValueState.find(V);
if (I != ValueState.end()) return I->second; // Common case, in the map
if (Constant *CPV = dyn_cast<Constant>(V)) { // Constants are constant
ValueState[CPV].markConstant(CPV);
} else if (isa<Argument>(V)) { // Arguments are overdefined
ValueState[V].markOverdefined();
}
// All others are underdefined by default...
return ValueState[V];
}
// markExecutable - Mark a basic block as executable, adding it to the BB
// work list if it is not already executable...
//
void markExecutable(BasicBlock *BB) {
if (BBExecutable.count(BB)) return;
//cerr << "Marking BB Executable: " << BB;
BBExecutable.insert(BB); // Basic block is executable!
BBWorkList.push_back(BB); // Add the block to the work list!
}
// visit implementations - Something changed in this instruction... Either an
// operand made a transition, or the instruction is newly executable. Change
// the value type of I to reflect these changes if appropriate.
//
void visitPHINode(PHINode *I);
// Terminators
void visitReturnInst(ReturnInst *I) { /*does not have an effect*/ }
void visitBranchInst(BranchInst *I);
void visitSwitchInst(SwitchInst *I);
void visitUnaryOperator(Instruction *I);
void visitCastInst(CastInst *I) { visitUnaryOperator(I); }
void visitBinaryOperator(Instruction *I);
void visitShiftInst(ShiftInst *I) { visitBinaryOperator(I); }
// Instructions that cannot be folded away...
void visitMemAccessInst (Instruction *I) { markOverdefined(I); }
void visitCallInst (Instruction *I) { markOverdefined(I); }
void visitInvokeInst (Instruction *I) { markOverdefined(I); }
void visitAllocationInst(Instruction *I) { markOverdefined(I); }
void visitFreeInst (Instruction *I) { markOverdefined(I); }
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;
markOverdefined(I); // Just in case
}
// OperandChangedState - This method is invoked on all of the users of an
// instruction that was just changed state somehow.... Based on this
// information, we need to update the specified user of this instruction.
//
void OperandChangedState(User *U);
};
//===----------------------------------------------------------------------===//
// SCCP Class Implementation
// doSCCP() - Run the Sparse Conditional Constant Propogation algorithm, and
// return true if the function was modified.
//
bool SCCP::doSCCP() {
// Mark the first block of the function as being executable...
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
markExecutable(M->front());
// Process the work lists until their are empty!
while (!BBWorkList.empty() || !InstWorkList.empty()) {
// Process the instruction work list...
while (!InstWorkList.empty()) {
Instruction *I = InstWorkList.back();
InstWorkList.pop_back();
//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.
//
// Update all of the users of this instruction's value...
//
for_each(I->use_begin(), I->use_end(),
bind_obj(this, &SCCP::OperandChangedState));
}
// Process the basic block work list...
while (!BBWorkList.empty()) {
BasicBlock *BB = BBWorkList.back();
BBWorkList.pop_back();
//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)
// Notify all instructions in this basic block that they are newly
// executable.
visit(BB);
}
}
#if 0
for (Function::iterator BBI = M->begin(), BBEnd = M->end();
BBI != BBEnd; ++BBI)
if (!BBExecutable.count(*BBI))
cerr << "BasicBlock Dead:" << *BBI;
#endif
// Iterate over all of the instructions in a function, replacing them with
// constants if we have found them to be of constant values.
//
bool MadeChanges = false;
for (Function::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI) {
BasicBlock *BB = *MI;
for (BasicBlock::iterator BI = BB->begin(); BI != BB->end();) {
Instruction *Inst = *BI;
InstVal &IV = ValueState[Inst];
if (IV.isConstant()) {
Constant *Const = IV.getConstant();
// cerr << "Constant: " << Inst << " is: " << Const;
// Replaces all of the uses of a variable with uses of the constant.
Inst->replaceAllUsesWith(Const);
// Remove the operator from the list of definitions...
BB->getInstList().remove(BI);
// The new constant inherits the old name of the operator...
if (Inst->hasName() && !Const->hasName())
Const->setName(Inst->getName(), M->getSymbolTableSure());
// Delete the operator now...
delete Inst;
// Hey, we just changed something!
MadeChanges = true;
} else if (TerminatorInst *TI = dyn_cast<TerminatorInst>(Inst)) {
MadeChanges |= ConstantFoldTerminator(BB, BI, TI);
}
// Merge identical constants last: this is important because we may have just
// introduced constants that already exist, and we don't want to pollute later
// stages with extraneous constants.
//
// visit Implementations - Something changed in this instruction... Either an
// operand made a transition, or the instruction is newly executable. Change
// the value type of I to reflect these changes if appropriate. This method
// makes sure to do the following actions:
//
// 1. If a phi node merges two constants in, and has conflicting value coming
// from different branches, or if the PHI node merges in an overdefined
// value, then the PHI node becomes overdefined.
// 2. If a phi node merges only constants in, and they all agree on value, the
// PHI node becomes a constant value equal to that.
// 3. If V <- x (op) y && isConstant(x) && isConstant(y) V = Constant
// 4. If V <- x (op) y && (isOverdefined(x) || isOverdefined(y)) V = Overdefined
// 5. If V <- MEM or V <- CALL or V <- (unknown) then V = Overdefined
// 6. If a conditional branch has a value that is constant, make the selected
// destination executable
// 7. If a conditional branch has a value that is overdefined, make all
// successors executable.
//
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
void SCCP::visitPHINode(PHINode *PN) {
unsigned NumValues = PN->getNumIncomingValues(), i;
InstVal *OperandIV = 0;
// 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
// constant, and they agree with each other, the PHI becomes the identical
// 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) {
if (BBExecutable.count(PN->getIncomingBlock(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 (OperandIV == 0) { // Grab the first value...
OperandIV = &IV;
} 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()) {
// Yes there is. This means the PHI node is not constant.
// You must be overdefined poor PHI.
//
markOverdefined(PN); // The PHI node now becomes overdefined
return; // I'm done analyzing you
// 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
void SCCP::visitBranchInst(BranchInst *BI) {
if (BI->isUnconditional())
return; // Unconditional branches are already handled!
InstVal &BCValue = getValueState(BI->getCondition());
if (BCValue.isOverdefined()) {
// Overdefined condition variables mean the branch could go either way.
markExecutable(BI->getSuccessor(0));
markExecutable(BI->getSuccessor(1));
} else if (BCValue.isConstant()) {
// Constant condition variables mean the branch can only go a single way.
if (BCValue.getConstant() == ConstantBool::True)
markExecutable(BI->getSuccessor(0));
else
markExecutable(BI->getSuccessor(1));
}
void SCCP::visitSwitchInst(SwitchInst *SI) {
InstVal &SCValue = getValueState(SI->getCondition());
if (SCValue.isOverdefined()) { // Overdefined condition? All dests are exe
Chris Lattner
committed
for(unsigned i = 0, E = SI->getNumSuccessors(); i != E; ++i)
markExecutable(SI->getSuccessor(i));
} else if (SCValue.isConstant()) {
Constant *CPV = SCValue.getConstant();
// Make sure to skip the "default value" which isn't a value
for (unsigned i = 1, E = SI->getNumSuccessors(); i != E; ++i) {
if (SI->getSuccessorValue(i) == CPV) {// Found the right branch...
markExecutable(SI->getSuccessor(i));
return;
// Constant value not equal to any of the branches... must execute
// default branch then...
markExecutable(SI->getDefaultDest());
void SCCP::visitUnaryOperator(Instruction *I) {
Value *V = I->getOperand(0);
InstVal &VState = getValueState(V);
if (VState.isOverdefined()) { // Inherit overdefinedness of operand
} else if (VState.isConstant()) { // Propogate constant value
Constant *Result = isa<CastInst>(I)
? ConstantFoldCastInstruction(VState.getConstant(), I->getType())
: ConstantFoldUnaryInstruction(I->getOpcode(), VState.getConstant());
if (Result) {
// This instruction constant folds!
markConstant(I, Result);
} else {
markOverdefined(I); // Don't know how to fold this instruction. :(
}
}
}
// Handle BinaryOperators and Shift Instructions...
void SCCP::visitBinaryOperator(Instruction *I) {
InstVal &V1State = getValueState(I->getOperand(0));
InstVal &V2State = getValueState(I->getOperand(1));
if (V1State.isOverdefined() || V2State.isOverdefined()) {
markOverdefined(I);
} else if (V1State.isConstant() && V2State.isConstant()) {
Constant *Result = ConstantFoldBinaryInstruction(I->getOpcode(),
V1State.getConstant(),
V2State.getConstant());
if (Result)
markConstant(I, Result); // This instruction constant fold!s
else
markOverdefined(I); // Don't know how to fold this instruction. :(
}
}
// OperandChangedState - This method is invoked on all of the users of an
// instruction that was just changed state somehow.... Based on this
// information, we need to update the specified user of this instruction.
//
void SCCP::OperandChangedState(User *U) {
// Only instructions use other variable values!
if (!BBExecutable.count(I->getParent())) return; // Inst not executable yet!
visit(I);
namespace {
// SCCPPass - Use Sparse Conditional Constant Propogation
// to prove whether a value is constant and whether blocks are used.
//
struct SCCPPass : public FunctionPass {
const char *getPassName() const {
return "Sparse Conditional Constant Propogation";
}
inline bool runOnFunction(Function *F) {
return S.doSCCP();
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
// FIXME: SCCP does not preserve the CFG because it folds terminators!
//AU.preservesCFG();
}
};
}
Pass *createSCCPPass() {
return new SCCPPass();