xref: /llvm-project/llvm/unittests/CodeGen/MachineDomTreeUpdaterTest.cpp (revision bb3f5e1fed7c6ba733b7f273e93f5d3930976185)
1c931ac59Spaperchalice //===- MachineDomTreeUpdaterTest.cpp - MachineDomTreeUpdater unit tests ---===//
2c931ac59Spaperchalice //
3c931ac59Spaperchalice // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c931ac59Spaperchalice // See https://llvm.org/LICENSE.txt for license information.
5c931ac59Spaperchalice // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c931ac59Spaperchalice //
7c931ac59Spaperchalice //===----------------------------------------------------------------------===//
8c931ac59Spaperchalice 
9c931ac59Spaperchalice #include "llvm/CodeGen/MachineDomTreeUpdater.h"
10c931ac59Spaperchalice #include "llvm/Analysis/CGSCCPassManager.h"
11c931ac59Spaperchalice #include "llvm/Analysis/LoopAnalysisManager.h"
12c931ac59Spaperchalice #include "llvm/CodeGen/MIRParser/MIRParser.h"
13c931ac59Spaperchalice #include "llvm/CodeGen/MachineFunctionAnalysis.h"
14c931ac59Spaperchalice #include "llvm/CodeGen/MachineModuleInfo.h"
15c931ac59Spaperchalice #include "llvm/CodeGen/MachinePassManager.h"
16c931ac59Spaperchalice #include "llvm/CodeGen/MachinePostDominators.h"
17c931ac59Spaperchalice #include "llvm/CodeGen/SelectionDAG.h"
18c931ac59Spaperchalice #include "llvm/CodeGen/TargetLowering.h"
1974deadf1SNikita Popov #include "llvm/IR/Module.h"
20c931ac59Spaperchalice #include "llvm/MC/TargetRegistry.h"
21c931ac59Spaperchalice #include "llvm/Passes/PassBuilder.h"
22c931ac59Spaperchalice #include "llvm/Support/SourceMgr.h"
23c931ac59Spaperchalice #include "llvm/Support/TargetSelect.h"
24c931ac59Spaperchalice #include "llvm/Target/TargetMachine.h"
25c931ac59Spaperchalice #include "gtest/gtest.h"
26c931ac59Spaperchalice 
27c931ac59Spaperchalice using namespace llvm;
28c931ac59Spaperchalice 
29c931ac59Spaperchalice class MachineDomTreeUpdaterTest : public testing::Test {
30c931ac59Spaperchalice public:
31c931ac59Spaperchalice   LLVMContext Context;
32c931ac59Spaperchalice   std::unique_ptr<TargetMachine> TM;
33c931ac59Spaperchalice   std::unique_ptr<Module> M;
34c931ac59Spaperchalice   std::unique_ptr<MachineModuleInfo> MMI;
35c931ac59Spaperchalice   std::unique_ptr<MIRParser> MIR;
36c931ac59Spaperchalice 
37c931ac59Spaperchalice   LoopAnalysisManager LAM;
38c931ac59Spaperchalice   MachineFunctionAnalysisManager MFAM;
39c931ac59Spaperchalice   FunctionAnalysisManager FAM;
40c931ac59Spaperchalice   CGSCCAnalysisManager CGAM;
41c931ac59Spaperchalice   ModuleAnalysisManager MAM;
42c931ac59Spaperchalice 
43c931ac59Spaperchalice   ModulePassManager MPM;
44c931ac59Spaperchalice   FunctionPassManager FPM;
45c931ac59Spaperchalice   MachineFunctionPassManager MFPM;
46c931ac59Spaperchalice 
47c931ac59Spaperchalice   static void SetUpTestCase() {
48c931ac59Spaperchalice     InitializeAllTargets();
49c931ac59Spaperchalice     InitializeAllTargetMCs();
50c931ac59Spaperchalice   }
51c931ac59Spaperchalice 
52c931ac59Spaperchalice   void SetUp() override {
53c931ac59Spaperchalice     Triple TargetTriple("x86_64-unknown-linux-gnu");
54c931ac59Spaperchalice     std::string Error;
55c931ac59Spaperchalice     const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
56c931ac59Spaperchalice     if (!T)
57c931ac59Spaperchalice       GTEST_SKIP();
58c931ac59Spaperchalice     TargetOptions Options;
59c931ac59Spaperchalice     TM = std::unique_ptr<TargetMachine>(
60c931ac59Spaperchalice         T->createTargetMachine("X86", "", "", Options, std::nullopt));
61c931ac59Spaperchalice     if (!TM)
62c931ac59Spaperchalice       GTEST_SKIP();
63*bb3f5e1fSMatin Raayai     MMI = std::make_unique<MachineModuleInfo>(TM.get());
64c931ac59Spaperchalice 
65c931ac59Spaperchalice     PassBuilder PB(TM.get());
66c931ac59Spaperchalice     PB.registerModuleAnalyses(MAM);
67c931ac59Spaperchalice     PB.registerCGSCCAnalyses(CGAM);
68c931ac59Spaperchalice     PB.registerFunctionAnalyses(FAM);
69c931ac59Spaperchalice     PB.registerLoopAnalyses(LAM);
70c931ac59Spaperchalice     PB.registerMachineFunctionAnalyses(MFAM);
71c931ac59Spaperchalice     PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM);
72c931ac59Spaperchalice     MAM.registerPass([&] { return MachineModuleAnalysis(*MMI); });
73c931ac59Spaperchalice   }
74c931ac59Spaperchalice 
7538c3855cSKyungwoo Lee   bool parseMIR(StringRef MIRCode) {
76c931ac59Spaperchalice     SMDiagnostic Diagnostic;
77c931ac59Spaperchalice     std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);
78c931ac59Spaperchalice     MIR = createMIRParser(std::move(MBuffer), Context);
79c931ac59Spaperchalice     if (!MIR)
80c931ac59Spaperchalice       return false;
81c931ac59Spaperchalice 
82c931ac59Spaperchalice     M = MIR->parseIRModule();
83c931ac59Spaperchalice     M->setDataLayout(TM->createDataLayout());
84c931ac59Spaperchalice 
85c931ac59Spaperchalice     if (MIR->parseMachineFunctions(*M, MAM)) {
86c931ac59Spaperchalice       M.reset();
87c931ac59Spaperchalice       return false;
88c931ac59Spaperchalice     }
89c931ac59Spaperchalice 
90c931ac59Spaperchalice     return true;
91c931ac59Spaperchalice   }
92c931ac59Spaperchalice };
93c931ac59Spaperchalice 
94c931ac59Spaperchalice TEST_F(MachineDomTreeUpdaterTest, EagerUpdateBasicOperations) {
95c931ac59Spaperchalice   StringRef MIRString = R"(
96c931ac59Spaperchalice --- |
97c931ac59Spaperchalice   define i64 @f0(i64 %i, ptr %p) {
98c931ac59Spaperchalice   bb0:
99c931ac59Spaperchalice     store i64 %i, ptr %p, align 4
100c931ac59Spaperchalice     switch i64 %i, label %bb1 [
101c931ac59Spaperchalice       i64 1, label %bb2
102c931ac59Spaperchalice       i64 2, label %bb3
103c931ac59Spaperchalice     ]
104c931ac59Spaperchalice   bb1:                                              ; preds = %bb0
105c931ac59Spaperchalice     ret i64 1
106c931ac59Spaperchalice   bb2:                                              ; preds = %bb0
107c931ac59Spaperchalice     ret i64 2
108c931ac59Spaperchalice   bb3:                                              ; preds = %bb0
109c931ac59Spaperchalice     ret i64 3
110c931ac59Spaperchalice   }
111c931ac59Spaperchalice ...
112c931ac59Spaperchalice ---
113c931ac59Spaperchalice name:            f0
114c931ac59Spaperchalice body:             |
115c931ac59Spaperchalice   bb.0.bb0:
116c931ac59Spaperchalice     successors: %bb.2, %bb.4
117c931ac59Spaperchalice     liveins: $rdi, $rsi
118c931ac59Spaperchalice 
119c931ac59Spaperchalice     %1:gr32 = COPY $rsi
120c931ac59Spaperchalice     %0:gr64 = COPY $rdi
121c931ac59Spaperchalice     MOV64mr %1, 1, $noreg, 0, $noreg, %0 :: (store (s64) into %ir.p)
122c931ac59Spaperchalice     %2:gr64 = SUB64ri32 %0, 1, implicit-def $eflags
123c931ac59Spaperchalice     JCC_1 %bb.2, 4, implicit $eflags
124c931ac59Spaperchalice     JMP_1 %bb.4
125c931ac59Spaperchalice 
126c931ac59Spaperchalice   bb.4.bb0:
127c931ac59Spaperchalice     successors: %bb.3, %bb.1
128c931ac59Spaperchalice 
129c931ac59Spaperchalice     %3:gr64 = SUB64ri32 %0, 2, implicit-def $eflags
130c931ac59Spaperchalice     JCC_1 %bb.3, 4, implicit $eflags
131c931ac59Spaperchalice     JMP_1 %bb.1
132c931ac59Spaperchalice 
133c931ac59Spaperchalice   bb.1.bb1:
134c931ac59Spaperchalice     %6:gr64 = MOV32ri64 1
135c931ac59Spaperchalice     $rax = COPY %6
136c931ac59Spaperchalice     RET 0, $rax
137c931ac59Spaperchalice 
138c931ac59Spaperchalice   bb.2.bb2:
139c931ac59Spaperchalice     %5:gr64 = MOV32ri64 2
140c931ac59Spaperchalice     $rax = COPY %5
141c931ac59Spaperchalice     RET 0, $rax
142c931ac59Spaperchalice 
143c931ac59Spaperchalice   bb.3.bb3:
144c931ac59Spaperchalice     %4:gr64 = MOV32ri64 3
145c931ac59Spaperchalice     $rax = COPY %4
146c931ac59Spaperchalice     RET 0, $rax
147c931ac59Spaperchalice 
148c931ac59Spaperchalice ...
149c931ac59Spaperchalice )";
150c931ac59Spaperchalice 
15138c3855cSKyungwoo Lee   ASSERT_TRUE(parseMIR(MIRString));
152c931ac59Spaperchalice 
153c931ac59Spaperchalice   auto &MF =
154c931ac59Spaperchalice       FAM.getResult<MachineFunctionAnalysis>(*M->getFunction("f0")).getMF();
155c931ac59Spaperchalice 
156c931ac59Spaperchalice   MachineDominatorTree DT(MF);
157c931ac59Spaperchalice   MachinePostDominatorTree PDT(MF);
158c931ac59Spaperchalice   MachineDomTreeUpdater DTU(DT, PDT,
159c931ac59Spaperchalice                             MachineDomTreeUpdater::UpdateStrategy::Eager);
160c931ac59Spaperchalice 
161c931ac59Spaperchalice   ASSERT_TRUE(DTU.hasDomTree());
162c931ac59Spaperchalice   ASSERT_TRUE(DTU.hasPostDomTree());
163c931ac59Spaperchalice   ASSERT_TRUE(DTU.isEager());
164c931ac59Spaperchalice   ASSERT_FALSE(DTU.isLazy());
165c931ac59Spaperchalice   ASSERT_TRUE(DTU.getDomTree().verify());
166c931ac59Spaperchalice   ASSERT_TRUE(DTU.getPostDomTree().verify());
167c931ac59Spaperchalice   ASSERT_FALSE(DTU.hasPendingUpdates());
168c931ac59Spaperchalice 
169c931ac59Spaperchalice   auto B = MF.begin();
170c931ac59Spaperchalice   [[maybe_unused]] auto BB0 = B;
171c931ac59Spaperchalice   auto BB1 = ++B;
172c931ac59Spaperchalice   auto BB2 = ++B;
173c931ac59Spaperchalice   [[maybe_unused]] auto BB3 = ++B;
174c931ac59Spaperchalice   auto BB4 = ++B;
175c931ac59Spaperchalice   EXPECT_EQ(BB1->succ_size(), 2u);
176c931ac59Spaperchalice   ASSERT_TRUE(DT.dominates(&*BB1, &*BB2));
177c931ac59Spaperchalice   ASSERT_TRUE(DT.dominates(&*BB1, &*BB4));
178c931ac59Spaperchalice   BB1->removeSuccessor(&*BB4);
179c931ac59Spaperchalice   DTU.deleteBB(&*BB4);
180c931ac59Spaperchalice   EXPECT_EQ(BB1->succ_size(), 1u);
181c931ac59Spaperchalice   ASSERT_TRUE(DT.dominates(&*BB1, &*BB2));
182c931ac59Spaperchalice }
183c931ac59Spaperchalice 
184c931ac59Spaperchalice TEST_F(MachineDomTreeUpdaterTest, LazyUpdateBasicOperations) {
185c931ac59Spaperchalice   StringRef MIRString = R"(
186c931ac59Spaperchalice --- |
187c931ac59Spaperchalice   define i64 @f0(i64 %i, ptr %p) {
188c931ac59Spaperchalice   bb0:
189c931ac59Spaperchalice     store i64 %i, ptr %p, align 4
190c931ac59Spaperchalice     switch i64 %i, label %bb1 [
191c931ac59Spaperchalice       i64 1, label %bb2
192c931ac59Spaperchalice       i64 2, label %bb3
193c931ac59Spaperchalice     ]
194c931ac59Spaperchalice   bb1:                                              ; preds = %bb0
195c931ac59Spaperchalice     ret i64 1
196c931ac59Spaperchalice   bb2:                                              ; preds = %bb0
197c931ac59Spaperchalice     ret i64 2
198c931ac59Spaperchalice   bb3:                                              ; preds = %bb0
199c931ac59Spaperchalice     ret i64 3
200c931ac59Spaperchalice   }
201c931ac59Spaperchalice ...
202c931ac59Spaperchalice ---
203c931ac59Spaperchalice name:            f0
204c931ac59Spaperchalice body:             |
205c931ac59Spaperchalice   bb.0.bb0:
206c931ac59Spaperchalice     successors: %bb.2, %bb.4
207c931ac59Spaperchalice     liveins: $rdi, $rsi
208c931ac59Spaperchalice 
209c931ac59Spaperchalice     %1:gr32 = COPY $rsi
210c931ac59Spaperchalice     %0:gr64 = COPY $rdi
211c931ac59Spaperchalice     MOV64mr %1, 1, $noreg, 0, $noreg, %0 :: (store (s64) into %ir.p)
212c931ac59Spaperchalice     %2:gr64 = SUB64ri32 %0, 1, implicit-def $eflags
213c931ac59Spaperchalice     JCC_1 %bb.2, 4, implicit $eflags
214c931ac59Spaperchalice     JMP_1 %bb.4
215c931ac59Spaperchalice 
216c931ac59Spaperchalice   bb.4.bb0:
217c931ac59Spaperchalice     successors: %bb.3, %bb.1
218c931ac59Spaperchalice 
219c931ac59Spaperchalice     %3:gr64 = SUB64ri32 %0, 2, implicit-def $eflags
220c931ac59Spaperchalice     JCC_1 %bb.3, 4, implicit $eflags
221c931ac59Spaperchalice     JMP_1 %bb.1
222c931ac59Spaperchalice 
223c931ac59Spaperchalice   bb.1.bb1:
224c931ac59Spaperchalice     %6:gr64 = MOV32ri64 1
225c931ac59Spaperchalice     $rax = COPY %6
226c931ac59Spaperchalice     RET 0, $rax
227c931ac59Spaperchalice 
228c931ac59Spaperchalice   bb.2.bb2:
229c931ac59Spaperchalice     %5:gr64 = MOV32ri64 2
230c931ac59Spaperchalice     $rax = COPY %5
231c931ac59Spaperchalice     RET 0, $rax
232c931ac59Spaperchalice 
233c931ac59Spaperchalice   bb.3.bb3:
234c931ac59Spaperchalice     %4:gr64 = MOV32ri64 3
235c931ac59Spaperchalice     $rax = COPY %4
236c931ac59Spaperchalice     RET 0, $rax
237c931ac59Spaperchalice 
238c931ac59Spaperchalice ...
239c931ac59Spaperchalice )";
240c931ac59Spaperchalice 
24138c3855cSKyungwoo Lee   ASSERT_TRUE(parseMIR(MIRString));
242c931ac59Spaperchalice 
243c931ac59Spaperchalice   auto &MF =
244c931ac59Spaperchalice       FAM.getResult<MachineFunctionAnalysis>(*M->getFunction("f0")).getMF();
245c931ac59Spaperchalice 
246c931ac59Spaperchalice   MachineDominatorTree DT(MF);
247c931ac59Spaperchalice   MachinePostDominatorTree PDT(MF);
248c931ac59Spaperchalice   MachineDomTreeUpdater DTU(DT, PDT,
249c931ac59Spaperchalice                             MachineDomTreeUpdater::UpdateStrategy::Lazy);
250c931ac59Spaperchalice 
251c931ac59Spaperchalice   ASSERT_TRUE(DTU.hasDomTree());
252c931ac59Spaperchalice   ASSERT_TRUE(DTU.hasPostDomTree());
253c931ac59Spaperchalice   ASSERT_FALSE(DTU.isEager());
254c931ac59Spaperchalice   ASSERT_TRUE(DTU.isLazy());
255c931ac59Spaperchalice   ASSERT_TRUE(DTU.getDomTree().verify());
256c931ac59Spaperchalice   ASSERT_TRUE(DTU.getPostDomTree().verify());
257c931ac59Spaperchalice   ASSERT_FALSE(DTU.hasPendingUpdates());
258c931ac59Spaperchalice 
259c931ac59Spaperchalice   auto B = MF.begin();
260c931ac59Spaperchalice   [[maybe_unused]] auto BB0 = B;
261c931ac59Spaperchalice   auto BB1 = ++B;
262c931ac59Spaperchalice   auto BB2 = ++B;
263c931ac59Spaperchalice   [[maybe_unused]] auto BB3 = ++B;
264c931ac59Spaperchalice   auto BB4 = ++B;
265c931ac59Spaperchalice   EXPECT_EQ(BB1->succ_size(), 2u);
266c931ac59Spaperchalice   ASSERT_TRUE(DT.dominates(&*BB1, &*BB2));
267c931ac59Spaperchalice   ASSERT_TRUE(DT.dominates(&*BB1, &*BB4));
268c931ac59Spaperchalice   BB1->removeSuccessor(&*BB4);
269c931ac59Spaperchalice   DTU.deleteBB(&*BB4);
270bf528849Spaperchalice   ASSERT_TRUE(DTU.hasPendingDeletedBB());
271c931ac59Spaperchalice   EXPECT_EQ(BB1->succ_size(), 1u);
272c931ac59Spaperchalice   ASSERT_TRUE(DT.dominates(&*BB1, &*BB2));
273c931ac59Spaperchalice   ASSERT_NE(DT.getNode(&*BB4), nullptr);
274c931ac59Spaperchalice   DTU.flush();
275c931ac59Spaperchalice }
276