MachineInstrTest.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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. #include "llvm/CodeGen/MachineInstr.h"
  10. #include "llvm/CodeGen/MachineFunction.h"
  11. #include "llvm/CodeGen/MachineModuleInfo.h"
  12. #include "llvm/CodeGen/TargetFrameLowering.h"
  13. #include "llvm/CodeGen/TargetInstrInfo.h"
  14. #include "llvm/CodeGen/TargetLowering.h"
  15. #include "llvm/CodeGen/TargetSubtargetInfo.h"
  16. #include "llvm/IR/DebugInfoMetadata.h"
  17. #include "llvm/IR/ModuleSlotTracker.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. using namespace llvm;
  24. namespace {
  25. // Add a few Bogus backend classes so we can create MachineInstrs without
  26. // depending on a real target.
  27. class BogusTargetLowering : public TargetLowering {
  28. public:
  29. BogusTargetLowering(TargetMachine &TM) : TargetLowering(TM) {}
  30. };
  31. class BogusFrameLowering : public TargetFrameLowering {
  32. public:
  33. BogusFrameLowering()
  34. : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 4, 4) {}
  35. void emitPrologue(MachineFunction &MF,
  36. MachineBasicBlock &MBB) const override {}
  37. void emitEpilogue(MachineFunction &MF,
  38. MachineBasicBlock &MBB) const override {}
  39. bool hasFP(const MachineFunction &MF) const override { return false; }
  40. };
  41. class BogusSubtarget : public TargetSubtargetInfo {
  42. public:
  43. BogusSubtarget(TargetMachine &TM)
  44. : TargetSubtargetInfo(Triple(""), "", "", {}, {}, nullptr, nullptr,
  45. nullptr, nullptr, nullptr, nullptr, nullptr),
  46. FL(), TL(TM) {}
  47. ~BogusSubtarget() override {}
  48. const TargetFrameLowering *getFrameLowering() const override { return &FL; }
  49. const TargetLowering *getTargetLowering() const override { return &TL; }
  50. const TargetInstrInfo *getInstrInfo() const override { return &TII; }
  51. private:
  52. BogusFrameLowering FL;
  53. BogusTargetLowering TL;
  54. TargetInstrInfo TII;
  55. };
  56. class BogusTargetMachine : public LLVMTargetMachine {
  57. public:
  58. BogusTargetMachine()
  59. : LLVMTargetMachine(Target(), "", Triple(""), "", "", TargetOptions(),
  60. Reloc::Static, CodeModel::Small, CodeGenOpt::Default),
  61. ST(*this) {}
  62. ~BogusTargetMachine() override {}
  63. const TargetSubtargetInfo *getSubtargetImpl(const Function &) const override {
  64. return &ST;
  65. }
  66. private:
  67. BogusSubtarget ST;
  68. };
  69. std::unique_ptr<BogusTargetMachine> createTargetMachine() {
  70. return llvm::make_unique<BogusTargetMachine>();
  71. }
  72. std::unique_ptr<MachineFunction> createMachineFunction() {
  73. LLVMContext Ctx;
  74. Module M("Module", Ctx);
  75. auto Type = FunctionType::get(Type::getVoidTy(Ctx), false);
  76. auto F = Function::Create(Type, GlobalValue::ExternalLinkage, "Test", &M);
  77. auto TM = createTargetMachine();
  78. unsigned FunctionNum = 42;
  79. MachineModuleInfo MMI(TM.get());
  80. const TargetSubtargetInfo &STI = *TM->getSubtargetImpl(*F);
  81. return llvm::make_unique<MachineFunction>(*F, *TM, STI, FunctionNum, MMI);
  82. }
  83. // This test makes sure that MachineInstr::isIdenticalTo handles Defs correctly
  84. // for various combinations of IgnoreDefs, and also that it is symmetrical.
  85. TEST(IsIdenticalToTest, DifferentDefs) {
  86. auto MF = createMachineFunction();
  87. unsigned short NumOps = 2;
  88. unsigned char NumDefs = 1;
  89. MCOperandInfo OpInfo[] = {
  90. {0, 0, MCOI::OPERAND_REGISTER, 0},
  91. {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}};
  92. MCInstrDesc MCID = {
  93. 0, NumOps, NumDefs, 0, 0, 1ULL << MCID::HasOptionalDef,
  94. 0, nullptr, nullptr, OpInfo, 0, nullptr};
  95. // Create two MIs with different virtual reg defs and the same uses.
  96. unsigned VirtualDef1 = -42; // The value doesn't matter, but the sign does.
  97. unsigned VirtualDef2 = -43;
  98. unsigned VirtualUse = -44;
  99. auto MI1 = MF->CreateMachineInstr(MCID, DebugLoc());
  100. MI1->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
  101. MI1->addOperand(*MF, MachineOperand::CreateReg(VirtualUse, /*isDef*/ false));
  102. auto MI2 = MF->CreateMachineInstr(MCID, DebugLoc());
  103. MI2->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
  104. MI2->addOperand(*MF, MachineOperand::CreateReg(VirtualUse, /*isDef*/ false));
  105. // Check that they are identical when we ignore virtual register defs, but not
  106. // when we check defs.
  107. ASSERT_FALSE(MI1->isIdenticalTo(*MI2, MachineInstr::CheckDefs));
  108. ASSERT_FALSE(MI2->isIdenticalTo(*MI1, MachineInstr::CheckDefs));
  109. ASSERT_TRUE(MI1->isIdenticalTo(*MI2, MachineInstr::IgnoreVRegDefs));
  110. ASSERT_TRUE(MI2->isIdenticalTo(*MI1, MachineInstr::IgnoreVRegDefs));
  111. // Create two MIs with different virtual reg defs, and a def or use of a
  112. // sentinel register.
  113. unsigned SentinelReg = 0;
  114. auto MI3 = MF->CreateMachineInstr(MCID, DebugLoc());
  115. MI3->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
  116. MI3->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ true));
  117. auto MI4 = MF->CreateMachineInstr(MCID, DebugLoc());
  118. MI4->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
  119. MI4->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ false));
  120. // Check that they are never identical.
  121. ASSERT_FALSE(MI3->isIdenticalTo(*MI4, MachineInstr::CheckDefs));
  122. ASSERT_FALSE(MI4->isIdenticalTo(*MI3, MachineInstr::CheckDefs));
  123. ASSERT_FALSE(MI3->isIdenticalTo(*MI4, MachineInstr::IgnoreVRegDefs));
  124. ASSERT_FALSE(MI4->isIdenticalTo(*MI3, MachineInstr::IgnoreVRegDefs));
  125. }
  126. // Check that MachineInstrExpressionTrait::isEqual is symmetric and in sync with
  127. // MachineInstrExpressionTrait::getHashValue
  128. void checkHashAndIsEqualMatch(MachineInstr *MI1, MachineInstr *MI2) {
  129. bool IsEqual1 = MachineInstrExpressionTrait::isEqual(MI1, MI2);
  130. bool IsEqual2 = MachineInstrExpressionTrait::isEqual(MI2, MI1);
  131. ASSERT_EQ(IsEqual1, IsEqual2);
  132. auto Hash1 = MachineInstrExpressionTrait::getHashValue(MI1);
  133. auto Hash2 = MachineInstrExpressionTrait::getHashValue(MI2);
  134. ASSERT_EQ(IsEqual1, Hash1 == Hash2);
  135. }
  136. // This test makes sure that MachineInstrExpressionTraits::isEqual is in sync
  137. // with MachineInstrExpressionTraits::getHashValue.
  138. TEST(MachineInstrExpressionTraitTest, IsEqualAgreesWithGetHashValue) {
  139. auto MF = createMachineFunction();
  140. unsigned short NumOps = 2;
  141. unsigned char NumDefs = 1;
  142. MCOperandInfo OpInfo[] = {
  143. {0, 0, MCOI::OPERAND_REGISTER, 0},
  144. {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}};
  145. MCInstrDesc MCID = {
  146. 0, NumOps, NumDefs, 0, 0, 1ULL << MCID::HasOptionalDef,
  147. 0, nullptr, nullptr, OpInfo, 0, nullptr};
  148. // Define a series of instructions with different kinds of operands and make
  149. // sure that the hash function is consistent with isEqual for various
  150. // combinations of them.
  151. unsigned VirtualDef1 = -42;
  152. unsigned VirtualDef2 = -43;
  153. unsigned VirtualReg = -44;
  154. unsigned SentinelReg = 0;
  155. unsigned PhysicalReg = 45;
  156. auto VD1VU = MF->CreateMachineInstr(MCID, DebugLoc());
  157. VD1VU->addOperand(*MF,
  158. MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
  159. VD1VU->addOperand(*MF,
  160. MachineOperand::CreateReg(VirtualReg, /*isDef*/ false));
  161. auto VD2VU = MF->CreateMachineInstr(MCID, DebugLoc());
  162. VD2VU->addOperand(*MF,
  163. MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
  164. VD2VU->addOperand(*MF,
  165. MachineOperand::CreateReg(VirtualReg, /*isDef*/ false));
  166. auto VD1SU = MF->CreateMachineInstr(MCID, DebugLoc());
  167. VD1SU->addOperand(*MF,
  168. MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
  169. VD1SU->addOperand(*MF,
  170. MachineOperand::CreateReg(SentinelReg, /*isDef*/ false));
  171. auto VD1SD = MF->CreateMachineInstr(MCID, DebugLoc());
  172. VD1SD->addOperand(*MF,
  173. MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
  174. VD1SD->addOperand(*MF,
  175. MachineOperand::CreateReg(SentinelReg, /*isDef*/ true));
  176. auto VD2PU = MF->CreateMachineInstr(MCID, DebugLoc());
  177. VD2PU->addOperand(*MF,
  178. MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
  179. VD2PU->addOperand(*MF,
  180. MachineOperand::CreateReg(PhysicalReg, /*isDef*/ false));
  181. auto VD2PD = MF->CreateMachineInstr(MCID, DebugLoc());
  182. VD2PD->addOperand(*MF,
  183. MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
  184. VD2PD->addOperand(*MF,
  185. MachineOperand::CreateReg(PhysicalReg, /*isDef*/ true));
  186. checkHashAndIsEqualMatch(VD1VU, VD2VU);
  187. checkHashAndIsEqualMatch(VD1VU, VD1SU);
  188. checkHashAndIsEqualMatch(VD1VU, VD1SD);
  189. checkHashAndIsEqualMatch(VD1VU, VD2PU);
  190. checkHashAndIsEqualMatch(VD1VU, VD2PD);
  191. checkHashAndIsEqualMatch(VD2VU, VD1SU);
  192. checkHashAndIsEqualMatch(VD2VU, VD1SD);
  193. checkHashAndIsEqualMatch(VD2VU, VD2PU);
  194. checkHashAndIsEqualMatch(VD2VU, VD2PD);
  195. checkHashAndIsEqualMatch(VD1SU, VD1SD);
  196. checkHashAndIsEqualMatch(VD1SU, VD2PU);
  197. checkHashAndIsEqualMatch(VD1SU, VD2PD);
  198. checkHashAndIsEqualMatch(VD1SD, VD2PU);
  199. checkHashAndIsEqualMatch(VD1SD, VD2PD);
  200. checkHashAndIsEqualMatch(VD2PU, VD2PD);
  201. }
  202. TEST(MachineInstrPrintingTest, DebugLocPrinting) {
  203. auto MF = createMachineFunction();
  204. MCOperandInfo OpInfo{0, 0, MCOI::OPERAND_REGISTER, 0};
  205. MCInstrDesc MCID = {0, 1, 1, 0, 0, 0,
  206. 0, nullptr, nullptr, &OpInfo, 0, nullptr};
  207. LLVMContext Ctx;
  208. DILocation *DIL = DILocation::get(Ctx, 1, 5, (Metadata *)nullptr, nullptr);
  209. DebugLoc DL(DIL);
  210. MachineInstr *MI = MF->CreateMachineInstr(MCID, DL);
  211. MI->addOperand(*MF, MachineOperand::CreateReg(0, /*isDef*/ true));
  212. std::string str;
  213. raw_string_ostream OS(str);
  214. MI->print(OS);
  215. ASSERT_TRUE(
  216. StringRef(OS.str()).startswith("%noreg = UNKNOWN debug-location "));
  217. }
  218. } // end namespace