[llvm] r276724 - LiveIntervalAnalysis: Fix handleMoveDown() problem

Matthias Braun via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 25 20:57:46 PDT 2016


Author: matze
Date: Mon Jul 25 22:57:45 2016
New Revision: 276724

URL: http://llvm.org/viewvc/llvm-project?rev=276724&view=rev
Log:
LiveIntervalAnalysis: Fix handleMoveDown() problem

If we move a last-use register read to a later position we may skip
intermediate segments. This may require us to not only extend the
segment before the NewIdx, but also extend the segment live-in to
OldIdx.

This switches LiveIntervalTest to use AMDGPU so we can test subregister
liveness.

Modified:
    llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
    llvm/trunk/unittests/MI/LiveIntervalTest.cpp

Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=276724&r1=276723&r2=276724&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Mon Jul 25 22:57:45 2016
@@ -1039,6 +1039,8 @@ private:
           LiveRange::iterator Prev = std::prev(NewIdxIn);
           Prev->end = NewIdx.getRegSlot();
         }
+        // Extend OldIdxIn.
+        OldIdxIn->end = Next->start;
         return;
       }
 

Modified: llvm/trunk/unittests/MI/LiveIntervalTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/MI/LiveIntervalTest.cpp?rev=276724&r1=276723&r2=276724&view=diff
==============================================================================
--- llvm/trunk/unittests/MI/LiveIntervalTest.cpp (original)
+++ llvm/trunk/unittests/MI/LiveIntervalTest.cpp Mon Jul 25 22:57:45 2016
@@ -35,9 +35,10 @@ void initLLVM() {
 }
 
 /// Create a TargetMachine. As we lack a dedicated always available target for
-/// unittests, we go for "x86_64" which should be available in most builds.
+/// unittests, we go for "AMDGPU" to be able to test normal and subregister
+/// liveranges.
 std::unique_ptr<TargetMachine> createTargetMachine() {
-  Triple TargetTriple("x86_64--");
+  Triple TargetTriple("amdgcn--");
   std::string Error;
   const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
   if (!T)
@@ -45,7 +46,7 @@ std::unique_ptr<TargetMachine> createTar
 
   TargetOptions Options;
   return std::unique_ptr<TargetMachine>(
-      T->createTargetMachine("x86_64", "", "", Options, None,
+      T->createTargetMachine("AMDGPU", "", "", Options, None,
                              CodeModel::Default, CodeGenOpt::Aggressive));
 }
 
@@ -104,28 +105,31 @@ private:
   LiveIntervalTest T;
 };
 
-/**
- * Move instruction number \p From in front of instruction number \p To and
- * update affected liveness intervals with LiveIntervalAnalysis::handleMove().
- */
-static void testHandleMove(MachineFunction &MF, LiveIntervals &LIS,
-                           unsigned From, unsigned To, unsigned BlockNum = 0) {
+static MachineInstr &getMI(MachineFunction &MF, unsigned At,
+                           unsigned BlockNum) {
   MachineBasicBlock &MBB = *MF.getBlockNumbered(BlockNum);
 
   unsigned I = 0;
-  MachineInstr *FromInstr = nullptr;
-  MachineInstr *ToInstr = nullptr;
   for (MachineInstr &MI : MBB) {
-    if (I == From)
-      FromInstr = &MI;
-    if (I == To)
-      ToInstr = &MI;
+    if (I == At)
+      return MI;
     ++I;
   }
-  assert(FromInstr != nullptr && ToInstr != nullptr);
+  llvm_unreachable("Instruction not found");
+}
 
-  MBB.splice(ToInstr->getIterator(), &MBB, FromInstr->getIterator());
-  LIS.handleMove(*FromInstr, true);
+/**
+ * Move instruction number \p From in front of instruction number \p To and
+ * update affected liveness intervals with LiveIntervalAnalysis::handleMove().
+ */
+static void testHandleMove(MachineFunction &MF, LiveIntervals &LIS,
+                           unsigned From, unsigned To, unsigned BlockNum = 0) {
+  MachineInstr &FromInstr = getMI(MF, From, BlockNum);
+  MachineInstr &ToInstr = getMI(MF, To, BlockNum);
+
+  MachineBasicBlock &MBB = *FromInstr.getParent();
+  MBB.splice(ToInstr.getIterator(), &MBB, FromInstr.getIterator());
+  LIS.handleMove(FromInstr, true);
 }
 
 static void liveIntervalTest(StringRef MIRFunc, LiveIntervalTest T) {
@@ -143,7 +147,7 @@ static void liveIntervalTest(StringRef M
 "...\n"
 "name: func\n"
 "registers:\n"
-"  - { id: 0, class: gr64 }\n"
+"  - { id: 0, class: sreg_64 }\n"
 "body: |\n"
 "  bb.0:\n"
   ) + Twine(MIRFunc) + Twine("...\n")).toNullTerminatedStringRef(S);
@@ -164,10 +168,10 @@ INITIALIZE_PASS(TestPass, "testpass", "t
 TEST(LiveIntervalTest, MoveUpDef) {
   // Value defined.
   liveIntervalTest(
-"    NOOP\n"
-"    NOOP\n"
+"    S_NOP 0\n"
+"    S_NOP 0\n"
 "    early-clobber %0 = IMPLICIT_DEF\n"
-"    RETQ %0\n",
+"    S_NOP 0, implicit %0\n",
   [](MachineFunction &MF, LiveIntervals &LIS) {
     testHandleMove(MF, LIS, 2, 1);
   });
@@ -176,9 +180,9 @@ TEST(LiveIntervalTest, MoveUpDef) {
 TEST(LiveIntervalTest, MoveUpRedef) {
   liveIntervalTest(
 "    %0 = IMPLICIT_DEF\n"
-"    NOOP\n"
+"    S_NOP 0\n"
 "    %0 = IMPLICIT_DEF implicit %0(tied-def 0)\n"
-"    RETQ %0\n",
+"    S_NOP 0, implicit %0\n",
   [](MachineFunction &MF, LiveIntervals &LIS) {
     testHandleMove(MF, LIS, 2, 1);
   });
@@ -186,10 +190,10 @@ TEST(LiveIntervalTest, MoveUpRedef) {
 
 TEST(LiveIntervalTest, MoveUpEarlyDef) {
   liveIntervalTest(
-"    NOOP\n"
-"    NOOP\n"
+"    S_NOP 0\n"
+"    S_NOP 0\n"
 "    early-clobber %0 = IMPLICIT_DEF\n"
-"    RETQ %0\n",
+"    S_NOP 0, implicit %0\n",
   [](MachineFunction &MF, LiveIntervals &LIS) {
     testHandleMove(MF, LIS, 2, 1);
   });
@@ -198,9 +202,9 @@ TEST(LiveIntervalTest, MoveUpEarlyDef) {
 TEST(LiveIntervalTest, MoveUpEarlyRedef) {
   liveIntervalTest(
 "    %0 = IMPLICIT_DEF\n"
-"    NOOP\n"
+"    S_NOP 0\n"
 "    early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)\n"
-"    RETQ %0\n",
+"    S_NOP 0, implicit %0\n",
   [](MachineFunction &MF, LiveIntervals &LIS) {
     testHandleMove(MF, LIS, 2, 1);
   });
@@ -209,8 +213,8 @@ TEST(LiveIntervalTest, MoveUpEarlyRedef)
 TEST(LiveIntervalTest, MoveUpKill) {
   liveIntervalTest(
 "    %0 = IMPLICIT_DEF\n"
-"    NOOP\n"
-"    NOOP implicit %0\n",
+"    S_NOP 0\n"
+"    S_NOP 0, implicit %0\n",
   [](MachineFunction &MF, LiveIntervals &LIS) {
     testHandleMove(MF, LIS, 2, 1);
   });
@@ -219,9 +223,9 @@ TEST(LiveIntervalTest, MoveUpKill) {
 TEST(LiveIntervalTest, MoveUpKillFollowing) {
   liveIntervalTest(
 "    %0 = IMPLICIT_DEF\n"
-"    NOOP\n"
-"    NOOP implicit %0\n"
-"    RETQ %0\n",
+"    S_NOP 0\n"
+"    S_NOP 0, implicit %0\n"
+"    S_NOP 0, implicit %0\n",
   [](MachineFunction &MF, LiveIntervals &LIS) {
     testHandleMove(MF, LIS, 2, 1);
   });
@@ -233,10 +237,10 @@ TEST(LiveIntervalTest, MoveUpKillFollowi
 TEST(LiveIntervalTest, MoveDownDef) {
   // Value defined.
   liveIntervalTest(
-"    NOOP\n"
+"    S_NOP 0\n"
 "    early-clobber %0 = IMPLICIT_DEF\n"
-"    NOOP\n"
-"    RETQ %0\n",
+"    S_NOP 0\n"
+"    S_NOP 0, implicit %0\n",
   [](MachineFunction &MF, LiveIntervals &LIS) {
     testHandleMove(MF, LIS, 1, 2);
   });
@@ -246,8 +250,8 @@ TEST(LiveIntervalTest, MoveDownRedef) {
   liveIntervalTest(
 "    %0 = IMPLICIT_DEF\n"
 "    %0 = IMPLICIT_DEF implicit %0(tied-def 0)\n"
-"    NOOP\n"
-"    RETQ %0\n",
+"    S_NOP 0\n"
+"    S_NOP 0, implicit %0\n",
   [](MachineFunction &MF, LiveIntervals &LIS) {
     testHandleMove(MF, LIS, 1, 2);
   });
@@ -255,10 +259,10 @@ TEST(LiveIntervalTest, MoveDownRedef) {
 
 TEST(LiveIntervalTest, MoveDownEarlyDef) {
   liveIntervalTest(
-"    NOOP\n"
+"    S_NOP 0\n"
 "    early-clobber %0 = IMPLICIT_DEF\n"
-"    NOOP\n"
-"    RETQ %0\n",
+"    S_NOP 0\n"
+"    S_NOP 0, implicit %0\n",
   [](MachineFunction &MF, LiveIntervals &LIS) {
     testHandleMove(MF, LIS, 1, 2);
   });
@@ -268,8 +272,8 @@ TEST(LiveIntervalTest, MoveDownEarlyRede
   liveIntervalTest(
 "    %0 = IMPLICIT_DEF\n"
 "    early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)\n"
-"    NOOP\n"
-"    RETQ %0\n",
+"    S_NOP 0\n"
+"    S_NOP 0, implicit %0\n",
   [](MachineFunction &MF, LiveIntervals &LIS) {
     testHandleMove(MF, LIS, 1, 2);
   });
@@ -278,8 +282,8 @@ TEST(LiveIntervalTest, MoveDownEarlyRede
 TEST(LiveIntervalTest, MoveDownKill) {
   liveIntervalTest(
 "    %0 = IMPLICIT_DEF\n"
-"    NOOP implicit %0\n"
-"    NOOP\n",
+"    S_NOP 0, implicit %0\n"
+"    S_NOP 0\n",
   [](MachineFunction &MF, LiveIntervals &LIS) {
     testHandleMove(MF, LIS, 1, 2);
   });
@@ -288,9 +292,9 @@ TEST(LiveIntervalTest, MoveDownKill) {
 TEST(LiveIntervalTest, MoveDownKillFollowing) {
   liveIntervalTest(
 "    %0 = IMPLICIT_DEF\n"
-"    NOOP\n"
-"    NOOP implicit %0\n"
-"    RETQ %0\n",
+"    S_NOP 0\n"
+"    S_NOP 0, implicit %0\n"
+"    S_NOP 0, implicit %0\n",
   [](MachineFunction &MF, LiveIntervals &LIS) {
     testHandleMove(MF, LIS, 1, 2);
   });
@@ -299,9 +303,9 @@ TEST(LiveIntervalTest, MoveDownKillFollo
 TEST(LiveIntervalTest, MoveUndefUse) {
   liveIntervalTest(
 "    %0 = IMPLICIT_DEF\n"
-"    NOOP implicit undef %0\n"
-"    NOOP implicit %0\n"
-"    NOOP\n",
+"    S_NOP 0, implicit undef %0\n"
+"    S_NOP 0, implicit %0\n"
+"    S_NOP 0\n",
   [](MachineFunction &MF, LiveIntervals &LIS) {
     testHandleMove(MF, LIS, 1, 3);
   });
@@ -314,16 +318,16 @@ TEST(LiveIntervalTest, MoveUpValNos) {
   liveIntervalTest(
 "    successors: %bb.1, %bb.2\n"
 "    %0 = IMPLICIT_DEF\n"
-"    JG_1 %bb.2, implicit %eflags\n"
-"    JMP_1 %bb.1\n"
+"    S_CBRANCH_VCCNZ %bb.2, implicit undef %vcc\n"
+"    S_BRANCH %bb.1\n"
 "  bb.2:\n"
-"    NOOP implicit %0\n"
+"    S_NOP 0, implicit %0\n"
 "  bb.1:\n"
 "    successors: %bb.2\n"
 "    %0 = IMPLICIT_DEF implicit %0(tied-def 0)\n"
 "    %0 = IMPLICIT_DEF implicit %0(tied-def 0)\n"
 "    %0 = IMPLICIT_DEF implicit %0(tied-def 0)\n"
-"    JMP_1 %bb.2\n",
+"    S_BRANCH %bb.2\n",
   [](MachineFunction &MF, LiveIntervals &LIS) {
     testHandleMove(MF, LIS, 2, 0, 2);
   });
@@ -333,8 +337,8 @@ TEST(LiveIntervalTest, MoveOverUndefUse0
   // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
   liveIntervalTest(
 "    %0 = IMPLICIT_DEF\n"
-"    NOOP\n"
-"    NOOP implicit undef %0\n"
+"    S_NOP 0\n"
+"    S_NOP 0, implicit undef %0\n"
 "    %0 = IMPLICIT_DEF implicit %0(tied-def 0)\n",
   [](MachineFunction &MF, LiveIntervals &LIS) {
     testHandleMove(MF, LIS, 3, 1);
@@ -344,15 +348,40 @@ TEST(LiveIntervalTest, MoveOverUndefUse0
 TEST(LiveIntervalTest, MoveOverUndefUse1) {
   // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
   liveIntervalTest(
-"    %rax = IMPLICIT_DEF\n"
-"    NOOP\n"
-"    NOOP implicit undef %rax\n"
-"    %rax = IMPLICIT_DEF implicit %rax(tied-def 0)\n",
+"    %sgpr0 = IMPLICIT_DEF\n"
+"    S_NOP 0\n"
+"    S_NOP 0, implicit undef %sgpr0\n"
+"    %sgpr0 = IMPLICIT_DEF implicit %sgpr0(tied-def 0)\n",
   [](MachineFunction &MF, LiveIntervals &LIS) {
     testHandleMove(MF, LIS, 3, 1);
   });
 }
 
+TEST(LiveIntervalTest, SubRegMoveDown) {
+  // Subregister ranges can have holes inside a basic block. Check for a
+  // movement of the form 32->150 in a liverange [16, 32) [100,200).
+  liveIntervalTest(
+"    successors: %bb.1, %bb.2\n"
+"    %0 = IMPLICIT_DEF\n"
+"    S_CBRANCH_VCCNZ %bb.2, implicit undef %vcc\n"
+"    S_BRANCH %bb.1\n"
+"  bb.2:\n"
+"    successors: %bb.1\n"
+"    S_NOP 0, implicit %0:sub0\n"
+"    S_NOP 0, implicit %0:sub1\n"
+"    S_NOP 0\n"
+"    undef %0:sub0 = IMPLICIT_DEF\n"
+"    %0:sub1 = IMPLICIT_DEF\n"
+"  bb.1:\n"
+"    S_NOP 0, implicit %0\n",
+  [](MachineFunction &MF, LiveIntervals &LIS) {
+    // Scheduler behaviour: Clear def,read-undef flag and move.
+    MachineInstr &MI = getMI(MF, 3, /*BlockNum=*/1);
+    MI.getOperand(0).setIsUndef(false);
+    testHandleMove(MF, LIS, 1, 4, /*BlockNum=*/1);
+  });
+}
+
 int main(int argc, char **argv) {
   ::testing::InitGoogleTest(&argc, argv);
   initLLVM();




More information about the llvm-commits mailing list