[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