<p dir="ltr"><br>
On Mar 1, 2015 12:42 PM, "Arnaud A. de Grandmaison" <<a href="mailto:arnaud.degrandmaison@arm.com">arnaud.degrandmaison@arm.com</a>> wrote:<br>
><br>
> Author: aadg<br>
> Date: Sun Mar 1 14:39:34 2015<br>
> New Revision: 230904<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=230904&view=rev">http://llvm.org/viewvc/llvm-project?rev=230904&view=rev</a><br>
> Log:<br>
> [PBQP] Do not add an edge between nodes with totally disjoint allowed registers<br>
><br>
> Such edges are zero matrix, and they bring no additional info to the<br>
> allocation problem, apart from contributing to nodes' degree. Removing<br>
> those edges is expected to improve allocation time.<br>
><br>
> Tune the spill cost comparison, as this gives better average performances<br>
> now that the nodes' degrees has changed.<br>
><br>
> Modified:<br>
> llvm/trunk/include/llvm/CodeGen/RegAllocPBQP.h<br>
> llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp<br>
><br>
> Modified: llvm/trunk/include/llvm/CodeGen/RegAllocPBQP.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/RegAllocPBQP.h?rev=230904&r1=230903&r2=230904&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/RegAllocPBQP.h?rev=230904&r1=230903&r2=230904&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/CodeGen/RegAllocPBQP.h (original)<br>
> +++ llvm/trunk/include/llvm/CodeGen/RegAllocPBQP.h Sun Mar 1 14:39:34 2015<br>
> @@ -544,8 +544,10 @@ private:<br>
> public:<br>
> SpillCostComparator(const Graph& G) : G(G) {}<br>
> bool operator()(NodeId N1Id, NodeId N2Id) {<br>
> - PBQPNum N1SC = G.getNodeCosts(N1Id)[0] / G.getNodeDegree(N1Id);<br>
> - PBQPNum N2SC = G.getNodeCosts(N2Id)[0] / G.getNodeDegree(N2Id);<br>
> + PBQPNum N1SC = G.getNodeCosts(N1Id)[0];<br>
> + PBQPNum N2SC = G.getNodeCosts(N2Id)[0];<br>
> + if (N1SC == N2SC)<br>
> + return G.getNodeDegree(N1Id) < G.getNodeDegree(N2Id);<br>
> return N1SC < N2SC;<br>
> }<br>
> private:<br>
><br>
> Modified: llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp?rev=230904&r1=230903&r2=230904&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp?rev=230904&r1=230903&r2=230904&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp (original)<br>
> +++ llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp Sun Mar 1 14:39:34 2015<br>
> @@ -178,8 +178,38 @@ class Interference : public PBQPRAConstr<br>
> private:<br>
><br>
> typedef const PBQP::RegAlloc::AllowedRegVector* AllowedRegVecPtr;<br>
> - typedef std::pair<AllowedRegVecPtr, AllowedRegVecPtr> IMatrixKey;<br>
> - typedef DenseMap<IMatrixKey, PBQPRAGraph::MatrixPtr> IMatrixCache;<br>
> + typedef std::pair<AllowedRegVecPtr, AllowedRegVecPtr> IKey;<br>
> + typedef DenseMap<IKey, PBQPRAGraph::MatrixPtr> IMatrixCache;<br>
> + typedef DenseSet<IKey> DisjointAllowedRegsCache;<br>
> +<br>
> + bool haveDisjointAllowedRegs(const PBQPRAGraph &G, PBQPRAGraph::NodeId NId,<br>
> + PBQPRAGraph::NodeId MId,<br>
> + const DisjointAllowedRegsCache &D) const {<br>
> + const auto *NRegs = &G.getNodeMetadata(NId).getAllowedRegs();<br>
> + const auto *MRegs = &G.getNodeMetadata(MId).getAllowedRegs();<br>
> +<br>
> + if (NRegs == MRegs)<br>
> + return false;<br>
> +<br>
> + if (NRegs < MRegs)<br>
> + return D.count(IKey(NRegs, MRegs)) > 0;<br>
> + else</p>
<p dir="ltr">You can drop the else after return (per style guide)</p>
<p dir="ltr">> + return D.count(IKey(MRegs, NRegs)) > 0;<br>
> + }<br>
> +<br>
> + void setDisjointAllowedRegs(const PBQPRAGraph &G, PBQPRAGraph::NodeId NId,<br>
> + PBQPRAGraph::NodeId MId,<br>
> + DisjointAllowedRegsCache &D) {<br>
> + const auto *NRegs = &G.getNodeMetadata(NId).getAllowedRegs();<br>
> + const auto *MRegs = &G.getNodeMetadata(MId).getAllowedRegs();<br>
> +<br>
> + assert(NRegs != MRegs && "AllowedRegs can not be disjoint with itself");<br>
> +<br>
> + if (NRegs < MRegs)<br>
> + D.insert(IKey(NRegs, MRegs));<br>
> + else<br>
> + D.insert(IKey(MRegs, NRegs));<br>
> + }<br>
><br>
> // Holds (Interval, CurrentSegmentID, and NodeId). The first two are required<br>
> // for the fast interference graph construction algorithm. The last is there<br>
> @@ -247,6 +277,9 @@ public:<br>
> // and uniquing them.<br>
> IMatrixCache C;<br>
><br>
> + // Cache known disjoint allowed registers pairs<br>
> + DisjointAllowedRegsCache D;<br>
> +<br>
> typedef std::set<IntervalInfo, decltype(&lowestEndPoint)> IntervalSet;<br>
> typedef std::priority_queue<IntervalInfo, std::vector<IntervalInfo>,<br>
> decltype(&lowestStartPoint)> IntervalQueue;<br>
> @@ -290,6 +323,11 @@ public:<br>
> for (const auto &A : Active) {<br>
> PBQP::GraphBase::NodeId MId = getNodeId(A);<br>
><br>
> + // Do not add an edge when the nodes' allowed registers do not<br>
> + // intersect: there is obviously no interference.<br>
> + if (haveDisjointAllowedRegs(G, NId, MId, D))<br>
> + continue;<br>
> +<br>
> // Check that we haven't already added this edge<br>
> // FIXME: findEdge is expensive in the worst case (O(max_clique(G))).<br>
> // It might be better to replace this with a local bit-matrix.<br>
> @@ -297,7 +335,8 @@ public:<br>
> continue;<br>
><br>
> // This is a new edge - add it to the graph.<br>
> - createInterferenceEdge(G, NId, MId, C);<br>
> + if (!createInterferenceEdge(G, NId, MId, C))<br>
> + setDisjointAllowedRegs(G, NId, MId, D);<br>
> }<br>
><br>
> // Finally, add Cur to the Active set.<br>
> @@ -307,35 +346,48 @@ public:<br>
><br>
> private:<br>
><br>
> - void createInterferenceEdge(PBQPRAGraph &G, PBQPRAGraph::NodeId NId,<br>
> - PBQPRAGraph::NodeId MId, IMatrixCache &C) {<br>
> + // Create an Interference edge and add it to the graph, unless it is<br>
> + // a null matrix, meaning the nodes' allowed registers do not have any<br>
> + // interference. This case occurs frequently between integer and floating<br>
> + // point registers for example.<br>
> + // return true iff both nodes interferes.<br>
> + bool createInterferenceEdge(PBQPRAGraph &G,<br>
> + PBQPRAGraph::NodeId NId, PBQPRAGraph::NodeId MId,<br>
> + IMatrixCache &C) {<br>
><br>
> const TargetRegisterInfo &TRI =<br>
> *G.getMetadata().MF.getSubtarget().getRegisterInfo();<br>
> -<br>
> const auto &NRegs = G.getNodeMetadata(NId).getAllowedRegs();<br>
> const auto &MRegs = G.getNodeMetadata(MId).getAllowedRegs();<br>
><br>
> // Try looking the edge costs up in the IMatrixCache first.<br>
> - IMatrixKey K(&NRegs, &MRegs);<br>
> + IKey K(&NRegs, &MRegs);<br>
> IMatrixCache::iterator I = C.find(K);<br>
> if (I != C.end()) {<br>
> G.addEdgeBypassingCostAllocator(NId, MId, I->second);<br>
> - return;<br>
> + return true;<br>
> }<br>
><br>
> PBQPRAGraph::RawMatrix M(NRegs.size() + 1, MRegs.size() + 1, 0);<br>
> + bool NodesInterfere = false;<br>
> for (unsigned I = 0; I != NRegs.size(); ++I) {<br>
> unsigned PRegN = NRegs[I];<br>
> for (unsigned J = 0; J != MRegs.size(); ++J) {<br>
> unsigned PRegM = MRegs[J];<br>
> - if (TRI.regsOverlap(PRegN, PRegM))<br>
> + if (TRI.regsOverlap(PRegN, PRegM)) {<br>
> M[I + 1][J + 1] = std::numeric_limits<PBQP::PBQPNum>::infinity();<br>
> + NodesInterfere = true;<br>
> + }<br>
> }<br>
> }<br>
><br>
> + if (!NodesInterfere)<br>
> + return false;<br>
> +<br>
> PBQPRAGraph::EdgeId EId = G.addEdge(NId, MId, std::move(M));<br>
> C[K] = G.getEdgeCostsPtr(EId);<br>
> +<br>
> + return true;<br>
> }<br>
> };<br>
><br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</p>