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