Rename getABITypeSize to getTypePaddedSize, as
[oota-llvm.git] / lib / CodeGen / LiveIntervalAnalysis.cpp
index 2a979e19eb560ec2d3be3b16aba3763f89d6c0d5..22595895627b62ec5b81110eb31870f24cab235a 100644 (file)
@@ -323,6 +323,47 @@ bool LiveIntervals::conflictsWithPhysRegDef(const LiveInterval &li,
   return false;
 }
 
+/// conflictsWithPhysRegRef - Similar to conflictsWithPhysRegRef except
+/// it can check use as well.
+bool LiveIntervals::conflictsWithPhysRegRef(LiveInterval &li,
+                                            unsigned Reg, bool CheckUse,
+                                  SmallPtrSet<MachineInstr*,32> &JoinedCopies) {
+  for (LiveInterval::Ranges::const_iterator
+         I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) {
+    for (unsigned index = getBaseIndex(I->start),
+           end = getBaseIndex(I->end-1) + InstrSlots::NUM; index != end;
+         index += InstrSlots::NUM) {
+      // Skip deleted instructions.
+      MachineInstr *MI = 0;
+      while (index != end) {
+        MI = getInstructionFromIndex(index);
+        if (MI)
+          break;
+        index += InstrSlots::NUM;
+      }
+      if (index == end) break;
+
+      if (JoinedCopies.count(MI))
+        continue;
+      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+        MachineOperand& MO = MI->getOperand(i);
+        if (!MO.isReg())
+          continue;
+        if (MO.isUse() && !CheckUse)
+          continue;
+        unsigned PhysReg = MO.getReg();
+        if (PhysReg == 0 || TargetRegisterInfo::isVirtualRegister(PhysReg))
+          continue;
+        if (tri_->isSubRegister(Reg, PhysReg))
+          return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+
 void LiveIntervals::printRegName(unsigned reg) const {
   if (TargetRegisterInfo::isPhysicalRegister(reg))
     cerr << tri_->getName(reg);
@@ -360,6 +401,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
         mi->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
         tii_->isMoveInstr(*mi, SrcReg, DstReg))
       CopyMI = mi;
+    // Earlyclobbers move back one.
     ValNo = interval.getNextValue(defIndex, CopyMI, VNInfoAllocator);
 
     assert(ValNo->id == 0 && "First value in interval is not 0?");
@@ -426,7 +468,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
     // must be due to phi elimination or two addr elimination.  If this is
     // the result of two address elimination, then the vreg is one of the
     // def-and-use register operand.
-    if (mi->isRegReDefinedByTwoAddr(interval.reg, MOIdx)) {
+    if (mi->isRegReDefinedByTwoAddr(MOIdx)) {
       // If this is a two-address definition, then we have already processed
       // the live range.  The only problem is that we didn't realize there
       // are actually two values in the live interval.  Because of this we
@@ -435,9 +477,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
       assert(interval.containsOneValue());
       unsigned DefIndex = getDefIndex(interval.getValNumInfo(0)->def);
       unsigned RedefIndex = getDefIndex(MIIdx);
-      // Earlyclobbers move back one.
-      if (MO.isEarlyClobber())
-        RedefIndex = getUseIndex(MIIdx);
+      // It cannot be an early clobber MO.
+      assert(!MO.isEarlyClobber() && "Unexpected early clobber!");
 
       const LiveRange *OldLR = interval.getLiveRangeContaining(RedefIndex-1);
       VNInfo *OldValNo = OldLR->valno;
@@ -505,9 +546,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
       // live until the end of the block.  We've already taken care of the
       // rest of the live range.
       unsigned defIndex = getDefIndex(MIIdx);
-      // Earlyclobbers move back one.
-      if (MO.isEarlyClobber())
-        defIndex = getUseIndex(MIIdx);
+      // It cannot be an early clobber MO.
+      assert(!MO.isEarlyClobber() && "Unexpected early clobber!");
       
       VNInfo *ValNo;
       MachineInstr *CopyMI = NULL;
@@ -592,8 +632,11 @@ exit:
 
   // Already exists? Extend old live interval.
   LiveInterval::iterator OldLR = interval.FindLiveRangeContaining(start);
-  VNInfo *ValNo = (OldLR != interval.end())
+  bool Extend = OldLR != interval.end();
+  VNInfo *ValNo = Extend
     ? OldLR->valno : interval.getNextValue(start, CopyMI, VNInfoAllocator);
+  if (MO.isEarlyClobber() && Extend)
+    ValNo->redefByEC = true;
   LiveRange LR(start, end, ValNo);
   interval.addRange(LR);
   interval.addKill(LR.valno, end);
@@ -750,7 +793,7 @@ bool LiveIntervals::findLiveInMBBs(unsigned Start, unsigned End,
 
   bool ResVal = false;
   while (I != Idx2MBBMap.end()) {
-    if (I->first > End)
+    if (I->first >= End)
       break;
     MBBs.push_back(I->second);
     ResVal = true;
@@ -792,10 +835,15 @@ unsigned LiveIntervals::getVNInfoSourceReg(const VNInfo *VNI) const {
   if (!VNI->copy)
     return 0;
 
-  if (VNI->copy->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG)
-    return VNI->copy->getOperand(1).getReg();
-  if (VNI->copy->getOpcode() == TargetInstrInfo::INSERT_SUBREG)
+  if (VNI->copy->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
+    // If it's extracting out of a physical register, return the sub-register.
+    unsigned Reg = VNI->copy->getOperand(1).getReg();
+    if (TargetRegisterInfo::isPhysicalRegister(Reg))
+      Reg = tri_->getSubReg(Reg, VNI->copy->getOperand(2).getImm());
+    return Reg;
+  } else if (VNI->copy->getOpcode() == TargetInstrInfo::INSERT_SUBREG)
     return VNI->copy->getOperand(2).getReg();
+
   unsigned SrcReg, DstReg;
   if (tii_->isMoveInstr(*VNI->copy, SrcReg, DstReg))
     return SrcReg;
@@ -918,7 +966,7 @@ bool LiveIntervals::isReMaterializable(const LiveInterval &li,
         MachineRegisterInfo::def_iterator I = mri_->def_begin(Reg),
                                           E = mri_->def_end();
 
-        // For the def, it should be the only def.
+        // For the def, it should be the only def of that register.
         if (MO.isDef() && (next(I) != E || IsLiveIn))
           return false;
 
@@ -931,7 +979,7 @@ bool LiveIntervals::isReMaterializable(const LiveInterval &li,
             else if (Reg != ImpUse)
               return false;
           }
-          // For uses, there should be only one associate def.
+          // For the use, there should be only one associated def.
           if (I != E && (next(I) != E || IsLiveIn))
             return false;
         }
@@ -1800,7 +1848,7 @@ addIntervalsForSpills(const LiveInterval &li,
   // Spill slot weight.
   SSWeight = 0.0f;
 
-  // Each bit specify whether it a spill is required in the MBB.
+  // Each bit specify whether a spill is required in the MBB.
   BitVector SpillMBBs(mf_->getNumBlockIDs());
   DenseMap<unsigned, std::vector<SRInfo> > SpillIdxes;
   BitVector RestoreMBBs(mf_->getNumBlockIDs());
@@ -1841,7 +1889,7 @@ addIntervalsForSpills(const LiveInterval &li,
     int LdSlot = 0;
     bool isLoadSS = DefIsReMat && tii_->isLoadFromStackSlot(ReMatDefMI, LdSlot);
     bool isLoad = isLoadSS ||
-      (DefIsReMat && (ReMatDefMI->getDesc().isSimpleLoad()));
+      (DefIsReMat && (ReMatDefMI->getDesc().canFoldAsLoad()));
     bool IsFirstRange = true;
     for (LiveInterval::Ranges::const_iterator
            I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) {
@@ -1927,7 +1975,7 @@ addIntervalsForSpills(const LiveInterval &li,
     int LdSlot = 0;
     bool isLoadSS = DefIsReMat && tii_->isLoadFromStackSlot(ReMatDefMI, LdSlot);
     bool isLoad = isLoadSS ||
-      (DefIsReMat && ReMatDefMI->getDesc().isSimpleLoad());
+      (DefIsReMat && ReMatDefMI->getDesc().canFoldAsLoad());
     rewriteInstructionsForSpills(li, TrySplit, I, ReMatOrigDefMI, ReMatDefMI,
                                Slot, LdSlot, isLoad, isLoadSS, DefIsReMat,
                                CanDelete, vrm, rc, ReMatIds, loopInfo,
@@ -2056,18 +2104,20 @@ addIntervalsForSpills(const LiveInterval &li,
           int LdSlot = 0;
           bool isLoadSS = tii_->isLoadFromStackSlot(ReMatDefMI, LdSlot);
           // If the rematerializable def is a load, also try to fold it.
-          if (isLoadSS || ReMatDefMI->getDesc().isSimpleLoad())
+          if (isLoadSS || ReMatDefMI->getDesc().canFoldAsLoad())
             Folded = tryFoldMemoryOperand(MI, vrm, ReMatDefMI, index,
                                           Ops, isLoadSS, LdSlot, VReg);
-          unsigned ImpUse = getReMatImplicitUse(li, ReMatDefMI);
-          if (ImpUse) {
-            // Re-matting an instruction with virtual register use. Add the
-            // register as an implicit use on the use MI and update the register
-            // interval's spill weight to HUGE_VALF to prevent it from being
-            // spilled.
-            LiveInterval &ImpLi = getInterval(ImpUse);
-            ImpLi.weight = HUGE_VALF;
-            MI->addOperand(MachineOperand::CreateReg(ImpUse, false, true));
+          if (!Folded) {
+            unsigned ImpUse = getReMatImplicitUse(li, ReMatDefMI);
+            if (ImpUse) {
+              // Re-matting an instruction with virtual register use. Add the
+              // register as an implicit use on the use MI and update the register
+              // interval's spill weight to HUGE_VALF to prevent it from being
+              // spilled.
+              LiveInterval &ImpLi = getInterval(ImpUse);
+              ImpLi.weight = HUGE_VALF;
+              MI->addOperand(MachineOperand::CreateReg(ImpUse, false, true));
+            }
           }
         }
       }