blob: 9d1d864eccdd91043a94e984f73f6fc902c36b3f [file] [log] [blame]
Matthias Braun3199c4e2016-05-02 23:05:48 +00001#include "llvm/ADT/STLExtras.h"
2#include "llvm/CodeGen/LiveIntervalAnalysis.h"
3#include "llvm/CodeGen/MIRParser/MIRParser.h"
4#include "llvm/CodeGen/MachineFunction.h"
Matthias Braun7938eee2016-05-10 03:03:55 +00005#include "llvm/CodeGen/MachineModuleInfo.h"
Matthias Braun3199c4e2016-05-02 23:05:48 +00006#include "llvm/CodeGen/MachineRegisterInfo.h"
7#include "llvm/CodeGen/Passes.h"
Chandler Carruth9a67b072017-06-06 11:06:56 +00008#include "llvm/IR/LegacyPassManager.h"
Matthias Braun3199c4e2016-05-02 23:05:48 +00009#include "llvm/Support/MemoryBuffer.h"
10#include "llvm/Support/SourceMgr.h"
11#include "llvm/Support/TargetRegistry.h"
12#include "llvm/Support/TargetSelect.h"
13#include "llvm/Target/TargetMachine.h"
14#include "llvm/Target/TargetOptions.h"
15#include "llvm/Target/TargetRegisterInfo.h"
Chandler Carruth9a67b072017-06-06 11:06:56 +000016#include "gtest/gtest.h"
NAKAMURA Takumic1857d12016-02-18 07:37:17 +000017
Matthias Braun3199c4e2016-05-02 23:05:48 +000018using namespace llvm;
19
20namespace llvm {
21 void initializeTestPassPass(PassRegistry &);
22}
23
24namespace {
25
26void initLLVM() {
27 InitializeAllTargets();
28 InitializeAllTargetMCs();
29 InitializeAllAsmPrinters();
30 InitializeAllAsmParsers();
31
32 PassRegistry *Registry = PassRegistry::getPassRegistry();
33 initializeCore(*Registry);
34 initializeCodeGen(*Registry);
35}
36
37/// Create a TargetMachine. As we lack a dedicated always available target for
Matthias Braun3865b1d2016-07-26 03:57:45 +000038/// unittests, we go for "AMDGPU" to be able to test normal and subregister
39/// liveranges.
Matthias Braun3199c4e2016-05-02 23:05:48 +000040std::unique_ptr<TargetMachine> createTargetMachine() {
Matthias Braun3865b1d2016-07-26 03:57:45 +000041 Triple TargetTriple("amdgcn--");
Matthias Braun3199c4e2016-05-02 23:05:48 +000042 std::string Error;
43 const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
44 if (!T)
45 return nullptr;
46
47 TargetOptions Options;
Rafael Espindola79e238a2017-08-03 02:16:21 +000048 return std::unique_ptr<TargetMachine>(T->createTargetMachine(
49 "AMDGPU", "", "", Options, None, None, CodeGenOpt::Aggressive));
Matthias Braun3199c4e2016-05-02 23:05:48 +000050}
51
52std::unique_ptr<Module> parseMIR(LLVMContext &Context,
53 legacy::PassManagerBase &PM, std::unique_ptr<MIRParser> &MIR,
54 const TargetMachine &TM, StringRef MIRCode, const char *FuncName) {
55 SMDiagnostic Diagnostic;
56 std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);
57 MIR = createMIRParser(std::move(MBuffer), Context);
58 if (!MIR)
59 return nullptr;
60
Matthias Braun7bda1952017-06-06 00:44:35 +000061 std::unique_ptr<Module> M = MIR->parseIRModule();
Matthias Braun3199c4e2016-05-02 23:05:48 +000062 if (!M)
63 return nullptr;
64
65 M->setDataLayout(TM.createDataLayout());
66
Matthias Braun733fe362016-08-24 01:52:46 +000067 MachineModuleInfo *MMI = new MachineModuleInfo(&TM);
Matthias Braun7bda1952017-06-06 00:44:35 +000068 if (MIR->parseMachineFunctions(*M, *MMI))
69 return nullptr;
Matthias Braun733fe362016-08-24 01:52:46 +000070 PM.add(MMI);
Matthias Braun3199c4e2016-05-02 23:05:48 +000071
72 return M;
73}
74
75typedef std::function<void(MachineFunction&,LiveIntervals&)> LiveIntervalTest;
76
77struct TestPass : public MachineFunctionPass {
78 static char ID;
79 TestPass() : MachineFunctionPass(ID) {
80 // We should never call this but always use PM.add(new TestPass(...))
81 abort();
82 }
83 TestPass(LiveIntervalTest T) : MachineFunctionPass(ID), T(T) {
84 initializeTestPassPass(*PassRegistry::getPassRegistry());
85 }
86
87 bool runOnMachineFunction(MachineFunction &MF) override {
88 LiveIntervals &LIS = getAnalysis<LiveIntervals>();
89 T(MF, LIS);
90 EXPECT_TRUE(MF.verify(this));
91 return true;
92 }
93
94 void getAnalysisUsage(AnalysisUsage &AU) const override {
95 AU.setPreservesAll();
96 AU.addRequired<LiveIntervals>();
97 AU.addPreserved<LiveIntervals>();
98 MachineFunctionPass::getAnalysisUsage(AU);
99 }
100private:
101 LiveIntervalTest T;
102};
103
Matthias Braun3865b1d2016-07-26 03:57:45 +0000104static MachineInstr &getMI(MachineFunction &MF, unsigned At,
105 unsigned BlockNum) {
106 MachineBasicBlock &MBB = *MF.getBlockNumbered(BlockNum);
107
108 unsigned I = 0;
109 for (MachineInstr &MI : MBB) {
110 if (I == At)
111 return MI;
112 ++I;
113 }
114 llvm_unreachable("Instruction not found");
115}
116
Matthias Braun3199c4e2016-05-02 23:05:48 +0000117/**
118 * Move instruction number \p From in front of instruction number \p To and
119 * update affected liveness intervals with LiveIntervalAnalysis::handleMove().
120 */
121static void testHandleMove(MachineFunction &MF, LiveIntervals &LIS,
Matthias Braunfc4c8a12016-05-24 21:54:01 +0000122 unsigned From, unsigned To, unsigned BlockNum = 0) {
Matthias Braun3865b1d2016-07-26 03:57:45 +0000123 MachineInstr &FromInstr = getMI(MF, From, BlockNum);
124 MachineInstr &ToInstr = getMI(MF, To, BlockNum);
Matthias Braun3199c4e2016-05-02 23:05:48 +0000125
Matthias Braun3865b1d2016-07-26 03:57:45 +0000126 MachineBasicBlock &MBB = *FromInstr.getParent();
127 MBB.splice(ToInstr.getIterator(), &MBB, FromInstr.getIterator());
128 LIS.handleMove(FromInstr, true);
Matthias Braun3199c4e2016-05-02 23:05:48 +0000129}
130
131static void liveIntervalTest(StringRef MIRFunc, LiveIntervalTest T) {
132 LLVMContext Context;
133 std::unique_ptr<TargetMachine> TM = createTargetMachine();
134 // This test is designed for the X86 backend; stop if it is not available.
135 if (!TM)
136 return;
137
138 legacy::PassManager PM;
139
140 SmallString<160> S;
Matthias Braun1cba1402017-02-23 01:09:01 +0000141 StringRef MIRString = (Twine(R"MIR(
142---
143...
144name: func
145registers:
146 - { id: 0, class: sreg_64 }
147body: |
148 bb.0:
149)MIR") + Twine(MIRFunc) + Twine("...\n")).toNullTerminatedStringRef(S);
Matthias Braun3199c4e2016-05-02 23:05:48 +0000150 std::unique_ptr<MIRParser> MIR;
151 std::unique_ptr<Module> M = parseMIR(Context, PM, MIR, *TM, MIRString,
152 "func");
Matthias Braun531f3a92017-06-15 22:50:57 +0000153 ASSERT_TRUE(M);
Matthias Braun3199c4e2016-05-02 23:05:48 +0000154
155 PM.add(new TestPass(T));
156
157 PM.run(*M);
158}
159
160} // End of anonymous namespace.
161
162char TestPass::ID = 0;
163INITIALIZE_PASS(TestPass, "testpass", "testpass", false, false)
164
165TEST(LiveIntervalTest, MoveUpDef) {
166 // Value defined.
Matthias Braun1cba1402017-02-23 01:09:01 +0000167 liveIntervalTest(R"MIR(
168 S_NOP 0
169 S_NOP 0
170 early-clobber %0 = IMPLICIT_DEF
171 S_NOP 0, implicit %0
172)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000173 testHandleMove(MF, LIS, 2, 1);
174 });
175}
176
177TEST(LiveIntervalTest, MoveUpRedef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000178 liveIntervalTest(R"MIR(
179 %0 = IMPLICIT_DEF
180 S_NOP 0
181 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
182 S_NOP 0, implicit %0
183)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000184 testHandleMove(MF, LIS, 2, 1);
185 });
186}
187
188TEST(LiveIntervalTest, MoveUpEarlyDef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000189 liveIntervalTest(R"MIR(
190 S_NOP 0
191 S_NOP 0
192 early-clobber %0 = IMPLICIT_DEF
193 S_NOP 0, implicit %0
194)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000195 testHandleMove(MF, LIS, 2, 1);
196 });
197}
198
199TEST(LiveIntervalTest, MoveUpEarlyRedef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000200 liveIntervalTest(R"MIR(
201 %0 = IMPLICIT_DEF
202 S_NOP 0
203 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
204 S_NOP 0, implicit %0
205)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000206 testHandleMove(MF, LIS, 2, 1);
207 });
208}
209
210TEST(LiveIntervalTest, MoveUpKill) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000211 liveIntervalTest(R"MIR(
212 %0 = IMPLICIT_DEF
213 S_NOP 0
214 S_NOP 0, implicit %0
215)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000216 testHandleMove(MF, LIS, 2, 1);
217 });
218}
219
220TEST(LiveIntervalTest, MoveUpKillFollowing) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000221 liveIntervalTest(R"MIR(
222 %0 = IMPLICIT_DEF
223 S_NOP 0
224 S_NOP 0, implicit %0
225 S_NOP 0, implicit %0
226)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000227 testHandleMove(MF, LIS, 2, 1);
228 });
229}
230
231// TODO: Construct a situation where we have intervals following a hole
232// while still having connected components.
233
234TEST(LiveIntervalTest, MoveDownDef) {
235 // Value defined.
Matthias Braun1cba1402017-02-23 01:09:01 +0000236 liveIntervalTest(R"MIR(
237 S_NOP 0
238 early-clobber %0 = IMPLICIT_DEF
239 S_NOP 0
240 S_NOP 0, implicit %0
241)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000242 testHandleMove(MF, LIS, 1, 2);
243 });
244}
245
246TEST(LiveIntervalTest, MoveDownRedef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000247 liveIntervalTest(R"MIR(
248 %0 = IMPLICIT_DEF
249 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
250 S_NOP 0
251 S_NOP 0, implicit %0
252)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000253 testHandleMove(MF, LIS, 1, 2);
254 });
255}
256
257TEST(LiveIntervalTest, MoveDownEarlyDef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000258 liveIntervalTest(R"MIR(
259 S_NOP 0
260 early-clobber %0 = IMPLICIT_DEF
261 S_NOP 0
262 S_NOP 0, implicit %0
263)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000264 testHandleMove(MF, LIS, 1, 2);
265 });
266}
267
268TEST(LiveIntervalTest, MoveDownEarlyRedef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000269 liveIntervalTest(R"MIR(
270 %0 = IMPLICIT_DEF
271 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
272 S_NOP 0
273 S_NOP 0, implicit %0
274)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000275 testHandleMove(MF, LIS, 1, 2);
276 });
277}
278
279TEST(LiveIntervalTest, MoveDownKill) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000280 liveIntervalTest(R"MIR(
281 %0 = IMPLICIT_DEF
282 S_NOP 0, implicit %0
283 S_NOP 0
284)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000285 testHandleMove(MF, LIS, 1, 2);
286 });
287}
288
289TEST(LiveIntervalTest, MoveDownKillFollowing) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000290 liveIntervalTest(R"MIR(
291 %0 = IMPLICIT_DEF
292 S_NOP 0
293 S_NOP 0, implicit %0
294 S_NOP 0, implicit %0
295)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000296 testHandleMove(MF, LIS, 1, 2);
297 });
298}
299
Matthias Braun71474e82016-05-06 21:47:41 +0000300TEST(LiveIntervalTest, MoveUndefUse) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000301 liveIntervalTest(R"MIR(
302 %0 = IMPLICIT_DEF
303 S_NOP 0, implicit undef %0
304 S_NOP 0, implicit %0
305 S_NOP 0
306)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun71474e82016-05-06 21:47:41 +0000307 testHandleMove(MF, LIS, 1, 3);
308 });
309}
310
Matthias Braunfc4c8a12016-05-24 21:54:01 +0000311TEST(LiveIntervalTest, MoveUpValNos) {
312 // handleMoveUp() had a bug where it would reuse the value number of the
313 // destination segment, even though we have no guarntee that this valno wasn't
314 // used in other segments.
Matthias Braun1cba1402017-02-23 01:09:01 +0000315 liveIntervalTest(R"MIR(
316 successors: %bb.1, %bb.2
317 %0 = IMPLICIT_DEF
318 S_CBRANCH_VCCNZ %bb.2, implicit undef %vcc
319 S_BRANCH %bb.1
320 bb.2:
321 S_NOP 0, implicit %0
322 bb.1:
323 successors: %bb.2
324 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
325 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
326 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
327 S_BRANCH %bb.2
328)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braunfc4c8a12016-05-24 21:54:01 +0000329 testHandleMove(MF, LIS, 2, 0, 2);
330 });
331}
332
Matthias Braun959a8c92016-06-11 00:31:28 +0000333TEST(LiveIntervalTest, MoveOverUndefUse0) {
334 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
Matthias Braun1cba1402017-02-23 01:09:01 +0000335 liveIntervalTest(R"MIR(
336 %0 = IMPLICIT_DEF
337 S_NOP 0
338 S_NOP 0, implicit undef %0
339 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
340)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun959a8c92016-06-11 00:31:28 +0000341 testHandleMove(MF, LIS, 3, 1);
342 });
343}
344
345TEST(LiveIntervalTest, MoveOverUndefUse1) {
346 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
Matthias Braun1cba1402017-02-23 01:09:01 +0000347 liveIntervalTest(R"MIR(
348 %sgpr0 = IMPLICIT_DEF
349 S_NOP 0
350 S_NOP 0, implicit undef %sgpr0
351 %sgpr0 = IMPLICIT_DEF implicit %sgpr0(tied-def 0)
352)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun959a8c92016-06-11 00:31:28 +0000353 testHandleMove(MF, LIS, 3, 1);
354 });
355}
356
Matthias Braun3865b1d2016-07-26 03:57:45 +0000357TEST(LiveIntervalTest, SubRegMoveDown) {
358 // Subregister ranges can have holes inside a basic block. Check for a
359 // movement of the form 32->150 in a liverange [16, 32) [100,200).
Matthias Braun1cba1402017-02-23 01:09:01 +0000360 liveIntervalTest(R"MIR(
361 successors: %bb.1, %bb.2
362 %0 = IMPLICIT_DEF
363 S_CBRANCH_VCCNZ %bb.2, implicit undef %vcc
364 S_BRANCH %bb.1
365 bb.2:
366 successors: %bb.1
367 S_NOP 0, implicit %0.sub0
368 S_NOP 0, implicit %0.sub1
369 S_NOP 0
370 undef %0.sub0 = IMPLICIT_DEF
371 %0.sub1 = IMPLICIT_DEF
372 bb.1:
373 S_NOP 0, implicit %0
374)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3865b1d2016-07-26 03:57:45 +0000375 // Scheduler behaviour: Clear def,read-undef flag and move.
376 MachineInstr &MI = getMI(MF, 3, /*BlockNum=*/1);
377 MI.getOperand(0).setIsUndef(false);
378 testHandleMove(MF, LIS, 1, 4, /*BlockNum=*/1);
379 });
380}
381
Stanislav Mekhanoshinb546174b2017-03-11 00:14:52 +0000382TEST(LiveIntervalTest, SubRegMoveUp) {
383 // handleMoveUp had a bug not updating valno of segment incoming to bb.2
384 // after swapping subreg definitions.
385 liveIntervalTest(R"MIR(
386 successors: %bb.1, %bb.2
387 undef %0.sub0 = IMPLICIT_DEF
388 %0.sub1 = IMPLICIT_DEF
389 S_CBRANCH_VCCNZ %bb.2, implicit undef %vcc
390 S_BRANCH %bb.1
391 bb.1:
392 S_NOP 0, implicit %0.sub1
393 bb.2:
394 S_NOP 0, implicit %0.sub1
395)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
396 testHandleMove(MF, LIS, 1, 0);
397 });
398}
399
Matthias Braun3199c4e2016-05-02 23:05:48 +0000400int main(int argc, char **argv) {
401 ::testing::InitGoogleTest(&argc, argv);
402 initLLVM();
403 return RUN_ALL_TESTS();
NAKAMURA Takumic1857d12016-02-18 07:37:17 +0000404}