blob: 43dfa4a79787fed0148a0d43f5cb78a927740650 [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;
48 return std::unique_ptr<TargetMachine>(
Matthias Braun3865b1d2016-07-26 03:57:45 +000049 T->createTargetMachine("AMDGPU", "", "", Options, None,
Matthias Braun3199c4e2016-05-02 23:05:48 +000050 CodeModel::Default, CodeGenOpt::Aggressive));
51}
52
53std::unique_ptr<Module> parseMIR(LLVMContext &Context,
54 legacy::PassManagerBase &PM, std::unique_ptr<MIRParser> &MIR,
55 const TargetMachine &TM, StringRef MIRCode, const char *FuncName) {
56 SMDiagnostic Diagnostic;
57 std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);
58 MIR = createMIRParser(std::move(MBuffer), Context);
59 if (!MIR)
60 return nullptr;
61
Matthias Braun7bda1952017-06-06 00:44:35 +000062 std::unique_ptr<Module> M = MIR->parseIRModule();
Matthias Braun3199c4e2016-05-02 23:05:48 +000063 if (!M)
64 return nullptr;
65
66 M->setDataLayout(TM.createDataLayout());
67
Matthias Braun733fe362016-08-24 01:52:46 +000068 MachineModuleInfo *MMI = new MachineModuleInfo(&TM);
Matthias Braun7bda1952017-06-06 00:44:35 +000069 if (MIR->parseMachineFunctions(*M, *MMI))
70 return nullptr;
Matthias Braun733fe362016-08-24 01:52:46 +000071 PM.add(MMI);
Matthias Braun3199c4e2016-05-02 23:05:48 +000072
73 return M;
74}
75
76typedef std::function<void(MachineFunction&,LiveIntervals&)> LiveIntervalTest;
77
78struct TestPass : public MachineFunctionPass {
79 static char ID;
80 TestPass() : MachineFunctionPass(ID) {
81 // We should never call this but always use PM.add(new TestPass(...))
82 abort();
83 }
84 TestPass(LiveIntervalTest T) : MachineFunctionPass(ID), T(T) {
85 initializeTestPassPass(*PassRegistry::getPassRegistry());
86 }
87
88 bool runOnMachineFunction(MachineFunction &MF) override {
89 LiveIntervals &LIS = getAnalysis<LiveIntervals>();
90 T(MF, LIS);
91 EXPECT_TRUE(MF.verify(this));
92 return true;
93 }
94
95 void getAnalysisUsage(AnalysisUsage &AU) const override {
96 AU.setPreservesAll();
97 AU.addRequired<LiveIntervals>();
98 AU.addPreserved<LiveIntervals>();
99 MachineFunctionPass::getAnalysisUsage(AU);
100 }
101private:
102 LiveIntervalTest T;
103};
104
Matthias Braun3865b1d2016-07-26 03:57:45 +0000105static MachineInstr &getMI(MachineFunction &MF, unsigned At,
106 unsigned BlockNum) {
107 MachineBasicBlock &MBB = *MF.getBlockNumbered(BlockNum);
108
109 unsigned I = 0;
110 for (MachineInstr &MI : MBB) {
111 if (I == At)
112 return MI;
113 ++I;
114 }
115 llvm_unreachable("Instruction not found");
116}
117
Matthias Braun3199c4e2016-05-02 23:05:48 +0000118/**
119 * Move instruction number \p From in front of instruction number \p To and
120 * update affected liveness intervals with LiveIntervalAnalysis::handleMove().
121 */
122static void testHandleMove(MachineFunction &MF, LiveIntervals &LIS,
Matthias Braunfc4c8a12016-05-24 21:54:01 +0000123 unsigned From, unsigned To, unsigned BlockNum = 0) {
Matthias Braun3865b1d2016-07-26 03:57:45 +0000124 MachineInstr &FromInstr = getMI(MF, From, BlockNum);
125 MachineInstr &ToInstr = getMI(MF, To, BlockNum);
Matthias Braun3199c4e2016-05-02 23:05:48 +0000126
Matthias Braun3865b1d2016-07-26 03:57:45 +0000127 MachineBasicBlock &MBB = *FromInstr.getParent();
128 MBB.splice(ToInstr.getIterator(), &MBB, FromInstr.getIterator());
129 LIS.handleMove(FromInstr, true);
Matthias Braun3199c4e2016-05-02 23:05:48 +0000130}
131
132static void liveIntervalTest(StringRef MIRFunc, LiveIntervalTest T) {
133 LLVMContext Context;
134 std::unique_ptr<TargetMachine> TM = createTargetMachine();
135 // This test is designed for the X86 backend; stop if it is not available.
136 if (!TM)
137 return;
138
139 legacy::PassManager PM;
140
141 SmallString<160> S;
Matthias Braun1cba1402017-02-23 01:09:01 +0000142 StringRef MIRString = (Twine(R"MIR(
143---
144...
145name: func
146registers:
147 - { id: 0, class: sreg_64 }
148body: |
149 bb.0:
150)MIR") + Twine(MIRFunc) + Twine("...\n")).toNullTerminatedStringRef(S);
Matthias Braun3199c4e2016-05-02 23:05:48 +0000151 std::unique_ptr<MIRParser> MIR;
152 std::unique_ptr<Module> M = parseMIR(Context, PM, MIR, *TM, MIRString,
153 "func");
Matthias Braun542b3ce2017-06-15 22:31:08 +0000154 EXPECT_TRUE(M);
Matthias Braun3199c4e2016-05-02 23:05:48 +0000155
156 PM.add(new TestPass(T));
157
158 PM.run(*M);
159}
160
161} // End of anonymous namespace.
162
163char TestPass::ID = 0;
164INITIALIZE_PASS(TestPass, "testpass", "testpass", false, false)
165
166TEST(LiveIntervalTest, MoveUpDef) {
167 // Value defined.
Matthias Braun1cba1402017-02-23 01:09:01 +0000168 liveIntervalTest(R"MIR(
169 S_NOP 0
170 S_NOP 0
171 early-clobber %0 = IMPLICIT_DEF
172 S_NOP 0, implicit %0
173)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000174 testHandleMove(MF, LIS, 2, 1);
175 });
176}
177
178TEST(LiveIntervalTest, MoveUpRedef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000179 liveIntervalTest(R"MIR(
180 %0 = IMPLICIT_DEF
181 S_NOP 0
182 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
183 S_NOP 0, implicit %0
184)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000185 testHandleMove(MF, LIS, 2, 1);
186 });
187}
188
189TEST(LiveIntervalTest, MoveUpEarlyDef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000190 liveIntervalTest(R"MIR(
191 S_NOP 0
192 S_NOP 0
193 early-clobber %0 = IMPLICIT_DEF
194 S_NOP 0, implicit %0
195)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000196 testHandleMove(MF, LIS, 2, 1);
197 });
198}
199
200TEST(LiveIntervalTest, MoveUpEarlyRedef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000201 liveIntervalTest(R"MIR(
202 %0 = IMPLICIT_DEF
203 S_NOP 0
204 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
205 S_NOP 0, implicit %0
206)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000207 testHandleMove(MF, LIS, 2, 1);
208 });
209}
210
211TEST(LiveIntervalTest, MoveUpKill) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000212 liveIntervalTest(R"MIR(
213 %0 = IMPLICIT_DEF
214 S_NOP 0
215 S_NOP 0, implicit %0
216)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000217 testHandleMove(MF, LIS, 2, 1);
218 });
219}
220
221TEST(LiveIntervalTest, MoveUpKillFollowing) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000222 liveIntervalTest(R"MIR(
223 %0 = IMPLICIT_DEF
224 S_NOP 0
225 S_NOP 0, implicit %0
226 S_NOP 0, implicit %0
227)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000228 testHandleMove(MF, LIS, 2, 1);
229 });
230}
231
232// TODO: Construct a situation where we have intervals following a hole
233// while still having connected components.
234
235TEST(LiveIntervalTest, MoveDownDef) {
236 // Value defined.
Matthias Braun1cba1402017-02-23 01:09:01 +0000237 liveIntervalTest(R"MIR(
238 S_NOP 0
239 early-clobber %0 = IMPLICIT_DEF
240 S_NOP 0
241 S_NOP 0, implicit %0
242)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000243 testHandleMove(MF, LIS, 1, 2);
244 });
245}
246
247TEST(LiveIntervalTest, MoveDownRedef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000248 liveIntervalTest(R"MIR(
249 %0 = IMPLICIT_DEF
250 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
251 S_NOP 0
252 S_NOP 0, implicit %0
253)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000254 testHandleMove(MF, LIS, 1, 2);
255 });
256}
257
258TEST(LiveIntervalTest, MoveDownEarlyDef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000259 liveIntervalTest(R"MIR(
260 S_NOP 0
261 early-clobber %0 = IMPLICIT_DEF
262 S_NOP 0
263 S_NOP 0, implicit %0
264)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000265 testHandleMove(MF, LIS, 1, 2);
266 });
267}
268
269TEST(LiveIntervalTest, MoveDownEarlyRedef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000270 liveIntervalTest(R"MIR(
271 %0 = IMPLICIT_DEF
272 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
273 S_NOP 0
274 S_NOP 0, implicit %0
275)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000276 testHandleMove(MF, LIS, 1, 2);
277 });
278}
279
280TEST(LiveIntervalTest, MoveDownKill) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000281 liveIntervalTest(R"MIR(
282 %0 = IMPLICIT_DEF
283 S_NOP 0, implicit %0
284 S_NOP 0
285)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000286 testHandleMove(MF, LIS, 1, 2);
287 });
288}
289
290TEST(LiveIntervalTest, MoveDownKillFollowing) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000291 liveIntervalTest(R"MIR(
292 %0 = IMPLICIT_DEF
293 S_NOP 0
294 S_NOP 0, implicit %0
295 S_NOP 0, implicit %0
296)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000297 testHandleMove(MF, LIS, 1, 2);
298 });
299}
300
Matthias Braun71474e82016-05-06 21:47:41 +0000301TEST(LiveIntervalTest, MoveUndefUse) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000302 liveIntervalTest(R"MIR(
303 %0 = IMPLICIT_DEF
304 S_NOP 0, implicit undef %0
305 S_NOP 0, implicit %0
306 S_NOP 0
307)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun71474e82016-05-06 21:47:41 +0000308 testHandleMove(MF, LIS, 1, 3);
309 });
310}
311
Matthias Braunfc4c8a12016-05-24 21:54:01 +0000312TEST(LiveIntervalTest, MoveUpValNos) {
313 // handleMoveUp() had a bug where it would reuse the value number of the
314 // destination segment, even though we have no guarntee that this valno wasn't
315 // used in other segments.
Matthias Braun1cba1402017-02-23 01:09:01 +0000316 liveIntervalTest(R"MIR(
317 successors: %bb.1, %bb.2
318 %0 = IMPLICIT_DEF
319 S_CBRANCH_VCCNZ %bb.2, implicit undef %vcc
320 S_BRANCH %bb.1
321 bb.2:
322 S_NOP 0, implicit %0
323 bb.1:
324 successors: %bb.2
325 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
326 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
327 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
328 S_BRANCH %bb.2
329)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braunfc4c8a12016-05-24 21:54:01 +0000330 testHandleMove(MF, LIS, 2, 0, 2);
331 });
332}
333
Matthias Braun959a8c92016-06-11 00:31:28 +0000334TEST(LiveIntervalTest, MoveOverUndefUse0) {
335 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
Matthias Braun1cba1402017-02-23 01:09:01 +0000336 liveIntervalTest(R"MIR(
337 %0 = IMPLICIT_DEF
338 S_NOP 0
339 S_NOP 0, implicit undef %0
340 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
341)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun959a8c92016-06-11 00:31:28 +0000342 testHandleMove(MF, LIS, 3, 1);
343 });
344}
345
346TEST(LiveIntervalTest, MoveOverUndefUse1) {
347 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
Matthias Braun1cba1402017-02-23 01:09:01 +0000348 liveIntervalTest(R"MIR(
349 %sgpr0 = IMPLICIT_DEF
350 S_NOP 0
351 S_NOP 0, implicit undef %sgpr0
352 %sgpr0 = IMPLICIT_DEF implicit %sgpr0(tied-def 0)
353)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun959a8c92016-06-11 00:31:28 +0000354 testHandleMove(MF, LIS, 3, 1);
355 });
356}
357
Matthias Braun3865b1d2016-07-26 03:57:45 +0000358TEST(LiveIntervalTest, SubRegMoveDown) {
359 // Subregister ranges can have holes inside a basic block. Check for a
360 // movement of the form 32->150 in a liverange [16, 32) [100,200).
Matthias Braun1cba1402017-02-23 01:09:01 +0000361 liveIntervalTest(R"MIR(
362 successors: %bb.1, %bb.2
363 %0 = IMPLICIT_DEF
364 S_CBRANCH_VCCNZ %bb.2, implicit undef %vcc
365 S_BRANCH %bb.1
366 bb.2:
367 successors: %bb.1
368 S_NOP 0, implicit %0.sub0
369 S_NOP 0, implicit %0.sub1
370 S_NOP 0
371 undef %0.sub0 = IMPLICIT_DEF
372 %0.sub1 = IMPLICIT_DEF
373 bb.1:
374 S_NOP 0, implicit %0
375)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3865b1d2016-07-26 03:57:45 +0000376 // Scheduler behaviour: Clear def,read-undef flag and move.
377 MachineInstr &MI = getMI(MF, 3, /*BlockNum=*/1);
378 MI.getOperand(0).setIsUndef(false);
379 testHandleMove(MF, LIS, 1, 4, /*BlockNum=*/1);
380 });
381}
382
Stanislav Mekhanoshinb546174b2017-03-11 00:14:52 +0000383TEST(LiveIntervalTest, SubRegMoveUp) {
384 // handleMoveUp had a bug not updating valno of segment incoming to bb.2
385 // after swapping subreg definitions.
386 liveIntervalTest(R"MIR(
387 successors: %bb.1, %bb.2
388 undef %0.sub0 = IMPLICIT_DEF
389 %0.sub1 = IMPLICIT_DEF
390 S_CBRANCH_VCCNZ %bb.2, implicit undef %vcc
391 S_BRANCH %bb.1
392 bb.1:
393 S_NOP 0, implicit %0.sub1
394 bb.2:
395 S_NOP 0, implicit %0.sub1
396)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
397 testHandleMove(MF, LIS, 1, 0);
398 });
399}
400
Matthias Braun3199c4e2016-05-02 23:05:48 +0000401int main(int argc, char **argv) {
402 ::testing::InitGoogleTest(&argc, argv);
403 initLLVM();
404 return RUN_ALL_TESTS();
NAKAMURA Takumic1857d12016-02-18 07:37:17 +0000405}