//===- MachineBasicBlockTest.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/CodeGenTargetMachineImpl.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/TargetFrameLowering.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetLowering.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/DIBuilder.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Module.h" #include "llvm/MC/TargetRegistry.h" #include "gmock/gmock.h" #include "gtest/gtest.h" using namespace llvm; namespace { // Include helper functions to ease the manipulation of MachineFunctions. #include "MFCommon.inc" TEST(FindDebugLocTest, DifferentIterators) { LLVMContext Ctx; Module Mod("Module", Ctx); auto MF = createMachineFunction(Ctx, Mod); auto &MBB = *MF->CreateMachineBasicBlock(); // Create metadata: CU, subprogram, some blocks and an inline function // scope. DIBuilder DIB(Mod); DIFile *OurFile = DIB.createFile("foo.c", "/bar"); DICompileUnit *OurCU = DIB.createCompileUnit(dwarf::DW_LANG_C99, OurFile, "", false, "", 0); auto OurSubT = DIB.createSubroutineType(DIB.getOrCreateTypeArray({})); DISubprogram *OurFunc = DIB.createFunction(OurCU, "bees", "", OurFile, 1, OurSubT, 1, DINode::FlagZero, DISubprogram::SPFlagDefinition); DebugLoc DL0; DebugLoc DL1 = DILocation::get(Ctx, 1, 0, OurFunc); DebugLoc DL2 = DILocation::get(Ctx, 2, 0, OurFunc); DebugLoc DL3 = DILocation::get(Ctx, 3, 0, OurFunc); // Test using and empty MBB. EXPECT_EQ(DL0, MBB.findDebugLoc(MBB.instr_begin())); EXPECT_EQ(DL0, MBB.findDebugLoc(MBB.instr_end())); EXPECT_EQ(DL0, MBB.rfindDebugLoc(MBB.instr_rbegin())); EXPECT_EQ(DL0, MBB.rfindDebugLoc(MBB.instr_rend())); EXPECT_EQ(DL0, MBB.findPrevDebugLoc(MBB.instr_begin())); EXPECT_EQ(DL0, MBB.findPrevDebugLoc(MBB.instr_end())); EXPECT_EQ(DL0, MBB.rfindPrevDebugLoc(MBB.instr_rbegin())); EXPECT_EQ(DL0, MBB.rfindPrevDebugLoc(MBB.instr_rend())); // Insert two MIs with DebugLoc DL1 and DL3. // Also add a DBG_VALUE with a different DebugLoc in between. MCInstrDesc COPY = {TargetOpcode::COPY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; MCInstrDesc DBG = {TargetOpcode::DBG_VALUE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; auto MI3 = MF->CreateMachineInstr(COPY, DL3); MBB.insert(MBB.begin(), MI3); auto MI2 = MF->CreateMachineInstr(DBG, DL2); MBB.insert(MBB.begin(), MI2); auto MI1 = MF->CreateMachineInstr(COPY, DL1); MBB.insert(MBB.begin(), MI1); // Test using two MIs with a debug instruction in between. EXPECT_EQ(DL1, MBB.findDebugLoc(MBB.instr_begin())); EXPECT_EQ(DL1, MBB.findDebugLoc(MI1)); EXPECT_EQ(DL3, MBB.findDebugLoc(MI2)); EXPECT_EQ(DL3, MBB.findDebugLoc(MI3)); EXPECT_EQ(DL0, MBB.findDebugLoc(MBB.instr_end())); EXPECT_EQ(DL1, MBB.rfindDebugLoc(MBB.instr_rend())); EXPECT_EQ(DL1, MBB.rfindDebugLoc(MI1)); EXPECT_EQ(DL3, MBB.rfindDebugLoc(MI2)); EXPECT_EQ(DL3, MBB.rfindDebugLoc(MI3)); EXPECT_EQ(DL3, MBB.rfindDebugLoc(MBB.instr_rbegin())); EXPECT_EQ(DL0, MBB.findPrevDebugLoc(MBB.instr_begin())); EXPECT_EQ(DL0, MBB.findPrevDebugLoc(MI1)); EXPECT_EQ(DL1, MBB.findPrevDebugLoc(MI2)); EXPECT_EQ(DL1, MBB.findPrevDebugLoc(MI3)); EXPECT_EQ(DL3, MBB.findPrevDebugLoc(MBB.instr_end())); EXPECT_EQ(DL0, MBB.rfindPrevDebugLoc(MBB.instr_rend())); EXPECT_EQ(DL0, MBB.rfindPrevDebugLoc(MI1)); EXPECT_EQ(DL1, MBB.rfindPrevDebugLoc(MI2)); EXPECT_EQ(DL1, MBB.rfindPrevDebugLoc(MI3)); EXPECT_EQ(DL1, MBB.rfindPrevDebugLoc(MBB.instr_rbegin())); // Finalize DIBuilder to avoid memory leaks. DIB.finalize(); } } // end namespace