From: Duncan P. N. Exon Smith Date: Fri, 25 Apr 2014 18:47:04 +0000 (+0000) Subject: blockfreq: Further shift logic to LoopData X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=2d18167483cf274413e52b4fa9513a7dffa6a7f8;p=oota-llvm.git blockfreq: Further shift logic to LoopData Move a lot of the loop-related logic that was sprinkled around the code into `LoopData`. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207258 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/include/llvm/Analysis/BlockFrequencyInfoImpl.h index f8215bf62dd..e5e9b479523 100644 --- a/include/llvm/Analysis/BlockFrequencyInfoImpl.h +++ b/include/llvm/Analysis/BlockFrequencyInfoImpl.h @@ -975,23 +975,46 @@ public: WorkingData(const BlockNode &Node) : Node(Node), Loop(nullptr) {} 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->getHeader(); - return BlockNode(); + + /// \brief Resolve a node to its representative. + /// + /// Get the node currently representing Node, which could be a containing + /// loop. + /// + /// This function should only be called when distributing mass. As long as + /// there are no irreducilbe edges to Node, then it will have complexity + /// O(1) in this context. + /// + /// In general, the complexity is O(L), where L is the number of loop + /// headers Node has been packaged into. Since this method is called in + /// the context of distributing mass, L will be the number of loop headers + /// an early exit edge jumps out of. + BlockNode getResolvedNode() const { + auto L = getPackagedLoop(); + return L ? L->getHeader() : Node; + } + LoopData *getPackagedLoop() const { + if (!Loop || !Loop->IsPackaged) + return nullptr; + auto L = Loop; + while (L->Parent && L->Parent->IsPackaged) + L = L->Parent; + return L; } + /// \brief Get the appropriate mass for a node. + /// + /// Get appropriate mass for Node. If Node is a loop-header (whose loop + /// has been packaged), returns the mass of its pseudo-node. If it's a + /// node inside a packaged loop, it returns the loop's mass. + BlockMass &getMass() { return isAPackage() ? Loop->Mass : Mass; } + /// \brief Has ContainingLoop been packaged up? - bool isPackaged() const { - auto *ContainingLoop = getContainingLoop(); - return ContainingLoop && ContainingLoop->IsPackaged; - } + bool isPackaged() const { return getResolvedNode() != Node; } /// \brief Has Loop been packaged up? bool isAPackage() const { return isLoopHeader() && Loop->IsPackaged; } }; @@ -1087,28 +1110,6 @@ public: return *Working[Head.Index].Loop; } - /// \brief Get a possibly packaged node. - /// - /// Get the node currently representing Node, which could be a containing - /// loop. - /// - /// This function should only be called when distributing mass. As long as - /// there are no irreducilbe edges to Node, then it will have complexity O(1) - /// in this context. - /// - /// In general, the complexity is O(L), where L is the number of loop headers - /// Node has been packaged into. Since this method is called in the context - /// of distributing mass, L will be the number of loop headers an early exit - /// edge jumps out of. - BlockNode getPackagedNode(const BlockNode &Node) { - assert(Node.isValid()); - if (!Working[Node.Index].isPackaged()) - return Node; - if (!Working[Node.Index].isAPackage()) - return Node; - return getPackagedNode(Working[Node.Index].getContainingHeader()); - } - /// \brief Distribute mass according to a distribution. /// /// Distributes the mass in Source according to Dist. If LoopHead.isValid(), @@ -1539,7 +1540,7 @@ void BlockFrequencyInfoImpl::computeMassInLoop(LoopData &Loop) { DEBUG(dbgs() << "compute-mass-in-loop: " << getBlockName(Loop.getHeader()) << "\n"); - Working[Loop.getHeader().Index].Mass = BlockMass::getFull(); + Working[Loop.getHeader().Index].getMass() = BlockMass::getFull(); propagateMassToSuccessors(&Loop, Loop.getHeader()); for (const BlockNode &M : Loop.members()) @@ -1555,11 +1556,11 @@ template void BlockFrequencyInfoImpl::computeMassInFunction() { assert(!Working.empty() && "no blocks in function"); assert(!Working[0].isLoopHeader() && "entry block is a loop header"); - Working[0].Mass = BlockMass::getFull(); + Working[0].getMass() = BlockMass::getFull(); for (rpot_iterator I = rpot_begin(), IE = rpot_end(); I != IE; ++I) { // Check for nodes that have been packaged. BlockNode Node = getNode(I); - if (Working[Node.Index].hasLoopHeader()) + if (Working[Node.Index].isPackaged()) continue; propagateMassToSuccessors(nullptr, Node); @@ -1573,10 +1574,10 @@ BlockFrequencyInfoImpl::propagateMassToSuccessors(LoopData *OuterLoop, DEBUG(dbgs() << " - node: " << getBlockName(Node) << "\n"); // Calculate probability for successors. Distribution Dist; - if (Working[Node.Index].isLoopHeader() && - Working[Node.Index].Loop != OuterLoop) - addLoopSuccessorsToDist(OuterLoop, *Working[Node.Index].Loop, Dist); - else { + if (auto *Loop = Working[Node.Index].getPackagedLoop()) { + assert(Loop != OuterLoop && "Cannot propagate mass in a packaged loop"); + addLoopSuccessorsToDist(OuterLoop, *Loop, Dist); + } else { const BlockT *BB = getBlock(Node); for (auto SI = Successor::child_begin(BB), SE = Successor::child_end(BB); SI != SE; ++SI) diff --git a/lib/Analysis/BlockFrequencyInfoImpl.cpp b/lib/Analysis/BlockFrequencyInfoImpl.cpp index 744bbe2fe95..2fcd9b8377b 100644 --- a/lib/Analysis/BlockFrequencyInfoImpl.cpp +++ b/lib/Analysis/BlockFrequencyInfoImpl.cpp @@ -568,21 +568,6 @@ static void cleanup(BlockFrequencyInfoImplBase &BFI) { BFI.Freqs = std::move(SavedFreqs); } -/// \brief Get the appropriate mass for a possible pseudo-node loop package. -/// -/// Get appropriate mass for Node. If Node is a loop-header (whose loop has -/// been packaged), returns the mass of its pseudo-node. If it's a node inside -/// a packaged loop, it returns the loop's pseudo-node. -static BlockMass &getPackageMass(BlockFrequencyInfoImplBase &BFI, - const BlockNode &Node) { - assert(Node.isValid()); - assert(!BFI.Working[Node.Index].isPackaged()); - if (!BFI.Working[Node.Index].isAPackage()) - return BFI.Working[Node.Index].Mass; - - return BFI.getLoopPackage(Node).Mass; -} - void BlockFrequencyInfoImplBase::addToDist(Distribution &Dist, const LoopData *OuterLoop, const BlockNode &Pred, @@ -595,11 +580,13 @@ void BlockFrequencyInfoImplBase::addToDist(Distribution &Dist, return OuterLoop && OuterLoop->isHeader(Node); }; + BlockNode Resolved = Working[Succ.Index].getResolvedNode(); + #ifndef NDEBUG - auto debugSuccessor = [&](const char *Type, const BlockNode &Resolved) { + auto debugSuccessor = [&](const char *Type) { dbgs() << " =>" << " [" << Type << "] weight = " << Weight; - if (!isLoopHeader(Succ)) + if (!isLoopHeader(Resolved)) dbgs() << ", succ = " << getBlockName(Succ); if (Resolved != Succ) dbgs() << ", resolved = " << getBlockName(Resolved); @@ -608,27 +595,25 @@ void BlockFrequencyInfoImplBase::addToDist(Distribution &Dist, (void)debugSuccessor; #endif - if (isLoopHeader(Succ)) { - DEBUG(debugSuccessor("backedge", Succ)); + if (isLoopHeader(Resolved)) { + DEBUG(debugSuccessor("backedge")); Dist.addBackedge(OuterLoop->getHeader(), Weight); return; } - BlockNode Resolved = getPackagedNode(Succ); - assert(!isLoopHeader(Resolved)); if (Working[Resolved.Index].getContainingLoop() != OuterLoop) { - DEBUG(debugSuccessor(" exit ", Resolved)); + DEBUG(debugSuccessor(" exit ")); Dist.addExit(Resolved, Weight); return; } if (Resolved < Pred) { - // Irreducible backedge. Skip this edge in the distribution. - DEBUG(debugSuccessor("skipped ", Resolved)); + // Irreducible backedge. Skip. + DEBUG(debugSuccessor(" skip ")); return; } - DEBUG(debugSuccessor(" local ", Resolved)); + DEBUG(debugSuccessor(" local ")); Dist.addLocal(Resolved, Weight); } @@ -685,7 +670,7 @@ void BlockFrequencyInfoImplBase::packageLoop(LoopData &Loop) { void BlockFrequencyInfoImplBase::distributeMass(const BlockNode &Source, LoopData *OuterLoop, Distribution &Dist) { - BlockMass Mass = getPackageMass(*this, Source); + BlockMass Mass = Working[Source.Index].getMass(); DEBUG(dbgs() << " => mass: " << Mass << "\n"); // Distribute mass to successors as laid out in Dist. @@ -708,7 +693,7 @@ void BlockFrequencyInfoImplBase::distributeMass(const BlockNode &Source, // Check for a local edge (non-backedge and non-exit). BlockMass Taken = D.takeMass(W.Amount); if (W.Type == Weight::Local) { - getPackageMass(*this, W.TargetNode) += Taken; + Working[W.TargetNode.Index].getMass() += Taken; DEBUG(debugAssign(W.TargetNode, Taken, nullptr)); continue; }