blockfreq: Store the header with the members
[oota-llvm.git] / include / llvm / Analysis / BlockFrequencyInfoImpl.h
index 02c04fd174074fdb9f482749edc3f09ae8c135c2..f9978cc1c47eaff5c9a754140fcab13594dd77d5 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/iterator_range.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/Support/BlockFrequency.h"
 #include "llvm/Support/BranchProbability.h"
@@ -945,40 +946,56 @@ public:
   struct LoopData {
     typedef SmallVector<std::pair<BlockNode, BlockMass>, 4> ExitMap;
     typedef SmallVector<BlockNode, 4> MemberList;
-    BlockNode Header;       ///< Header.
+    LoopData *Parent;       ///< The parent loop.
     bool IsPackaged;        ///< Whether this has been packaged.
     ExitMap Exits;          ///< Successor edges (and weights).
-    MemberList Members;     ///< Members of the loop.
+    MemberList Nodes;       ///< Header and the members of the loop.
     BlockMass BackedgeMass; ///< Mass returned to loop header.
     BlockMass Mass;
     Float Scale;
 
-    LoopData(const BlockNode &Header) : Header(Header), IsPackaged(false) {}
+    LoopData(LoopData *Parent, const BlockNode &Header)
+        : Parent(Parent), IsPackaged(false), Nodes(1, Header) {}
+    bool isHeader(const BlockNode &Node) const { return Node == Nodes[0]; }
+    BlockNode getHeader() const { return Nodes[0]; }
+
+    MemberList::const_iterator members_begin() const {
+      return Nodes.begin() + 1;
+    }
+    MemberList::const_iterator members_end() const { return Nodes.end(); }
+    iterator_range<MemberList::const_iterator> members() const {
+      return make_range(members_begin(), members_end());
+    }
   };
 
   /// \brief Index of loop information.
   struct WorkingData {
-    LoopData *Loop;           ///< The loop this block is the header of.
-    LoopData *ContainingLoop; ///< The block whose loop this block is inside.
-    BlockMass Mass;           ///< Mass distribution from the entry block.
+    BlockNode Node; ///< This node.
+    LoopData *Loop; ///< The loop this block is inside.
+    BlockMass Mass; ///< Mass distribution from the entry block.
 
-    WorkingData() : Loop(nullptr), ContainingLoop(nullptr) {}
+    WorkingData(const BlockNode &Node) : Node(Node), Loop(nullptr) {}
 
-    bool hasLoopHeader() const { return ContainingLoop; }
-    bool isLoopHeader() const { return Loop; }
+    bool isLoopHeader() const { return Loop && Loop->isHeader(Node); }
+    bool hasLoopHeader() const { return isLoopHeader() ? Loop->Parent : Loop; }
 
+    LoopData *getContainingLoop() const {
+      return isLoopHeader() ? Loop->Parent : Loop;
+    }
     BlockNode getContainingHeader() const {
+      auto *ContainingLoop = getContainingLoop();
       if (ContainingLoop)
-        return ContainingLoop->Header;
+        return ContainingLoop->getHeader();
       return BlockNode();
     }
 
     /// \brief Has ContainingLoop been packaged up?
     bool isPackaged() const {
+      auto *ContainingLoop = getContainingLoop();
       return ContainingLoop && ContainingLoop->IsPackaged;
     }
     /// \brief Has Loop been packaged up?
-    bool isAPackage() const { return Loop && Loop->IsPackaged; }
+    bool isAPackage() const { return isLoopHeader() && Loop->IsPackaged; }
   };
 
   /// \brief Unscaled probability weight.
@@ -1072,7 +1089,7 @@ public:
 
   LoopData &getLoopPackage(const BlockNode &Head) {
     assert(Head.Index < Working.size());
-    assert(Working[Head.Index].Loop != nullptr);
+    assert(Working[Head.Index].isLoopHeader());
     return *Working[Head.Index].Loop;
   }
 
@@ -1416,7 +1433,9 @@ template <class BT> void BlockFrequencyInfoImpl<BT>::initializeRPOT() {
     Nodes[*I] = Node;
   }
 
-  Working.resize(RPOT.size());
+  Working.reserve(RPOT.size());
+  for (size_t Index = 0; Index < RPOT.size(); ++Index)
+    Working.emplace_back(Index);
   Freqs.resize(RPOT.size());
 }
 
@@ -1426,42 +1445,48 @@ template <class BT> void BlockFrequencyInfoImpl<BT>::initializeLoops() {
     return;
 
   // Visit loops top down and assign them an index.
-  std::deque<const LoopT *> Q;
-  Q.insert(Q.end(), LI->begin(), LI->end());
+  std::deque<std::pair<const LoopT *, LoopData *>> Q;
+  for (const LoopT *L : *LI)
+    Q.emplace_back(L, nullptr);
   while (!Q.empty()) {
-    const LoopT *Loop = Q.front();
+    const LoopT *Loop = Q.front().first;
+    LoopData *Parent = Q.front().second;
     Q.pop_front();
-    Q.insert(Q.end(), Loop->begin(), Loop->end());
 
-    // Save the order this loop was visited.
     BlockNode Header = getNode(Loop->getHeader());
     assert(Header.isValid());
 
-    Loops.emplace_back(Header);
+    Loops.emplace_back(Parent, Header);
     Working[Header.Index].Loop = &Loops.back();
     DEBUG(dbgs() << " - loop = " << getBlockName(Header) << "\n");
+
+    for (const LoopT *L : *Loop)
+      Q.emplace_back(L, &Loops.back());
   }
 
   // Visit nodes in reverse post-order and add them to their deepest containing
   // loop.
   for (size_t Index = 0; Index < RPOT.size(); ++Index) {
+    // Loop headers have already been mostly mapped.
+    if (Working[Index].isLoopHeader()) {
+      LoopData *ContainingLoop = Working[Index].getContainingLoop();
+      if (ContainingLoop)
+        ContainingLoop->Nodes.push_back(Index);
+      continue;
+    }
+
     const LoopT *Loop = LI->getLoopFor(RPOT[Index]);
     if (!Loop)
       continue;
 
-    // If this is a loop header, find its parent loop (if any).
-    if (Working[Index].isLoopHeader())
-      if (!(Loop = Loop->getParentLoop()))
-        continue;
-
     // Add this node to its containing loop's member list.
     BlockNode Header = getNode(Loop->getHeader());
     assert(Header.isValid());
     const auto &HeaderData = Working[Header.Index];
     assert(HeaderData.isLoopHeader());
 
-    Working[Index].ContainingLoop = HeaderData.Loop;
-    HeaderData.Loop->Members.push_back(Index);
+    Working[Index].Loop = HeaderData.Loop;
+    HeaderData.Loop->Nodes.push_back(Index);
     DEBUG(dbgs() << " - loop = " << getBlockName(Header)
                  << ": member = " << getBlockName(Index) << "\n");
   }
@@ -1476,13 +1501,13 @@ template <class BT> void BlockFrequencyInfoImpl<BT>::computeMassInLoops() {
 template <class BT>
 void BlockFrequencyInfoImpl<BT>::computeMassInLoop(LoopData &Loop) {
   // Compute mass in loop.
-  DEBUG(dbgs() << "compute-mass-in-loop: " << getBlockName(Loop.Header)
+  DEBUG(dbgs() << "compute-mass-in-loop: " << getBlockName(Loop.getHeader())
                << "\n");
 
-  Working[Loop.Header.Index].Mass = BlockMass::getFull();
-  propagateMassToSuccessors(&Loop, Loop.Header);
+  Working[Loop.getHeader().Index].Mass = BlockMass::getFull();
+  propagateMassToSuccessors(&Loop, Loop.getHeader());
 
-  for (const BlockNode &M : Loop.Members)
+  for (const BlockNode &M : Loop.members())
     propagateMassToSuccessors(&Loop, M);
 
   computeLoopScale(Loop);
@@ -1513,10 +1538,8 @@ BlockFrequencyInfoImpl<BT>::propagateMassToSuccessors(LoopData *OuterLoop,
   DEBUG(dbgs() << " - node: " << getBlockName(Node) << "\n");
   // Calculate probability for successors.
   Distribution Dist;
-  BlockNode LoopHead;
-  if (OuterLoop)
-    LoopHead = OuterLoop->Header;
-  if (Node != LoopHead && Working[Node.Index].isLoopHeader())
+  if (Working[Node.Index].isLoopHeader() &&
+      Working[Node.Index].Loop != OuterLoop)
     addLoopSuccessorsToDist(OuterLoop, *Working[Node.Index].Loop, Dist);
   else {
     const BlockT *BB = getBlock(Node);