<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>