Fix SingleSource/Regression/C/2005-05-06-LongLongSignedShift.c, we were not
[oota-llvm.git] / lib / CodeGen / LiveIntervalAnalysis.cpp
index c3c6fee98311127aafdd660a2ef3d606aa9cd428..8a54051673b3d569710a02719b9fb034592d7beb 100644 (file)
@@ -86,6 +86,7 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
   mf_ = &fn;
   tm_ = &fn.getTarget();
   mri_ = tm_->getRegisterInfo();
+  tii_ = tm_->getInstrInfo();
   lv_ = &getAnalysis<LiveVariables>();
   allocatableRegs_ = mri_->getAllocatableSet(fn);
   r2rMap_.grow(mf_->getSSARegMap()->getLastVirtReg());
@@ -120,7 +121,6 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
   // perform a final pass over the instructions and compute spill
   // weights, coalesce virtual registers and remove identity moves
   const LoopInfo& loopInfo = getAnalysis<LoopInfo>();
-  const TargetInstrInfo& tii = *tm_->getInstrInfo();
 
   for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
        mbbi != mbbe; ++mbbi) {
@@ -131,7 +131,7 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
          mii != mie; ) {
       // if the move will be an identity move delete it
       unsigned srcReg, dstReg, RegRep;
-      if (tii.isMoveInstr(*mii, srcReg, dstReg) &&
+      if (tii_->isMoveInstr(*mii, srcReg, dstReg) &&
           (RegRep = rep(srcReg)) == rep(dstReg)) {
         // remove from def list
         LiveInterval &interval = getOrCreateInterval(RegRep);
@@ -156,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;
@@ -169,10 +169,10 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
 }
 
 /// print - Implement the dump method.
-void LiveIntervals::print(std::ostream &O) const {
+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 << "  " << I->second << "\n";
 
   O << "********** MACHINEINSTRS **********\n";
   for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
@@ -185,7 +185,6 @@ void LiveIntervals::print(std::ostream &O) const {
   }
 }
 
-
 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
@@ -224,7 +223,7 @@ addIntervalsForSpills(const LiveInterval &li, VirtRegMap &vrm, int slot) {
           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;
@@ -262,7 +261,7 @@ addIntervalsForSpills(const LiveInterval &li, VirtRegMap &vrm, int slot) {
 
             // 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);
@@ -445,7 +444,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb,
 
 void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
                                               MachineBasicBlock::iterator mi,
-                                              LiveInterval& interval)
+                                              LiveInterval& interval,
+                                              unsigned SrcReg, unsigned DestReg)
 {
   // A physical register cannot be live across basic block, so its
   // lifetime must end somewhere in its defining basic block.
@@ -487,6 +487,45 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
 
 exit:
   assert(start < end && "did not find end of interval?");
+
+  // Finally, if this is defining a new range for the physical register, and if
+  // that physreg is just a copy from a vreg, and if THAT vreg was a copy from
+  // the physreg, then the new fragment has the same value as the one copied
+  // into the vreg.
+  if (interval.reg == DestReg && !interval.empty() &&
+      MRegisterInfo::isVirtualRegister(SrcReg)) {
+
+    // Get the live interval for the vreg, see if it is defined by a copy.
+    LiveInterval &SrcInterval = getOrCreateInterval(SrcReg);
+
+    if (SrcInterval.containsOneValue()) {
+      assert(!SrcInterval.empty() && "Can't contain a value and be empty!");
+
+      // Get the first index of the first range.  Though the interval may have
+      // multiple liveranges in it, we only check the first.
+      unsigned StartIdx = SrcInterval.begin()->start;
+      MachineInstr *SrcDefMI = getInstructionFromIndex(StartIdx);
+
+      // Check to see if the vreg was defined by a copy instruction, and that
+      // the source was this physreg.
+      unsigned VRegSrcSrc, VRegSrcDest;
+      if (tii_->isMoveInstr(*SrcDefMI, VRegSrcSrc, VRegSrcDest) &&
+          SrcReg == VRegSrcDest && VRegSrcSrc == DestReg) {
+        // Okay, now we know that the vreg was defined by a copy from this
+        // physreg.  Find the value number being copied and use it as the value
+        // for this range.
+        const LiveRange *DefRange = interval.getLiveRangeContaining(StartIdx-1);
+        if (DefRange) {
+          LiveRange LR(start, end, DefRange->ValId);
+          interval.addRange(LR);
+          DEBUG(std::cerr << " +" << LR << '\n');
+          return;
+        }
+      }
+    }
+  }
+
+
   LiveRange LR(start, end, interval.getNextValue());
   interval.addRange(LR);
   DEBUG(std::cerr << " +" << LR << '\n');
@@ -498,9 +537,14 @@ void LiveIntervals::handleRegisterDef(MachineBasicBlock *MBB,
   if (MRegisterInfo::isVirtualRegister(reg))
     handleVirtualRegisterDef(MBB, MI, getOrCreateInterval(reg));
   else if (allocatableRegs_[reg]) {
-    handlePhysicalRegisterDef(MBB, MI, getOrCreateInterval(reg));
+    unsigned SrcReg = 0, DestReg = 0;
+    bool IsMove = tii_->isMoveInstr(*MI, SrcReg, DestReg);
+
+    handlePhysicalRegisterDef(MBB, MI, getOrCreateInterval(reg),
+                              SrcReg, DestReg);
     for (const unsigned* AS = mri_->getAliasSet(reg); *AS; ++AS)
-      handlePhysicalRegisterDef(MBB, MI, getOrCreateInterval(*AS));
+      handlePhysicalRegisterDef(MBB, MI, getOrCreateInterval(*AS),
+                                SrcReg, DestReg);
   }
 }
 
@@ -542,7 +586,6 @@ void LiveIntervals::computeIntervals()
 
 void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) {
   DEBUG(std::cerr << ((Value*)MBB->getBasicBlock())->getName() << ":\n");
-  const TargetInstrInfo &TII = *tm_->getInstrInfo();
 
   for (MachineBasicBlock::iterator mi = MBB->begin(), mie = MBB->end();
        mi != mie; ++mi) {
@@ -552,7 +595,7 @@ void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) {
     // physical registers since we do not have liveness information
     // on not allocatable physical registers
     unsigned regA, regB;
-    if (TII.isMoveInstr(*mi, regA, regB) &&
+    if (tii_->isMoveInstr(*mi, regA, regB) &&
         (MRegisterInfo::isVirtualRegister(regA) || allocatableRegs_[regA]) &&
         (MRegisterInfo::isVirtualRegister(regB) || allocatableRegs_[regB])) {
 
@@ -659,15 +702,16 @@ void LiveIntervals::joinIntervals() {
 /// 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
@@ -694,6 +738,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);
 }