Teach liveintervalanalysis about virtual registers which are defined by reg_sequence...
authorEvan Cheng <evan.cheng@apple.com>
Wed, 5 May 2010 18:27:40 +0000 (18:27 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Wed, 5 May 2010 18:27:40 +0000 (18:27 +0000)
80      %reg1041:6<def> = VSHRNv4i16 %reg1034<kill>, 12, pred:14, pred:%reg0
. . .
120     %reg1041:5<def> = VSHRNv4i16 %reg1039<kill>, 12, pred:14, pred:%reg0

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103102 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/LiveIntervalAnalysis.h
lib/CodeGen/LiveIntervalAnalysis.cpp

index 351217ce583df8b9174b07c1d670e58e5c9ab841..32fa70970d06c3ca911bddd72aed5a8a0f7d9281 100644 (file)
@@ -303,6 +303,12 @@ namespace llvm {
                            SlotIndex MIIdx,
                            MachineOperand& MO, unsigned MOIdx);
 
+    /// isPartialRedef - Return true if the specified def at the specific index
+    /// is partially re-defining the specified live interval. A common case of
+    /// this is a definition of the sub-register. 
+    bool isPartialRedef(SlotIndex MIIdx, MachineOperand &MO,
+                        LiveInterval &interval);
+
     /// handleVirtualRegisterDef - update intervals for a virtual
     /// register def
     void handleVirtualRegisterDef(MachineBasicBlock *MBB,
index ca9921cd3323ee64c1dc1341f617e78bd390c87f..d775e5b74e548128d590c93934fdf3c760f35e5b 100644 (file)
@@ -263,7 +263,7 @@ static void printRegName(unsigned reg, const TargetRegisterInfo* tri_) {
 #endif
 
 static
-bool MultipleDefsByMI(const MachineInstr &MI, unsigned MOIdx) {
+bool MultipleDefsBySameMI(const MachineInstr &MI, unsigned MOIdx) {
   unsigned Reg = MI.getOperand(MOIdx).getReg();
   for (unsigned i = MOIdx+1, e = MI.getNumOperands(); i < e; ++i) {
     const MachineOperand &MO = MI.getOperand(i);
@@ -279,6 +279,24 @@ bool MultipleDefsByMI(const MachineInstr &MI, unsigned MOIdx) {
   return false;
 }
 
+/// isPartialRedef - Return true if the specified def at the specific index is
+/// partially re-defining the specified live interval. A common case of this is
+/// a definition of the sub-register. 
+bool LiveIntervals::isPartialRedef(SlotIndex MIIdx, MachineOperand &MO,
+                                   LiveInterval &interval) {
+  if (!MO.getSubReg() || MO.isEarlyClobber())
+    return false;
+
+  SlotIndex RedefIndex = MIIdx.getDefIndex();
+  const LiveRange *OldLR =
+    interval.getLiveRangeContaining(RedefIndex.getUseIndex());
+  if (OldLR->valno->isDefAccurate()) {
+    MachineInstr *DefMI = getInstructionFromIndex(OldLR->valno->def);
+    return DefMI->findRegisterDefOperandIdx(interval.reg) != -1;
+  }
+  return false;
+}
+
 void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
                                              MachineBasicBlock::iterator mi,
                                              SlotIndex MIIdx,
@@ -302,15 +320,14 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
     // of inputs.
     if (MO.isEarlyClobber())
       defIndex = MIIdx.getUseIndex();
-    VNInfo *ValNo;
     MachineInstr *CopyMI = NULL;
     unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
     if (mi->isExtractSubreg() || mi->isInsertSubreg() || mi->isSubregToReg() ||
         tii_->isMoveInstr(*mi, SrcReg, DstReg, SrcSubReg, DstSubReg))
       CopyMI = mi;
-    // Earlyclobbers move back one.
-    ValNo = interval.getNextValue(defIndex, CopyMI, true, VNInfoAllocator);
 
+    VNInfo *ValNo = interval.getNextValue(defIndex, CopyMI, true,
+                                          VNInfoAllocator);
     assert(ValNo->id == 0 && "First value in interval is not 0?");
 
     // Loop over all of the blocks that the vreg is defined in.  There are
@@ -389,7 +406,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
     }
 
   } else {
-    if (MultipleDefsByMI(*mi, MOIdx))
+    if (MultipleDefsBySameMI(*mi, MOIdx))
       // Mutple defs of the same virtual register by the same instruction. e.g.
       // %reg1031:5<def>, %reg1031:6<def> = VLD1q16 %reg1024<kill>, ...
       // This is likely due to elimination of REG_SEQUENCE instructions. Return
@@ -400,14 +417,23 @@ 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->isRegTiedToUseOperand(MOIdx)) {
+
+    // It may also be partial redef like this:
+    // 80      %reg1041:6<def> = VSHRNv4i16 %reg1034<kill>, 12, pred:14, pred:%reg0
+    // 120     %reg1041:5<def> = VSHRNv4i16 %reg1039<kill>, 12, pred:14, pred:%reg0
+    bool PartReDef = isPartialRedef(MIIdx, MO, interval);
+    if (PartReDef || mi->isRegTiedToUseOperand(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
       // need to take the LiveRegion that defines this register and split it
       // into two values.
-      assert(interval.containsOneValue());
-      SlotIndex DefIndex = interval.getValNumInfo(0)->def.getDefIndex();
+      // Two-address vregs should always only be redefined once.  This means
+      // that at this point, there should be exactly one value number in it.
+      assert((PartReDef || interval.containsOneValue()) &&
+             "Unexpected 2-addr liveint!");
+      unsigned NumVals = interval.getNumValNums();
+      SlotIndex DefIndex = interval.getValNumInfo(NumVals-1)->def.getDefIndex();
       SlotIndex RedefIndex = MIIdx.getDefIndex();
       if (MO.isEarlyClobber())
         RedefIndex = MIIdx.getUseIndex();
@@ -420,10 +446,6 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
       // because the 2-addr copy must be in the same MBB as the redef.
       interval.removeRange(DefIndex, RedefIndex);
 
-      // Two-address vregs should always only be redefined once.  This means
-      // that at this point, there should be exactly one value number in it.
-      assert(interval.containsOneValue() && "Unexpected 2-addr liveint!");
-
       // The new value number (#1) is defined by the instruction we claimed
       // defined value #0.
       VNInfo *ValNo = interval.getNextValue(OldValNo->def, OldValNo->getCopy(),
@@ -451,8 +473,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
           dbgs() << " RESULT: ";
           interval.print(dbgs(), tri_);
         });
-    } else {
-      assert(lv_->isPHIJoin(interval.reg) && "Multiply defined register");
+    } else if (lv_->isPHIJoin(interval.reg)) {
       // In the case of PHI elimination, each variable definition is only
       // live until the end of the block.  We've already taken care of the
       // rest of the live range.
@@ -475,6 +496,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
       ValNo->addKill(indexes_->getTerminatorGap(mbb));
       ValNo->setHasPHIKill(true);
       DEBUG(dbgs() << " phi-join +" << LR);
+    } else {
+      llvm_unreachable("Multiply defined register");
     }
   }