<div dir="ltr">My apologies for that. The missing headers were committed in<span style="font-family:arial,sans-serif;font-size:13px"> r219421.</span><div><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div><span style="font-family:arial,sans-serif;font-size:13px">Cheers,</span></div><div><span style="font-family:arial,sans-serif;font-size:13px">Lang.</span></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Oct 9, 2014 at 11:40 AM, Hans Wennborg <span dir="ltr"><<a href="mailto:hans@chromium.org" target="_blank">hans@chromium.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This breaks my build with:<br>
<br>
[176/1224] Building CXX object<br>
lib/Target/CMakeFiles/LLVMTarget.dir/TargetSubtargetInfo.cpp.o<br>
FAILED: /work/gcc482prefix/bin/clang++   -DGTEST_HAS_RTTI=0 -D_DEBUG<br>
-D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS<br>
-D__STDC_LIMIT_MACROS -fPIC -fvisibility-inlines-hidden -Wall -W<br>
-Wno-unused-parameter -Wwrite-strings -Wmissing-field-initializers<br>
-pedantic -Wno-long-long -Wcovered-switch-default -Wnon-virtual-dtor<br>
-std=c++11 -fcolor-diagnostics -ffunction-sections -fdata-sections -g<br>
-Ilib/Target -I../lib/Target -Iinclude -I../include    -fno-exceptions<br>
-fno-rtti -MMD -MT<br>
lib/Target/CMakeFiles/LLVMTarget.dir/TargetSubtargetInfo.cpp.o -MF<br>
"lib/Target/CMakeFiles/LLVMTarget.dir/TargetSubtargetInfo.cpp.o.d" -o<br>
lib/Target/CMakeFiles/LLVMTarget.dir/TargetSubtargetInfo.cpp.o -c<br>
../lib/Target/TargetSubtargetInfo.cpp<br>
In file included from ../lib/Target/TargetSubtargetInfo.cpp:16:<br>
../include/llvm/Target/TargetSubtargetInfo.h:17:10: fatal error:<br>
'llvm/CodeGen/PBQPRAConstraint.h' file not found<br>
#include "llvm/CodeGen/PBQPRAConstraint.h"<br>
         ^<br>
<div class="HOEnZb"><div class="h5"><br>
On Thu, Oct 9, 2014 at 11:20 AM, Lang Hames <<a href="mailto:lhames@gmail.com">lhames@gmail.com</a>> wrote:<br>
> Author: lhames<br>
> Date: Thu Oct  9 13:20:51 2014<br>
> New Revision: 219421<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=219421&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=219421&view=rev</a><br>
> Log:<br>
> [PBQP] Replace PBQPBuilder with composable constraints (PBQPRAConstraint).<br>
><br>
> This patch removes the PBQPBuilder class and its subclasses and replaces them<br>
> with a composable constraints class: PBQPRAConstraint. This allows constraints<br>
> that are only required for optimisation (e.g. coalescing, soft pairing) to be<br>
> mixed and matched.<br>
><br>
> This patch also introduces support for target writers to supply custom<br>
> constraints for their targets by overriding a TargetSubtargetInfo method:<br>
><br>
> std::unique_ptr<PBQPRAConstraints> getCustomPBQPConstraints() const;<br>
><br>
> This patch should have no effect on allocations.<br>
><br>
><br>
> Modified:<br>
>     llvm/trunk/include/llvm/CodeGen/PBQP/CostAllocator.h<br>
>     llvm/trunk/include/llvm/CodeGen/PBQP/Graph.h<br>
>     llvm/trunk/include/llvm/CodeGen/PBQP/Math.h<br>
>     llvm/trunk/include/llvm/CodeGen/PBQP/ReductionRules.h<br>
>     llvm/trunk/include/llvm/CodeGen/PBQP/RegAllocSolver.h<br>
>     llvm/trunk/include/llvm/CodeGen/PBQP/Solution.h<br>
>     llvm/trunk/include/llvm/CodeGen/RegAllocPBQP.h<br>
>     llvm/trunk/include/llvm/Target/TargetSubtargetInfo.h<br>
>     llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp<br>
>     llvm/trunk/lib/Target/AArch64/AArch64.h<br>
>     llvm/trunk/lib/Target/AArch64/AArch64PBQPRegAlloc.cpp<br>
>     llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp<br>
>     llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h<br>
>     llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp<br>
><br>
> Modified: llvm/trunk/include/llvm/CodeGen/PBQP/CostAllocator.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/PBQP/CostAllocator.h?rev=219421&r1=219420&r2=219421&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/PBQP/CostAllocator.h?rev=219421&r1=219420&r2=219421&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/CodeGen/PBQP/CostAllocator.h (original)<br>
> +++ llvm/trunk/include/llvm/CodeGen/PBQP/CostAllocator.h Thu Oct  9 13:20:51 2014<br>
> @@ -22,6 +22,7 @@<br>
>  #include <set><br>
>  #include <type_traits><br>
><br>
> +namespace llvm {<br>
>  namespace PBQP {<br>
><br>
>  template <typename CostT,<br>
> @@ -104,6 +105,7 @@ private:<br>
>    MatrixCostPool matrixPool;<br>
>  };<br>
><br>
> -}<br>
> +} // namespace PBQP<br>
> +} // namespace llvm<br>
><br>
>  #endif<br>
><br>
> Modified: llvm/trunk/include/llvm/CodeGen/PBQP/Graph.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/PBQP/Graph.h?rev=219421&r1=219420&r2=219421&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/PBQP/Graph.h?rev=219421&r1=219420&r2=219421&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/CodeGen/PBQP/Graph.h (original)<br>
> +++ llvm/trunk/include/llvm/CodeGen/PBQP/Graph.h Thu Oct  9 13:20:51 2014<br>
> @@ -17,11 +17,12 @@<br>
><br>
>  #include "llvm/ADT/ilist.h"<br>
>  #include "llvm/ADT/ilist_node.h"<br>
> -#include "llvm/Support/Compiler.h"<br>
> +#include "llvm/Support/Debug.h"<br>
>  #include <list><br>
>  #include <map><br>
>  #include <set><br>
><br>
> +namespace llvm {<br>
>  namespace PBQP {<br>
><br>
>    class GraphBase {<br>
> @@ -195,7 +196,7 @@ namespace PBQP {<br>
>      EdgeEntry& getEdge(EdgeId EId) { return Edges[EId]; }<br>
>      const EdgeEntry& getEdge(EdgeId EId) const { return Edges[EId]; }<br>
><br>
> -    NodeId addConstructedNode(const NodeEntry &N) {<br>
> +    NodeId addConstructedNode(NodeEntry N) {<br>
>        NodeId NId = 0;<br>
>        if (!FreeNodeIds.empty()) {<br>
>          NId = FreeNodeIds.back();<br>
> @@ -208,7 +209,7 @@ namespace PBQP {<br>
>        return NId;<br>
>      }<br>
><br>
> -    EdgeId addConstructedEdge(const EdgeEntry &E) {<br>
> +    EdgeId addConstructedEdge(EdgeEntry E) {<br>
>        assert(findEdge(E.getN1Id(), E.getN2Id()) == invalidEdgeId() &&<br>
>               "Attempt to add duplicate edge.");<br>
>        EdgeId EId = 0;<br>
> @@ -237,6 +238,12 @@ namespace PBQP {<br>
><br>
>      class NodeItr {<br>
>      public:<br>
> +      typedef std::forward_iterator_tag iterator_category;<br>
> +      typedef NodeId value_type;<br>
> +      typedef int difference_type;<br>
> +      typedef NodeId* pointer;<br>
> +      typedef NodeId& reference;<br>
> +<br>
>        NodeItr(NodeId CurNId, const Graph &G)<br>
>          : CurNId(CurNId), EndNId(G.Nodes.size()), FreeNodeIds(G.FreeNodeIds) {<br>
>          this->CurNId = findNextInUse(CurNId); // Move to first in-use node id<br>
> @@ -251,7 +258,7 @@ namespace PBQP {<br>
>        NodeId findNextInUse(NodeId NId) const {<br>
>          while (NId < EndNId &&<br>
>                 std::find(FreeNodeIds.begin(), FreeNodeIds.end(), NId) !=<br>
> -                 FreeNodeIds.end()) {<br>
> +               FreeNodeIds.end()) {<br>
>            ++NId;<br>
>          }<br>
>          return NId;<br>
> @@ -331,7 +338,10 @@ namespace PBQP {<br>
>      };<br>
><br>
>      /// @brief Construct an empty PBQP graph.<br>
> -    Graph() : Solver(nullptr) { }<br>
> +    Graph() : Solver(nullptr) {}<br>
> +<br>
> +    /// @brief Construct an empty PBQP graph with the given graph metadata.<br>
> +    Graph(GraphMetadata Metadata) : Metadata(Metadata), Solver(nullptr) {}<br>
><br>
>      /// @brief Get a reference to the graph metadata.<br>
>      GraphMetadata& getMetadata() { return Metadata; }<br>
> @@ -418,9 +428,7 @@ namespace PBQP {<br>
>      /// @brief Get a node's cost vector (const version).<br>
>      /// @param NId Node id.<br>
>      /// @return Node cost vector.<br>
> -    const Vector& getNodeCosts(NodeId NId) const {<br>
> -      return *getNode(NId).Costs;<br>
> -    }<br>
> +    const Vector& getNodeCosts(NodeId NId) const { return *getNode(NId).Costs; }<br>
><br>
>      NodeMetadata& getNodeMetadata(NodeId NId) {<br>
>        return getNode(NId).Metadata;<br>
> @@ -448,7 +456,9 @@ namespace PBQP {<br>
>      /// @brief Get an edge's cost matrix (const version).<br>
>      /// @param EId Edge id.<br>
>      /// @return Edge cost matrix.<br>
> -    const Matrix& getEdgeCosts(EdgeId EId) const { return *getEdge(EId).Costs; }<br>
> +    const Matrix& getEdgeCosts(EdgeId EId) const {<br>
> +      return *getEdge(EId).Costs;<br>
> +    }<br>
><br>
>      EdgeMetadata& getEdgeMetadata(EdgeId NId) {<br>
>        return getEdge(NId).Metadata;<br>
> @@ -507,7 +517,7 @@ namespace PBQP {<br>
>        NodeEntry &N = getNode(NId);<br>
>        // TODO: Can this be for-each'd?<br>
>        for (AdjEdgeItr AEItr = N.adjEdgesBegin(),<br>
> -                      AEEnd = N.adjEdgesEnd();<br>
> +             AEEnd = N.adjEdgesEnd();<br>
>             AEItr != AEEnd;) {<br>
>          EdgeId EId = *AEItr;<br>
>          ++AEItr;<br>
> @@ -588,7 +598,7 @@ namespace PBQP {<br>
><br>
>      /// @brief Dump a graph to an output stream.<br>
>      template <typename OStream><br>
> -    void dump(OStream &OS) {<br>
> +    void dumpToStream(OStream &OS) {<br>
>        OS << nodeIds().size() << " " << edgeIds().size() << "\n";<br>
><br>
>        for (auto NId : nodeIds()) {<br>
> @@ -621,6 +631,11 @@ namespace PBQP {<br>
>        }<br>
>      }<br>
><br>
> +    /// @brief Dump this graph to dbgs().<br>
> +    void dump() {<br>
> +      dumpToStream(dbgs());<br>
> +    }<br>
> +<br>
>      /// @brief Print a representation of this graph in DOT format.<br>
>      /// @param OS Output stream to print on.<br>
>      template <typename OStream><br>
> @@ -645,6 +660,7 @@ namespace PBQP {<br>
>      }<br>
>    };<br>
><br>
> -}<br>
> +}  // namespace PBQP<br>
> +}  // namespace llvm<br>
><br>
>  #endif // LLVM_CODEGEN_PBQP_GRAPH_HPP<br>
><br>
> Modified: llvm/trunk/include/llvm/CodeGen/PBQP/Math.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/PBQP/Math.h?rev=219421&r1=219420&r2=219421&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/PBQP/Math.h?rev=219421&r1=219420&r2=219421&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/CodeGen/PBQP/Math.h (original)<br>
> +++ llvm/trunk/include/llvm/CodeGen/PBQP/Math.h Thu Oct  9 13:20:51 2014<br>
> @@ -14,6 +14,7 @@<br>
>  #include <cassert><br>
>  #include <functional><br>
><br>
> +namespace llvm {<br>
>  namespace PBQP {<br>
><br>
>  typedef float PBQPNum;<br>
> @@ -433,6 +434,7 @@ private:<br>
>    Metadata md;<br>
>  };<br>
><br>
> -}<br>
> +} // namespace PBQP<br>
> +} // namespace llvm<br>
><br>
>  #endif // LLVM_CODEGEN_PBQP_MATH_H<br>
><br>
> Modified: llvm/trunk/include/llvm/CodeGen/PBQP/ReductionRules.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/PBQP/ReductionRules.h?rev=219421&r1=219420&r2=219421&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/PBQP/ReductionRules.h?rev=219421&r1=219420&r2=219421&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/CodeGen/PBQP/ReductionRules.h (original)<br>
> +++ llvm/trunk/include/llvm/CodeGen/PBQP/ReductionRules.h Thu Oct  9 13:20:51 2014<br>
> @@ -18,6 +18,7 @@<br>
>  #include "Math.h"<br>
>  #include "Solution.h"<br>
><br>
> +namespace llvm {<br>
>  namespace PBQP {<br>
><br>
>    /// \brief Reduce a node of degree one.<br>
> @@ -186,6 +187,7 @@ namespace PBQP {<br>
>      return s;<br>
>    }<br>
><br>
> -}<br>
> +} // namespace PBQP<br>
> +} // namespace llvm<br>
><br>
>  #endif<br>
><br>
> Modified: llvm/trunk/include/llvm/CodeGen/PBQP/RegAllocSolver.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/PBQP/RegAllocSolver.h?rev=219421&r1=219420&r2=219421&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/PBQP/RegAllocSolver.h?rev=219421&r1=219420&r2=219421&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/CodeGen/PBQP/RegAllocSolver.h (original)<br>
> +++ llvm/trunk/include/llvm/CodeGen/PBQP/RegAllocSolver.h Thu Oct  9 13:20:51 2014<br>
> @@ -26,10 +26,13 @@<br>
>  #include <limits><br>
>  #include <vector><br>
><br>
> +namespace llvm{<br>
>  namespace PBQP {<br>
> -<br>
>    namespace RegAlloc {<br>
><br>
> +    /// @brief Spill option index.<br>
> +    inline unsigned getSpillOptionIdx() { return 0; }<br>
> +<br>
>      /// \brief Metadata to speed allocatability test.<br>
>      ///<br>
>      /// Keeps track of the number of infinities in each row and column.<br>
> @@ -81,6 +84,8 @@ namespace PBQP {<br>
><br>
>      class NodeMetadata {<br>
>      public:<br>
> +      typedef std::vector<unsigned> OptionToRegMap;<br>
> +<br>
>        typedef enum { Unprocessed,<br>
>                       OptimallyReducible,<br>
>                       ConservativelyAllocatable,<br>
> @@ -89,6 +94,14 @@ namespace PBQP {<br>
>        NodeMetadata() : RS(Unprocessed), DeniedOpts(0), OptUnsafeEdges(nullptr){}<br>
>        ~NodeMetadata() { delete[] OptUnsafeEdges; }<br>
><br>
> +      void setVReg(unsigned VReg) { this->VReg = VReg; }<br>
> +      unsigned getVReg() const { return VReg; }<br>
> +<br>
> +      void setOptionRegs(OptionToRegMap OptionRegs) {<br>
> +        this->OptionRegs = std::move(OptionRegs);<br>
> +      }<br>
> +      const OptionToRegMap& getOptionRegs() const { return OptionRegs; }<br>
> +<br>
>        void setup(const Vector& Costs) {<br>
>          NumOpts = Costs.getLength() - 1;<br>
>          OptUnsafeEdges = new unsigned[NumOpts]();<br>
> @@ -124,6 +137,8 @@ namespace PBQP {<br>
>        unsigned NumOpts;<br>
>        unsigned DeniedOpts;<br>
>        unsigned* OptUnsafeEdges;<br>
> +      unsigned VReg;<br>
> +      OptionToRegMap OptionRegs;<br>
>      };<br>
><br>
>      class RegAllocSolverImpl {<br>
> @@ -144,7 +159,36 @@ namespace PBQP {<br>
>        typedef RegAlloc::NodeMetadata NodeMetadata;<br>
><br>
>        struct EdgeMetadata { };<br>
> -      struct GraphMetadata { };<br>
> +<br>
> +      class GraphMetadata {<br>
> +      public:<br>
> +        GraphMetadata(MachineFunction &MF,<br>
> +                      LiveIntervals &LIS,<br>
> +                      MachineBlockFrequencyInfo &MBFI)<br>
> +          : MF(MF), LIS(LIS), MBFI(MBFI) {}<br>
> +<br>
> +        MachineFunction &MF;<br>
> +        LiveIntervals &LIS;<br>
> +        MachineBlockFrequencyInfo &MBFI;<br>
> +<br>
> +        void setNodeIdForVReg(unsigned VReg, GraphBase::NodeId NId) {<br>
> +          VRegToNodeId[VReg] = NId;<br>
> +        }<br>
> +<br>
> +        GraphBase::NodeId getNodeIdForVReg(unsigned VReg) const {<br>
> +          auto VRegItr = VRegToNodeId.find(VReg);<br>
> +          if (VRegItr == VRegToNodeId.end())<br>
> +            return GraphBase::invalidNodeId();<br>
> +          return VRegItr->second;<br>
> +        }<br>
> +<br>
> +        void eraseNodeIdForVReg(unsigned VReg) {<br>
> +          VRegToNodeId.erase(VReg);<br>
> +        }<br>
> +<br>
> +      private:<br>
> +        DenseMap<unsigned, NodeId> VRegToNodeId;<br>
> +      };<br>
><br>
>        typedef PBQP::Graph<RegAllocSolverImpl> Graph;<br>
><br>
> @@ -345,16 +389,21 @@ namespace PBQP {<br>
>        NodeSet NotProvablyAllocatableNodes;<br>
>      };<br>
><br>
> -    typedef Graph<RegAllocSolverImpl> Graph;<br>
> +    class PBQPRAGraph : public PBQP::Graph<RegAllocSolverImpl> {<br>
> +    private:<br>
> +      typedef PBQP::Graph<RegAllocSolverImpl> BaseT;<br>
> +    public:<br>
> +      PBQPRAGraph(GraphMetadata Metadata) : BaseT(Metadata) {}<br>
> +    };<br>
><br>
> -    inline Solution solve(Graph& G) {<br>
> +    inline Solution solve(PBQPRAGraph& G) {<br>
>        if (G.empty())<br>
>          return Solution();<br>
>        RegAllocSolverImpl RegAllocSolver(G);<br>
>        return RegAllocSolver.solve();<br>
>      }<br>
> -<br>
> -  }<br>
> -}<br>
> +  } // namespace RegAlloc<br>
> +} // namespace PBQP<br>
> +} // namespace llvm<br>
><br>
>  #endif // LLVM_CODEGEN_PBQP_REGALLOCSOLVER_H<br>
><br>
> Modified: llvm/trunk/include/llvm/CodeGen/PBQP/Solution.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/PBQP/Solution.h?rev=219421&r1=219420&r2=219421&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/PBQP/Solution.h?rev=219421&r1=219420&r2=219421&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/CodeGen/PBQP/Solution.h (original)<br>
> +++ llvm/trunk/include/llvm/CodeGen/PBQP/Solution.h Thu Oct  9 13:20:51 2014<br>
> @@ -18,6 +18,7 @@<br>
>  #include "Math.h"<br>
>  #include <map><br>
><br>
> +namespace llvm {<br>
>  namespace PBQP {<br>
><br>
>    /// \brief Represents a solution to a PBQP problem.<br>
> @@ -87,6 +88,7 @@ namespace PBQP {<br>
><br>
>    };<br>
><br>
> -}<br>
> +} // namespace PBQP<br>
> +} // namespace llvm<br>
><br>
>  #endif // LLVM_CODEGEN_PBQP_SOLUTION_H<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=219421&r1=219420&r2=219421&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/RegAllocPBQP.h?rev=219421&r1=219420&r2=219421&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/CodeGen/RegAllocPBQP.h (original)<br>
> +++ llvm/trunk/include/llvm/CodeGen/RegAllocPBQP.h Thu Oct  9 13:20:51 2014<br>
> @@ -16,152 +16,15 @@<br>
>  #ifndef LLVM_CODEGEN_REGALLOCPBQP_H<br>
>  #define LLVM_CODEGEN_REGALLOCPBQP_H<br>
><br>
> -#include "llvm/ADT/DenseMap.h"<br>
> -#include "llvm/ADT/SmallVector.h"<br>
>  #include "llvm/CodeGen/MachineFunctionPass.h"<br>
> +#include "llvm/CodeGen/PBQPRAConstraint.h"<br>
>  #include "llvm/CodeGen/PBQP/RegAllocSolver.h"<br>
> -#include <map><br>
> -#include <set><br>
><br>
>  namespace llvm {<br>
><br>
> -  class LiveIntervals;<br>
> -  class MachineBlockFrequencyInfo;<br>
> -  class MachineFunction;<br>
> -  class TargetRegisterInfo;<br>
> -<br>
> -  typedef PBQP::RegAlloc::Graph PBQPRAGraph;<br>
> -<br>
> -  /// This class wraps up a PBQP instance representing a register allocation<br>
> -  /// problem, plus the structures necessary to map back from the PBQP solution<br>
> -  /// to a register allocation solution. (i.e. The PBQP-node <--> vreg map,<br>
> -  /// and the PBQP option <--> storage location map).<br>
> -  class PBQPRAProblem {<br>
> -  public:<br>
> -<br>
> -    typedef SmallVector<unsigned, 16> AllowedSet;<br>
> -<br>
> -    PBQPRAGraph& getGraph() { return graph; }<br>
> -<br>
> -    const PBQPRAGraph& getGraph() const { return graph; }<br>
> -<br>
> -    /// Record the mapping between the given virtual register and PBQP node,<br>
> -    /// and the set of allowed pregs for the vreg.<br>
> -    ///<br>
> -    /// If you are extending<br>
> -    /// PBQPBuilder you are unlikely to need this: Nodes and options for all<br>
> -    /// vregs will already have been set up for you by the base class.<br>
> -    template <typename AllowedRegsItr><br>
> -    void recordVReg(unsigned vreg, PBQPRAGraph::NodeId nodeId,<br>
> -                    AllowedRegsItr arBegin, AllowedRegsItr arEnd) {<br>
> -      assert(node2VReg.find(nodeId) == node2VReg.end() && "Re-mapping node.");<br>
> -      assert(vreg2Node.find(vreg) == vreg2Node.end() && "Re-mapping vreg.");<br>
> -      assert(allowedSets[vreg].empty() && "vreg already has pregs.");<br>
> -<br>
> -      node2VReg[nodeId] = vreg;<br>
> -      vreg2Node[vreg] = nodeId;<br>
> -      std::copy(arBegin, arEnd, std::back_inserter(allowedSets[vreg]));<br>
> -    }<br>
> -<br>
> -    /// Get the virtual register corresponding to the given PBQP node.<br>
> -    unsigned getVRegForNode(PBQPRAGraph::NodeId nodeId) const;<br>
> -<br>
> -    /// Get the PBQP node corresponding to the given virtual register.<br>
> -    PBQPRAGraph::NodeId getNodeForVReg(unsigned vreg) const;<br>
> -<br>
> -    /// Returns true if the given PBQP option represents a physical register,<br>
> -    /// false otherwise.<br>
> -    bool isPRegOption(unsigned vreg, unsigned option) const {<br>
> -      // At present we only have spills or pregs, so anything that's not a<br>
> -      // spill is a preg. (This might be extended one day to support remat).<br>
> -      return !isSpillOption(vreg, option);<br>
> -    }<br>
> -<br>
> -    /// Returns true if the given PBQP option represents spilling, false<br>
> -    /// otherwise.<br>
> -    bool isSpillOption(unsigned vreg, unsigned option) const {<br>
> -      // We hardcode option zero as the spill option.<br>
> -      return option == 0;<br>
> -    }<br>
> -<br>
> -    /// Returns the allowed set for the given virtual register.<br>
> -    const AllowedSet& getAllowedSet(unsigned vreg) const;<br>
> -<br>
> -    /// Get PReg for option.<br>
> -    unsigned getPRegForOption(unsigned vreg, unsigned option) const;<br>
> -<br>
> -  private:<br>
> -<br>
> -    typedef std::map<PBQPRAGraph::NodeId, unsigned>  Node2VReg;<br>
> -    typedef DenseMap<unsigned, PBQPRAGraph::NodeId> VReg2Node;<br>
> -    typedef DenseMap<unsigned, AllowedSet> AllowedSetMap;<br>
> -<br>
> -    PBQPRAGraph graph;<br>
> -    Node2VReg node2VReg;<br>
> -    VReg2Node vreg2Node;<br>
> -<br>
> -    AllowedSetMap allowedSets;<br>
> -<br>
> -  };<br>
> -<br>
> -  /// Builds PBQP instances to represent register allocation problems. Includes<br>
> -  /// spill, interference and coalescing costs by default. You can extend this<br>
> -  /// class to support additional constraints for your architecture.<br>
> -  class PBQPBuilder {<br>
> -  private:<br>
> -    PBQPBuilder(const PBQPBuilder&) LLVM_DELETED_FUNCTION;<br>
> -    void operator=(const PBQPBuilder&) LLVM_DELETED_FUNCTION;<br>
> -  public:<br>
> -<br>
> -    typedef std::set<unsigned> RegSet;<br>
> -<br>
> -    /// Default constructor.<br>
> -    PBQPBuilder() {}<br>
> -<br>
> -    /// Clean up a PBQPBuilder.<br>
> -    virtual ~PBQPBuilder() {}<br>
> -<br>
> -    /// Build a PBQP instance to represent the register allocation problem for<br>
> -    /// the given MachineFunction.<br>
> -    virtual std::unique_ptr<PBQPRAProblem><br>
> -    build(MachineFunction *mf, const LiveIntervals *lis,<br>
> -          const MachineBlockFrequencyInfo *mbfi, const RegSet &vregs);<br>
> -<br>
> -  private:<br>
> -<br>
> -    void addSpillCosts(PBQP::Vector &costVec, PBQP::PBQPNum spillCost);<br>
> -<br>
> -    void addInterferenceCosts(PBQP::Matrix &costMat,<br>
> -                              const PBQPRAProblem::AllowedSet &vr1Allowed,<br>
> -                              const PBQPRAProblem::AllowedSet &vr2Allowed,<br>
> -                              const TargetRegisterInfo *tri);<br>
> -  };<br>
> -<br>
> -  /// Extended builder which adds coalescing constraints to a problem.<br>
> -  class PBQPBuilderWithCoalescing : public PBQPBuilder {<br>
> -  public:<br>
> -<br>
> -    /// Build a PBQP instance to represent the register allocation problem for<br>
> -    /// the given MachineFunction.<br>
> -    std::unique_ptr<PBQPRAProblem> build(MachineFunction *mf,<br>
> -                                         const LiveIntervals *lis,<br>
> -                                         const MachineBlockFrequencyInfo *mbfi,<br>
> -                                         const RegSet &vregs) override;<br>
> -<br>
> -  private:<br>
> -<br>
> -    void addPhysRegCoalesce(PBQP::Vector &costVec, unsigned pregOption,<br>
> -                            PBQP::PBQPNum benefit);<br>
> -<br>
> -    void addVirtRegCoalesce(PBQP::Matrix &costMat,<br>
> -                            const PBQPRAProblem::AllowedSet &vr1Allowed,<br>
> -                            const PBQPRAProblem::AllowedSet &vr2Allowed,<br>
> -                            PBQP::PBQPNum benefit);<br>
> -  };<br>
> -<br>
> +  /// @brief Create a PBQP register allocator instance.<br>
>    FunctionPass *<br>
> -  createPBQPRegisterAllocator(std::unique_ptr<PBQPBuilder> builder,<br>
> -                              char *customPassID = nullptr);<br>
> +  createPBQPRegisterAllocator(char *customPassID = nullptr);<br>
>  }<br>
><br>
>  #endif /* LLVM_CODEGEN_REGALLOCPBQP_H */<br>
><br>
> Modified: llvm/trunk/include/llvm/Target/TargetSubtargetInfo.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSubtargetInfo.h?rev=219421&r1=219420&r2=219421&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSubtargetInfo.h?rev=219421&r1=219420&r2=219421&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/Target/TargetSubtargetInfo.h (original)<br>
> +++ llvm/trunk/include/llvm/Target/TargetSubtargetInfo.h Thu Oct  9 13:20:51 2014<br>
> @@ -14,6 +14,7 @@<br>
>  #ifndef LLVM_TARGET_TARGETSUBTARGETINFO_H<br>
>  #define LLVM_TARGET_TARGETSUBTARGETINFO_H<br>
><br>
> +#include "llvm/CodeGen/PBQPRAConstraint.h"<br>
>  #include "llvm/MC/MCSubtargetInfo.h"<br>
>  #include "llvm/Support/CodeGen.h"<br>
><br>
> @@ -160,6 +161,13 @@ public:<br>
><br>
>    /// \brief Enable the use of the early if conversion pass.<br>
>    virtual bool enableEarlyIfConversion() const { return false; }<br>
> +<br>
> +  /// \brief Return PBQPConstraint(s) for the target.<br>
> +  ///<br>
> +  /// Override to provide custom PBQP constraints.<br>
> +  virtual std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const {<br>
> +    return nullptr;<br>
> +  }<br>
>  };<br>
><br>
>  } // End llvm namespace<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=219421&r1=219420&r2=219421&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp?rev=219421&r1=219420&r2=219421&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp (original)<br>
> +++ llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp Thu Oct  9 13:20:51 2014<br>
> @@ -62,17 +62,17 @@ using namespace llvm;<br>
>  #define DEBUG_TYPE "regalloc"<br>
><br>
>  static RegisterRegAlloc<br>
> -registerPBQPRepAlloc("pbqp", "PBQP register allocator",<br>
> +RegisterPBQPRepAlloc("pbqp", "PBQP register allocator",<br>
>                         createDefaultPBQPRegisterAllocator);<br>
><br>
>  static cl::opt<bool><br>
> -pbqpCoalescing("pbqp-coalescing",<br>
> +PBQPCoalescing("pbqp-coalescing",<br>
>                  cl::desc("Attempt coalescing during PBQP register allocation."),<br>
>                  cl::init(false), cl::Hidden);<br>
><br>
>  #ifndef NDEBUG<br>
>  static cl::opt<bool><br>
> -pbqpDumpGraphs("pbqp-dump-graphs",<br>
> +PBQPDumpGraphs("pbqp-dump-graphs",<br>
>                 cl::desc("Dump graphs for each function/round in the compilation unit."),<br>
>                 cl::init(false), cl::Hidden);<br>
>  #endif<br>
> @@ -89,8 +89,8 @@ public:<br>
>    static char ID;<br>
><br>
>    /// Construct a PBQP register allocator.<br>
> -  RegAllocPBQP(std::unique_ptr<PBQPBuilder> b, char *cPassID = nullptr)<br>
> -      : MachineFunctionPass(ID), builder(std::move(b)), customPassID(cPassID) {<br>
> +  RegAllocPBQP(char *cPassID = nullptr)<br>
> +      : MachineFunctionPass(ID), customPassID(cPassID) {<br>
>      initializeSlotIndexesPass(*PassRegistry::getPassRegistry());<br>
>      initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());<br>
>      initializeLiveStacksPass(*PassRegistry::getPassRegistry());<br>
> @@ -118,301 +118,198 @@ private:<br>
>    typedef std::map<RegPair, PBQP::PBQPNum> CoalesceMap;<br>
>    typedef std::set<unsigned> RegSet;<br>
><br>
> -  std::unique_ptr<PBQPBuilder> builder;<br>
> -<br>
>    char *customPassID;<br>
><br>
> -  MachineFunction *mf;<br>
> -  const TargetMachine *tm;<br>
> -  const TargetRegisterInfo *tri;<br>
> -  const TargetInstrInfo *tii;<br>
> -  MachineRegisterInfo *mri;<br>
> -  const MachineBlockFrequencyInfo *mbfi;<br>
> -<br>
> -  std::unique_ptr<Spiller> spiller;<br>
> -  LiveIntervals *lis;<br>
> -  LiveStacks *lss;<br>
> -  VirtRegMap *vrm;<br>
> -<br>
> -  RegSet vregsToAlloc, emptyIntervalVRegs;<br>
> +  RegSet VRegsToAlloc, EmptyIntervalVRegs;<br>
><br>
>    /// \brief Finds the initial set of vreg intervals to allocate.<br>
> -  void findVRegIntervalsToAlloc();<br>
> +  void findVRegIntervalsToAlloc(const MachineFunction &MF, LiveIntervals &LIS);<br>
> +<br>
> +  /// \brief Constructs an initial graph.<br>
> +  void initializeGraph(PBQPRAGraph &G);<br>
><br>
>    /// \brief Given a solved PBQP problem maps this solution back to a register<br>
>    /// assignment.<br>
> -  bool mapPBQPToRegAlloc(const PBQPRAProblem &problem,<br>
> -                         const PBQP::Solution &solution);<br>
> +  bool mapPBQPToRegAlloc(const PBQPRAGraph &G,<br>
> +                         const PBQP::Solution &Solution,<br>
> +                         VirtRegMap &VRM,<br>
> +                         Spiller &VRegSpiller);<br>
><br>
>    /// \brief Postprocessing before final spilling. Sets basic block "live in"<br>
>    /// variables.<br>
> -  void finalizeAlloc() const;<br>
> +  void finalizeAlloc(MachineFunction &MF, LiveIntervals &LIS,<br>
> +                     VirtRegMap &VRM) const;<br>
><br>
>  };<br>
><br>
>  char RegAllocPBQP::ID = 0;<br>
><br>
> -} // End anonymous namespace.<br>
> -<br>
> -unsigned PBQPRAProblem::getVRegForNode(PBQPRAGraph::NodeId node) const {<br>
> -  Node2VReg::const_iterator vregItr = node2VReg.find(node);<br>
> -  assert(vregItr != node2VReg.end() && "No vreg for node.");<br>
> -  return vregItr->second;<br>
> -}<br>
> -<br>
> -PBQPRAGraph::NodeId PBQPRAProblem::getNodeForVReg(unsigned vreg) const {<br>
> -  VReg2Node::const_iterator nodeItr = vreg2Node.find(vreg);<br>
> -  assert(nodeItr != vreg2Node.end() && "No node for vreg.");<br>
> -  return nodeItr->second;<br>
> -<br>
> -}<br>
> -<br>
> -const PBQPRAProblem::AllowedSet&<br>
> -  PBQPRAProblem::getAllowedSet(unsigned vreg) const {<br>
> -  AllowedSetMap::const_iterator allowedSetItr = allowedSets.find(vreg);<br>
> -  assert(allowedSetItr != allowedSets.end() && "No pregs for vreg.");<br>
> -  const AllowedSet &allowedSet = allowedSetItr->second;<br>
> -  return allowedSet;<br>
> -}<br>
> -<br>
> -unsigned PBQPRAProblem::getPRegForOption(unsigned vreg, unsigned option) const {<br>
> -  assert(isPRegOption(vreg, option) && "Not a preg option.");<br>
> -<br>
> -  const AllowedSet& allowedSet = getAllowedSet(vreg);<br>
> -  assert(option <= allowedSet.size() && "Option outside allowed set.");<br>
> -  return allowedSet[option - 1];<br>
> -}<br>
> +/// @brief Set spill costs for each node in the PBQP reg-alloc graph.<br>
> +class SpillCosts : public PBQPRAConstraint {<br>
> +public:<br>
> +  void apply(PBQPRAGraph &G) override {<br>
> +    LiveIntervals &LIS = G.getMetadata().LIS;<br>
><br>
> -std::unique_ptr<PBQPRAProblem><br>
> -PBQPBuilder::build(MachineFunction *mf, const LiveIntervals *lis,<br>
> -                   const MachineBlockFrequencyInfo *mbfi, const RegSet &vregs) {<br>
> -<br>
> -  LiveIntervals *LIS = const_cast<LiveIntervals*>(lis);<br>
> -  MachineRegisterInfo *mri = &mf->getRegInfo();<br>
> -  const TargetRegisterInfo *tri = mf->getSubtarget().getRegisterInfo();<br>
> -<br>
> -  auto p = llvm::make_unique<PBQPRAProblem>();<br>
> -  PBQPRAGraph &g = p->getGraph();<br>
> -  RegSet pregs;<br>
> -<br>
> -  // Collect the set of preg intervals, record that they're used in the MF.<br>
> -  for (unsigned Reg = 1, e = tri->getNumRegs(); Reg != e; ++Reg) {<br>
> -    if (mri->def_empty(Reg))<br>
> -      continue;<br>
> -    pregs.insert(Reg);<br>
> -    mri->setPhysRegUsed(Reg);<br>
> +    for (auto NId : G.nodeIds()) {<br>
> +      PBQP::PBQPNum SpillCost =<br>
> +        LIS.getInterval(G.getNodeMetadata(NId).getVReg()).weight;<br>
> +      if (SpillCost == 0.0)<br>
> +        SpillCost = std::numeric_limits<PBQP::PBQPNum>::min();<br>
> +      PBQPRAGraph::RawVector NodeCosts(G.getNodeCosts(NId));<br>
> +      NodeCosts[PBQP::RegAlloc::getSpillOptionIdx()] = SpillCost;<br>
> +      G.setNodeCosts(NId, std::move(NodeCosts));<br>
> +    }<br>
>    }<br>
> +};<br>
><br>
> -  // Iterate over vregs.<br>
> -  for (RegSet::const_iterator vregItr = vregs.begin(), vregEnd = vregs.end();<br>
> -       vregItr != vregEnd; ++vregItr) {<br>
> -    unsigned vreg = *vregItr;<br>
> -    const TargetRegisterClass *trc = mri->getRegClass(vreg);<br>
> -    LiveInterval *vregLI = &LIS->getInterval(vreg);<br>
> -<br>
> -    // Record any overlaps with regmask operands.<br>
> -    BitVector regMaskOverlaps;<br>
> -    LIS->checkRegMaskInterference(*vregLI, regMaskOverlaps);<br>
> -<br>
> -    // Compute an initial allowed set for the current vreg.<br>
> -    typedef std::vector<unsigned> VRAllowed;<br>
> -    VRAllowed vrAllowed;<br>
> -    ArrayRef<MCPhysReg> rawOrder = trc->getRawAllocationOrder(*mf);<br>
> -    for (unsigned i = 0; i != rawOrder.size(); ++i) {<br>
> -      unsigned preg = rawOrder[i];<br>
> -      if (mri->isReserved(preg))<br>
> -        continue;<br>
> -<br>
> -      // vregLI crosses a regmask operand that clobbers preg.<br>
> -      if (!regMaskOverlaps.empty() && !regMaskOverlaps.test(preg))<br>
> -        continue;<br>
> +/// @brief Add interference edges between overlapping vregs.<br>
> +class Interference : public PBQPRAConstraint {<br>
> +public:<br>
><br>
> -      // vregLI overlaps fixed regunit interference.<br>
> -      bool Interference = false;<br>
> -      for (MCRegUnitIterator Units(preg, tri); Units.isValid(); ++Units) {<br>
> -        if (vregLI->overlaps(LIS->getRegUnit(*Units))) {<br>
> -          Interference = true;<br>
> -          break;<br>
> +  void apply(PBQPRAGraph &G) override {<br>
> +    LiveIntervals &LIS = G.getMetadata().LIS;<br>
> +    const TargetRegisterInfo &TRI =<br>
> +      *G.getMetadata().MF.getTarget().getSubtargetImpl()->getRegisterInfo();<br>
> +<br>
> +    for (auto NItr = G.nodeIds().begin(), NEnd = G.nodeIds().end();<br>
> +         NItr != NEnd; ++NItr) {<br>
> +      auto NId = *NItr;<br>
> +      unsigned NVReg = G.getNodeMetadata(NId).getVReg();<br>
> +      LiveInterval &NLI = LIS.getInterval(NVReg);<br>
> +<br>
> +      for (auto MItr = std::next(NItr); MItr != NEnd; ++MItr) {<br>
> +        auto MId = *MItr;<br>
> +        unsigned MVReg = G.getNodeMetadata(MId).getVReg();<br>
> +        LiveInterval &MLI = LIS.getInterval(MVReg);<br>
> +<br>
> +        if (NLI.overlaps(MLI)) {<br>
> +          const auto &NOpts = G.getNodeMetadata(NId).getOptionRegs();<br>
> +          const auto &MOpts = G.getNodeMetadata(MId).getOptionRegs();<br>
> +          G.addEdge(NId, MId, createInterferenceMatrix(TRI, NOpts, MOpts));<br>
>          }<br>
>        }<br>
> -      if (Interference)<br>
> -        continue;<br>
> -<br>
> -      // preg is usable for this virtual register.<br>
> -      vrAllowed.push_back(preg);<br>
>      }<br>
> -<br>
> -    PBQP::Vector nodeCosts(vrAllowed.size() + 1, 0);<br>
> -<br>
> -    PBQP::PBQPNum spillCost = (vregLI->weight != 0.0) ?<br>
> -        vregLI->weight : std::numeric_limits<PBQP::PBQPNum>::min();<br>
> -<br>
> -    addSpillCosts(nodeCosts, spillCost);<br>
> -<br>
> -    // Construct the node.<br>
> -    PBQPRAGraph::NodeId nId = g.addNode(std::move(nodeCosts));<br>
> -<br>
> -    // Record the mapping and allowed set in the problem.<br>
> -    p->recordVReg(vreg, nId, vrAllowed.begin(), vrAllowed.end());<br>
> -<br>
>    }<br>
><br>
> -  for (RegSet::const_iterator vr1Itr = vregs.begin(), vrEnd = vregs.end();<br>
> -         vr1Itr != vrEnd; ++vr1Itr) {<br>
> -    unsigned vr1 = *vr1Itr;<br>
> -    const LiveInterval &l1 = lis->getInterval(vr1);<br>
> -    const PBQPRAProblem::AllowedSet &vr1Allowed = p->getAllowedSet(vr1);<br>
> -<br>
> -    for (RegSet::const_iterator vr2Itr = std::next(vr1Itr); vr2Itr != vrEnd;<br>
> -         ++vr2Itr) {<br>
> -      unsigned vr2 = *vr2Itr;<br>
> -      const LiveInterval &l2 = lis->getInterval(vr2);<br>
> -      const PBQPRAProblem::AllowedSet &vr2Allowed = p->getAllowedSet(vr2);<br>
> -<br>
> -      assert(!l2.empty() && "Empty interval in vreg set?");<br>
> -      if (l1.overlaps(l2)) {<br>
> -        PBQP::Matrix edgeCosts(vr1Allowed.size()+1, vr2Allowed.size()+1, 0);<br>
> -        addInterferenceCosts(edgeCosts, vr1Allowed, vr2Allowed, tri);<br>
> +private:<br>
><br>
> -        g.addEdge(p->getNodeForVReg(vr1), p->getNodeForVReg(vr2),<br>
> -                  std::move(edgeCosts));<br>
> +  PBQPRAGraph::RawMatrix createInterferenceMatrix(<br>
> +                       const TargetRegisterInfo &TRI,<br>
> +                       const PBQPRAGraph::NodeMetadata::OptionToRegMap &NOpts,<br>
> +                       const PBQPRAGraph::NodeMetadata::OptionToRegMap &MOpts) {<br>
> +    PBQPRAGraph::RawMatrix M(NOpts.size() + 1, MOpts.size() + 1, 0);<br>
> +    for (unsigned I = 0; I != NOpts.size(); ++I) {<br>
> +      unsigned PRegN = NOpts[I];<br>
> +      for (unsigned J = 0; J != MOpts.size(); ++J) {<br>
> +        unsigned PRegM = MOpts[J];<br>
> +        if (TRI.regsOverlap(PRegN, PRegM))<br>
> +          M[I + 1][J + 1] = std::numeric_limits<PBQP::PBQPNum>::infinity();<br>
>        }<br>
>      }<br>
> +<br>
> +    return M;<br>
>    }<br>
> +};<br>
><br>
> -  return p;<br>
> -}<br>
><br>
> -void PBQPBuilder::addSpillCosts(PBQP::Vector &costVec,<br>
> -                                PBQP::PBQPNum spillCost) {<br>
> -  costVec[0] = spillCost;<br>
> -}<br>
> +class Coalescing : public PBQPRAConstraint {<br>
> +public:<br>
> +  void apply(PBQPRAGraph &G) override {<br>
> +    MachineFunction &MF = G.getMetadata().MF;<br>
> +    MachineBlockFrequencyInfo &MBFI = G.getMetadata().MBFI;<br>
> +    CoalescerPair CP(*MF.getTarget().getSubtargetImpl()->getRegisterInfo());<br>
> +<br>
> +    // Scan the machine function and add a coalescing cost whenever CoalescerPair<br>
> +    // gives the Ok.<br>
> +    for (const auto &MBB : MF) {<br>
> +      for (const auto &MI : MBB) {<br>
><br>
> -void PBQPBuilder::addInterferenceCosts(<br>
> -                                    PBQP::Matrix &costMat,<br>
> -                                    const PBQPRAProblem::AllowedSet &vr1Allowed,<br>
> -                                    const PBQPRAProblem::AllowedSet &vr2Allowed,<br>
> -                                    const TargetRegisterInfo *tri) {<br>
> -  assert(costMat.getRows() == vr1Allowed.size() + 1 && "Matrix height mismatch.");<br>
> -  assert(costMat.getCols() == vr2Allowed.size() + 1 && "Matrix width mismatch.");<br>
> +        // Skip not-coalescable or already coalesced copies.<br>
> +        if (!CP.setRegisters(&MI) || CP.getSrcReg() == CP.getDstReg())<br>
> +          continue;<br>
><br>
> -  for (unsigned i = 0; i != vr1Allowed.size(); ++i) {<br>
> -    unsigned preg1 = vr1Allowed[i];<br>
> +        unsigned DstReg = CP.getDstReg();<br>
> +        unsigned SrcReg = CP.getSrcReg();<br>
><br>
> -    for (unsigned j = 0; j != vr2Allowed.size(); ++j) {<br>
> -      unsigned preg2 = vr2Allowed[j];<br>
> +        const float CopyFactor = 0.5; // Cost of copy relative to load. Current<br>
> +                                      // value plucked randomly out of the air.<br>
><br>
> -      if (tri->regsOverlap(preg1, preg2)) {<br>
> -        costMat[i + 1][j + 1] = std::numeric_limits<PBQP::PBQPNum>::infinity();<br>
> -      }<br>
> -    }<br>
> -  }<br>
> -}<br>
> +        PBQP::PBQPNum CBenefit =<br>
> +          CopyFactor * LiveIntervals::getSpillWeight(false, true, &MBFI, &MI);<br>
><br>
> -std::unique_ptr<PBQPRAProblem><br>
> -PBQPBuilderWithCoalescing::build(MachineFunction *mf, const LiveIntervals *lis,<br>
> -                                 const MachineBlockFrequencyInfo *mbfi,<br>
> -                                 const RegSet &vregs) {<br>
> -<br>
> -  std::unique_ptr<PBQPRAProblem> p = PBQPBuilder::build(mf, lis, mbfi, vregs);<br>
> -  PBQPRAGraph &g = p->getGraph();<br>
> -<br>
> -  const TargetMachine &tm = mf->getTarget();<br>
> -  CoalescerPair cp(*tm.getSubtargetImpl()->getRegisterInfo());<br>
> -<br>
> -  // Scan the machine function and add a coalescing cost whenever CoalescerPair<br>
> -  // gives the Ok.<br>
> -  for (const auto &mbb : *mf) {<br>
> -    for (const auto &mi : mbb) {<br>
> -      if (!cp.setRegisters(&mi)) {<br>
> -        continue; // Not coalescable.<br>
> -      }<br>
> -<br>
> -      if (cp.getSrcReg() == cp.getDstReg()) {<br>
> -        continue; // Already coalesced.<br>
> -      }<br>
> +        if (CP.isPhys()) {<br>
> +          if (!MF.getRegInfo().isAllocatable(DstReg))<br>
> +            continue;<br>
><br>
> -      unsigned dst = cp.getDstReg(),<br>
> -               src = cp.getSrcReg();<br>
> +          PBQPRAGraph::NodeId NId = G.getMetadata().getNodeIdForVReg(SrcReg);<br>
><br>
> -      const float copyFactor = 0.5; // Cost of copy relative to load. Current<br>
> -      // value plucked randomly out of the air.<br>
> +          const PBQPRAGraph::NodeMetadata::OptionToRegMap &Allowed =<br>
> +            G.getNodeMetadata(NId).getOptionRegs();<br>
><br>
> -      PBQP::PBQPNum cBenefit =<br>
> -        copyFactor * LiveIntervals::getSpillWeight(false, true, mbfi, &mi);<br>
> +          unsigned PRegOpt = 0;<br>
> +          while (PRegOpt < Allowed.size() && Allowed[PRegOpt] != DstReg)<br>
> +            ++PRegOpt;<br>
><br>
> -      if (cp.isPhys()) {<br>
> -        if (!mf->getRegInfo().isAllocatable(dst)) {<br>
> -          continue;<br>
> -        }<br>
> -<br>
> -        const PBQPRAProblem::AllowedSet &allowed = p->getAllowedSet(src);<br>
> -        unsigned pregOpt = 0;<br>
> -        while (pregOpt < allowed.size() && allowed[pregOpt] != dst) {<br>
> -          ++pregOpt;<br>
> -        }<br>
> -        if (pregOpt < allowed.size()) {<br>
> -          ++pregOpt; // +1 to account for spill option.<br>
> -          PBQPRAGraph::NodeId node = p->getNodeForVReg(src);<br>
> -          DEBUG(llvm::dbgs() << "Reading node costs for node " << node << "\n");<br>
> -          DEBUG(llvm::dbgs() << "Source node: " << &g.getNodeCosts(node) << "\n");<br>
> -          PBQP::Vector newCosts(g.getNodeCosts(node));<br>
> -          addPhysRegCoalesce(newCosts, pregOpt, cBenefit);<br>
> -          g.setNodeCosts(node, newCosts);<br>
> -        }<br>
> -      } else {<br>
> -        const PBQPRAProblem::AllowedSet *allowed1 = &p->getAllowedSet(dst);<br>
> -        const PBQPRAProblem::AllowedSet *allowed2 = &p->getAllowedSet(src);<br>
> -        PBQPRAGraph::NodeId node1 = p->getNodeForVReg(dst);<br>
> -        PBQPRAGraph::NodeId node2 = p->getNodeForVReg(src);<br>
> -        PBQPRAGraph::EdgeId edge = g.findEdge(node1, node2);<br>
> -        if (edge == g.invalidEdgeId()) {<br>
> -          PBQP::Matrix costs(allowed1->size() + 1, allowed2->size() + 1, 0);<br>
> -          addVirtRegCoalesce(costs, *allowed1, *allowed2, cBenefit);<br>
> -          g.addEdge(node1, node2, costs);<br>
> +          if (PRegOpt < Allowed.size()) {<br>
> +            PBQPRAGraph::RawVector NewCosts(G.getNodeCosts(NId));<br>
> +            NewCosts[PRegOpt + 1] += CBenefit;<br>
> +            G.setNodeCosts(NId, std::move(NewCosts));<br>
> +          }<br>
>          } else {<br>
> -          if (g.getEdgeNode1Id(edge) == node2) {<br>
> -            std::swap(node1, node2);<br>
> -            std::swap(allowed1, allowed2);<br>
> +          PBQPRAGraph::NodeId N1Id = G.getMetadata().getNodeIdForVReg(DstReg);<br>
> +          PBQPRAGraph::NodeId N2Id = G.getMetadata().getNodeIdForVReg(SrcReg);<br>
> +          const PBQPRAGraph::NodeMetadata::OptionToRegMap *Allowed1 =<br>
> +            &G.getNodeMetadata(N1Id).getOptionRegs();<br>
> +          const PBQPRAGraph::NodeMetadata::OptionToRegMap *Allowed2 =<br>
> +            &G.getNodeMetadata(N2Id).getOptionRegs();<br>
> +<br>
> +          PBQPRAGraph::EdgeId EId = G.findEdge(N1Id, N2Id);<br>
> +          if (EId == G.invalidEdgeId()) {<br>
> +            PBQPRAGraph::RawMatrix Costs(Allowed1->size() + 1,<br>
> +                                         Allowed2->size() + 1, 0);<br>
> +            addVirtRegCoalesce(Costs, *Allowed1, *Allowed2, CBenefit);<br>
> +            G.addEdge(N1Id, N2Id, std::move(Costs));<br>
> +          } else {<br>
> +            if (G.getEdgeNode1Id(EId) == N2Id) {<br>
> +              std::swap(N1Id, N2Id);<br>
> +              std::swap(Allowed1, Allowed2);<br>
> +            }<br>
> +            PBQPRAGraph::RawMatrix Costs(G.getEdgeCosts(EId));<br>
> +            addVirtRegCoalesce(Costs, *Allowed1, *Allowed2, CBenefit);<br>
> +            G.setEdgeCosts(EId, std::move(Costs));<br>
>            }<br>
> -          PBQP::Matrix costs(g.getEdgeCosts(edge));<br>
> -          addVirtRegCoalesce(costs, *allowed1, *allowed2, cBenefit);<br>
> -          g.setEdgeCosts(edge, costs);<br>
>          }<br>
>        }<br>
>      }<br>
>    }<br>
><br>
> -  return p;<br>
> -}<br>
> -<br>
> -void PBQPBuilderWithCoalescing::addPhysRegCoalesce(PBQP::Vector &costVec,<br>
> -                                                   unsigned pregOption,<br>
> -                                                   PBQP::PBQPNum benefit) {<br>
> -  costVec[pregOption] += -benefit;<br>
> -}<br>
> -<br>
> -void PBQPBuilderWithCoalescing::addVirtRegCoalesce(<br>
> -                                    PBQP::Matrix &costMat,<br>
> -                                    const PBQPRAProblem::AllowedSet &vr1Allowed,<br>
> -                                    const PBQPRAProblem::AllowedSet &vr2Allowed,<br>
> -                                    PBQP::PBQPNum benefit) {<br>
> -<br>
> -  assert(costMat.getRows() == vr1Allowed.size() + 1 && "Size mismatch.");<br>
> -  assert(costMat.getCols() == vr2Allowed.size() + 1 && "Size mismatch.");<br>
> -<br>
> -  for (unsigned i = 0; i != vr1Allowed.size(); ++i) {<br>
> -    unsigned preg1 = vr1Allowed[i];<br>
> -    for (unsigned j = 0; j != vr2Allowed.size(); ++j) {<br>
> -      unsigned preg2 = vr2Allowed[j];<br>
> +private:<br>
><br>
> -      if (preg1 == preg2) {<br>
> -        costMat[i + 1][j + 1] += -benefit;<br>
> +  void addVirtRegCoalesce(<br>
> +                      PBQPRAGraph::RawMatrix &CostMat,<br>
> +                      const PBQPRAGraph::NodeMetadata::OptionToRegMap &Allowed1,<br>
> +                      const PBQPRAGraph::NodeMetadata::OptionToRegMap &Allowed2,<br>
> +                      PBQP::PBQPNum Benefit) {<br>
> +    assert(CostMat.getRows() == Allowed1.size() + 1 && "Size mismatch.");<br>
> +    assert(CostMat.getCols() == Allowed2.size() + 1 && "Size mismatch.");<br>
> +    for (unsigned I = 0; I != Allowed1.size(); ++I) {<br>
> +      unsigned PReg1 = Allowed1[I];<br>
> +      for (unsigned J = 0; J != Allowed2.size(); ++J) {<br>
> +        unsigned PReg2 = Allowed2[J];<br>
> +        if (PReg1 == PReg2)<br>
> +          CostMat[I + 1][J + 1] += -Benefit;<br>
>        }<br>
>      }<br>
>    }<br>
> -}<br>
><br>
> +};<br>
> +<br>
> +} // End anonymous namespace.<br>
> +<br>
> +// Out-of-line destructor/anchor for PBQPRAConstraint.<br>
> +PBQPRAConstraint::~PBQPRAConstraint() {}<br>
> +void PBQPRAConstraint::anchor() {}<br>
> +void PBQPRAConstraintList::anchor() {}<br>
><br>
>  void RegAllocPBQP::getAnalysisUsage(AnalysisUsage &au) const {<br>
>    au.setPreservesCFG();<br>
> @@ -438,118 +335,173 @@ void RegAllocPBQP::getAnalysisUsage(Anal<br>
>    MachineFunctionPass::getAnalysisUsage(au);<br>
>  }<br>
><br>
> -void RegAllocPBQP::findVRegIntervalsToAlloc() {<br>
> +void RegAllocPBQP::findVRegIntervalsToAlloc(const MachineFunction &MF,<br>
> +                                            LiveIntervals &LIS) {<br>
> +  const MachineRegisterInfo &MRI = MF.getRegInfo();<br>
><br>
>    // Iterate over all live ranges.<br>
> -  for (unsigned i = 0, e = mri->getNumVirtRegs(); i != e; ++i) {<br>
> -    unsigned Reg = TargetRegisterInfo::index2VirtReg(i);<br>
> -    if (mri->reg_nodbg_empty(Reg))<br>
> +  for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {<br>
> +    unsigned Reg = TargetRegisterInfo::index2VirtReg(I);<br>
> +    if (MRI.reg_nodbg_empty(Reg))<br>
>        continue;<br>
> -    LiveInterval *li = &lis->getInterval(Reg);<br>
> +    LiveInterval &LI = LIS.getInterval(Reg);<br>
><br>
>      // If this live interval is non-empty we will use pbqp to allocate it.<br>
>      // Empty intervals we allocate in a simple post-processing stage in<br>
>      // finalizeAlloc.<br>
> -    if (!li->empty()) {<br>
> -      vregsToAlloc.insert(li->reg);<br>
> +    if (!LI.empty()) {<br>
> +      VRegsToAlloc.insert(LI.reg);<br>
>      } else {<br>
> -      emptyIntervalVRegs.insert(li->reg);<br>
> +      EmptyIntervalVRegs.insert(LI.reg);<br>
>      }<br>
>    }<br>
>  }<br>
><br>
> -bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAProblem &problem,<br>
> -                                     const PBQP::Solution &solution) {<br>
> +void RegAllocPBQP::initializeGraph(PBQPRAGraph &G) {<br>
> +  MachineFunction &MF = G.getMetadata().MF;<br>
> +<br>
> +  LiveIntervals &LIS = G.getMetadata().LIS;<br>
> +  const MachineRegisterInfo &MRI = G.getMetadata().MF.getRegInfo();<br>
> +  const TargetRegisterInfo &TRI =<br>
> +    *G.getMetadata().MF.getTarget().getSubtargetImpl()->getRegisterInfo();<br>
> +<br>
> +  for (auto VReg : VRegsToAlloc) {<br>
> +    const TargetRegisterClass *TRC = MRI.getRegClass(VReg);<br>
> +    LiveInterval &VRegLI = LIS.getInterval(VReg);<br>
> +<br>
> +    // Record any overlaps with regmask operands.<br>
> +    BitVector RegMaskOverlaps;<br>
> +    LIS.checkRegMaskInterference(VRegLI, RegMaskOverlaps);<br>
> +<br>
> +    // Compute an initial allowed set for the current vreg.<br>
> +    std::vector<unsigned> VRegAllowed;<br>
> +    ArrayRef<MCPhysReg> RawPRegOrder = TRC->getRawAllocationOrder(MF);<br>
> +    for (unsigned I = 0; I != RawPRegOrder.size(); ++I) {<br>
> +      unsigned PReg = RawPRegOrder[I];<br>
> +      if (MRI.isReserved(PReg))<br>
> +        continue;<br>
> +<br>
> +      // vregLI crosses a regmask operand that clobbers preg.<br>
> +      if (!RegMaskOverlaps.empty() && !RegMaskOverlaps.test(PReg))<br>
> +        continue;<br>
> +<br>
> +      // vregLI overlaps fixed regunit interference.<br>
> +      bool Interference = false;<br>
> +      for (MCRegUnitIterator Units(PReg, &TRI); Units.isValid(); ++Units) {<br>
> +        if (VRegLI.overlaps(LIS.getRegUnit(*Units))) {<br>
> +          Interference = true;<br>
> +          break;<br>
> +        }<br>
> +      }<br>
> +      if (Interference)<br>
> +        continue;<br>
> +<br>
> +      // preg is usable for this virtual register.<br>
> +      VRegAllowed.push_back(PReg);<br>
> +    }<br>
> +<br>
> +    PBQPRAGraph::RawVector NodeCosts(VRegAllowed.size() + 1, 0);<br>
> +    PBQPRAGraph::NodeId NId = G.addNode(std::move(NodeCosts));<br>
> +    G.getNodeMetadata(NId).setVReg(VReg);<br>
> +    G.getNodeMetadata(NId).setOptionRegs(std::move(VRegAllowed));<br>
> +    G.getMetadata().setNodeIdForVReg(VReg, NId);<br>
> +  }<br>
> +}<br>
> +<br>
> +bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAGraph &G,<br>
> +                                     const PBQP::Solution &Solution,<br>
> +                                     VirtRegMap &VRM,<br>
> +                                     Spiller &VRegSpiller) {<br>
> +  MachineFunction &MF = G.getMetadata().MF;<br>
> +  LiveIntervals &LIS = G.getMetadata().LIS;<br>
> +  const TargetRegisterInfo &TRI =<br>
> +    *MF.getTarget().getSubtargetImpl()->getRegisterInfo();<br>
> +  (void)TRI;<br>
> +<br>
>    // Set to true if we have any spills<br>
> -  bool anotherRoundNeeded = false;<br>
> +  bool AnotherRoundNeeded = false;<br>
><br>
>    // Clear the existing allocation.<br>
> -  vrm->clearAllVirt();<br>
> +  VRM.clearAllVirt();<br>
><br>
> -  const PBQPRAGraph &g = problem.getGraph();<br>
>    // Iterate over the nodes mapping the PBQP solution to a register<br>
>    // assignment.<br>
> -  for (auto NId : g.nodeIds()) {<br>
> -    unsigned vreg = problem.getVRegForNode(NId);<br>
> -    unsigned alloc = solution.getSelection(NId);<br>
> -<br>
> -    if (problem.isPRegOption(vreg, alloc)) {<br>
> -      unsigned preg = problem.getPRegForOption(vreg, alloc);<br>
> -      DEBUG(dbgs() << "VREG " << PrintReg(vreg, tri) << " -> "<br>
> -            << tri->getName(preg) << "\n");<br>
> -      assert(preg != 0 && "Invalid preg selected.");<br>
> -      vrm->assignVirt2Phys(vreg, preg);<br>
> -    } else if (problem.isSpillOption(vreg, alloc)) {<br>
> -      vregsToAlloc.erase(vreg);<br>
> -      SmallVector<unsigned, 8> newSpills;<br>
> -      LiveRangeEdit LRE(&lis->getInterval(vreg), newSpills, *mf, *lis, vrm);<br>
> -      spiller->spill(LRE);<br>
> +  for (auto NId : G.nodeIds()) {<br>
> +    unsigned VReg = G.getNodeMetadata(NId).getVReg();<br>
> +    unsigned AllocOption = Solution.getSelection(NId);<br>
> +<br>
> +    if (AllocOption != PBQP::RegAlloc::getSpillOptionIdx()) {<br>
> +      unsigned PReg = G.getNodeMetadata(NId).getOptionRegs()[AllocOption - 1];<br>
> +      DEBUG(dbgs() << "VREG " << PrintReg(VReg, &TRI) << " -> "<br>
> +            << TRI.getName(PReg) << "\n");<br>
> +      assert(PReg != 0 && "Invalid preg selected.");<br>
> +      VRM.assignVirt2Phys(VReg, PReg);<br>
> +    } else {<br>
> +      VRegsToAlloc.erase(VReg);<br>
> +      SmallVector<unsigned, 8> NewSpills;<br>
> +      LiveRangeEdit LRE(&LIS.getInterval(VReg), NewSpills, MF, LIS, &VRM);<br>
> +      VRegSpiller.spill(LRE);<br>
><br>
> -      DEBUG(dbgs() << "VREG " << PrintReg(vreg, tri) << " -> SPILLED (Cost: "<br>
> +      DEBUG(dbgs() << "VREG " << PrintReg(VReg, &TRI) << " -> SPILLED (Cost: "<br>
>                     << LRE.getParent().weight << ", New vregs: ");<br>
><br>
>        // Copy any newly inserted live intervals into the list of regs to<br>
>        // allocate.<br>
> -      for (LiveRangeEdit::iterator itr = LRE.begin(), end = LRE.end();<br>
> -           itr != end; ++itr) {<br>
> -        LiveInterval &li = lis->getInterval(*itr);<br>
> -        assert(!li.empty() && "Empty spill range.");<br>
> -        DEBUG(dbgs() << PrintReg(li.reg, tri) << " ");<br>
> -        vregsToAlloc.insert(li.reg);<br>
> +      for (LiveRangeEdit::iterator I = LRE.begin(), E = LRE.end();<br>
> +           I != E; ++I) {<br>
> +        LiveInterval &LI = LIS.getInterval(*I);<br>
> +        assert(!LI.empty() && "Empty spill range.");<br>
> +        DEBUG(dbgs() << PrintReg(LI.reg, &TRI) << " ");<br>
> +        VRegsToAlloc.insert(LI.reg);<br>
>        }<br>
><br>
>        DEBUG(dbgs() << ")\n");<br>
><br>
>        // We need another round if spill intervals were added.<br>
> -      anotherRoundNeeded |= !LRE.empty();<br>
> -    } else {<br>
> -      llvm_unreachable("Unknown allocation option.");<br>
> +      AnotherRoundNeeded |= !LRE.empty();<br>
>      }<br>
>    }<br>
><br>
> -  return !anotherRoundNeeded;<br>
> +  return !AnotherRoundNeeded;<br>
>  }<br>
><br>
><br>
> -void RegAllocPBQP::finalizeAlloc() const {<br>
> +void RegAllocPBQP::finalizeAlloc(MachineFunction &MF,<br>
> +                                 LiveIntervals &LIS,<br>
> +                                 VirtRegMap &VRM) const {<br>
> +  MachineRegisterInfo &MRI = MF.getRegInfo();<br>
> +<br>
>    // First allocate registers for the empty intervals.<br>
>    for (RegSet::const_iterator<br>
> -         itr = emptyIntervalVRegs.begin(), end = emptyIntervalVRegs.end();<br>
> -         itr != end; ++itr) {<br>
> -    LiveInterval *li = &lis->getInterval(*itr);<br>
> -<br>
> -    unsigned physReg = mri->getSimpleHint(li->reg);<br>
> -<br>
> -    if (physReg == 0) {<br>
> -      const TargetRegisterClass *liRC = mri->getRegClass(li->reg);<br>
> -      physReg = liRC->getRawAllocationOrder(*mf).front();<br>
> +         I = EmptyIntervalVRegs.begin(), E = EmptyIntervalVRegs.end();<br>
> +         I != E; ++I) {<br>
> +    LiveInterval &LI = LIS.getInterval(*I);<br>
> +<br>
> +    unsigned PReg = MRI.getSimpleHint(LI.reg);<br>
> +<br>
> +    if (PReg == 0) {<br>
> +      const TargetRegisterClass &RC = *MRI.getRegClass(LI.reg);<br>
> +      PReg = RC.getRawAllocationOrder(MF).front();<br>
>      }<br>
><br>
> -    vrm->assignVirt2Phys(li->reg, physReg);<br>
> +    VRM.assignVirt2Phys(LI.reg, PReg);<br>
>    }<br>
>  }<br>
><br>
>  bool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) {<br>
> +  LiveIntervals &LIS = getAnalysis<LiveIntervals>();<br>
> +  MachineBlockFrequencyInfo &MBFI =<br>
> +    getAnalysis<MachineBlockFrequencyInfo>();<br>
><br>
> -  mf = &MF;<br>
> -  tm = &mf->getTarget();<br>
> -  tri = tm->getSubtargetImpl()->getRegisterInfo();<br>
> -  tii = tm->getSubtargetImpl()->getInstrInfo();<br>
> -  mri = &mf->getRegInfo();<br>
> -<br>
> -  lis = &getAnalysis<LiveIntervals>();<br>
> -  lss = &getAnalysis<LiveStacks>();<br>
> -  mbfi = &getAnalysis<MachineBlockFrequencyInfo>();<br>
> +  calculateSpillWeightsAndHints(LIS, MF, getAnalysis<MachineLoopInfo>(), MBFI);<br>
><br>
> -  calculateSpillWeightsAndHints(*lis, MF, getAnalysis<MachineLoopInfo>(),<br>
> -                                *mbfi);<br>
> +  VirtRegMap &VRM = getAnalysis<VirtRegMap>();<br>
><br>
> -  vrm = &getAnalysis<VirtRegMap>();<br>
> -  spiller.reset(createInlineSpiller(*this, MF, *vrm));<br>
> +  std::unique_ptr<Spiller> VRegSpiller(createInlineSpiller(*this, MF, VRM));<br>
><br>
> -  mri->freezeReservedRegs(MF);<br>
> +  MF.getRegInfo().freezeReservedRegs(MF);<br>
><br>
> -  DEBUG(dbgs() << "PBQP Register Allocating for " << mf->getName() << "\n");<br>
> +  DEBUG(dbgs() << "PBQP Register Allocating for " << MF.getName() << "\n");<br>
><br>
>    // Allocator main loop:<br>
>    //<br>
> @@ -561,72 +513,72 @@ bool RegAllocPBQP::runOnMachineFunction(<br>
>    // This process is continued till no more spills are generated.<br>
><br>
>    // Find the vreg intervals in need of allocation.<br>
> -  findVRegIntervalsToAlloc();<br>
> +  findVRegIntervalsToAlloc(MF, LIS);<br>
><br>
>  #ifndef NDEBUG<br>
> -  const Function* func = mf->getFunction();<br>
> -  std::string fqn =<br>
> -    func->getParent()->getModuleIdentifier() + "." +<br>
> -    func->getName().str();<br>
> +  const Function &F = *MF.getFunction();<br>
> +  std::string FullyQualifiedName =<br>
> +    F.getParent()->getModuleIdentifier() + "." + F.getName().str();<br>
>  #endif<br>
><br>
>    // If there are non-empty intervals allocate them using pbqp.<br>
> -  if (!vregsToAlloc.empty()) {<br>
> -<br>
> -    bool pbqpAllocComplete = false;<br>
> -    unsigned round = 0;<br>
> +  if (!VRegsToAlloc.empty()) {<br>
><br>
> -    while (!pbqpAllocComplete) {<br>
> -      DEBUG(dbgs() << "  PBQP Regalloc round " << round << ":\n");<br>
> -<br>
> -      std::unique_ptr<PBQPRAProblem> problem =<br>
> -          builder->build(mf, lis, mbfi, vregsToAlloc);<br>
> +    const TargetSubtargetInfo &Subtarget = *MF.getTarget().getSubtargetImpl();<br>
> +    std::unique_ptr<PBQPRAConstraintList> ConstraintsRoot =<br>
> +      llvm::make_unique<PBQPRAConstraintList>();<br>
> +    ConstraintsRoot->addConstraint(llvm::make_unique<SpillCosts>());<br>
> +    ConstraintsRoot->addConstraint(llvm::make_unique<Interference>());<br>
> +    if (PBQPCoalescing)<br>
> +      ConstraintsRoot->addConstraint(llvm::make_unique<Coalescing>());<br>
> +    ConstraintsRoot->addConstraint(Subtarget.getCustomPBQPConstraints());<br>
> +<br>
> +    bool PBQPAllocComplete = false;<br>
> +    unsigned Round = 0;<br>
> +<br>
> +    while (!PBQPAllocComplete) {<br>
> +      DEBUG(dbgs() << "  PBQP Regalloc round " << Round << ":\n");<br>
> +<br>
> +      PBQPRAGraph G(PBQPRAGraph::GraphMetadata(MF, LIS, MBFI));<br>
> +      initializeGraph(G);<br>
> +      ConstraintsRoot->apply(G);<br>
><br>
>  #ifndef NDEBUG<br>
> -      if (pbqpDumpGraphs) {<br>
> -        std::ostringstream rs;<br>
> -        rs << round;<br>
> -        std::string graphFileName(fqn + "." + rs.str() + ".pbqpgraph");<br>
> +      if (PBQPDumpGraphs) {<br>
> +        std::ostringstream RS;<br>
> +        RS << Round;<br>
> +        std::string GraphFileName = FullyQualifiedName + "." + RS.str() +<br>
> +                                    ".pbqpgraph";<br>
>          std::error_code EC;<br>
> -        raw_fd_ostream os(graphFileName, EC, sys::fs::F_Text);<br>
> -        DEBUG(dbgs() << "Dumping graph for round " << round << " to \""<br>
> -              << graphFileName << "\"\n");<br>
> -        problem->getGraph().dump(os);<br>
> +        raw_fd_ostream OS(GraphFileName, EC, sys::fs::F_Text);<br>
> +        DEBUG(dbgs() << "Dumping graph for round " << Round << " to \""<br>
> +              << GraphFileName << "\"\n");<br>
> +        G.dumpToStream(OS);<br>
>        }<br>
>  #endif<br>
><br>
> -      PBQP::Solution solution =<br>
> -        PBQP::RegAlloc::solve(problem->getGraph());<br>
> -<br>
> -      pbqpAllocComplete = mapPBQPToRegAlloc(*problem, solution);<br>
> -<br>
> -      ++round;<br>
> +      PBQP::Solution Solution = PBQP::RegAlloc::solve(G);<br>
> +      PBQPAllocComplete = mapPBQPToRegAlloc(G, Solution, VRM, *VRegSpiller);<br>
> +      ++Round;<br>
>      }<br>
>    }<br>
><br>
>    // Finalise allocation, allocate empty ranges.<br>
> -  finalizeAlloc();<br>
> -  vregsToAlloc.clear();<br>
> -  emptyIntervalVRegs.clear();<br>
> +  finalizeAlloc(MF, LIS, VRM);<br>
> +  VRegsToAlloc.clear();<br>
> +  EmptyIntervalVRegs.clear();<br>
><br>
> -  DEBUG(dbgs() << "Post alloc VirtRegMap:\n" << *vrm << "\n");<br>
> +  DEBUG(dbgs() << "Post alloc VirtRegMap:\n" << VRM << "\n");<br>
><br>
>    return true;<br>
>  }<br>
><br>
> -FunctionPass *<br>
> -llvm::createPBQPRegisterAllocator(std::unique_ptr<PBQPBuilder> builder,<br>
> -                                  char *customPassID) {<br>
> -  return new RegAllocPBQP(std::move(builder), customPassID);<br>
> +FunctionPass *llvm::createPBQPRegisterAllocator(char *customPassID) {<br>
> +  return new RegAllocPBQP(customPassID);<br>
>  }<br>
><br>
>  FunctionPass* llvm::createDefaultPBQPRegisterAllocator() {<br>
> -  std::unique_ptr<PBQPBuilder> Builder;<br>
> -  if (pbqpCoalescing)<br>
> -    Builder = llvm::make_unique<PBQPBuilderWithCoalescing>();<br>
> -  else<br>
> -    Builder = llvm::make_unique<PBQPBuilder>();<br>
> -  return createPBQPRegisterAllocator(std::move(Builder));<br>
> +  return createPBQPRegisterAllocator();<br>
>  }<br>
><br>
>  #undef DEBUG_TYPE<br>
><br>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64.h?rev=219421&r1=219420&r2=219421&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64.h?rev=219421&r1=219420&r2=219421&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Target/AArch64/AArch64.h (original)<br>
> +++ llvm/trunk/lib/Target/AArch64/AArch64.h Thu Oct  9 13:20:51 2014<br>
> @@ -39,7 +39,6 @@ ModulePass *createAArch64PromoteConstant<br>
>  FunctionPass *createAArch64ConditionOptimizerPass();<br>
>  FunctionPass *createAArch64AddressTypePromotionPass();<br>
>  FunctionPass *createAArch64A57FPLoadBalancing();<br>
> -FunctionPass *createAArch64A57PBQPRegAlloc();<br>
>  /// \brief Creates an ARM-specific Target Transformation Info pass.<br>
>  ImmutablePass *<br>
>  createAArch64TargetTransformInfoPass(const AArch64TargetMachine *TM);<br>
><br>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64PBQPRegAlloc.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64PBQPRegAlloc.cpp?rev=219421&r1=219420&r2=219421&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64PBQPRegAlloc.cpp?rev=219421&r1=219420&r2=219421&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Target/AArch64/AArch64PBQPRegAlloc.cpp (original)<br>
> +++ llvm/trunk/lib/Target/AArch64/AArch64PBQPRegAlloc.cpp Thu Oct  9 13:20:51 2014<br>
> @@ -18,9 +18,8 @@<br>
>  #define DEBUG_TYPE "aarch64-pbqp"<br>
><br>
>  #include "AArch64.h"<br>
> +#include "AArch64PBQPRegAlloc.h"<br>
>  #include "AArch64RegisterInfo.h"<br>
> -<br>
> -#include "llvm/ADT/SetVector.h"<br>
>  #include "llvm/CodeGen/LiveIntervalAnalysis.h"<br>
>  #include "llvm/CodeGen/MachineBasicBlock.h"<br>
>  #include "llvm/CodeGen/MachineFunction.h"<br>
> @@ -30,8 +29,6 @@<br>
>  #include "llvm/Support/ErrorHandling.h"<br>
>  #include "llvm/Support/raw_ostream.h"<br>
><br>
> -#define PBQP_BUILDER PBQPBuilderWithCoalescing<br>
> -<br>
>  using namespace llvm;<br>
><br>
>  namespace {<br>
> @@ -157,85 +154,65 @@ bool haveSameParity(unsigned reg1, unsig<br>
>    return isOdd(reg1) == isOdd(reg2);<br>
>  }<br>
><br>
> -class A57PBQPBuilder : public PBQP_BUILDER {<br>
> -public:<br>
> -  A57PBQPBuilder() : PBQP_BUILDER(), TRI(nullptr), LIs(nullptr), Chains() {}<br>
> -<br>
> -  // Build a PBQP instance to represent the register allocation problem for<br>
> -  // the given MachineFunction.<br>
> -  std::unique_ptr<PBQPRAProblem><br>
> -  build(MachineFunction *MF, const LiveIntervals *LI,<br>
> -        const MachineBlockFrequencyInfo *blockInfo,<br>
> -        const RegSet &VRegs) override;<br>
> -<br>
> -private:<br>
> -  const AArch64RegisterInfo *TRI;<br>
> -  const LiveIntervals *LIs;<br>
> -  SmallSetVector<unsigned, 32> Chains;<br>
> -<br>
> -  // Return true if reg is a physical register<br>
> -  bool isPhysicalReg(unsigned reg) const {<br>
> -    return TRI->isPhysicalRegister(reg);<br>
> -  }<br>
> -<br>
> -  // Add the accumulator chaining constraint, inside the chain, i.e. so that<br>
> -  // parity(Rd) == parity(Ra).<br>
> -  // \return true if a constraint was added<br>
> -  bool addIntraChainConstraint(PBQPRAProblem *p, unsigned Rd, unsigned Ra);<br>
> -<br>
> -  // Add constraints between existing chains<br>
> -  void addInterChainConstraint(PBQPRAProblem *p, unsigned Rd, unsigned Ra);<br>
> -};<br>
> -} // Anonymous namespace<br>
> +}<br>
><br>
> -bool A57PBQPBuilder::addIntraChainConstraint(PBQPRAProblem *p, unsigned Rd,<br>
> -                                             unsigned Ra) {<br>
> +bool A57PBQPConstraints::addIntraChainConstraint(PBQPRAGraph &G, unsigned Rd,<br>
> +                                                 unsigned Ra) {<br>
>    if (Rd == Ra)<br>
>      return false;<br>
><br>
> -  if (isPhysicalReg(Rd) || isPhysicalReg(Ra)) {<br>
> -    DEBUG(dbgs() << "Rd is a physical reg:" << isPhysicalReg(Rd) << '\n');<br>
> -    DEBUG(dbgs() << "Ra is a physical reg:" << isPhysicalReg(Ra) << '\n');<br>
> +  const TargetRegisterInfo &TRI =<br>
> +    *G.getMetadata().MF.getTarget().getSubtargetImpl()->getRegisterInfo();<br>
> +  LiveIntervals &LIs = G.getMetadata().LIS;<br>
> +<br>
> +  if (TRI.isPhysicalRegister(Rd) || TRI.isPhysicalRegister(Ra)) {<br>
> +    DEBUG(dbgs() << "Rd is a physical reg:" << TRI.isPhysicalRegister(Rd)<br>
> +          << '\n');<br>
> +    DEBUG(dbgs() << "Ra is a physical reg:" << TRI.isPhysicalRegister(Ra)<br>
> +          << '\n');<br>
>      return false;<br>
>    }<br>
><br>
> -  const PBQPRAProblem::AllowedSet *vRdAllowed = &p->getAllowedSet(Rd);<br>
> -  const PBQPRAProblem::AllowedSet *vRaAllowed = &p->getAllowedSet(Ra);<br>
> +  PBQPRAGraph::NodeId node1 = G.getMetadata().getNodeIdForVReg(Rd);<br>
> +  PBQPRAGraph::NodeId node2 = G.getMetadata().getNodeIdForVReg(Ra);<br>
> +<br>
> +  const PBQPRAGraph::NodeMetadata::OptionToRegMap *vRdAllowed =<br>
> +    &G.getNodeMetadata(node1).getOptionRegs();<br>
> +  const PBQPRAGraph::NodeMetadata::OptionToRegMap *vRaAllowed =<br>
> +    &G.getNodeMetadata(node2).getOptionRegs();<br>
><br>
> -  PBQPRAGraph &g = p->getGraph();<br>
> -  PBQPRAGraph::NodeId node1 = p->getNodeForVReg(Rd);<br>
> -  PBQPRAGraph::NodeId node2 = p->getNodeForVReg(Ra);<br>
> -  PBQPRAGraph::EdgeId edge = g.findEdge(node1, node2);<br>
> +  PBQPRAGraph::EdgeId edge = G.findEdge(node1, node2);<br>
><br>
>    // The edge does not exist. Create one with the appropriate interference<br>
>    // costs.<br>
> -  if (edge == g.invalidEdgeId()) {<br>
> -    const LiveInterval &ld = LIs->getInterval(Rd);<br>
> -    const LiveInterval &la = LIs->getInterval(Ra);<br>
> +  if (edge == G.invalidEdgeId()) {<br>
> +    const LiveInterval &ld = LIs.getInterval(Rd);<br>
> +    const LiveInterval &la = LIs.getInterval(Ra);<br>
>      bool livesOverlap = ld.overlaps(la);<br>
><br>
> -    PBQP::Matrix costs(vRdAllowed->size() + 1, vRaAllowed->size() + 1, 0);<br>
> +    PBQPRAGraph::RawMatrix costs(vRdAllowed->size() + 1,<br>
> +                                 vRaAllowed->size() + 1, 0);<br>
>      for (unsigned i = 0, ie = vRdAllowed->size(); i != ie; ++i) {<br>
>        unsigned pRd = (*vRdAllowed)[i];<br>
>        for (unsigned j = 0, je = vRaAllowed->size(); j != je; ++j) {<br>
>          unsigned pRa = (*vRaAllowed)[j];<br>
> -        if (livesOverlap && TRI->regsOverlap(pRd, pRa))<br>
> +        if (livesOverlap && TRI.regsOverlap(pRd, pRa))<br>
>            costs[i + 1][j + 1] = std::numeric_limits<PBQP::PBQPNum>::infinity();<br>
>          else<br>
>            costs[i + 1][j + 1] = haveSameParity(pRd, pRa) ? 0.0 : 1.0;<br>
>        }<br>
>      }<br>
> -    g.addEdge(node1, node2, std::move(costs));<br>
> +    G.addEdge(node1, node2, std::move(costs));<br>
>      return true;<br>
>    }<br>
><br>
> -  if (g.getEdgeNode1Id(edge) == node2) {<br>
> +  if (G.getEdgeNode1Id(edge) == node2) {<br>
>      std::swap(node1, node2);<br>
>      std::swap(vRdAllowed, vRaAllowed);<br>
>    }<br>
><br>
>    // Enforce minCost(sameParity(RaClass)) > maxCost(otherParity(RdClass))<br>
> -  PBQP::Matrix costs(g.getEdgeCosts(edge));<br>
> +  PBQPRAGraph::RawMatrix costs(G.getEdgeCosts(edge));<br>
>    for (unsigned i = 0, ie = vRdAllowed->size(); i != ie; ++i) {<br>
>      unsigned pRd = (*vRdAllowed)[i];<br>
><br>
> @@ -260,55 +237,62 @@ bool A57PBQPBuilder::addIntraChainConstr<br>
>            costs[i + 1][j + 1] = sameParityMax + 1.0;<br>
>      }<br>
>    }<br>
> -  g.setEdgeCosts(edge, costs);<br>
> +  G.setEdgeCosts(edge, std::move(costs));<br>
><br>
>    return true;<br>
>  }<br>
><br>
> -void<br>
> -A57PBQPBuilder::addInterChainConstraint(PBQPRAProblem *p, unsigned Rd,<br>
> -                                        unsigned Ra) {<br>
> +void A57PBQPConstraints::addInterChainConstraint(PBQPRAGraph &G, unsigned Rd,<br>
> +                                                 unsigned Ra) {<br>
> +  const TargetRegisterInfo &TRI =<br>
> +    *G.getMetadata().MF.getTarget().getSubtargetImpl()->getRegisterInfo();<br>
> +  (void)TRI;<br>
> +  LiveIntervals &LIs = G.getMetadata().LIS;<br>
> +<br>
>    // Do some Chain management<br>
>    if (Chains.count(Ra)) {<br>
>      if (Rd != Ra) {<br>
> -      DEBUG(dbgs() << "Moving acc chain from " << PrintReg(Ra, TRI) << " to "<br>
> -                   << PrintReg(Rd, TRI) << '\n';);<br>
> +      DEBUG(dbgs() << "Moving acc chain from " << PrintReg(Ra, &TRI) << " to "<br>
> +                   << PrintReg(Rd, &TRI) << '\n';);<br>
>        Chains.remove(Ra);<br>
>        Chains.insert(Rd);<br>
>      }<br>
>    } else {<br>
> -    DEBUG(dbgs() << "Creating new acc chain for " << PrintReg(Rd, TRI)<br>
> +    DEBUG(dbgs() << "Creating new acc chain for " << PrintReg(Rd, &TRI)<br>
>                   << '\n';);<br>
>      Chains.insert(Rd);<br>
>    }<br>
><br>
> -  const LiveInterval &ld = LIs->getInterval(Rd);<br>
> +  PBQPRAGraph::NodeId node1 = G.getMetadata().getNodeIdForVReg(Rd);<br>
> +<br>
> +  const LiveInterval &ld = LIs.getInterval(Rd);<br>
>    for (auto r : Chains) {<br>
>      // Skip self<br>
>      if (r == Rd)<br>
>        continue;<br>
><br>
> -    const LiveInterval &lr = LIs->getInterval(r);<br>
> +    const LiveInterval &lr = LIs.getInterval(r);<br>
>      if (ld.overlaps(lr)) {<br>
> -      const PBQPRAProblem::AllowedSet *vRdAllowed = &p->getAllowedSet(Rd);<br>
> -      const PBQPRAProblem::AllowedSet *vRrAllowed = &p->getAllowedSet(r);<br>
> +      const PBQPRAGraph::NodeMetadata::OptionToRegMap *vRdAllowed =<br>
> +        &G.getNodeMetadata(node1).getOptionRegs();<br>
> +<br>
> +      PBQPRAGraph::NodeId node2 = G.getMetadata().getNodeIdForVReg(r);<br>
> +      const PBQPRAGraph::NodeMetadata::OptionToRegMap *vRrAllowed =<br>
> +        &G.getNodeMetadata(node2).getOptionRegs();<br>
><br>
> -      PBQPRAGraph &g = p->getGraph();<br>
> -      PBQPRAGraph::NodeId node1 = p->getNodeForVReg(Rd);<br>
> -      PBQPRAGraph::NodeId node2 = p->getNodeForVReg(r);<br>
> -      PBQPRAGraph::EdgeId edge = g.findEdge(node1, node2);<br>
> -      assert(edge != g.invalidEdgeId() &&<br>
> +      PBQPRAGraph::EdgeId edge = G.findEdge(node1, node2);<br>
> +      assert(edge != G.invalidEdgeId() &&<br>
>               "PBQP error ! The edge should exist !");<br>
><br>
>        DEBUG(dbgs() << "Refining constraint !\n";);<br>
><br>
> -      if (g.getEdgeNode1Id(edge) == node2) {<br>
> +      if (G.getEdgeNode1Id(edge) == node2) {<br>
>          std::swap(node1, node2);<br>
>          std::swap(vRdAllowed, vRrAllowed);<br>
>        }<br>
><br>
>        // Enforce that cost is higher with all other Chains of the same parity<br>
> -      PBQP::Matrix costs(g.getEdgeCosts(edge));<br>
> +      PBQP::Matrix costs(G.getEdgeCosts(edge));<br>
>        for (unsigned i = 0, ie = vRdAllowed->size(); i != ie; ++i) {<br>
>          unsigned pRd = (*vRdAllowed)[i];<br>
><br>
> @@ -333,25 +317,20 @@ A57PBQPBuilder::addInterChainConstraint(<br>
>                costs[i + 1][j + 1] = sameParityMax + 1.0;<br>
>          }<br>
>        }<br>
> -      g.setEdgeCosts(edge, costs);<br>
> +      G.setEdgeCosts(edge, std::move(costs));<br>
>      }<br>
>    }<br>
>  }<br>
><br>
> -std::unique_ptr<PBQPRAProblem><br>
> -A57PBQPBuilder::build(MachineFunction *MF, const LiveIntervals *LI,<br>
> -                      const MachineBlockFrequencyInfo *blockInfo,<br>
> -                      const RegSet &VRegs) {<br>
> -  std::unique_ptr<PBQPRAProblem> p =<br>
> -      PBQP_BUILDER::build(MF, LI, blockInfo, VRegs);<br>
> -<br>
> -  TRI = static_cast<const AArch64RegisterInfo *>(<br>
> -      MF->getTarget().getSubtargetImpl()->getRegisterInfo());<br>
> -  LIs = LI;<br>
> +void A57PBQPConstraints::apply(PBQPRAGraph &G) {<br>
> +  MachineFunction &MF = G.getMetadata().MF;<br>
><br>
> -  DEBUG(MF->dump(););<br>
> +  const TargetRegisterInfo &TRI =<br>
> +    *MF.getTarget().getSubtargetImpl()->getRegisterInfo();<br>
> +  (void)TRI;<br>
> +  DEBUG(MF.dump());<br>
><br>
> -  for (MachineFunction::const_iterator mbbItr = MF->begin(), mbbEnd = MF->end();<br>
> +  for (MachineFunction::const_iterator mbbItr = MF.begin(), mbbEnd = MF.end();<br>
>         mbbItr != mbbEnd; ++mbbItr) {<br>
>      const MachineBasicBlock *MBB = &*mbbItr;<br>
>      Chains.clear(); // FIXME: really needed ? Could not work at MF level ?<br>
> @@ -372,15 +351,15 @@ A57PBQPBuilder::build(MachineFunction *M<br>
>          unsigned Rd = MI->getOperand(0).getReg();<br>
>          unsigned Ra = MI->getOperand(3).getReg();<br>
><br>
> -        if (addIntraChainConstraint(p.get(), Rd, Ra))<br>
> -          addInterChainConstraint(p.get(), Rd, Ra);<br>
> +        if (addIntraChainConstraint(G, Rd, Ra))<br>
> +          addInterChainConstraint(G, Rd, Ra);<br>
>          break;<br>
>        }<br>
><br>
>        case AArch64::FMLAv2f32:<br>
>        case AArch64::FMLSv2f32: {<br>
>          unsigned Rd = MI->getOperand(0).getReg();<br>
> -        addInterChainConstraint(p.get(), Rd, Rd);<br>
> +        addInterChainConstraint(G, Rd, Rd);<br>
>          break;<br>
>        }<br>
><br>
> @@ -389,7 +368,7 @@ A57PBQPBuilder::build(MachineFunction *M<br>
>          for (auto r : Chains) {<br>
>            SmallVector<unsigned, 8> toDel;<br>
>            if (MI->killsRegister(r)) {<br>
> -            DEBUG(dbgs() << "Killing chain " << PrintReg(r, TRI) << " at ";<br>
> +            DEBUG(dbgs() << "Killing chain " << PrintReg(r, &TRI) << " at ";<br>
>                    MI->print(dbgs()););<br>
>              toDel.push_back(r);<br>
>            }<br>
> @@ -402,13 +381,4 @@ A57PBQPBuilder::build(MachineFunction *M<br>
>        }<br>
>      }<br>
>    }<br>
> -<br>
> -  return p;<br>
> -}<br>
> -<br>
> -// Factory function used by AArch64TargetMachine to add the pass to the<br>
> -// passmanager.<br>
> -FunctionPass *llvm::createAArch64A57PBQPRegAlloc() {<br>
> -  std::unique_ptr<PBQP_BUILDER> builder = llvm::make_unique<A57PBQPBuilder>();<br>
> -  return createPBQPRegisterAllocator(std::move(builder), nullptr);<br>
>  }<br>
><br>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp?rev=219421&r1=219420&r2=219421&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp?rev=219421&r1=219420&r2=219421&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp (original)<br>
> +++ llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp Thu Oct  9 13:20:51 2014<br>
> @@ -12,6 +12,7 @@<br>
>  //===----------------------------------------------------------------------===//<br>
><br>
>  #include "AArch64InstrInfo.h"<br>
> +#include "AArch64PBQPRegAlloc.h"<br>
>  #include "AArch64Subtarget.h"<br>
>  #include "llvm/ADT/SmallVector.h"<br>
>  #include "llvm/CodeGen/MachineScheduler.h"<br>
> @@ -133,3 +134,8 @@ void AArch64Subtarget::overrideSchedPoli<br>
>  bool AArch64Subtarget::enableEarlyIfConversion() const {<br>
>    return EnableEarlyIfConvert;<br>
>  }<br>
> +<br>
> +std::unique_ptr<PBQPRAConstraint><br>
> +AArch64Subtarget::getCustomPBQPConstraints() const {<br>
> +  return llvm::make_unique<A57PBQPConstraints>();<br>
> +}<br>
><br>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h?rev=219421&r1=219420&r2=219421&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h?rev=219421&r1=219420&r2=219421&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h (original)<br>
> +++ llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h Thu Oct  9 13:20:51 2014<br>
> @@ -142,6 +142,8 @@ public:<br>
>                             unsigned NumRegionInstrs) const override;<br>
><br>
>    bool enableEarlyIfConversion() const override;<br>
> +<br>
> +  std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const override;<br>
>  };<br>
>  } // End llvm namespace<br>
><br>
><br>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp?rev=219421&r1=219420&r2=219421&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp?rev=219421&r1=219420&r2=219421&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp (original)<br>
> +++ llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp Thu Oct  9 13:20:51 2014<br>
> @@ -102,7 +102,7 @@ AArch64TargetMachine::AArch64TargetMachi<br>
><br>
>    if (EnablePBQP && Subtarget.isCortexA57() && OL != CodeGenOpt::None) {<br>
>      usingPBQP = true;<br>
> -    RegisterRegAlloc::setDefault(createAArch64A57PBQPRegAlloc);<br>
> +    RegisterRegAlloc::setDefault(createDefaultPBQPRegisterAllocator);<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" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</div></div></blockquote></div><br></div>