MachineInstrTest.cpp 11 KB

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