[llvm] r213456 - Templatify RegionInfo so it works on MachineBasicBlocks

Matt Arsenault Matthew.Arsenault at amd.com
Sat Jul 19 11:29:30 PDT 2014


Author: arsenm
Date: Sat Jul 19 13:29:29 2014
New Revision: 213456

URL: http://llvm.org/viewvc/llvm-project?rev=213456&view=rev
Log:
Templatify RegionInfo so it works on MachineBasicBlocks

Added:
    llvm/trunk/include/llvm/Analysis/RegionInfoImpl.h
    llvm/trunk/include/llvm/CodeGen/MachineRegionInfo.h
    llvm/trunk/lib/CodeGen/MachineRegionInfo.cpp
Modified:
    llvm/trunk/include/llvm/Analysis/RegionInfo.h
    llvm/trunk/include/llvm/Analysis/RegionIterator.h
    llvm/trunk/include/llvm/InitializePasses.h
    llvm/trunk/lib/Analysis/Analysis.cpp
    llvm/trunk/lib/Analysis/RegionInfo.cpp
    llvm/trunk/lib/Analysis/RegionPass.cpp
    llvm/trunk/lib/Analysis/RegionPrinter.cpp
    llvm/trunk/lib/CodeGen/CMakeLists.txt
    llvm/trunk/lib/Transforms/Scalar/StructurizeCFG.cpp

Modified: llvm/trunk/include/llvm/Analysis/RegionInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/RegionInfo.h?rev=213456&r1=213455&r2=213456&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/RegionInfo.h (original)
+++ llvm/trunk/include/llvm/Analysis/RegionInfo.h Sat Jul 19 13:29:29 2014
@@ -37,21 +37,62 @@
 #ifndef LLVM_ANALYSIS_REGIONINFO_H
 #define LLVM_ANALYSIS_REGIONINFO_H
 
+#include "llvm/ADT/DepthFirstIterator.h"
 #include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Analysis/DominanceFrontier.h"
-#include "llvm/Analysis/PostDominators.h"
-#include "llvm/Support/Allocator.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Dominators.h"
 #include <map>
 #include <memory>
+#include <set>
 
 namespace llvm {
 
-class Region;
-class RegionInfo;
-class raw_ostream;
+// RegionTraits - Class to be specialized for different users of RegionInfo
+// (i.e. BasicBlocks or MachineBasicBlocks). This is only to avoid needing to
+// pass around an unreasonable number of template parameters.
+template <class FuncT_>
+struct RegionTraits {
+  // FuncT
+  // BlockT
+  // RegionT
+  // RegionNodeT
+  // RegionInfoT
+  typedef typename FuncT_::UnknownRegionTypeError BrokenT;
+};
+
+class DominatorTree;
+class DominanceFrontier;
 class Loop;
 class LoopInfo;
+struct PostDominatorTree;
+class raw_ostream;
+class Region;
+template <class RegionTr>
+class RegionBase;
+class RegionNode;
+class RegionInfo;
+template <class RegionTr>
+class RegionInfoBase;
+
+template <>
+struct RegionTraits<Function> {
+  typedef Function FuncT;
+  typedef BasicBlock BlockT;
+  typedef Region RegionT;
+  typedef RegionNode RegionNodeT;
+  typedef RegionInfo RegionInfoT;
+  typedef DominatorTree DomTreeT;
+  typedef DomTreeNode DomTreeNodeT;
+  typedef DominanceFrontier DomFrontierT;
+  typedef PostDominatorTree PostDomTreeT;
+  typedef Instruction InstT;
+  typedef Loop LoopT;
+  typedef LoopInfo LoopInfoT;
+
+  static unsigned getNumSuccessors(BasicBlock *BB) {
+    return BB->getTerminator()->getNumSuccessors();
+  }
+};
 
 /// @brief Marker class to iterate over the elements of a Region in flat mode.
 ///
@@ -65,11 +106,18 @@ class FlatIt {};
 
 /// @brief A RegionNode represents a subregion or a BasicBlock that is part of a
 /// Region.
-class RegionNode {
-  RegionNode(const RegionNode &) LLVM_DELETED_FUNCTION;
-  const RegionNode &operator=(const RegionNode &) LLVM_DELETED_FUNCTION;
+template <class Tr>
+class RegionNodeBase {
+  friend class RegionBase<Tr>;
+
+public:
+  typedef typename Tr::BlockT BlockT;
+  typedef typename Tr::RegionT RegionT;
+
+private:
+  RegionNodeBase(const RegionNodeBase &) LLVM_DELETED_FUNCTION;
+  const RegionNodeBase &operator=(const RegionNodeBase &) LLVM_DELETED_FUNCTION;
 
-protected:
   /// This is the entry basic block that starts this region node.  If this is a
   /// BasicBlock RegionNode, then entry is just the basic block, that this
   /// RegionNode represents.  Otherwise it is the entry of this (Sub)RegionNode.
@@ -80,13 +128,13 @@ protected:
   /// The node can hold either a Region or a BasicBlock.
   /// Use one bit to save, if this RegionNode is a subregion or BasicBlock
   /// RegionNode.
-  PointerIntPair<BasicBlock*, 1, bool> entry;
+  PointerIntPair<BlockT *, 1, bool> entry;
 
   /// @brief The parent Region of this RegionNode.
   /// @see getParent()
-  Region* parent;
+  RegionT *parent;
 
-public:
+protected:
   /// @brief Create a RegionNode.
   ///
   /// @param Parent      The parent of this RegionNode.
@@ -95,9 +143,11 @@ public:
   ///                    BasicBlock itself.  If it represents a subregion, this
   ///                    is the entry BasicBlock of the subregion.
   /// @param isSubRegion If this RegionNode represents a SubRegion.
-  inline RegionNode(Region* Parent, BasicBlock* Entry, bool isSubRegion = 0)
-    : entry(Entry, isSubRegion), parent(Parent) {}
+  inline RegionNodeBase(RegionT *Parent, BlockT *Entry,
+                        bool isSubRegion = false)
+      : entry(Entry, isSubRegion), parent(Parent) {}
 
+public:
   /// @brief Get the parent Region of this RegionNode.
   ///
   /// The parent Region is the Region this RegionNode belongs to. If for
@@ -106,7 +156,7 @@ public:
   /// pointing to the Region this RegionNode belongs to.
   ///
   /// @return Get the parent Region of this RegionNode.
-  inline Region* getParent() const { return parent; }
+  inline RegionT *getParent() const { return parent; }
 
   /// @brief Get the entry BasicBlock of this RegionNode.
   ///
@@ -114,7 +164,7 @@ public:
   /// itself, otherwise we return the entry BasicBlock of the Subregion
   ///
   /// @return The entry BasicBlock of this RegionNode.
-  inline BasicBlock* getEntry() const { return entry.getPointer(); }
+  inline BlockT *getEntry() const { return entry.getPointer(); }
 
   /// @brief Get the content of this RegionNode.
   ///
@@ -122,33 +172,15 @@ public:
   /// check the type of the content with the isSubRegion() function call.
   ///
   /// @return The content of this RegionNode.
-  template<class T>
-  inline T* getNodeAs() const;
+  template <class T> inline T *getNodeAs() const;
 
   /// @brief Is this RegionNode a subregion?
   ///
   /// @return True if it contains a subregion. False if it contains a
   ///         BasicBlock.
-  inline bool isSubRegion() const {
-    return entry.getInt();
-  }
+  inline bool isSubRegion() const { return entry.getInt(); }
 };
 
-/// Print a RegionNode.
-inline raw_ostream &operator<<(raw_ostream &OS, const RegionNode &Node);
-
-template<>
-inline BasicBlock* RegionNode::getNodeAs<BasicBlock>() const {
-  assert(!isSubRegion() && "This is not a BasicBlock RegionNode!");
-  return getEntry();
-}
-
-template<>
-inline Region* RegionNode::getNodeAs<Region>() const {
-  assert(isSubRegion() && "This is not a subregion RegionNode!");
-  return reinterpret_cast<Region*>(const_cast<RegionNode*>(this));
-}
-
 //===----------------------------------------------------------------------===//
 /// @brief A single entry single exit Region.
 ///
@@ -211,37 +243,53 @@ inline Region* RegionNode::getNodeAs<Reg
 ///
 /// The first call returns a textual representation of the program structure
 /// tree, the second one creates a graphical representation using graphviz.
-class Region : public RegionNode {
-  friend class RegionInfo;
-  Region(const Region &) LLVM_DELETED_FUNCTION;
-  const Region &operator=(const Region &) LLVM_DELETED_FUNCTION;
+template <class Tr>
+class RegionBase : public RegionNodeBase<Tr> {
+  typedef typename Tr::FuncT FuncT;
+  typedef typename Tr::BlockT BlockT;
+  typedef typename Tr::RegionInfoT RegionInfoT;
+  typedef typename Tr::RegionT RegionT;
+  typedef typename Tr::RegionNodeT RegionNodeT;
+  typedef typename Tr::DomTreeT DomTreeT;
+  typedef typename Tr::LoopT LoopT;
+  typedef typename Tr::LoopInfoT LoopInfoT;
+  typedef typename Tr::InstT InstT;
+
+  typedef GraphTraits<BlockT *> BlockTraits;
+  typedef GraphTraits<Inverse<BlockT *>> InvBlockTraits;
+  typedef typename BlockTraits::ChildIteratorType SuccIterTy;
+  typedef typename InvBlockTraits::ChildIteratorType PredIterTy;
+
+  friend class RegionInfoBase<Tr>;
+  RegionBase(const RegionBase &) LLVM_DELETED_FUNCTION;
+  const RegionBase &operator=(const RegionBase &) LLVM_DELETED_FUNCTION;
 
   // Information necessary to manage this Region.
-  RegionInfo* RI;
-  DominatorTree *DT;
+  RegionInfoT *RI;
+  DomTreeT *DT;
 
   // The exit BasicBlock of this region.
   // (The entry BasicBlock is part of RegionNode)
-  BasicBlock *exit;
+  BlockT *exit;
 
-  typedef std::vector<std::unique_ptr<Region>> RegionSet;
+  typedef std::vector<std::unique_ptr<RegionT>> RegionSet;
 
   // The subregions of this region.
   RegionSet children;
 
-  typedef std::map<BasicBlock*, RegionNode*> BBNodeMapT;
+  typedef std::map<BlockT *, RegionNodeT *> BBNodeMapT;
 
   // Save the BasicBlock RegionNodes that are element of this Region.
   mutable BBNodeMapT BBNodeMap;
 
   /// verifyBBInRegion - Check if a BB is in this Region. This check also works
   /// if the region is incorrectly built. (EXPENSIVE!)
-  void verifyBBInRegion(BasicBlock* BB) const;
+  void verifyBBInRegion(BlockT *BB) const;
 
   /// verifyWalk - Walk over all the BBs of the region starting from BB and
   /// verify that all reachable basic blocks are elements of the region.
   /// (EXPENSIVE!)
-  void verifyWalk(BasicBlock* BB, std::set<BasicBlock*>* visitedBB) const;
+  void verifyWalk(BlockT *BB, std::set<BlockT *> *visitedBB) const;
 
   /// verifyRegionNest - Verify if the region and its children are valid
   /// regions (EXPENSIVE!)
@@ -256,27 +304,27 @@ public:
   /// @param DT     The dominator tree of the current function.
   /// @param Parent The surrounding region or NULL if this is a top level
   ///               region.
-  Region(BasicBlock *Entry, BasicBlock *Exit, RegionInfo* RI,
-         DominatorTree *DT, Region *Parent = nullptr);
+  RegionBase(BlockT *Entry, BlockT *Exit, RegionInfoT *RI, DomTreeT *DT,
+             RegionT *Parent = nullptr);
 
   /// Delete the Region and all its subregions.
-  ~Region();
+  ~RegionBase();
 
   /// @brief Get the entry BasicBlock of the Region.
   /// @return The entry BasicBlock of the region.
-  BasicBlock *getEntry() const { return RegionNode::getEntry(); }
+  BlockT *getEntry() const { return RegionNodeT::getEntry(); }
 
   /// @brief Replace the entry basic block of the region with the new basic
   ///        block.
   ///
   /// @param BB  The new entry basic block of the region.
-  void replaceEntry(BasicBlock *BB);
+  void replaceEntry(BlockT *BB);
 
   /// @brief Replace the exit basic block of the region with the new basic
   ///        block.
   ///
   /// @param BB  The new exit basic block of the region.
-  void replaceExit(BasicBlock *BB);
+  void replaceExit(BlockT *BB);
 
   /// @brief Recursively replace the entry basic block of the region.
   ///
@@ -285,7 +333,7 @@ public:
   /// this region.
   ///
   /// @param NewEntry The new entry basic block.
-  void replaceEntryRecursive(BasicBlock *NewEntry);
+  void replaceEntryRecursive(BlockT *NewEntry);
 
   /// @brief Recursively replace the exit basic block of the region.
   ///
@@ -294,22 +342,23 @@ public:
   /// this region.
   ///
   /// @param NewExit The new exit basic block.
-  void replaceExitRecursive(BasicBlock *NewExit);
+  void replaceExitRecursive(BlockT *NewExit);
 
   /// @brief Get the exit BasicBlock of the Region.
   /// @return The exit BasicBlock of the Region, NULL if this is the TopLevel
   ///         Region.
-  BasicBlock *getExit() const { return exit; }
+  BlockT *getExit() const { return exit; }
 
   /// @brief Get the parent of the Region.
   /// @return The parent of the Region or NULL if this is a top level
   ///         Region.
-  Region *getParent() const { return RegionNode::getParent(); }
+  RegionT *getParent() const { return RegionNodeT::getParent(); }
 
   /// @brief Get the RegionNode representing the current Region.
   /// @return The RegionNode representing the current Region.
-  RegionNode* getNode() const {
-    return const_cast<RegionNode*>(reinterpret_cast<const RegionNode*>(this));
+  RegionNodeT *getNode() const {
+    return const_cast<RegionNodeT *>(
+        reinterpret_cast<const RegionNodeT *>(this));
   }
 
   /// @brief Get the nesting level of this Region.
@@ -330,21 +379,21 @@ public:
   /// @return A region also starting at getEntry(), but reaching to the next
   ///         basic block that forms with getEntry() a (non-canonical) region.
   ///         NULL if such a basic block does not exist.
-  Region *getExpandedRegion() const;
+  RegionT *getExpandedRegion() const;
 
   /// @brief Return the first block of this region's single entry edge,
   ///        if existing.
   ///
   /// @return The BasicBlock starting this region's single entry edge,
   ///         else NULL.
-  BasicBlock *getEnteringBlock() const;
+  BlockT *getEnteringBlock() const;
 
   /// @brief Return the first block of this region's single exit edge,
   ///        if existing.
   ///
   /// @return The BasicBlock starting this region's single exit edge,
   ///         else NULL.
-  BasicBlock *getExitingBlock() const;
+  BlockT *getExitingBlock() const;
 
   /// @brief Is this a simple region?
   ///
@@ -358,20 +407,18 @@ public:
   std::string getNameStr() const;
 
   /// @brief Return the RegionInfo object, that belongs to this Region.
-  RegionInfo *getRegionInfo() const {
-    return RI;
-  }
+  RegionInfoT *getRegionInfo() const { return RI; }
 
   /// PrintStyle - Print region in difference ways.
-  enum PrintStyle { PrintNone, PrintBB, PrintRN  };
+  enum PrintStyle { PrintNone, PrintBB, PrintRN };
 
   /// @brief Print the region.
   ///
   /// @param OS The output stream the Region is printed to.
   /// @param printTree Print also the tree of subregions.
   /// @param level The indentation level used for printing.
-  void print(raw_ostream& OS, bool printTree = true, unsigned level = 0,
-             enum PrintStyle Style = PrintNone) const;
+  void print(raw_ostream &OS, bool printTree = true, unsigned level = 0,
+             PrintStyle Style = PrintNone) const;
 
   /// @brief Print the region to stderr.
   void dump() const;
@@ -380,28 +427,28 @@ public:
   ///
   /// @param BB The BasicBlock that might be contained in this Region.
   /// @return True if the block is contained in the region otherwise false.
-  bool contains(const BasicBlock *BB) const;
+  bool contains(const BlockT *BB) const;
 
   /// @brief Check if the region contains another region.
   ///
   /// @param SubRegion The region that might be contained in this Region.
   /// @return True if SubRegion is contained in the region otherwise false.
-  bool contains(const Region *SubRegion) const {
+  bool contains(const RegionT *SubRegion) const {
     // Toplevel Region.
     if (!getExit())
       return true;
 
-    return contains(SubRegion->getEntry())
-      && (contains(SubRegion->getExit()) || SubRegion->getExit() == getExit());
+    return contains(SubRegion->getEntry()) &&
+           (contains(SubRegion->getExit()) ||
+            SubRegion->getExit() == getExit());
   }
 
   /// @brief Check if the region contains an Instruction.
   ///
   /// @param Inst The Instruction that might be contained in this region.
-  /// @return True if the Instruction is contained in the region otherwise false.
-  bool contains(const Instruction *Inst) const {
-    return contains(Inst->getParent());
-  }
+  /// @return True if the Instruction is contained in the region otherwise
+  /// false.
+  bool contains(const InstT *Inst) const { return contains(Inst->getParent()); }
 
   /// @brief Check if the region contains a loop.
   ///
@@ -410,7 +457,7 @@ public:
   ///         In case a NULL pointer is passed to this function the result
   ///         is false, except for the region that describes the whole function.
   ///         In that case true is returned.
-  bool contains(const Loop *L) const;
+  bool contains(const LoopT *L) const;
 
   /// @brief Get the outermost loop in the region that contains a loop.
   ///
@@ -420,7 +467,7 @@ public:
   /// @param L The loop the lookup is started.
   /// @return The outermost loop in the region, NULL if such a loop does not
   ///         exist or if the region describes the whole function.
-  Loop *outermostLoopInRegion(Loop *L) const;
+  LoopT *outermostLoopInRegion(LoopT *L) const;
 
   /// @brief Get the outermost loop in the region that contains a basic block.
   ///
@@ -431,13 +478,13 @@ public:
   /// @param BB The basic block surrounded by the loop.
   /// @return The outermost loop in the region, NULL if such a loop does not
   ///         exist or if the region describes the whole function.
-  Loop *outermostLoopInRegion(LoopInfo *LI, BasicBlock* BB) const;
+  LoopT *outermostLoopInRegion(LoopInfoT *LI, BlockT *BB) const;
 
   /// @brief Get the subregion that starts at a BasicBlock
   ///
   /// @param BB The BasicBlock the subregion should start.
   /// @return The Subregion if available, otherwise NULL.
-  Region* getSubRegionNode(BasicBlock *BB) const;
+  RegionT *getSubRegionNode(BlockT *BB) const;
 
   /// @brief Get the RegionNode for a BasicBlock
   ///
@@ -445,32 +492,32 @@ public:
   /// @return If available, the RegionNode that represents the subregion
   ///         starting at BB. If no subregion starts at BB, the RegionNode
   ///         representing BB.
-  RegionNode* getNode(BasicBlock *BB) const;
+  RegionNodeT *getNode(BlockT *BB) const;
 
   /// @brief Get the BasicBlock RegionNode for a BasicBlock
   ///
   /// @param BB The BasicBlock for which the RegionNode is requested.
   /// @return The RegionNode representing the BB.
-  RegionNode* getBBNode(BasicBlock *BB) const;
+  RegionNodeT *getBBNode(BlockT *BB) const;
 
   /// @brief Add a new subregion to this Region.
   ///
   /// @param SubRegion The new subregion that will be added.
   /// @param moveChildren Move the children of this region, that are also
   ///                     contained in SubRegion into SubRegion.
-  void addSubRegion(Region *SubRegion, bool moveChildren = false);
+  void addSubRegion(RegionT *SubRegion, bool moveChildren = false);
 
   /// @brief Remove a subregion from this Region.
   ///
   /// The subregion is not deleted, as it will probably be inserted into another
   /// region.
   /// @param SubRegion The SubRegion that will be removed.
-  Region *removeSubRegion(Region *SubRegion);
+  RegionT *removeSubRegion(RegionT *SubRegion);
 
   /// @brief Move all direct child nodes of this Region to another Region.
   ///
   /// @param To The Region the child nodes will be transferred to.
-  void transferChildrenTo(Region *To);
+  void transferChildrenTo(RegionT *To);
 
   /// @brief Verify if the region is a correct region.
   ///
@@ -489,8 +536,8 @@ public:
   ///
   /// These iterators iterator over all subregions of this Region.
   //@{
-  typedef RegionSet::iterator iterator;
-  typedef RegionSet::const_iterator const_iterator;
+  typedef typename RegionSet::iterator iterator;
+  typedef typename RegionSet::const_iterator const_iterator;
 
   iterator begin() { return children.begin(); }
   iterator end() { return children.end(); }
@@ -507,18 +554,18 @@ public:
   //@{
   template <bool IsConst>
   class block_iterator_wrapper
-      : public df_iterator<typename std::conditional<IsConst, const BasicBlock,
-                                                     BasicBlock>::type *> {
-    typedef df_iterator<typename std::conditional<IsConst, const BasicBlock,
-                                                  BasicBlock>::type *> super;
+      : public df_iterator<
+            typename std::conditional<IsConst, const BlockT, BlockT>::type *> {
+    typedef df_iterator<
+        typename std::conditional<IsConst, const BlockT, BlockT>::type *> super;
 
   public:
     typedef block_iterator_wrapper<IsConst> Self;
     typedef typename super::pointer pointer;
 
     // Construct the begin iterator.
-    block_iterator_wrapper(pointer Entry, pointer Exit) : super(df_begin(Entry))
-    {
+    block_iterator_wrapper(pointer Entry, pointer Exit)
+        : super(df_begin(Entry)) {
       // Mark the exit of the region as visited, so that the children of the
       // exit and the exit itself, i.e. the block outside the region will never
       // be visited.
@@ -526,35 +573,29 @@ public:
     }
 
     // Construct the end iterator.
-    block_iterator_wrapper() : super(df_end<pointer>((BasicBlock *)nullptr)) {}
+    block_iterator_wrapper() : super(df_end<pointer>((BlockT *)nullptr)) {}
 
     /*implicit*/ block_iterator_wrapper(super I) : super(I) {}
 
     // FIXME: Even a const_iterator returns a non-const BasicBlock pointer.
     //        This was introduced for backwards compatibility, but should
     //        be removed as soon as all users are fixed.
-    BasicBlock *operator*() const {
-      return const_cast<BasicBlock*>(super::operator*());
+    BlockT *operator*() const {
+      return const_cast<BlockT *>(super::operator*());
     }
   };
 
   typedef block_iterator_wrapper<false> block_iterator;
-  typedef block_iterator_wrapper<true>  const_block_iterator;
+  typedef block_iterator_wrapper<true> const_block_iterator;
 
-  block_iterator block_begin() {
-   return block_iterator(getEntry(), getExit());
-  }
+  block_iterator block_begin() { return block_iterator(getEntry(), getExit()); }
 
-  block_iterator block_end() {
-   return block_iterator();
-  }
+  block_iterator block_end() { return block_iterator(); }
 
   const_block_iterator block_begin() const {
     return const_block_iterator(getEntry(), getExit());
   }
-  const_block_iterator block_end() const {
-    return const_block_iterator();
-  }
+  const_block_iterator block_end() const { return const_block_iterator(); }
 
   typedef iterator_range<block_iterator> block_range;
   typedef iterator_range<const_block_iterator> const_block_range;
@@ -578,12 +619,12 @@ public:
   /// are direct children of this Region. It does not iterate over any
   /// RegionNodes that are also element of a subregion of this Region.
   //@{
-  typedef df_iterator<RegionNode*, SmallPtrSet<RegionNode*, 8>, false,
-                      GraphTraits<RegionNode*> > element_iterator;
+  typedef df_iterator<RegionNodeT *, SmallPtrSet<RegionNodeT *, 8>, false,
+                      GraphTraits<RegionNodeT *>> element_iterator;
 
-  typedef df_iterator<const RegionNode*, SmallPtrSet<const RegionNode*, 8>,
-                      false, GraphTraits<const RegionNode*> >
-            const_element_iterator;
+  typedef df_iterator<const RegionNodeT *, SmallPtrSet<const RegionNodeT *, 8>,
+                      false,
+                      GraphTraits<const RegionNodeT *>> const_element_iterator;
 
   element_iterator element_begin();
   element_iterator element_end();
@@ -593,132 +634,147 @@ public:
   //@}
 };
 
+/// Print a RegionNode.
+template <class Tr>
+inline raw_ostream &operator<<(raw_ostream &OS, const RegionNodeBase<Tr> &Node);
+
 //===----------------------------------------------------------------------===//
 /// @brief Analysis that detects all canonical Regions.
 ///
 /// The RegionInfo pass detects all canonical regions in a function. The Regions
 /// are connected using the parent relation. This builds a Program Structure
 /// Tree.
-class RegionInfo : public FunctionPass {
-  typedef DenseMap<BasicBlock*,BasicBlock*> BBtoBBMap;
-  typedef DenseMap<BasicBlock*, Region*> BBtoRegionMap;
-  typedef SmallPtrSet<Region*, 4> RegionSet;
-
-  RegionInfo(const RegionInfo &) LLVM_DELETED_FUNCTION;
-  const RegionInfo &operator=(const RegionInfo &) LLVM_DELETED_FUNCTION;
-
-  DominatorTree *DT;
-  PostDominatorTree *PDT;
-  DominanceFrontier *DF;
+template <class Tr>
+class RegionInfoBase {
+  typedef typename Tr::BlockT BlockT;
+  typedef typename Tr::FuncT FuncT;
+  typedef typename Tr::RegionT RegionT;
+  typedef typename Tr::RegionInfoT RegionInfoT;
+  typedef typename Tr::DomTreeT DomTreeT;
+  typedef typename Tr::DomTreeNodeT DomTreeNodeT;
+  typedef typename Tr::PostDomTreeT PostDomTreeT;
+  typedef typename Tr::DomFrontierT DomFrontierT;
+  typedef GraphTraits<BlockT *> BlockTraits;
+  typedef GraphTraits<Inverse<BlockT *>> InvBlockTraits;
+  typedef typename BlockTraits::ChildIteratorType SuccIterTy;
+  typedef typename InvBlockTraits::ChildIteratorType PredIterTy;
+
+  friend class RegionInfo;
+  friend class MachineRegionInfo;
+  typedef DenseMap<BlockT *, BlockT *> BBtoBBMap;
+  typedef DenseMap<BlockT *, RegionT *> BBtoRegionMap;
+  typedef SmallPtrSet<RegionT *, 4> RegionSet;
+
+  RegionInfoBase();
+  ~RegionInfoBase();
+
+  RegionInfoBase(const RegionInfoBase &) LLVM_DELETED_FUNCTION;
+  const RegionInfoBase &operator=(const RegionInfoBase &) LLVM_DELETED_FUNCTION;
+
+  DomTreeT *DT;
+  PostDomTreeT *PDT;
+  DomFrontierT *DF;
 
   /// The top level region.
-  Region *TopLevelRegion;
+  RegionT *TopLevelRegion;
 
+private:
   /// Map every BB to the smallest region, that contains BB.
   BBtoRegionMap BBtoRegion;
 
   // isCommonDomFrontier - Returns true if BB is in the dominance frontier of
   // entry, because it was inherited from exit. In the other case there is an
   // edge going from entry to BB without passing exit.
-  bool isCommonDomFrontier(BasicBlock* BB, BasicBlock* entry,
-                           BasicBlock* exit) const;
+  bool isCommonDomFrontier(BlockT *BB, BlockT *entry, BlockT *exit) const;
 
   // isRegion - Check if entry and exit surround a valid region, based on
   // dominance tree and dominance frontier.
-  bool isRegion(BasicBlock* entry, BasicBlock* exit) const;
+  bool isRegion(BlockT *entry, BlockT *exit) const;
 
   // insertShortCut - Saves a shortcut pointing from entry to exit.
   // This function may extend this shortcut if possible.
-  void insertShortCut(BasicBlock* entry, BasicBlock* exit,
-                      BBtoBBMap* ShortCut) const;
+  void insertShortCut(BlockT *entry, BlockT *exit, BBtoBBMap *ShortCut) const;
 
   // getNextPostDom - Returns the next BB that postdominates N, while skipping
   // all post dominators that cannot finish a canonical region.
-  DomTreeNode *getNextPostDom(DomTreeNode* N, BBtoBBMap *ShortCut) const;
+  DomTreeNodeT *getNextPostDom(DomTreeNodeT *N, BBtoBBMap *ShortCut) const;
 
   // isTrivialRegion - A region is trivial, if it contains only one BB.
-  bool isTrivialRegion(BasicBlock *entry, BasicBlock *exit) const;
+  bool isTrivialRegion(BlockT *entry, BlockT *exit) const;
 
   // createRegion - Creates a single entry single exit region.
-  Region *createRegion(BasicBlock *entry, BasicBlock *exit);
+  RegionT *createRegion(BlockT *entry, BlockT *exit);
 
   // findRegionsWithEntry - Detect all regions starting with bb 'entry'.
-  void findRegionsWithEntry(BasicBlock *entry, BBtoBBMap *ShortCut);
+  void findRegionsWithEntry(BlockT *entry, BBtoBBMap *ShortCut);
 
   // scanForRegions - Detects regions in F.
-  void scanForRegions(Function &F, BBtoBBMap *ShortCut);
+  void scanForRegions(FuncT &F, BBtoBBMap *ShortCut);
 
   // getTopMostParent - Get the top most parent with the same entry block.
-  Region *getTopMostParent(Region *region);
+  RegionT *getTopMostParent(RegionT *region);
 
   // buildRegionsTree - build the region hierarchy after all region detected.
-  void buildRegionsTree(DomTreeNode *N, Region *region);
-
-  // Calculate - detecte all regions in function and build the region tree.
-  void Calculate(Function& F);
-
-  void releaseMemory() override;
+  void buildRegionsTree(DomTreeNodeT *N, RegionT *region);
 
   // updateStatistics - Update statistic about created regions.
-  void updateStatistics(Region *R);
+  virtual void updateStatistics(RegionT *R) = 0;
 
   // isSimple - Check if a region is a simple region with exactly one entry
   // edge and exactly one exit edge.
-  bool isSimple(Region* R) const;
+  bool isSimple(RegionT *R) const;
+
+  // calculate - detect all regions in function and build the region tree.
+  void calculate(FuncT &F);
 
 public:
-  static char ID;
-  explicit RegionInfo();
+  static bool VerifyRegionInfo;
+  static typename RegionT::PrintStyle printStyle;
 
-  ~RegionInfo();
+  void print(raw_ostream &OS) const;
+  void dump() const;
 
-  /// @name FunctionPass interface
-  //@{
-  bool runOnFunction(Function &F) override;
-  void getAnalysisUsage(AnalysisUsage &AU) const override;
-  void print(raw_ostream &OS, const Module *) const override;
-  void verifyAnalysis() const override;
-  //@}
+  void releaseMemory();
 
   /// @brief Get the smallest region that contains a BasicBlock.
   ///
   /// @param BB The basic block.
   /// @return The smallest region, that contains BB or NULL, if there is no
   /// region containing BB.
-  Region *getRegionFor(BasicBlock *BB) const;
+  RegionT *getRegionFor(BlockT *BB) const;
 
   /// @brief  Set the smallest region that surrounds a basic block.
   ///
   /// @param BB The basic block surrounded by a region.
   /// @param R The smallest region that surrounds BB.
-  void setRegionFor(BasicBlock *BB, Region *R);
+  void setRegionFor(BlockT *BB, RegionT *R);
 
   /// @brief A shortcut for getRegionFor().
   ///
   /// @param BB The basic block.
   /// @return The smallest region, that contains BB or NULL, if there is no
   /// region containing BB.
-  Region *operator[](BasicBlock *BB) const;
+  RegionT *operator[](BlockT *BB) const;
 
   /// @brief Return the exit of the maximal refined region, that starts at a
   /// BasicBlock.
   ///
   /// @param BB The BasicBlock the refined region starts.
-  BasicBlock *getMaxRegionExit(BasicBlock *BB) const;
+  BlockT *getMaxRegionExit(BlockT *BB) const;
 
   /// @brief Find the smallest region that contains two regions.
   ///
   /// @param A The first region.
   /// @param B The second region.
   /// @return The smallest region containing A and B.
-  Region *getCommonRegion(Region* A, Region *B) const;
+  RegionT *getCommonRegion(RegionT *A, RegionT *B) const;
 
   /// @brief Find the smallest region that contains two basic blocks.
   ///
   /// @param A The first basic block.
   /// @param B The second basic block.
   /// @return The smallest region that contains A and B.
-  Region* getCommonRegion(BasicBlock* A, BasicBlock *B) const {
+  RegionT *getCommonRegion(BlockT *A, BlockT *B) const {
     return getCommonRegion(getRegionFor(A), getRegionFor(B));
   }
 
@@ -726,23 +782,21 @@ public:
   ///
   /// @param Regions A vector of regions.
   /// @return The smallest region that contains all regions in Regions.
-  Region* getCommonRegion(SmallVectorImpl<Region*> &Regions) const;
+  RegionT *getCommonRegion(SmallVectorImpl<RegionT *> &Regions) const;
 
   /// @brief Find the smallest region that contains a set of basic blocks.
   ///
   /// @param BBs A vector of basic blocks.
   /// @return The smallest region that contains all basic blocks in BBS.
-  Region* getCommonRegion(SmallVectorImpl<BasicBlock*> &BBs) const;
+  RegionT *getCommonRegion(SmallVectorImpl<BlockT *> &BBs) const;
 
-  Region *getTopLevelRegion() const {
-    return TopLevelRegion;
-  }
+  RegionT *getTopLevelRegion() const { return TopLevelRegion; }
 
   /// @brief Update RegionInfo after a basic block was split.
   ///
   /// @param NewBB The basic block that was created before OldBB.
   /// @param OldBB The old basic block.
-  void splitBlock(BasicBlock* NewBB, BasicBlock *OldBB);
+  void splitBlock(BlockT *NewBB, BlockT *OldBB);
 
   /// @brief Clear the Node Cache for all Regions.
   ///
@@ -751,14 +805,104 @@ public:
     if (TopLevelRegion)
       TopLevelRegion->clearNodeCache();
   }
+
+  void verifyAnalysis() const;
+};
+
+class Region;
+
+class RegionNode : public RegionNodeBase<RegionTraits<Function>> {
+public:
+  inline RegionNode(Region *Parent, BasicBlock *Entry, bool isSubRegion = false)
+      : RegionNodeBase<RegionTraits<Function>>(Parent, Entry, isSubRegion) {}
+
+  ~RegionNode() {}
+
+  bool operator==(const Region &RN) const {
+    return this == reinterpret_cast<const RegionNode *>(&RN);
+  }
 };
 
-inline raw_ostream &operator<<(raw_ostream &OS, const RegionNode &Node) {
+class Region : public RegionBase<RegionTraits<Function>> {
+public:
+  Region(BasicBlock *Entry, BasicBlock *Exit, RegionInfo *RI, DominatorTree *DT,
+         Region *Parent = nullptr);
+  ~Region();
+
+  bool operator==(const RegionNode &RN) const {
+    return &RN == reinterpret_cast<const RegionNode *>(this);
+  }
+};
+
+class RegionInfo : public RegionInfoBase<RegionTraits<Function>> {
+public:
+  explicit RegionInfo();
+
+  virtual ~RegionInfo();
+
+  // updateStatistics - Update statistic about created regions.
+  void updateStatistics(Region *R) final;
+
+  void recalculate(Function &F, DominatorTree *DT, PostDominatorTree *PDT,
+                   DominanceFrontier *DF);
+};
+
+class RegionInfoPass : public FunctionPass {
+  RegionInfo RI;
+
+public:
+  static char ID;
+  explicit RegionInfoPass();
+
+  ~RegionInfoPass();
+
+  RegionInfo &getRegionInfo() { return RI; }
+
+  const RegionInfo &getRegionInfo() const { return RI; }
+
+  /// @name FunctionPass interface
+  //@{
+  bool runOnFunction(Function &F) override;
+  void releaseMemory() override;
+  void verifyAnalysis() const override;
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+  void print(raw_ostream &OS, const Module *) const override;
+  void dump() const;
+  //@}
+};
+
+template <>
+template <>
+inline BasicBlock *
+RegionNodeBase<RegionTraits<Function>>::getNodeAs<BasicBlock>() const {
+  assert(!isSubRegion() && "This is not a BasicBlock RegionNode!");
+  return getEntry();
+}
+
+template <>
+template <>
+inline Region *
+RegionNodeBase<RegionTraits<Function>>::getNodeAs<Region>() const {
+  assert(isSubRegion() && "This is not a subregion RegionNode!");
+  auto Unconst = const_cast<RegionNodeBase<RegionTraits<Function>> *>(this);
+  return reinterpret_cast<Region *>(Unconst);
+}
+
+template <class Tr>
+inline raw_ostream &operator<<(raw_ostream &OS,
+                               const RegionNodeBase<Tr> &Node) {
+  typedef typename Tr::BlockT BlockT;
+  typedef typename Tr::RegionT RegionT;
+
   if (Node.isSubRegion())
-    return OS << Node.getNodeAs<Region>()->getNameStr();
+    return OS << Node.template getNodeAs<RegionT>()->getNameStr();
   else
-    return OS << Node.getNodeAs<BasicBlock>()->getName();
+    return OS << Node.template getNodeAs<BlockT>()->getName();
 }
+
+EXTERN_TEMPLATE_INSTANTIATION(class RegionBase<RegionTraits<Function>>);
+EXTERN_TEMPLATE_INSTANTIATION(class RegionNodeBase<RegionTraits<Function>>);
+EXTERN_TEMPLATE_INSTANTIATION(class RegionInfoBase<RegionTraits<Function>>);
+
 } // End llvm namespace
 #endif
-

Added: llvm/trunk/include/llvm/Analysis/RegionInfoImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/RegionInfoImpl.h?rev=213456&view=auto
==============================================================================
--- llvm/trunk/include/llvm/Analysis/RegionInfoImpl.h (added)
+++ llvm/trunk/include/llvm/Analysis/RegionInfoImpl.h Sat Jul 19 13:29:29 2014
@@ -0,0 +1,919 @@
+//===- RegionInfoImpl.h - SESE region detection analysis --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Detects single entry single exit regions in the control flow graph.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_REGIONINFOIMPL_H
+#define LLVM_ANALYSIS_REGIONINFOIMPL_H
+
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/Analysis/DominanceFrontier.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/Analysis/RegionIterator.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <algorithm>
+#include <iterator>
+#include <set>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "region"
+
+//===----------------------------------------------------------------------===//
+/// RegionBase Implementation
+template <class Tr>
+RegionBase<Tr>::RegionBase(BlockT *Entry, BlockT *Exit,
+                           typename Tr::RegionInfoT *RInfo, DomTreeT *dt,
+                           RegionT *Parent)
+    : RegionNodeBase<Tr>(Parent, Entry, 1), RI(RInfo), DT(dt), exit(Exit) {}
+
+template <class Tr>
+RegionBase<Tr>::~RegionBase() {
+  // Free the cached nodes.
+  for (typename BBNodeMapT::iterator it = BBNodeMap.begin(),
+                                     ie = BBNodeMap.end();
+       it != ie; ++it)
+    delete it->second;
+
+  // Only clean the cache for this Region. Caches of child Regions will be
+  // cleaned when the child Regions are deleted.
+  BBNodeMap.clear();
+}
+
+template <class Tr>
+void RegionBase<Tr>::replaceEntry(BlockT *BB) {
+  this->entry.setPointer(BB);
+}
+
+template <class Tr>
+void RegionBase<Tr>::replaceExit(BlockT *BB) {
+  assert(exit && "No exit to replace!");
+  exit = BB;
+}
+
+template <class Tr>
+void RegionBase<Tr>::replaceEntryRecursive(BlockT *NewEntry) {
+  std::vector<RegionT *> RegionQueue;
+  BlockT *OldEntry = getEntry();
+
+  RegionQueue.push_back(static_cast<RegionT *>(this));
+  while (!RegionQueue.empty()) {
+    RegionT *R = RegionQueue.back();
+    RegionQueue.pop_back();
+
+    R->replaceEntry(NewEntry);
+    for (typename RegionT::const_iterator RI = R->begin(), RE = R->end();
+         RI != RE; ++RI) {
+      if ((*RI)->getEntry() == OldEntry)
+        RegionQueue.push_back(RI->get());
+    }
+  }
+}
+
+template <class Tr>
+void RegionBase<Tr>::replaceExitRecursive(BlockT *NewExit) {
+  std::vector<RegionT *> RegionQueue;
+  BlockT *OldExit = getExit();
+
+  RegionQueue.push_back(static_cast<RegionT *>(this));
+  while (!RegionQueue.empty()) {
+    RegionT *R = RegionQueue.back();
+    RegionQueue.pop_back();
+
+    R->replaceExit(NewExit);
+    for (typename RegionT::const_iterator RI = R->begin(), RE = R->end();
+         RI != RE; ++RI) {
+      if ((*RI)->getExit() == OldExit)
+        RegionQueue.push_back(RI->get());
+    }
+  }
+}
+
+template <class Tr>
+bool RegionBase<Tr>::contains(const BlockT *B) const {
+  BlockT *BB = const_cast<BlockT *>(B);
+
+  if (!DT->getNode(BB))
+    return false;
+
+  BlockT *entry = getEntry(), *exit = getExit();
+
+  // Toplevel region.
+  if (!exit)
+    return true;
+
+  return (DT->dominates(entry, BB) &&
+          !(DT->dominates(exit, BB) && DT->dominates(entry, exit)));
+}
+
+template <class Tr>
+bool RegionBase<Tr>::contains(const LoopT *L) const {
+  // BBs that are not part of any loop are element of the Loop
+  // described by the NULL pointer. This loop is not part of any region,
+  // except if the region describes the whole function.
+  if (!L)
+    return getExit() == nullptr;
+
+  if (!contains(L->getHeader()))
+    return false;
+
+  SmallVector<BlockT *, 8> ExitingBlocks;
+  L->getExitingBlocks(ExitingBlocks);
+
+  for (BlockT *BB : ExitingBlocks) {
+    if (!contains(BB))
+      return false;
+  }
+
+  return true;
+}
+
+template <class Tr>
+typename Tr::LoopT *RegionBase<Tr>::outermostLoopInRegion(LoopT *L) const {
+  if (!contains(L))
+    return nullptr;
+
+  while (L && contains(L->getParentLoop())) {
+    L = L->getParentLoop();
+  }
+
+  return L;
+}
+
+template <class Tr>
+typename Tr::LoopT *RegionBase<Tr>::outermostLoopInRegion(LoopInfoT *LI,
+                                                          BlockT *BB) const {
+  assert(LI && BB && "LI and BB cannot be null!");
+  LoopT *L = LI->getLoopFor(BB);
+  return outermostLoopInRegion(L);
+}
+
+template <class Tr>
+typename RegionBase<Tr>::BlockT *RegionBase<Tr>::getEnteringBlock() const {
+  BlockT *entry = getEntry();
+  BlockT *Pred;
+  BlockT *enteringBlock = nullptr;
+
+  for (PredIterTy PI = InvBlockTraits::child_begin(entry),
+                  PE = InvBlockTraits::child_end(entry);
+       PI != PE; ++PI) {
+    Pred = *PI;
+    if (DT->getNode(Pred) && !contains(Pred)) {
+      if (enteringBlock)
+        return nullptr;
+
+      enteringBlock = Pred;
+    }
+  }
+
+  return enteringBlock;
+}
+
+template <class Tr>
+typename RegionBase<Tr>::BlockT *RegionBase<Tr>::getExitingBlock() const {
+  BlockT *exit = getExit();
+  BlockT *Pred;
+  BlockT *exitingBlock = nullptr;
+
+  if (!exit)
+    return nullptr;
+
+  for (PredIterTy PI = InvBlockTraits::child_begin(exit),
+                  PE = InvBlockTraits::child_end(exit);
+       PI != PE; ++PI) {
+    Pred = *PI;
+    if (contains(Pred)) {
+      if (exitingBlock)
+        return nullptr;
+
+      exitingBlock = Pred;
+    }
+  }
+
+  return exitingBlock;
+}
+
+template <class Tr>
+bool RegionBase<Tr>::isSimple() const {
+  return !isTopLevelRegion() && getEnteringBlock() && getExitingBlock();
+}
+
+template <class Tr>
+std::string RegionBase<Tr>::getNameStr() const {
+  std::string exitName;
+  std::string entryName;
+
+  if (getEntry()->getName().empty()) {
+    raw_string_ostream OS(entryName);
+
+    getEntry()->printAsOperand(OS, false);
+  } else
+    entryName = getEntry()->getName();
+
+  if (getExit()) {
+    if (getExit()->getName().empty()) {
+      raw_string_ostream OS(exitName);
+
+      getExit()->printAsOperand(OS, false);
+    } else
+      exitName = getExit()->getName();
+  } else
+    exitName = "<Function Return>";
+
+  return entryName + " => " + exitName;
+}
+
+template <class Tr>
+void RegionBase<Tr>::verifyBBInRegion(BlockT *BB) const {
+  if (!contains(BB))
+    llvm_unreachable("Broken region found!");
+
+  BlockT *entry = getEntry(), *exit = getExit();
+
+  for (SuccIterTy SI = BlockTraits::child_begin(BB),
+                  SE = BlockTraits::child_end(BB);
+       SI != SE; ++SI) {
+    if (!contains(*SI) && exit != *SI)
+      llvm_unreachable("Broken region found!");
+  }
+
+  if (entry != BB) {
+    for (PredIterTy SI = InvBlockTraits::child_begin(BB),
+                    SE = InvBlockTraits::child_end(BB);
+         SI != SE; ++SI) {
+      if (!contains(*SI))
+        llvm_unreachable("Broken region found!");
+    }
+  }
+}
+
+template <class Tr>
+void RegionBase<Tr>::verifyWalk(BlockT *BB, std::set<BlockT *> *visited) const {
+  BlockT *exit = getExit();
+
+  visited->insert(BB);
+
+  verifyBBInRegion(BB);
+
+  for (SuccIterTy SI = BlockTraits::child_begin(BB),
+                  SE = BlockTraits::child_end(BB);
+       SI != SE; ++SI) {
+    if (*SI != exit && visited->find(*SI) == visited->end())
+      verifyWalk(*SI, visited);
+  }
+}
+
+template <class Tr>
+void RegionBase<Tr>::verifyRegion() const {
+  // Only do verification when user wants to, otherwise this expensive check
+  // will be invoked by PMDataManager::verifyPreservedAnalysis when
+  // a regionpass (marked PreservedAll) finish.
+  if (!RegionInfoBase<Tr>::VerifyRegionInfo)
+    return;
+
+  std::set<BlockT *> visited;
+  verifyWalk(getEntry(), &visited);
+}
+
+template <class Tr>
+void RegionBase<Tr>::verifyRegionNest() const {
+  for (typename RegionT::const_iterator RI = begin(), RE = end(); RI != RE;
+       ++RI)
+    (*RI)->verifyRegionNest();
+
+  verifyRegion();
+}
+
+template <class Tr>
+typename RegionBase<Tr>::element_iterator RegionBase<Tr>::element_begin() {
+  return GraphTraits<RegionT *>::nodes_begin(static_cast<RegionT *>(this));
+}
+
+template <class Tr>
+typename RegionBase<Tr>::element_iterator RegionBase<Tr>::element_end() {
+  return GraphTraits<RegionT *>::nodes_end(static_cast<RegionT *>(this));
+}
+
+template <class Tr>
+typename RegionBase<Tr>::const_element_iterator
+RegionBase<Tr>::element_begin() const {
+  return GraphTraits<const RegionT *>::nodes_begin(
+      static_cast<const RegionT *>(this));
+}
+
+template <class Tr>
+typename RegionBase<Tr>::const_element_iterator
+RegionBase<Tr>::element_end() const {
+  return GraphTraits<const RegionT *>::nodes_end(
+      static_cast<const RegionT *>(this));
+}
+
+template <class Tr>
+typename Tr::RegionT *RegionBase<Tr>::getSubRegionNode(BlockT *BB) const {
+  typedef typename Tr::RegionT RegionT;
+  RegionT *R = RI->getRegionFor(BB);
+
+  if (!R || R == this)
+    return nullptr;
+
+  // If we pass the BB out of this region, that means our code is broken.
+  assert(contains(R) && "BB not in current region!");
+
+  while (contains(R->getParent()) && R->getParent() != this)
+    R = R->getParent();
+
+  if (R->getEntry() != BB)
+    return nullptr;
+
+  return R;
+}
+
+template <class Tr>
+typename Tr::RegionNodeT *RegionBase<Tr>::getBBNode(BlockT *BB) const {
+  assert(contains(BB) && "Can get BB node out of this region!");
+
+  typename BBNodeMapT::const_iterator at = BBNodeMap.find(BB);
+
+  if (at != BBNodeMap.end())
+    return at->second;
+
+  auto Deconst = const_cast<RegionBase<Tr> *>(this);
+  RegionNodeT *NewNode = new RegionNodeT(static_cast<RegionT *>(Deconst), BB);
+  BBNodeMap.insert(std::make_pair(BB, NewNode));
+  return NewNode;
+}
+
+template <class Tr>
+typename Tr::RegionNodeT *RegionBase<Tr>::getNode(BlockT *BB) const {
+  assert(contains(BB) && "Can get BB node out of this region!");
+  if (RegionT *Child = getSubRegionNode(BB))
+    return Child->getNode();
+
+  return getBBNode(BB);
+}
+
+template <class Tr>
+void RegionBase<Tr>::transferChildrenTo(RegionT *To) {
+  for (iterator I = begin(), E = end(); I != E; ++I) {
+    (*I)->parent = To;
+    To->children.push_back(std::move(*I));
+  }
+  children.clear();
+}
+
+template <class Tr>
+void RegionBase<Tr>::addSubRegion(RegionT *SubRegion, bool moveChildren) {
+  assert(!SubRegion->parent && "SubRegion already has a parent!");
+  assert(std::find_if(begin(), end(), [&](const std::unique_ptr<RegionT> &R) {
+           return R.get() == SubRegion;
+         }) == children.end() &&
+         "Subregion already exists!");
+
+  SubRegion->parent = static_cast<RegionT *>(this);
+  children.push_back(std::unique_ptr<RegionT>(SubRegion));
+
+  if (!moveChildren)
+    return;
+
+  assert(SubRegion->children.empty() &&
+         "SubRegions that contain children are not supported");
+
+  for (element_iterator I = element_begin(), E = element_end(); I != E; ++I) {
+    if (!(*I)->isSubRegion()) {
+      BlockT *BB = (*I)->template getNodeAs<BlockT>();
+
+      if (SubRegion->contains(BB))
+        RI->setRegionFor(BB, SubRegion);
+    }
+  }
+
+  std::vector<std::unique_ptr<RegionT>> Keep;
+  for (iterator I = begin(), E = end(); I != E; ++I) {
+    if (SubRegion->contains(I->get()) && I->get() != SubRegion) {
+      (*I)->parent = SubRegion;
+      SubRegion->children.push_back(std::move(*I));
+    } else
+      Keep.push_back(std::move(*I));
+  }
+
+  children.clear();
+  children.insert(
+      children.begin(),
+      std::move_iterator<typename RegionSet::iterator>(Keep.begin()),
+      std::move_iterator<typename RegionSet::iterator>(Keep.end()));
+}
+
+template <class Tr>
+typename Tr::RegionT *RegionBase<Tr>::removeSubRegion(RegionT *Child) {
+  assert(Child->parent == this && "Child is not a child of this region!");
+  Child->parent = nullptr;
+  typename RegionSet::iterator I = std::find_if(
+      children.begin(), children.end(),
+      [&](const std::unique_ptr<RegionT> &R) { return R.get() == Child; });
+  assert(I != children.end() && "Region does not exit. Unable to remove.");
+  children.erase(children.begin() + (I - begin()));
+  return Child;
+}
+
+template <class Tr>
+unsigned RegionBase<Tr>::getDepth() const {
+  unsigned Depth = 0;
+
+  for (RegionT *R = getParent(); R != nullptr; R = R->getParent())
+    ++Depth;
+
+  return Depth;
+}
+
+template <class Tr>
+typename Tr::RegionT *RegionBase<Tr>::getExpandedRegion() const {
+  unsigned NumSuccessors = Tr::getNumSuccessors(exit);
+
+  if (NumSuccessors == 0)
+    return nullptr;
+
+  for (PredIterTy PI = InvBlockTraits::child_begin(getExit()),
+                  PE = InvBlockTraits::child_end(getExit());
+       PI != PE; ++PI) {
+    if (!DT->dominates(getEntry(), *PI))
+      return nullptr;
+  }
+
+  RegionT *R = RI->getRegionFor(exit);
+
+  if (R->getEntry() != exit) {
+    if (Tr::getNumSuccessors(exit) == 1)
+      return new RegionT(getEntry(), *BlockTraits::child_begin(exit), RI, DT);
+    return nullptr;
+  }
+
+  while (R->getParent() && R->getParent()->getEntry() == exit)
+    R = R->getParent();
+
+  if (!DT->dominates(getEntry(), R->getExit())) {
+    for (PredIterTy PI = InvBlockTraits::child_begin(getExit()),
+                    PE = InvBlockTraits::child_end(getExit());
+         PI != PE; ++PI) {
+      if (!DT->dominates(R->getExit(), *PI))
+        return nullptr;
+    }
+  }
+
+  return new RegionT(getEntry(), R->getExit(), RI, DT);
+}
+
+template <class Tr>
+void RegionBase<Tr>::print(raw_ostream &OS, bool print_tree, unsigned level,
+                           PrintStyle Style) const {
+  if (print_tree)
+    OS.indent(level * 2) << '[' << level << "] " << getNameStr();
+  else
+    OS.indent(level * 2) << getNameStr();
+
+  OS << '\n';
+
+  if (Style != PrintNone) {
+    OS.indent(level * 2) << "{\n";
+    OS.indent(level * 2 + 2);
+
+    if (Style == PrintBB) {
+      for (const auto &BB : blocks())
+        OS << BB->getName() << ", "; // TODO: remove the last ","
+    } else if (Style == PrintRN) {
+      for (const_element_iterator I = element_begin(), E = element_end();
+           I != E; ++I) {
+        OS << **I << ", "; // TODO: remove the last ",
+      }
+    }
+
+    OS << '\n';
+  }
+
+  if (print_tree) {
+    for (const_iterator RI = begin(), RE = end(); RI != RE; ++RI)
+      (*RI)->print(OS, print_tree, level + 1, Style);
+  }
+
+  if (Style != PrintNone)
+    OS.indent(level * 2) << "} \n";
+}
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+template <class Tr>
+void RegionBase<Tr>::dump() const {
+  print(dbgs(), true, getDepth(), RegionInfoBase<Tr>::printStyle);
+}
+#endif
+
+template <class Tr>
+void RegionBase<Tr>::clearNodeCache() {
+  // Free the cached nodes.
+  for (typename BBNodeMapT::iterator I = BBNodeMap.begin(),
+                                     IE = BBNodeMap.end();
+       I != IE; ++I)
+    delete I->second;
+
+  BBNodeMap.clear();
+  for (typename RegionT::iterator RI = begin(), RE = end(); RI != RE; ++RI)
+    (*RI)->clearNodeCache();
+}
+
+//===----------------------------------------------------------------------===//
+// RegionInfoBase implementation
+//
+
+template <class Tr>
+RegionInfoBase<Tr>::RegionInfoBase()
+    : TopLevelRegion(nullptr) {}
+
+template <class Tr>
+RegionInfoBase<Tr>::~RegionInfoBase() {
+  releaseMemory();
+}
+
+template <class Tr>
+bool RegionInfoBase<Tr>::isCommonDomFrontier(BlockT *BB, BlockT *entry,
+                                             BlockT *exit) const {
+  for (PredIterTy PI = InvBlockTraits::child_begin(BB),
+                  PE = InvBlockTraits::child_end(BB);
+       PI != PE; ++PI) {
+    BlockT *P = *PI;
+    if (DT->dominates(entry, P) && !DT->dominates(exit, P))
+      return false;
+  }
+
+  return true;
+}
+
+template <class Tr>
+bool RegionInfoBase<Tr>::isRegion(BlockT *entry, BlockT *exit) const {
+  assert(entry && exit && "entry and exit must not be null!");
+  typedef typename DomFrontierT::DomSetType DST;
+
+  DST *entrySuccs = &DF->find(entry)->second;
+
+  // Exit is the header of a loop that contains the entry. In this case,
+  // the dominance frontier must only contain the exit.
+  if (!DT->dominates(entry, exit)) {
+    for (typename DST::iterator SI = entrySuccs->begin(),
+                                SE = entrySuccs->end();
+         SI != SE; ++SI) {
+      if (*SI != exit && *SI != entry)
+        return false;
+    }
+
+    return true;
+  }
+
+  DST *exitSuccs = &DF->find(exit)->second;
+
+  // Do not allow edges leaving the region.
+  for (typename DST::iterator SI = entrySuccs->begin(), SE = entrySuccs->end();
+       SI != SE; ++SI) {
+    if (*SI == exit || *SI == entry)
+      continue;
+    if (exitSuccs->find(*SI) == exitSuccs->end())
+      return false;
+    if (!isCommonDomFrontier(*SI, entry, exit))
+      return false;
+  }
+
+  // Do not allow edges pointing into the region.
+  for (typename DST::iterator SI = exitSuccs->begin(), SE = exitSuccs->end();
+       SI != SE; ++SI) {
+    if (DT->properlyDominates(entry, *SI) && *SI != exit)
+      return false;
+  }
+
+  return true;
+}
+
+template <class Tr>
+void RegionInfoBase<Tr>::insertShortCut(BlockT *entry, BlockT *exit,
+                                        BBtoBBMap *ShortCut) const {
+  assert(entry && exit && "entry and exit must not be null!");
+
+  typename BBtoBBMap::iterator e = ShortCut->find(exit);
+
+  if (e == ShortCut->end())
+    // No further region at exit available.
+    (*ShortCut)[entry] = exit;
+  else {
+    // We found a region e that starts at exit. Therefore (entry, e->second)
+    // is also a region, that is larger than (entry, exit). Insert the
+    // larger one.
+    BlockT *BB = e->second;
+    (*ShortCut)[entry] = BB;
+  }
+}
+
+template <class Tr>
+typename Tr::DomTreeNodeT *
+RegionInfoBase<Tr>::getNextPostDom(DomTreeNodeT *N, BBtoBBMap *ShortCut) const {
+  typename BBtoBBMap::iterator e = ShortCut->find(N->getBlock());
+
+  if (e == ShortCut->end())
+    return N->getIDom();
+
+  return PDT->getNode(e->second)->getIDom();
+}
+
+template <class Tr>
+bool RegionInfoBase<Tr>::isTrivialRegion(BlockT *entry, BlockT *exit) const {
+  assert(entry && exit && "entry and exit must not be null!");
+
+  unsigned num_successors =
+      BlockTraits::child_end(entry) - BlockTraits::child_begin(entry);
+
+  if (num_successors <= 1 && exit == *(BlockTraits::child_begin(entry)))
+    return true;
+
+  return false;
+}
+
+template <class Tr>
+typename Tr::RegionT *RegionInfoBase<Tr>::createRegion(BlockT *entry,
+                                                       BlockT *exit) {
+  assert(entry && exit && "entry and exit must not be null!");
+
+  if (isTrivialRegion(entry, exit))
+    return nullptr;
+
+  RegionT *region =
+      new RegionT(entry, exit, static_cast<RegionInfoT *>(this), DT);
+  BBtoRegion.insert(std::make_pair(entry, region));
+
+#ifdef XDEBUG
+  region->verifyRegion();
+#else
+  DEBUG(region->verifyRegion());
+#endif
+
+  updateStatistics(region);
+  return region;
+}
+
+template <class Tr>
+void RegionInfoBase<Tr>::findRegionsWithEntry(BlockT *entry,
+                                              BBtoBBMap *ShortCut) {
+  assert(entry);
+
+  DomTreeNodeT *N = PDT->getNode(entry);
+  if (!N)
+    return;
+
+  RegionT *lastRegion = nullptr;
+  BlockT *lastExit = entry;
+
+  // As only a BasicBlock that postdominates entry can finish a region, walk the
+  // post dominance tree upwards.
+  while ((N = getNextPostDom(N, ShortCut))) {
+    BlockT *exit = N->getBlock();
+
+    if (!exit)
+      break;
+
+    if (isRegion(entry, exit)) {
+      RegionT *newRegion = createRegion(entry, exit);
+
+      if (lastRegion)
+        newRegion->addSubRegion(lastRegion);
+
+      lastRegion = newRegion;
+      lastExit = exit;
+    }
+
+    // This can never be a region, so stop the search.
+    if (!DT->dominates(entry, exit))
+      break;
+  }
+
+  // Tried to create regions from entry to lastExit.  Next time take a
+  // shortcut from entry to lastExit.
+  if (lastExit != entry)
+    insertShortCut(entry, lastExit, ShortCut);
+}
+
+template <class Tr>
+void RegionInfoBase<Tr>::scanForRegions(FuncT &F, BBtoBBMap *ShortCut) {
+  typedef typename std::add_pointer<FuncT>::type FuncPtrT;
+  BlockT *entry = GraphTraits<FuncPtrT>::getEntryNode(&F);
+  DomTreeNodeT *N = DT->getNode(entry);
+
+  // Iterate over the dominance tree in post order to start with the small
+  // regions from the bottom of the dominance tree.  If the small regions are
+  // detected first, detection of bigger regions is faster, as we can jump
+  // over the small regions.
+  for (po_iterator<DomTreeNodeT *> FI = po_begin(N), FE = po_end(N); FI != FE;
+       ++FI) {
+    findRegionsWithEntry(FI->getBlock(), ShortCut);
+  }
+}
+
+template <class Tr>
+typename Tr::RegionT *RegionInfoBase<Tr>::getTopMostParent(RegionT *region) {
+  while (region->getParent())
+    region = region->getParent();
+
+  return region;
+}
+
+template <class Tr>
+void RegionInfoBase<Tr>::buildRegionsTree(DomTreeNodeT *N, RegionT *region) {
+  BlockT *BB = N->getBlock();
+
+  // Passed region exit
+  while (BB == region->getExit())
+    region = region->getParent();
+
+  typename BBtoRegionMap::iterator it = BBtoRegion.find(BB);
+
+  // This basic block is a start block of a region. It is already in the
+  // BBtoRegion relation. Only the child basic blocks have to be updated.
+  if (it != BBtoRegion.end()) {
+    RegionT *newRegion = it->second;
+    region->addSubRegion(getTopMostParent(newRegion));
+    region = newRegion;
+  } else {
+    BBtoRegion[BB] = region;
+  }
+
+  for (typename DomTreeNodeT::iterator CI = N->begin(), CE = N->end(); CI != CE;
+       ++CI) {
+    buildRegionsTree(*CI, region);
+  }
+}
+
+#ifdef XDEBUG
+template <class Tr>
+bool RegionInfoBase<Tr>::VerifyRegionInfo = true;
+#else
+template <class Tr>
+bool RegionInfoBase<Tr>::VerifyRegionInfo = false;
+#endif
+
+template <class Tr>
+typename Tr::RegionT::PrintStyle RegionInfoBase<Tr>::printStyle =
+    RegionBase<Tr>::PrintNone;
+
+template <class Tr>
+void RegionInfoBase<Tr>::print(raw_ostream &OS) const {
+  OS << "Region tree:\n";
+  TopLevelRegion->print(OS, true, 0, printStyle);
+  OS << "End region tree\n";
+}
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+template <class Tr>
+void RegionInfoBase<Tr>::dump() const { print(dbgs()); }
+#endif
+
+template <class Tr>
+void RegionInfoBase<Tr>::releaseMemory() {
+  BBtoRegion.clear();
+  if (TopLevelRegion)
+    delete TopLevelRegion;
+  TopLevelRegion = nullptr;
+}
+
+template <class Tr>
+void RegionInfoBase<Tr>::verifyAnalysis() const {
+  TopLevelRegion->verifyRegionNest();
+}
+
+// Region pass manager support.
+template <class Tr>
+typename Tr::RegionT *RegionInfoBase<Tr>::getRegionFor(BlockT *BB) const {
+  typename BBtoRegionMap::const_iterator I = BBtoRegion.find(BB);
+  return I != BBtoRegion.end() ? I->second : nullptr;
+}
+
+template <class Tr>
+void RegionInfoBase<Tr>::setRegionFor(BlockT *BB, RegionT *R) {
+  BBtoRegion[BB] = R;
+}
+
+template <class Tr>
+typename Tr::RegionT *RegionInfoBase<Tr>::operator[](BlockT *BB) const {
+  return getRegionFor(BB);
+}
+
+template <class Tr>
+typename RegionInfoBase<Tr>::BlockT *
+RegionInfoBase<Tr>::getMaxRegionExit(BlockT *BB) const {
+  BlockT *Exit = nullptr;
+
+  while (true) {
+    // Get largest region that starts at BB.
+    RegionT *R = getRegionFor(BB);
+    while (R && R->getParent() && R->getParent()->getEntry() == BB)
+      R = R->getParent();
+
+    // Get the single exit of BB.
+    if (R && R->getEntry() == BB)
+      Exit = R->getExit();
+    else if (++BlockTraits::child_begin(BB) == BlockTraits::child_end(BB))
+      Exit = *BlockTraits::child_begin(BB);
+    else // No single exit exists.
+      return Exit;
+
+    // Get largest region that starts at Exit.
+    RegionT *ExitR = getRegionFor(Exit);
+    while (ExitR && ExitR->getParent() &&
+           ExitR->getParent()->getEntry() == Exit)
+      ExitR = ExitR->getParent();
+
+    for (PredIterTy PI = InvBlockTraits::child_begin(Exit),
+                    PE = InvBlockTraits::child_end(Exit);
+         PI != PE; ++PI) {
+      if (!R->contains(*PI) && !ExitR->contains(*PI))
+        break;
+    }
+
+    // This stops infinite cycles.
+    if (DT->dominates(Exit, BB))
+      break;
+
+    BB = Exit;
+  }
+
+  return Exit;
+}
+
+template <class Tr>
+typename Tr::RegionT *RegionInfoBase<Tr>::getCommonRegion(RegionT *A,
+                                                          RegionT *B) const {
+  assert(A && B && "One of the Regions is NULL");
+
+  if (A->contains(B))
+    return A;
+
+  while (!B->contains(A))
+    B = B->getParent();
+
+  return B;
+}
+
+template <class Tr>
+typename Tr::RegionT *
+RegionInfoBase<Tr>::getCommonRegion(SmallVectorImpl<RegionT *> &Regions) const {
+  RegionT *ret = Regions.back();
+  Regions.pop_back();
+
+  for (RegionT *R : Regions)
+    ret = getCommonRegion(ret, R);
+
+  return ret;
+}
+
+template <class Tr>
+typename Tr::RegionT *
+RegionInfoBase<Tr>::getCommonRegion(SmallVectorImpl<BlockT *> &BBs) const {
+  RegionT *ret = getRegionFor(BBs.back());
+  BBs.pop_back();
+
+  for (BlockT *BB : BBs)
+    ret = getCommonRegion(ret, getRegionFor(BB));
+
+  return ret;
+}
+
+template <class Tr>
+void RegionInfoBase<Tr>::splitBlock(BlockT *NewBB, BlockT *OldBB) {
+  RegionT *R = getRegionFor(OldBB);
+
+  setRegionFor(NewBB, R);
+
+  while (R->getEntry() == OldBB && !R->isTopLevelRegion()) {
+    R->replaceEntry(NewBB);
+    R = R->getParent();
+  }
+
+  setRegionFor(OldBB, R);
+}
+
+template <class Tr>
+void RegionInfoBase<Tr>::calculate(FuncT &F) {
+  typedef typename std::add_pointer<FuncT>::type FuncPtrT;
+
+  // ShortCut a function where for every BB the exit of the largest region
+  // starting with BB is stored. These regions can be threated as single BBS.
+  // This improves performance on linear CFGs.
+  BBtoBBMap ShortCut;
+
+  scanForRegions(F, &ShortCut);
+  BlockT *BB = GraphTraits<FuncPtrT>::getEntryNode(&F);
+  buildRegionsTree(DT->getNode(BB), TopLevelRegion);
+}
+
+#endif

Modified: llvm/trunk/include/llvm/Analysis/RegionIterator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/RegionIterator.h?rev=213456&r1=213455&r2=213456&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/RegionIterator.h (original)
+++ llvm/trunk/include/llvm/Analysis/RegionIterator.h Sat Jul 19 13:29:29 2014
@@ -30,13 +30,16 @@ namespace llvm {
 ///
 /// For a subregion RegionNode there is just one successor. The RegionNode
 /// representing the exit of the subregion.
-template<class NodeType>
+template<class NodeType, class BlockT, class RegionT>
 class RNSuccIterator : public std::iterator<std::forward_iterator_tag,
-                                           NodeType, ptrdiff_t>
-{
+                                           NodeType, ptrdiff_t> {
   typedef std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t> super;
+
+  typedef GraphTraits<BlockT*> BlockTraits;
+  typedef typename BlockTraits::ChildIteratorType SuccIterTy;
+
   // The iterator works in two modes, bb mode or region mode.
-  enum ItMode{
+  enum ItMode {
     // In BB mode it returns all successors of this BasicBlock as its
     // successors.
     ItBB,
@@ -47,10 +50,10 @@ class RNSuccIterator : public std::itera
   };
 
   // Use two bit to represent the mode iterator.
-  PointerIntPair<NodeType*, 2, enum ItMode> Node;
+  PointerIntPair<NodeType*, 2, ItMode> Node;
 
   // The block successor iterator.
-  succ_iterator BItor;
+  SuccIterTy BItor;
 
   // advanceRegionSucc - A region node has only one successor. It reaches end
   // once we advance it.
@@ -66,37 +69,36 @@ class RNSuccIterator : public std::itera
 
   // Get the immediate successor. This function may return a Basic Block
   // RegionNode or a subregion RegionNode.
-  RegionNode* getISucc(BasicBlock* BB) const {
-    RegionNode *succ;
+  NodeType* getISucc(BlockT* BB) const {
+    NodeType *succ;
     succ = getNode()->getParent()->getNode(BB);
     assert(succ && "BB not in Region or entered subregion!");
     return succ;
   }
 
   // getRegionSucc - Return the successor basic block of a SubRegion RegionNode.
-  inline BasicBlock* getRegionSucc() const {
+  inline BlockT* getRegionSucc() const {
     assert(Node.getInt() == ItRgBegin && "Cannot get the region successor!");
-    return getNode()->template getNodeAs<Region>()->getExit();
+    return getNode()->template getNodeAs<RegionT>()->getExit();
   }
 
   // isExit - Is this the exit BB of the Region?
-  inline bool isExit(BasicBlock* BB) const {
+  inline bool isExit(BlockT* BB) const {
     return getNode()->getParent()->getExit() == BB;
   }
 public:
-  typedef RNSuccIterator<NodeType> Self;
+  typedef RNSuccIterator<NodeType, BlockT, RegionT> Self;
 
   typedef typename super::pointer pointer;
 
   /// @brief Create begin iterator of a RegionNode.
   inline RNSuccIterator(NodeType* node)
     : Node(node, node->isSubRegion() ? ItRgBegin : ItBB),
-    BItor(succ_begin(node->getEntry())) {
-
+      BItor(BlockTraits::child_begin(node->getEntry())) {
 
     // Skip the exit block
     if (!isRegionMode())
-      while (succ_end(node->getEntry()) != BItor && isExit(*BItor))
+      while (BlockTraits::child_end(node->getEntry()) != BItor && isExit(*BItor))
         ++BItor;
 
     if (isRegionMode() && isExit(getRegionSucc()))
@@ -106,7 +108,7 @@ public:
   /// @brief Create an end iterator.
   inline RNSuccIterator(NodeType* node, bool)
     : Node(node, node->isSubRegion() ? ItRgEnd : ItBB),
-    BItor(succ_end(node->getEntry())) {}
+      BItor(BlockTraits::child_end(node->getEntry())) {}
 
   inline bool operator==(const Self& x) const {
     assert(isRegionMode() == x.isRegionMode() && "Broken iterator!");
@@ -119,7 +121,7 @@ public:
   inline bool operator!=(const Self& x) const { return !operator==(x); }
 
   inline pointer operator*() const {
-    BasicBlock* BB = isRegionMode() ? getRegionSucc() : *BItor;
+    BlockT *BB = isRegionMode() ? getRegionSucc() : *BItor;
     assert(!isExit(BB) && "Iterator out of range!");
     return getISucc(BB);
   }
@@ -132,7 +134,7 @@ public:
       // Skip the exit.
       do
         ++BItor;
-      while (BItor != succ_end(getNode()->getEntry())
+      while (BItor != BlockTraits::child_end(getNode()->getEntry())
           && isExit(*BItor));
     }
     return *this;
@@ -162,36 +164,41 @@ public:
 /// The Flat Region iterator will iterate over all BasicBlock RegionNodes that
 /// are contained in the Region and its subregions. This is close to a virtual
 /// control flow graph of the Region.
-template<class NodeType>
-class RNSuccIterator<FlatIt<NodeType> >
-  : public std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t>
-{
+template<class NodeType, class BlockT, class RegionT>
+class RNSuccIterator<FlatIt<NodeType>, BlockT, RegionT>
+  : public std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t> {
   typedef std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t> super;
+  typedef GraphTraits<BlockT*> BlockTraits;
+  typedef typename BlockTraits::ChildIteratorType SuccIterTy;
+
   NodeType* Node;
-  succ_iterator Itor;
+  SuccIterTy Itor;
 
 public:
-  typedef RNSuccIterator<FlatIt<NodeType> > Self;
+  typedef RNSuccIterator<FlatIt<NodeType>, BlockT, RegionT> Self;
   typedef typename super::pointer pointer;
 
   /// @brief Create the iterator from a RegionNode.
   ///
   /// Note that the incoming node must be a bb node, otherwise it will trigger
   /// an assertion when we try to get a BasicBlock.
-  inline RNSuccIterator(NodeType* node) : Node(node),
-    Itor(succ_begin(node->getEntry())) {
+  inline RNSuccIterator(NodeType* node) :
+    Node(node),
+    Itor(BlockTraits::child_begin(node->getEntry())) {
       assert(!Node->isSubRegion()
              && "Subregion node not allowed in flat iterating mode!");
       assert(Node->getParent() && "A BB node must have a parent!");
 
       // Skip the exit block of the iterating region.
-      while (succ_end(Node->getEntry()) != Itor
+      while (BlockTraits::child_end(Node->getEntry()) != Itor
           && Node->getParent()->getExit() == *Itor)
         ++Itor;
   }
+
   /// @brief Create an end iterator
-  inline RNSuccIterator(NodeType* node, bool) : Node(node),
-    Itor(succ_end(node->getEntry())) {
+  inline RNSuccIterator(NodeType* node, bool) :
+    Node(node),
+    Itor(BlockTraits::child_end(node->getEntry())) {
       assert(!Node->isSubRegion()
              && "Subregion node not allowed in flat iterating mode!");
   }
@@ -206,10 +213,10 @@ public:
   inline bool operator!=(const Self& x) const { return !operator==(x); }
 
   inline pointer operator*() const {
-    BasicBlock* BB = *Itor;
+    BlockT *BB = *Itor;
 
     // Get the iterating region.
-    Region* Parent = Node->getParent();
+    RegionT *Parent = Node->getParent();
 
     // The only case that the successor reaches out of the region is it reaches
     // the exit of the region.
@@ -245,14 +252,14 @@ public:
   }
 };
 
-template<class NodeType>
-inline RNSuccIterator<NodeType> succ_begin(NodeType* Node) {
-  return RNSuccIterator<NodeType>(Node);
+template<class NodeType, class BlockT, class RegionT>
+inline RNSuccIterator<NodeType, BlockT, RegionT> succ_begin(NodeType* Node) {
+  return RNSuccIterator<NodeType, BlockT, RegionT>(Node);
 }
 
-template<class NodeType>
-inline RNSuccIterator<NodeType> succ_end(NodeType* Node) {
-  return RNSuccIterator<NodeType>(Node, true);
+template<class NodeType, class BlockT, class RegionT>
+inline RNSuccIterator<NodeType, BlockT, RegionT> succ_end(NodeType* Node) {
+  return RNSuccIterator<NodeType, BlockT, RegionT>(Node, true);
 }
 
 //===--------------------------------------------------------------------===//
@@ -262,27 +269,27 @@ inline RNSuccIterator<NodeType> succ_end
 // NodeT can either be region node or const region node, otherwise child_begin
 // and child_end fail.
 
-#define RegionNodeGraphTraits(NodeT) \
-  template<> struct GraphTraits<NodeT*> { \
+#define RegionNodeGraphTraits(NodeT, BlockT, RegionT)   \
+  template<> struct GraphTraits<NodeT*> {      \
   typedef NodeT NodeType; \
-  typedef RNSuccIterator<NodeType> ChildIteratorType; \
+  typedef RNSuccIterator<NodeType, BlockT, RegionT> ChildIteratorType;  \
   static NodeType *getEntryNode(NodeType* N) { return N; } \
   static inline ChildIteratorType child_begin(NodeType *N) { \
-    return RNSuccIterator<NodeType>(N); \
+    return RNSuccIterator<NodeType, BlockT, RegionT>(N);             \
   } \
   static inline ChildIteratorType child_end(NodeType *N) { \
-    return RNSuccIterator<NodeType>(N, true); \
+    return RNSuccIterator<NodeType, BlockT, RegionT>(N, true);     \
   } \
 }; \
-template<> struct GraphTraits<FlatIt<NodeT*> > { \
+template<> struct GraphTraits<FlatIt<NodeT*>> {  \
   typedef NodeT NodeType; \
-  typedef RNSuccIterator<FlatIt<NodeT> > ChildIteratorType; \
+  typedef RNSuccIterator<FlatIt<NodeT>, BlockT, RegionT > ChildIteratorType;    \
   static NodeType *getEntryNode(NodeType* N) { return N; } \
   static inline ChildIteratorType child_begin(NodeType *N) { \
-    return RNSuccIterator<FlatIt<NodeType> >(N); \
+    return RNSuccIterator<FlatIt<NodeType>, BlockT, RegionT>(N); \
   } \
   static inline ChildIteratorType child_end(NodeType *N) { \
-    return RNSuccIterator<FlatIt<NodeType> >(N, true); \
+    return RNSuccIterator<FlatIt<NodeType>, BlockT, RegionT>(N, true); \
   } \
 }
 
@@ -315,8 +322,8 @@ template<> struct GraphTraits<FlatIt<Reg
   } \
 }
 
-RegionNodeGraphTraits(RegionNode);
-RegionNodeGraphTraits(const RegionNode);
+RegionNodeGraphTraits(RegionNode, BasicBlock, Region);
+RegionNodeGraphTraits(const RegionNode, BasicBlock, Region);
 
 RegionGraphTraits(Region, RegionNode);
 RegionGraphTraits(const Region, const RegionNode);
@@ -337,6 +344,22 @@ template <> struct GraphTraits<RegionInf
   }
 };
 
+template <> struct GraphTraits<RegionInfoPass*>
+  : public GraphTraits<RegionInfo *> {
+  typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false,
+                      GraphTraits<FlatIt<NodeType*> > > nodes_iterator;
+
+  static NodeType *getEntryNode(RegionInfoPass *RI) {
+    return GraphTraits<RegionInfo*>::getEntryNode(&RI->getRegionInfo());
+  }
+  static nodes_iterator nodes_begin(RegionInfoPass* RI) {
+    return GraphTraits<RegionInfo*>::nodes_begin(&RI->getRegionInfo());
+  }
+  static nodes_iterator nodes_end(RegionInfoPass *RI) {
+    return GraphTraits<RegionInfo*>::nodes_end(&RI->getRegionInfo());
+  }
+};
+
 } // End namespace llvm
 
 #endif

Added: llvm/trunk/include/llvm/CodeGen/MachineRegionInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineRegionInfo.h?rev=213456&view=auto
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineRegionInfo.h (added)
+++ llvm/trunk/include/llvm/CodeGen/MachineRegionInfo.h Sat Jul 19 13:29:29 2014
@@ -0,0 +1,183 @@
+//===- llvm/CodeGen/MachineRegionInfo.h -------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEREGIONINFO_H
+#define LLVM_CODEGEN_MACHINEREGIONINFO_H
+
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/Analysis/RegionIterator.h"
+#include "llvm/CodeGen/MachineDominanceFrontier.h"
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineLoopInfo.h"
+
+
+namespace llvm {
+
+class MachineDominatorTree;
+struct MachinePostDominatorTree;
+class MachineRegion;
+class MachineRegionNode;
+class MachineRegionInfo;
+
+template<>
+struct RegionTraits<MachineFunction> {
+  typedef MachineFunction FuncT;
+  typedef MachineBasicBlock BlockT;
+  typedef MachineRegion RegionT;
+  typedef MachineRegionNode RegionNodeT;
+  typedef MachineRegionInfo RegionInfoT;
+  typedef MachineDominatorTree DomTreeT;
+  typedef MachineDomTreeNode DomTreeNodeT;
+  typedef MachinePostDominatorTree PostDomTreeT;
+  typedef MachineDominanceFrontier DomFrontierT;
+  typedef MachineInstr InstT;
+  typedef MachineLoop LoopT;
+  typedef MachineLoopInfo LoopInfoT;
+
+  static unsigned getNumSuccessors(MachineBasicBlock *BB) {
+    return BB->succ_size();
+  }
+};
+
+
+class MachineRegionNode : public RegionNodeBase<RegionTraits<MachineFunction>> {
+public:
+  inline MachineRegionNode(MachineRegion *Parent,
+                           MachineBasicBlock *Entry,
+                           bool isSubRegion = false)
+    : RegionNodeBase<RegionTraits<MachineFunction>>(Parent, Entry, isSubRegion) {
+
+  }
+
+  ~MachineRegionNode() { }
+
+  bool operator==(const MachineRegion &RN) const {
+    return this == reinterpret_cast<const MachineRegionNode*>(&RN);
+  }
+};
+
+class MachineRegion : public RegionBase<RegionTraits<MachineFunction>> {
+public:
+  MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,
+                MachineRegionInfo* RI,
+                MachineDominatorTree *DT, MachineRegion *Parent = nullptr);
+  ~MachineRegion();
+
+  bool operator==(const MachineRegionNode &RN) const {
+    return &RN == reinterpret_cast<const MachineRegionNode*>(this);
+  }
+};
+
+class MachineRegionInfo : public RegionInfoBase<RegionTraits<MachineFunction>> {
+public:
+  explicit MachineRegionInfo();
+
+  virtual ~MachineRegionInfo();
+
+  // updateStatistics - Update statistic about created regions.
+  void updateStatistics(MachineRegion *R) final;
+
+  void recalculate(MachineFunction &F,
+                   MachineDominatorTree *DT,
+                   MachinePostDominatorTree *PDT,
+                   MachineDominanceFrontier *DF);
+};
+
+class MachineRegionInfoPass : public MachineFunctionPass {
+  MachineRegionInfo RI;
+
+public:
+  static char ID;
+  explicit MachineRegionInfoPass();
+
+  ~MachineRegionInfoPass();
+
+  MachineRegionInfo &getRegionInfo() {
+    return RI;
+  }
+
+  const MachineRegionInfo &getRegionInfo() const {
+    return RI;
+  }
+
+  /// @name MachineFunctionPass interface
+  //@{
+  bool runOnMachineFunction(MachineFunction &F) override;
+  void releaseMemory() override;
+  void verifyAnalysis() const override;
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+  void print(raw_ostream &OS, const Module *) const override;
+  void dump() const;
+  //@}
+};
+
+
+template <>
+template <>
+inline MachineBasicBlock* RegionNodeBase<RegionTraits<MachineFunction>>::getNodeAs<MachineBasicBlock>() const {
+  assert(!isSubRegion() && "This is not a MachineBasicBlock RegionNode!");
+  return getEntry();
+}
+
+template<>
+template<>
+inline MachineRegion* RegionNodeBase<RegionTraits<MachineFunction>>::getNodeAs<MachineRegion>() const {
+  assert(isSubRegion() && "This is not a subregion RegionNode!");
+  auto Unconst = const_cast<RegionNodeBase<RegionTraits<MachineFunction>>*>(this);
+  return reinterpret_cast<MachineRegion*>(Unconst);
+}
+
+
+RegionNodeGraphTraits(MachineRegionNode, MachineBasicBlock, MachineRegion);
+RegionNodeGraphTraits(const MachineRegionNode, MachineBasicBlock, MachineRegion);
+
+RegionGraphTraits(MachineRegion, MachineRegionNode);
+RegionGraphTraits(const MachineRegion, const MachineRegionNode);
+
+template <> struct GraphTraits<MachineRegionInfo*>
+  : public GraphTraits<FlatIt<MachineRegionNode*> > {
+  typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false,
+                      GraphTraits<FlatIt<NodeType*> > > nodes_iterator;
+
+  static NodeType *getEntryNode(MachineRegionInfo *RI) {
+    return GraphTraits<FlatIt<MachineRegion*> >::getEntryNode(RI->getTopLevelRegion());
+  }
+  static nodes_iterator nodes_begin(MachineRegionInfo* RI) {
+    return nodes_iterator::begin(getEntryNode(RI));
+  }
+  static nodes_iterator nodes_end(MachineRegionInfo *RI) {
+    return nodes_iterator::end(getEntryNode(RI));
+  }
+};
+
+template <> struct GraphTraits<MachineRegionInfoPass*>
+  : public GraphTraits<MachineRegionInfo *> {
+  typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false,
+                      GraphTraits<FlatIt<NodeType*> > > nodes_iterator;
+
+  static NodeType *getEntryNode(MachineRegionInfoPass *RI) {
+    return GraphTraits<MachineRegionInfo*>::getEntryNode(&RI->getRegionInfo());
+  }
+  static nodes_iterator nodes_begin(MachineRegionInfoPass* RI) {
+    return GraphTraits<MachineRegionInfo*>::nodes_begin(&RI->getRegionInfo());
+  }
+  static nodes_iterator nodes_end(MachineRegionInfoPass *RI) {
+    return GraphTraits<MachineRegionInfo*>::nodes_end(&RI->getRegionInfo());
+  }
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class RegionBase<RegionTraits<MachineFunction>>);
+EXTERN_TEMPLATE_INSTANTIATION(class RegionNodeBase<RegionTraits<MachineFunction>>);
+EXTERN_TEMPLATE_INSTANTIATION(class RegionInfoBase<RegionTraits<MachineFunction>>);
+
+}
+
+#endif

Modified: llvm/trunk/include/llvm/InitializePasses.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=213456&r1=213455&r2=213456&view=diff
==============================================================================
--- llvm/trunk/include/llvm/InitializePasses.h (original)
+++ llvm/trunk/include/llvm/InitializePasses.h Sat Jul 19 13:29:29 2014
@@ -189,6 +189,7 @@ void initializeMachinePostDominatorTreeP
 void initializeMachineLICMPass(PassRegistry&);
 void initializeMachineLoopInfoPass(PassRegistry&);
 void initializeMachineModuleInfoPass(PassRegistry&);
+void initializeMachineRegionInfoPassPass(PassRegistry&);
 void initializeMachineSchedulerPass(PassRegistry&);
 void initializeMachineSinkingPass(PassRegistry&);
 void initializeMachineTraceMetricsPass(PassRegistry&);
@@ -227,7 +228,7 @@ void initializePromotePassPass(PassRegis
 void initializePruneEHPass(PassRegistry&);
 void initializeReassociatePass(PassRegistry&);
 void initializeRegToMemPass(PassRegistry&);
-void initializeRegionInfoPass(PassRegistry&);
+void initializeRegionInfoPassPass(PassRegistry&);
 void initializeRegionOnlyPrinterPass(PassRegistry&);
 void initializeRegionOnlyViewerPass(PassRegistry&);
 void initializeRegionPrinterPass(PassRegistry&);

Modified: llvm/trunk/lib/Analysis/Analysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Analysis.cpp?rev=213456&r1=213455&r2=213456&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/Analysis.cpp (original)
+++ llvm/trunk/lib/Analysis/Analysis.cpp Sat Jul 19 13:29:29 2014
@@ -57,7 +57,7 @@ void llvm::initializeAnalysis(PassRegist
   initializeMemoryDependenceAnalysisPass(Registry);
   initializeModuleDebugInfoPrinterPass(Registry);
   initializePostDominatorTreePass(Registry);
-  initializeRegionInfoPass(Registry);
+  initializeRegionInfoPassPass(Registry);
   initializeRegionViewerPass(Registry);
   initializeRegionPrinterPass(Registry);
   initializeRegionOnlyViewerPass(Registry);

Modified: llvm/trunk/lib/Analysis/RegionInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/RegionInfo.cpp?rev=213456&r1=213455&r2=213456&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/RegionInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/RegionInfo.cpp Sat Jul 19 13:29:29 2014
@@ -10,6 +10,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Analysis/RegionInfo.h"
+#include "llvm/Analysis/RegionInfoImpl.h"
 #include "llvm/ADT/PostOrderIterator.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Analysis/LoopInfo.h"
@@ -25,21 +26,26 @@ using namespace llvm;
 
 #define DEBUG_TYPE "region"
 
+namespace llvm {
+template class RegionBase<RegionTraits<Function>>;
+template class RegionNodeBase<RegionTraits<Function>>;
+template class RegionInfoBase<RegionTraits<Function>>;
+}
+
+STATISTIC(numRegions,       "The # of regions");
+STATISTIC(numSimpleRegions, "The # of simple regions");
+
 // Always verify if expensive checking is enabled.
-#ifdef XDEBUG
-static bool VerifyRegionInfo = true;
-#else
-static bool VerifyRegionInfo = false;
-#endif
 
 static cl::opt<bool,true>
-VerifyRegionInfoX("verify-region-info", cl::location(VerifyRegionInfo),
-                cl::desc("Verify region info (time consuming)"));
+VerifyRegionInfoX(
+  "verify-region-info",
+  cl::location(RegionInfoBase<RegionTraits<Function>>::VerifyRegionInfo),
+  cl::desc("Verify region info (time consuming)"));
 
-STATISTIC(numRegions,       "The # of regions");
-STATISTIC(numSimpleRegions, "The # of simple regions");
 
-static cl::opt<enum Region::PrintStyle> printStyle("print-region-style",
+static cl::opt<Region::PrintStyle, true> printStyleX("print-region-style",
+  cl::location(RegionInfo::printStyle),
   cl::Hidden,
   cl::desc("style of printing regions"),
   cl::values(
@@ -49,812 +55,110 @@ static cl::opt<enum Region::PrintStyle>
     clEnumValN(Region::PrintRN, "rn",
                "print regions in detail with element_iterator"),
     clEnumValEnd));
-//===----------------------------------------------------------------------===//
-/// Region Implementation
-Region::Region(BasicBlock *Entry, BasicBlock *Exit, RegionInfo* RInfo,
-               DominatorTree *dt, Region *Parent)
-               : RegionNode(Parent, Entry, 1), RI(RInfo), DT(dt), exit(Exit) {}
-
-Region::~Region() {
-  // Free the cached nodes.
-  for (BBNodeMapT::iterator it = BBNodeMap.begin(),
-         ie = BBNodeMap.end(); it != ie; ++it)
-    delete it->second;
-
-  // Only clean the cache for this Region. Caches of child Regions will be
-  // cleaned when the child Regions are deleted.
-  BBNodeMap.clear();
-}
-
-void Region::replaceEntry(BasicBlock *BB) {
-  entry.setPointer(BB);
-}
-
-void Region::replaceExit(BasicBlock *BB) {
-  assert(exit && "No exit to replace!");
-  exit = BB;
-}
-
-void Region::replaceEntryRecursive(BasicBlock *NewEntry) {
-  std::vector<Region *> RegionQueue;
-  BasicBlock *OldEntry = getEntry();
-
-  RegionQueue.push_back(this);
-  while (!RegionQueue.empty()) {
-    Region *R = RegionQueue.back();
-    RegionQueue.pop_back();
-
-    R->replaceEntry(NewEntry);
-    for (Region::const_iterator RI = R->begin(), RE = R->end(); RI != RE; ++RI)
-      if ((*RI)->getEntry() == OldEntry)
-        RegionQueue.push_back(RI->get());
-  }
-}
-
-void Region::replaceExitRecursive(BasicBlock *NewExit) {
-  std::vector<Region *> RegionQueue;
-  BasicBlock *OldExit = getExit();
-
-  RegionQueue.push_back(this);
-  while (!RegionQueue.empty()) {
-    Region *R = RegionQueue.back();
-    RegionQueue.pop_back();
-
-    R->replaceExit(NewExit);
-    for (Region::const_iterator RI = R->begin(), RE = R->end(); RI != RE; ++RI)
-      if ((*RI)->getExit() == OldExit)
-        RegionQueue.push_back(RI->get());
-  }
-}
-
-bool Region::contains(const BasicBlock *B) const {
-  BasicBlock *BB = const_cast<BasicBlock*>(B);
-
-  if (!DT->getNode(BB))
-    return false;
-
-  BasicBlock *entry = getEntry(), *exit = getExit();
-
-  // Toplevel region.
-  if (!exit)
-    return true;
-
-  return (DT->dominates(entry, BB)
-    && !(DT->dominates(exit, BB) && DT->dominates(entry, exit)));
-}
-
-bool Region::contains(const Loop *L) const {
-  // BBs that are not part of any loop are element of the Loop
-  // described by the NULL pointer. This loop is not part of any region,
-  // except if the region describes the whole function.
-  if (!L)
-    return getExit() == nullptr;
-
-  if (!contains(L->getHeader()))
-    return false;
-
-  SmallVector<BasicBlock *, 8> ExitingBlocks;
-  L->getExitingBlocks(ExitingBlocks);
-
-  for (SmallVectorImpl<BasicBlock*>::iterator BI = ExitingBlocks.begin(),
-       BE = ExitingBlocks.end(); BI != BE; ++BI)
-    if (!contains(*BI))
-      return false;
-
-  return true;
-}
-
-Loop *Region::outermostLoopInRegion(Loop *L) const {
-  if (!contains(L))
-    return nullptr;
-
-  while (L && contains(L->getParentLoop())) {
-    L = L->getParentLoop();
-  }
-
-  return L;
-}
-
-Loop *Region::outermostLoopInRegion(LoopInfo *LI, BasicBlock* BB) const {
-  assert(LI && BB && "LI and BB cannot be null!");
-  Loop *L = LI->getLoopFor(BB);
-  return outermostLoopInRegion(L);
-}
-
-BasicBlock *Region::getEnteringBlock() const {
-  BasicBlock *entry = getEntry();
-  BasicBlock *Pred;
-  BasicBlock *enteringBlock = nullptr;
-
-  for (pred_iterator PI = pred_begin(entry), PE = pred_end(entry); PI != PE;
-       ++PI) {
-    Pred = *PI;
-    if (DT->getNode(Pred) && !contains(Pred)) {
-      if (enteringBlock)
-        return nullptr;
-
-      enteringBlock = Pred;
-    }
-  }
-
-  return enteringBlock;
-}
-
-BasicBlock *Region::getExitingBlock() const {
-  BasicBlock *exit = getExit();
-  BasicBlock *Pred;
-  BasicBlock *exitingBlock = nullptr;
-
-  if (!exit)
-    return nullptr;
-
-  for (pred_iterator PI = pred_begin(exit), PE = pred_end(exit); PI != PE;
-       ++PI) {
-    Pred = *PI;
-    if (contains(Pred)) {
-      if (exitingBlock)
-        return nullptr;
-
-      exitingBlock = Pred;
-    }
-  }
-
-  return exitingBlock;
-}
-
-bool Region::isSimple() const {
-  return !isTopLevelRegion() && getEnteringBlock() && getExitingBlock();
-}
-
-std::string Region::getNameStr() const {
-  std::string exitName;
-  std::string entryName;
-
-  if (getEntry()->getName().empty()) {
-    raw_string_ostream OS(entryName);
-
-    getEntry()->printAsOperand(OS, false);
-  } else
-    entryName = getEntry()->getName();
-
-  if (getExit()) {
-    if (getExit()->getName().empty()) {
-      raw_string_ostream OS(exitName);
-
-      getExit()->printAsOperand(OS, false);
-    } else
-      exitName = getExit()->getName();
-  } else
-    exitName = "<Function Return>";
-
-  return entryName + " => " + exitName;
-}
-
-void Region::verifyBBInRegion(BasicBlock *BB) const {
-  if (!contains(BB))
-    llvm_unreachable("Broken region found!");
-
-  BasicBlock *entry = getEntry(), *exit = getExit();
-
-  for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
-    if (!contains(*SI) && exit != *SI)
-      llvm_unreachable("Broken region found!");
-
-  if (entry != BB)
-    for (pred_iterator SI = pred_begin(BB), SE = pred_end(BB); SI != SE; ++SI)
-      if (!contains(*SI))
-        llvm_unreachable("Broken region found!");
-}
-
-void Region::verifyWalk(BasicBlock *BB, std::set<BasicBlock*> *visited) const {
-  BasicBlock *exit = getExit();
-
-  visited->insert(BB);
-
-  verifyBBInRegion(BB);
-
-  for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
-    if (*SI != exit && visited->find(*SI) == visited->end())
-        verifyWalk(*SI, visited);
-}
-
-void Region::verifyRegion() const {
-  // Only do verification when user wants to, otherwise this expensive
-  // check will be invoked by PassManager.
-  if (!VerifyRegionInfo) return;
-
-  std::set<BasicBlock*> visited;
-  verifyWalk(getEntry(), &visited);
-}
-
-void Region::verifyRegionNest() const {
-  for (Region::const_iterator RI = begin(), RE = end(); RI != RE; ++RI)
-    (*RI)->verifyRegionNest();
-
-  verifyRegion();
-}
-
-Region::element_iterator Region::element_begin() {
-  return GraphTraits<Region*>::nodes_begin(this);
-}
-
-Region::element_iterator Region::element_end() {
-  return GraphTraits<Region*>::nodes_end(this);
-}
-
-Region::const_element_iterator Region::element_begin() const {
-  return GraphTraits<const Region*>::nodes_begin(this);
-}
-
-Region::const_element_iterator Region::element_end() const {
-  return GraphTraits<const Region*>::nodes_end(this);
-}
-
-Region* Region::getSubRegionNode(BasicBlock *BB) const {
-  Region *R = RI->getRegionFor(BB);
-
-  if (!R || R == this)
-    return nullptr;
-
-  // If we pass the BB out of this region, that means our code is broken.
-  assert(contains(R) && "BB not in current region!");
-
-  while (contains(R->getParent()) && R->getParent() != this)
-    R = R->getParent();
-
-  if (R->getEntry() != BB)
-    return nullptr;
-
-  return R;
-}
-
-RegionNode* Region::getBBNode(BasicBlock *BB) const {
-  assert(contains(BB) && "Can get BB node out of this region!");
-
-  BBNodeMapT::const_iterator at = BBNodeMap.find(BB);
-
-  if (at != BBNodeMap.end())
-    return at->second;
-
-  RegionNode *NewNode = new RegionNode(const_cast<Region*>(this), BB);
-  BBNodeMap.insert(std::make_pair(BB, NewNode));
-  return NewNode;
-}
-
-RegionNode* Region::getNode(BasicBlock *BB) const {
-  assert(contains(BB) && "Can get BB node out of this region!");
-  if (Region* Child = getSubRegionNode(BB))
-    return Child->getNode();
-
-  return getBBNode(BB);
-}
-
-void Region::transferChildrenTo(Region *To) {
-  for (iterator I = begin(), E = end(); I != E; ++I) {
-    (*I)->parent = To;
-    To->children.push_back(std::move(*I));
-  }
-  children.clear();
-}
-
-void Region::addSubRegion(Region *SubRegion, bool moveChildren) {
-  assert(!SubRegion->parent && "SubRegion already has a parent!");
-  assert(std::find_if(begin(), end(), [&](const std::unique_ptr<Region> &R) {
-           return R.get() == SubRegion;
-         }) == children.end() &&
-         "Subregion already exists!");
-
-  SubRegion->parent = this;
-  children.push_back(std::unique_ptr<Region>(SubRegion));
-
-  if (!moveChildren)
-    return;
-
-  assert(SubRegion->children.size() == 0
-         && "SubRegions that contain children are not supported");
-
-  for (element_iterator I = element_begin(), E = element_end(); I != E; ++I)
-    if (!(*I)->isSubRegion()) {
-      BasicBlock *BB = (*I)->getNodeAs<BasicBlock>();
-
-      if (SubRegion->contains(BB))
-        RI->setRegionFor(BB, SubRegion);
-    }
-
-  std::vector<std::unique_ptr<Region>> Keep;
-  for (iterator I = begin(), E = end(); I != E; ++I)
-    if (SubRegion->contains(I->get()) && I->get() != SubRegion) {
-      (*I)->parent = SubRegion;
-      SubRegion->children.push_back(std::move(*I));
-    } else
-      Keep.push_back(std::move(*I));
-
-  children.clear();
-  children.insert(children.begin(),
-                  std::move_iterator<RegionSet::iterator>(Keep.begin()),
-                  std::move_iterator<RegionSet::iterator>(Keep.end()));
-}
 
 
-Region *Region::removeSubRegion(Region *Child) {
-  assert(Child->parent == this && "Child is not a child of this region!");
-  Child->parent = nullptr;
-  RegionSet::iterator I = std::find_if(
-      children.begin(), children.end(),
-      [&](const std::unique_ptr<Region> &R) { return R.get() == Child; });
-  assert(I != children.end() && "Region does not exit. Unable to remove.");
-  children.erase(children.begin()+(I-begin()));
-  return Child;
-}
-
-unsigned Region::getDepth() const {
-  unsigned Depth = 0;
-
-  for (Region *R = parent; R != nullptr; R = R->parent)
-    ++Depth;
-
-  return Depth;
-}
-
-Region *Region::getExpandedRegion() const {
-  unsigned NumSuccessors = exit->getTerminator()->getNumSuccessors();
-
-  if (NumSuccessors == 0)
-    return nullptr;
-
-  for (pred_iterator PI = pred_begin(getExit()), PE = pred_end(getExit());
-       PI != PE; ++PI)
-    if (!DT->dominates(getEntry(), *PI))
-      return nullptr;
-
-  Region *R = RI->getRegionFor(exit);
-
-  if (R->getEntry() != exit) {
-    if (exit->getTerminator()->getNumSuccessors() == 1)
-      return new Region(getEntry(), *succ_begin(exit), RI, DT);
-    else
-      return nullptr;
-  }
-
-  while (R->getParent() && R->getParent()->getEntry() == exit)
-    R = R->getParent();
-
-  if (!DT->dominates(getEntry(), R->getExit()))
-    for (pred_iterator PI = pred_begin(getExit()), PE = pred_end(getExit());
-         PI != PE; ++PI)
-    if (!DT->dominates(R->getExit(), *PI))
-      return nullptr;
-
-  return new Region(getEntry(), R->getExit(), RI, DT);
-}
-
-void Region::print(raw_ostream &OS, bool print_tree, unsigned level,
-                   enum PrintStyle Style) const {
-  if (print_tree)
-    OS.indent(level*2) << "[" << level << "] " << getNameStr();
-  else
-    OS.indent(level*2) << getNameStr();
-
-  OS << "\n";
-
-
-  if (Style != PrintNone) {
-    OS.indent(level*2) << "{\n";
-    OS.indent(level*2 + 2);
-
-    if (Style == PrintBB) {
-      for (const auto &BB : blocks())
-        OS << BB->getName() << ", "; // TODO: remove the last ","
-    } else if (Style == PrintRN) {
-      for (const_element_iterator I = element_begin(), E = element_end(); I!=E; ++I)
-        OS << **I << ", "; // TODO: remove the last ",
-    }
-
-    OS << "\n";
-  }
-
-  if (print_tree)
-    for (const_iterator RI = begin(), RE = end(); RI != RE; ++RI)
-      (*RI)->print(OS, print_tree, level+1, Style);
+//===----------------------------------------------------------------------===//
+// Region implementation
+//
 
-  if (Style != PrintNone)
-    OS.indent(level*2) << "} \n";
-}
+Region::Region(BasicBlock *Entry, BasicBlock *Exit,
+               RegionInfo* RI,
+               DominatorTree *DT, Region *Parent) :
+  RegionBase<RegionTraits<Function>>(Entry, Exit, RI, DT, Parent) {
 
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-void Region::dump() const {
-  print(dbgs(), true, getDepth(), printStyle.getValue());
 }
-#endif
 
-void Region::clearNodeCache() {
-  // Free the cached nodes.
-  for (BBNodeMapT::iterator I = BBNodeMap.begin(),
-       IE = BBNodeMap.end(); I != IE; ++I)
-    delete I->second;
-
-  BBNodeMap.clear();
-  for (Region::iterator RI = begin(), RE = end(); RI != RE; ++RI)
-    (*RI)->clearNodeCache();
-}
+Region::~Region() { }
 
 //===----------------------------------------------------------------------===//
 // RegionInfo implementation
 //
 
-bool RegionInfo::isCommonDomFrontier(BasicBlock *BB, BasicBlock *entry,
-                                     BasicBlock *exit) const {
-  for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) {
-    BasicBlock *P = *PI;
-    if (DT->dominates(entry, P) && !DT->dominates(exit, P))
-      return false;
-  }
-  return true;
-}
-
-bool RegionInfo::isRegion(BasicBlock *entry, BasicBlock *exit) const {
-  assert(entry && exit && "entry and exit must not be null!");
-  typedef DominanceFrontier::DomSetType DST;
-
-  DST *entrySuccs = &DF->find(entry)->second;
-
-  // Exit is the header of a loop that contains the entry. In this case,
-  // the dominance frontier must only contain the exit.
-  if (!DT->dominates(entry, exit)) {
-    for (DST::iterator SI = entrySuccs->begin(), SE = entrySuccs->end();
-         SI != SE; ++SI)
-      if (*SI != exit && *SI != entry)
-        return false;
-
-    return true;
-  }
-
-  DST *exitSuccs = &DF->find(exit)->second;
-
-  // Do not allow edges leaving the region.
-  for (DST::iterator SI = entrySuccs->begin(), SE = entrySuccs->end();
-       SI != SE; ++SI) {
-    if (*SI == exit || *SI == entry)
-      continue;
-    if (exitSuccs->find(*SI) == exitSuccs->end())
-      return false;
-    if (!isCommonDomFrontier(*SI, entry, exit))
-      return false;
-  }
-
-  // Do not allow edges pointing into the region.
-  for (DST::iterator SI = exitSuccs->begin(), SE = exitSuccs->end();
-       SI != SE; ++SI)
-    if (DT->properlyDominates(entry, *SI) && *SI != exit)
-      return false;
-
-
-  return true;
-}
-
-void RegionInfo::insertShortCut(BasicBlock *entry, BasicBlock *exit,
-                             BBtoBBMap *ShortCut) const {
-  assert(entry && exit && "entry and exit must not be null!");
-
-  BBtoBBMap::iterator e = ShortCut->find(exit);
-
-  if (e == ShortCut->end())
-    // No further region at exit available.
-    (*ShortCut)[entry] = exit;
-  else {
-    // We found a region e that starts at exit. Therefore (entry, e->second)
-    // is also a region, that is larger than (entry, exit). Insert the
-    // larger one.
-    BasicBlock *BB = e->second;
-    (*ShortCut)[entry] = BB;
-  }
-}
-
-DomTreeNode* RegionInfo::getNextPostDom(DomTreeNode* N,
-                                        BBtoBBMap *ShortCut) const {
-  BBtoBBMap::iterator e = ShortCut->find(N->getBlock());
-
-  if (e == ShortCut->end())
-    return N->getIDom();
+RegionInfo::RegionInfo() :
+  RegionInfoBase<RegionTraits<Function>>() {
 
-  return PDT->getNode(e->second)->getIDom();
 }
 
-bool RegionInfo::isTrivialRegion(BasicBlock *entry, BasicBlock *exit) const {
-  assert(entry && exit && "entry and exit must not be null!");
-
-  unsigned num_successors = succ_end(entry) - succ_begin(entry);
-
-  if (num_successors <= 1 && exit == *(succ_begin(entry)))
-    return true;
+RegionInfo::~RegionInfo() {
 
-  return false;
 }
 
 void RegionInfo::updateStatistics(Region *R) {
   ++numRegions;
 
   // TODO: Slow. Should only be enabled if -stats is used.
-  if (R->isSimple()) ++numSimpleRegions;
+  if (R->isSimple())
+    ++numSimpleRegions;
 }
 
-Region *RegionInfo::createRegion(BasicBlock *entry, BasicBlock *exit) {
-  assert(entry && exit && "entry and exit must not be null!");
-
-  if (isTrivialRegion(entry, exit))
-    return nullptr;
-
-  Region *region = new Region(entry, exit, this, DT);
-  BBtoRegion.insert(std::make_pair(entry, region));
-
- #ifdef XDEBUG
-    region->verifyRegion();
- #else
-    DEBUG(region->verifyRegion());
- #endif
+void RegionInfo::RegionInfo::recalculate(Function &F,
+                                         DominatorTree *DT_,
+                                         PostDominatorTree *PDT_,
+                                         DominanceFrontier *DF_) {
+  DT = DT_;
+  PDT = PDT_;
+  DF = DF_;
 
-  updateStatistics(region);
-  return region;
+  TopLevelRegion = new Region(&F.getEntryBlock(), nullptr,
+                              this, DT, nullptr);
+  updateStatistics(TopLevelRegion);
+  calculate(F);
 }
 
-void RegionInfo::findRegionsWithEntry(BasicBlock *entry, BBtoBBMap *ShortCut) {
-  assert(entry);
-
-  DomTreeNode *N = PDT->getNode(entry);
-
-  if (!N)
-    return;
-
-  Region *lastRegion= nullptr;
-  BasicBlock *lastExit = entry;
-
-  // As only a BasicBlock that postdominates entry can finish a region, walk the
-  // post dominance tree upwards.
-  while ((N = getNextPostDom(N, ShortCut))) {
-    BasicBlock *exit = N->getBlock();
-
-    if (!exit)
-      break;
-
-    if (isRegion(entry, exit)) {
-      Region *newRegion = createRegion(entry, exit);
-
-      if (lastRegion)
-        newRegion->addSubRegion(lastRegion);
-
-      lastRegion = newRegion;
-      lastExit = exit;
-    }
-
-    // This can never be a region, so stop the search.
-    if (!DT->dominates(entry, exit))
-      break;
-  }
+//===----------------------------------------------------------------------===//
+// RegionInfoPass implementation
+//
 
-  // Tried to create regions from entry to lastExit.  Next time take a
-  // shortcut from entry to lastExit.
-  if (lastExit != entry)
-    insertShortCut(entry, lastExit, ShortCut);
-}
-
-void RegionInfo::scanForRegions(Function &F, BBtoBBMap *ShortCut) {
-  BasicBlock *entry = &(F.getEntryBlock());
-  DomTreeNode *N = DT->getNode(entry);
-
-  // Iterate over the dominance tree in post order to start with the small
-  // regions from the bottom of the dominance tree.  If the small regions are
-  // detected first, detection of bigger regions is faster, as we can jump
-  // over the small regions.
-  for (po_iterator<DomTreeNode*> FI = po_begin(N), FE = po_end(N); FI != FE;
-    ++FI) {
-    findRegionsWithEntry(FI->getBlock(), ShortCut);
-  }
+RegionInfoPass::RegionInfoPass() : FunctionPass(ID) {
+  initializeRegionInfoPassPass(*PassRegistry::getPassRegistry());
 }
 
-Region *RegionInfo::getTopMostParent(Region *region) {
-  while (region->parent)
-    region = region->getParent();
-
-  return region;
-}
-
-void RegionInfo::buildRegionsTree(DomTreeNode *N, Region *region) {
-  BasicBlock *BB = N->getBlock();
-
-  // Passed region exit
-  while (BB == region->getExit())
-    region = region->getParent();
-
-  BBtoRegionMap::iterator it = BBtoRegion.find(BB);
-
-  // This basic block is a start block of a region. It is already in the
-  // BBtoRegion relation. Only the child basic blocks have to be updated.
-  if (it != BBtoRegion.end()) {
-    Region *newRegion = it->second;
-    region->addSubRegion(getTopMostParent(newRegion));
-    region = newRegion;
-  } else {
-    BBtoRegion[BB] = region;
-  }
+RegionInfoPass::~RegionInfoPass() {
 
-  for (DomTreeNode::iterator CI = N->begin(), CE = N->end(); CI != CE; ++CI)
-    buildRegionsTree(*CI, region);
 }
 
-void RegionInfo::releaseMemory() {
-  BBtoRegion.clear();
-  if (TopLevelRegion)
-    delete TopLevelRegion;
-  TopLevelRegion = nullptr;
-}
+bool RegionInfoPass::runOnFunction(Function &F) {
+  releaseMemory();
 
-RegionInfo::RegionInfo() : FunctionPass(ID) {
-  initializeRegionInfoPass(*PassRegistry::getPassRegistry());
-  TopLevelRegion = nullptr;
-}
+  auto DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+  auto PDT = &getAnalysis<PostDominatorTree>();
+  auto DF = &getAnalysis<DominanceFrontier>();
 
-RegionInfo::~RegionInfo() {
-  releaseMemory();
+  RI.recalculate(F, DT, PDT, DF);
+  return false;
 }
 
-void RegionInfo::Calculate(Function &F) {
-  // ShortCut a function where for every BB the exit of the largest region
-  // starting with BB is stored. These regions can be threated as single BBS.
-  // This improves performance on linear CFGs.
-  BBtoBBMap ShortCut;
-
-  scanForRegions(F, &ShortCut);
-  BasicBlock *BB = &F.getEntryBlock();
-  buildRegionsTree(DT->getNode(BB), TopLevelRegion);
+void RegionInfoPass::releaseMemory() {
+  RI.releaseMemory();
 }
 
-bool RegionInfo::runOnFunction(Function &F) {
-  releaseMemory();
-
-  DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
-  PDT = &getAnalysis<PostDominatorTree>();
-  DF = &getAnalysis<DominanceFrontier>();
-
-  TopLevelRegion = new Region(&F.getEntryBlock(), nullptr, this, DT, nullptr);
-  updateStatistics(TopLevelRegion);
-
-  Calculate(F);
-
-  return false;
+void RegionInfoPass::verifyAnalysis() const {
+    RI.verifyAnalysis();
 }
 
-void RegionInfo::getAnalysisUsage(AnalysisUsage &AU) const {
+void RegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.setPreservesAll();
   AU.addRequiredTransitive<DominatorTreeWrapperPass>();
   AU.addRequired<PostDominatorTree>();
   AU.addRequired<DominanceFrontier>();
 }
 
-void RegionInfo::print(raw_ostream &OS, const Module *) const {
-  OS << "Region tree:\n";
-  TopLevelRegion->print(OS, true, 0, printStyle.getValue());
-  OS << "End region tree\n";
-}
-
-void RegionInfo::verifyAnalysis() const {
-  // Only do verification when user wants to, otherwise this expensive check
-  // will be invoked by PMDataManager::verifyPreservedAnalysis when
-  // a regionpass (marked PreservedAll) finish.
-  if (!VerifyRegionInfo) return;
-
-  TopLevelRegion->verifyRegionNest();
-}
-
-// Region pass manager support.
-Region *RegionInfo::getRegionFor(BasicBlock *BB) const {
-  BBtoRegionMap::const_iterator I=
-    BBtoRegion.find(BB);
-  return I != BBtoRegion.end() ? I->second : nullptr;
-}
-
-void RegionInfo::setRegionFor(BasicBlock *BB, Region *R) {
-  BBtoRegion[BB] = R;
+void RegionInfoPass::print(raw_ostream &OS, const Module *) const {
+  RI.print(OS);
 }
 
-Region *RegionInfo::operator[](BasicBlock *BB) const {
-  return getRegionFor(BB);
+void RegionInfoPass::dump() const {
+  RI.dump();
 }
 
-BasicBlock *RegionInfo::getMaxRegionExit(BasicBlock *BB) const {
-  BasicBlock *Exit = nullptr;
-
-  while (true) {
-    // Get largest region that starts at BB.
-    Region *R = getRegionFor(BB);
-    while (R && R->getParent() && R->getParent()->getEntry() == BB)
-      R = R->getParent();
-
-    // Get the single exit of BB.
-    if (R && R->getEntry() == BB)
-      Exit = R->getExit();
-    else if (++succ_begin(BB) == succ_end(BB))
-      Exit = *succ_begin(BB);
-    else // No single exit exists.
-      return Exit;
-
-    // Get largest region that starts at Exit.
-    Region *ExitR = getRegionFor(Exit);
-    while (ExitR && ExitR->getParent()
-           && ExitR->getParent()->getEntry() == Exit)
-      ExitR = ExitR->getParent();
-
-    for (pred_iterator PI = pred_begin(Exit), PE = pred_end(Exit); PI != PE;
-         ++PI)
-      if (!R->contains(*PI) && !ExitR->contains(*PI))
-        break;
-
-    // This stops infinite cycles.
-    if (DT->dominates(Exit, BB))
-      break;
-
-    BB = Exit;
-  }
-
-  return Exit;
-}
-
-Region*
-RegionInfo::getCommonRegion(Region *A, Region *B) const {
-  assert (A && B && "One of the Regions is NULL");
-
-  if (A->contains(B)) return A;
-
-  while (!B->contains(A))
-    B = B->getParent();
-
-  return B;
-}
-
-Region*
-RegionInfo::getCommonRegion(SmallVectorImpl<Region*> &Regions) const {
-  Region* ret = Regions.back();
-  Regions.pop_back();
-
-  for (SmallVectorImpl<Region*>::const_iterator I = Regions.begin(),
-       E = Regions.end(); I != E; ++I)
-      ret = getCommonRegion(ret, *I);
-
-  return ret;
-}
-
-Region*
-RegionInfo::getCommonRegion(SmallVectorImpl<BasicBlock*> &BBs) const {
-  Region* ret = getRegionFor(BBs.back());
-  BBs.pop_back();
-
-  for (SmallVectorImpl<BasicBlock*>::const_iterator I = BBs.begin(),
-       E = BBs.end(); I != E; ++I)
-      ret = getCommonRegion(ret, getRegionFor(*I));
-
-  return ret;
-}
-
-void RegionInfo::splitBlock(BasicBlock* NewBB, BasicBlock *OldBB)
-{
-  Region *R = getRegionFor(OldBB);
-
-  setRegionFor(NewBB, R);
-
-  while (R->getEntry() == OldBB && !R->isTopLevelRegion()) {
-    R->replaceEntry(NewBB);
-    R = R->getParent();
-  }
-
-  setRegionFor(OldBB, R);
-}
+char RegionInfoPass::ID = 0;
 
-char RegionInfo::ID = 0;
-INITIALIZE_PASS_BEGIN(RegionInfo, "regions",
+INITIALIZE_PASS_BEGIN(RegionInfoPass, "regions",
                 "Detect single entry single exit regions", true, true)
 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(PostDominatorTree)
 INITIALIZE_PASS_DEPENDENCY(DominanceFrontier)
-INITIALIZE_PASS_END(RegionInfo, "regions",
+INITIALIZE_PASS_END(RegionInfoPass, "regions",
                 "Detect single entry single exit regions", true, true)
 
 // Create methods available outside of this file, to use them
@@ -863,7 +167,7 @@ INITIALIZE_PASS_END(RegionInfo, "regions
 
 namespace llvm {
   FunctionPass *createRegionInfoPass() {
-    return new RegionInfo();
+    return new RegionInfoPass();
   }
 }
 

Modified: llvm/trunk/lib/Analysis/RegionPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/RegionPass.cpp?rev=213456&r1=213455&r2=213456&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/RegionPass.cpp (original)
+++ llvm/trunk/lib/Analysis/RegionPass.cpp Sat Jul 19 13:29:29 2014
@@ -45,14 +45,14 @@ static void addRegionIntoQueue(Region &R
 
 /// Pass Manager itself does not invalidate any analysis info.
 void RGPassManager::getAnalysisUsage(AnalysisUsage &Info) const {
-  Info.addRequired<RegionInfo>();
+  Info.addRequired<RegionInfoPass>();
   Info.setPreservesAll();
 }
 
 /// run - Execute all of the passes scheduled for execution.  Keep track of
 /// whether any of the passes modifies the function, and if so, return true.
 bool RGPassManager::runOnFunction(Function &F) {
-  RI = &getAnalysis<RegionInfo>();
+  RI = &getAnalysis<RegionInfoPass>().getRegionInfo();
   bool Changed = false;
 
   // Collect inherited analysis from Module level pass manager.

Modified: llvm/trunk/lib/Analysis/RegionPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/RegionPrinter.cpp?rev=213456&r1=213455&r2=213456&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/RegionPrinter.cpp (original)
+++ llvm/trunk/lib/Analysis/RegionPrinter.cpp Sat Jul 19 13:29:29 2014
@@ -56,23 +56,24 @@ struct DOTGraphTraits<RegionNode*> : pub
 };
 
 template<>
-struct DOTGraphTraits<RegionInfo*> : public DOTGraphTraits<RegionNode*> {
+struct DOTGraphTraits<RegionInfoPass*> : public DOTGraphTraits<RegionNode*> {
 
-  DOTGraphTraits (bool isSimple=false)
+  DOTGraphTraits (bool isSimple = false)
     : DOTGraphTraits<RegionNode*>(isSimple) {}
 
-  static std::string getGraphName(RegionInfo *DT) {
+  static std::string getGraphName(RegionInfoPass *DT) {
     return "Region Graph";
   }
 
-  std::string getNodeLabel(RegionNode *Node, RegionInfo *G) {
+  std::string getNodeLabel(RegionNode *Node, RegionInfoPass *G) {
+    RegionInfo &RI = G->getRegionInfo();
     return DOTGraphTraits<RegionNode*>::getNodeLabel(Node,
-                                                     G->getTopLevelRegion());
+                                                     reinterpret_cast<RegionNode*>(RI.getTopLevelRegion()));
   }
 
   std::string getEdgeAttributes(RegionNode *srcNode,
-    GraphTraits<RegionInfo*>::ChildIteratorType CI, RegionInfo *RI) {
-
+    GraphTraits<RegionInfo*>::ChildIteratorType CI, RegionInfoPass *G) {
+    RegionInfo &RI = G->getRegionInfo();
     RegionNode *destNode = *CI;
 
     if (srcNode->isSubRegion() || destNode->isSubRegion())
@@ -82,7 +83,7 @@ struct DOTGraphTraits<RegionInfo*> : pub
     BasicBlock *srcBB = srcNode->getNodeAs<BasicBlock>();
     BasicBlock *destBB = destNode->getNodeAs<BasicBlock>();
 
-    Region *R = RI->getRegionFor(destBB);
+    Region *R = RI.getRegionFor(destBB);
 
     while (R && R->getParent())
       if (R->getParent()->getEntry() == destBB)
@@ -98,7 +99,8 @@ struct DOTGraphTraits<RegionInfo*> : pub
 
   // Print the cluster of the subregions. This groups the single basic blocks
   // and adds a different background color for each group.
-  static void printRegionCluster(const Region &R, GraphWriter<RegionInfo*> &GW,
+  static void printRegionCluster(const Region &R,
+                                 GraphWriter<RegionInfoPass*> &GW,
                                  unsigned depth = 0) {
     raw_ostream &O = GW.getOStream();
     O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void*>(&R)
@@ -119,22 +121,23 @@ struct DOTGraphTraits<RegionInfo*> : pub
     for (Region::const_iterator RI = R.begin(), RE = R.end(); RI != RE; ++RI)
       printRegionCluster(**RI, GW, depth + 1);
 
-    RegionInfo *RI = R.getRegionInfo();
+    const RegionInfo &RI = *static_cast<const RegionInfo*>(R.getRegionInfo());
 
     for (const auto &BB : R.blocks())
-      if (RI->getRegionFor(BB) == &R)
+      if (RI.getRegionFor(BB) == &R)
         O.indent(2 * (depth + 1)) << "Node"
-          << static_cast<const void*>(RI->getTopLevelRegion()->getBBNode(BB))
+          << static_cast<const void*>(RI.getTopLevelRegion()->getBBNode(BB))
           << ";\n";
 
     O.indent(2 * depth) << "}\n";
   }
 
-  static void addCustomGraphFeatures(const RegionInfo* RI,
-                                     GraphWriter<RegionInfo*> &GW) {
+  static void addCustomGraphFeatures(const RegionInfoPass* RIP,
+                                     GraphWriter<RegionInfoPass*> &GW) {
+    const RegionInfo &RI = RIP->getRegionInfo();
     raw_ostream &O = GW.getOStream();
     O << "\tcolorscheme = \"paired12\"\n";
-    printRegionCluster(*RI->getTopLevelRegion(), GW, 4);
+    printRegionCluster(*RI.getTopLevelRegion(), GW, 4);
   }
 };
 } //end namespace llvm
@@ -142,28 +145,28 @@ struct DOTGraphTraits<RegionInfo*> : pub
 namespace {
 
 struct RegionViewer
-  : public DOTGraphTraitsViewer<RegionInfo, false> {
+  : public DOTGraphTraitsViewer<RegionInfoPass, false> {
   static char ID;
-  RegionViewer() : DOTGraphTraitsViewer<RegionInfo, false>("reg", ID){
+  RegionViewer() : DOTGraphTraitsViewer<RegionInfoPass, false>("reg", ID){
     initializeRegionViewerPass(*PassRegistry::getPassRegistry());
   }
 };
 char RegionViewer::ID = 0;
 
 struct RegionOnlyViewer
-  : public DOTGraphTraitsViewer<RegionInfo, true> {
+  : public DOTGraphTraitsViewer<RegionInfoPass, true> {
   static char ID;
-  RegionOnlyViewer() : DOTGraphTraitsViewer<RegionInfo, true>("regonly", ID) {
+  RegionOnlyViewer() : DOTGraphTraitsViewer<RegionInfoPass, true>("regonly", ID) {
     initializeRegionOnlyViewerPass(*PassRegistry::getPassRegistry());
   }
 };
 char RegionOnlyViewer::ID = 0;
 
 struct RegionPrinter
-  : public DOTGraphTraitsPrinter<RegionInfo, false> {
+  : public DOTGraphTraitsPrinter<RegionInfoPass, false> {
   static char ID;
   RegionPrinter() :
-    DOTGraphTraitsPrinter<RegionInfo, false>("reg", ID) {
+    DOTGraphTraitsPrinter<RegionInfoPass, false>("reg", ID) {
       initializeRegionPrinterPass(*PassRegistry::getPassRegistry());
     }
 };
@@ -175,7 +178,7 @@ INITIALIZE_PASS(RegionPrinter, "dot-regi
 
 INITIALIZE_PASS(RegionViewer, "view-regions", "View regions of function",
                 true, true)
-                
+
 INITIALIZE_PASS(RegionOnlyViewer, "view-regions-only",
                 "View regions of function (with no function bodies)",
                 true, true)
@@ -183,10 +186,10 @@ INITIALIZE_PASS(RegionOnlyViewer, "view-
 namespace {
 
 struct RegionOnlyPrinter
-  : public DOTGraphTraitsPrinter<RegionInfo, true> {
+  : public DOTGraphTraitsPrinter<RegionInfoPass, true> {
   static char ID;
   RegionOnlyPrinter() :
-    DOTGraphTraitsPrinter<RegionInfo, true>("reg", ID) {
+    DOTGraphTraitsPrinter<RegionInfoPass, true>("reg", ID) {
       initializeRegionOnlyPrinterPass(*PassRegistry::getPassRegistry());
     }
 };

Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=213456&r1=213455&r2=213456&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CMakeLists.txt (original)
+++ llvm/trunk/lib/CodeGen/CMakeLists.txt Sat Jul 19 13:29:29 2014
@@ -65,6 +65,7 @@ add_llvm_library(LLVMCodeGen
   MachinePassRegistry.cpp
   MachinePostDominators.cpp
   MachineRegisterInfo.cpp
+  MachineRegionInfo.cpp
   MachineSSAUpdater.cpp
   MachineScheduler.cpp
   MachineSink.cpp

Added: llvm/trunk/lib/CodeGen/MachineRegionInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineRegionInfo.cpp?rev=213456&view=auto
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineRegionInfo.cpp (added)
+++ llvm/trunk/lib/CodeGen/MachineRegionInfo.cpp Sat Jul 19 13:29:29 2014
@@ -0,0 +1,137 @@
+
+#include "llvm/CodeGen/MachineRegionInfo.h"
+#include "llvm/CodeGen/MachinePostDominators.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/RegionInfoImpl.h"
+
+using namespace llvm;
+
+STATISTIC(numMachineRegions,       "The # of machine regions");
+STATISTIC(numMachineSimpleRegions, "The # of simple machine regions");
+
+namespace llvm {
+template class RegionBase<RegionTraits<MachineFunction>>;
+template class RegionNodeBase<RegionTraits<MachineFunction>>;
+template class RegionInfoBase<RegionTraits<MachineFunction>>;
+}
+
+//===----------------------------------------------------------------------===//
+// MachineRegion implementation
+//
+
+MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,
+                             MachineRegionInfo* RI,
+                             MachineDominatorTree *DT, MachineRegion *Parent) :
+  RegionBase<RegionTraits<MachineFunction>>(Entry, Exit, RI, DT, Parent) {
+
+}
+
+MachineRegion::~MachineRegion() { }
+
+//===----------------------------------------------------------------------===//
+// MachineRegionInfo implementation
+//
+
+MachineRegionInfo::MachineRegionInfo() :
+  RegionInfoBase<RegionTraits<MachineFunction>>() {
+
+}
+
+MachineRegionInfo::~MachineRegionInfo() {
+
+}
+
+void MachineRegionInfo::updateStatistics(MachineRegion *R) {
+  ++numMachineRegions;
+
+  // TODO: Slow. Should only be enabled if -stats is used.
+  if (R->isSimple())
+    ++numMachineSimpleRegions;
+}
+
+void MachineRegionInfo::MachineRegionInfo::recalculate(
+  MachineFunction &F,
+  MachineDominatorTree *DT_,
+  MachinePostDominatorTree *PDT_,
+  MachineDominanceFrontier *DF_) {
+  DT = DT_;
+  PDT = PDT_;
+  DF = DF_;
+
+  MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(&F);
+
+  TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr);
+  updateStatistics(TopLevelRegion);
+  calculate(F);
+}
+
+//===----------------------------------------------------------------------===//
+// MachineRegionInfoPass implementation
+//
+
+MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) {
+  initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry());
+}
+
+MachineRegionInfoPass::~MachineRegionInfoPass() {
+
+}
+
+bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) {
+  releaseMemory();
+
+  auto DT = &getAnalysis<MachineDominatorTree>();
+  auto PDT = &getAnalysis<MachinePostDominatorTree>();
+  auto DF = &getAnalysis<MachineDominanceFrontier>();
+
+  RI.recalculate(F, DT, PDT, DF);
+  return false;
+}
+
+void MachineRegionInfoPass::releaseMemory() {
+  RI.releaseMemory();
+}
+
+void MachineRegionInfoPass::verifyAnalysis() const {
+  // Only do verification when user wants to, otherwise this expensive check
+  // will be invoked by PMDataManager::verifyPreservedAnalysis when
+  // a regionpass (marked PreservedAll) finish.
+  if (MachineRegionInfo::VerifyRegionInfo)
+    RI.verifyAnalysis();
+}
+
+void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.setPreservesAll();
+  AU.addRequiredTransitive<DominatorTreeWrapperPass>();
+  AU.addRequired<PostDominatorTree>();
+  AU.addRequired<DominanceFrontier>();
+}
+
+void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const {
+  RI.print(OS);
+}
+
+void MachineRegionInfoPass::dump() const {
+  RI.dump();
+}
+
+char MachineRegionInfoPass::ID = 0;
+
+INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, "regions",
+                "Detect single entry single exit regions", true, true)
+INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
+INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree)
+INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier)
+INITIALIZE_PASS_END(MachineRegionInfoPass, "regions",
+                "Detect single entry single exit regions", true, true)
+
+// Create methods available outside of this file, to use them
+// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
+// the link time optimization.
+
+namespace llvm {
+  FunctionPass *createMachineRegionInfoPass() {
+    return new MachineRegionInfoPass();
+  }
+}
+

Modified: llvm/trunk/lib/Transforms/Scalar/StructurizeCFG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/StructurizeCFG.cpp?rev=213456&r1=213455&r2=213456&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/StructurizeCFG.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/StructurizeCFG.cpp Sat Jul 19 13:29:29 2014
@@ -260,7 +260,7 @@ INITIALIZE_PASS_BEGIN(StructurizeCFG, "s
                       false, false)
 INITIALIZE_PASS_DEPENDENCY(LowerSwitch)
 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(RegionInfo)
+INITIALIZE_PASS_DEPENDENCY(RegionInfoPass)
 INITIALIZE_PASS_END(StructurizeCFG, "structurizecfg", "Structurize the CFG",
                     false, false)
 
@@ -406,11 +406,11 @@ void StructurizeCFG::gatherPredicates(Re
     } else {
 
       // It's an exit from a sub region
-      while(R->getParent() != ParentRegion)
+      while (R->getParent() != ParentRegion)
         R = R->getParent();
 
       // Edge from inside a subregion to its entry, ignore it
-      if (R == N)
+      if (*R == *N)
         continue;
 
       BasicBlock *Entry = R->getEntry();





More information about the llvm-commits mailing list