#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
+#include "llvm/LLVMContext.h"
#include "llvm/Pass.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
/// Constant Propagation.
///
class SCCPSolver : public InstVisitor<SCCPSolver> {
+ LLVMContext *Context;
DenseSet<BasicBlock*> BBExecutable;// The basic blocks that are executable
std::map<Value*, LatticeVal> ValueState; // The state each value is in.
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.
Succs[0] = Succs[1] = true;
} else if (BCValue.isConstant()) {
// Constant condition variables mean the branch can only go a single way
- Succs[BCValue.getConstant() == ConstantInt::getFalse()] = true;
+ Succs[BCValue.getConstant() == Context->getFalse()] = true;
}
}
} else if (isa<InvokeInst>(&TI)) {
} else if (SCValue.isConstant())
Succs[SI->findCaseValue(cast<ConstantInt>(SCValue.getConstant()))] = true;
} else {
- assert(0 && "SCCP: Don't know how to handle this terminator!");
+ llvm_unreachable("SCCP: Don't know how to handle this terminator!");
}
}
// Constant condition variables mean the branch can only go a single way
return BI->getSuccessor(BCValue.getConstant() ==
- ConstantInt::getFalse()) == To;
+ Context->getFalse()) == To;
}
return false;
}
}
return false;
} else {
+#ifndef NDEBUG
cerr << "Unknown terminator instruction: " << *TI;
- abort();
+#endif
+ llvm_unreachable(0);
}
}
DenseMap<std::pair<Function*, unsigned>, LatticeVal>::iterator
It = TrackedMultipleRetVals.find(std::make_pair(F, i));
if (It == TrackedMultipleRetVals.end()) break;
- Value *Val = FindInsertedValue(I.getOperand(0), i);
- mergeInValue(It->second, F, getValueState(Val));
+ if (Value *Val = FindInsertedValue(I.getOperand(0), i, I.getContext()))
+ mergeInValue(It->second, F, getValueState(Val));
}
}
}
if (VState.isOverdefined()) // Inherit overdefinedness of operand
markOverdefined(&I);
else if (VState.isConstant()) // Propagate constant value
- markConstant(&I, ConstantExpr::getCast(I.getOpcode(),
+ markConstant(&I, Context->getConstantExprCast(I.getOpcode(),
VState.getConstant(), I.getType()));
}
if (NonOverdefVal->isUndefined()) {
// Could annihilate value.
if (I.getOpcode() == Instruction::And)
- markConstant(IV, &I, Constant::getNullValue(I.getType()));
+ markConstant(IV, &I, Context->getNullValue(I.getType()));
else if (const VectorType *PT = dyn_cast<VectorType>(I.getType()))
- markConstant(IV, &I, ConstantVector::getAllOnesValue(PT));
+ markConstant(IV, &I, Context->getAllOnesValue(PT));
else
- markConstant(IV, &I, ConstantInt::getAllOnesValue(I.getType()));
+ markConstant(IV, &I,
+ Context->getAllOnesValue(I.getType()));
return;
} else {
if (I.getOpcode() == Instruction::And) {
Result.markOverdefined();
break; // Cannot fold this operation over the PHI nodes!
} else if (In1.isConstant() && In2.isConstant()) {
- Constant *V = ConstantExpr::get(I.getOpcode(), In1.getConstant(),
+ Constant *V =
+ Context->getConstantExpr(I.getOpcode(), In1.getConstant(),
In2.getConstant());
if (Result.isUndefined())
Result.markConstant(V);
markOverdefined(IV, &I);
} else if (V1State.isConstant() && V2State.isConstant()) {
- markConstant(IV, &I, ConstantExpr::get(I.getOpcode(), V1State.getConstant(),
+ markConstant(IV, &I,
+ Context->getConstantExpr(I.getOpcode(), V1State.getConstant(),
V2State.getConstant()));
}
}
Result.markOverdefined();
break; // Cannot fold this operation over the PHI nodes!
} else if (In1.isConstant() && In2.isConstant()) {
- Constant *V = ConstantExpr::getCompare(I.getPredicate(),
+ Constant *V = Context->getConstantExprCompare(I.getPredicate(),
In1.getConstant(),
In2.getConstant());
if (Result.isUndefined())
markOverdefined(IV, &I);
} else if (V1State.isConstant() && V2State.isConstant()) {
- markConstant(IV, &I, ConstantExpr::getCompare(I.getPredicate(),
+ markConstant(IV, &I, Context->getConstantExprCompare(I.getPredicate(),
V1State.getConstant(),
V2State.getConstant()));
}
Constant *Ptr = Operands[0];
Operands.erase(Operands.begin()); // Erase the pointer from idx list...
- markConstant(IV, &I, ConstantExpr::getGetElementPtr(Ptr, &Operands[0],
+ markConstant(IV, &I, Context->getConstantExprGetElementPtr(Ptr, &Operands[0],
Operands.size()));
}
if (isa<ConstantPointerNull>(Ptr) &&
cast<PointerType>(Ptr->getType())->getAddressSpace() == 0) {
// load null -> null
- markConstant(IV, &I, Constant::getNullValue(I.getType()));
+ markConstant(IV, &I, Context->getNullValue(I.getType()));
return;
}
// Transform load (constant global) into the value loaded.
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Ptr)) {
if (GV->isConstant()) {
- if (!GV->isDeclaration() && !GV->mayBeOverridden()) {
+ if (GV->hasDefinitiveInitializer()) {
markConstant(IV, &I, GV->getInitializer());
return;
}
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr))
if (CE->getOpcode() == Instruction::GetElementPtr)
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(CE->getOperand(0)))
- if (GV->isConstant() && !GV->isDeclaration() && !GV->mayBeOverridden())
+ if (GV->isConstant() && GV->hasDefinitiveInitializer())
if (Constant *V =
- ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE)) {
+ ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE,
+ *Context)) {
markConstant(IV, &I, V);
return;
}
// If we can constant fold this, mark the result of the call as a
// constant.
- if (Constant *C = ConstantFoldCall(F, &Operands[0], Operands.size())) {
+ if (Constant *C = ConstantFoldCall(F, Operands.data(), Operands.size())) {
markConstant(I, C);
return;
}
// to be handled here, because we don't know whether the top part is 1's
// or 0's.
assert(Op0LV.isUndefined());
- markForcedConstant(LV, I, Constant::getNullValue(ITy));
+ markForcedConstant(LV, I, Context->getNullValue(ITy));
return true;
case Instruction::Mul:
case Instruction::And:
// undef * X -> 0. X could be zero.
// undef & X -> 0. X could be zero.
- markForcedConstant(LV, I, Constant::getNullValue(ITy));
+ markForcedConstant(LV, I, Context->getNullValue(ITy));
return true;
case Instruction::Or:
// undef | X -> -1. X could be -1.
if (const VectorType *PTy = dyn_cast<VectorType>(ITy))
- markForcedConstant(LV, I, ConstantVector::getAllOnesValue(PTy));
+ markForcedConstant(LV, I,
+ Context->getAllOnesValue(PTy));
else
- markForcedConstant(LV, I, ConstantInt::getAllOnesValue(ITy));
+ markForcedConstant(LV, I, Context->getAllOnesValue(ITy));
return true;
case Instruction::SDiv:
// undef / X -> 0. X could be maxint.
// undef % X -> 0. X could be 1.
- markForcedConstant(LV, I, Constant::getNullValue(ITy));
+ markForcedConstant(LV, I, Context->getNullValue(ITy));
return true;
case Instruction::AShr:
// X >> undef -> 0. X could be 0.
// X << undef -> 0. X could be 0.
- markForcedConstant(LV, I, Constant::getNullValue(ITy));
+ markForcedConstant(LV, I, Context->getNullValue(ITy));
return true;
case Instruction::Select:
// undef ? X : Y -> X or Y. There could be commonality between X/Y.
// as undef, then further analysis could think the undef went another way
// leading to an inconsistent set of conclusions.
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
- BI->setCondition(ConstantInt::getFalse());
+ BI->setCondition(Context->getFalse());
} else {
SwitchInst *SI = cast<SwitchInst>(TI);
SI->setCondition(SI->getCaseValue(1));
bool SCCP::runOnFunction(Function &F) {
DOUT << "SCCP on function '" << F.getNameStart() << "'\n";
SCCPSolver Solver;
+ Solver.setContext(&F.getContext());
// Mark the first block of the function as being executable.
Solver.MarkBlockExecutable(F.begin());
Instruction *I = Insts.back();
Insts.pop_back();
if (!I->use_empty())
- I->replaceAllUsesWith(UndefValue::get(I->getType()));
+ I->replaceAllUsesWith(F.getContext().getUndef(I->getType()));
BB->getInstList().erase(I);
MadeChanges = true;
++NumInstRemoved;
continue;
Constant *Const = IV.isConstant()
- ? IV.getConstant() : UndefValue::get(Inst->getType());
+ ? IV.getConstant() : F.getContext().getUndef(Inst->getType());
DOUT << " Constant: " << *Const << " = " << *Inst;
// Replaces all of the uses of a variable with uses of the constant.
}
bool IPSCCP::runOnModule(Module &M) {
+ LLVMContext *Context = &M.getContext();
+
SCCPSolver Solver;
+ Solver.setContext(Context);
// Loop over all functions, marking arguments to those with their addresses
// taken or that are external as overdefined.
LatticeVal &IV = Values[AI];
if (IV.isConstant() || IV.isUndefined()) {
Constant *CST = IV.isConstant() ?
- IV.getConstant() : UndefValue::get(AI->getType());
+ IV.getConstant() : Context->getUndef(AI->getType());
DOUT << "*** Arg " << *AI << " = " << *CST <<"\n";
// Replaces all of the uses of a variable with uses of the
Instruction *I = Insts.back();
Insts.pop_back();
if (!I->use_empty())
- I->replaceAllUsesWith(UndefValue::get(I->getType()));
+ I->replaceAllUsesWith(Context->getUndef(I->getType()));
BB->getInstList().erase(I);
MadeChanges = true;
++IPNumInstRemoved;
TI->getSuccessor(i)->removePredecessor(BB);
}
if (!TI->use_empty())
- TI->replaceAllUsesWith(UndefValue::get(TI->getType()));
+ TI->replaceAllUsesWith(Context->getUndef(TI->getType()));
BB->getInstList().erase(TI);
if (&*BB != &F->front())
continue;
Constant *Const = IV.isConstant()
- ? IV.getConstant() : UndefValue::get(Inst->getType());
+ ? IV.getConstant() : Context->getUndef(Inst->getType());
DOUT << " Constant: " << *Const << " = " << *Inst;
// Replaces all of the uses of a variable with uses of the
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(I)) {
assert(isa<UndefValue>(SI->getCondition()) && "Switch should fold");
} else {
- assert(0 && "Didn't fold away reference to block!");
+ llvm_unreachable("Didn't fold away reference to block!");
}
#endif
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator()))
if (!isa<UndefValue>(RI->getOperand(0)))
- RI->setOperand(0, UndefValue::get(F->getReturnType()));
+ RI->setOperand(0, Context->getUndef(F->getReturnType()));
}
// If we infered constant or undef values for globals variables, we can delete