Newer
Older
markOverdefined(IV, I);
return;
}
std::vector<Constant*> Operands;
Operands.reserve(I->getNumOperands()-1);
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(IV, I);
return;
}
assert(State.isConstant() && "Unknown state!");
Operands.push_back(State.getConstant());
}
if (Constant *C = ConstantFoldCall(F, Operands))
markConstant(IV, I, C);
markOverdefined(IV, I);
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
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
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.
markForcedConstant(LV, I, ConstantInt::getAllOnesValue(ITy));
return true;
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;
}
}
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 (!getValueState(SI->getCondition()).isUndefined())
continue;
} else {
continue;
// If the edge to the first successor isn't thought to be feasible yet, mark
// it so now.
if (KnownFeasibleEdges.count(Edge(BB, TI->getSuccessor(0))))
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(0));
return true;
}
namespace {
Chris Lattner
committed
//===--------------------------------------------------------------------===//
//
Chris Lattner
committed
/// SCCP Class - This class uses the SCCPSolver to implement a per-function
/// Sparse Conditional COnstant Propagator.
///
struct SCCP : public FunctionPass {
// 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();
}
};
RegisterPass<SCCP> X("sccp", "Sparse Conditional Constant Propagation");
} // end anonymous namespace
// 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.getName() << "'\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.
hash_map<Value*, LatticeVal> &Values = Solver.getValueMapping();
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.
//
std::set<BasicBlock*> &ExecutableBBs = Solver.getExecutableBlocks();
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.
std::vector<Instruction*> Insts;
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) {
LatticeVal &IV = Values[Inst];
if (IV.isConstant() || IV.isUndefined() &&
!isa<TerminatorInst>(Inst)) {
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.
BB->getInstList().erase(Inst);
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
// Hey, we just changed something!
MadeChanges = true;
++NumInstRemoved;
}
}
}
}
return MadeChanges;
}
namespace {
//===--------------------------------------------------------------------===//
//
/// IPSCCP Class - This class implements interprocedural Sparse Conditional
/// Constant Propagation.
///
struct IPSCCP : public ModulePass {
bool runOnModule(Module &M);
};
RegisterPass<IPSCCP>
Y("ipsccp", "Interprocedural Sparse Conditional Constant Propagation");
} // end anonymous namespace
// 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.
//
hash_map<Value*, LatticeVal> &Values = Solver.getValueMapping();
for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
if (!F->hasInternalLinkage() || AddressIsTaken(F)) {
if (!F->isExternal())
Solver.MarkBlockExecutable(F->begin());
for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
AI != E; ++AI)
Values[AI].markOverdefined();
} 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.
//
std::set<BasicBlock*> &ExecutableBBs = Solver.getExecutableBlocks();
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;
}
}
std::vector<BasicBlock*> BlocksToErase;
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.
std::vector<Instruction*> Insts;
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->begin() != Succ->end() && 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++;
if (Inst->getType() != Type::VoidTy) {
LatticeVal &IV = Values[Inst];
if (IV.isConstant() || IV.isUndefined() &&
!isa<TerminatorInst>(Inst)) {
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<TerminatorInst>(Inst) && !isa<CallInst>(Inst))
BB->getInstList().erase(Inst);
// 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());
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
if (!Folded) {
// The constant folder may not have been able to fold the termiantor
// 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();
new BranchInst(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);
}
// 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.
const hash_map<Function*, LatticeVal> &RV =Solver.getTrackedFunctionRetVals();
for (hash_map<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 hash_map<GlobalVariable*, LatticeVal> &TG = Solver.getTrackedGlobals();
for (hash_map<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->getName()<< "' is constant!\n";
while (!GV->use_empty()) {
StoreInst *SI = cast<StoreInst>(GV->use_back());
SI->eraseFromParent();
}
M.getGlobalList().erase(GV);
}
return MadeChanges;
}