//===- SimplifyCFG.cpp - Code to perform CFG simplification ---------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
//
// Peephole optimize the CFG.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "simplifycfg"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/Type.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Debug.h"
#include <algorithm>
#include <functional>
#include <set>
using namespace llvm;
// PropagatePredecessorsForPHIs - This gets "Succ" ready to have the
// predecessors from "BB". This is a little tricky because "Succ" has PHI
// nodes, which need to have extra slots added to them to hold the merge edges
// from BB's predecessors, and BB itself might have had PHI nodes in it. This
// function returns true (failure) if the Succ BB already has a predecessor that
// is a predecessor of BB and incoming PHI arguments would not be discernible.
//
// Assumption: Succ is the single successor for BB.
//
static bool PropagatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) {
assert(*succ_begin(BB) == Succ && "Succ is not successor of BB!");
if (!isa<PHINode>(Succ->front()))
return false; // We can make the transformation, no problem.
// If there is more than one predecessor, and there are PHI nodes in
// the successor, then we need to add incoming edges for the PHI nodes
//
const std::vector<BasicBlock*> BBPreds(pred_begin(BB), pred_end(BB));
// Check to see if one of the predecessors of BB is already a predecessor of
// Succ. If so, we cannot do the transformation if there are any PHI nodes
// with incompatible values coming in from the two edges!
//
for (pred_iterator PI = pred_begin(Succ), PE = pred_end(Succ); PI != PE; ++PI)
if (find(BBPreds.begin(), BBPreds.end(), *PI) != BBPreds.end()) {
// Loop over all of the PHI nodes checking to see if there are
// incompatible values coming in.
for (BasicBlock::iterator I = Succ->begin();
PHINode *PN = dyn_cast<PHINode>(I); ++I) {
// Loop up the entries in the PHI node for BB and for *PI if the values
// coming in are non-equal, we cannot merge these two blocks (instead we
// should insert a conditional move or something, then merge the
// blocks).
int Idx1 = PN->getBasicBlockIndex(BB);
int Idx2 = PN->getBasicBlockIndex(*PI);
assert(Idx1 != -1 && Idx2 != -1 &&
"Didn't have entries for my predecessors??");
if (PN->getIncomingValue(Idx1) != PN->getIncomingValue(Idx2))
return true; // Values are not equal...
}
}
// Loop over all of the PHI nodes in the successor BB.
for (BasicBlock::iterator I = Succ->begin();
PHINode *PN = dyn_cast<PHINode>(I); ++I) {
Value *OldVal = PN->removeIncomingValue(BB, false);
assert(OldVal && "No entry in PHI for Pred BB!");
// If this incoming value is one of the PHI nodes in BB, the new entries in
// the PHI node are the entries from the old PHI.
if (isa<PHINode>(OldVal) && cast<PHINode>(OldVal)->getParent() == BB) {
PHINode *OldValPN = cast<PHINode>(OldVal);
for (unsigned i = 0, e = OldValPN->getNumIncomingValues(); i != e; ++i)
PN->addIncoming(OldValPN->getIncomingValue(i),
OldValPN->getIncomingBlock(i));
} else {
for (std::vector<BasicBlock*>::const_iterator PredI = BBPreds.begin(),
End = BBPreds.end(); PredI != End; ++PredI) {
// Add an incoming value for each of the new incoming values...
PN->addIncoming(OldVal, *PredI);
}
}
}
return false;
}
/// GetIfCondition - Given a basic block (BB) with two predecessors (and
/// presumably PHI nodes in it), check to see if the merge at this block is due
/// to an "if condition". If so, return the boolean condition that determines
/// which entry into BB will be taken. Also, return by references the block
/// that will be entered from if the condition is true, and the block that will
/// be entered if the condition is false.
///
///
static Value *GetIfCondition(BasicBlock *BB,