Newer
Older
for (pred_iterator PI = pred_begin(Dst), PE = pred_end(Dst); PI != PE; ++PI) {
if (*PI != Src)
continue;
// An edge from Src to Dst.
if (SawEdgeFromSrc)
// There are multiple edges from Src to Dst - fail.
return false;
SawEdgeFromSrc = true;
}
assert(SawEdgeFromSrc && "No edge between these basic blocks!");
// Secondly, any other predecessors of Dst should be dominated by Dst. If the
// predecessor is not dominated by Dst, then it must be possible to reach it
// either without passing through Src (thus not via the edge) or by passing
// through Src but taking a different edge out of Src. Either way Dst can be
// reached without passing via the edge, so fail.
for (pred_iterator PI = pred_begin(Dst), PE = pred_end(Dst); PI != PE; ++PI) {
BasicBlock *Pred = *PI;
if (Pred != Src && !DT->dominates(Dst, Pred))
return false;
}
// 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 = 0, e = SI->getNumCases(); i != e; ++i) {
BasicBlock *Dst = SI->getCaseSuccessor(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!");
}
}