Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
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, ConstantExpr::getCompare(I.getPredicate(),
V1State.getConstant(),
V2State.getConstant()));
}
}
void SCCPSolver::visitExtractElementInst(ExtractElementInst &I) {
// FIXME : SCCP does not handle vectors properly.
markOverdefined(&I);
return;
#if 0
LatticeVal &ValState = getValueState(I.getOperand(0));
LatticeVal &IdxState = getValueState(I.getOperand(1));
if (ValState.isOverdefined() || IdxState.isOverdefined())
markOverdefined(&I);
else if(ValState.isConstant() && IdxState.isConstant())
markConstant(&I, ConstantExpr::getExtractElement(ValState.getConstant(),
IdxState.getConstant()));
#endif
void SCCPSolver::visitInsertElementInst(InsertElementInst &I) {
// FIXME : SCCP does not handle vectors properly.
markOverdefined(&I);
return;
#if 0
LatticeVal &ValState = getValueState(I.getOperand(0));
LatticeVal &EltState = getValueState(I.getOperand(1));
LatticeVal &IdxState = getValueState(I.getOperand(2));
if (ValState.isOverdefined() || EltState.isOverdefined() ||
IdxState.isOverdefined())
markOverdefined(&I);
else if(ValState.isConstant() && EltState.isConstant() &&
IdxState.isConstant())
markConstant(&I, ConstantExpr::getInsertElement(ValState.getConstant(),
EltState.getConstant(),
IdxState.getConstant()));
else if (ValState.isUndefined() && EltState.isConstant() &&
IdxState.isConstant())
markConstant(&I,ConstantExpr::getInsertElement(UndefValue::get(I.getType()),
EltState.getConstant(),
IdxState.getConstant()));
#endif
void SCCPSolver::visitShuffleVectorInst(ShuffleVectorInst &I) {
// FIXME : SCCP does not handle vectors properly.
markOverdefined(&I);
return;
#if 0
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
LatticeVal &V1State = getValueState(I.getOperand(0));
LatticeVal &V2State = getValueState(I.getOperand(1));
LatticeVal &MaskState = getValueState(I.getOperand(2));
if (MaskState.isUndefined() ||
(V1State.isUndefined() && V2State.isUndefined()))
return; // Undefined output if mask or both inputs undefined.
if (V1State.isOverdefined() || V2State.isOverdefined() ||
MaskState.isOverdefined()) {
markOverdefined(&I);
} else {
// A mix of constant/undef inputs.
Constant *V1 = V1State.isConstant() ?
V1State.getConstant() : UndefValue::get(I.getType());
Constant *V2 = V2State.isConstant() ?
V2State.getConstant() : UndefValue::get(I.getType());
Constant *Mask = MaskState.isConstant() ?
MaskState.getConstant() : UndefValue::get(I.getOperand(2)->getType());
markConstant(&I, ConstantExpr::getShuffleVector(V1, V2, Mask));
}
#endif
// Handle getelementptr instructions... if all operands are constants then we
// can turn this into a getelementptr ConstantExpr.
//
void SCCPSolver::visitGetElementPtrInst(GetElementPtrInst &I) {
LatticeVal &IV = ValueState[&I];
if (IV.isOverdefined()) return;
SmallVector<Constant*, 8> Operands;
Operands.reserve(I.getNumOperands());
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
LatticeVal &State = getValueState(I.getOperand(i));
if (State.isUndefined())
return; // Operands are not resolved yet...
else if (State.isOverdefined()) {
markOverdefined(IV, &I);
return;
}
assert(State.isConstant() && "Unknown state!");
Operands.push_back(State.getConstant());
}
Constant *Ptr = Operands[0];
Operands.erase(Operands.begin()); // Erase the pointer from idx list...
markConstant(IV, &I, ConstantExpr::getGetElementPtr(Ptr, &Operands[0],
Operands.size()));
}
void SCCPSolver::visitStoreInst(Instruction &SI) {
if (TrackedGlobals.empty() || !isa<GlobalVariable>(SI.getOperand(1)))
return;
GlobalVariable *GV = cast<GlobalVariable>(SI.getOperand(1));
DenseMap<GlobalVariable*, LatticeVal>::iterator I = TrackedGlobals.find(GV);
if (I == TrackedGlobals.end() || I->second.isOverdefined()) return;
// Get the value we are storing into the global.
LatticeVal &PtrVal = getValueState(SI.getOperand(0));
mergeInValue(I->second, GV, PtrVal);
if (I->second.isOverdefined())
TrackedGlobals.erase(I); // No need to keep tracking this!
}
// Handle load instructions. If the operand is a constant pointer to a constant
// global, we can replace the load with the loaded constant value!
void SCCPSolver::visitLoadInst(LoadInst &I) {
LatticeVal &IV = ValueState[&I];
if (IV.isOverdefined()) return;
LatticeVal &PtrVal = getValueState(I.getOperand(0));
if (PtrVal.isUndefined()) return; // The pointer is not resolved yet!
if (PtrVal.isConstant() && !I.isVolatile()) {
Value *Ptr = PtrVal.getConstant();
Christopher Lamb
committed
// TODO: Consider a target hook for valid address spaces for this xform.
if (isa<ConstantPointerNull>(Ptr) &&
cast<PointerType>(Ptr->getType())->getAddressSpace() == 0) {
Chris Lattner
committed
// load null -> null
markConstant(IV, &I, Constant::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()) {
markConstant(IV, &I, GV->getInitializer());
return;
}
} else if (!TrackedGlobals.empty()) {
// If we are tracking this global, merge in the known value for it.
DenseMap<GlobalVariable*, LatticeVal>::iterator It =
TrackedGlobals.find(GV);
if (It != TrackedGlobals.end()) {
mergeInValue(IV, &I, It->second);
return;
}
}
}
// Transform load (constantexpr_GEP global, 0, ...) into the value loaded.
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())
ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE)) {
markConstant(IV, &I, V);
return;
}
}
// Otherwise we cannot say for certain what value this load will produce.
// Bail out.
markOverdefined(IV, &I);
}
void SCCPSolver::visitCallSite(CallSite CS) {
Function *F = CS.getCalledFunction();
Instruction *I = CS.getInstruction();
// The common case is that we aren't tracking the callee, either because we
// are not doing interprocedural analysis or the callee is indirect, or is
// external. Handle these cases first.
if (F == 0 || !F->hasInternalLinkage()) {
CallOverdefined:
// Void return and not tracking callee, just bail.
if (I->getType() == Type::VoidTy) return;
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
// Otherwise, if we have a single return value case, and if the function is
// a declaration, maybe we can constant fold it.
if (!isa<StructType>(I->getType()) && F && F->isDeclaration() &&
canConstantFoldCallTo(F)) {
SmallVector<Constant*, 8> Operands;
for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
AI != E; ++AI) {
LatticeVal &State = getValueState(*AI);
if (State.isUndefined())
return; // Operands are not resolved yet.
else if (State.isOverdefined()) {
markOverdefined(I);
return;
}
assert(State.isConstant() && "Unknown state!");
Operands.push_back(State.getConstant());
}
// If we can constant fold this, mark the result of the call as a
// constant.
if (Constant *C = ConstantFoldCall(F, &Operands[0], Operands.size())) {
markConstant(I, C);
return;
}
// Otherwise, we don't know anything about this call, mark it overdefined.
markOverdefined(I);
return;
}
// If this is a single/zero retval case, see if we're tracking the function.
DenseMap<Function*, LatticeVal>::iterator TFRVI = TrackedRetVals.find(F);
if (TFRVI != TrackedRetVals.end()) {
// If so, propagate the return value of the callee into this call result.
mergeInValue(I, TFRVI->second);
} else if (isa<StructType>(I->getType())) {
// Check to see if we're tracking this callee, if not, handle it in the
// common path above.
std::map<std::pair<Function*, unsigned>, LatticeVal>::iterator
TMRVI = TrackedMultipleRetVals.find(std::make_pair(F, 0));
if (TMRVI == TrackedMultipleRetVals.end())
goto CallOverdefined;
// If we are tracking this callee, propagate the return values of the call
// into this call site. We do this by walking all the uses. Single-index
// ExtractValueInst uses can be tracked; anything more complicated is
// currently handled conservatively.
for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
UI != E; ++UI) {
if (GetResultInst *GRI = dyn_cast<GetResultInst>(*UI)) {
mergeInValue(GRI,
TrackedMultipleRetVals[std::make_pair(F, GRI->getIndex())]);
continue;
}
if (ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(*UI)) {
if (EVI->getNumIndices() == 1) {
mergeInValue(EVI,
TrackedMultipleRetVals[std::make_pair(F, *EVI->idx_begin())]);
continue;
}
}
// The aggregate value is used in a way not handled here. Assume nothing.
markOverdefined(*UI);
} else {
// Otherwise we're not tracking this callee, so handle it in the
// common path above.
goto CallOverdefined;
// Finally, if this is the first call to the function hit, mark its entry
// block executable.
if (!BBExecutable.count(F->begin()))
MarkBlockExecutable(F->begin());
// Propagate information from this call site into the callee.
CallSite::arg_iterator CAI = CS.arg_begin();
for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
AI != E; ++AI, ++CAI) {
LatticeVal &IV = ValueState[AI];
if (!IV.isOverdefined())
mergeInValue(IV, AI, getValueState(*CAI));
}
void SCCPSolver::Solve() {
// Process the work lists until they are empty!
while (!BBWorkList.empty() || !InstWorkList.empty() ||
// Process the instruction work list...
while (!OverdefinedInstWorkList.empty()) {
Value *I = OverdefinedInstWorkList.back();
OverdefinedInstWorkList.pop_back();
DOUT << "\nPopped off OI-WL: " << *I;
// "I" got into the work list because it either made the transition from
// bottom to constant
//
// Anything on this worklist that is overdefined need not be visited
// since all of its users will have already been marked as overdefined
// Update all of the users of this instruction's value...
//
for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
UI != E; ++UI)
OperandChangedState(*UI);
}
// Process the instruction work list...
while (!InstWorkList.empty()) {
Value *I = InstWorkList.back();
InstWorkList.pop_back();
DOUT << "\nPopped off I-WL: " << *I;
// "I" got into the work list because it either made the transition from
// bottom to constant
//
// Anything on this worklist that is overdefined need not be visited
// since all of its users will have already been marked as overdefined.
// Update all of the users of this instruction's value...
//
if (!getValueState(I).isOverdefined())
for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
UI != E; ++UI)
OperandChangedState(*UI);
}
// Process the basic block work list...
while (!BBWorkList.empty()) {
BasicBlock *BB = BBWorkList.back();
BBWorkList.pop_back();
DOUT << "\nPopped off BBWL: " << *BB;
// Notify all instructions in this basic block that they are newly
// executable.
visit(BB);
}
}
}
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.
///
/// This method handles this by finding an unresolved branch and marking it one
/// of the edges from the block as being feasible, even though the condition
/// doesn't say it would otherwise be. This allows SCCP to find the rest of the
/// CFG and only slightly pessimizes the analysis results (by marking one,
Chris Lattner
committed
/// potentially infeasible, edge feasible). This cannot usefully modify the
/// constraints on the condition of the branch, as that would impact other users
/// of the value.
Chris Lattner
committed
///
/// This scan also checks for values that use undefs, whose results are actually
/// defined. For example, 'zext i8 undef to i32' should produce all zeros
/// conservatively, as "(zext i8 X -> i32) & 0xFF00" must always return zero,
/// even if X isn't defined.
bool SCCPSolver::ResolvedUndefsIn(Function &F) {
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
if (!BBExecutable.count(BB))
continue;
Chris Lattner
committed
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
// Look for instructions which produce undef values.
if (I->getType() == Type::VoidTy) continue;
LatticeVal &LV = getValueState(I);
if (!LV.isUndefined()) continue;
// Get the lattice values of the first two operands for use below.
LatticeVal &Op0LV = getValueState(I->getOperand(0));
LatticeVal Op1LV;
if (I->getNumOperands() == 2) {
// If this is a two-operand instruction, and if both operands are
// undefs, the result stays undef.
Op1LV = getValueState(I->getOperand(1));
if (Op0LV.isUndefined() && Op1LV.isUndefined())
continue;
}
// If this is an instructions whose result is defined even if the input is
// not fully defined, propagate the information.
const Type *ITy = I->getType();
switch (I->getOpcode()) {
default: break; // Leave the instruction as an undef.
case Instruction::ZExt:
// After a zero extend, we know the top part is zero. SExt doesn't have
// 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));
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));
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));
else
markForcedConstant(LV, I, ConstantInt::getAllOnesValue(ITy));
return true;
Chris Lattner
committed
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
case Instruction::SDiv:
case Instruction::UDiv:
case Instruction::SRem:
case Instruction::URem:
// X / undef -> undef. No change.
// X % undef -> undef. No change.
if (Op1LV.isUndefined()) break;
// undef / X -> 0. X could be maxint.
// undef % X -> 0. X could be 1.
markForcedConstant(LV, I, Constant::getNullValue(ITy));
return true;
case Instruction::AShr:
// undef >>s X -> undef. No change.
if (Op0LV.isUndefined()) break;
// X >>s undef -> X. X could be 0, X could have the high-bit known set.
if (Op0LV.isConstant())
markForcedConstant(LV, I, Op0LV.getConstant());
else
markOverdefined(LV, I);
return true;
case Instruction::LShr:
case Instruction::Shl:
// undef >> X -> undef. No change.
// undef << X -> undef. No change.
if (Op0LV.isUndefined()) break;
// X >> undef -> 0. X could be 0.
// X << undef -> 0. X could be 0.
markForcedConstant(LV, I, Constant::getNullValue(ITy));
return true;
case Instruction::Select:
// undef ? X : Y -> X or Y. There could be commonality between X/Y.
if (Op0LV.isUndefined()) {
if (!Op1LV.isConstant()) // Pick the constant one if there is any.
Op1LV = getValueState(I->getOperand(2));
} else if (Op1LV.isUndefined()) {
// c ? undef : undef -> undef. No change.
Op1LV = getValueState(I->getOperand(2));
if (Op1LV.isUndefined())
break;
// Otherwise, c ? undef : x -> x.
} else {
// Leave Op1LV as Operand(1)'s LatticeValue.
}
if (Op1LV.isConstant())
markForcedConstant(LV, I, Op1LV.getConstant());
else
markOverdefined(LV, I);
return true;
case Instruction::Call:
// If a call has an undef result, it is because it is constant foldable
// but one of the inputs was undef. Just force the result to
// overdefined.
markOverdefined(LV, I);
Chris Lattner
committed
return true;
}
}
TerminatorInst *TI = BB->getTerminator();
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
if (!BI->isConditional()) continue;
if (!getValueState(BI->getCondition()).isUndefined())
continue;
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
if (SI->getNumSuccessors()<2) // no cases
continue;
if (!getValueState(SI->getCondition()).isUndefined())
continue;
} else {
continue;
// If the edge to the second successor isn't thought to be feasible yet,
// mark it so now. We pick the second one so that this goes to some
// enumerated value in a switch instead of going to the default destination.
if (KnownFeasibleEdges.count(Edge(BB, TI->getSuccessor(1))))
continue;
// Otherwise, it isn't already thought to be feasible. Mark it as such now
// and return. This will make other blocks reachable, which will allow new
// values to be discovered and existing ones to be moved in the lattice.
markEdgeExecutable(BB, TI->getSuccessor(1));
// This must be a conditional branch of switch on undef. At this point,
// force the old terminator to branch to the first successor. This is
// required because we are now influencing the dataflow of the function with
// the assumption that this edge is taken. If we leave the branch condition
// 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());
} else {
SwitchInst *SI = cast<SwitchInst>(TI);
SI->setCondition(SI->getCaseValue(1));
}
namespace {
Chris Lattner
committed
//===--------------------------------------------------------------------===//
//
Chris Lattner
committed
/// SCCP Class - This class uses the SCCPSolver to implement a per-function
Chris Lattner
committed
///
struct VISIBILITY_HIDDEN SCCP : public FunctionPass {
static char ID; // Pass identification, replacement for typeid
SCCP() : FunctionPass((intptr_t)&ID) {}
Chris Lattner
committed
// runOnFunction - Run the Sparse Conditional Constant Propagation
// algorithm, and return true if the function was modified.
//
bool runOnFunction(Function &F);
Chris Lattner
committed
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
}
};
} // end anonymous namespace
char SCCP::ID = 0;
static RegisterPass<SCCP>
X("sccp", "Sparse Conditional Constant Propagation");
// createSCCPPass - This is the public interface to this file...
FunctionPass *llvm::createSCCPPass() {
return new SCCP();
}
// runOnFunction() - Run the Sparse Conditional Constant Propagation algorithm,
// and return true if the function was modified.
//
bool SCCP::runOnFunction(Function &F) {
DOUT << "SCCP on function '" << F.getNameStart() << "'\n";
SCCPSolver Solver;
// Mark the first block of the function as being executable.
Solver.MarkBlockExecutable(F.begin());
// Mark all arguments to the function as being overdefined.
for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end(); AI != E;++AI)
// Solve for constants.
Chris Lattner
committed
bool ResolvedUndefs = true;
while (ResolvedUndefs) {
Chris Lattner
committed
DOUT << "RESOLVING UNDEFs\n";
ResolvedUndefs = Solver.ResolvedUndefsIn(F);
bool MadeChanges = false;
// If we decided that there are basic blocks that are dead in this function,
// delete their contents now. Note that we cannot actually delete the blocks,
// as we cannot modify the CFG of the function.
//
SmallSet<BasicBlock*, 16> &ExecutableBBs = Solver.getExecutableBlocks();
Chris Lattner
committed
SmallVector<Instruction*, 32> Insts;
std::map<Value*, LatticeVal> &Values = Solver.getValueMapping();
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
if (!ExecutableBBs.count(BB)) {
DOUT << " BasicBlock Dead:" << *BB;
// Delete the instructions backwards, as it has a reduced likelihood of
// having to update as many def-use and use-def chains.
for (BasicBlock::iterator I = BB->begin(), E = BB->getTerminator();
I != E; ++I)
Insts.push_back(I);
while (!Insts.empty()) {
Instruction *I = Insts.back();
Insts.pop_back();
if (!I->use_empty())
I->replaceAllUsesWith(UndefValue::get(I->getType()));
BB->getInstList().erase(I);
MadeChanges = true;
} else {
// Iterate over all of the instructions in a function, replacing them with
// constants if we have found them to be of constant values.
//
for (BasicBlock::iterator BI = BB->begin(), E = BB->end(); BI != E; ) {
Instruction *Inst = BI++;
if (Inst->getType() == Type::VoidTy ||
isa<StructType>(Inst->getType()) ||
isa<TerminatorInst>(Inst))
continue;
LatticeVal &IV = Values[Inst];
if (!IV.isConstant() && !IV.isUndefined())
continue;
Constant *Const = IV.isConstant()
? IV.getConstant() : UndefValue::get(Inst->getType());
DOUT << " Constant: " << *Const << " = " << *Inst;
// Replaces all of the uses of a variable with uses of the constant.
Inst->replaceAllUsesWith(Const);
// Delete the instruction.
Inst->eraseFromParent();
// Hey, we just changed something!
MadeChanges = true;
++NumInstRemoved;
}
}
return MadeChanges;
}
namespace {
//===--------------------------------------------------------------------===//
//
/// IPSCCP Class - This class implements interprocedural Sparse Conditional
/// Constant Propagation.
///
struct VISIBILITY_HIDDEN IPSCCP : public ModulePass {
IPSCCP() : ModulePass((intptr_t)&ID) {}
bool runOnModule(Module &M);
};
} // end anonymous namespace
char IPSCCP::ID = 0;
static RegisterPass<IPSCCP>
Y("ipsccp", "Interprocedural Sparse Conditional Constant Propagation");
// createIPSCCPPass - This is the public interface to this file...
ModulePass *llvm::createIPSCCPPass() {
return new IPSCCP();
}
static bool AddressIsTaken(GlobalValue *GV) {
// Delete any dead constantexpr klingons.
GV->removeDeadConstantUsers();
for (Value::use_iterator UI = GV->use_begin(), E = GV->use_end();
UI != E; ++UI)
if (StoreInst *SI = dyn_cast<StoreInst>(*UI)) {
if (SI->getOperand(0) == GV || SI->isVolatile())
return true; // Storing addr of GV.
} else if (isa<InvokeInst>(*UI) || isa<CallInst>(*UI)) {
// Make sure we are calling the function, not passing the address.
CallSite CS = CallSite::get(cast<Instruction>(*UI));
for (CallSite::arg_iterator AI = CS.arg_begin(),
E = CS.arg_end(); AI != E; ++AI)
if (*AI == GV)
return true;
} else if (LoadInst *LI = dyn_cast<LoadInst>(*UI)) {
if (LI->isVolatile())
return true;
} else {
return true;
}
return false;
}
bool IPSCCP::runOnModule(Module &M) {
SCCPSolver Solver;
// Loop over all functions, marking arguments to those with their addresses
// taken or that are external as overdefined.
//
for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
if (!F->hasInternalLinkage() || AddressIsTaken(F)) {
if (!F->isDeclaration())
Solver.MarkBlockExecutable(F->begin());
for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
AI != E; ++AI)
} else {
Solver.AddTrackedFunction(F);
// Loop over global variables. We inform the solver about any internal global
// variables that do not have their 'addresses taken'. If they don't have
// their addresses taken, we can propagate constants through them.
for (Module::global_iterator G = M.global_begin(), E = M.global_end();
G != E; ++G)
if (!G->isConstant() && G->hasInternalLinkage() && !AddressIsTaken(G))
Solver.TrackValueOfGlobalVariable(G);
// Solve for constants.
Chris Lattner
committed
bool ResolvedUndefs = true;
while (ResolvedUndefs) {
Chris Lattner
committed
DOUT << "RESOLVING UNDEFS\n";
ResolvedUndefs = false;
for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
Chris Lattner
committed
ResolvedUndefs |= Solver.ResolvedUndefsIn(*F);
bool MadeChanges = false;
// Iterate over all of the instructions in the module, replacing them with
// constants if we have found them to be of constant values.
//
SmallSet<BasicBlock*, 16> &ExecutableBBs = Solver.getExecutableBlocks();
Chris Lattner
committed
SmallVector<Instruction*, 32> Insts;
SmallVector<BasicBlock*, 32> BlocksToErase;
std::map<Value*, LatticeVal> &Values = Solver.getValueMapping();
Chris Lattner
committed
for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
AI != E; ++AI)
if (!AI->use_empty()) {
LatticeVal &IV = Values[AI];
if (IV.isConstant() || IV.isUndefined()) {
Constant *CST = IV.isConstant() ?
IV.getConstant() : UndefValue::get(AI->getType());
DOUT << "*** Arg " << *AI << " = " << *CST <<"\n";
// Replaces all of the uses of a variable with uses of the
// constant.
AI->replaceAllUsesWith(CST);
++IPNumArgsElimed;
}
}
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
if (!ExecutableBBs.count(BB)) {
DOUT << " BasicBlock Dead:" << *BB;
++IPNumDeadBlocks;
// Delete the instructions backwards, as it has a reduced likelihood of
// having to update as many def-use and use-def chains.
TerminatorInst *TI = BB->getTerminator();
for (BasicBlock::iterator I = BB->begin(), E = TI; I != E; ++I)
Insts.push_back(I);
while (!Insts.empty()) {
Instruction *I = Insts.back();
Insts.pop_back();
if (!I->use_empty())
I->replaceAllUsesWith(UndefValue::get(I->getType()));
BB->getInstList().erase(I);
MadeChanges = true;
++IPNumInstRemoved;
}
for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) {
BasicBlock *Succ = TI->getSuccessor(i);
if (!Succ->empty() && isa<PHINode>(Succ->begin()))
TI->getSuccessor(i)->removePredecessor(BB);
}
if (!TI->use_empty())
TI->replaceAllUsesWith(UndefValue::get(TI->getType()));
BB->getInstList().erase(TI);
if (&*BB != &F->front())
BlocksToErase.push_back(BB);
else
new UnreachableInst(BB);
} else {
for (BasicBlock::iterator BI = BB->begin(), E = BB->end(); BI != E; ) {
Instruction *Inst = BI++;
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
if (Inst->getType() == Type::VoidTy ||
isa<StructType>(Inst->getType()) ||
isa<TerminatorInst>(Inst))
continue;
LatticeVal &IV = Values[Inst];
if (!IV.isConstant() && !IV.isUndefined())
continue;
Constant *Const = IV.isConstant()
? IV.getConstant() : UndefValue::get(Inst->getType());
DOUT << " Constant: " << *Const << " = " << *Inst;
// Replaces all of the uses of a variable with uses of the
// constant.
Inst->replaceAllUsesWith(Const);
// Delete the instruction.
if (!isa<CallInst>(Inst))
Inst->eraseFromParent();
// Hey, we just changed something!
MadeChanges = true;
++IPNumInstRemoved;
}
}
// Now that all instructions in the function are constant folded, erase dead
// blocks, because we can now use ConstantFoldTerminator to get rid of
// in-edges.
for (unsigned i = 0, e = BlocksToErase.size(); i != e; ++i) {
// If there are any PHI nodes in this successor, drop entries for BB now.
BasicBlock *DeadBB = BlocksToErase[i];
while (!DeadBB->use_empty()) {
Instruction *I = cast<Instruction>(DeadBB->use_back());
bool Folded = ConstantFoldTerminator(I->getParent());
if (!Folded) {
// The constant folder may not have been able to fold the terminator
// if this is a branch or switch on undef. Fold it manually as a
// branch to the first successor.
if (BranchInst *BI = dyn_cast<BranchInst>(I)) {
assert(BI->isConditional() && isa<UndefValue>(BI->getCondition()) &&
"Branch should be foldable!");
} 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!");
}
// Make this an uncond branch to the first successor.
TerminatorInst *TI = I->getParent()->getTerminator();
BranchInst::Create(TI->getSuccessor(0), TI);
// Remove entries in successor phi nodes to remove edges.
for (unsigned i = 1, e = TI->getNumSuccessors(); i != e; ++i)
TI->getSuccessor(i)->removePredecessor(TI->getParent());
// Remove the old terminator.
TI->eraseFromParent();
}
}
// Finally, delete the basic block.
F->getBasicBlockList().erase(DeadBB);
}
Chris Lattner
committed
BlocksToErase.clear();
// If we inferred constant or undef return values for a function, we replaced
// all call uses with the inferred value. This means we don't need to bother
// actually returning anything from the function. Replace all return
// instructions with return undef.
// TODO: Process multiple value ret instructions also.
const DenseMap<Function*, LatticeVal> &RV = Solver.getTrackedRetVals();
for (DenseMap<Function*, LatticeVal>::const_iterator I = RV.begin(),
E = RV.end(); I != E; ++I)
if (!I->second.isOverdefined() &&
I->first->getReturnType() != Type::VoidTy) {
Function *F = I->first;
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()));
}
// If we infered constant or undef values for globals variables, we can delete
// the global and any stores that remain to it.
const DenseMap<GlobalVariable*, LatticeVal> &TG = Solver.getTrackedGlobals();
for (DenseMap<GlobalVariable*, LatticeVal>::const_iterator I = TG.begin(),
E = TG.end(); I != E; ++I) {
GlobalVariable *GV = I->first;
assert(!I->second.isOverdefined() &&
"Overdefined values should have been taken out of the map!");
DOUT << "Found that GV '" << GV->getNameStart() << "' is constant!\n";
while (!GV->use_empty()) {
StoreInst *SI = cast<StoreInst>(GV->use_back());
SI->eraseFromParent();
}
M.getGlobalList().erase(GV);
}
return MadeChanges;
}