#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
#include <algorithm>
-#include <iostream>
#include <set>
using namespace llvm;
/// 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) {
- DEBUG(std::cerr << "Marking Block Executable: " << BB->getName() << "\n");
+ DOUT << "Marking Block Executable: " << BB->getName() << "\n";
BBExecutable.insert(BB); // Basic block is executable!
BBWorkList.push_back(BB); // Add the block to the work list!
}
//
inline void markConstant(LatticeVal &IV, Value *V, Constant *C) {
if (IV.markConstant(C)) {
- DEBUG(std::cerr << "markConstant: " << *C << ": " << *V);
+ DOUT << "markConstant: " << *C << ": " << *V;
InstWorkList.push_back(V);
}
}
inline void markOverdefined(LatticeVal &IV, Value *V) {
if (IV.markOverdefined()) {
- DEBUG(std::cerr << "markOverdefined: ";
+ DEBUG(DOUT << "markOverdefined: ";
if (Function *F = dyn_cast<Function>(V))
- std::cerr << "Function '" << F->getName() << "'\n";
+ DOUT << "Function '" << F->getName() << "'\n";
else
- std::cerr << *V);
+ DOUT << *V);
// Only instructions go on the work list
OverdefinedInstWorkList.push_back(V);
}
return; // This edge is already known to be executable!
if (BBExecutable.count(Dest)) {
- DEBUG(std::cerr << "Marking Edge Executable: " << Source->getName()
- << " -> " << Dest->getName() << "\n");
+ DOUT << "Marking Edge Executable: " << Source->getName()
+ << " -> " << Dest->getName() << "\n";
// The destination is already executable, but we just made an edge
// feasible that wasn't before. Revisit the PHI nodes in the block
void visitInstruction(Instruction &I) {
// If a new instruction is added to LLVM that we don't handle...
- std::cerr << "SCCP: Don't know how to handle: " << I;
+ cerr << "SCCP: Don't know how to handle: " << I;
markOverdefined(&I); // Just in case
}
};
Succs[BCValue.getConstant() == ConstantBool::getFalse()] = true;
}
}
- } else if (InvokeInst *II = dyn_cast<InvokeInst>(&TI)) {
+ } else if (isa<InvokeInst>(&TI)) {
// Invoke instructions successors are always executable.
Succs[0] = Succs[1] = true;
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(&TI)) {
Succs[0] = true;
}
} else {
- std::cerr << "SCCP: Don't know how to handle: " << TI;
+ cerr << "SCCP: Don't know how to handle: " << TI;
Succs.assign(TI.getNumSuccessors(), true);
}
}
}
return false;
}
- } else if (InvokeInst *II = dyn_cast<InvokeInst>(TI)) {
+ } else if (isa<InvokeInst>(TI)) {
// Invoke instructions successors are always executable.
return true;
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
}
return false;
} else {
- std::cerr << "Unknown terminator instruction: " << *TI;
+ cerr << "Unknown terminator instruction: " << *TI;
abort();
}
}
}
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));
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));
EltState.getConstant(),
IdxState.getConstant()));
else if (ValState.isUndefined() && EltState.isConstant() &&
- IdxState.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
LatticeVal &V1State = getValueState(I.getOperand(0));
LatticeVal &V2State = getValueState(I.getOperand(1));
LatticeVal &MaskState = getValueState(I.getOperand(2));
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
Value *I = OverdefinedInstWorkList.back();
OverdefinedInstWorkList.pop_back();
- DEBUG(std::cerr << "\nPopped off OI-WL: " << *I);
+ DOUT << "\nPopped off OI-WL: " << *I;
// "I" got into the work list because it either made the transition from
// bottom to constant
Value *I = InstWorkList.back();
InstWorkList.pop_back();
- DEBUG(std::cerr << "\nPopped off I-WL: " << *I);
+ DOUT << "\nPopped off I-WL: " << *I;
// "I" got into the work list because it either made the transition from
// bottom to constant
BasicBlock *BB = BBWorkList.back();
BBWorkList.pop_back();
- DEBUG(std::cerr << "\nPopped off BBWL: " << *BB);
+ DOUT << "\nPopped off BBWL: " << *BB;
// Notify all instructions in this basic block that they are newly
// executable.
namespace {
- Statistic<> NumInstRemoved("sccp", "Number of instructions removed");
- Statistic<> NumDeadBlocks ("sccp", "Number of basic blocks unreachable");
+ Statistic NumInstRemoved("sccp", "Number of instructions removed");
+ Statistic NumDeadBlocks ("sccp", "Number of basic blocks unreachable");
//===--------------------------------------------------------------------===//
//
// and return true if the function was modified.
//
bool SCCP::runOnFunction(Function &F) {
- DEBUG(std::cerr << "SCCP on function '" << F.getName() << "'\n");
+ DOUT << "SCCP on function '" << F.getName() << "'\n";
SCCPSolver Solver;
// Mark the first block of the function as being executable.
bool ResolvedBranches = true;
while (ResolvedBranches) {
Solver.Solve();
- DEBUG(std::cerr << "RESOLVING UNDEF BRANCHES\n");
+ DOUT << "RESOLVING UNDEF BRANCHES\n";
ResolvedBranches = Solver.ResolveBranchesIn(F);
}
std::set<BasicBlock*> &ExecutableBBs = Solver.getExecutableBlocks();
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
if (!ExecutableBBs.count(BB)) {
- DEBUG(std::cerr << " BasicBlock Dead:" << *BB);
+ DOUT << " BasicBlock Dead:" << *BB;
++NumDeadBlocks;
// Delete the instructions backwards, as it has a reduced likelihood of
!isa<TerminatorInst>(Inst)) {
Constant *Const = IV.isConstant()
? IV.getConstant() : UndefValue::get(Inst->getType());
- DEBUG(std::cerr << " Constant: " << *Const << " = " << *Inst);
+ DOUT << " Constant: " << *Const << " = " << *Inst;
// Replaces all of the uses of a variable with uses of the constant.
Inst->replaceAllUsesWith(Const);
}
namespace {
- Statistic<> IPNumInstRemoved("ipsccp", "Number of instructions removed");
- Statistic<> IPNumDeadBlocks ("ipsccp", "Number of basic blocks unreachable");
- Statistic<> IPNumArgsElimed ("ipsccp",
+ Statistic IPNumInstRemoved("ipsccp", "Number of instructions removed");
+ Statistic IPNumDeadBlocks ("ipsccp", "Number of basic blocks unreachable");
+ Statistic IPNumArgsElimed ("ipsccp",
"Number of arguments constant propagated");
- Statistic<> IPNumGlobalConst("ipsccp",
+ Statistic IPNumGlobalConst("ipsccp",
"Number of globals found to be constant");
//===--------------------------------------------------------------------===//
while (ResolvedBranches) {
Solver.Solve();
- DEBUG(std::cerr << "RESOLVING UNDEF BRANCHES\n");
+ DOUT << "RESOLVING UNDEF BRANCHES\n";
ResolvedBranches = false;
for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
ResolvedBranches |= Solver.ResolveBranchesIn(*F);
if (IV.isConstant() || IV.isUndefined()) {
Constant *CST = IV.isConstant() ?
IV.getConstant() : UndefValue::get(AI->getType());
- DEBUG(std::cerr << "*** Arg " << *AI << " = " << *CST <<"\n");
+ DOUT << "*** Arg " << *AI << " = " << *CST <<"\n";
// Replaces all of the uses of a variable with uses of the
// constant.
std::vector<BasicBlock*> BlocksToErase;
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
if (!ExecutableBBs.count(BB)) {
- DEBUG(std::cerr << " BasicBlock Dead:" << *BB);
+ DOUT << " BasicBlock Dead:" << *BB;
++IPNumDeadBlocks;
// Delete the instructions backwards, as it has a reduced likelihood of
!isa<TerminatorInst>(Inst)) {
Constant *Const = IV.isConstant()
? IV.getConstant() : UndefValue::get(Inst->getType());
- DEBUG(std::cerr << " Constant: " << *Const << " = " << *Inst);
+ DOUT << " Constant: " << *Const << " = " << *Inst;
// Replaces all of the uses of a variable with uses of the
// constant.
GlobalVariable *GV = I->first;
assert(!I->second.isOverdefined() &&
"Overdefined values should have been taken out of the map!");
- DEBUG(std::cerr << "Found that GV '" << GV->getName()<< "' is constant!\n");
+ DOUT << "Found that GV '" << GV->getName()<< "' is constant!\n";
while (!GV->use_empty()) {
StoreInst *SI = cast<StoreInst>(GV->use_back());
SI->eraseFromParent();