[docs] Fix build-docs.sh
[llvm-project.git] / llvm / unittests / CodeGen / LexicalScopesTest.cpp
blobe1835b433f86a93b1fde6ca4b4811c319ecee24f
1 //===----------- llvm/unittest/CodeGen/LexicalScopesTest.cpp --------------===//
2 //
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
6 //
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"
32 using namespace llvm;
34 namespace {
35 // Include helper functions to ease the manipulation of MachineFunctions
36 #include "MFCommon.inc"
38 class LexicalScopesTest : public testing::Test {
39 public:
40 // Boilerplate,
41 LLVMContext Ctx;
42 Module Mod;
43 std::unique_ptr<MachineFunction> MF;
44 DICompileUnit *OurCU;
45 DIFile *OurFile;
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
60 // opcode.
61 MCInstrDesc BeanInst;
62 MCInstrDesc DbgValueInst;
64 LexicalScopesTest() : Ctx(), Mod("beehives", Ctx) {
65 memset(&BeanInst, 0, sizeof(BeanInst));
66 BeanInst.Opcode = 1;
67 BeanInst.Size = 1;
69 memset(&DbgValueInst, 0, sizeof(DbgValueInst));
70 DbgValueInst.Opcode = TargetOpcode::DBG_VALUE;
71 DbgValueInst.Size = 1;
72 DbgValueInst.Flags = 1U << MCID::Meta;
74 // Boilerplate that creates a MachineFunction and associated blocks.
75 MF = createMachineFunction(Ctx, Mod);
76 llvm::Function &F = const_cast<llvm::Function &>(MF->getFunction());
77 auto BB1 = BasicBlock::Create(Ctx, "a", &F);
78 auto BB2 = BasicBlock::Create(Ctx, "b", &F);
79 auto BB3 = BasicBlock::Create(Ctx, "c", &F);
80 auto BB4 = BasicBlock::Create(Ctx, "d", &F);
81 IRBuilder<> IRB1(BB1), IRB2(BB2), IRB3(BB3), IRB4(BB4);
82 IRB1.CreateBr(BB2);
83 IRB2.CreateBr(BB3);
84 IRB3.CreateBr(BB4);
85 IRB4.CreateRetVoid();
86 MBB1 = MF->CreateMachineBasicBlock(BB1);
87 MF->insert(MF->end(), MBB1);
88 MBB2 = MF->CreateMachineBasicBlock(BB2);
89 MF->insert(MF->end(), MBB2);
90 MBB3 = MF->CreateMachineBasicBlock(BB3);
91 MF->insert(MF->end(), MBB3);
92 MBB4 = MF->CreateMachineBasicBlock(BB4);
93 MF->insert(MF->end(), MBB4);
94 MBB1->addSuccessor(MBB2);
95 MBB1->addSuccessor(MBB3);
96 MBB2->addSuccessor(MBB4);
97 MBB3->addSuccessor(MBB4);
99 // Create metadata: CU, subprogram, some blocks and an inline function
100 // scope.
101 DIBuilder DIB(Mod);
102 OurFile = DIB.createFile("xyzzy.c", "/cave");
103 OurCU =
104 DIB.createCompileUnit(dwarf::DW_LANG_C99, OurFile, "nou", false, "", 0);
105 auto OurSubT = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
106 OurFunc =
107 DIB.createFunction(OurCU, "bees", "", OurFile, 1, OurSubT, 1,
108 DINode::FlagZero, DISubprogram::SPFlagDefinition);
109 F.setSubprogram(OurFunc);
110 OurBlock = DIB.createLexicalBlock(OurFunc, OurFile, 2, 3);
111 AnotherBlock = DIB.createLexicalBlock(OurFunc, OurFile, 2, 6);
112 ToInlineFunc =
113 DIB.createFunction(OurFile, "shoes", "", OurFile, 10, OurSubT, 10,
114 DINode::FlagZero, DISubprogram::SPFlagDefinition);
116 // Make some nested scopes.
117 OutermostLoc = DILocation::get(Ctx, 3, 1, OurFunc);
118 InBlockLoc = DILocation::get(Ctx, 4, 1, OurBlock);
119 InlinedLoc = DILocation::get(Ctx, 10, 1, ToInlineFunc, InBlockLoc.get());
121 // Make a scope that isn't nested within the others.
122 NotNestedBlockLoc = DILocation::get(Ctx, 4, 1, AnotherBlock);
124 DIB.finalize();
128 // Fill blocks with dummy instructions, test some base lexical scope
129 // functionaliy.
130 TEST_F(LexicalScopesTest, FlatLayout) {
131 BuildMI(*MBB1, MBB1->end(), OutermostLoc, BeanInst);
132 BuildMI(*MBB2, MBB2->end(), OutermostLoc, BeanInst);
133 BuildMI(*MBB3, MBB3->end(), OutermostLoc, BeanInst);
134 BuildMI(*MBB4, MBB4->end(), OutermostLoc, BeanInst);
136 LexicalScopes LS;
137 EXPECT_TRUE(LS.empty());
138 LS.reset();
139 EXPECT_EQ(LS.getCurrentFunctionScope(), nullptr);
141 LS.initialize(*MF);
142 EXPECT_FALSE(LS.empty());
143 LexicalScope *FuncScope = LS.getCurrentFunctionScope();
144 EXPECT_EQ(FuncScope->getParent(), nullptr);
145 EXPECT_EQ(FuncScope->getDesc(), OurFunc);
146 EXPECT_EQ(FuncScope->getInlinedAt(), nullptr);
147 EXPECT_EQ(FuncScope->getScopeNode(), OurFunc);
148 EXPECT_FALSE(FuncScope->isAbstractScope());
149 EXPECT_EQ(FuncScope->getChildren().size(), 0u);
151 // There should be one range, covering the whole function. Test that it
152 // points at the correct instructions.
153 auto &Ranges = FuncScope->getRanges();
154 ASSERT_EQ(Ranges.size(), 1u);
155 EXPECT_EQ(Ranges.front().first, &*MF->begin()->begin());
156 auto BBIt = MF->end();
157 BBIt = std::prev(BBIt);
158 EXPECT_EQ(Ranges.front().second, &*BBIt->begin());
160 EXPECT_TRUE(FuncScope->dominates(FuncScope));
161 SmallPtrSet<const MachineBasicBlock *, 4> MBBVec;
162 LS.getMachineBasicBlocks(OutermostLoc.get(), MBBVec);
164 EXPECT_EQ(MBBVec.size(), 4u);
165 // All the blocks should be in that set; the outermost loc should dominate
166 // them; and no other scope should.
167 for (auto &MBB : *MF) {
168 EXPECT_EQ(MBBVec.count(&MBB), 1u);
169 EXPECT_TRUE(LS.dominates(OutermostLoc.get(), &MBB));
170 EXPECT_FALSE(LS.dominates(InBlockLoc.get(), &MBB));
171 EXPECT_FALSE(LS.dominates(InlinedLoc.get(), &MBB));
175 // Examine relationship between two nested scopes inside the function, the
176 // outer function and the lexical block within it.
177 TEST_F(LexicalScopesTest, BlockScopes) {
178 BuildMI(*MBB1, MBB1->end(), InBlockLoc, BeanInst);
179 BuildMI(*MBB2, MBB2->end(), InBlockLoc, BeanInst);
180 BuildMI(*MBB3, MBB3->end(), InBlockLoc, BeanInst);
181 BuildMI(*MBB4, MBB4->end(), InBlockLoc, BeanInst);
183 LexicalScopes LS;
184 LS.initialize(*MF);
185 LexicalScope *FuncScope = LS.getCurrentFunctionScope();
186 EXPECT_EQ(FuncScope->getDesc(), OurFunc);
187 auto &Children = FuncScope->getChildren();
188 ASSERT_EQ(Children.size(), 1u);
189 auto *BlockScope = Children[0];
190 EXPECT_EQ(LS.findLexicalScope(InBlockLoc.get()), BlockScope);
191 EXPECT_EQ(BlockScope->getDesc(), InBlockLoc->getScope());
192 EXPECT_FALSE(BlockScope->isAbstractScope());
194 EXPECT_TRUE(FuncScope->dominates(BlockScope));
195 EXPECT_FALSE(BlockScope->dominates(FuncScope));
196 EXPECT_EQ(FuncScope->getParent(), nullptr);
197 EXPECT_EQ(BlockScope->getParent(), FuncScope);
199 SmallPtrSet<const MachineBasicBlock *, 4> MBBVec;
200 LS.getMachineBasicBlocks(OutermostLoc.get(), MBBVec);
202 EXPECT_EQ(MBBVec.size(), 4u);
203 for (auto &MBB : *MF) {
204 EXPECT_EQ(MBBVec.count(&MBB), 1u);
205 EXPECT_TRUE(LS.dominates(OutermostLoc.get(), &MBB));
206 EXPECT_TRUE(LS.dominates(InBlockLoc.get(), &MBB));
207 EXPECT_FALSE(LS.dominates(InlinedLoc.get(), &MBB));
211 // Test inlined scopes functionality and relationship with the outer scopes.
212 TEST_F(LexicalScopesTest, InlinedScopes) {
213 BuildMI(*MBB1, MBB1->end(), InlinedLoc, BeanInst);
214 BuildMI(*MBB2, MBB2->end(), InlinedLoc, BeanInst);
215 BuildMI(*MBB3, MBB3->end(), InlinedLoc, BeanInst);
216 BuildMI(*MBB4, MBB4->end(), InlinedLoc, BeanInst);
218 LexicalScopes LS;
219 LS.initialize(*MF);
220 LexicalScope *FuncScope = LS.getCurrentFunctionScope();
221 auto &Children = FuncScope->getChildren();
222 ASSERT_EQ(Children.size(), 1u);
223 auto *BlockScope = Children[0];
224 auto &BlockChildren = BlockScope->getChildren();
225 ASSERT_EQ(BlockChildren.size(), 1u);
226 auto *InlinedScope = BlockChildren[0];
228 EXPECT_FALSE(InlinedScope->isAbstractScope());
229 EXPECT_EQ(InlinedScope->getInlinedAt(), InlinedLoc.getInlinedAt());
230 EXPECT_EQ(InlinedScope->getDesc(), InlinedLoc.getScope());
231 EXPECT_EQ(InlinedScope->getChildren().size(), 0u);
233 EXPECT_EQ(FuncScope->getParent(), nullptr);
234 EXPECT_EQ(BlockScope->getParent(), FuncScope);
235 EXPECT_EQ(InlinedScope->getParent(), BlockScope);
237 const auto &AbstractScopes = LS.getAbstractScopesList();
238 ASSERT_EQ(AbstractScopes.size(), 1u);
239 const auto &AbstractScope = *AbstractScopes[0];
240 EXPECT_TRUE(AbstractScope.isAbstractScope());
241 EXPECT_EQ(AbstractScope.getDesc(), InlinedLoc.getScope());
242 EXPECT_EQ(AbstractScope.getInlinedAt(), nullptr);
243 EXPECT_EQ(AbstractScope.getParent(), nullptr);
246 // Test behaviour in a function that has empty DebugLocs.
247 TEST_F(LexicalScopesTest, FuncWithEmptyGap) {
248 BuildMI(*MBB1, MBB1->end(), OutermostLoc, BeanInst);
249 BuildMI(*MBB2, MBB2->end(), DebugLoc(), BeanInst);
250 BuildMI(*MBB3, MBB3->end(), DebugLoc(), BeanInst);
251 BuildMI(*MBB4, MBB4->end(), OutermostLoc, BeanInst);
253 LexicalScopes LS;
254 LS.initialize(*MF);
255 LexicalScope *FuncScope = LS.getCurrentFunctionScope();
257 // A gap in a range that contains no other location, is not actually a
258 // gap as far as lexical scopes are concerned.
259 auto &Ranges = FuncScope->getRanges();
260 ASSERT_EQ(Ranges.size(), 1u);
261 EXPECT_EQ(Ranges[0].first, &*MF->begin()->begin());
262 auto BBIt = MF->end();
263 BBIt = std::prev(BBIt);
264 EXPECT_EQ(Ranges[0].second, &*BBIt->begin());
267 // Now a function with intervening not-in-scope instructions.
268 TEST_F(LexicalScopesTest, FuncWithRealGap) {
269 MachineInstr *FirstI = BuildMI(*MBB1, MBB1->end(), InBlockLoc, BeanInst);
270 BuildMI(*MBB2, MBB2->end(), OutermostLoc, BeanInst);
271 BuildMI(*MBB3, MBB3->end(), OutermostLoc, BeanInst);
272 MachineInstr *LastI = BuildMI(*MBB4, MBB4->end(), InBlockLoc, BeanInst);
274 LexicalScopes LS;
275 LS.initialize(*MF);
276 LexicalScope *BlockScope = LS.findLexicalScope(InBlockLoc.get());
277 ASSERT_NE(BlockScope, nullptr);
279 // Within the block scope, there's a gap between the first and last
280 // block / instruction, where it's only the outermost scope.
281 auto &Ranges = BlockScope->getRanges();
282 ASSERT_EQ(Ranges.size(), 2u);
283 EXPECT_EQ(Ranges[0].first, FirstI);
284 EXPECT_EQ(Ranges[0].second, FirstI);
285 EXPECT_EQ(Ranges[1].first, LastI);
286 EXPECT_EQ(Ranges[1].second, LastI);
288 // The outer function scope should cover the whole function, including
289 // blocks the lexicalblock covers.
290 LexicalScope *FuncScope = LS.getCurrentFunctionScope();
291 auto &FuncRanges = FuncScope->getRanges();
292 ASSERT_EQ(FuncRanges.size(), 1u);
293 EXPECT_NE(FuncRanges[0].first, FuncRanges[0].second);
294 EXPECT_EQ(FuncRanges[0].first, FirstI);
295 EXPECT_EQ(FuncRanges[0].second, LastI);
298 // Examine the relationship between two scopes that don't nest (are siblings).
299 TEST_F(LexicalScopesTest, NotNested) {
300 MachineInstr *FirstI = BuildMI(*MBB1, MBB1->end(), InBlockLoc, BeanInst);
301 MachineInstr *SecondI =
302 BuildMI(*MBB2, MBB2->end(), NotNestedBlockLoc, BeanInst);
303 MachineInstr *ThirdI =
304 BuildMI(*MBB3, MBB3->end(), NotNestedBlockLoc, BeanInst);
305 MachineInstr *FourthI = BuildMI(*MBB4, MBB4->end(), InBlockLoc, BeanInst);
307 LexicalScopes LS;
308 LS.initialize(*MF);
309 LexicalScope *FuncScope = LS.getCurrentFunctionScope();
310 LexicalScope *BlockScope = LS.findLexicalScope(InBlockLoc.get());
311 LexicalScope *OtherBlockScope = LS.findLexicalScope(NotNestedBlockLoc.get());
312 ASSERT_NE(FuncScope, nullptr);
313 ASSERT_NE(BlockScope, nullptr);
314 ASSERT_NE(OtherBlockScope, nullptr);
316 // The function should cover everything; the two blocks are distinct and
317 // should not.
318 auto &FuncRanges = FuncScope->getRanges();
319 ASSERT_EQ(FuncRanges.size(), 1u);
320 EXPECT_EQ(FuncRanges[0].first, FirstI);
321 EXPECT_EQ(FuncRanges[0].second, FourthI);
323 // Two ranges, start and end instructions.
324 auto &BlockRanges = BlockScope->getRanges();
325 ASSERT_EQ(BlockRanges.size(), 2u);
326 EXPECT_EQ(BlockRanges[0].first, FirstI);
327 EXPECT_EQ(BlockRanges[0].second, FirstI);
328 EXPECT_EQ(BlockRanges[1].first, FourthI);
329 EXPECT_EQ(BlockRanges[1].second, FourthI);
331 // One inner range, covering the two inner blocks.
332 auto &OtherBlockRanges = OtherBlockScope->getRanges();
333 ASSERT_EQ(OtherBlockRanges.size(), 1u);
334 EXPECT_EQ(OtherBlockRanges[0].first, SecondI);
335 EXPECT_EQ(OtherBlockRanges[0].second, ThirdI);
338 // Test the scope-specific and block-specific dominates methods.
339 TEST_F(LexicalScopesTest, TestDominates) {
340 BuildMI(*MBB1, MBB1->end(), InBlockLoc, BeanInst);
341 BuildMI(*MBB2, MBB2->end(), NotNestedBlockLoc, BeanInst);
342 BuildMI(*MBB3, MBB3->end(), NotNestedBlockLoc, BeanInst);
343 BuildMI(*MBB4, MBB4->end(), InBlockLoc, BeanInst);
345 LexicalScopes LS;
346 LS.initialize(*MF);
347 LexicalScope *FuncScope = LS.getCurrentFunctionScope();
348 LexicalScope *BlockScope = LS.findLexicalScope(InBlockLoc.get());
349 LexicalScope *OtherBlockScope = LS.findLexicalScope(NotNestedBlockLoc.get());
350 ASSERT_NE(FuncScope, nullptr);
351 ASSERT_NE(BlockScope, nullptr);
352 ASSERT_NE(OtherBlockScope, nullptr);
354 EXPECT_TRUE(FuncScope->dominates(BlockScope));
355 EXPECT_TRUE(FuncScope->dominates(OtherBlockScope));
356 EXPECT_FALSE(BlockScope->dominates(FuncScope));
357 EXPECT_FALSE(BlockScope->dominates(OtherBlockScope));
358 EXPECT_FALSE(OtherBlockScope->dominates(FuncScope));
359 EXPECT_FALSE(OtherBlockScope->dominates(BlockScope));
361 // Outermost scope dominates everything, as all insts are within it.
362 EXPECT_TRUE(LS.dominates(OutermostLoc.get(), MBB1));
363 EXPECT_TRUE(LS.dominates(OutermostLoc.get(), MBB2));
364 EXPECT_TRUE(LS.dominates(OutermostLoc.get(), MBB3));
365 EXPECT_TRUE(LS.dominates(OutermostLoc.get(), MBB4));
367 // One inner block dominates the outer pair of blocks,
368 EXPECT_TRUE(LS.dominates(InBlockLoc.get(), MBB1));
369 EXPECT_FALSE(LS.dominates(InBlockLoc.get(), MBB2));
370 EXPECT_FALSE(LS.dominates(InBlockLoc.get(), MBB3));
371 EXPECT_TRUE(LS.dominates(InBlockLoc.get(), MBB4));
373 // While the other dominates the inner two blocks.
374 EXPECT_FALSE(LS.dominates(NotNestedBlockLoc.get(), MBB1));
375 EXPECT_TRUE(LS.dominates(NotNestedBlockLoc.get(), MBB2));
376 EXPECT_TRUE(LS.dominates(NotNestedBlockLoc.get(), MBB3));
377 EXPECT_FALSE(LS.dominates(NotNestedBlockLoc.get(), MBB4));
380 // Test getMachineBasicBlocks returns all dominated blocks.
381 TEST_F(LexicalScopesTest, TestGetBlocks) {
382 BuildMI(*MBB1, MBB1->end(), InBlockLoc, BeanInst);
383 BuildMI(*MBB2, MBB2->end(), NotNestedBlockLoc, BeanInst);
384 BuildMI(*MBB3, MBB3->end(), NotNestedBlockLoc, BeanInst);
385 BuildMI(*MBB4, MBB4->end(), InBlockLoc, BeanInst);
387 LexicalScopes LS;
388 LS.initialize(*MF);
389 LexicalScope *FuncScope = LS.getCurrentFunctionScope();
390 LexicalScope *BlockScope = LS.findLexicalScope(InBlockLoc.get());
391 LexicalScope *OtherBlockScope = LS.findLexicalScope(NotNestedBlockLoc.get());
392 ASSERT_NE(FuncScope, nullptr);
393 ASSERT_NE(BlockScope, nullptr);
394 ASSERT_NE(OtherBlockScope, nullptr);
396 SmallPtrSet<const MachineBasicBlock *, 4> OutermostBlocks, InBlockBlocks,
397 NotNestedBlockBlocks;
398 LS.getMachineBasicBlocks(OutermostLoc.get(), OutermostBlocks);
399 LS.getMachineBasicBlocks(InBlockLoc.get(), InBlockBlocks);
400 LS.getMachineBasicBlocks(NotNestedBlockLoc.get(), NotNestedBlockBlocks);
402 EXPECT_EQ(OutermostBlocks.count(MBB1), 1u);
403 EXPECT_EQ(OutermostBlocks.count(MBB2), 1u);
404 EXPECT_EQ(OutermostBlocks.count(MBB3), 1u);
405 EXPECT_EQ(OutermostBlocks.count(MBB4), 1u);
407 EXPECT_EQ(InBlockBlocks.count(MBB1), 1u);
408 EXPECT_EQ(InBlockBlocks.count(MBB2), 0u);
409 EXPECT_EQ(InBlockBlocks.count(MBB3), 0u);
410 EXPECT_EQ(InBlockBlocks.count(MBB4), 1u);
412 EXPECT_EQ(NotNestedBlockBlocks.count(MBB1), 0u);
413 EXPECT_EQ(NotNestedBlockBlocks.count(MBB2), 1u);
414 EXPECT_EQ(NotNestedBlockBlocks.count(MBB3), 1u);
415 EXPECT_EQ(NotNestedBlockBlocks.count(MBB4), 0u);
418 TEST_F(LexicalScopesTest, TestMetaInst) {
419 // Instruction Layout looks like this, where 'F' means funcscope, and
420 // 'B' blockscope:
421 // bb1:
422 // F: bean
423 // B: bean
424 // bb2:
425 // F: bean
426 // B: DBG_VALUE
427 // bb3:
428 // F: bean
429 // B: DBG_VALUE
430 // bb4:
431 // F: bean
432 // B: bean
433 // The block / 'B' should only dominate bb1 and bb4. DBG_VALUE is a meta
434 // instruction, and shouldn't contribute to scopes.
435 BuildMI(*MBB1, MBB1->end(), OutermostLoc, BeanInst);
436 BuildMI(*MBB1, MBB1->end(), InBlockLoc, BeanInst);
437 BuildMI(*MBB2, MBB2->end(), OutermostLoc, BeanInst);
438 BuildMI(*MBB2, MBB2->end(), InBlockLoc, DbgValueInst);
439 BuildMI(*MBB3, MBB3->end(), OutermostLoc, BeanInst);
440 BuildMI(*MBB3, MBB3->end(), InBlockLoc, DbgValueInst);
441 BuildMI(*MBB4, MBB4->end(), OutermostLoc, BeanInst);
442 BuildMI(*MBB4, MBB4->end(), InBlockLoc, BeanInst);
444 LexicalScopes LS;
445 LS.initialize(*MF);
446 LexicalScope *FuncScope = LS.getCurrentFunctionScope();
447 LexicalScope *BlockScope = LS.findLexicalScope(InBlockLoc.get());
448 ASSERT_NE(FuncScope, nullptr);
449 ASSERT_NE(BlockScope, nullptr);
451 EXPECT_TRUE(LS.dominates(OutermostLoc.get(), MBB1));
452 EXPECT_TRUE(LS.dominates(OutermostLoc.get(), MBB2));
453 EXPECT_TRUE(LS.dominates(OutermostLoc.get(), MBB3));
454 EXPECT_TRUE(LS.dominates(OutermostLoc.get(), MBB4));
455 EXPECT_TRUE(LS.dominates(InBlockLoc.get(), MBB1));
456 EXPECT_FALSE(LS.dominates(InBlockLoc.get(), MBB2));
457 EXPECT_FALSE(LS.dominates(InBlockLoc.get(), MBB3));
458 EXPECT_TRUE(LS.dominates(InBlockLoc.get(), MBB4));
461 } // anonymous namespace