diff --git a/lib/Transforms/Scalar/CondPropagate.cpp b/lib/Transforms/Scalar/CondPropagate.cpp new file mode 100644 index 00000000000..138be522ee1 --- /dev/null +++ b/lib/Transforms/Scalar/CondPropagate.cpp @@ -0,0 +1,213 @@ +//===-- 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 +using namespace llvm; + +namespace { + Statistic<> + NumBrThread("condprop", "Number of CFG edges threaded through branches"); + Statistic<> + NumSwThread("condprop", "Number of CFG edges threaded through switches"); + + struct 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); + }; + RegisterOpt 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); + } + + // See if we can fold any PHI nodes in this block now. + // FIXME: This would not be required if removePredecessor did this for us!! + PHINode *PN; + for (BasicBlock::iterator I = BB->begin(); PN = dyn_cast(I++); ) + if (Value *PNV = hasConstantValue(PN)) + if (!isa(PNV)) { + PN->replaceAllUsesWith(PNV); + PN->eraseFromParent(); + MadeChange = true; + } + + // 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()) { + BasicBlock *Succ = BI->getSuccessor(0); + // 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 (ConstantBool *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->getValue() == 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); + + // ToBB should not have any PHI nodes in it to update, because OldSucc had + // multiple successors. If OldSucc had multiple successor and ToBB had + // multiple predecessors, the edge between them would be critical, which we + // already took care of. + assert(!isa(ToBB->begin()) && "Critical Edge Found!"); + + // 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; +}