[llvm-commits] [llvm] r114429 - in /llvm/trunk: include/llvm/CodeGen/PBQP/Heuristics/Briggs.h include/llvm/CodeGen/RegAllocPBQP.h lib/CodeGen/RegAllocPBQP.cpp

Lang Hames lhames at gmail.com
Tue Sep 21 06:19:36 PDT 2010


Author: lhames
Date: Tue Sep 21 08:19:36 2010
New Revision: 114429

URL: http://llvm.org/viewvc/llvm-project?rev=114429&view=rev
Log:
Added an additional PBQP problem builder which adds coalescing costs (both between pairs of virtuals, and between virtuals and physicals).


Modified:
    llvm/trunk/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h
    llvm/trunk/include/llvm/CodeGen/RegAllocPBQP.h
    llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp

Modified: llvm/trunk/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h?rev=114429&r1=114428&r2=114429&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h (original)
+++ llvm/trunk/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h Tue Sep 21 08:19:36 2010
@@ -63,8 +63,12 @@
         SpillCostComparator(HeuristicSolverImpl<Briggs> &s)
           : s(&s), g(&s.getGraph()) {}
         bool operator()(Graph::NodeItr n1Itr, Graph::NodeItr n2Itr) const {
-          PBQPNum cost1 = g->getNodeCosts(n1Itr)[0] / s->getSolverDegree(n1Itr),
-                  cost2 = g->getNodeCosts(n2Itr)[0] / s->getSolverDegree(n2Itr);
+          const PBQP::Vector &cv1 = g->getNodeCosts(n1Itr);
+          const PBQP::Vector &cv2 = g->getNodeCosts(n2Itr);
+
+          PBQPNum cost1 = cv1[0] / s->getSolverDegree(n1Itr);
+          PBQPNum cost2 = cv2[0] / s->getSolverDegree(n2Itr);
+
           if (cost1 < cost2)
             return true;
           return false;

Modified: llvm/trunk/include/llvm/CodeGen/RegAllocPBQP.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/RegAllocPBQP.h?rev=114429&r1=114428&r2=114429&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/RegAllocPBQP.h (original)
+++ llvm/trunk/include/llvm/CodeGen/RegAllocPBQP.h Tue Sep 21 08:19:36 2010
@@ -27,6 +27,7 @@
 
   class LiveInterval;
   class MachineFunction;
+  class MachineLoopInfo;
 
   /// This class wraps up a PBQP instance representing a register allocation
   /// problem, plus the structures necessary to map back from the PBQP solution
@@ -113,7 +114,6 @@
 
     typedef std::set<unsigned> RegSet;
  
-
     /// Default constructor.
     PBQPBuilder() {}
 
@@ -125,6 +125,7 @@
     virtual std::auto_ptr<PBQPRAProblem> build(
                                               MachineFunction *mf,
                                               const LiveIntervals *lis,
+                                              const MachineLoopInfo *loopInfo,
                                               const RegSet &vregs);
   private:
 
@@ -136,6 +137,29 @@
                               const TargetRegisterInfo *tri);
   };
 
+  /// Extended builder which adds coalescing constraints to a problem.
+  class PBQPBuilderWithCoalescing : public PBQPBuilder {
+  public:
+ 
+    /// Build a PBQP instance to represent the register allocation problem for
+    /// the given MachineFunction.
+    virtual std::auto_ptr<PBQPRAProblem> build(
+                                              MachineFunction *mf,
+                                              const LiveIntervals *lis,
+                                              const MachineLoopInfo *loopInfo,
+                                              const RegSet &vregs);   
+
+  private:
+
+    void addPhysRegCoalesce(PBQP::Vector &costVec, unsigned pregOption,
+                            PBQP::PBQPNum benefit);
+
+    void addVirtRegCoalesce(PBQP::Matrix &costMat,
+                            const PBQPRAProblem::AllowedSet &vr1Allowed,
+                            const PBQPRAProblem::AllowedSet &vr2Allowed,
+                            PBQP::PBQPNum benefit);
+  };
+
   ///
   /// PBQP based allocators solve the register allocation problem by mapping
   /// register allocation problems to Partitioned Boolean Quadratic

Modified: llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp?rev=114429&r1=114428&r2=114429&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp Tue Sep 21 08:19:36 2010
@@ -58,9 +58,6 @@
 
 namespace llvm {
 
-using namespace PBQP;
-  using namespace PBQP::Heuristics;
-
 static RegisterRegAlloc
 registerPBQPRepAlloc("pbqp", "PBQP register allocator",
                        llvm::createPBQPRegisterAllocator);
@@ -112,10 +109,10 @@
   return allowedSet[option - 1];
 }
 
-std::auto_ptr<PBQPRAProblem> PBQPBuilder::build(
-                                             MachineFunction *mf,
-                                             const LiveIntervals *lis,
-                                             const RegSet &vregs) {
+std::auto_ptr<PBQPRAProblem> PBQPBuilder::build(MachineFunction *mf,
+                                                const LiveIntervals *lis,
+                                                const MachineLoopInfo *loopInfo,
+                                                const RegSet &vregs) {
 
   typedef std::vector<const LiveInterval*> LIVector;
 
@@ -235,10 +232,11 @@
   costVec[0] = spillCost;
 }
 
-void PBQPBuilder::addInterferenceCosts(PBQP::Matrix &costMat,
-                                       const PBQPRAProblem::AllowedSet &vr1Allowed,
-                                       const PBQPRAProblem::AllowedSet &vr2Allowed,
-                                       const TargetRegisterInfo *tri) {
+void PBQPBuilder::addInterferenceCosts(
+                                    PBQP::Matrix &costMat,
+                                    const PBQPRAProblem::AllowedSet &vr1Allowed,
+                                    const PBQPRAProblem::AllowedSet &vr2Allowed,
+                                    const TargetRegisterInfo *tri) {
   assert(costMat.getRows() == vr1Allowed.size() + 1 && "Matrix height mismatch.");
   assert(costMat.getCols() == vr2Allowed.size() + 1 && "Matrix width mismatch.");
 
@@ -255,6 +253,115 @@
   }
 }
 
+std::auto_ptr<PBQPRAProblem> PBQPBuilderWithCoalescing::build(
+                                                MachineFunction *mf,
+                                                const LiveIntervals *lis,
+                                                const MachineLoopInfo *loopInfo,
+                                                const RegSet &vregs) {
+
+  std::auto_ptr<PBQPRAProblem> p = PBQPBuilder::build(mf, lis, loopInfo, vregs);
+  PBQP::Graph &g = p->getGraph();
+
+  const TargetMachine &tm = mf->getTarget();
+  CoalescerPair cp(*tm.getInstrInfo(), *tm.getRegisterInfo());
+
+  // Scan the machine function and add a coalescing cost whenever CoalescerPair
+  // gives the Ok.
+  for (MachineFunction::const_iterator mbbItr = mf->begin(),
+                                       mbbEnd = mf->end();
+       mbbItr != mbbEnd; ++mbbItr) {
+    const MachineBasicBlock *mbb = &*mbbItr;
+
+    for (MachineBasicBlock::const_iterator miItr = mbb->begin(),
+                                           miEnd = mbb->end();
+         miItr != miEnd; ++miItr) {
+      const MachineInstr *mi = &*miItr;
+
+      if (!mi->isCopy() && !mi->isSubregToReg())
+        continue; // Not coalescable.
+
+      if (!cp.setRegisters(mi))
+        continue; // Not coalescable.
+
+      if (cp.getSrcReg() == cp.getDstReg())
+        continue; // Already coalesced.
+
+      if (cp.isCoalescable(mi)) {
+
+        unsigned dst = cp.getDstReg(),
+                 src = cp.getSrcReg();
+
+
+
+        PBQP::PBQPNum cBenefit = std::pow(10.0f, loopInfo->getLoopDepth(mbb));
+
+        if (cp.isPhys()) {
+          if (!lis->isAllocatable(dst))
+            continue;
+
+          const PBQPRAProblem::AllowedSet &allowed = p->getAllowedSet(src);
+          unsigned pregOpt = 0;  
+          while (pregOpt < allowed.size() && allowed[pregOpt] != dst)
+            ++pregOpt;
+          if (pregOpt < allowed.size()) {
+            ++pregOpt; // +1 to account for spill option.
+            PBQP::Graph::NodeItr node = p->getNodeForVReg(src);
+            addPhysRegCoalesce(g.getNodeCosts(node), pregOpt, cBenefit);
+          }
+        } else {
+          const PBQPRAProblem::AllowedSet *allowed1 = &p->getAllowedSet(dst);
+          const PBQPRAProblem::AllowedSet *allowed2 = &p->getAllowedSet(src);
+          PBQP::Graph::NodeItr node1 = p->getNodeForVReg(dst);
+          PBQP::Graph::NodeItr node2 = p->getNodeForVReg(src);
+          PBQP::Graph::EdgeItr edge = g.findEdge(node1, node2);
+          if (edge == g.edgesEnd()) {
+            edge = g.addEdge(node1, node2, PBQP::Matrix(allowed1->size() + 1,
+                                                        allowed2->size() + 1,
+                                                        0));
+          } else {
+            if (g.getEdgeNode1(edge) == node2) {
+              std::swap(node1, node2);
+              std::swap(allowed1, allowed2);
+            }
+          }
+            
+          addVirtRegCoalesce(g.getEdgeCosts(edge), *allowed1, *allowed2,
+                             cBenefit);
+        }
+      }
+    }
+  }
+
+  return p;
+}
+
+
+void PBQPBuilderWithCoalescing::addPhysRegCoalesce(PBQP::Vector &costVec,
+                                                   unsigned pregOption,
+                                                   PBQP::PBQPNum benefit) {
+  costVec[pregOption] += -benefit;
+}
+
+void PBQPBuilderWithCoalescing::addVirtRegCoalesce(
+                                    PBQP::Matrix &costMat,
+                                    const PBQPRAProblem::AllowedSet &vr1Allowed,
+                                    const PBQPRAProblem::AllowedSet &vr2Allowed,
+                                    PBQP::PBQPNum benefit) {
+
+  assert(costMat.getRows() == vr1Allowed.size() + 1 && "Size mismatch.");
+  assert(costMat.getCols() == vr2Allowed.size() + 1 && "Size mismatch.");
+
+  for (unsigned i = 0; i < vr1Allowed.size(); ++i) {
+    unsigned preg1 = vr1Allowed[i];
+    for (unsigned j = 0; j < vr2Allowed.size(); ++j) {
+      unsigned preg2 = vr2Allowed[j];
+
+      if (preg1 == preg2) {
+        costMat[i + 1][j + 1] += -benefit;
+      } 
+    }
+  }
+}
 
 
 void RegAllocPBQP::getAnalysisUsage(AnalysisUsage &au) const {
@@ -1037,9 +1144,10 @@
         DEBUG(dbgs() << "  PBQP Regalloc round " << round << ":\n");
 
         std::auto_ptr<PBQPRAProblem> problem =
-          builder->build(mf, lis, vregsToAlloc);
+          builder->build(mf, lis, loopInfo, vregsToAlloc);
         PBQP::Solution solution =
-          HeuristicSolver<Briggs>::solve(problem->getGraph());
+          PBQP::HeuristicSolver<PBQP::Heuristics::Briggs>::solve(
+            problem->getGraph());
 
         pbqpAllocComplete = mapPBQPToRegAlloc2(*problem, solution);
 
@@ -1071,7 +1179,12 @@
 }
 
 FunctionPass* createPBQPRegisterAllocator() {
-  return new RegAllocPBQP(std::auto_ptr<PBQPBuilder>(new PBQPBuilder()));
+  if (pbqpCoalescing) {
+    return new RegAllocPBQP(
+                 std::auto_ptr<PBQPBuilder>(new PBQPBuilderWithCoalescing()));
+  } // else
+  return new RegAllocPBQP(
+                 std::auto_ptr<PBQPBuilder>(new PBQPBuilder()));
 }
 
 }





More information about the llvm-commits mailing list