Support adding relocations for data sections, handling the cases where
[oota-llvm.git] / lib / CodeGen / RegAllocPBQP.cpp
index f3c10e9de99a0c34e6b5e8dc1617d09aabcff0f7..89e2c59fe805d1f07337f09b42ca41b2cf1950b5 100644 (file)
@@ -16,7 +16,7 @@
 //
 // The PBQP solver (pbqp.c) provided for this allocator uses a heuristic tuned
 // for register allocation. For more information on PBQP for register
-// allocation see the following papers:
+// allocation, see the following papers:
 //
 //   (1) Hames, L. and Scholz, B. 2006. Nearly optimal register allocation with
 //   PBQP. In Proceedings of the 7th Joint Modular Languages Conference
 //   Compilers and Tools for Embedded Systems (LCTES'02), ACM Press, New York,
 //   NY, USA, 139-148.
 //
-// Author: Lang Hames
-// Email: lhames@gmail.com
-//
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "regalloc"
 
 #include "PBQP.h"
 #include "VirtRegMap.h"
+#include "VirtRegRewriter.h"
 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
 #include "llvm/CodeGen/LiveStackAnalysis.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
@@ -85,6 +83,7 @@ namespace {
       au.addPreserved<LiveStacks>();
       au.addRequired<MachineLoopInfo>();
       au.addPreserved<MachineLoopInfo>();
+      au.addRequired<VirtRegMap>();
       MachineFunctionPass::getAnalysisUsage(au);
     }
 
@@ -166,7 +165,7 @@ namespace {
 
     //! \brief Adds a stack interval if the given live interval has been
     //! spilled. Used to support stack slot coloring.
-    void addStackInterval(const LiveInterval *spilled, float &weight);
+    void addStackInterval(const LiveInterval *spilled,MachineRegisterInfo* mri);
 
     //! \brief Given a solved PBQP problem maps this solution back to a register
     //! assignment.
@@ -362,10 +361,10 @@ PBQPRegAlloc::CoalesceMap PBQPRegAlloc::findCoalesces() {
          iItr != iEnd; ++iItr) {
 
       const MachineInstr *instr = &*iItr;
-      unsigned srcReg, dstReg;
+      unsigned srcReg, dstReg, srcSubReg, dstSubReg;
 
       // If this isn't a copy then continue to the next instruction.
-      if (!tii->isMoveInstr(*instr, srcReg, dstReg))
+      if (!tii->isMoveInstr(*instr, srcReg, dstReg, srcSubReg, dstSubReg))
         continue;
 
       // If the registers are already the same our job is nice and easy.
@@ -638,20 +637,21 @@ pbqp* PBQPRegAlloc::constructPBQPProblem() {
   return solver;
 }
 
-void PBQPRegAlloc::addStackInterval(const LiveInterval *spilled, float &weight) {
+void PBQPRegAlloc::addStackInterval(const LiveInterval *spilled,
+                                    MachineRegisterInfo* mri) {
   int stackSlot = vrm->getStackSlot(spilled->reg);
 
   if (stackSlot == VirtRegMap::NO_STACK_SLOT)
     return;
 
-  LiveInterval &stackInterval = lss->getOrCreateInterval(stackSlot);
-  stackInterval.weight += weight;
+  const TargetRegisterClass *RC = mri->getRegClass(spilled->reg);
+  LiveInterval &stackInterval = lss->getOrCreateInterval(stackSlot, RC);
 
   VNInfo *vni;
   if (stackInterval.getNumValNums() != 0)
     vni = stackInterval.getValNumInfo(0);
   else
-    vni = stackInterval.getNextValue(-0U, 0, lss->getVNInfoAllocator());
+    vni = stackInterval.getNextValue(0, 0, false, lss->getVNInfoAllocator());
 
   LiveInterval &rhsInterval = lis->getInterval(spilled->reg);
   stackInterval.MergeRangesInAsValue(rhsInterval, vni);
@@ -689,16 +689,13 @@ bool PBQPRegAlloc::mapPBQPToRegAlloc(pbqp *problem) {
       // of allocation
       vregIntervalsToAlloc.erase(&lis->getInterval(virtReg));
 
-      float ssWeight;
-
       // Insert spill ranges for this live range
       const LiveInterval *spillInterval = node2LI[node];
       double oldSpillWeight = spillInterval->weight;
       SmallVector<LiveInterval*, 8> spillIs;
       std::vector<LiveInterval*> newSpills =
-        lis->addIntervalsForSpills(*spillInterval, spillIs, loopInfo, *vrm,
-                                   ssWeight);
-      addStackInterval(spillInterval, ssWeight);
+        lis->addIntervalsForSpills(*spillInterval, spillIs, loopInfo, *vrm);
+      addStackInterval(spillInterval, mri);
 
       DOUT << "VREG " << virtReg << " -> SPILLED (Cost: "
            << oldSpillWeight << ", New vregs: ";
@@ -732,12 +729,11 @@ void PBQPRegAlloc::finalizeAlloc() const {
 
   // First allocate registers for the empty intervals.
   for (LiveIntervalSet::const_iterator
-        itr = emptyVRegIntervals.begin(), end = emptyVRegIntervals.end();
+         itr = emptyVRegIntervals.begin(), end = emptyVRegIntervals.end();
          itr != end; ++itr) {
     LiveInterval *li = *itr;
 
-    unsigned physReg = li->preference;
-
+    unsigned physReg = vrm->getRegAllocPref(li->reg);
     if (physReg == 0) {
       const TargetRegisterClass *liRC = mri->getRegClass(li->reg);
       physReg = *liRC->allocation_order_begin(*mf);
@@ -768,6 +764,11 @@ void PBQPRegAlloc::finalizeAlloc() const {
       continue;
     }
 
+    // Ignore unallocated vregs:
+    if (reg == 0) {
+      continue;
+    }
+
     // Iterate over the ranges of the current interval...
     for (LRIterator lrItr = li->begin(), lrEnd = li->end();
          lrItr != lrEnd; ++lrItr) {
@@ -801,8 +802,7 @@ bool PBQPRegAlloc::runOnMachineFunction(MachineFunction &MF) {
   lss = &getAnalysis<LiveStacks>();
   loopInfo = &getAnalysis<MachineLoopInfo>();
 
-  std::auto_ptr<VirtRegMap> vrmAutoPtr(new VirtRegMap(*mf));
-  vrm = vrmAutoPtr.get();
+  vrm = &getAnalysis<VirtRegMap>();
 
   DOUT << "PBQP Register Allocating for " << mf->getFunction()->getName() << "\n";
 
@@ -854,9 +854,10 @@ bool PBQPRegAlloc::runOnMachineFunction(MachineFunction &MF) {
 
   DOUT << "Post alloc VirtRegMap:\n" << *vrm << "\n";
 
-  // Run spiller
-  std::auto_ptr<Spiller> spiller(createSpiller());
-  spiller->runOnMachineFunction(*mf, *vrm);
+  // Run rewriter
+  std::auto_ptr<VirtRegRewriter> rewriter(createVirtRegRewriter());
+
+  rewriter->runOnMachineFunction(*mf, *vrm, lis);
 
   return true;
 }