Replace the odd kill# hack with something less fragile.
authorEvan Cheng <evan.cheng@apple.com>
Thu, 29 Nov 2007 09:49:23 +0000 (09:49 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Thu, 29 Nov 2007 09:49:23 +0000 (09:49 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44434 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 69936a0302d2c6ffe6f46b35954177c8ef06db3d..48c7ab6807d0fcc583b0a0a17037bc805774ccdb 100644 (file)
@@ -38,16 +38,18 @@ namespace llvm {
   /// contains ~1u,x to indicate that the value # is not used. 
   ///   def   - Instruction # of the definition.
   ///   reg   - Source reg iff val# is defined by a copy; zero otherwise.
+  ///   hasPHIKill - One or more of the kills are PHI nodes.
   ///   kills - Instruction # of the kills. If a kill is an odd #, it means
   ///           the kill is a phi join point.
   struct VNInfo {
     unsigned id;
     unsigned def;
     unsigned reg;
+    bool hasPHIKill;
     SmallVector<unsigned, 4> kills;
-    VNInfo() : id(~1U), def(~1U), reg(0) {}
+    VNInfo() : id(~1U), def(~1U), reg(0), hasPHIKill(false) {}
     VNInfo(unsigned i, unsigned d, unsigned r)
-      : id(i), def(d), reg(r) {}
+      : id(i), def(d), reg(r), hasPHIKill(false) {}
   };
 
   /// LiveRange structure - This represents a simple register range in the
@@ -158,6 +160,7 @@ namespace llvm {
     void copyValNumInfo(VNInfo *DstValNo, const VNInfo *SrcValNo) {
       DstValNo->def = SrcValNo->def;
       DstValNo->reg = SrcValNo->reg;
+      DstValNo->hasPHIKill = SrcValNo->hasPHIKill;
       DstValNo->kills = SrcValNo->kills;
     }
 
index 934cb7beb9b35c07429544cd6384b4375ca3a52f..472165069746d216da6916e19be109a95a425822 100644 (file)
@@ -206,7 +206,7 @@ LiveInterval::addRangeFrom(LiveRange LR, iterator From) {
         // endpoint as well.
         if (End > it->end)
           extendIntervalEndTo(it, End);
-        else
+        else if (End < it->end)
           // Overlapping intervals, there might have been a kill here.
           removeKill(it->valno, End);
         return it;
@@ -631,6 +631,8 @@ void LiveInterval::print(std::ostream &OS, const MRegisterInfo *MRI) const {
             if (j != ee-1)
               OS << " ";
           }
+          if (vni->hasPHIKill)
+            OS << " phi";
           OS << ")";
         }
       }
index 75d5aac404856bb6586437ae557558a283125402..065143720190924e772dddaeb2a4d93a92b7b29c 100644 (file)
@@ -362,7 +362,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
         DOUT << " Removing [" << Start << "," << End << "] from: ";
         interval.print(DOUT, mri_); DOUT << "\n";
         interval.removeRange(Start, End);
-        interval.addKill(VNI, Start+1); // odd # means phi node
+        interval.addKill(VNI, Start);
+        VNI->hasPHIKill = true;
         DOUT << " RESULT: "; interval.print(DOUT, mri_);
 
         // Replace the interval with one of a NEW value number.  Note that this
@@ -392,7 +393,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
       unsigned killIndex = getInstructionIndex(&mbb->back()) + InstrSlots::NUM;
       LiveRange LR(defIndex, killIndex, ValNo);
       interval.addRange(LR);
-      interval.addKill(ValNo, killIndex+1); // odd # means phi node
+      interval.addKill(ValNo, killIndex);
+      ValNo->hasPHIKill = true;
       DOUT << " +" << LR;
     }
   }
@@ -1081,21 +1083,14 @@ addIntervalsForSpills(const LiveInterval &li,
       vrm.setVirtIsReMaterialized(li.reg, ReMatDefMI);
 
       bool CanDelete = true;
-      for (unsigned j = 0, ee = VNI->kills.size(); j != ee; ++j) {
-        unsigned KillIdx = VNI->kills[j];
-        MachineInstr *KillMI = (KillIdx & 1)
-          ? NULL : getInstructionFromIndex(KillIdx);
-        // Kill is a phi node, not all of its uses can be rematerialized.
+      if (VNI->hasPHIKill) {
+        // A kill is a phi node, not all of its uses can be rematerialized.
         // It must not be deleted.
-        if (!KillMI) {
-          CanDelete = false;
-          // Need a stack slot if there is any live range where uses cannot be
-          // rematerialized.
-          NeedStackSlot = true;
-          break;
-        }
+        CanDelete = false;
+        // Need a stack slot if there is any live range where uses cannot be
+        // rematerialized.
+        NeedStackSlot = true;
       }
-
       if (CanDelete)
         ReMatDelete.set(VN);
     } else {
index 4b96cac84d959391fbee1ab3053b716be859af75..3d2669becd4015a3728a34ab12db50e9d9734ad1 100644 (file)
@@ -490,6 +490,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec TheCopy, bool &Again) {
         if (CopiedValNos.insert(DstValNo)) {
           VNInfo *ValNo = RealDstInt.getNextValue(DstValNo->def, DstValNo->reg,
                                                   li_->getVNInfoAllocator());
+          ValNo->hasPHIKill = DstValNo->hasPHIKill;
           RealDstInt.addKills(ValNo, DstValNo->kills);
           RealDstInt.MergeValueInAsValue(*ResDstInt, DstValNo, ValNo);
         }
@@ -734,6 +735,7 @@ bool SimpleRegisterCoalescing::SimpleJoin(LiveInterval &LHS, LiveInterval &RHS)
   
   // Okay, the final step is to loop over the RHS live intervals, adding them to
   // the LHS.
+  LHSValNo->hasPHIKill |= VNI->hasPHIKill;
   LHS.addKills(LHSValNo, VNI->kills);
   LHS.MergeRangesInAsValue(RHS, LHSValNo);
   LHS.weight += RHS.weight;
@@ -969,6 +971,7 @@ bool SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS,
     VNInfo *VNI = I->first;
     unsigned LHSValID = LHSValNoAssignments[VNI->id];
     LiveInterval::removeKill(NewVNInfo[LHSValID], VNI->def);
+    NewVNInfo[LHSValID]->hasPHIKill |= VNI->hasPHIKill;
     RHS.addKills(NewVNInfo[LHSValID], VNI->kills);
   }
 
@@ -978,6 +981,7 @@ bool SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS,
     VNInfo *VNI = I->first;
     unsigned RHSValID = RHSValNoAssignments[VNI->id];
     LiveInterval::removeKill(NewVNInfo[RHSValID], VNI->def);
+    NewVNInfo[RHSValID]->hasPHIKill |= VNI->hasPHIKill;
     LHS.addKills(NewVNInfo[RHSValID], VNI->kills);
   }