1 //===----------- llvm/unittest/CodeGen/LexicalScopesTest.cpp --------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/CodeGen/LexicalScopes.h"
10 #include "llvm/CodeGen/MachineBasicBlock.h"
11 #include "llvm/CodeGen/MachineFunction.h"
12 #include "llvm/CodeGen/MachineInstr.h"
13 #include "llvm/CodeGen/MachineMemOperand.h"
14 #include "llvm/CodeGen/MachineModuleInfo.h"
15 #include "llvm/CodeGen/TargetFrameLowering.h"
16 #include "llvm/CodeGen/TargetInstrInfo.h"
17 #include "llvm/CodeGen/TargetLowering.h"
18 #include "llvm/CodeGen/TargetSubtargetInfo.h"
19 #include "llvm/IR/DIBuilder.h"
20 #include "llvm/IR/DebugInfoMetadata.h"
21 #include "llvm/IR/IRBuilder.h"
22 #include "llvm/IR/ModuleSlotTracker.h"
23 #include "llvm/MC/MCAsmInfo.h"
24 #include "llvm/MC/MCSymbol.h"
25 #include "llvm/MC/TargetRegistry.h"
26 #include "llvm/Support/TargetSelect.h"
27 #include "llvm/Target/TargetMachine.h"
28 #include "llvm/Target/TargetOptions.h"
30 #include "gtest/gtest.h"
35 // Include helper functions to ease the manipulation of MachineFunctions
36 #include "MFCommon.inc"
38 class LexicalScopesTest
: public testing::Test
{
43 std::unique_ptr
<MachineFunction
> MF
;
46 DISubprogram
*OurFunc
;
47 DILexicalBlock
*OurBlock
, *AnotherBlock
;
48 DISubprogram
*ToInlineFunc
;
49 DILexicalBlock
*ToInlineBlock
;
50 // DebugLocs that we'll used to create test environments.
51 DebugLoc OutermostLoc
, InBlockLoc
, NotNestedBlockLoc
, InlinedLoc
;
53 // Test environment blocks -- these form a diamond control flow pattern,
54 // MBB1 being the entry block, blocks two and three being the branches, and
55 // block four joining the branches and being an exit block.
56 MachineBasicBlock
*MBB1
, *MBB2
, *MBB3
, *MBB4
;
58 // Some meaningless instructions -- the first is fully meaningless,
59 // while the second is supposed to impersonate DBG_VALUEs through its
62 MCInstrDesc DbgValueInst
;
64 LexicalScopesTest() : Ctx(), Mod("beehives", Ctx
) {
65 memset(&BeanInst
, 0, sizeof(BeanInst
));
69 memset(&DbgValueInst
, 0, sizeof(DbgValueInst
));
70 DbgValueInst
.Opcode
= TargetOpcode::DBG_VALUE
;
71 DbgValueInst
.Size
= 1;
73 // Boilerplate that creates a MachineFunction and associated blocks.
74 MF
= createMachineFunction(Ctx
, Mod
);
75 llvm::Function
&F
= const_cast<llvm::Function
&>(MF
->getFunction());
76 auto BB1
= BasicBlock::Create(Ctx
, "a", &F
);
77 auto BB2
= BasicBlock::Create(Ctx
, "b", &F
);
78 auto BB3
= BasicBlock::Create(Ctx
, "c", &F
);
79 auto BB4
= BasicBlock::Create(Ctx
, "d", &F
);
80 IRBuilder
<> IRB1(BB1
), IRB2(BB2
), IRB3(BB3
), IRB4(BB4
);
85 MBB1
= MF
->CreateMachineBasicBlock(BB1
);
86 MF
->insert(MF
->end(), MBB1
);
87 MBB2
= MF
->CreateMachineBasicBlock(BB2
);
88 MF
->insert(MF
->end(), MBB2
);
89 MBB3
= MF
->CreateMachineBasicBlock(BB3
);
90 MF
->insert(MF
->end(), MBB3
);
91 MBB4
= MF
->CreateMachineBasicBlock(BB4
);
92 MF
->insert(MF
->end(), MBB4
);
93 MBB1
->addSuccessor(MBB2
);
94 MBB1
->addSuccessor(MBB3
);
95 MBB2
->addSuccessor(MBB4
);
96 MBB3
->addSuccessor(MBB4
);
98 // Create metadata: CU, subprogram, some blocks and an inline function
101 OurFile
= DIB
.createFile("xyzzy.c", "/cave");
103 DIB
.createCompileUnit(dwarf::DW_LANG_C99
, OurFile
, "nou", false, "", 0);
104 auto OurSubT
= DIB
.createSubroutineType(DIB
.getOrCreateTypeArray(None
));
106 DIB
.createFunction(OurCU
, "bees", "", OurFile
, 1, OurSubT
, 1,
107 DINode::FlagZero
, DISubprogram::SPFlagDefinition
);
108 F
.setSubprogram(OurFunc
);
109 OurBlock
= DIB
.createLexicalBlock(OurFunc
, OurFile
, 2, 3);
110 AnotherBlock
= DIB
.createLexicalBlock(OurFunc
, OurFile
, 2, 6);
112 DIB
.createFunction(OurFile
, "shoes", "", OurFile
, 10, OurSubT
, 10,
113 DINode::FlagZero
, DISubprogram::SPFlagDefinition
);
115 // Make some nested scopes.
116 OutermostLoc
= DILocation::get(Ctx
, 3, 1, OurFunc
);
117 InBlockLoc
= DILocation::get(Ctx
, 4, 1, OurBlock
);
118 InlinedLoc
= DILocation::get(Ctx
, 10, 1, ToInlineFunc
, InBlockLoc
.get());
120 // Make a scope that isn't nested within the others.
121 NotNestedBlockLoc
= DILocation::get(Ctx
, 4, 1, AnotherBlock
);
127 // Fill blocks with dummy instructions, test some base lexical scope
129 TEST_F(LexicalScopesTest
, FlatLayout
) {
130 BuildMI(*MBB1
, MBB1
->end(), OutermostLoc
, BeanInst
);
131 BuildMI(*MBB2
, MBB2
->end(), OutermostLoc
, BeanInst
);
132 BuildMI(*MBB3
, MBB3
->end(), OutermostLoc
, BeanInst
);
133 BuildMI(*MBB4
, MBB4
->end(), OutermostLoc
, BeanInst
);
136 EXPECT_TRUE(LS
.empty());
138 EXPECT_EQ(LS
.getCurrentFunctionScope(), nullptr);
141 EXPECT_FALSE(LS
.empty());
142 LexicalScope
*FuncScope
= LS
.getCurrentFunctionScope();
143 EXPECT_EQ(FuncScope
->getParent(), nullptr);
144 EXPECT_EQ(FuncScope
->getDesc(), OurFunc
);
145 EXPECT_EQ(FuncScope
->getInlinedAt(), nullptr);
146 EXPECT_EQ(FuncScope
->getScopeNode(), OurFunc
);
147 EXPECT_FALSE(FuncScope
->isAbstractScope());
148 EXPECT_EQ(FuncScope
->getChildren().size(), 0u);
150 // There should be one range, covering the whole function. Test that it
151 // points at the correct instructions.
152 auto &Ranges
= FuncScope
->getRanges();
153 ASSERT_EQ(Ranges
.size(), 1u);
154 EXPECT_EQ(Ranges
.front().first
, &*MF
->begin()->begin());
155 auto BBIt
= MF
->end();
156 BBIt
= std::prev(BBIt
);
157 EXPECT_EQ(Ranges
.front().second
, &*BBIt
->begin());
159 EXPECT_TRUE(FuncScope
->dominates(FuncScope
));
160 SmallPtrSet
<const MachineBasicBlock
*, 4> MBBVec
;
161 LS
.getMachineBasicBlocks(OutermostLoc
.get(), MBBVec
);
163 EXPECT_EQ(MBBVec
.size(), 4u);
164 // All the blocks should be in that set; the outermost loc should dominate
165 // them; and no other scope should.
166 for (auto &MBB
: *MF
) {
167 EXPECT_EQ(MBBVec
.count(&MBB
), 1u);
168 EXPECT_TRUE(LS
.dominates(OutermostLoc
.get(), &MBB
));
169 EXPECT_FALSE(LS
.dominates(InBlockLoc
.get(), &MBB
));
170 EXPECT_FALSE(LS
.dominates(InlinedLoc
.get(), &MBB
));
174 // Examine relationship between two nested scopes inside the function, the
175 // outer function and the lexical block within it.
176 TEST_F(LexicalScopesTest
, BlockScopes
) {
177 BuildMI(*MBB1
, MBB1
->end(), InBlockLoc
, BeanInst
);
178 BuildMI(*MBB2
, MBB2
->end(), InBlockLoc
, BeanInst
);
179 BuildMI(*MBB3
, MBB3
->end(), InBlockLoc
, BeanInst
);
180 BuildMI(*MBB4
, MBB4
->end(), InBlockLoc
, BeanInst
);
184 LexicalScope
*FuncScope
= LS
.getCurrentFunctionScope();
185 EXPECT_EQ(FuncScope
->getDesc(), OurFunc
);
186 auto &Children
= FuncScope
->getChildren();
187 ASSERT_EQ(Children
.size(), 1u);
188 auto *BlockScope
= Children
[0];
189 EXPECT_EQ(LS
.findLexicalScope(InBlockLoc
.get()), BlockScope
);
190 EXPECT_EQ(BlockScope
->getDesc(), InBlockLoc
->getScope());
191 EXPECT_FALSE(BlockScope
->isAbstractScope());
193 EXPECT_TRUE(FuncScope
->dominates(BlockScope
));
194 EXPECT_FALSE(BlockScope
->dominates(FuncScope
));
195 EXPECT_EQ(FuncScope
->getParent(), nullptr);
196 EXPECT_EQ(BlockScope
->getParent(), FuncScope
);
198 SmallPtrSet
<const MachineBasicBlock
*, 4> MBBVec
;
199 LS
.getMachineBasicBlocks(OutermostLoc
.get(), MBBVec
);
201 EXPECT_EQ(MBBVec
.size(), 4u);
202 for (auto &MBB
: *MF
) {
203 EXPECT_EQ(MBBVec
.count(&MBB
), 1u);
204 EXPECT_TRUE(LS
.dominates(OutermostLoc
.get(), &MBB
));
205 EXPECT_TRUE(LS
.dominates(InBlockLoc
.get(), &MBB
));
206 EXPECT_FALSE(LS
.dominates(InlinedLoc
.get(), &MBB
));
210 // Test inlined scopes functionality and relationship with the outer scopes.
211 TEST_F(LexicalScopesTest
, InlinedScopes
) {
212 BuildMI(*MBB1
, MBB1
->end(), InlinedLoc
, BeanInst
);
213 BuildMI(*MBB2
, MBB2
->end(), InlinedLoc
, BeanInst
);
214 BuildMI(*MBB3
, MBB3
->end(), InlinedLoc
, BeanInst
);
215 BuildMI(*MBB4
, MBB4
->end(), InlinedLoc
, BeanInst
);
219 LexicalScope
*FuncScope
= LS
.getCurrentFunctionScope();
220 auto &Children
= FuncScope
->getChildren();
221 ASSERT_EQ(Children
.size(), 1u);
222 auto *BlockScope
= Children
[0];
223 auto &BlockChildren
= BlockScope
->getChildren();
224 ASSERT_EQ(BlockChildren
.size(), 1u);
225 auto *InlinedScope
= BlockChildren
[0];
227 EXPECT_FALSE(InlinedScope
->isAbstractScope());
228 EXPECT_EQ(InlinedScope
->getInlinedAt(), InlinedLoc
.getInlinedAt());
229 EXPECT_EQ(InlinedScope
->getDesc(), InlinedLoc
.getScope());
230 EXPECT_EQ(InlinedScope
->getChildren().size(), 0u);
232 EXPECT_EQ(FuncScope
->getParent(), nullptr);
233 EXPECT_EQ(BlockScope
->getParent(), FuncScope
);
234 EXPECT_EQ(InlinedScope
->getParent(), BlockScope
);
236 const auto &AbstractScopes
= LS
.getAbstractScopesList();
237 ASSERT_EQ(AbstractScopes
.size(), 1u);
238 const auto &AbstractScope
= *AbstractScopes
[0];
239 EXPECT_TRUE(AbstractScope
.isAbstractScope());
240 EXPECT_EQ(AbstractScope
.getDesc(), InlinedLoc
.getScope());
241 EXPECT_EQ(AbstractScope
.getInlinedAt(), nullptr);
242 EXPECT_EQ(AbstractScope
.getParent(), nullptr);
245 // Test behaviour in a function that has empty DebugLocs.
246 TEST_F(LexicalScopesTest
, FuncWithEmptyGap
) {
247 BuildMI(*MBB1
, MBB1
->end(), OutermostLoc
, BeanInst
);
248 BuildMI(*MBB2
, MBB2
->end(), DebugLoc(), BeanInst
);
249 BuildMI(*MBB3
, MBB3
->end(), DebugLoc(), BeanInst
);
250 BuildMI(*MBB4
, MBB4
->end(), OutermostLoc
, BeanInst
);
254 LexicalScope
*FuncScope
= LS
.getCurrentFunctionScope();
256 // A gap in a range that contains no other location, is not actually a
257 // gap as far as lexical scopes are concerned.
258 auto &Ranges
= FuncScope
->getRanges();
259 ASSERT_EQ(Ranges
.size(), 1u);
260 EXPECT_EQ(Ranges
[0].first
, &*MF
->begin()->begin());
261 auto BBIt
= MF
->end();
262 BBIt
= std::prev(BBIt
);
263 EXPECT_EQ(Ranges
[0].second
, &*BBIt
->begin());
266 // Now a function with intervening not-in-scope instructions.
267 TEST_F(LexicalScopesTest
, FuncWithRealGap
) {
268 MachineInstr
*FirstI
= BuildMI(*MBB1
, MBB1
->end(), InBlockLoc
, BeanInst
);
269 BuildMI(*MBB2
, MBB2
->end(), OutermostLoc
, BeanInst
);
270 BuildMI(*MBB3
, MBB3
->end(), OutermostLoc
, BeanInst
);
271 MachineInstr
*LastI
= BuildMI(*MBB4
, MBB4
->end(), InBlockLoc
, BeanInst
);
275 LexicalScope
*BlockScope
= LS
.findLexicalScope(InBlockLoc
.get());
276 ASSERT_NE(BlockScope
, nullptr);
278 // Within the block scope, there's a gap between the first and last
279 // block / instruction, where it's only the outermost scope.
280 auto &Ranges
= BlockScope
->getRanges();
281 ASSERT_EQ(Ranges
.size(), 2u);
282 EXPECT_EQ(Ranges
[0].first
, FirstI
);
283 EXPECT_EQ(Ranges
[0].second
, FirstI
);
284 EXPECT_EQ(Ranges
[1].first
, LastI
);
285 EXPECT_EQ(Ranges
[1].second
, LastI
);
287 // The outer function scope should cover the whole function, including
288 // blocks the lexicalblock covers.
289 LexicalScope
*FuncScope
= LS
.getCurrentFunctionScope();
290 auto &FuncRanges
= FuncScope
->getRanges();
291 ASSERT_EQ(FuncRanges
.size(), 1u);
292 EXPECT_NE(FuncRanges
[0].first
, FuncRanges
[0].second
);
293 EXPECT_EQ(FuncRanges
[0].first
, FirstI
);
294 EXPECT_EQ(FuncRanges
[0].second
, LastI
);
297 // Examine the relationship between two scopes that don't nest (are siblings).
298 TEST_F(LexicalScopesTest
, NotNested
) {
299 MachineInstr
*FirstI
= BuildMI(*MBB1
, MBB1
->end(), InBlockLoc
, BeanInst
);
300 MachineInstr
*SecondI
=
301 BuildMI(*MBB2
, MBB2
->end(), NotNestedBlockLoc
, BeanInst
);
302 MachineInstr
*ThirdI
=
303 BuildMI(*MBB3
, MBB3
->end(), NotNestedBlockLoc
, BeanInst
);
304 MachineInstr
*FourthI
= BuildMI(*MBB4
, MBB4
->end(), InBlockLoc
, BeanInst
);
308 LexicalScope
*FuncScope
= LS
.getCurrentFunctionScope();
309 LexicalScope
*BlockScope
= LS
.findLexicalScope(InBlockLoc
.get());
310 LexicalScope
*OtherBlockScope
= LS
.findLexicalScope(NotNestedBlockLoc
.get());
311 ASSERT_NE(FuncScope
, nullptr);
312 ASSERT_NE(BlockScope
, nullptr);
313 ASSERT_NE(OtherBlockScope
, nullptr);
315 // The function should cover everything; the two blocks are distinct and
317 auto &FuncRanges
= FuncScope
->getRanges();
318 ASSERT_EQ(FuncRanges
.size(), 1u);
319 EXPECT_EQ(FuncRanges
[0].first
, FirstI
);
320 EXPECT_EQ(FuncRanges
[0].second
, FourthI
);
322 // Two ranges, start and end instructions.
323 auto &BlockRanges
= BlockScope
->getRanges();
324 ASSERT_EQ(BlockRanges
.size(), 2u);
325 EXPECT_EQ(BlockRanges
[0].first
, FirstI
);
326 EXPECT_EQ(BlockRanges
[0].second
, FirstI
);
327 EXPECT_EQ(BlockRanges
[1].first
, FourthI
);
328 EXPECT_EQ(BlockRanges
[1].second
, FourthI
);
330 // One inner range, covering the two inner blocks.
331 auto &OtherBlockRanges
= OtherBlockScope
->getRanges();
332 ASSERT_EQ(OtherBlockRanges
.size(), 1u);
333 EXPECT_EQ(OtherBlockRanges
[0].first
, SecondI
);
334 EXPECT_EQ(OtherBlockRanges
[0].second
, ThirdI
);
337 // Test the scope-specific and block-specific dominates methods.
338 TEST_F(LexicalScopesTest
, TestDominates
) {
339 BuildMI(*MBB1
, MBB1
->end(), InBlockLoc
, BeanInst
);
340 BuildMI(*MBB2
, MBB2
->end(), NotNestedBlockLoc
, BeanInst
);
341 BuildMI(*MBB3
, MBB3
->end(), NotNestedBlockLoc
, BeanInst
);
342 BuildMI(*MBB4
, MBB4
->end(), InBlockLoc
, BeanInst
);
346 LexicalScope
*FuncScope
= LS
.getCurrentFunctionScope();
347 LexicalScope
*BlockScope
= LS
.findLexicalScope(InBlockLoc
.get());
348 LexicalScope
*OtherBlockScope
= LS
.findLexicalScope(NotNestedBlockLoc
.get());
349 ASSERT_NE(FuncScope
, nullptr);
350 ASSERT_NE(BlockScope
, nullptr);
351 ASSERT_NE(OtherBlockScope
, nullptr);
353 EXPECT_TRUE(FuncScope
->dominates(BlockScope
));
354 EXPECT_TRUE(FuncScope
->dominates(OtherBlockScope
));
355 EXPECT_FALSE(BlockScope
->dominates(FuncScope
));
356 EXPECT_FALSE(BlockScope
->dominates(OtherBlockScope
));
357 EXPECT_FALSE(OtherBlockScope
->dominates(FuncScope
));
358 EXPECT_FALSE(OtherBlockScope
->dominates(BlockScope
));
360 // Outermost scope dominates everything, as all insts are within it.
361 EXPECT_TRUE(LS
.dominates(OutermostLoc
.get(), MBB1
));
362 EXPECT_TRUE(LS
.dominates(OutermostLoc
.get(), MBB2
));
363 EXPECT_TRUE(LS
.dominates(OutermostLoc
.get(), MBB3
));
364 EXPECT_TRUE(LS
.dominates(OutermostLoc
.get(), MBB4
));
366 // One inner block dominates the outer pair of blocks,
367 EXPECT_TRUE(LS
.dominates(InBlockLoc
.get(), MBB1
));
368 EXPECT_FALSE(LS
.dominates(InBlockLoc
.get(), MBB2
));
369 EXPECT_FALSE(LS
.dominates(InBlockLoc
.get(), MBB3
));
370 EXPECT_TRUE(LS
.dominates(InBlockLoc
.get(), MBB4
));
372 // While the other dominates the inner two blocks.
373 EXPECT_FALSE(LS
.dominates(NotNestedBlockLoc
.get(), MBB1
));
374 EXPECT_TRUE(LS
.dominates(NotNestedBlockLoc
.get(), MBB2
));
375 EXPECT_TRUE(LS
.dominates(NotNestedBlockLoc
.get(), MBB3
));
376 EXPECT_FALSE(LS
.dominates(NotNestedBlockLoc
.get(), MBB4
));
379 // Test getMachineBasicBlocks returns all dominated blocks.
380 TEST_F(LexicalScopesTest
, TestGetBlocks
) {
381 BuildMI(*MBB1
, MBB1
->end(), InBlockLoc
, BeanInst
);
382 BuildMI(*MBB2
, MBB2
->end(), NotNestedBlockLoc
, BeanInst
);
383 BuildMI(*MBB3
, MBB3
->end(), NotNestedBlockLoc
, BeanInst
);
384 BuildMI(*MBB4
, MBB4
->end(), InBlockLoc
, BeanInst
);
388 LexicalScope
*FuncScope
= LS
.getCurrentFunctionScope();
389 LexicalScope
*BlockScope
= LS
.findLexicalScope(InBlockLoc
.get());
390 LexicalScope
*OtherBlockScope
= LS
.findLexicalScope(NotNestedBlockLoc
.get());
391 ASSERT_NE(FuncScope
, nullptr);
392 ASSERT_NE(BlockScope
, nullptr);
393 ASSERT_NE(OtherBlockScope
, nullptr);
395 SmallPtrSet
<const MachineBasicBlock
*, 4> OutermostBlocks
, InBlockBlocks
,
396 NotNestedBlockBlocks
;
397 LS
.getMachineBasicBlocks(OutermostLoc
.get(), OutermostBlocks
);
398 LS
.getMachineBasicBlocks(InBlockLoc
.get(), InBlockBlocks
);
399 LS
.getMachineBasicBlocks(NotNestedBlockLoc
.get(), NotNestedBlockBlocks
);
401 EXPECT_EQ(OutermostBlocks
.count(MBB1
), 1u);
402 EXPECT_EQ(OutermostBlocks
.count(MBB2
), 1u);
403 EXPECT_EQ(OutermostBlocks
.count(MBB3
), 1u);
404 EXPECT_EQ(OutermostBlocks
.count(MBB4
), 1u);
406 EXPECT_EQ(InBlockBlocks
.count(MBB1
), 1u);
407 EXPECT_EQ(InBlockBlocks
.count(MBB2
), 0u);
408 EXPECT_EQ(InBlockBlocks
.count(MBB3
), 0u);
409 EXPECT_EQ(InBlockBlocks
.count(MBB4
), 1u);
411 EXPECT_EQ(NotNestedBlockBlocks
.count(MBB1
), 0u);
412 EXPECT_EQ(NotNestedBlockBlocks
.count(MBB2
), 1u);
413 EXPECT_EQ(NotNestedBlockBlocks
.count(MBB3
), 1u);
414 EXPECT_EQ(NotNestedBlockBlocks
.count(MBB4
), 0u);
417 TEST_F(LexicalScopesTest
, TestMetaInst
) {
418 // Instruction Layout looks like this, where 'F' means funcscope, and
432 // The block / 'B' should only dominate bb1 and bb4. DBG_VALUE is a meta
433 // instruction, and shouldn't contribute to scopes.
434 BuildMI(*MBB1
, MBB1
->end(), OutermostLoc
, BeanInst
);
435 BuildMI(*MBB1
, MBB1
->end(), InBlockLoc
, BeanInst
);
436 BuildMI(*MBB2
, MBB2
->end(), OutermostLoc
, BeanInst
);
437 BuildMI(*MBB2
, MBB2
->end(), InBlockLoc
, DbgValueInst
);
438 BuildMI(*MBB3
, MBB3
->end(), OutermostLoc
, BeanInst
);
439 BuildMI(*MBB3
, MBB3
->end(), InBlockLoc
, DbgValueInst
);
440 BuildMI(*MBB4
, MBB4
->end(), OutermostLoc
, BeanInst
);
441 BuildMI(*MBB4
, MBB4
->end(), InBlockLoc
, BeanInst
);
445 LexicalScope
*FuncScope
= LS
.getCurrentFunctionScope();
446 LexicalScope
*BlockScope
= LS
.findLexicalScope(InBlockLoc
.get());
447 ASSERT_NE(FuncScope
, nullptr);
448 ASSERT_NE(BlockScope
, nullptr);
450 EXPECT_TRUE(LS
.dominates(OutermostLoc
.get(), MBB1
));
451 EXPECT_TRUE(LS
.dominates(OutermostLoc
.get(), MBB2
));
452 EXPECT_TRUE(LS
.dominates(OutermostLoc
.get(), MBB3
));
453 EXPECT_TRUE(LS
.dominates(OutermostLoc
.get(), MBB4
));
454 EXPECT_TRUE(LS
.dominates(InBlockLoc
.get(), MBB1
));
455 EXPECT_FALSE(LS
.dominates(InBlockLoc
.get(), MBB2
));
456 EXPECT_FALSE(LS
.dominates(InBlockLoc
.get(), MBB3
));
457 EXPECT_TRUE(LS
.dominates(InBlockLoc
.get(), MBB4
));
460 } // anonymous namespace