1 //===- MachineInstrTest.cpp -----------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/CodeGen/MachineInstr.h" 11 #include "llvm/CodeGen/MachineInstrBuilder.h" 12 #include "llvm/CodeGen/MachineFunction.h" 13 #include "llvm/CodeGen/MachineModuleInfo.h" 14 #include "llvm/CodeGen/TargetFrameLowering.h" 15 #include "llvm/CodeGen/TargetInstrInfo.h" 16 #include "llvm/CodeGen/TargetLowering.h" 17 #include "llvm/CodeGen/TargetSubtargetInfo.h" 18 #include "llvm/Support/TargetRegistry.h" 19 #include "llvm/Support/TargetSelect.h" 20 #include "llvm/Target/TargetMachine.h" 21 #include "llvm/Target/TargetOptions.h" 22 #include "gtest/gtest.h" 23 24 using namespace llvm; 25 26 namespace { 27 // Add a few Bogus backend classes so we can create MachineInstrs without 28 // depending on a real target. 29 class BogusTargetLowering : public TargetLowering { 30 public: 31 BogusTargetLowering(TargetMachine &TM) : TargetLowering(TM) {} 32 }; 33 34 class BogusFrameLowering : public TargetFrameLowering { 35 public: 36 BogusFrameLowering() 37 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 4, 4) {} 38 39 void emitPrologue(MachineFunction &MF, 40 MachineBasicBlock &MBB) const override {} 41 void emitEpilogue(MachineFunction &MF, 42 MachineBasicBlock &MBB) const override {} 43 bool hasFP(const MachineFunction &MF) const override { return false; } 44 }; 45 46 class BogusSubtarget : public TargetSubtargetInfo { 47 public: 48 BogusSubtarget(TargetMachine &TM) 49 : TargetSubtargetInfo(Triple(""), "", "", {}, {}, nullptr, nullptr, 50 nullptr, nullptr, nullptr, nullptr, nullptr), 51 FL(), TL(TM) {} 52 ~BogusSubtarget() override {} 53 54 const TargetFrameLowering *getFrameLowering() const override { return &FL; } 55 56 const TargetLowering *getTargetLowering() const override { return &TL; } 57 58 const TargetInstrInfo *getInstrInfo() const override { return &TII; } 59 60 private: 61 BogusFrameLowering FL; 62 BogusTargetLowering TL; 63 TargetInstrInfo TII; 64 }; 65 66 class BogusTargetMachine : public LLVMTargetMachine { 67 public: 68 BogusTargetMachine() 69 : LLVMTargetMachine(Target(), "", Triple(""), "", "", TargetOptions(), 70 Reloc::Static, CodeModel::Small, CodeGenOpt::Default), 71 ST(*this) {} 72 ~BogusTargetMachine() override {} 73 74 const TargetSubtargetInfo *getSubtargetImpl(const Function &) const override { 75 return &ST; 76 } 77 78 private: 79 BogusSubtarget ST; 80 }; 81 82 std::unique_ptr<BogusTargetMachine> createTargetMachine() { 83 return llvm::make_unique<BogusTargetMachine>(); 84 } 85 86 std::unique_ptr<MachineFunction> createMachineFunction() { 87 LLVMContext Ctx; 88 Module M("Module", Ctx); 89 auto Type = FunctionType::get(Type::getVoidTy(Ctx), false); 90 auto F = Function::Create(Type, GlobalValue::ExternalLinkage, "Test", &M); 91 92 auto TM = createTargetMachine(); 93 unsigned FunctionNum = 42; 94 MachineModuleInfo MMI(TM.get()); 95 const TargetSubtargetInfo &STI = *TM->getSubtargetImpl(*F); 96 97 return llvm::make_unique<MachineFunction>(*F, *TM, STI, FunctionNum, MMI); 98 } 99 100 // This test makes sure that MachineInstr::isIdenticalTo handles Defs correctly 101 // for various combinations of IgnoreDefs, and also that it is symmetrical. 102 TEST(IsIdenticalToTest, DifferentDefs) { 103 auto MF = createMachineFunction(); 104 105 unsigned short NumOps = 2; 106 unsigned char NumDefs = 1; 107 MCOperandInfo OpInfo[] = { 108 {0, 0, MCOI::OPERAND_REGISTER, 0}, 109 {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}}; 110 MCInstrDesc MCID = { 111 0, NumOps, NumDefs, 0, 0, 1ULL << MCID::HasOptionalDef, 112 0, nullptr, nullptr, OpInfo, 0, nullptr}; 113 114 // Create two MIs with different virtual reg defs and the same uses. 115 unsigned VirtualDef1 = -42; // The value doesn't matter, but the sign does. 116 unsigned VirtualDef2 = -43; 117 unsigned VirtualUse = -44; 118 119 auto MI1 = MF->CreateMachineInstr(MCID, DebugLoc()); 120 MI1->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true)); 121 MI1->addOperand(*MF, MachineOperand::CreateReg(VirtualUse, /*isDef*/ false)); 122 123 auto MI2 = MF->CreateMachineInstr(MCID, DebugLoc()); 124 MI2->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true)); 125 MI2->addOperand(*MF, MachineOperand::CreateReg(VirtualUse, /*isDef*/ false)); 126 127 // Check that they are identical when we ignore virtual register defs, but not 128 // when we check defs. 129 ASSERT_FALSE(MI1->isIdenticalTo(*MI2, MachineInstr::CheckDefs)); 130 ASSERT_FALSE(MI2->isIdenticalTo(*MI1, MachineInstr::CheckDefs)); 131 132 ASSERT_TRUE(MI1->isIdenticalTo(*MI2, MachineInstr::IgnoreVRegDefs)); 133 ASSERT_TRUE(MI2->isIdenticalTo(*MI1, MachineInstr::IgnoreVRegDefs)); 134 135 // Create two MIs with different virtual reg defs, and a def or use of a 136 // sentinel register. 137 unsigned SentinelReg = 0; 138 139 auto MI3 = MF->CreateMachineInstr(MCID, DebugLoc()); 140 MI3->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true)); 141 MI3->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ true)); 142 143 auto MI4 = MF->CreateMachineInstr(MCID, DebugLoc()); 144 MI4->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true)); 145 MI4->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ false)); 146 147 // Check that they are never identical. 148 ASSERT_FALSE(MI3->isIdenticalTo(*MI4, MachineInstr::CheckDefs)); 149 ASSERT_FALSE(MI4->isIdenticalTo(*MI3, MachineInstr::CheckDefs)); 150 151 ASSERT_FALSE(MI3->isIdenticalTo(*MI4, MachineInstr::IgnoreVRegDefs)); 152 ASSERT_FALSE(MI4->isIdenticalTo(*MI3, MachineInstr::IgnoreVRegDefs)); 153 } 154 155 // Check that MachineInstrExpressionTrait::isEqual is symmetric and in sync with 156 // MachineInstrExpressionTrait::getHashValue 157 void checkHashAndIsEqualMatch(MachineInstr *MI1, MachineInstr *MI2) { 158 bool IsEqual1 = MachineInstrExpressionTrait::isEqual(MI1, MI2); 159 bool IsEqual2 = MachineInstrExpressionTrait::isEqual(MI2, MI1); 160 161 ASSERT_EQ(IsEqual1, IsEqual2); 162 163 auto Hash1 = MachineInstrExpressionTrait::getHashValue(MI1); 164 auto Hash2 = MachineInstrExpressionTrait::getHashValue(MI2); 165 166 ASSERT_EQ(IsEqual1, Hash1 == Hash2); 167 } 168 169 // This test makes sure that MachineInstrExpressionTraits::isEqual is in sync 170 // with MachineInstrExpressionTraits::getHashValue. 171 TEST(MachineInstrExpressionTraitTest, IsEqualAgreesWithGetHashValue) { 172 auto MF = createMachineFunction(); 173 174 unsigned short NumOps = 2; 175 unsigned char NumDefs = 1; 176 MCOperandInfo OpInfo[] = { 177 {0, 0, MCOI::OPERAND_REGISTER, 0}, 178 {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}}; 179 MCInstrDesc MCID = { 180 0, NumOps, NumDefs, 0, 0, 1ULL << MCID::HasOptionalDef, 181 0, nullptr, nullptr, OpInfo, 0, nullptr}; 182 183 // Define a series of instructions with different kinds of operands and make 184 // sure that the hash function is consistent with isEqual for various 185 // combinations of them. 186 unsigned VirtualDef1 = -42; 187 unsigned VirtualDef2 = -43; 188 unsigned VirtualReg = -44; 189 unsigned SentinelReg = 0; 190 unsigned PhysicalReg = 45; 191 192 auto VD1VU = MF->CreateMachineInstr(MCID, DebugLoc()); 193 VD1VU->addOperand(*MF, 194 MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true)); 195 VD1VU->addOperand(*MF, 196 MachineOperand::CreateReg(VirtualReg, /*isDef*/ false)); 197 198 auto VD2VU = MF->CreateMachineInstr(MCID, DebugLoc()); 199 VD2VU->addOperand(*MF, 200 MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true)); 201 VD2VU->addOperand(*MF, 202 MachineOperand::CreateReg(VirtualReg, /*isDef*/ false)); 203 204 auto VD1SU = MF->CreateMachineInstr(MCID, DebugLoc()); 205 VD1SU->addOperand(*MF, 206 MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true)); 207 VD1SU->addOperand(*MF, 208 MachineOperand::CreateReg(SentinelReg, /*isDef*/ false)); 209 210 auto VD1SD = MF->CreateMachineInstr(MCID, DebugLoc()); 211 VD1SD->addOperand(*MF, 212 MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true)); 213 VD1SD->addOperand(*MF, 214 MachineOperand::CreateReg(SentinelReg, /*isDef*/ true)); 215 216 auto VD2PU = MF->CreateMachineInstr(MCID, DebugLoc()); 217 VD2PU->addOperand(*MF, 218 MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true)); 219 VD2PU->addOperand(*MF, 220 MachineOperand::CreateReg(PhysicalReg, /*isDef*/ false)); 221 222 auto VD2PD = MF->CreateMachineInstr(MCID, DebugLoc()); 223 VD2PD->addOperand(*MF, 224 MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true)); 225 VD2PD->addOperand(*MF, 226 MachineOperand::CreateReg(PhysicalReg, /*isDef*/ true)); 227 228 checkHashAndIsEqualMatch(VD1VU, VD2VU); 229 checkHashAndIsEqualMatch(VD1VU, VD1SU); 230 checkHashAndIsEqualMatch(VD1VU, VD1SD); 231 checkHashAndIsEqualMatch(VD1VU, VD2PU); 232 checkHashAndIsEqualMatch(VD1VU, VD2PD); 233 234 checkHashAndIsEqualMatch(VD2VU, VD1SU); 235 checkHashAndIsEqualMatch(VD2VU, VD1SD); 236 checkHashAndIsEqualMatch(VD2VU, VD2PU); 237 checkHashAndIsEqualMatch(VD2VU, VD2PD); 238 239 checkHashAndIsEqualMatch(VD1SU, VD1SD); 240 checkHashAndIsEqualMatch(VD1SU, VD2PU); 241 checkHashAndIsEqualMatch(VD1SU, VD2PD); 242 243 checkHashAndIsEqualMatch(VD1SD, VD2PU); 244 checkHashAndIsEqualMatch(VD1SD, VD2PD); 245 246 checkHashAndIsEqualMatch(VD2PU, VD2PD); 247 } 248 249 TEST(MachineBasicBlockTest, PhiRange) { 250 auto MF = createMachineFunction(); 251 252 // Create the main block. 253 auto BB = MF->CreateMachineBasicBlock(); 254 255 // Create some predecessors of it. 256 auto BB1 = MF->CreateMachineBasicBlock(); 257 BB1->addSuccessor(BB); 258 auto BB2 = MF->CreateMachineBasicBlock(); 259 BB2->addSuccessor(BB); 260 261 // Make sure this doesn't crash if there are no phis. 262 for (auto &PN : BB->phis()) { 263 (void)PN; 264 ASSERT_TRUE(false) << "empty block should have no phis"; 265 } 266 267 // Make it a cycle. 268 BB->addSuccessor(BB); 269 270 // Now insert some PHI nodes. 271 MCOperandInfo OpInfo[] = { { -1, 0, MCOI::OPERAND_UNKNOWN, 0} }; 272 MCInstrDesc PHIMCID = { 273 TargetOpcode::PHI, 1, 1, 0, 0, 274 (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic), 0, 275 nullptr, nullptr, OpInfo, -1, nullptr}; 276 auto P1 = BuildMI(*BB, BB->end(), DebugLoc(), PHIMCID, -101); 277 auto P2 = BuildMI(*BB, BB->end(), DebugLoc(), PHIMCID, -102); 278 auto P3 = BuildMI(*BB, BB->end(), DebugLoc(), PHIMCID, -103); 279 280 // A non-PHI node. 281 MCInstrDesc ImpDefMCID = { 282 TargetOpcode::IMPLICIT_DEF, 1, 1, 0, 0, 283 (1ULL << MCID::Pseudo), 0, 284 nullptr, nullptr, OpInfo, -1, nullptr}; 285 BuildMI(*BB, BB->end(), DebugLoc(), ImpDefMCID, -104); 286 287 // Now wire up the incoming values that are interesting. 288 P1.addReg(-102).addMBB(BB); 289 P2.addReg(-101).addMBB(BB); 290 P3.addReg(-104).addMBB(BB); 291 292 // Finally, let's iterate them, which is the thing we're trying to test. 293 // We'll use this to wire up the rest of the incoming values. 294 for (auto &PN : BB->phis()) { 295 EXPECT_TRUE(PN.isPHI()); 296 PN.addOperand(*MF, MachineOperand::CreateReg(-100, /*isDef*/ false)); 297 PN.addOperand(*MF, MachineOperand::CreateMBB(BB1)); 298 PN.addOperand(*MF, MachineOperand::CreateReg(-100, /*isDef*/ false)); 299 PN.addOperand(*MF, MachineOperand::CreateMBB(BB2)); 300 } 301 302 // Test that we can use const iterators and generally that the iterators 303 // behave like iterators. 304 MachineBasicBlock::const_iterator CI; 305 CI = BB->phis().begin(); 306 EXPECT_NE(CI, BB->phis().end()); 307 308 // And iterate a const range. 309 for (const auto &PN : const_cast<const MachineBasicBlock *>(BB)->phis()) { 310 EXPECT_EQ(BB, PN.getOperand(2).getMBB()); 311 EXPECT_EQ(BB1, PN.getOperand(4).getMBB()); 312 EXPECT_EQ(BB2, PN.getOperand(6).getMBB()); 313 } 314 } 315 } // end namespace 316