//===-- CondPropagate.cpp - Propagate Conditional Expressions -------------===// // // The LLVM Compiler Infrastructure // // This file was developed by the LLVM research group and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This pass propagates information about conditional expressions through the // program, allowing it to eliminate conditional branches in some cases. // //===----------------------------------------------------------------------===// #define DEBUG_TYPE "condprop" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Constants.h" #include "llvm/Function.h" #include "llvm/Instructions.h" #include "llvm/Pass.h" #include "llvm/Type.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Streams.h" using namespace llvm; STATISTIC(NumBrThread, "Number of CFG edges threaded through branches"); STATISTIC(NumSwThread, "Number of CFG edges threaded through switches"); namespace { struct VISIBILITY_HIDDEN CondProp : public FunctionPass { virtual bool runOnFunction(Function &F); virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequiredID(BreakCriticalEdgesID); //AU.addRequired(); } private: bool MadeChange; void SimplifyBlock(BasicBlock *BB); void SimplifyPredecessors(BranchInst *BI); void SimplifyPredecessors(SwitchInst *SI); void RevectorBlockTo(BasicBlock *FromBB, BasicBlock *ToBB); }; RegisterPass X("condprop", "Conditional Propagation"); } FunctionPass *llvm::createCondPropagationPass() { return new CondProp(); } bool CondProp::runOnFunction(Function &F) { bool EverMadeChange = false; // While we are simplifying blocks, keep iterating. do { MadeChange = false; for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) SimplifyBlock(BB); EverMadeChange = MadeChange; } while (MadeChange); return EverMadeChange; } void CondProp::SimplifyBlock(BasicBlock *BB) { if (BranchInst *BI = dyn_cast(BB->getTerminator())) { // If this is a conditional branch based on a phi node that is defined in // this block, see if we can simplify predecessors of this block. if (BI->isConditional() && isa(BI->getCondition()) && cast(BI->getCondition())->getParent() == BB) SimplifyPredecessors(BI); } else if (SwitchInst *SI = dyn_cast(BB->getTerminator())) { if (isa(SI->getCondition()) && cast(SI->getCondition())->getParent() == BB) SimplifyPredecessors(SI); } // If possible, simplify the terminator of this block. if (ConstantFoldTerminator(BB)) MadeChange = true; // If this block ends with an unconditional branch and the only successor has // only this block as a predecessor, merge the two blocks together. if (BranchInst *BI = dyn_cast(BB->getTerminator())) if (BI->isUnconditional() && BI->getSuccessor(0)->getSinglePredecessor() && BB != BI->getSuccessor(0)) { BasicBlock *Succ = BI->getSuccessor(0); // If Succ has any PHI nodes, they are all single-entry PHI's. while (PHINode *PN = dyn_cast(Succ->begin())) { assert(PN->getNumIncomingValues() == 1 && "PHI doesn't match parent block"); PN->replaceAllUsesWith(PN->getIncomingValue(0)); PN->eraseFromParent(); } // Remove BI. BI->eraseFromParent(); // Move over all of the instructions. BB->getInstList().splice(BB->end(), Succ->getInstList()); // Any phi nodes that had entries for Succ now have entries from BB. Succ->replaceAllUsesWith(BB); // Succ is now dead, but we cannot delete it without potentially // invalidating iterators elsewhere. Just insert an unreachable // instruction in it. new UnreachableInst(Succ); MadeChange = true; } } // SimplifyPredecessors(branches) - We know that BI is a conditional branch // based on a PHI node defined in this block. If the phi node contains constant // operands, then the blocks corresponding to those operands can be modified to // jump directly to the destination instead of going through this block. void CondProp::SimplifyPredecessors(BranchInst *BI) { // TODO: We currently only handle the most trival case, where the PHI node has // one use (the branch), and is the only instruction besides the branch in the // block. PHINode *PN = cast(BI->getCondition()); if (!PN->hasOneUse()) return; BasicBlock *BB = BI->getParent(); if (&*BB->begin() != PN || &*next(BB->begin()) != BI) return; // Ok, we have this really simple case, walk the PHI operands, looking for // constants. Walk from the end to remove operands from the end when // possible, and to avoid invalidating "i". for (unsigned i = PN->getNumIncomingValues(); i != 0; --i) if (ConstantInt *CB = dyn_cast(PN->getIncomingValue(i-1))) { // If we have a constant, forward the edge from its current to its // ultimate destination. bool PHIGone = PN->getNumIncomingValues() == 2; RevectorBlockTo(PN->getIncomingBlock(i-1), BI->getSuccessor(CB->getZExtValue() == 0)); ++NumBrThread; // If there were two predecessors before this simplification, the PHI node // will be deleted. Don't iterate through it the last time. if (PHIGone) return; } } // SimplifyPredecessors(switch) - We know that SI is switch based on a PHI node // defined in this block. If the phi node contains constant operands, then the // blocks corresponding to those operands can be modified to jump directly to // the destination instead of going through this block. void CondProp::SimplifyPredecessors(SwitchInst *SI) { // TODO: We currently only handle the most trival case, where the PHI node has // one use (the branch), and is the only instruction besides the branch in the // block. PHINode *PN = cast(SI->getCondition()); if (!PN->hasOneUse()) return; BasicBlock *BB = SI->getParent(); if (&*BB->begin() != PN || &*next(BB->begin()) != SI) return; bool RemovedPreds = false; // Ok, we have this really simple case, walk the PHI operands, looking for // constants. Walk from the end to remove operands from the end when // possible, and to avoid invalidating "i". for (unsigned i = PN->getNumIncomingValues(); i != 0; --i) if (ConstantInt *CI = dyn_cast(PN->getIncomingValue(i-1))) { // If we have a constant, forward the edge from its current to its // ultimate destination. bool PHIGone = PN->getNumIncomingValues() == 2; unsigned DestCase = SI->findCaseValue(CI); RevectorBlockTo(PN->getIncomingBlock(i-1), SI->getSuccessor(DestCase)); ++NumSwThread; RemovedPreds = true; // If there were two predecessors before this simplification, the PHI node // will be deleted. Don't iterate through it the last time. if (PHIGone) return; } } // RevectorBlockTo - Revector the unconditional branch at the end of FromBB to // the ToBB block, which is one of the successors of its current successor. void CondProp::RevectorBlockTo(BasicBlock *FromBB, BasicBlock *ToBB) { BranchInst *FromBr = cast(FromBB->getTerminator()); assert(FromBr->isUnconditional() && "FromBB should end with uncond br!"); // Get the old block we are threading through. BasicBlock *OldSucc = FromBr->getSuccessor(0); // OldSucc had multiple successors. If ToBB has multiple predecessors, then // the edge between them would be critical, which we already took care of. // If ToBB has single operand PHI node then take care of it here. while (PHINode *PN = dyn_cast(ToBB->begin())) { assert(PN->getNumIncomingValues() == 1 && "Critical Edge Found!"); PN->replaceAllUsesWith(PN->getIncomingValue(0)); PN->eraseFromParent(); } // Update PHI nodes in OldSucc to know that FromBB no longer branches to it. OldSucc->removePredecessor(FromBB); // Change FromBr to branch to the new destination. FromBr->setSuccessor(0, ToBB); MadeChange = true; }