<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 14 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p
        {mso-style-priority:99;
        mso-margin-top-alt:auto;
        margin-right:0cm;
        mso-margin-bottom-alt:auto;
        margin-left:0cm;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=EN-GB link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Addressed with r230908. Thanks David !<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Cheers,<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Arnaud<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><div style='border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt'><div><div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal><b><span lang=EN-US style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'>From:</span></b><span lang=EN-US style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'> David Blaikie [mailto:dblaikie@gmail.com] <br><b>Sent:</b> 01 March 2015 21:59<br><b>To:</b> Arnaud De Grandmaison<br><b>Cc:</b> llvm-commits@cs.uiuc.edu<br><b>Subject:</b> Re: [llvm] r230904 - [PBQP] Do not add an edge between nodes with totally disjoint allowed registers<o:p></o:p></span></p></div></div><p class=MsoNormal><o:p> </o:p></p><p><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<o:p></o:p></p><p>You can drop the else after return (per style guide)<o:p></o:p></p><p>> +      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><o:p></o:p></p></div></div></body></html>