//===-- 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
#include "llvm/Type.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
-#include <iostream>
+#include "llvm/Support/Streams.h"
using namespace llvm;
-namespace {
- Statistic<>
- NumBrThread("condprop", "Number of CFG edges threaded through branches");
- Statistic<>
- NumSwThread("condprop", "Number of CFG edges threaded through switches");
+STATISTIC(NumBrThread, "Number of CFG edges threaded through branches");
+STATISTIC(NumSwThread, "Number of CFG edges threaded through switches");
+namespace {
struct CondProp : public FunctionPass {
virtual bool runOnFunction(Function &F);
void SimplifyPredecessors(SwitchInst *SI);
void RevectorBlockTo(BasicBlock *FromBB, BasicBlock *ToBB);
};
- RegisterOpt<CondProp> X("condprop", "Conditional Propagation");
+ RegisterPass<CondProp> X("condprop", "Conditional Propagation");
}
FunctionPass *llvm::createCondPropagationPass() {
if (BI->isConditional() && isa<PHINode>(BI->getCondition()) &&
cast<PHINode>(BI->getCondition())->getParent() == BB)
SimplifyPredecessors(BI);
-
+
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(BB->getTerminator())) {
if (isa<PHINode>(SI->getCondition()) &&
cast<PHINode>(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<PHINode>(I++); )
- if (Value *PNV = hasConstantValue(PN))
- if (!isa<Instruction>(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<BranchInst>(BB->getTerminator()))
- if (BI->isUnconditional() && BI->getSuccessor(0)->getSinglePredecessor()) {
+ 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<PHINode>(Succ->begin())) {
+ assert(PN->getNumIncomingValues() == 1 &&
+ "PHI doesn't match parent block");
+ PN->replaceAllUsesWith(PN->getIncomingValue(0));
+ PN->eraseFromParent();
+ }
+
// Remove BI.
BI->eraseFromParent();
// 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<ConstantBool>(PN->getIncomingValue(i-1))) {
+ if (ConstantInt *CB = dyn_cast<ConstantInt>(PN->getIncomingValue(i-1))) {
+ if (CB->getType() != Type::Int1Ty) continue;
// 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));
+ BI->getSuccessor(CB->getZExtValue() == 0));
++NumBrThread;
// If there were two predecessors before this simplification, the PHI node
// 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<PHINode>(ToBB->begin()) && "Critical Edge Found!");
+ // 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<PHINode>(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);