Newer
Older
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
bool SawEdgeFromSrc = false;
for (pred_iterator PI = pred_begin(Dst), PE = pred_end(Dst); PI != PE; ++PI) {
BasicBlock *Pred = *PI;
if (Pred == Src) {
// An edge from Src to Dst.
if (SawEdgeFromSrc)
// There are multiple edges from Src to Dst - fail.
return false;
SawEdgeFromSrc = true;
continue;
}
// If the predecessor is not dominated by Dst, then it must be possible to
// reach it either without passing through Src (and thus not via the edge)
// or by passing through Src but taking a different edge out of Src. Either
// way it is possible to reach Dst without passing via the edge, so fail.
if (!DT->dominates(Dst, *PI))
return false;
}
assert(SawEdgeFromSrc && "No edge between these basic blocks!");
// Every path from the entry block to Dst must at some point pass to Dst from
// a predecessor that is not dominated by Dst. This predecessor can only be
// Src, since all others are dominated by Dst. As there is only one edge from
// Src to Dst, the path passes by this edge.
return true;
}
Owen Anderson
committed
/// processInstruction - When calculating availability, handle an instruction
Owen Anderson
committed
/// by inserting it into the appropriate sets
bool GVN::processInstruction(Instruction *I) {
// Ignore dbg info intrinsics.
if (isa<DbgInfoIntrinsic>(I))
return false;
// If the instruction can be easily simplified then do so now in preference
// to value numbering it. Value numbering often exposes redundancies, for
// example if it determines that %y is equal to %x then the instruction
// "%z = and i32 %x, %y" becomes "%z = and i32 %x, %x" which we now simplify.
if (Value *V = SimplifyInstruction(I, TD, TLI, DT)) {
I->replaceAllUsesWith(V);
if (MD && V->getType()->isPointerTy())
MD->invalidateCachedPointerInfo(V);
Chris Lattner
committed
markInstructionForDeletion(I);
++NumGVNSimpl;
return true;
}
if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
if (processLoad(LI))
return true;
unsigned Num = VN.lookup_or_add(LI);
addToLeaderTable(Num, LI, LI->getParent());
return false;
Owen Anderson
committed
}
// For conditional branches, we can perform simple conditional propagation on
Owen Anderson
committed
// the condition value itself.
if (BranchInst *BI = dyn_cast<BranchInst>(I)) {
if (!BI->isConditional() || isa<Constant>(BI->getCondition()))
return false;
Owen Anderson
committed
Value *BranchCond = BI->getCondition();
Owen Anderson
committed
BasicBlock *TrueSucc = BI->getSuccessor(0);
BasicBlock *FalseSucc = BI->getSuccessor(1);
BasicBlock *Parent = BI->getParent();
bool Changed = false;
if (isOnlyReachableViaThisEdge(Parent, TrueSucc, DT))
Changed |= propagateEquality(BranchCond,
ConstantInt::getTrue(TrueSucc->getContext()),
TrueSucc);
if (isOnlyReachableViaThisEdge(Parent, FalseSucc, DT))
Changed |= propagateEquality(BranchCond,
ConstantInt::getFalse(FalseSucc->getContext()),
FalseSucc);
return Changed;
}
// For switches, propagate the case values into the case destinations.
if (SwitchInst *SI = dyn_cast<SwitchInst>(I)) {
Value *SwitchCond = SI->getCondition();
BasicBlock *Parent = SI->getParent();
bool Changed = false;
for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i) {
BasicBlock *Dst = SI->getSuccessor(i);
if (isOnlyReachableViaThisEdge(Parent, Dst, DT))
Changed |= propagateEquality(SwitchCond, SI->getCaseValue(i), Dst);
}
return Changed;
Owen Anderson
committed
}
Owen Anderson
committed
// Instructions with void type don't return a value, so there's
// no point in trying to find redudancies in them.
if (I->getType()->isVoidTy()) return false;
Owen Anderson
committed
uint32_t NextNum = VN.getNextUnusedValueNumber();
unsigned Num = VN.lookup_or_add(I);
Owen Anderson
committed
// Allocations are always uniquely numbered, so we can save time and memory
// by fast failing them.
if (isa<AllocaInst>(I) || isa<TerminatorInst>(I) || isa<PHINode>(I)) {
Owen Anderson
committed
addToLeaderTable(Num, I, I->getParent());
Owen Anderson
committed
return false;
Owen Anderson
committed
}
Owen Anderson
committed
// If the number we were assigned was a brand new VN, then we don't
// need to do a lookup to see if the number already exists
// somewhere in the domtree: it can't!
Owen Anderson
committed
addToLeaderTable(Num, I, I->getParent());
Owen Anderson
committed
// Perform fast-path value-number based elimination of values inherited from
// dominators.
Owen Anderson
committed
Value *repl = findLeader(I->getParent(), Num);
if (repl == 0) {
// Failure, just remember this instance for future use.
Owen Anderson
committed
addToLeaderTable(Num, I, I->getParent());
Owen Anderson
committed
}
// Remove it!
I->replaceAllUsesWith(repl);
if (MD && repl->getType()->isPointerTy())
MD->invalidateCachedPointerInfo(repl);
Chris Lattner
committed
markInstructionForDeletion(I);
Owen Anderson
committed
}
/// runOnFunction - This is the main transformation entry point for a function.
if (!NoLoads)
MD = &getAnalysis<MemoryDependenceAnalysis>();
DT = &getAnalysis<DominatorTree>();
TD = getAnalysisIfAvailable<TargetData>();
TLI = &getAnalysis<TargetLibraryInfo>();
VN.setAliasAnalysis(&getAnalysis<AliasAnalysis>());
VN.setMemDep(MD);
VN.setDomTree(DT);
bool Changed = false;
bool ShouldContinue = true;
Owen Anderson
committed
// Merge unconditional branches, allowing PRE to catch more
// optimization opportunities.
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ) {
BasicBlock *BB = FI++;
bool removedBlock = MergeBlockIntoPredecessor(BB, this);
if (removedBlock) ++NumGVNBlocks;
Owen Anderson
committed
}
DEBUG(dbgs() << "GVN iteration: " << Iteration << "\n");
ShouldContinue = iterateOnFunction(F);
if (splitCriticalEdges())
ShouldContinue = true;
Changed |= ShouldContinue;
Owen Anderson
committed
if (EnablePRE) {
bool PREChanged = true;
while (PREChanged) {
PREChanged = performPRE(F);
Owen Anderson
committed
}
// FIXME: Should perform GVN again after PRE does something. PRE can move
// computations into blocks where they become fully redundant. Note that
// we can't do this until PRE's critical edge splitting updates memdep.
// Actually, when this happens, we should just fully integrate PRE into GVN.
cleanupGlobalSets();
bool GVN::processBlock(BasicBlock *BB) {
// FIXME: Kill off InstrsToErase by doing erasing eagerly in a helper function
// (and incrementing BI before processing an instruction).
assert(InstrsToErase.empty() &&
"We expect InstrsToErase to be empty across iterations");
bool ChangedFunction = false;
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();
BI != BE;) {
ChangedFunction |= processInstruction(BI);
if (InstrsToErase.empty()) {
// If we need some instructions deleted, do it now.
NumGVNInstr += InstrsToErase.size();
// Avoid iterator invalidation.
bool AtStart = BI == BB->begin();
if (!AtStart)
--BI;
for (SmallVector<Instruction*, 4>::iterator I = InstrsToErase.begin(),
E = InstrsToErase.end(); I != E; ++I) {
DEBUG(dbgs() << "GVN removed: " << **I << '\n');
if (MD) MD->removeInstruction(*I);
if (AtStart)
BI = BB->begin();
else
++BI;
}
Owen Anderson
committed
/// performPRE - Perform a purely local form of PRE that looks for diamond
/// control flow patterns and attempts to perform simple PRE at the join point.
bool GVN::performPRE(Function &F) {
Chris Lattner
committed
bool Changed = false;
DenseMap<BasicBlock*, Value*> predMap;
Owen Anderson
committed
for (df_iterator<BasicBlock*> DI = df_begin(&F.getEntryBlock()),
DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) {
BasicBlock *CurrentBlock = *DI;
Owen Anderson
committed
// Nothing to PRE in the entry block.
if (CurrentBlock == &F.getEntryBlock()) continue;
// Don't perform PRE on a landing pad.
if (CurrentBlock->isLandingPad()) continue;
Owen Anderson
committed
for (BasicBlock::iterator BI = CurrentBlock->begin(),
BE = CurrentBlock->end(); BI != BE; ) {
Chris Lattner
committed
Instruction *CurInst = BI++;
Victor Hernandez
committed
if (isa<AllocaInst>(CurInst) ||
Victor Hernandez
committed
isa<TerminatorInst>(CurInst) || isa<PHINode>(CurInst) ||
CurInst->mayReadFromMemory() || CurInst->mayHaveSideEffects() ||
isa<DbgInfoIntrinsic>(CurInst))
Owen Anderson
committed
continue;
Owen Anderson
committed
// We don't currently value number ANY inline asm calls.
if (CallInst *CallI = dyn_cast<CallInst>(CurInst))
if (CallI->isInlineAsm())
continue;
uint32_t ValNo = VN.lookup(CurInst);
Owen Anderson
committed
// Look for the predecessors for PRE opportunities. We're
// only trying to solve the basic diamond case, where
// a value is computed in the successor and one predecessor,
// but not the other. We also explicitly disallow cases
// where the successor is its own predecessor, because they're
// more complicated to get right.
unsigned NumWith = 0;
unsigned NumWithout = 0;
BasicBlock *PREPred = 0;
predMap.clear();
Owen Anderson
committed
for (pred_iterator PI = pred_begin(CurrentBlock),
PE = pred_end(CurrentBlock); PI != PE; ++PI) {
Owen Anderson
committed
// We're not interested in PRE where the block is its
// own predecessor, or in blocks with predecessors
Owen Anderson
committed
// that are not reachable.
Owen Anderson
committed
break;
Owen Anderson
committed
} else if (!DT->dominates(&F.getEntryBlock(), P)) {
Owen Anderson
committed
break;
}
Owen Anderson
committed
Value* predV = findLeader(P, ValNo);
Owen Anderson
committed
if (predV == 0) {
++NumWithout;
Owen Anderson
committed
} else if (predV == CurInst) {
Owen Anderson
committed
} else {
Owen Anderson
committed
predMap[P] = predV;
++NumWith;
Owen Anderson
committed
}
}
Owen Anderson
committed
// Don't do PRE when it might increase code size, i.e. when
// we would need to insert instructions in more than one pred.
if (NumWithout != 1 || NumWith == 0)
Owen Anderson
committed
continue;
// Don't do PRE across indirect branch.
if (isa<IndirectBrInst>(PREPred->getTerminator()))
continue;
// We can't do PRE safely on a critical edge, so instead we schedule
// the edge to be split and perform the PRE the next time we iterate
// on the function.
unsigned SuccNum = GetSuccessorNumber(PREPred, CurrentBlock);
if (isCriticalEdge(PREPred->getTerminator(), SuccNum)) {
toSplit.push_back(std::make_pair(PREPred->getTerminator(), SuccNum));
// Instantiate the expression in the predecessor that lacked it.
Owen Anderson
committed
// Because we are going top-down through the block, all value numbers
// will be available in the predecessor by the time we need them. Any
// that weren't originally present will have been instantiated earlier
Owen Anderson
committed
// in this loop.
Instruction *PREInstr = CurInst->clone();
Owen Anderson
committed
bool success = true;
Chris Lattner
committed
for (unsigned i = 0, e = CurInst->getNumOperands(); i != e; ++i) {
Value *Op = PREInstr->getOperand(i);
if (isa<Argument>(Op) || isa<Constant>(Op) || isa<GlobalValue>(Op))
continue;
Owen Anderson
committed
if (Value *V = findLeader(PREPred, VN.lookup(Op))) {
Chris Lattner
committed
PREInstr->setOperand(i, V);
} else {
success = false;
break;
Owen Anderson
committed
}
Owen Anderson
committed
// Fail out if we encounter an operand that is not available in
// the PRE predecessor. This is typically because of loads which
Owen Anderson
committed
// are not value numbered precisely.
if (!success) {
delete PREInstr;
DEBUG(verifyRemoved(PREInstr));
Owen Anderson
committed
continue;
}
Owen Anderson
committed
PREInstr->insertBefore(PREPred->getTerminator());
Chris Lattner
committed
PREInstr->setName(CurInst->getName() + ".pre");
PREInstr->setDebugLoc(CurInst->getDebugLoc());
Owen Anderson
committed
predMap[PREPred] = PREInstr;
++NumGVNPRE;
Owen Anderson
committed
// Update the availability map to include the new instruction.
Owen Anderson
committed
addToLeaderTable(ValNo, PREInstr, PREPred);
Owen Anderson
committed
// Create a PHI to make the value available in this block.
pred_iterator PB = pred_begin(CurrentBlock), PE = pred_end(CurrentBlock);
PHINode* Phi = PHINode::Create(CurInst->getType(), std::distance(PB, PE),
Chris Lattner
committed
CurInst->getName() + ".pre-phi",
Owen Anderson
committed
CurrentBlock->begin());
for (pred_iterator PI = PB; PI != PE; ++PI) {
BasicBlock *P = *PI;
Phi->addIncoming(predMap[P], P);
}
Owen Anderson
committed
addToLeaderTable(ValNo, Phi, CurrentBlock);
Phi->setDebugLoc(CurInst->getDebugLoc());
Chris Lattner
committed
CurInst->replaceAllUsesWith(Phi);
Owen Anderson
committed
if (Phi->getType()->isPointerTy()) {
// Because we have added a PHI-use of the pointer value, it has now
// "escaped" from alias analysis' perspective. We need to inform
// AA of this.
for (unsigned ii = 0, ee = Phi->getNumIncomingValues(); ii != ee;
++ii) {
unsigned jj = PHINode::getOperandNumForIncomingValue(ii);
VN.getAliasAnalysis()->addEscapingUse(Phi->getOperandUse(jj));
}
Owen Anderson
committed
if (MD)
MD->invalidateCachedPointerInfo(Phi);
}
Chris Lattner
committed
VN.erase(CurInst);
Owen Anderson
committed
removeFromLeaderTable(ValNo, CurInst, CurrentBlock);
DEBUG(dbgs() << "GVN PRE removed: " << *CurInst << '\n');
if (MD) MD->removeInstruction(CurInst);
Chris Lattner
committed
CurInst->eraseFromParent();
Chris Lattner
committed
Changed = true;
Owen Anderson
committed
}
}
if (splitCriticalEdges())
Changed = true;
return Changed;
}
/// splitCriticalEdges - Split critical edges found during the previous
/// iteration that may enable further optimization.
bool GVN::splitCriticalEdges() {
if (toSplit.empty())
return false;
do {
std::pair<TerminatorInst*, unsigned> Edge = toSplit.pop_back_val();
SplitCriticalEdge(Edge.first, Edge.second, this);
} while (!toSplit.empty());
if (MD) MD->invalidateCachedPredecessors();
Owen Anderson
committed
}
/// iterateOnFunction - Executes one iteration of GVN
Owen Anderson
committed
Owen Anderson
committed
// Top-down walk of the dominator tree
#if 0
// Needed for value numbering with phi construction to work.
Owen Anderson
committed
ReversePostOrderTraversal<Function*> RPOT(&F);
for (ReversePostOrderTraversal<Function*>::rpo_iterator RI = RPOT.begin(),
RE = RPOT.end(); RI != RE; ++RI)
Changed |= processBlock(*RI);
#else
for (df_iterator<DomTreeNode*> DI = df_begin(DT->getRootNode()),
DE = df_end(DT->getRootNode()); DI != DE; ++DI)
Changed |= processBlock(DI->getBlock());
#endif
Owen Anderson
committed
}
void GVN::cleanupGlobalSets() {
VN.clear();
Owen Anderson
committed
TableAllocator.Reset();
Bill Wendling
committed
/// verifyRemoved - Verify that the specified instruction does not occur in our
/// internal data structures.
void GVN::verifyRemoved(const Instruction *Inst) const {
VN.verifyRemoved(Inst);
// Walk through the value number scope to make sure the instruction isn't
// ferreted away in it.
Owen Anderson
committed
for (DenseMap<uint32_t, LeaderTableEntry>::const_iterator
I = LeaderTable.begin(), E = LeaderTable.end(); I != E; ++I) {
Owen Anderson
committed
const LeaderTableEntry *Node = &I->second;
Owen Anderson
committed
assert(Node->Val != Inst && "Inst still in value numbering scope!");
Owen Anderson
committed
Owen Anderson
committed
while (Node->Next) {
Node = Node->Next;
assert(Node->Val != Inst && "Inst still in value numbering scope!");
}
}