Newer
Older
//===- SCCP.cpp - Sparse Conditional Constant Propagation -----------------===//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//===----------------------------------------------------------------------===//
// This file implements sparse conditional constant propagation 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 to be unconditional
//
// 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.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "sccp"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/IPO.h"
Chris Lattner
committed
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Pass.h"
Chris Lattner
committed
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/Compiler.h"
Chris Lattner
committed
#include "llvm/Support/InstVisitor.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallSet.h"
Chris Lattner
committed
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
#include <algorithm>
#include <map>
Chris Lattner
committed
STATISTIC(NumInstRemoved, "Number of instructions removed");
STATISTIC(NumDeadBlocks , "Number of basic blocks unreachable");
STATISTIC(IPNumInstRemoved, "Number of instructions removed by IPSCCP");
Chris Lattner
committed
STATISTIC(IPNumDeadBlocks , "Number of basic blocks unreachable by IPSCCP");
STATISTIC(IPNumArgsElimed ,"Number of arguments constant propagated by IPSCCP");
STATISTIC(IPNumGlobalConst, "Number of globals found to be constant by IPSCCP");
namespace {
Chris Lattner
committed
/// LatticeVal class - This class represents the different lattice values that
/// an LLVM value may occupy. It is a simple class with value semantics.
///
class VISIBILITY_HIDDEN LatticeVal {
Chris Lattner
committed
/// undefined - This LLVM Value has no known value yet.
undefined,
/// constant - This LLVM Value has a specific constant value.
constant,
/// forcedconstant - This LLVM Value was thought to be undef until
/// ResolvedUndefsIn. This is treated just like 'constant', but if merged
/// with another (different) constant, it goes to overdefined, instead of
/// asserting.
forcedconstant,
/// overdefined - This instruction is not known to be constant, and we know
/// it has a value.
overdefined
} LatticeValue; // The current lattice position
Constant *ConstantVal; // If Constant value, the current value
inline LatticeVal() : LatticeValue(undefined), ConstantVal(0) {}
Chris Lattner
committed
// markOverdefined - Return true if this is a new status to be in...
inline bool markOverdefined() {
if (LatticeValue != overdefined) {
LatticeValue = overdefined;
return true;
}
return false;
}
Chris Lattner
committed
// markConstant - Return true if this is a new status for us.
inline bool markConstant(Constant *V) {
if (LatticeValue != constant) {
Chris Lattner
committed
if (LatticeValue == undefined) {
LatticeValue = constant;
assert(V && "Marking constant with NULL");
Chris Lattner
committed
ConstantVal = V;
} else {
assert(LatticeValue == forcedconstant &&
"Cannot move from overdefined to constant!");
// Stay at forcedconstant if the constant is the same.
if (V == ConstantVal) return false;
// Otherwise, we go to overdefined. Assumptions made based on the
// forced value are possibly wrong. Assuming this is another constant
// could expose a contradiction.
LatticeValue = overdefined;
}
return true;
} else {
assert(ConstantVal == V && "Marking constant with different value");
}
return false;
}
Chris Lattner
committed
inline void markForcedConstant(Constant *V) {
assert(LatticeValue == undefined && "Can't force a defined value!");
LatticeValue = forcedconstant;
ConstantVal = V;
}
inline bool isUndefined() const { return LatticeValue == undefined; }
inline bool isConstant() const {
return LatticeValue == constant || LatticeValue == forcedconstant;
}
inline bool isOverdefined() const { return LatticeValue == overdefined; }
inline Constant *getConstant() const {
assert(isConstant() && "Cannot get the constant of a non-constant!");
return ConstantVal;
}
};
//===----------------------------------------------------------------------===//
//
/// SCCPSolver - This class is a general purpose solver for Sparse Conditional
/// Constant Propagation.
///
class SCCPSolver : public InstVisitor<SCCPSolver> {
DenseSet<BasicBlock*> BBExecutable;// The basic blocks that are executable
std::map<Value*, LatticeVal> ValueState; // The state each value is in.
/// GlobalValue - If we are tracking any values for the contents of a global
/// variable, we keep a mapping from the constant accessor to the element of
/// the global, to the currently known value. If the value becomes
/// overdefined, it's entry is simply removed from this map.
DenseMap<GlobalVariable*, LatticeVal> TrackedGlobals;
/// TrackedRetVals - If we are tracking arguments into and the return
/// value out of a function, it will have an entry in this map, indicating
/// what the known return value for the function is.
DenseMap<Function*, LatticeVal> TrackedRetVals;
/// TrackedMultipleRetVals - Same as TrackedRetVals, but used for functions
/// that return multiple values.
DenseMap<std::pair<Function*, unsigned>, LatticeVal> TrackedMultipleRetVals;
// The reason for two worklists is that overdefined is the lowest state
// on the lattice, and moving things to overdefined as fast as possible
// makes SCCP converge much faster.
// By having a separate worklist, we accomplish this because everything
// possibly overdefined will become overdefined at the soonest possible
// point.
SmallVector<Value*, 64> OverdefinedInstWorkList;
SmallVector<Value*, 64> InstWorkList;
SmallVector<BasicBlock*, 64> BBWorkList; // The BasicBlock work list
Chris Lattner
committed
/// UsersOfOverdefinedPHIs - Keep track of any users of PHI nodes that are not
/// overdefined, despite the fact that the PHI node is overdefined.
std::multimap<PHINode*, Instruction*> UsersOfOverdefinedPHIs;
Chris Lattner
committed
/// KnownFeasibleEdges - Entries in this set are edges which have already had
/// PHI nodes retriggered.
typedef std::pair<BasicBlock*, BasicBlock*> Edge;
DenseSet<Edge> KnownFeasibleEdges;
public:
void setContext(LLVMContext *C) { Context = C; }
/// MarkBlockExecutable - This method can be used by clients to mark all of
/// the blocks that are known to be intrinsically live in the processed unit.
void MarkBlockExecutable(BasicBlock *BB) {
DOUT << "Marking Block Executable: " << BB->getNameStart() << "\n";
BBExecutable.insert(BB); // Basic block is executable!
BBWorkList.push_back(BB); // Add the block to the work list!
}
/// TrackValueOfGlobalVariable - Clients can use this method to
/// inform the SCCPSolver that it should track loads and stores to the
/// specified global variable if it can. This is only legal to call if
/// performing Interprocedural SCCP.
void TrackValueOfGlobalVariable(GlobalVariable *GV) {
const Type *ElTy = GV->getType()->getElementType();
if (ElTy->isFirstClassType()) {
LatticeVal &IV = TrackedGlobals[GV];
if (!isa<UndefValue>(GV->getInitializer()))
IV.markConstant(GV->getInitializer());
}
}
/// AddTrackedFunction - If the SCCP solver is supposed to track calls into
/// and out of the specified function (which cannot have its address taken),
/// this method must be called.
void AddTrackedFunction(Function *F) {
assert(F->hasLocalLinkage() && "Can only track internal functions!");
// Add an entry, F -> undef.
if (const StructType *STy = dyn_cast<StructType>(F->getReturnType())) {
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
TrackedMultipleRetVals.insert(std::make_pair(std::make_pair(F, i),
LatticeVal()));
} else
TrackedRetVals.insert(std::make_pair(F, LatticeVal()));
}
/// Solve - Solve for constants and executable blocks.
///
void Solve();
Chris Lattner
committed
/// ResolvedUndefsIn - While solving the dataflow for a function, we assume
/// that branches on undef values cannot reach any of their successors.
/// However, this is not a safe assumption. After we solve dataflow, this
/// method should be use to handle this. If this returns true, the solver
/// should be rerun.
Chris Lattner
committed
bool ResolvedUndefsIn(Function &F);
bool isBlockExecutable(BasicBlock *BB) const {
return BBExecutable.count(BB);
}
/// getValueMapping - Once we have solved for constants, return the mapping of
/// LLVM values to LatticeVals.
std::map<Value*, LatticeVal> &getValueMapping() {
return ValueState;
}
/// getTrackedRetVals - Get the inferred return value map.
const DenseMap<Function*, LatticeVal> &getTrackedRetVals() {
return TrackedRetVals;
}
/// getTrackedGlobals - Get and return the set of inferred initializers for
/// global variables.
const DenseMap<GlobalVariable*, LatticeVal> &getTrackedGlobals() {
return TrackedGlobals;
}
inline void markOverdefined(Value *V) {
markOverdefined(ValueState[V], V);
}
// markConstant - 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 void markConstant(LatticeVal &IV, Value *V, Constant *C) {
DOUT << "markConstant: " << *C << ": " << *V;
InstWorkList.push_back(V);
Chris Lattner
committed
inline void markForcedConstant(LatticeVal &IV, Value *V, Constant *C) {
IV.markForcedConstant(C);
DOUT << "markForcedConstant: " << *C << ": " << *V;
InstWorkList.push_back(V);
}
inline void markConstant(Value *V, Constant *C) {
markConstant(ValueState[V], V, C);
// markOverdefined - Make a value be marked as "overdefined". If the
// value is not already overdefined, add it to the overdefined instruction
// work list so that the users of the instruction are updated later.
inline void markOverdefined(LatticeVal &IV, Value *V) {
DEBUG(DOUT << "markOverdefined: ";
DOUT << "Function '" << F->getName() << "'\n";
DOUT << *V);
// Only instructions go on the work list
OverdefinedInstWorkList.push_back(V);
inline void mergeInValue(LatticeVal &IV, Value *V, LatticeVal &MergeWithV) {
if (IV.isOverdefined() || MergeWithV.isUndefined())
return; // Noop.
if (MergeWithV.isOverdefined())
markOverdefined(IV, V);
else if (IV.isUndefined())
markConstant(IV, V, MergeWithV.getConstant());
else if (IV.getConstant() != MergeWithV.getConstant())
markOverdefined(IV, V);
inline void mergeInValue(Value *V, LatticeVal &MergeWithV) {
return mergeInValue(ValueState[V], V, MergeWithV);
}
// getValueState - Return the LatticeVal object that corresponds to the value.
// This function is necessary 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 LatticeVal &getValueState(Value *V) {
std::map<Value*, LatticeVal>::iterator I = ValueState.find(V);
if (I != ValueState.end()) return I->second; // Common case, in the map
Chris Lattner
committed
if (Constant *C = dyn_cast<Constant>(V)) {
if (isa<UndefValue>(V)) {
// Nothing to do, remain undefined.
} else {
LatticeVal &LV = ValueState[C];
LV.markConstant(C); // Constants are constant
return LV;
// All others are underdefined by default...
return ValueState[V];
}
// markEdgeExecutable - Mark a basic block as executable, adding it to the BB
// work list if it is not already executable...
Chris Lattner
committed
void markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest) {
if (!KnownFeasibleEdges.insert(Edge(Source, Dest)).second)
return; // This edge is already known to be executable!
if (BBExecutable.count(Dest)) {
DOUT << "Marking Edge Executable: " << Source->getNameStart()
<< " -> " << Dest->getNameStart() << "\n";
Chris Lattner
committed
// The destination is already executable, but we just made an edge
// feasible that wasn't before. Revisit the PHI nodes in the block
// because they have potentially new operands.
for (BasicBlock::iterator I = Dest->begin(); isa<PHINode>(I); ++I)
visitPHINode(*cast<PHINode>(I));
MarkBlockExecutable(Dest);
// getFeasibleSuccessors - Return a vector of booleans to indicate which
// successors are reachable from a given terminator instruction.
//
Chris Lattner
committed
void getFeasibleSuccessors(TerminatorInst &TI, SmallVector<bool, 16> &Succs);
// isEdgeFeasible - Return true if the control flow edge from the 'From' basic
// block to the 'To' basic block is currently feasible...
//
bool isEdgeFeasible(BasicBlock *From, BasicBlock *To);
// 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) {
// Only instructions use other variable values!
Instruction &I = cast<Instruction>(*U);
if (BBExecutable.count(I.getParent())) // Inst is executable?
visit(I);
}
private:
friend class InstVisitor<SCCPSolver>;
// 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.
//
// Terminators
void visitReturnInst(ReturnInst &I);
void visitSelectInst(SelectInst &I);
void visitExtractElementInst(ExtractElementInst &I);
void visitInsertElementInst(InsertElementInst &I);
void visitShuffleVectorInst(ShuffleVectorInst &I);
void visitExtractValueInst(ExtractValueInst &EVI);
void visitInsertValueInst(InsertValueInst &IVI);
// Instructions that cannot be folded away...
void visitStoreInst (Instruction &I);
void visitLoadInst (LoadInst &I);
void visitGetElementPtrInst(GetElementPtrInst &I);
void visitCallInst (CallInst &I) { visitCallSite(CallSite::get(&I)); }
void visitInvokeInst (InvokeInst &II) {
visitCallSite(CallSite::get(&II));
visitTerminatorInst(II);
void visitCallSite (CallSite CS);
void visitUnwindInst (TerminatorInst &I) { /*returns void*/ }
void visitUnreachableInst(TerminatorInst &I) { /*returns void*/ }
void visitAllocationInst(Instruction &I) { markOverdefined(&I); }
void visitVANextInst (Instruction &I) { markOverdefined(&I); }
void visitVAArgInst (Instruction &I) { markOverdefined(&I); }
void visitFreeInst (Instruction &I) { /*returns void*/ }
void visitInstruction(Instruction &I) {
// If a new instruction is added to LLVM that we don't handle...
Bill Wendling
committed
cerr << "SCCP: Don't know how to handle: " << I;
} // end anonymous namespace
// getFeasibleSuccessors - Return a vector of booleans to indicate which
// successors are reachable from a given terminator instruction.
//
void SCCPSolver::getFeasibleSuccessors(TerminatorInst &TI,
Chris Lattner
committed
SmallVector<bool, 16> &Succs) {
if (BI->isUnconditional()) {
Succs[0] = true;
} else {
LatticeVal &BCValue = getValueState(BI->getCondition());
if (BCValue.isOverdefined() ||
(BCValue.isConstant() && !isa<ConstantInt>(BCValue.getConstant()))) {
// Overdefined condition variables, and branches on unfoldable constant
// conditions, mean the branch could go either way.
Succs[0] = Succs[1] = true;
} else if (BCValue.isConstant()) {
// Constant condition variables mean the branch can only go a single way
Succs[BCValue.getConstant() == Context->getConstantIntFalse()] = true;
// Invoke instructions successors are always executable.
Succs[0] = Succs[1] = true;
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(&TI)) {
LatticeVal &SCValue = getValueState(SI->getCondition());
if (SCValue.isOverdefined() || // Overdefined condition?
(SCValue.isConstant() && !isa<ConstantInt>(SCValue.getConstant()))) {
// All destinations are executable!
Chris Lattner
committed
} else if (SCValue.isConstant())
Succs[SI->findCaseValue(cast<ConstantInt>(SCValue.getConstant()))] = true;
Chris Lattner
committed
assert(0 && "SCCP: Don't know how to handle this terminator!");
}
}
// isEdgeFeasible - Return true if the control flow edge from the 'From' basic
// block to the 'To' basic block is currently feasible...
//
bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) {
assert(BBExecutable.count(To) && "Dest should always be alive!");
// Make sure the source basic block is executable!!
if (!BBExecutable.count(From)) return false;
// Check to make sure this edge itself is actually feasible now...
Chris Lattner
committed
TerminatorInst *TI = From->getTerminator();
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
if (BI->isUnconditional())
return true;
Chris Lattner
committed
else {
LatticeVal &BCValue = getValueState(BI->getCondition());
Chris Lattner
committed
if (BCValue.isOverdefined()) {
// Overdefined condition variables mean the branch could go either way.
return true;
} else if (BCValue.isConstant()) {
// Not branching on an evaluatable constant?
if (!isa<ConstantInt>(BCValue.getConstant())) return true;
Chris Lattner
committed
// Constant condition variables mean the branch can only go a single way
return BI->getSuccessor(BCValue.getConstant() ==
Context->getConstantIntFalse()) == To;
Chris Lattner
committed
}
return false;
}
Chris Lattner
committed
// Invoke instructions successors are always executable.
return true;
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
LatticeVal &SCValue = getValueState(SI->getCondition());
Chris Lattner
committed
if (SCValue.isOverdefined()) { // Overdefined condition?
// All destinations are executable!
return true;
} else if (SCValue.isConstant()) {
Constant *CPV = SCValue.getConstant();
if (!isa<ConstantInt>(CPV))
return true; // not a foldable constant?
Chris Lattner
committed
// 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 taken branch...
return SI->getSuccessor(i) == To;
// Constant value not equal to any of the branches... must execute
// default branch then...
return SI->getDefaultDest() == To;
}
return false;
} else {
Bill Wendling
committed
cerr << "Unknown terminator instruction: " << *TI;
Chris Lattner
committed
abort();
}
}
// 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.
//
void SCCPSolver::visitPHINode(PHINode &PN) {
LatticeVal &PNIV = getValueState(&PN);
if (PNIV.isOverdefined()) {
// There may be instructions using this PHI node that are not overdefined
// themselves. If so, make sure that they know that the PHI node operand
// changed.
std::multimap<PHINode*, Instruction*>::iterator I, E;
tie(I, E) = UsersOfOverdefinedPHIs.equal_range(&PN);
if (I != E) {
Chris Lattner
committed
SmallVector<Instruction*, 16> Users;
for (; I != E; ++I) Users.push_back(I->second);
while (!Users.empty()) {
visit(Users.back());
Users.pop_back();
}
}
return; // Quick exit
}
Chris Lattner
committed
// Super-extra-high-degree PHI nodes are unlikely to ever be marked constant,
// and slow us down a lot. Just mark them overdefined.
if (PN.getNumIncomingValues() > 64) {
markOverdefined(PNIV, &PN);
return;
}
// 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.
//
Constant *OperandVal = 0;
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
LatticeVal &IV = getValueState(PN.getIncomingValue(i));
if (IV.isUndefined()) continue; // Doesn't influence PHI node.
if (isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent())) {
if (IV.isOverdefined()) { // PHI node becomes overdefined!
markOverdefined(&PN);
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...
// 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 OperandVal is the constant) or
// OperandVal is null because there are no defined incoming arguments. If
// this is the case, the PHI remains undefined.
markConstant(&PN, OperandVal); // Acquire operand value
void SCCPSolver::visitReturnInst(ReturnInst &I) {
if (I.getNumOperands() == 0) return; // Ret void
Function *F = I.getParent()->getParent();
// If we are tracking the return value of this function, merge it in.
if (!TrackedRetVals.empty() && I.getNumOperands() == 1) {
DenseMap<Function*, LatticeVal>::iterator TFRVI =
TrackedRetVals.find(F);
if (TFRVI != TrackedRetVals.end() &&
!TFRVI->second.isOverdefined()) {
LatticeVal &IV = getValueState(I.getOperand(0));
mergeInValue(TFRVI->second, F, IV);
// Handle functions that return multiple values.
if (!TrackedMultipleRetVals.empty() && I.getNumOperands() > 1) {
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
DenseMap<std::pair<Function*, unsigned>, LatticeVal>::iterator
It = TrackedMultipleRetVals.find(std::make_pair(F, i));
if (It == TrackedMultipleRetVals.end()) break;
mergeInValue(It->second, F, getValueState(I.getOperand(i)));
} else if (!TrackedMultipleRetVals.empty() &&
I.getNumOperands() == 1 &&
isa<StructType>(I.getOperand(0)->getType())) {
for (unsigned i = 0, e = I.getOperand(0)->getType()->getNumContainedTypes();
i != e; ++i) {
DenseMap<std::pair<Function*, unsigned>, LatticeVal>::iterator
It = TrackedMultipleRetVals.find(std::make_pair(F, i));
if (It == TrackedMultipleRetVals.end()) break;
if (Value *Val = FindInsertedValue(I.getOperand(0), i, Context))
mergeInValue(It->second, F, getValueState(Val));
}
}
void SCCPSolver::visitTerminatorInst(TerminatorInst &TI) {
Chris Lattner
committed
SmallVector<bool, 16> SuccFeasible;
getFeasibleSuccessors(TI, SuccFeasible);
Chris Lattner
committed
BasicBlock *BB = TI.getParent();
// Mark all feasible successors executable...
for (unsigned i = 0, e = SuccFeasible.size(); i != e; ++i)
Chris Lattner
committed
if (SuccFeasible[i])
markEdgeExecutable(BB, TI.getSuccessor(i));
void SCCPSolver::visitCastInst(CastInst &I) {
LatticeVal &VState = getValueState(V);
Chris Lattner
committed
if (VState.isOverdefined()) // Inherit overdefinedness of operand
Chris Lattner
committed
else if (VState.isConstant()) // Propagate constant value
markConstant(&I, Context->getConstantExprCast(I.getOpcode(),
VState.getConstant(), I.getType()));
void SCCPSolver::visitExtractValueInst(ExtractValueInst &EVI) {
Value *Aggr = EVI.getAggregateOperand();
// If the operand to the extractvalue is an undef, the result is undef.
if (isa<UndefValue>(Aggr))
return;
// Currently only handle single-index extractvalues.
if (EVI.getNumIndices() != 1) {
markOverdefined(&EVI);
return;
}
Function *F = 0;
if (CallInst *CI = dyn_cast<CallInst>(Aggr))
F = CI->getCalledFunction();
else if (InvokeInst *II = dyn_cast<InvokeInst>(Aggr))
F = II->getCalledFunction();
// TODO: If IPSCCP resolves the callee of this function, we could propagate a
// result back!
if (F == 0 || TrackedMultipleRetVals.empty()) {
markOverdefined(&EVI);
return;
}
// See if we are tracking the result of the callee. If not tracking this
// function (for example, it is a declaration) just move to overdefined.
if (!TrackedMultipleRetVals.count(std::make_pair(F, *EVI.idx_begin()))) {
markOverdefined(&EVI);
return;
}
// Otherwise, the value will be merged in here as a result of CallSite
// handling.
}
void SCCPSolver::visitInsertValueInst(InsertValueInst &IVI) {
Value *Aggr = IVI.getAggregateOperand();
Value *Val = IVI.getInsertedValueOperand();
// If the operands to the insertvalue are undef, the result is undef.
if (isa<UndefValue>(Aggr) && isa<UndefValue>(Val))
return;
// Currently only handle single-index insertvalues.
if (IVI.getNumIndices() != 1) {
markOverdefined(&IVI);
return;
}
// Currently only handle insertvalue instructions that are in a single-use
// chain that builds up a return value.
for (const InsertValueInst *TmpIVI = &IVI; ; ) {
if (!TmpIVI->hasOneUse()) {
markOverdefined(&IVI);
return;
}
const Value *V = *TmpIVI->use_begin();
if (isa<ReturnInst>(V))
break;
TmpIVI = dyn_cast<InsertValueInst>(V);
if (!TmpIVI) {
markOverdefined(&IVI);
return;
}
}
// See if we are tracking the result of the callee.
Function *F = IVI.getParent()->getParent();
DenseMap<std::pair<Function*, unsigned>, LatticeVal>::iterator
It = TrackedMultipleRetVals.find(std::make_pair(F, *IVI.idx_begin()));
// Merge in the inserted member value.
if (It != TrackedMultipleRetVals.end())
mergeInValue(It->second, F, getValueState(Val));
// Mark the aggregate result of the IVI overdefined; any tracking that we do
// will be done on the individual member values.
markOverdefined(&IVI);
}
void SCCPSolver::visitSelectInst(SelectInst &I) {
LatticeVal &CondValue = getValueState(I.getCondition());
if (CondValue.isUndefined())
return;
if (CondValue.isConstant()) {
if (ConstantInt *CondCB = dyn_cast<ConstantInt>(CondValue.getConstant())){
mergeInValue(&I, getValueState(CondCB->getZExtValue() ? I.getTrueValue()
return;
}
}
// Otherwise, the condition is overdefined or a constant we can't evaluate.
// See if we can produce something better than overdefined based on the T/F
// value.
LatticeVal &TVal = getValueState(I.getTrueValue());
LatticeVal &FVal = getValueState(I.getFalseValue());
// select ?, C, C -> C.
if (TVal.isConstant() && FVal.isConstant() &&
TVal.getConstant() == FVal.getConstant()) {
markConstant(&I, FVal.getConstant());
return;
}
if (TVal.isUndefined()) { // select ?, undef, X -> X.
mergeInValue(&I, FVal);
} else if (FVal.isUndefined()) { // select ?, X, undef -> X.
mergeInValue(&I, TVal);
} else {
markOverdefined(&I);
// Handle BinaryOperators and Shift Instructions...
void SCCPSolver::visitBinaryOperator(Instruction &I) {
LatticeVal &IV = ValueState[&I];
LatticeVal &V1State = getValueState(I.getOperand(0));
LatticeVal &V2State = getValueState(I.getOperand(1));
if (V1State.isOverdefined() || V2State.isOverdefined()) {
// If this is an AND or OR with 0 or -1, it doesn't matter that the other
// operand is overdefined.
if (I.getOpcode() == Instruction::And || I.getOpcode() == Instruction::Or) {
LatticeVal *NonOverdefVal = 0;
if (!V1State.isOverdefined()) {
NonOverdefVal = &V1State;
} else if (!V2State.isOverdefined()) {
NonOverdefVal = &V2State;
}
if (NonOverdefVal) {
if (NonOverdefVal->isUndefined()) {
// Could annihilate value.
if (I.getOpcode() == Instruction::And)
markConstant(IV, &I, Context->getNullValue(I.getType()));
else if (const VectorType *PT = dyn_cast<VectorType>(I.getType()))
markConstant(IV, &I, Context->getConstantVectorAllOnesValue(PT));
else
markConstant(IV, &I,
Context->getConstantIntAllOnesValue(I.getType()));
return;
} else {
if (I.getOpcode() == Instruction::And) {
if (NonOverdefVal->getConstant()->isNullValue()) {
markConstant(IV, &I, NonOverdefVal->getConstant());
return; // X and 0 = 0
}
} else {
if (ConstantInt *CI =
dyn_cast<ConstantInt>(NonOverdefVal->getConstant()))
if (CI->isAllOnesValue()) {
markConstant(IV, &I, NonOverdefVal->getConstant());
return; // X or -1 = -1
}
}
}
}
}
// If both operands are PHI nodes, it is possible that this instruction has
// a constant value, despite the fact that the PHI node doesn't. Check for
// this condition now.
if (PHINode *PN1 = dyn_cast<PHINode>(I.getOperand(0)))
if (PHINode *PN2 = dyn_cast<PHINode>(I.getOperand(1)))
if (PN1->getParent() == PN2->getParent()) {
// Since the two PHI nodes are in the same basic block, they must have
// entries for the same predecessors. Walk the predecessor list, and
// if all of the incoming values are constants, and the result of
// evaluating this expression with all incoming value pairs is the
// same, then this expression is a constant even though the PHI node
// is not a constant!
LatticeVal Result;
for (unsigned i = 0, e = PN1->getNumIncomingValues(); i != e; ++i) {
LatticeVal &In1 = getValueState(PN1->getIncomingValue(i));
BasicBlock *InBlock = PN1->getIncomingBlock(i);
LatticeVal &In2 =
getValueState(PN2->getIncomingValueForBlock(InBlock));
if (In1.isOverdefined() || In2.isOverdefined()) {
Result.markOverdefined();
break; // Cannot fold this operation over the PHI nodes!
} else if (In1.isConstant() && In2.isConstant()) {
Constant *V =
Context->getConstantExpr(I.getOpcode(), In1.getConstant(),
Result.markConstant(V);
else if (Result.isConstant() && Result.getConstant() != V) {
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
Result.markOverdefined();
break;
}
}
}
// If we found a constant value here, then we know the instruction is
// constant despite the fact that the PHI nodes are overdefined.
if (Result.isConstant()) {
markConstant(IV, &I, Result.getConstant());
// Remember that this instruction is virtually using the PHI node
// operands.
UsersOfOverdefinedPHIs.insert(std::make_pair(PN1, &I));
UsersOfOverdefinedPHIs.insert(std::make_pair(PN2, &I));
return;
} else if (Result.isUndefined()) {
return;
}
// Okay, this really is overdefined now. Since we might have
// speculatively thought that this was not overdefined before, and
// added ourselves to the UsersOfOverdefinedPHIs list for the PHIs,
// make sure to clean out any entries that we put there, for
// efficiency.
std::multimap<PHINode*, Instruction*>::iterator It, E;
tie(It, E) = UsersOfOverdefinedPHIs.equal_range(PN1);
while (It != E) {
if (It->second == &I) {
UsersOfOverdefinedPHIs.erase(It++);
} else
++It;
}
tie(It, E) = UsersOfOverdefinedPHIs.equal_range(PN2);
while (It != E) {
if (It->second == &I) {
UsersOfOverdefinedPHIs.erase(It++);
} else
++It;
}
}
markOverdefined(IV, &I);
} else if (V1State.isConstant() && V2State.isConstant()) {
markConstant(IV, &I,
Context->getConstantExpr(I.getOpcode(), V1State.getConstant(),
}
}
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
// Handle ICmpInst instruction...
void SCCPSolver::visitCmpInst(CmpInst &I) {
LatticeVal &IV = ValueState[&I];
if (IV.isOverdefined()) return;
LatticeVal &V1State = getValueState(I.getOperand(0));
LatticeVal &V2State = getValueState(I.getOperand(1));
if (V1State.isOverdefined() || V2State.isOverdefined()) {
// If both operands are PHI nodes, it is possible that this instruction has
// a constant value, despite the fact that the PHI node doesn't. Check for
// this condition now.
if (PHINode *PN1 = dyn_cast<PHINode>(I.getOperand(0)))
if (PHINode *PN2 = dyn_cast<PHINode>(I.getOperand(1)))
if (PN1->getParent() == PN2->getParent()) {
// Since the two PHI nodes are in the same basic block, they must have
// entries for the same predecessors. Walk the predecessor list, and
// if all of the incoming values are constants, and the result of
// evaluating this expression with all incoming value pairs is the
// same, then this expression is a constant even though the PHI node
// is not a constant!
LatticeVal Result;
for (unsigned i = 0, e = PN1->getNumIncomingValues(); i != e; ++i) {
LatticeVal &In1 = getValueState(PN1->getIncomingValue(i));
BasicBlock *InBlock = PN1->getIncomingBlock(i);
LatticeVal &In2 =
getValueState(PN2->getIncomingValueForBlock(InBlock));
if (In1.isOverdefined() || In2.isOverdefined()) {
Result.markOverdefined();
break; // Cannot fold this operation over the PHI nodes!
} else if (In1.isConstant() && In2.isConstant()) {
Constant *V = Context->getConstantExprCompare(I.getPredicate(),
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
In1.getConstant(),
In2.getConstant());
if (Result.isUndefined())
Result.markConstant(V);
else if (Result.isConstant() && Result.getConstant() != V) {
Result.markOverdefined();
break;
}
}
}
// If we found a constant value here, then we know the instruction is
// constant despite the fact that the PHI nodes are overdefined.
if (Result.isConstant()) {
markConstant(IV, &I, Result.getConstant());
// Remember that this instruction is virtually using the PHI node
// operands.
UsersOfOverdefinedPHIs.insert(std::make_pair(PN1, &I));
UsersOfOverdefinedPHIs.insert(std::make_pair(PN2, &I));
return;
} else if (Result.isUndefined()) {
return;
}
// Okay, this really is overdefined now. Since we might have
// speculatively thought that this was not overdefined before, and
// added ourselves to the UsersOfOverdefinedPHIs list for the PHIs,
// make sure to clean out any entries that we put there, for
// efficiency.
std::multimap<PHINode*, Instruction*>::iterator It, E;
tie(It, E) = UsersOfOverdefinedPHIs.equal_range(PN1);
while (It != E) {
if (It->second == &I) {
UsersOfOverdefinedPHIs.erase(It++);
} else
++It;
}
tie(It, E) = UsersOfOverdefinedPHIs.equal_range(PN2);
while (It != E) {
if (It->second == &I) {
UsersOfOverdefinedPHIs.erase(It++);
} else
++It;
}
}
markOverdefined(IV, &I);
} else if (V1State.isConstant() && V2State.isConstant()) {
markConstant(IV, &I, Context->getConstantExprCompare(I.getPredicate(),