[PATCH] D30558: Fix value numbers in successor blocks if liveout number has changed

Stanislav Mekhanoshin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 3 12:57:44 PST 2017


rampitec updated this revision to Diff 90522.
rampitec added a comment.

Successors only updated in a very rare case liveout value number has changed. The fast check should keep compile time as before.


Repository:
  rL LLVM

https://reviews.llvm.org/D30558

Files:
  lib/CodeGen/LiveIntervalAnalysis.cpp
  unittests/MI/LiveIntervalTest.cpp


Index: unittests/MI/LiveIntervalTest.cpp
===================================================================
--- unittests/MI/LiveIntervalTest.cpp
+++ unittests/MI/LiveIntervalTest.cpp
@@ -382,6 +382,24 @@
   });
 }
 
+TEST(LiveIntervalTest, SwapSubregDefs) {
+  // handleMoveUp had a bug not updating valno of segment incoming to bb.2
+  // after swapping subreg definitions.
+  liveIntervalTest(R"MIR(
+    successors: %bb.1, %bb.2
+    undef %0.sub0 = IMPLICIT_DEF
+    %0.sub1 = IMPLICIT_DEF
+    S_CBRANCH_VCCNZ %bb.2, implicit undef %vcc
+    S_BRANCH %bb.1
+  bb.1:
+    S_NOP 0, implicit %0.sub1
+  bb.2:
+    S_NOP 0, implicit %0.sub1
+)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
+    testHandleMove(MF, LIS, 1, 0);
+  });
+}
+
 int main(int argc, char **argv) {
   ::testing::InitGoogleTest(&argc, argv);
   initLLVM();
Index: lib/CodeGen/LiveIntervalAnalysis.cpp
===================================================================
--- lib/CodeGen/LiveIntervalAnalysis.cpp
+++ lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -978,14 +978,49 @@
       }
       dbgs() << ":\t" << LR << '\n';
     });
+    const SlotIndexes *Indexes = LIS.getSlotIndexes();
+    const MachineBasicBlock *MBB = Indexes->getMBBFromIndex(NewIdx);
+    const VNInfo *OldLiveOut = LR.getVNInfoBefore(LIS.getMBBEndIdx(MBB));
+
     if (SlotIndex::isEarlierInstr(OldIdx, NewIdx))
       handleMoveDown(LR);
     else
       handleMoveUp(LR, Reg, LaneMask);
+
+    // Fix liveins to other blocks which may need to be changed to new liveouts.
+    if (OldLiveOut && LR.getNumValNums() > 1) {
+      const VNInfo *NewLiveOut = LR.getVNInfoBefore(LIS.getMBBEndIdx(MBB));
+      if (OldLiveOut->id != NewLiveOut->id)
+        updateSuccessors(LR, MBB, NewLiveOut);
+    }
+
     DEBUG(dbgs() << "        -->\t" << LR << '\n');
     LR.verify();
   }
 
+  // Update value numbers in successor blocks in case if we have a new liveout
+  // replacing an old one. I.e. if we have swapped two instructions defining
+  // subregisters of a same register. Last one becomes a new liveout.
+  void updateSuccessors(LiveRange &LR, const MachineBasicBlock *MBB,
+                        const VNInfo *Valno) {
+    VNInfo *Out = LR.getVNInfoBefore(LIS.getMBBEndIdx(MBB));
+    if (!Out || Out != Valno)
+      return;
+    // This is a liveout.
+    // Find live-ins to other blocks which should connect to this live-out.
+    for (const auto &Succ : MBB->successors()) {
+      // Now set new value number in a successor.
+      auto *InSeg = LR.getSegmentContaining(LIS.getMBBStartIdx(Succ));
+      if (InSeg && !InSeg->valno->isPHIDef() && InSeg->valno != Out) {
+        InSeg->valno = Out;
+        // Iterate next successors. No need to maintain visited list because
+        // when we update all possible segments loop will terminate.
+        if (InSeg->contains(LIS.getMBBEndIdx(Succ).getPrevSlot()))
+          updateSuccessors(LR, Succ, Out);
+      }
+    }
+  }
+
   /// Update LR to reflect an instruction has been moved downwards from OldIdx
   /// to NewIdx (OldIdx < NewIdx).
   void handleMoveDown(LiveRange &LR) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D30558.90522.patch
Type: text/x-patch
Size: 3105 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170303/9578c0e0/attachment.bin>


More information about the llvm-commits mailing list