[PATCH] Move StructurizeCFG out of R600 to generic Transforms

Tom Stellard tom at stellard.net
Mon Jun 3 10:28:33 PDT 2013


On Mon, Jun 03, 2013 at 06:50:54AM -0700, Tom Stellard wrote:
> Hi Matt,
> 
> On Fri, May 31, 2013 at 05:53:22PM -0700, Matt Arsenault wrote:
> > Move StructurizeCFG out of R600 to generic Transforms.
> >     
> > Register it with PassManager
> > 
> > http://llvm-reviews.chandlerc.com/D906
> > 
> > Files:
> >   include/llvm/InitializePasses.h
> >   include/llvm/LinkAllPasses.h
> >   include/llvm/Transforms/Scalar.h
> >   lib/Target/R600/AMDGPUStructurizeCFG.cpp
> >   lib/Target/R600/AMDGPUTargetMachine.cpp
> >   lib/Target/R600/CMakeLists.txt
> >   lib/Transforms/Scalar/CMakeLists.txt
> >   lib/Transforms/Scalar/Scalar.cpp
> >   lib/Transforms/Scalar/StructurizeCFG.cpp
> 
> You forgot to add include/llvm/Transforms/Utils/StructurizeCFG.h to the
> patch.
> 
> Also, I'm working on some tests.
> 

I've attached a test case, It tests the structurizer using the R600
backend, since I couldn't get this patch to apply, but it should work
with opt too.  It just needs a RUN line.

-Tom


> > Index: include/llvm/InitializePasses.h
> > ===================================================================
> > --- include/llvm/InitializePasses.h
> > +++ include/llvm/InitializePasses.h
> > @@ -87,6 +87,7 @@
> >  void initializeCFGOnlyViewerPass(PassRegistry&);
> >  void initializeCFGPrinterPass(PassRegistry&);
> >  void initializeCFGSimplifyPassPass(PassRegistry&);
> > +void initializeStructurizeCFGPass(PassRegistry&);
> >  void initializeCFGViewerPass(PassRegistry&);
> >  void initializeCalculateSpillWeightsPass(PassRegistry&);
> >  void initializeCallGraphAnalysisGroup(PassRegistry&);
> > Index: include/llvm/LinkAllPasses.h
> > ===================================================================
> > --- include/llvm/LinkAllPasses.h
> > +++ include/llvm/LinkAllPasses.h
> > @@ -62,6 +62,7 @@
> >        (void) llvm::createCallGraphPrinterPass();
> >        (void) llvm::createCallGraphViewerPass();
> >        (void) llvm::createCFGSimplificationPass();
> > +      (void) llvm::createStructurizeCFGPass();
> >        (void) llvm::createConstantMergePass();
> >        (void) llvm::createConstantPropagationPass();
> >        (void) llvm::createCostModelAnalysisPass();
> > Index: include/llvm/Transforms/Scalar.h
> > ===================================================================
> > --- include/llvm/Transforms/Scalar.h
> > +++ include/llvm/Transforms/Scalar.h
> > @@ -199,6 +199,12 @@
> >  
> >  //===----------------------------------------------------------------------===//
> >  //
> > +// CFG Structurization - Remove irreducible control flow
> > +//
> > +Pass *createStructurizeCFGPass();
> > +
> > +//===----------------------------------------------------------------------===//
> > +//
> >  // BreakCriticalEdges - Break all of the critical edges in the CFG by inserting
> >  // a dummy basic block. This pass may be "required" by passes that cannot deal
> >  // with critical edges. For this usage, a pass must call:
> > Index: lib/Target/R600/AMDGPUStructurizeCFG.cpp
> > ===================================================================
> > --- lib/Target/R600/AMDGPUStructurizeCFG.cpp
> > +++ /dev/null
> > @@ -1,896 +0,0 @@
> > -//===-- AMDGPUStructurizeCFG.cpp -  ------------------===//
> > -//
> > -//                     The LLVM Compiler Infrastructure
> > -//
> > -// This file is distributed under the University of Illinois Open Source
> > -// License. See LICENSE.TXT for details.
> > -//
> > -//===----------------------------------------------------------------------===//
> > -//
> > -/// \file
> > -/// The pass implemented in this file transforms the programs control flow
> > -/// graph into a form that's suitable for code generation on hardware that
> > -/// implements control flow by execution masking. This currently includes all
> > -/// AMD GPUs but may as well be useful for other types of hardware.
> > -//
> > -//===----------------------------------------------------------------------===//
> > -
> > -#include "AMDGPU.h"
> > -#include "llvm/ADT/MapVector.h"
> > -#include "llvm/ADT/SCCIterator.h"
> > -#include "llvm/Analysis/RegionInfo.h"
> > -#include "llvm/Analysis/RegionIterator.h"
> > -#include "llvm/Analysis/RegionPass.h"
> > -#include "llvm/IR/Module.h"
> > -#include "llvm/Support/PatternMatch.h"
> > -#include "llvm/Transforms/Utils/SSAUpdater.h"
> > -
> > -using namespace llvm;
> > -using namespace llvm::PatternMatch;
> > -
> > -namespace {
> > -
> > -// Definition of the complex types used in this pass.
> > -
> > -typedef std::pair<BasicBlock *, Value *> BBValuePair;
> > -
> > -typedef SmallVector<RegionNode*, 8> RNVector;
> > -typedef SmallVector<BasicBlock*, 8> BBVector;
> > -typedef SmallVector<BranchInst*, 8> BranchVector;
> > -typedef SmallVector<BBValuePair, 2> BBValueVector;
> > -
> > -typedef SmallPtrSet<BasicBlock *, 8> BBSet;
> > -
> > -typedef MapVector<PHINode *, BBValueVector> PhiMap;
> > -typedef MapVector<BasicBlock *, BBVector> BB2BBVecMap;
> > -
> > -typedef DenseMap<DomTreeNode *, unsigned> DTN2UnsignedMap;
> > -typedef DenseMap<BasicBlock *, PhiMap> BBPhiMap;
> > -typedef DenseMap<BasicBlock *, Value *> BBPredicates;
> > -typedef DenseMap<BasicBlock *, BBPredicates> PredMap;
> > -typedef DenseMap<BasicBlock *, BasicBlock*> BB2BBMap;
> > -
> > -// The name for newly created blocks.
> > -
> > -static const char *FlowBlockName = "Flow";
> > -
> > -/// @brief Find the nearest common dominator for multiple BasicBlocks
> > -///
> > -/// Helper class for AMDGPUStructurizeCFG
> > -/// TODO: Maybe move into common code
> > -class NearestCommonDominator {
> > -
> > -  DominatorTree *DT;
> > -
> > -  DTN2UnsignedMap IndexMap;
> > -
> > -  BasicBlock *Result;
> > -  unsigned ResultIndex;
> > -  bool ExplicitMentioned;
> > -
> > -public:
> > -  /// \brief Start a new query
> > -  NearestCommonDominator(DominatorTree *DomTree) {
> > -    DT = DomTree;
> > -    Result = 0;
> > -  }
> > -
> > -  /// \brief Add BB to the resulting dominator
> > -  void addBlock(BasicBlock *BB, bool Remember = true) {
> > -
> > -    DomTreeNode *Node = DT->getNode(BB);
> > -
> > -    if (Result == 0) {
> > -      unsigned Numbering = 0;
> > -      for (;Node;Node = Node->getIDom())
> > -        IndexMap[Node] = ++Numbering;
> > -      Result = BB;
> > -      ResultIndex = 1;
> > -      ExplicitMentioned = Remember;
> > -      return;
> > -    }
> > -
> > -    for (;Node;Node = Node->getIDom())
> > -      if (IndexMap.count(Node))
> > -        break;
> > -      else
> > -        IndexMap[Node] = 0;
> > -
> > -    assert(Node && "Dominator tree invalid!");
> > -
> > -    unsigned Numbering = IndexMap[Node];
> > -    if (Numbering > ResultIndex) {
> > -      Result = Node->getBlock();
> > -      ResultIndex = Numbering;
> > -      ExplicitMentioned = Remember && (Result == BB);
> > -    } else if (Numbering == ResultIndex) {
> > -      ExplicitMentioned |= Remember;
> > -    }
> > -  }
> > -
> > -  /// \brief Is "Result" one of the BBs added with "Remember" = True?
> > -  bool wasResultExplicitMentioned() {
> > -    return ExplicitMentioned;
> > -  }
> > -
> > -  /// \brief Get the query result
> > -  BasicBlock *getResult() {
> > -    return Result;
> > -  }
> > -};
> > -
> > -/// @brief Transforms the control flow graph on one single entry/exit region
> > -/// at a time.
> > -///
> > -/// After the transform all "If"/"Then"/"Else" style control flow looks like
> > -/// this:
> > -///
> > -/// \verbatim
> > -/// 1
> > -/// ||
> > -/// | |
> > -/// 2 |
> > -/// | /
> > -/// |/   
> > -/// 3
> > -/// ||   Where:
> > -/// | |  1 = "If" block, calculates the condition
> > -/// 4 |  2 = "Then" subregion, runs if the condition is true
> > -/// | /  3 = "Flow" blocks, newly inserted flow blocks, rejoins the flow
> > -/// |/   4 = "Else" optional subregion, runs if the condition is false
> > -/// 5    5 = "End" block, also rejoins the control flow
> > -/// \endverbatim
> > -///
> > -/// Control flow is expressed as a branch where the true exit goes into the
> > -/// "Then"/"Else" region, while the false exit skips the region
> > -/// The condition for the optional "Else" region is expressed as a PHI node.
> > -/// The incomming values of the PHI node are true for the "If" edge and false
> > -/// for the "Then" edge.
> > -///
> > -/// Additionally to that even complicated loops look like this:
> > -///
> > -/// \verbatim
> > -/// 1
> > -/// ||
> > -/// | |
> > -/// 2 ^  Where:
> > -/// | /  1 = "Entry" block
> > -/// |/   2 = "Loop" optional subregion, with all exits at "Flow" block
> > -/// 3    3 = "Flow" block, with back edge to entry block
> > -/// |
> > -/// \endverbatim
> > -///
> > -/// The back edge of the "Flow" block is always on the false side of the branch
> > -/// while the true side continues the general flow. So the loop condition
> > -/// consist of a network of PHI nodes where the true incoming values expresses
> > -/// breaks and the false values expresses continue states.
> > -class AMDGPUStructurizeCFG : public RegionPass {
> > -
> > -  static char ID;
> > -
> > -  Type *Boolean;
> > -  ConstantInt *BoolTrue;
> > -  ConstantInt *BoolFalse;
> > -  UndefValue *BoolUndef;
> > -
> > -  Function *Func;
> > -  Region *ParentRegion;
> > -
> > -  DominatorTree *DT;
> > -
> > -  RNVector Order;
> > -  BBSet Visited;
> > -
> > -  BBPhiMap DeletedPhis;
> > -  BB2BBVecMap AddedPhis;
> > -
> > -  PredMap Predicates;
> > -  BranchVector Conditions;
> > -
> > -  BB2BBMap Loops;
> > -  PredMap LoopPreds;
> > -  BranchVector LoopConds;
> > -
> > -  RegionNode *PrevNode;
> > -
> > -  void orderNodes();
> > -
> > -  void analyzeLoops(RegionNode *N);
> > -
> > -  Value *invert(Value *Condition);
> > -
> > -  Value *buildCondition(BranchInst *Term, unsigned Idx, bool Invert);
> > -
> > -  void gatherPredicates(RegionNode *N);
> > -
> > -  void collectInfos();
> > -
> > -  void insertConditions(bool Loops);
> > -
> > -  void delPhiValues(BasicBlock *From, BasicBlock *To);
> > -
> > -  void addPhiValues(BasicBlock *From, BasicBlock *To);
> > -
> > -  void setPhiValues();
> > -
> > -  void killTerminator(BasicBlock *BB);
> > -
> > -  void changeExit(RegionNode *Node, BasicBlock *NewExit,
> > -                  bool IncludeDominator);
> > -
> > -  BasicBlock *getNextFlow(BasicBlock *Dominator);
> > -
> > -  BasicBlock *needPrefix(bool NeedEmpty);
> > -
> > -  BasicBlock *needPostfix(BasicBlock *Flow, bool ExitUseAllowed);
> > -
> > -  void setPrevNode(BasicBlock *BB);
> > -
> > -  bool dominatesPredicates(BasicBlock *BB, RegionNode *Node);
> > -
> > -  bool isPredictableTrue(RegionNode *Node);
> > -
> > -  void wireFlow(bool ExitUseAllowed, BasicBlock *LoopEnd);
> > -
> > -  void handleLoops(bool ExitUseAllowed, BasicBlock *LoopEnd);
> > -
> > -  void createFlow();
> > -
> > -  void rebuildSSA();
> > -
> > -public:
> > -  AMDGPUStructurizeCFG():
> > -    RegionPass(ID) {
> > -
> > -    initializeRegionInfoPass(*PassRegistry::getPassRegistry());
> > -  }
> > -
> > -  using Pass::doInitialization;
> > -  virtual bool doInitialization(Region *R, RGPassManager &RGM);
> > -
> > -  virtual bool runOnRegion(Region *R, RGPassManager &RGM);
> > -
> > -  virtual const char *getPassName() const {
> > -    return "AMDGPU simplify control flow";
> > -  }
> > -
> > -  void getAnalysisUsage(AnalysisUsage &AU) const {
> > -
> > -    AU.addRequired<DominatorTree>();
> > -    AU.addPreserved<DominatorTree>();
> > -    RegionPass::getAnalysisUsage(AU);
> > -  }
> > -
> > -};
> > -
> > -} // end anonymous namespace
> > -
> > -char AMDGPUStructurizeCFG::ID = 0;
> > -
> > -/// \brief Initialize the types and constants used in the pass
> > -bool AMDGPUStructurizeCFG::doInitialization(Region *R, RGPassManager &RGM) {
> > -  LLVMContext &Context = R->getEntry()->getContext();
> > -
> > -  Boolean = Type::getInt1Ty(Context);
> > -  BoolTrue = ConstantInt::getTrue(Context);
> > -  BoolFalse = ConstantInt::getFalse(Context);
> > -  BoolUndef = UndefValue::get(Boolean);
> > -
> > -  return false;
> > -}
> > -
> > -/// \brief Build up the general order of nodes
> > -void AMDGPUStructurizeCFG::orderNodes() {
> > -  scc_iterator<Region *> I = scc_begin(ParentRegion),
> > -                         E = scc_end(ParentRegion);
> > -  for (Order.clear(); I != E; ++I) {
> > -    std::vector<RegionNode *> &Nodes = *I;
> > -    Order.append(Nodes.begin(), Nodes.end());
> > -  }
> > -}
> > -
> > -/// \brief Determine the end of the loops
> > -void AMDGPUStructurizeCFG::analyzeLoops(RegionNode *N) {
> > -
> > -  if (N->isSubRegion()) {
> > -    // Test for exit as back edge
> > -    BasicBlock *Exit = N->getNodeAs<Region>()->getExit();
> > -    if (Visited.count(Exit))
> > -      Loops[Exit] = N->getEntry();
> > -
> > -  } else {
> > -    // Test for sucessors as back edge
> > -    BasicBlock *BB = N->getNodeAs<BasicBlock>();
> > -    BranchInst *Term = cast<BranchInst>(BB->getTerminator());
> > -
> > -    for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
> > -      BasicBlock *Succ = Term->getSuccessor(i);
> > -
> > -      if (Visited.count(Succ))
> > -        Loops[Succ] = BB;
> > -    }
> > -  }
> > -}
> > -
> > -/// \brief Invert the given condition
> > -Value *AMDGPUStructurizeCFG::invert(Value *Condition) {
> > -
> > -  // First: Check if it's a constant
> > -  if (Condition == BoolTrue)
> > -    return BoolFalse;
> > -
> > -  if (Condition == BoolFalse)
> > -    return BoolTrue;
> > -
> > -  if (Condition == BoolUndef)
> > -    return BoolUndef;
> > -
> > -  // Second: If the condition is already inverted, return the original value
> > -  if (match(Condition, m_Not(m_Value(Condition))))
> > -    return Condition;
> > -
> > -  // Third: Check all the users for an invert
> > -  BasicBlock *Parent = cast<Instruction>(Condition)->getParent();
> > -  for (Value::use_iterator I = Condition->use_begin(),
> > -       E = Condition->use_end(); I != E; ++I) {
> > -
> > -    Instruction *User = dyn_cast<Instruction>(*I);
> > -    if (!User || User->getParent() != Parent)
> > -      continue;
> > -
> > -    if (match(*I, m_Not(m_Specific(Condition))))
> > -      return *I;
> > -  }
> > -
> > -  // Last option: Create a new instruction
> > -  return BinaryOperator::CreateNot(Condition, "", Parent->getTerminator());
> > -}
> > -
> > -/// \brief Build the condition for one edge
> > -Value *AMDGPUStructurizeCFG::buildCondition(BranchInst *Term, unsigned Idx,
> > -                                            bool Invert) {
> > -  Value *Cond = Invert ? BoolFalse : BoolTrue;
> > -  if (Term->isConditional()) {
> > -    Cond = Term->getCondition();
> > -
> > -    if (Idx != Invert)
> > -      Cond = invert(Cond);
> > -  }
> > -  return Cond;
> > -}
> > -
> > -/// \brief Analyze the predecessors of each block and build up predicates
> > -void AMDGPUStructurizeCFG::gatherPredicates(RegionNode *N) {
> > -
> > -  RegionInfo *RI = ParentRegion->getRegionInfo();
> > -  BasicBlock *BB = N->getEntry();
> > -  BBPredicates &Pred = Predicates[BB];
> > -  BBPredicates &LPred = LoopPreds[BB];
> > -
> > -  for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
> > -       PI != PE; ++PI) {
> > -
> > -    // Ignore it if it's a branch from outside into our region entry
> > -    if (!ParentRegion->contains(*PI))
> > -      continue;
> > -
> > -    Region *R = RI->getRegionFor(*PI);
> > -    if (R == ParentRegion) {
> > -
> > -      // It's a top level block in our region
> > -      BranchInst *Term = cast<BranchInst>((*PI)->getTerminator());
> > -      for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
> > -        BasicBlock *Succ = Term->getSuccessor(i);
> > -        if (Succ != BB)
> > -          continue;
> > -
> > -        if (Visited.count(*PI)) {
> > -          // Normal forward edge
> > -          if (Term->isConditional()) {
> > -            // Try to treat it like an ELSE block
> > -            BasicBlock *Other = Term->getSuccessor(!i);
> > -            if (Visited.count(Other) && !Loops.count(Other) &&
> > -                !Pred.count(Other) && !Pred.count(*PI)) {
> > -
> > -              Pred[Other] = BoolFalse;
> > -              Pred[*PI] = BoolTrue;
> > -              continue;
> > -            }
> > -          }
> > -          Pred[*PI] = buildCondition(Term, i, false);
> > - 
> > -        } else {
> > -          // Back edge
> > -          LPred[*PI] = buildCondition(Term, i, true);
> > -        }
> > -      }
> > -
> > -    } else {
> > -
> > -      // It's an exit from a sub region
> > -      while(R->getParent() != ParentRegion)
> > -        R = R->getParent();
> > -
> > -      // Edge from inside a subregion to its entry, ignore it
> > -      if (R == N)
> > -        continue;
> > -
> > -      BasicBlock *Entry = R->getEntry();
> > -      if (Visited.count(Entry))
> > -        Pred[Entry] = BoolTrue;
> > -      else
> > -        LPred[Entry] = BoolFalse;
> > -    }
> > -  }
> > -}
> > -
> > -/// \brief Collect various loop and predicate infos
> > -void AMDGPUStructurizeCFG::collectInfos() {
> > -
> > -  // Reset predicate
> > -  Predicates.clear();
> > -
> > -  // and loop infos
> > -  Loops.clear();
> > -  LoopPreds.clear();
> > -
> > -  // Reset the visited nodes
> > -  Visited.clear();
> > -
> > -  for (RNVector::reverse_iterator OI = Order.rbegin(), OE = Order.rend();
> > -       OI != OE; ++OI) {
> > -
> > -    // Analyze all the conditions leading to a node
> > -    gatherPredicates(*OI);
> > -
> > -    // Remember that we've seen this node
> > -    Visited.insert((*OI)->getEntry());
> > -
> > -    // Find the last back edges
> > -    analyzeLoops(*OI);
> > -  }
> > -}
> > -
> > -/// \brief Insert the missing branch conditions
> > -void AMDGPUStructurizeCFG::insertConditions(bool Loops) {
> > -  BranchVector &Conds = Loops ? LoopConds : Conditions;
> > -  Value *Default = Loops ? BoolTrue : BoolFalse;
> > -  SSAUpdater PhiInserter;
> > -
> > -  for (BranchVector::iterator I = Conds.begin(),
> > -       E = Conds.end(); I != E; ++I) {
> > -
> > -    BranchInst *Term = *I;
> > -    assert(Term->isConditional());
> > -
> > -    BasicBlock *Parent = Term->getParent();
> > -    BasicBlock *SuccTrue = Term->getSuccessor(0);
> > -    BasicBlock *SuccFalse = Term->getSuccessor(1);
> > -
> > -    PhiInserter.Initialize(Boolean, "");
> > -    PhiInserter.AddAvailableValue(&Func->getEntryBlock(), Default);
> > -    PhiInserter.AddAvailableValue(Loops ? SuccFalse : Parent, Default);
> > -
> > -    BBPredicates &Preds = Loops ? LoopPreds[SuccFalse] : Predicates[SuccTrue];
> > -
> > -    NearestCommonDominator Dominator(DT);
> > -    Dominator.addBlock(Parent, false);
> > -
> > -    Value *ParentValue = 0;
> > -    for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end();
> > -         PI != PE; ++PI) {
> > -
> > -      if (PI->first == Parent) {
> > -        ParentValue = PI->second;
> > -        break;
> > -      }
> > -      PhiInserter.AddAvailableValue(PI->first, PI->second);
> > -      Dominator.addBlock(PI->first);
> > -    }
> > -
> > -    if (ParentValue) {
> > -      Term->setCondition(ParentValue);
> > -    } else {
> > -      if (!Dominator.wasResultExplicitMentioned())
> > -        PhiInserter.AddAvailableValue(Dominator.getResult(), Default);
> > -
> > -      Term->setCondition(PhiInserter.GetValueInMiddleOfBlock(Parent));
> > -    }
> > -  }
> > -}
> > -
> > -/// \brief Remove all PHI values coming from "From" into "To" and remember
> > -/// them in DeletedPhis
> > -void AMDGPUStructurizeCFG::delPhiValues(BasicBlock *From, BasicBlock *To) {
> > -  PhiMap &Map = DeletedPhis[To];
> > -  for (BasicBlock::iterator I = To->begin(), E = To->end();
> > -       I != E && isa<PHINode>(*I);) {
> > -
> > -    PHINode &Phi = cast<PHINode>(*I++);
> > -    while (Phi.getBasicBlockIndex(From) != -1) {
> > -      Value *Deleted = Phi.removeIncomingValue(From, false);
> > -      Map[&Phi].push_back(std::make_pair(From, Deleted));
> > -    }
> > -  }
> > -}
> > -
> > -/// \brief Add a dummy PHI value as soon as we knew the new predecessor
> > -void AMDGPUStructurizeCFG::addPhiValues(BasicBlock *From, BasicBlock *To) {
> > -  for (BasicBlock::iterator I = To->begin(), E = To->end();
> > -       I != E && isa<PHINode>(*I);) {
> > -
> > -    PHINode &Phi = cast<PHINode>(*I++);
> > -    Value *Undef = UndefValue::get(Phi.getType());
> > -    Phi.addIncoming(Undef, From);
> > -  }
> > -  AddedPhis[To].push_back(From);
> > -}
> > -
> > -/// \brief Add the real PHI value as soon as everything is set up
> > -void AMDGPUStructurizeCFG::setPhiValues() {
> > -
> > -  SSAUpdater Updater;
> > -  for (BB2BBVecMap::iterator AI = AddedPhis.begin(), AE = AddedPhis.end();
> > -       AI != AE; ++AI) {
> > -
> > -    BasicBlock *To = AI->first;
> > -    BBVector &From = AI->second;
> > -
> > -    if (!DeletedPhis.count(To))
> > -      continue;
> > -
> > -    PhiMap &Map = DeletedPhis[To];
> > -    for (PhiMap::iterator PI = Map.begin(), PE = Map.end();
> > -         PI != PE; ++PI) {
> > -
> > -      PHINode *Phi = PI->first;
> > -      Value *Undef = UndefValue::get(Phi->getType());
> > -      Updater.Initialize(Phi->getType(), "");
> > -      Updater.AddAvailableValue(&Func->getEntryBlock(), Undef);
> > -      Updater.AddAvailableValue(To, Undef);
> > -
> > -      NearestCommonDominator Dominator(DT);
> > -      Dominator.addBlock(To, false);
> > -      for (BBValueVector::iterator VI = PI->second.begin(),
> > -           VE = PI->second.end(); VI != VE; ++VI) {
> > -
> > -        Updater.AddAvailableValue(VI->first, VI->second);
> > -        Dominator.addBlock(VI->first);
> > -      }
> > -
> > -      if (!Dominator.wasResultExplicitMentioned())
> > -        Updater.AddAvailableValue(Dominator.getResult(), Undef);
> > -
> > -      for (BBVector::iterator FI = From.begin(), FE = From.end();
> > -           FI != FE; ++FI) {
> > -
> > -        int Idx = Phi->getBasicBlockIndex(*FI);
> > -        assert(Idx != -1);
> > -        Phi->setIncomingValue(Idx, Updater.GetValueAtEndOfBlock(*FI));
> > -      }
> > -    }
> > -
> > -    DeletedPhis.erase(To);
> > -  }
> > -  assert(DeletedPhis.empty());
> > -}
> > -
> > -/// \brief Remove phi values from all successors and then remove the terminator.
> > -void AMDGPUStructurizeCFG::killTerminator(BasicBlock *BB) {
> > -  TerminatorInst *Term = BB->getTerminator();
> > -  if (!Term)
> > -    return;
> > -
> > -  for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB);
> > -       SI != SE; ++SI) {
> > -
> > -    delPhiValues(BB, *SI);
> > -  }
> > -
> > -  Term->eraseFromParent();
> > -}
> > -
> > -/// \brief Let node exit(s) point to NewExit
> > -void AMDGPUStructurizeCFG::changeExit(RegionNode *Node, BasicBlock *NewExit,
> > -                                      bool IncludeDominator) {
> > -
> > -  if (Node->isSubRegion()) {
> > -    Region *SubRegion = Node->getNodeAs<Region>();
> > -    BasicBlock *OldExit = SubRegion->getExit();
> > -    BasicBlock *Dominator = 0;
> > -
> > -    // Find all the edges from the sub region to the exit
> > -    for (pred_iterator I = pred_begin(OldExit), E = pred_end(OldExit);
> > -         I != E;) {
> > -
> > -      BasicBlock *BB = *I++;
> > -      if (!SubRegion->contains(BB))
> > -        continue;
> > -
> > -      // Modify the edges to point to the new exit
> > -      delPhiValues(BB, OldExit);
> > -      BB->getTerminator()->replaceUsesOfWith(OldExit, NewExit);
> > -      addPhiValues(BB, NewExit);
> > -
> > -      // Find the new dominator (if requested)
> > -      if (IncludeDominator) {
> > -        if (!Dominator)
> > -          Dominator = BB;
> > -        else
> > -          Dominator = DT->findNearestCommonDominator(Dominator, BB);
> > -      }
> > -    }
> > -
> > -    // Change the dominator (if requested)
> > -    if (Dominator)
> > -      DT->changeImmediateDominator(NewExit, Dominator);
> > -
> > -    // Update the region info
> > -    SubRegion->replaceExit(NewExit);
> > -
> > -  } else {
> > -    BasicBlock *BB = Node->getNodeAs<BasicBlock>();
> > -    killTerminator(BB);
> > -    BranchInst::Create(NewExit, BB);
> > -    addPhiValues(BB, NewExit);
> > -    if (IncludeDominator)
> > -      DT->changeImmediateDominator(NewExit, BB);
> > -  }
> > -}
> > -
> > -/// \brief Create a new flow node and update dominator tree and region info
> > -BasicBlock *AMDGPUStructurizeCFG::getNextFlow(BasicBlock *Dominator) {
> > -  LLVMContext &Context = Func->getContext();
> > -  BasicBlock *Insert = Order.empty() ? ParentRegion->getExit() :
> > -                       Order.back()->getEntry();
> > -  BasicBlock *Flow = BasicBlock::Create(Context, FlowBlockName,
> > -                                        Func, Insert);
> > -  DT->addNewBlock(Flow, Dominator);
> > -  ParentRegion->getRegionInfo()->setRegionFor(Flow, ParentRegion);
> > -  return Flow;
> > -}
> > -
> > -/// \brief Create a new or reuse the previous node as flow node
> > -BasicBlock *AMDGPUStructurizeCFG::needPrefix(bool NeedEmpty) {
> > -
> > -  BasicBlock *Entry = PrevNode->getEntry();
> > -
> > -  if (!PrevNode->isSubRegion()) {
> > -    killTerminator(Entry);
> > -    if (!NeedEmpty || Entry->getFirstInsertionPt() == Entry->end())
> > -      return Entry;
> > -
> > -  } 
> > -
> > -  // create a new flow node
> > -  BasicBlock *Flow = getNextFlow(Entry);
> > -
> > -  // and wire it up
> > -  changeExit(PrevNode, Flow, true);
> > -  PrevNode = ParentRegion->getBBNode(Flow);
> > -  return Flow;
> > -}
> > -
> > -/// \brief Returns the region exit if possible, otherwise just a new flow node
> > -BasicBlock *AMDGPUStructurizeCFG::needPostfix(BasicBlock *Flow,
> > -                                              bool ExitUseAllowed) {
> > -
> > -  if (Order.empty() && ExitUseAllowed) {
> > -    BasicBlock *Exit = ParentRegion->getExit();
> > -    DT->changeImmediateDominator(Exit, Flow);
> > -    addPhiValues(Flow, Exit);
> > -    return Exit;
> > -  }
> > -  return getNextFlow(Flow);
> > -}
> > -
> > -/// \brief Set the previous node
> > -void AMDGPUStructurizeCFG::setPrevNode(BasicBlock *BB) {
> > -  PrevNode =  ParentRegion->contains(BB) ? ParentRegion->getBBNode(BB) : 0;
> > -}
> > -
> > -/// \brief Does BB dominate all the predicates of Node ?
> > -bool AMDGPUStructurizeCFG::dominatesPredicates(BasicBlock *BB, RegionNode *Node) {
> > -  BBPredicates &Preds = Predicates[Node->getEntry()];
> > -  for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end();
> > -       PI != PE; ++PI) {
> > -
> > -    if (!DT->dominates(BB, PI->first))
> > -      return false;
> > -  }
> > -  return true;
> > -}
> > -
> > -/// \brief Can we predict that this node will always be called?
> > -bool AMDGPUStructurizeCFG::isPredictableTrue(RegionNode *Node) {
> > -
> > -  BBPredicates &Preds = Predicates[Node->getEntry()];
> > -  bool Dominated = false;
> > -
> > -  // Regionentry is always true
> > -  if (PrevNode == 0)
> > -    return true;
> > -
> > -  for (BBPredicates::iterator I = Preds.begin(), E = Preds.end();
> > -       I != E; ++I) {
> > -
> > -    if (I->second != BoolTrue)
> > -      return false;
> > -
> > -    if (!Dominated && DT->dominates(I->first, PrevNode->getEntry()))
> > -      Dominated = true;
> > -  }
> > -
> > -  // TODO: The dominator check is too strict
> > -  return Dominated;
> > -}
> > -
> > -/// Take one node from the order vector and wire it up
> > -void AMDGPUStructurizeCFG::wireFlow(bool ExitUseAllowed,
> > -                                    BasicBlock *LoopEnd) {
> > -
> > -  RegionNode *Node = Order.pop_back_val();
> > -  Visited.insert(Node->getEntry());
> > -
> > -  if (isPredictableTrue(Node)) {
> > -    // Just a linear flow
> > -    if (PrevNode) {
> > -      changeExit(PrevNode, Node->getEntry(), true);
> > -    }
> > -    PrevNode = Node;
> > -
> > -  } else {
> > -    // Insert extra prefix node (or reuse last one)
> > -    BasicBlock *Flow = needPrefix(false);
> > -
> > -    // Insert extra postfix node (or use exit instead)
> > -    BasicBlock *Entry = Node->getEntry();
> > -    BasicBlock *Next = needPostfix(Flow, ExitUseAllowed);
> > -
> > -    // let it point to entry and next block
> > -    Conditions.push_back(BranchInst::Create(Entry, Next, BoolUndef, Flow));
> > -    addPhiValues(Flow, Entry);
> > -    DT->changeImmediateDominator(Entry, Flow);
> > -
> > -    PrevNode = Node;
> > -    while (!Order.empty() && !Visited.count(LoopEnd) &&
> > -           dominatesPredicates(Entry, Order.back())) {
> > -      handleLoops(false, LoopEnd);
> > -    }
> > -
> > -    changeExit(PrevNode, Next, false);
> > -    setPrevNode(Next);
> > -  }
> > -}
> > -
> > -void AMDGPUStructurizeCFG::handleLoops(bool ExitUseAllowed,
> > -                                       BasicBlock *LoopEnd) {
> > -  RegionNode *Node = Order.back();
> > -  BasicBlock *LoopStart = Node->getEntry();
> > -
> > -  if (!Loops.count(LoopStart)) {
> > -    wireFlow(ExitUseAllowed, LoopEnd);
> > -    return;
> > -  }
> > -
> > -  if (!isPredictableTrue(Node))
> > -    LoopStart = needPrefix(true);
> > -
> > -  LoopEnd = Loops[Node->getEntry()];
> > -  wireFlow(false, LoopEnd);
> > -  while (!Visited.count(LoopEnd)) {
> > -    handleLoops(false, LoopEnd);
> > -  }
> > -
> > -  // Create an extra loop end node
> > -  LoopEnd = needPrefix(false);
> > -  BasicBlock *Next = needPostfix(LoopEnd, ExitUseAllowed);
> > -  LoopConds.push_back(BranchInst::Create(Next, LoopStart,
> > -                                         BoolUndef, LoopEnd));
> > -  addPhiValues(LoopEnd, LoopStart);
> > -  setPrevNode(Next);
> > -}
> > -
> > -/// After this function control flow looks like it should be, but
> > -/// branches and PHI nodes only have undefined conditions.
> > -void AMDGPUStructurizeCFG::createFlow() {
> > -
> > -  BasicBlock *Exit = ParentRegion->getExit();
> > -  bool EntryDominatesExit = DT->dominates(ParentRegion->getEntry(), Exit);
> > -
> > -  DeletedPhis.clear();
> > -  AddedPhis.clear();
> > -  Conditions.clear();
> > -  LoopConds.clear();
> > -
> > -  PrevNode = 0;
> > -  Visited.clear();
> > -
> > -  while (!Order.empty()) {
> > -    handleLoops(EntryDominatesExit, 0);
> > -  }
> > -
> > -  if (PrevNode)
> > -    changeExit(PrevNode, Exit, EntryDominatesExit);
> > -  else
> > -    assert(EntryDominatesExit);
> > -}
> > -
> > -/// Handle a rare case where the disintegrated nodes instructions
> > -/// no longer dominate all their uses. Not sure if this is really nessasary
> > -void AMDGPUStructurizeCFG::rebuildSSA() {
> > -  SSAUpdater Updater;
> > -  for (Region::block_iterator I = ParentRegion->block_begin(),
> > -                              E = ParentRegion->block_end();
> > -       I != E; ++I) {
> > -
> > -    BasicBlock *BB = *I;
> > -    for (BasicBlock::iterator II = BB->begin(), IE = BB->end();
> > -         II != IE; ++II) {
> > -
> > -      bool Initialized = false;
> > -      for (Use *I = &II->use_begin().getUse(), *Next; I; I = Next) {
> > -
> > -        Next = I->getNext();
> > -
> > -        Instruction *User = cast<Instruction>(I->getUser());
> > -        if (User->getParent() == BB) {
> > -          continue;
> > -
> > -        } else if (PHINode *UserPN = dyn_cast<PHINode>(User)) {
> > -          if (UserPN->getIncomingBlock(*I) == BB)
> > -            continue;
> > -        }
> > -
> > -        if (DT->dominates(II, User))
> > -          continue;
> > -
> > -        if (!Initialized) {
> > -          Value *Undef = UndefValue::get(II->getType());
> > -          Updater.Initialize(II->getType(), "");
> > -          Updater.AddAvailableValue(&Func->getEntryBlock(), Undef);
> > -          Updater.AddAvailableValue(BB, II);
> > -          Initialized = true;
> > -        }
> > -        Updater.RewriteUseAfterInsertions(*I);
> > -      }
> > -    }
> > -  }
> > -}
> > -
> > -/// \brief Run the transformation for each region found
> > -bool AMDGPUStructurizeCFG::runOnRegion(Region *R, RGPassManager &RGM) {
> > -  if (R->isTopLevelRegion())
> > -    return false;
> > -
> > -  Func = R->getEntry()->getParent();
> > -  ParentRegion = R;
> > -
> > -  DT = &getAnalysis<DominatorTree>();
> > -
> > -  orderNodes();
> > -  collectInfos();
> > -  createFlow();
> > -  insertConditions(false);
> > -  insertConditions(true);
> > -  setPhiValues();
> > -  rebuildSSA();
> > -
> > -  // Cleanup
> > -  Order.clear();
> > -  Visited.clear();
> > -  DeletedPhis.clear();
> > -  AddedPhis.clear();
> > -  Predicates.clear();
> > -  Conditions.clear();
> > -  Loops.clear();
> > -  LoopPreds.clear();
> > -  LoopConds.clear();
> > -
> > -  return true;
> > -}
> > -
> > -/// \brief Create the pass
> > -Pass *llvm::createAMDGPUStructurizeCFGPass() {
> > -  return new AMDGPUStructurizeCFG();
> > -}
> > Index: lib/Target/R600/AMDGPUTargetMachine.cpp
> > ===================================================================
> > --- lib/Target/R600/AMDGPUTargetMachine.cpp
> > +++ lib/Target/R600/AMDGPUTargetMachine.cpp
> > @@ -31,6 +31,7 @@
> >  #include "llvm/Support/raw_os_ostream.h"
> >  #include "llvm/Transforms/IPO.h"
> >  #include "llvm/Transforms/Scalar.h"
> > +#include "llvm/Transforms/Utils/StructurizeCFG.h"
> >  #include <llvm/CodeGen/Passes.h>
> >  
> >  using namespace llvm;
> > @@ -109,7 +110,7 @@
> >  AMDGPUPassConfig::addPreISel() {
> >    const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
> >    if (ST.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
> > -    addPass(createAMDGPUStructurizeCFGPass());
> > +    addPass(createStructurizeCFGPass());
> >      addPass(createSIAnnotateControlFlowPass());
> >    } else {
> >      addPass(createR600TextureIntrinsicsReplacer());
> > Index: lib/Target/R600/CMakeLists.txt
> > ===================================================================
> > --- lib/Target/R600/CMakeLists.txt
> > +++ lib/Target/R600/CMakeLists.txt
> > @@ -28,7 +28,6 @@
> >    AMDGPUMCInstLower.cpp
> >    AMDGPUMachineFunction.cpp
> >    AMDGPUSubtarget.cpp
> > -  AMDGPUStructurizeCFG.cpp
> >    AMDGPUTargetMachine.cpp
> >    AMDGPUISelLowering.cpp
> >    AMDGPUConvertToISA.cpp
> > Index: lib/Transforms/Scalar/CMakeLists.txt
> > ===================================================================
> > --- lib/Transforms/Scalar/CMakeLists.txt
> > +++ lib/Transforms/Scalar/CMakeLists.txt
> > @@ -30,6 +30,7 @@
> >    SimplifyCFGPass.cpp
> >    SimplifyLibCalls.cpp
> >    Sink.cpp
> > +  StructurizeCFG.cpp
> >    TailRecursionElimination.cpp
> >    )
> >  
> > Index: lib/Transforms/Scalar/Scalar.cpp
> > ===================================================================
> > --- lib/Transforms/Scalar/Scalar.cpp
> > +++ lib/Transforms/Scalar/Scalar.cpp
> > @@ -58,6 +58,7 @@
> >    initializeSROA_DTPass(Registry);
> >    initializeSROA_SSAUpPass(Registry);
> >    initializeCFGSimplifyPassPass(Registry);
> > +  initializeStructurizeCFGPass(Registry);
> >    initializeSimplifyLibCallsPass(Registry);
> >    initializeSinkingPass(Registry);
> >    initializeTailCallElimPass(Registry);
> > Index: lib/Transforms/Scalar/StructurizeCFG.cpp
> > ===================================================================
> > --- /dev/null
> > +++ lib/Transforms/Scalar/StructurizeCFG.cpp
> > @@ -0,0 +1,879 @@
> > +//===-- StructurizeCFG.cpp ------------------------------------------------===//
> > +//
> > +//                     The LLVM Compiler Infrastructure
> > +//
> > +// This file is distributed under the University of Illinois Open Source
> > +// License. See LICENSE.TXT for details.
> > +//
> > +//===----------------------------------------------------------------------===//
> > +
> > +#define DEBUG_TYPE "structurizecfg"
> > +#include "llvm/Transforms/Utils/StructurizeCFG.h"
> > +#include "llvm/ADT/MapVector.h"
> > +#include "llvm/ADT/SCCIterator.h"
> > +#include "llvm/Analysis/RegionInfo.h"
> > +#include "llvm/Analysis/RegionIterator.h"
> > +#include "llvm/Analysis/RegionPass.h"
> > +#include "llvm/IR/Module.h"
> > +#include "llvm/Support/PatternMatch.h"
> > +#include "llvm/Transforms/Utils/SSAUpdater.h"
> > +
> > +using namespace llvm;
> > +using namespace llvm::PatternMatch;
> > +
> > +namespace {
> > +
> > +// Definition of the complex types used in this pass.
> > +
> > +typedef std::pair<BasicBlock *, Value *> BBValuePair;
> > +
> > +typedef SmallVector<RegionNode*, 8> RNVector;
> > +typedef SmallVector<BasicBlock*, 8> BBVector;
> > +typedef SmallVector<BranchInst*, 8> BranchVector;
> > +typedef SmallVector<BBValuePair, 2> BBValueVector;
> > +
> > +typedef SmallPtrSet<BasicBlock *, 8> BBSet;
> > +
> > +typedef MapVector<PHINode *, BBValueVector> PhiMap;
> > +typedef MapVector<BasicBlock *, BBVector> BB2BBVecMap;
> > +
> > +typedef DenseMap<DomTreeNode *, unsigned> DTN2UnsignedMap;
> > +typedef DenseMap<BasicBlock *, PhiMap> BBPhiMap;
> > +typedef DenseMap<BasicBlock *, Value *> BBPredicates;
> > +typedef DenseMap<BasicBlock *, BBPredicates> PredMap;
> > +typedef DenseMap<BasicBlock *, BasicBlock*> BB2BBMap;
> > +
> > +// The name for newly created blocks.
> > +
> > +static const char *FlowBlockName = "Flow";
> > +
> > +/// @brief Find the nearest common dominator for multiple BasicBlocks
> > +///
> > +/// Helper class for StructurizeCFG
> > +/// TODO: Maybe move into common code
> > +class NearestCommonDominator {
> > +  DominatorTree *DT;
> > +
> > +  DTN2UnsignedMap IndexMap;
> > +
> > +  BasicBlock *Result;
> > +  unsigned ResultIndex;
> > +  bool ExplicitMentioned;
> > +
> > +public:
> > +  /// \brief Start a new query
> > +  NearestCommonDominator(DominatorTree *DomTree) {
> > +    DT = DomTree;
> > +    Result = 0;
> > +  }
> > +
> > +  /// \brief Add BB to the resulting dominator
> > +  void addBlock(BasicBlock *BB, bool Remember = true) {
> > +    DomTreeNode *Node = DT->getNode(BB);
> > +
> > +    if (Result == 0) {
> > +      unsigned Numbering = 0;
> > +      for (;Node;Node = Node->getIDom())
> > +        IndexMap[Node] = ++Numbering;
> > +      Result = BB;
> > +      ResultIndex = 1;
> > +      ExplicitMentioned = Remember;
> > +      return;
> > +    }
> > +
> > +    for (;Node;Node = Node->getIDom())
> > +      if (IndexMap.count(Node))
> > +        break;
> > +      else
> > +        IndexMap[Node] = 0;
> > +
> > +    assert(Node && "Dominator tree invalid!");
> > +
> > +    unsigned Numbering = IndexMap[Node];
> > +    if (Numbering > ResultIndex) {
> > +      Result = Node->getBlock();
> > +      ResultIndex = Numbering;
> > +      ExplicitMentioned = Remember && (Result == BB);
> > +    } else if (Numbering == ResultIndex) {
> > +      ExplicitMentioned |= Remember;
> > +    }
> > +  }
> > +
> > +  /// \brief Is "Result" one of the BBs added with "Remember" = True?
> > +  bool wasResultExplicitMentioned() {
> > +    return ExplicitMentioned;
> > +  }
> > +
> > +  /// \brief Get the query result
> > +  BasicBlock *getResult() {
> > +    return Result;
> > +  }
> > +};
> > +
> > +/// @brief Transforms the control flow graph on one single entry/exit region
> > +/// at a time.
> > +///
> > +/// After the transform all "If"/"Then"/"Else" style control flow looks like
> > +/// this:
> > +///
> > +/// \verbatim
> > +/// 1
> > +/// ||
> > +/// | |
> > +/// 2 |
> > +/// | /
> > +/// |/
> > +/// 3
> > +/// ||   Where:
> > +/// | |  1 = "If" block, calculates the condition
> > +/// 4 |  2 = "Then" subregion, runs if the condition is true
> > +/// | /  3 = "Flow" blocks, newly inserted flow blocks, rejoins the flow
> > +/// |/   4 = "Else" optional subregion, runs if the condition is false
> > +/// 5    5 = "End" block, also rejoins the control flow
> > +/// \endverbatim
> > +///
> > +/// Control flow is expressed as a branch where the true exit goes into the
> > +/// "Then"/"Else" region, while the false exit skips the region
> > +/// The condition for the optional "Else" region is expressed as a PHI node.
> > +/// The incomming values of the PHI node are true for the "If" edge and false
> > +/// for the "Then" edge.
> > +///
> > +/// Additionally to that even complicated loops look like this:
> > +///
> > +/// \verbatim
> > +/// 1
> > +/// ||
> > +/// | |
> > +/// 2 ^  Where:
> > +/// | /  1 = "Entry" block
> > +/// |/   2 = "Loop" optional subregion, with all exits at "Flow" block
> > +/// 3    3 = "Flow" block, with back edge to entry block
> > +/// |
> > +/// \endverbatim
> > +///
> > +/// The back edge of the "Flow" block is always on the false side of the branch
> > +/// while the true side continues the general flow. So the loop condition
> > +/// consist of a network of PHI nodes where the true incoming values expresses
> > +/// breaks and the false values expresses continue states.
> > +class StructurizeCFG : public RegionPass {
> > +  Type *Boolean;
> > +  ConstantInt *BoolTrue;
> > +  ConstantInt *BoolFalse;
> > +  UndefValue *BoolUndef;
> > +
> > +  Function *Func;
> > +  Region *ParentRegion;
> > +
> > +  DominatorTree *DT;
> > +
> > +  RNVector Order;
> > +  BBSet Visited;
> > +
> > +  BBPhiMap DeletedPhis;
> > +  BB2BBVecMap AddedPhis;
> > +
> > +  PredMap Predicates;
> > +  BranchVector Conditions;
> > +
> > +  BB2BBMap Loops;
> > +  PredMap LoopPreds;
> > +  BranchVector LoopConds;
> > +
> > +  RegionNode *PrevNode;
> > +
> > +  void orderNodes();
> > +
> > +  void analyzeLoops(RegionNode *N);
> > +
> > +  Value *invert(Value *Condition);
> > +
> > +  Value *buildCondition(BranchInst *Term, unsigned Idx, bool Invert);
> > +
> > +  void gatherPredicates(RegionNode *N);
> > +
> > +  void collectInfos();
> > +
> > +  void insertConditions(bool Loops);
> > +
> > +  void delPhiValues(BasicBlock *From, BasicBlock *To);
> > +
> > +  void addPhiValues(BasicBlock *From, BasicBlock *To);
> > +
> > +  void setPhiValues();
> > +
> > +  void killTerminator(BasicBlock *BB);
> > +
> > +  void changeExit(RegionNode *Node, BasicBlock *NewExit,
> > +                  bool IncludeDominator);
> > +
> > +  BasicBlock *getNextFlow(BasicBlock *Dominator);
> > +
> > +  BasicBlock *needPrefix(bool NeedEmpty);
> > +
> > +  BasicBlock *needPostfix(BasicBlock *Flow, bool ExitUseAllowed);
> > +
> > +  void setPrevNode(BasicBlock *BB);
> > +
> > +  bool dominatesPredicates(BasicBlock *BB, RegionNode *Node);
> > +
> > +  bool isPredictableTrue(RegionNode *Node);
> > +
> > +  void wireFlow(bool ExitUseAllowed, BasicBlock *LoopEnd);
> > +
> > +  void handleLoops(bool ExitUseAllowed, BasicBlock *LoopEnd);
> > +
> > +  void createFlow();
> > +
> > +  void rebuildSSA();
> > +
> > +public:
> > +  static char ID;
> > +
> > +  StructurizeCFG() :
> > +    RegionPass(ID) {
> > +    initializeRegionInfoPass(*PassRegistry::getPassRegistry());
> > +  }
> > +
> > +  using Pass::doInitialization;
> > +  virtual bool doInitialization(Region *R, RGPassManager &RGM);
> > +
> > +  virtual bool runOnRegion(Region *R, RGPassManager &RGM);
> > +
> > +  virtual const char *getPassName() const {
> > +    return "Structurize control flow";
> > +  }
> > +
> > +  void getAnalysisUsage(AnalysisUsage &AU) const {
> > +    AU.addRequired<DominatorTree>();
> > +    AU.addPreserved<DominatorTree>();
> > +    RegionPass::getAnalysisUsage(AU);
> > +  }
> > +};
> > +
> > +} // end anonymous namespace
> > +
> > +char StructurizeCFG::ID = 0;
> > +
> > +INITIALIZE_PASS_BEGIN(StructurizeCFG, "structurizecfg", "Structurize the CFG",
> > +                      false, false)
> > +INITIALIZE_PASS_DEPENDENCY(DominatorTree)
> > +INITIALIZE_PASS_DEPENDENCY(RegionInfo)
> > +INITIALIZE_PASS_END(StructurizeCFG, "structurizecfg", "Structurize the CFG",
> > +                    false, false)
> > +
> > +/// \brief Initialize the types and constants used in the pass
> > +bool StructurizeCFG::doInitialization(Region *R, RGPassManager &RGM) {
> > +  LLVMContext &Context = R->getEntry()->getContext();
> > +
> > +  Boolean = Type::getInt1Ty(Context);
> > +  BoolTrue = ConstantInt::getTrue(Context);
> > +  BoolFalse = ConstantInt::getFalse(Context);
> > +  BoolUndef = UndefValue::get(Boolean);
> > +
> > +  return false;
> > +}
> > +
> > +/// \brief Build up the general order of nodes
> > +void StructurizeCFG::orderNodes() {
> > +  scc_iterator<Region *> I = scc_begin(ParentRegion),
> > +                         E = scc_end(ParentRegion);
> > +  for (Order.clear(); I != E; ++I) {
> > +    std::vector<RegionNode *> &Nodes = *I;
> > +    Order.append(Nodes.begin(), Nodes.end());
> > +  }
> > +}
> > +
> > +/// \brief Determine the end of the loops
> > +void StructurizeCFG::analyzeLoops(RegionNode *N) {
> > +  if (N->isSubRegion()) {
> > +    // Test for exit as back edge
> > +    BasicBlock *Exit = N->getNodeAs<Region>()->getExit();
> > +    if (Visited.count(Exit))
> > +      Loops[Exit] = N->getEntry();
> > +
> > +  } else {
> > +    // Test for sucessors as back edge
> > +    BasicBlock *BB = N->getNodeAs<BasicBlock>();
> > +    BranchInst *Term = cast<BranchInst>(BB->getTerminator());
> > +
> > +    for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
> > +      BasicBlock *Succ = Term->getSuccessor(i);
> > +
> > +      if (Visited.count(Succ))
> > +        Loops[Succ] = BB;
> > +    }
> > +  }
> > +}
> > +
> > +/// \brief Invert the given condition
> > +Value *StructurizeCFG::invert(Value *Condition) {
> > +  // First: Check if it's a constant
> > +  if (Condition == BoolTrue)
> > +    return BoolFalse;
> > +
> > +  if (Condition == BoolFalse)
> > +    return BoolTrue;
> > +
> > +  if (Condition == BoolUndef)
> > +    return BoolUndef;
> > +
> > +  // Second: If the condition is already inverted, return the original value
> > +  if (match(Condition, m_Not(m_Value(Condition))))
> > +    return Condition;
> > +
> > +  // Third: Check all the users for an invert
> > +  BasicBlock *Parent = cast<Instruction>(Condition)->getParent();
> > +  for (Value::use_iterator I = Condition->use_begin(),
> > +       E = Condition->use_end(); I != E; ++I) {
> > +
> > +    Instruction *User = dyn_cast<Instruction>(*I);
> > +    if (!User || User->getParent() != Parent)
> > +      continue;
> > +
> > +    if (match(*I, m_Not(m_Specific(Condition))))
> > +      return *I;
> > +  }
> > +
> > +  // Last option: Create a new instruction
> > +  return BinaryOperator::CreateNot(Condition, "", Parent->getTerminator());
> > +}
> > +
> > +/// \brief Build the condition for one edge
> > +Value *StructurizeCFG::buildCondition(BranchInst *Term, unsigned Idx,
> > +                                      bool Invert) {
> > +  Value *Cond = Invert ? BoolFalse : BoolTrue;
> > +  if (Term->isConditional()) {
> > +    Cond = Term->getCondition();
> > +
> > +    if (Idx != Invert)
> > +      Cond = invert(Cond);
> > +  }
> > +  return Cond;
> > +}
> > +
> > +/// \brief Analyze the predecessors of each block and build up predicates
> > +void StructurizeCFG::gatherPredicates(RegionNode *N) {
> > +  RegionInfo *RI = ParentRegion->getRegionInfo();
> > +  BasicBlock *BB = N->getEntry();
> > +  BBPredicates &Pred = Predicates[BB];
> > +  BBPredicates &LPred = LoopPreds[BB];
> > +
> > +  for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
> > +       PI != PE; ++PI) {
> > +
> > +    // Ignore it if it's a branch from outside into our region entry
> > +    if (!ParentRegion->contains(*PI))
> > +      continue;
> > +
> > +    Region *R = RI->getRegionFor(*PI);
> > +    if (R == ParentRegion) {
> > +
> > +      // It's a top level block in our region
> > +      BranchInst *Term = cast<BranchInst>((*PI)->getTerminator());
> > +      for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
> > +        BasicBlock *Succ = Term->getSuccessor(i);
> > +        if (Succ != BB)
> > +          continue;
> > +
> > +        if (Visited.count(*PI)) {
> > +          // Normal forward edge
> > +          if (Term->isConditional()) {
> > +            // Try to treat it like an ELSE block
> > +            BasicBlock *Other = Term->getSuccessor(!i);
> > +            if (Visited.count(Other) && !Loops.count(Other) &&
> > +                !Pred.count(Other) && !Pred.count(*PI)) {
> > +
> > +              Pred[Other] = BoolFalse;
> > +              Pred[*PI] = BoolTrue;
> > +              continue;
> > +            }
> > +          }
> > +          Pred[*PI] = buildCondition(Term, i, false);
> > +
> > +        } else {
> > +          // Back edge
> > +          LPred[*PI] = buildCondition(Term, i, true);
> > +        }
> > +      }
> > +
> > +    } else {
> > +
> > +      // It's an exit from a sub region
> > +      while(R->getParent() != ParentRegion)
> > +        R = R->getParent();
> > +
> > +      // Edge from inside a subregion to its entry, ignore it
> > +      if (R == N)
> > +        continue;
> > +
> > +      BasicBlock *Entry = R->getEntry();
> > +      if (Visited.count(Entry))
> > +        Pred[Entry] = BoolTrue;
> > +      else
> > +        LPred[Entry] = BoolFalse;
> > +    }
> > +  }
> > +}
> > +
> > +/// \brief Collect various loop and predicate infos
> > +void StructurizeCFG::collectInfos() {
> > +  // Reset predicate
> > +  Predicates.clear();
> > +
> > +  // and loop infos
> > +  Loops.clear();
> > +  LoopPreds.clear();
> > +
> > +  // Reset the visited nodes
> > +  Visited.clear();
> > +
> > +  for (RNVector::reverse_iterator OI = Order.rbegin(), OE = Order.rend();
> > +       OI != OE; ++OI) {
> > +
> > +    // Analyze all the conditions leading to a node
> > +    gatherPredicates(*OI);
> > +
> > +    // Remember that we've seen this node
> > +    Visited.insert((*OI)->getEntry());
> > +
> > +    // Find the last back edges
> > +    analyzeLoops(*OI);
> > +  }
> > +}
> > +
> > +/// \brief Insert the missing branch conditions
> > +void StructurizeCFG::insertConditions(bool Loops) {
> > +  BranchVector &Conds = Loops ? LoopConds : Conditions;
> > +  Value *Default = Loops ? BoolTrue : BoolFalse;
> > +  SSAUpdater PhiInserter;
> > +
> > +  for (BranchVector::iterator I = Conds.begin(),
> > +       E = Conds.end(); I != E; ++I) {
> > +
> > +    BranchInst *Term = *I;
> > +    assert(Term->isConditional());
> > +
> > +    BasicBlock *Parent = Term->getParent();
> > +    BasicBlock *SuccTrue = Term->getSuccessor(0);
> > +    BasicBlock *SuccFalse = Term->getSuccessor(1);
> > +
> > +    PhiInserter.Initialize(Boolean, "");
> > +    PhiInserter.AddAvailableValue(&Func->getEntryBlock(), Default);
> > +    PhiInserter.AddAvailableValue(Loops ? SuccFalse : Parent, Default);
> > +
> > +    BBPredicates &Preds = Loops ? LoopPreds[SuccFalse] : Predicates[SuccTrue];
> > +
> > +    NearestCommonDominator Dominator(DT);
> > +    Dominator.addBlock(Parent, false);
> > +
> > +    Value *ParentValue = 0;
> > +    for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end();
> > +         PI != PE; ++PI) {
> > +
> > +      if (PI->first == Parent) {
> > +        ParentValue = PI->second;
> > +        break;
> > +      }
> > +      PhiInserter.AddAvailableValue(PI->first, PI->second);
> > +      Dominator.addBlock(PI->first);
> > +    }
> > +
> > +    if (ParentValue) {
> > +      Term->setCondition(ParentValue);
> > +    } else {
> > +      if (!Dominator.wasResultExplicitMentioned())
> > +        PhiInserter.AddAvailableValue(Dominator.getResult(), Default);
> > +
> > +      Term->setCondition(PhiInserter.GetValueInMiddleOfBlock(Parent));
> > +    }
> > +  }
> > +}
> > +
> > +/// \brief Remove all PHI values coming from "From" into "To" and remember
> > +/// them in DeletedPhis
> > +void StructurizeCFG::delPhiValues(BasicBlock *From, BasicBlock *To) {
> > +  PhiMap &Map = DeletedPhis[To];
> > +  for (BasicBlock::iterator I = To->begin(), E = To->end();
> > +       I != E && isa<PHINode>(*I);) {
> > +
> > +    PHINode &Phi = cast<PHINode>(*I++);
> > +    while (Phi.getBasicBlockIndex(From) != -1) {
> > +      Value *Deleted = Phi.removeIncomingValue(From, false);
> > +      Map[&Phi].push_back(std::make_pair(From, Deleted));
> > +    }
> > +  }
> > +}
> > +
> > +/// \brief Add a dummy PHI value as soon as we knew the new predecessor
> > +void StructurizeCFG::addPhiValues(BasicBlock *From, BasicBlock *To) {
> > +  for (BasicBlock::iterator I = To->begin(), E = To->end();
> > +       I != E && isa<PHINode>(*I);) {
> > +
> > +    PHINode &Phi = cast<PHINode>(*I++);
> > +    Value *Undef = UndefValue::get(Phi.getType());
> > +    Phi.addIncoming(Undef, From);
> > +  }
> > +  AddedPhis[To].push_back(From);
> > +}
> > +
> > +/// \brief Add the real PHI value as soon as everything is set up
> > +void StructurizeCFG::setPhiValues() {
> > +  SSAUpdater Updater;
> > +  for (BB2BBVecMap::iterator AI = AddedPhis.begin(), AE = AddedPhis.end();
> > +       AI != AE; ++AI) {
> > +
> > +    BasicBlock *To = AI->first;
> > +    BBVector &From = AI->second;
> > +
> > +    if (!DeletedPhis.count(To))
> > +      continue;
> > +
> > +    PhiMap &Map = DeletedPhis[To];
> > +    for (PhiMap::iterator PI = Map.begin(), PE = Map.end();
> > +         PI != PE; ++PI) {
> > +
> > +      PHINode *Phi = PI->first;
> > +      Value *Undef = UndefValue::get(Phi->getType());
> > +      Updater.Initialize(Phi->getType(), "");
> > +      Updater.AddAvailableValue(&Func->getEntryBlock(), Undef);
> > +      Updater.AddAvailableValue(To, Undef);
> > +
> > +      NearestCommonDominator Dominator(DT);
> > +      Dominator.addBlock(To, false);
> > +      for (BBValueVector::iterator VI = PI->second.begin(),
> > +           VE = PI->second.end(); VI != VE; ++VI) {
> > +
> > +        Updater.AddAvailableValue(VI->first, VI->second);
> > +        Dominator.addBlock(VI->first);
> > +      }
> > +
> > +      if (!Dominator.wasResultExplicitMentioned())
> > +        Updater.AddAvailableValue(Dominator.getResult(), Undef);
> > +
> > +      for (BBVector::iterator FI = From.begin(), FE = From.end();
> > +           FI != FE; ++FI) {
> > +
> > +        int Idx = Phi->getBasicBlockIndex(*FI);
> > +        assert(Idx != -1);
> > +        Phi->setIncomingValue(Idx, Updater.GetValueAtEndOfBlock(*FI));
> > +      }
> > +    }
> > +
> > +    DeletedPhis.erase(To);
> > +  }
> > +  assert(DeletedPhis.empty());
> > +}
> > +
> > +/// \brief Remove phi values from all successors and then remove the terminator.
> > +void StructurizeCFG::killTerminator(BasicBlock *BB) {
> > +  TerminatorInst *Term = BB->getTerminator();
> > +  if (!Term)
> > +    return;
> > +
> > +  for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB);
> > +       SI != SE; ++SI) {
> > +
> > +    delPhiValues(BB, *SI);
> > +  }
> > +
> > +  Term->eraseFromParent();
> > +}
> > +
> > +/// \brief Let node exit(s) point to NewExit
> > +void StructurizeCFG::changeExit(RegionNode *Node, BasicBlock *NewExit,
> > +                                bool IncludeDominator) {
> > +  if (Node->isSubRegion()) {
> > +    Region *SubRegion = Node->getNodeAs<Region>();
> > +    BasicBlock *OldExit = SubRegion->getExit();
> > +    BasicBlock *Dominator = 0;
> > +
> > +    // Find all the edges from the sub region to the exit
> > +    for (pred_iterator I = pred_begin(OldExit), E = pred_end(OldExit);
> > +         I != E;) {
> > +
> > +      BasicBlock *BB = *I++;
> > +      if (!SubRegion->contains(BB))
> > +        continue;
> > +
> > +      // Modify the edges to point to the new exit
> > +      delPhiValues(BB, OldExit);
> > +      BB->getTerminator()->replaceUsesOfWith(OldExit, NewExit);
> > +      addPhiValues(BB, NewExit);
> > +
> > +      // Find the new dominator (if requested)
> > +      if (IncludeDominator) {
> > +        if (!Dominator)
> > +          Dominator = BB;
> > +        else
> > +          Dominator = DT->findNearestCommonDominator(Dominator, BB);
> > +      }
> > +    }
> > +
> > +    // Change the dominator (if requested)
> > +    if (Dominator)
> > +      DT->changeImmediateDominator(NewExit, Dominator);
> > +
> > +    // Update the region info
> > +    SubRegion->replaceExit(NewExit);
> > +
> > +  } else {
> > +    BasicBlock *BB = Node->getNodeAs<BasicBlock>();
> > +    killTerminator(BB);
> > +    BranchInst::Create(NewExit, BB);
> > +    addPhiValues(BB, NewExit);
> > +    if (IncludeDominator)
> > +      DT->changeImmediateDominator(NewExit, BB);
> > +  }
> > +}
> > +
> > +/// \brief Create a new flow node and update dominator tree and region info
> > +BasicBlock *StructurizeCFG::getNextFlow(BasicBlock *Dominator) {
> > +  LLVMContext &Context = Func->getContext();
> > +  BasicBlock *Insert = Order.empty() ? ParentRegion->getExit() :
> > +                       Order.back()->getEntry();
> > +  BasicBlock *Flow = BasicBlock::Create(Context, FlowBlockName,
> > +                                        Func, Insert);
> > +  DT->addNewBlock(Flow, Dominator);
> > +  ParentRegion->getRegionInfo()->setRegionFor(Flow, ParentRegion);
> > +  return Flow;
> > +}
> > +
> > +/// \brief Create a new or reuse the previous node as flow node
> > +BasicBlock *StructurizeCFG::needPrefix(bool NeedEmpty) {
> > +  BasicBlock *Entry = PrevNode->getEntry();
> > +
> > +  if (!PrevNode->isSubRegion()) {
> > +    killTerminator(Entry);
> > +    if (!NeedEmpty || Entry->getFirstInsertionPt() == Entry->end())
> > +      return Entry;
> > +
> > +  }
> > +
> > +  // create a new flow node
> > +  BasicBlock *Flow = getNextFlow(Entry);
> > +
> > +  // and wire it up
> > +  changeExit(PrevNode, Flow, true);
> > +  PrevNode = ParentRegion->getBBNode(Flow);
> > +  return Flow;
> > +}
> > +
> > +/// \brief Returns the region exit if possible, otherwise just a new flow node
> > +BasicBlock *StructurizeCFG::needPostfix(BasicBlock *Flow,
> > +                                        bool ExitUseAllowed) {
> > +  if (Order.empty() && ExitUseAllowed) {
> > +    BasicBlock *Exit = ParentRegion->getExit();
> > +    DT->changeImmediateDominator(Exit, Flow);
> > +    addPhiValues(Flow, Exit);
> > +    return Exit;
> > +  }
> > +  return getNextFlow(Flow);
> > +}
> > +
> > +/// \brief Set the previous node
> > +void StructurizeCFG::setPrevNode(BasicBlock *BB) {
> > +  PrevNode =  ParentRegion->contains(BB) ? ParentRegion->getBBNode(BB) : 0;
> > +}
> > +
> > +/// \brief Does BB dominate all the predicates of Node ?
> > +bool StructurizeCFG::dominatesPredicates(BasicBlock *BB, RegionNode *Node) {
> > +  BBPredicates &Preds = Predicates[Node->getEntry()];
> > +  for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end();
> > +       PI != PE; ++PI) {
> > +
> > +    if (!DT->dominates(BB, PI->first))
> > +      return false;
> > +  }
> > +  return true;
> > +}
> > +
> > +/// \brief Can we predict that this node will always be called?
> > +bool StructurizeCFG::isPredictableTrue(RegionNode *Node) {
> > +  BBPredicates &Preds = Predicates[Node->getEntry()];
> > +  bool Dominated = false;
> > +
> > +  // Regionentry is always true
> > +  if (PrevNode == 0)
> > +    return true;
> > +
> > +  for (BBPredicates::iterator I = Preds.begin(), E = Preds.end();
> > +       I != E; ++I) {
> > +
> > +    if (I->second != BoolTrue)
> > +      return false;
> > +
> > +    if (!Dominated && DT->dominates(I->first, PrevNode->getEntry()))
> > +      Dominated = true;
> > +  }
> > +
> > +  // TODO: The dominator check is too strict
> > +  return Dominated;
> > +}
> > +
> > +/// Take one node from the order vector and wire it up
> > +void StructurizeCFG::wireFlow(bool ExitUseAllowed,
> > +                              BasicBlock *LoopEnd) {
> > +  RegionNode *Node = Order.pop_back_val();
> > +  Visited.insert(Node->getEntry());
> > +
> > +  if (isPredictableTrue(Node)) {
> > +    // Just a linear flow
> > +    if (PrevNode) {
> > +      changeExit(PrevNode, Node->getEntry(), true);
> > +    }
> > +    PrevNode = Node;
> > +
> > +  } else {
> > +    // Insert extra prefix node (or reuse last one)
> > +    BasicBlock *Flow = needPrefix(false);
> > +
> > +    // Insert extra postfix node (or use exit instead)
> > +    BasicBlock *Entry = Node->getEntry();
> > +    BasicBlock *Next = needPostfix(Flow, ExitUseAllowed);
> > +
> > +    // let it point to entry and next block
> > +    Conditions.push_back(BranchInst::Create(Entry, Next, BoolUndef, Flow));
> > +    addPhiValues(Flow, Entry);
> > +    DT->changeImmediateDominator(Entry, Flow);
> > +
> > +    PrevNode = Node;
> > +    while (!Order.empty() && !Visited.count(LoopEnd) &&
> > +           dominatesPredicates(Entry, Order.back())) {
> > +      handleLoops(false, LoopEnd);
> > +    }
> > +
> > +    changeExit(PrevNode, Next, false);
> > +    setPrevNode(Next);
> > +  }
> > +}
> > +
> > +void StructurizeCFG::handleLoops(bool ExitUseAllowed,
> > +                                 BasicBlock *LoopEnd) {
> > +  RegionNode *Node = Order.back();
> > +  BasicBlock *LoopStart = Node->getEntry();
> > +
> > +  if (!Loops.count(LoopStart)) {
> > +    wireFlow(ExitUseAllowed, LoopEnd);
> > +    return;
> > +  }
> > +
> > +  if (!isPredictableTrue(Node))
> > +    LoopStart = needPrefix(true);
> > +
> > +  LoopEnd = Loops[Node->getEntry()];
> > +  wireFlow(false, LoopEnd);
> > +  while (!Visited.count(LoopEnd)) {
> > +    handleLoops(false, LoopEnd);
> > +  }
> > +
> > +  // Create an extra loop end node
> > +  LoopEnd = needPrefix(false);
> > +  BasicBlock *Next = needPostfix(LoopEnd, ExitUseAllowed);
> > +  LoopConds.push_back(BranchInst::Create(Next, LoopStart,
> > +                                         BoolUndef, LoopEnd));
> > +  addPhiValues(LoopEnd, LoopStart);
> > +  setPrevNode(Next);
> > +}
> > +
> > +/// After this function control flow looks like it should be, but
> > +/// branches and PHI nodes only have undefined conditions.
> > +void StructurizeCFG::createFlow() {
> > +  BasicBlock *Exit = ParentRegion->getExit();
> > +  bool EntryDominatesExit = DT->dominates(ParentRegion->getEntry(), Exit);
> > +
> > +  DeletedPhis.clear();
> > +  AddedPhis.clear();
> > +  Conditions.clear();
> > +  LoopConds.clear();
> > +
> > +  PrevNode = 0;
> > +  Visited.clear();
> > +
> > +  while (!Order.empty()) {
> > +    handleLoops(EntryDominatesExit, 0);
> > +  }
> > +
> > +  if (PrevNode)
> > +    changeExit(PrevNode, Exit, EntryDominatesExit);
> > +  else
> > +    assert(EntryDominatesExit);
> > +}
> > +
> > +/// Handle a rare case where the disintegrated nodes instructions
> > +/// no longer dominate all their uses. Not sure if this is really nessasary
> > +void StructurizeCFG::rebuildSSA() {
> > +  SSAUpdater Updater;
> > +  for (Region::block_iterator I = ParentRegion->block_begin(),
> > +                              E = ParentRegion->block_end();
> > +       I != E; ++I) {
> > +
> > +    BasicBlock *BB = *I;
> > +    for (BasicBlock::iterator II = BB->begin(), IE = BB->end();
> > +         II != IE; ++II) {
> > +
> > +      bool Initialized = false;
> > +      for (Use *I = &II->use_begin().getUse(), *Next; I; I = Next) {
> > +
> > +        Next = I->getNext();
> > +
> > +        Instruction *User = cast<Instruction>(I->getUser());
> > +        if (User->getParent() == BB) {
> > +          continue;
> > +
> > +        } else if (PHINode *UserPN = dyn_cast<PHINode>(User)) {
> > +          if (UserPN->getIncomingBlock(*I) == BB)
> > +            continue;
> > +        }
> > +
> > +        if (DT->dominates(II, User))
> > +          continue;
> > +
> > +        if (!Initialized) {
> > +          Value *Undef = UndefValue::get(II->getType());
> > +          Updater.Initialize(II->getType(), "");
> > +          Updater.AddAvailableValue(&Func->getEntryBlock(), Undef);
> > +          Updater.AddAvailableValue(BB, II);
> > +          Initialized = true;
> > +        }
> > +        Updater.RewriteUseAfterInsertions(*I);
> > +      }
> > +    }
> > +  }
> > +}
> > +
> > +/// \brief Run the transformation for each region found
> > +bool StructurizeCFG::runOnRegion(Region *R, RGPassManager &RGM) {
> > +  if (R->isTopLevelRegion())
> > +    return false;
> > +
> > +  Func = R->getEntry()->getParent();
> > +  ParentRegion = R;
> > +
> > +  DT = &getAnalysis<DominatorTree>();
> > +
> > +  orderNodes();
> > +  collectInfos();
> > +  createFlow();
> > +  insertConditions(false);
> > +  insertConditions(true);
> > +  setPhiValues();
> > +  rebuildSSA();
> > +
> > +  // Cleanup
> > +  Order.clear();
> > +  Visited.clear();
> > +  DeletedPhis.clear();
> > +  AddedPhis.clear();
> > +  Predicates.clear();
> > +  Conditions.clear();
> > +  Loops.clear();
> > +  LoopPreds.clear();
> > +  LoopConds.clear();
> > +
> > +  return true;
> > +}
> > +
> > +/// \brief Create the pass
> > +Pass *llvm::createStructurizeCFGPass() {
> > +  return new StructurizeCFG();
> > +}
> 
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
-------------- next part --------------

;
; void loop(int *out, int cond_a, int cond_b) {
;
;   unsigned i;
;   for (i = 0; i < cond_a; i++) {
;     out[i] = i;
;     if (i > cond_b) {
;       break;
;     }
;     out[i + cond_a] = i;
;   }
; }

define void @loop(i32 addrspace(1)* %out, i32 %cond_a, i32 %cond_b) nounwind uwtable {
entry:
  br label %for.cond

for.cond:                                         ; preds = %for.inc, %entry
  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
  %cmp = icmp ult i32 %i.0, %cond_a
  br i1 %cmp, label %for.body, label %for.end

; CHECK: for.body:
for.body:                                         ; preds = %for.cond
  %arrayidx = getelementptr inbounds i32 addrspace(1)* %out, i32 %i.0
  store i32 %i.0, i32 addrspace(1)* %arrayidx, align 4
  %cmp1 = icmp ugt i32 %i.0, %cond_b
; CHECK: br i1 %{{[0-9a-zA-Z_]+}}, label %for.inc, label %[[FLOW1:[0-9a-zA-Z_]+]]
  br i1 %cmp1, label %if.then, label %if.end

; CHECK: [[FLOW:[0-9a-zA-Z]+]]:
; CHECK: br i1 %{{[0-9a-zA-Z_]+}}, label %for.end, label %for.cond

if.then:                                          ; preds = %for.body
  br label %for.end

if.end:                                           ; preds = %for.body
  %add = add i32 %i.0, %cond_a
  %arrayidx3 = getelementptr inbounds i32 addrspace(1)* %out, i32 %add
  store i32 %i.0, i32 addrspace(1)* %arrayidx3, align 4
  br label %for.inc

; CHECK: for.inc:
for.inc:                                          ; preds = %if.end
  %inc = add i32 %i.0, 1
; CHECK: br label %[[FLOW1]]
  br label %for.cond

; CHECK: [[FLOW1]]
; CHECK: br label %[[FLOW]]

for.end:                                          ; preds = %if.then, %for.cond
  ret void
}


More information about the llvm-commits mailing list