brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.5 KiB · 0c6b932 Raw
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