Adjust to changes in SelectionDAG interfaces
[oota-llvm.git] / lib / CodeGen / LiveIntervalAnalysis.cpp
index 1165ae54fe2ce84278818ccfbcb1c5e4fcd83ab7..44b94b3e571eac4d3d34826de6f7949ab74ddecd 100644 (file)
@@ -17,6 +17,7 @@
 
 #define DEBUG_TYPE "liveintervals"
 #include "LiveIntervalAnalysis.h"
+#include "VirtRegMap.h"
 #include "llvm/Value.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/CodeGen/LiveVariables.h"
 #include "llvm/Target/MRegisterInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetMachine.h"
-#include "Support/CommandLine.h"
-#include "Support/Debug.h"
-#include "Support/Statistic.h"
-#include "Support/STLExtras.h"
-#include "VirtRegMap.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/STLExtras.h"
+#include <algorithm>
 #include <cmath>
-
 using namespace llvm;
 
 namespace {
@@ -88,6 +88,7 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
   mri_ = tm_->getRegisterInfo();
   lv_ = &getAnalysis<LiveVariables>();
   allocatableRegs_ = mri_->getAllocatableSet(fn);
+  r2rMap_.grow(mf_->getSSARegMap()->getLastVirtReg());
 
   // number MachineInstrs
   unsigned miIndex = 0;
@@ -155,7 +156,7 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
 
             LiveInterval &RegInt = getInterval(reg);
             RegInt.weight +=
-              (mop.isUse() + mop.isDef()) * pow(10.0F, loopDepth);
+              (mop.isUse() + mop.isDef()) * pow(10.0F, (int)loopDepth);
           }
         }
         ++mii;
@@ -163,29 +164,29 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
     }
   }
 
-  DEBUG(std::cerr << "********** INTERVALS **********\n");
-  DEBUG (for (iterator I = begin(), E = end(); I != E; ++I)
-         std::cerr << I->second << "\n");
-  DEBUG(std::cerr << "********** MACHINEINSTRS **********\n");
-  DEBUG(
-    for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
-         mbbi != mbbe; ++mbbi) {
-      std::cerr << ((Value*)mbbi->getBasicBlock())->getName() << ":\n";
-      for (MachineBasicBlock::iterator mii = mbbi->begin(),
-             mie = mbbi->end(); mii != mie; ++mii) {
-        std::cerr << getInstructionIndex(mii) << '\t';
-        mii->print(std::cerr, tm_);
-      }
-    });
-
+  DEBUG(dump());
   return true;
 }
 
-std::vector<LiveInterval*> LiveIntervals::addIntervalsForSpills(
-  const LiveInterval& li,
-  VirtRegMap& vrm,
-  int slot)
-{
+/// print - Implement the dump method.
+void LiveIntervals::print(std::ostream &O, const Module* ) const {
+  O << "********** INTERVALS **********\n";
+  for (const_iterator I = begin(), E = end(); I != E; ++I)
+    O << "  " << I->second << "\n";
+
+  O << "********** MACHINEINSTRS **********\n";
+  for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
+       mbbi != mbbe; ++mbbi) {
+    O << ((Value*)mbbi->getBasicBlock())->getName() << ":\n";
+    for (MachineBasicBlock::iterator mii = mbbi->begin(),
+           mie = mbbi->end(); mii != mie; ++mii) {
+      O << getInstructionIndex(mii) << '\t' << *mii;
+    }
+  }
+}
+
+std::vector<LiveInterval*> LiveIntervals::
+addIntervalsForSpills(const LiveInterval &li, VirtRegMap &vrm, int slot) {
   // since this is called after the analysis is done we don't know if
   // LiveVariables is available
   lv_ = getAnalysisToUpdate<LiveVariables>();
@@ -216,33 +217,36 @@ std::vector<LiveInterval*> LiveIntervals::addIntervalsForSpills(
       for (unsigned i = 0; i != mi->getNumOperands(); ++i) {
         MachineOperand& mop = mi->getOperand(i);
         if (mop.isRegister() && mop.getReg() == li.reg) {
+          // First thing, attempt to fold the memory reference into the
+          // instruction.  If we can do this, we don't need to insert spill
+          // code.
           if (MachineInstr* fmi = mri_->foldMemoryOperand(mi, i, slot)) {
             if (lv_)
               lv_->instructionChanged(mi, fmi);
-            vrm.virtFolded(li.reg, mi, fmi);
+            vrm.virtFolded(li.reg, mi, i, fmi);
             mi2iMap_.erase(mi);
             i2miMap_[index/InstrSlots::NUM] = fmi;
             mi2iMap_[fmi] = index;
-            MachineBasicBlock& mbb = *mi->getParent();
-            mi = mbb.insert(mbb.erase(mi), fmi);
+            MachineBasicBlock &MBB = *mi->getParent();
+            mi = MBB.insert(MBB.erase(mi), fmi);
             ++numFolded;
+
+            // Folding the load/store can completely change the instruction in
+            // unpredictable ways, rescan it from the beginning.
             goto for_operand;
-          }
-          else {
-            // This is tricky. We need to add information in
-            // the interval about the spill code so we have to
-            // use our extra load/store slots.
+          } else {
+            // This is tricky. We need to add information in the interval about
+            // the spill code so we have to use our extra load/store slots.
             //
-            // If we have a use we are going to have a load so
-            // we start the interval from the load slot
-            // onwards. Otherwise we start from the def slot.
+            // If we have a use we are going to have a load so we start the
+            // interval from the load slot onwards. Otherwise we start from the
+            // def slot.
             unsigned start = (mop.isUse() ?
                               getLoadIndex(index) :
                               getDefIndex(index));
-            // If we have a def we are going to have a store
-            // right after it so we end the interval after the
-            // use of the next instruction. Otherwise we end
-            // after the use of this instruction.
+            // If we have a def we are going to have a store right after it so
+            // we end the interval after the use of the next
+            // instruction. Otherwise we end after the use of this instruction.
             unsigned end = 1 + (mop.isDef() ?
                                 getStoreIndex(index) :
                                 getUseIndex(index));
@@ -254,13 +258,15 @@ std::vector<LiveInterval*> LiveIntervals::addIntervalsForSpills(
             vrm.assignVirt2StackSlot(nReg, slot);
             LiveInterval& nI = getOrCreateInterval(nReg);
             assert(nI.empty());
+
             // the spill weight is now infinity as it
             // cannot be spilled again
-            nI.weight = HUGE_VAL;
+            nI.weight = float(HUGE_VAL);
             LiveRange LR(start, end, nI.getNextValue());
             DEBUG(std::cerr << " +" << LR);
             nI.addRange(LR);
             added.push_back(&nI);
+
             // update live variables if it is available
             if (lv_)
               lv_->addVirtualRegisterKilled(nReg, mi);
@@ -329,8 +335,9 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb,
     // of the defining block, potentially live across some blocks, then is
     // live into some number of blocks, but gets killed.  Start by adding a
     // range that goes from this definition to the end of the defining block.
-    LiveRange NewLR(defIndex, getInstructionIndex(&mbb->back()) +
-                    InstrSlots::NUM, ValNum);
+    LiveRange NewLR(defIndex,
+                    getInstructionIndex(&mbb->back()) + InstrSlots::NUM,
+                    ValNum);
     DEBUG(std::cerr << " +" << NewLR);
     interval.addRange(NewLR);
 
@@ -342,7 +349,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb,
         MachineBasicBlock* mbb = mf_->getBlockNumbered(i);
         if (!mbb->empty()) {
           LiveRange LR(getInstructionIndex(&mbb->front()),
-                       getInstructionIndex(&mbb->back())+InstrSlots::NUM,
+                       getInstructionIndex(&mbb->back()) + InstrSlots::NUM,
                        ValNum);
           interval.addRange(LR);
           DEBUG(std::cerr << " +" << LR);
@@ -355,7 +362,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb,
     for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i) {
       MachineInstr *Kill = vi.Kills[i];
       LiveRange LR(getInstructionIndex(Kill->getParent()->begin()),
-                   getUseIndex(getInstructionIndex(Kill))+1, ValNum);
+                   getUseIndex(getInstructionIndex(Kill))+1,
+                   ValNum);
       interval.addRange(LR);
       DEBUG(std::cerr << " +" << LR);
     }
@@ -514,8 +522,7 @@ void LiveIntervals::computeIntervals()
          mi != miEnd; ++mi) {
       const TargetInstrDescriptor& tid =
         tm_->getInstrInfo()->get(mi->getOpcode());
-      DEBUG(std::cerr << getInstructionIndex(mi) << "\t";
-            mi->print(std::cerr, tm_));
+      DEBUG(std::cerr << getInstructionIndex(mi) << "\t" << *mi);
 
       // handle implicit defs
       for (const unsigned* id = tid.ImplicitDefs; *id; ++id)
@@ -642,24 +649,25 @@ void LiveIntervals::joinIntervals() {
   }
 
   DEBUG(std::cerr << "*** Register mapping ***\n");
-  DEBUG(for (std::map<unsigned, unsigned>::iterator I = r2rMap_.begin(),
-               E = r2rMap_.end(); I != E; ++I)
-        std::cerr << "  reg " << I->first << " -> reg " << I->second << "\n";);
+  DEBUG(for (int i = 0, e = r2rMap_.size(); i != e; ++i)
+          if (r2rMap_[i])
+             std::cerr << "  reg " << i << " -> reg " << r2rMap_[i] << "\n");
 }
 
 /// Return true if the two specified registers belong to different register
 /// classes.  The registers may be either phys or virt regs.
 bool LiveIntervals::differingRegisterClasses(unsigned RegA,
                                              unsigned RegB) const {
-  const TargetRegisterClass *RegClass;
 
   // Get the register classes for the first reg.
-  if (MRegisterInfo::isVirtualRegister(RegA))
-    RegClass = mf_->getSSARegMap()->getRegClass(RegA);
-  else
-    RegClass = mri_->getRegClass(RegA);
+  if (MRegisterInfo::isPhysicalRegister(RegA)) {
+    assert(MRegisterInfo::isVirtualRegister(RegB) && 
+           "Shouldn't consider two physregs!");
+    return !mf_->getSSARegMap()->getRegClass(RegB)->contains(RegA);
+  }
 
   // Compare against the regclass for the second reg.
+  const TargetRegisterClass *RegClass = mf_->getSSARegMap()->getRegClass(RegA);
   if (MRegisterInfo::isVirtualRegister(RegB))
     return RegClass != mf_->getSSARegMap()->getRegClass(RegB);
   else
@@ -686,6 +694,7 @@ bool LiveIntervals::overlapsAliases(const LiveInterval *LHS,
 }
 
 LiveInterval LiveIntervals::createInterval(unsigned reg) {
-  float Weight = MRegisterInfo::isPhysicalRegister(reg) ?  HUGE_VAL :0.0F;
+  float Weight = MRegisterInfo::isPhysicalRegister(reg) ? 
+                       (float)HUGE_VAL :0.0F;
   return LiveInterval(reg, Weight);
 }