Fix PR5024. LiveVariables physical register defs should *commit* only after all
[oota-llvm.git] / lib / CodeGen / LiveIntervalAnalysis.cpp
index 124ff022258c50530f818527e438b001b8e568b8..825cf396ab127aff026059ad30744bd1153f1bb0 100644 (file)
@@ -109,18 +109,15 @@ void LiveIntervals::releaseMemory() {
 }
 
 static bool CanTurnIntoImplicitDef(MachineInstr *MI, unsigned Reg,
-                                   const TargetInstrInfo *tii_) {
+                                   unsigned OpIdx, const TargetInstrInfo *tii_){
   unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
   if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
       Reg == SrcReg)
     return true;
 
-  if ((MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
-       MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) &&
-      MI->getOperand(2).getReg() == Reg)
+  if (OpIdx == 2 && MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG)
     return true;
-  if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG &&
-      MI->getOperand(1).getReg() == Reg)
+  if (OpIdx == 1 && MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG)
     return true;
   return false;
 }
@@ -144,10 +141,28 @@ void LiveIntervals::processImplicitDefs() {
       if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
         unsigned Reg = MI->getOperand(0).getReg();
         ImpDefRegs.insert(Reg);
+        if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
+          for (const unsigned *SS = tri_->getSubRegisters(Reg); *SS; ++SS)
+            ImpDefRegs.insert(*SS);
+        }
         ImpDefMIs.push_back(MI);
         continue;
       }
 
+      if (MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) {
+        MachineOperand &MO = MI->getOperand(2);
+        if (ImpDefRegs.count(MO.getReg())) {
+          // %reg1032<def> = INSERT_SUBREG %reg1032, undef, 2
+          // This is an identity copy, eliminate it now.
+          if (MO.isKill()) {
+            LiveVariables::VarInfo& vi = lv_->getVarInfo(MO.getReg());
+            vi.removeKill(MI);
+          }
+          MI->eraseFromParent();
+          continue;
+        }
+      }
+
       bool ChangedToImpDef = false;
       for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
         MachineOperand& MO = MI->getOperand(i);
@@ -159,13 +174,16 @@ void LiveIntervals::processImplicitDefs() {
         if (!ImpDefRegs.count(Reg))
           continue;
         // Use is a copy, just turn it into an implicit_def.
-        if (CanTurnIntoImplicitDef(MI, Reg, tii_)) {
+        if (CanTurnIntoImplicitDef(MI, Reg, i, tii_)) {
           bool isKill = MO.isKill();
           MI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF));
           for (int j = MI->getNumOperands() - 1, ee = 0; j > ee; --j)
             MI->RemoveOperand(j);
-          if (isKill)
+          if (isKill) {
             ImpDefRegs.erase(Reg);
+            LiveVariables::VarInfo& vi = lv_->getVarInfo(Reg);
+            vi.removeKill(MI);
+          }
           ChangedToImpDef = true;
           break;
         }
@@ -637,13 +655,14 @@ bool LiveIntervals::conflictsWithPhysRegRef(LiveInterval &li,
   return false;
 }
 
-
+#ifndef NDEBUG
 static void printRegName(unsigned reg, const TargetRegisterInfo* tri_) {
   if (TargetRegisterInfo::isPhysicalRegister(reg))
     errs() << tri_->getName(reg);
   else
     errs() << "%reg" << reg;
 }
+#endif
 
 void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
                                              MachineBasicBlock::iterator mi,
@@ -664,7 +683,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
   if (interval.empty()) {
     // Get the Idx of the defining instructions.
     MachineInstrIndex defIndex = getDefIndex(MIIdx);
-    // Earlyclobbers move back one.
+    // Earlyclobbers move back one, so that they overlap the live range
+    // of inputs.
     if (MO.isEarlyClobber())
       defIndex = getUseIndex(MIIdx);
     VNInfo *ValNo;
@@ -689,6 +709,11 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
       MachineInstrIndex killIdx;
       if (vi.Kills[0] != mi)
         killIdx = getNextSlot(getUseIndex(getInstructionIndex(vi.Kills[0])));
+      else if (MO.isEarlyClobber())
+        // Earlyclobbers that die in this instruction move up one extra, to
+        // compensate for having the starting point moved back one.  This
+        // gets them to overlap the live range of other outputs.
+        killIdx = getNextSlot(getNextSlot(defIndex));
       else
         killIdx = getNextSlot(defIndex);
 
@@ -731,8 +756,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
       MachineInstr *Kill = vi.Kills[i];
       MachineInstrIndex killIdx =
         getNextSlot(getUseIndex(getInstructionIndex(Kill)));
-      LiveRange LR(getMBBStartIdx(Kill->getParent()),
-                   killIdx, ValNo);
+      LiveRange LR(getMBBStartIdx(Kill->getParent()), killIdx, ValNo);
       interval.addRange(LR);
       ValNo->addKill(killIdx);
       DEBUG(errs() << " +" << LR);
@@ -790,7 +814,9 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
       // range covering the def slot.
       if (MO.isDead())
         interval.addRange(
-          LiveRange(RedefIndex, getNextSlot(RedefIndex), OldValNo));
+          LiveRange(RedefIndex, MO.isEarlyClobber() ?
+                                getNextSlot(getNextSlot(RedefIndex)) :
+                                getNextSlot(RedefIndex), OldValNo));
 
       DEBUG({
           errs() << " RESULT: ";
@@ -891,9 +917,14 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
   // If it is not used after definition, it is considered dead at
   // the instruction defining it. Hence its interval is:
   // [defSlot(def), defSlot(def)+1)
+  // For earlyclobbers, the defSlot was pushed back one; the extra
+  // advance below compensates.
   if (MO.isDead()) {
     DEBUG(errs() << " dead");
-    end = getNextSlot(start);
+    if (MO.isEarlyClobber())
+      end = getNextSlot(getNextSlot(start));
+    else
+      end = getNextSlot(start);
     goto exit;
   }
 
@@ -1052,23 +1083,19 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
 bool
 LiveIntervals::isProfitableToCoalesce(LiveInterval &DstInt, LiveInterval &SrcInt,
                                    SmallVector<MachineInstr*,16> &IdentCopies,
-                                   SmallVector<MachineInstr*,16> &OtherCopies,
-                                   bool &HaveConflict) {
-  HaveConflict = false;
-
+                                   SmallVector<MachineInstr*,16> &OtherCopies) {
+  bool HaveConflict = false;
   unsigned NumIdent = 0;
-  unsigned NumSources = 0;
   for (MachineRegisterInfo::reg_iterator ri = mri_->reg_begin(SrcInt.reg),
          re = mri_->reg_end(); ri != re; ++ri) {
     MachineOperand &O = ri.getOperand();
     if (!O.isDef())
       continue;
 
-    ++NumSources;
     MachineInstr *MI = &*ri;
     unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
     if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
-      continue;
+      return false;
     if (SrcReg != DstInt.reg) {
       OtherCopies.push_back(MI);
       HaveConflict |= DstInt.liveAt(getInstructionIndex(MI));
@@ -1078,7 +1105,9 @@ LiveIntervals::isProfitableToCoalesce(LiveInterval &DstInt, LiveInterval &SrcInt
     }
   }
 
-  return NumSources >= 5 && (((float)NumIdent) / NumSources) > 0.20F;
+  if (!HaveConflict)
+    return false; // Let coalescer handle it
+  return IdentCopies.size() > OtherCopies.size();
 }
 
 void LiveIntervals::performEarlyCoalescing() {
@@ -1104,78 +1133,78 @@ void LiveIntervals::performEarlyCoalescing() {
     LiveInterval &SrcInt = getInterval(PHISrc);
     SmallVector<MachineInstr*, 16> IdentCopies;
     SmallVector<MachineInstr*, 16> OtherCopies;
-    bool HaveConflict;
-    if (!isProfitableToCoalesce(DstInt, SrcInt, IdentCopies, OtherCopies,
-                                HaveConflict))
+    if (!isProfitableToCoalesce(DstInt, SrcInt, IdentCopies, OtherCopies))
       continue;
 
     DEBUG(errs() << "PHI Join: " << *Join);
     assert(DstInt.containsOneValue() && "PHI join should have just one val#!");
     VNInfo *VNI = DstInt.getValNumInfo(0);
-    VNInfo *NewVNI = HaveConflict
-      ? 0 : SrcInt.getNextValue(VNI->def, 0, false, VNInfoAllocator);
+
+    // Change the non-identity copies to directly target the phi destination.
+    for (unsigned i = 0, e = OtherCopies.size(); i != e; ++i) {
+      MachineInstr *PHICopy = OtherCopies[i];
+      DEBUG(errs() << "Moving: " << *PHICopy);
+
+      MachineInstrIndex MIIndex = getInstructionIndex(PHICopy);
+      MachineInstrIndex DefIndex = getDefIndex(MIIndex);
+      LiveRange *SLR = SrcInt.getLiveRangeContaining(DefIndex);
+      MachineInstrIndex StartIndex = SLR->start;
+      MachineInstrIndex EndIndex = SLR->end;
+
+      // Delete val# defined by the now identity copy and add the range from
+      // beginning of the mbb to the end of the range.
+      SrcInt.removeValNo(SLR->valno);
+      DEBUG(errs() << "  added range [" << StartIndex << ','
+            << EndIndex << "] to reg" << DstInt.reg << '\n');
+      if (DstInt.liveAt(StartIndex))
+        DstInt.removeRange(StartIndex, EndIndex);
+      VNInfo *NewVNI = DstInt.getNextValue(DefIndex, PHICopy, true,
+                                           VNInfoAllocator);
+      NewVNI->setHasPHIKill(true);
+      DstInt.addRange(LiveRange(StartIndex, EndIndex, NewVNI));
+      for (unsigned j = 0, ee = PHICopy->getNumOperands(); j != ee; ++j) {
+        MachineOperand &MO = PHICopy->getOperand(j);
+        if (!MO.isReg() || MO.getReg() != PHISrc)
+          continue;
+        MO.setReg(PHIDst);
+      }
+    }
+
     // Now let's eliminate all the would-be identity copies.
     for (unsigned i = 0, e = IdentCopies.size(); i != e; ++i) {
       MachineInstr *PHICopy = IdentCopies[i];
       DEBUG(errs() << "Coalescing: " << *PHICopy);
 
-      MachineBasicBlock *PHIMBB = PHICopy->getParent();
       MachineInstrIndex MIIndex = getInstructionIndex(PHICopy);
       MachineInstrIndex DefIndex = getDefIndex(MIIndex);
       LiveRange *SLR = SrcInt.getLiveRangeContaining(DefIndex);
-      MachineInstrIndex StartIndex = HaveConflict
-        ? SLR->start : getMBBStartIdx(PHIMBB);
+      MachineInstrIndex StartIndex = SLR->start;
       MachineInstrIndex EndIndex = SLR->end;
 
       // Delete val# defined by the now identity copy and add the range from
       // beginning of the mbb to the end of the range.
       SrcInt.removeValNo(SLR->valno);
-      if (HaveConflict) {
-        DEBUG(errs() << "  added range [" << StartIndex << ','
-                     << EndIndex << "] to reg" << DstInt.reg << '\n');
-        DstInt.addRange(LiveRange(StartIndex, EndIndex, VNI));
-        // FIXME: Update uses of src to dst in this range?
-      } else {
-        DEBUG(errs() << "  added range [" << StartIndex << ','
-                     << SLR->start << "] to reg" << SrcInt.reg << '\n');
-        SrcInt.addRange(LiveRange(StartIndex, EndIndex, NewVNI));
-        if (PHICopy->killsRegister(PHIDst))
-          EndIndex = DefIndex;
-        DstInt.removeRange(StartIndex, EndIndex);
-      }
       RemoveMachineInstrFromMaps(PHICopy);
       PHICopy->eraseFromParent();
+      DEBUG(errs() << "  added range [" << StartIndex << ','
+            << EndIndex << "] to reg" << DstInt.reg << '\n');
+      DstInt.addRange(LiveRange(StartIndex, EndIndex, VNI));
     }
-    if (HaveConflict) {
-      // First unset the kill. 
-      for (unsigned i = 0, e = Join->getNumOperands(); i != e; ++i) {
-        MachineOperand &O = Join->getOperand(i);
-        if (!O.isReg() || O.getReg() != PHISrc)
-          continue;
-        if (O.isKill())
-          O.setIsKill(false);
-      }
-      MachineInstrIndex MIIndex = getInstructionIndex(Join);
-      MachineInstrIndex UseIndex = getUseIndex(MIIndex);
-      MachineInstrIndex DefIndex = getDefIndex(MIIndex);
-      LiveRange *SLR = SrcInt.getLiveRangeContaining(UseIndex);
-      LiveRange *DLR = DstInt.getLiveRangeContaining(DefIndex);
-      SrcInt.addRange(LiveRange(DLR->start, DLR->end, SLR->valno));
-    } else {
-      SrcInt.MergeValueInAsValue(DstInt, VNI, NewVNI);
-
-      // Change all references of phi source to destination.
-      for (MachineRegisterInfo::reg_iterator ri = mri_->reg_begin(PHIDst),
-             re = mri_->reg_end(); ri != re; ) {
-        MachineOperand &O = ri.getOperand();
-        ++ri;
-        O.setReg(PHISrc);
-      }
-      removeInterval(DstInt.reg);
 
-      RemoveMachineInstrFromMaps(Join);
-      Join->eraseFromParent();
-    }
+    // Remove the phi join and update the phi block liveness.
+    MachineInstrIndex MIIndex = getInstructionIndex(Join);
+    MachineInstrIndex UseIndex = getUseIndex(MIIndex);
+    MachineInstrIndex DefIndex = getDefIndex(MIIndex);
+    LiveRange *SLR = SrcInt.getLiveRangeContaining(UseIndex);
+    LiveRange *DLR = DstInt.getLiveRangeContaining(DefIndex);
+    DLR->valno->setCopy(0);
+    DLR->valno->setIsDefAccurate(false);
+    DstInt.addRange(LiveRange(SLR->start, SLR->end, DLR->valno));
+    SrcInt.removeRange(SLR->start, SLR->end);
+    assert(SrcInt.empty());
+    removeInterval(PHISrc);
+    RemoveMachineInstrFromMaps(Join);
+    Join->eraseFromParent();
 
     ++numCoalescing;
   }