turn IPSCCP back on now that the iterator invalidation bug is fixed.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85858 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2009-11-03 03:42:51 +00:00
parent 8e46141e9e
commit 14532d03a1
2 changed files with 50 additions and 37 deletions

View File

@ -99,7 +99,6 @@ namespace llvm {
if (UnitAtATime) { if (UnitAtATime) {
PM->add(createGlobalOptimizerPass()); // Optimize out global vars PM->add(createGlobalOptimizerPass()); // Optimize out global vars
PM->add(createIPConstantPropagationPass()); // IP CP
PM->add(createIPSCCPPass()); // IP SCCP PM->add(createIPSCCPPass()); // IP SCCP
PM->add(createDeadArgEliminationPass()); // Dead argument elimination PM->add(createDeadArgEliminationPass()); // Dead argument elimination
} }

View File

@ -25,7 +25,6 @@
#include "llvm/Instructions.h" #include "llvm/Instructions.h"
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/ValueTracking.h"
#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/Local.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
@ -227,7 +226,6 @@ public:
/// and out of the specified function (which cannot have its address taken), /// and out of the specified function (which cannot have its address taken),
/// this method must be called. /// this method must be called.
void AddTrackedFunction(Function *F) { void AddTrackedFunction(Function *F) {
assert(F->hasLocalLinkage() && "Can only track internal functions!");
// Add an entry, F -> undef. // Add an entry, F -> undef.
if (const StructType *STy = dyn_cast<StructType>(F->getReturnType())) { if (const StructType *STy = dyn_cast<StructType>(F->getReturnType())) {
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
@ -380,11 +378,9 @@ private:
// instruction that was just changed state somehow. Based on this // instruction that was just changed state somehow. Based on this
// information, we need to update the specified user of this instruction. // information, we need to update the specified user of this instruction.
// //
void OperandChangedState(User *U) { void OperandChangedState(Instruction *I) {
// Only instructions use other variable values! if (BBExecutable.count(I->getParent())) // Inst is executable?
Instruction &I = cast<Instruction>(*U); visit(*I);
if (BBExecutable.count(I.getParent())) // Inst is executable?
visit(I);
} }
/// RemoveFromOverdefinedPHIs - If I has any entries in the /// RemoveFromOverdefinedPHIs - If I has any entries in the
@ -428,8 +424,6 @@ private:
void visitLoadInst (LoadInst &I); void visitLoadInst (LoadInst &I);
void visitGetElementPtrInst(GetElementPtrInst &I); void visitGetElementPtrInst(GetElementPtrInst &I);
void visitCallInst (CallInst &I) { void visitCallInst (CallInst &I) {
if (isFreeCall(&I))
return;
visitCallSite(CallSite::get(&I)); visitCallSite(CallSite::get(&I));
} }
void visitInvokeInst (InvokeInst &II) { void visitInvokeInst (InvokeInst &II) {
@ -656,19 +650,19 @@ void SCCPSolver::visitPHINode(PHINode &PN) {
markConstant(&PN, OperandVal); // Acquire operand value markConstant(&PN, OperandVal); // Acquire operand value
} }
void SCCPSolver::visitReturnInst(ReturnInst &I) { void SCCPSolver::visitReturnInst(ReturnInst &I) {
if (I.getNumOperands() == 0) return; // ret void if (I.getNumOperands() == 0) return; // ret void
Function *F = I.getParent()->getParent(); Function *F = I.getParent()->getParent();
// If we are tracking the return value of this function, merge it in. // If we are tracking the return value of this function, merge it in.
if (!F->hasLocalLinkage())
return;
if (!TrackedRetVals.empty()) { if (!TrackedRetVals.empty()) {
DenseMap<Function*, LatticeVal>::iterator TFRVI = DenseMap<Function*, LatticeVal>::iterator TFRVI =
TrackedRetVals.find(F); TrackedRetVals.find(F);
if (TFRVI != TrackedRetVals.end() && if (TFRVI != TrackedRetVals.end()) {
!TFRVI->second.isOverdefined()) {
mergeInValue(TFRVI->second, F, getValueState(I.getOperand(0))); mergeInValue(TFRVI->second, F, getValueState(I.getOperand(0)));
return; return;
} }
@ -1163,14 +1157,14 @@ void SCCPSolver::visitCallSite(CallSite CS) {
// The common case is that we aren't tracking the callee, either because we // 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 // are not doing interprocedural analysis or the callee is indirect, or is
// external. Handle these cases first. // external. Handle these cases first.
if (F == 0 || !F->hasLocalLinkage()) { if (F == 0 || F->isDeclaration()) {
CallOverdefined: CallOverdefined:
// Void return and not tracking callee, just bail. // Void return and not tracking callee, just bail.
if (I->getType()->isVoidTy()) return; if (I->getType()->isVoidTy()) return;
// Otherwise, if we have a single return value case, and if the function is // Otherwise, if we have a single return value case, and if the function is
// a declaration, maybe we can constant fold it. // a declaration, maybe we can constant fold it.
if (!isa<StructType>(I->getType()) && F && F->isDeclaration() && if (F && F->isDeclaration() && !isa<StructType>(I->getType()) &&
canConstantFoldCallTo(F)) { canConstantFoldCallTo(F)) {
SmallVector<Constant*, 8> Operands; SmallVector<Constant*, 8> Operands;
@ -1234,7 +1228,7 @@ CallOverdefined:
// common path above. // common path above.
goto CallOverdefined; goto CallOverdefined;
} }
// Finally, if this is the first call to the function hit, mark its entry // Finally, if this is the first call to the function hit, mark its entry
// block executable. // block executable.
MarkBlockExecutable(F->begin()); MarkBlockExecutable(F->begin());
@ -1243,6 +1237,8 @@ CallOverdefined:
CallSite::arg_iterator CAI = CS.arg_begin(); CallSite::arg_iterator CAI = CS.arg_begin();
for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
AI != E; ++AI, ++CAI) { AI != E; ++AI, ++CAI) {
// If this argument is byval, and if the function is not readonly, there
// will be an implicit copy formed of the input aggregate.
if (AI->hasByValAttr() && !F->onlyReadsMemory()) { if (AI->hasByValAttr() && !F->onlyReadsMemory()) {
markOverdefined(AI); markOverdefined(AI);
continue; continue;
@ -1272,7 +1268,8 @@ void SCCPSolver::Solve() {
// //
for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
UI != E; ++UI) UI != E; ++UI)
OperandChangedState(*UI); if (Instruction *I = dyn_cast<Instruction>(*UI))
OperandChangedState(I);
} }
// Process the instruction work list. // Process the instruction work list.
@ -1291,7 +1288,8 @@ void SCCPSolver::Solve() {
if (!getValueState(I).isOverdefined()) if (!getValueState(I).isOverdefined())
for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
UI != E; ++UI) UI != E; ++UI)
OperandChangedState(*UI); if (Instruction *I = dyn_cast<Instruction>(*UI))
OperandChangedState(I);
} }
// Process the basic block work list. // Process the basic block work list.
@ -1649,14 +1647,25 @@ bool IPSCCP::runOnModule(Module &M) {
if (F->isDeclaration()) if (F->isDeclaration())
continue; continue;
if (!F->hasLocalLinkage() || AddressIsTaken(F)) { // If this is a strong or ODR definition of this function, then we can
Solver.MarkBlockExecutable(F->begin()); // propagate information about its result into callsites of it.
for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); if (!F->mayBeOverridden() &&
AI != E; ++AI) !isa<StructType>(F->getReturnType()))
Solver.markOverdefined(AI);
} else {
Solver.AddTrackedFunction(F); Solver.AddTrackedFunction(F);
}
// If this function only has direct calls that we can see, we can track its
// arguments and return value aggressively, and can assume it is not called
// unless we see evidence to the contrary.
if (F->hasLocalLinkage() && !AddressIsTaken(F))
continue;
// Assume the function is called.
Solver.MarkBlockExecutable(F->begin());
// Assume nothing about the incoming arguments.
for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
AI != E; ++AI)
Solver.markOverdefined(AI);
} }
// Loop over global variables. We inform the solver about any internal global // Loop over global variables. We inform the solver about any internal global
@ -1804,16 +1813,21 @@ bool IPSCCP::runOnModule(Module &M) {
// TODO: Process multiple value ret instructions also. // TODO: Process multiple value ret instructions also.
const DenseMap<Function*, LatticeVal> &RV = Solver.getTrackedRetVals(); const DenseMap<Function*, LatticeVal> &RV = Solver.getTrackedRetVals();
for (DenseMap<Function*, LatticeVal>::const_iterator I = RV.begin(), for (DenseMap<Function*, LatticeVal>::const_iterator I = RV.begin(),
E = RV.end(); I != E; ++I) E = RV.end(); I != E; ++I) {
if (!I->second.isOverdefined() && Function *F = I->first;
!I->first->getReturnType()->isVoidTy()) { if (I->second.isOverdefined() || F->getReturnType()->isVoidTy())
Function *F = I->first; continue;
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) // We can only do this if we know that nothing else can call the function.
if (!isa<UndefValue>(RI->getOperand(0))) if (!F->hasLocalLinkage() || AddressIsTaken(F))
RI->setOperand(0, UndefValue::get(F->getReturnType())); continue;
}
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 // If we infered constant or undef values for globals variables, we can delete
// the global and any stores that remain to it. // the global and any stores that remain to it.
const DenseMap<GlobalVariable*, LatticeVal> &TG = Solver.getTrackedGlobals(); const DenseMap<GlobalVariable*, LatticeVal> &TG = Solver.getTrackedGlobals();