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