InstructionSelectorImpl.h 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h --------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. /// \file This file declares the API for the instruction selector.
  15. /// This class is responsible for selecting machine instructions.
  16. /// It's implemented by the target. It's used by the InstructionSelect pass.
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
  20. #define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
  21. #include "llvm/ADT/SmallVector.h"
  22. #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
  23. #include "llvm/CodeGen/GlobalISel/Utils.h"
  24. #include "llvm/CodeGen/MachineInstrBuilder.h"
  25. #include "llvm/CodeGen/MachineOperand.h"
  26. #include "llvm/CodeGen/MachineRegisterInfo.h"
  27. #include "llvm/CodeGen/RegisterBankInfo.h"
  28. #include "llvm/CodeGen/TargetInstrInfo.h"
  29. #include "llvm/CodeGen/TargetOpcodes.h"
  30. #include "llvm/CodeGen/TargetRegisterInfo.h"
  31. #include "llvm/IR/Constants.h"
  32. #include "llvm/IR/DataLayout.h"
  33. #include "llvm/Support/CodeGenCoverage.h"
  34. #include "llvm/Support/Debug.h"
  35. #include "llvm/Support/ErrorHandling.h"
  36. #include "llvm/Support/raw_ostream.h"
  37. #include <cassert>
  38. #include <cstddef>
  39. #include <cstdint>
  40. namespace llvm {
  41. /// GlobalISel PatFrag Predicates
  42. enum {
  43. GIPFP_I64_Invalid = 0,
  44. GIPFP_APInt_Invalid = 0,
  45. GIPFP_APFloat_Invalid = 0,
  46. GIPFP_MI_Invalid = 0,
  47. };
  48. template <class TgtInstructionSelector, class PredicateBitset,
  49. class ComplexMatcherMemFn, class CustomRendererFn>
  50. bool InstructionSelector::executeMatchTable(
  51. TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State,
  52. const ISelInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn>
  53. &ISelInfo,
  54. const int64_t *MatchTable, const TargetInstrInfo &TII,
  55. MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
  56. const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures,
  57. CodeGenCoverage &CoverageInfo) const {
  58. uint64_t CurrentIdx = 0;
  59. SmallVector<uint64_t, 4> OnFailResumeAt;
  60. // Bypass the flag check on the instruction, and only look at the MCInstrDesc.
  61. bool NoFPException = !State.MIs[0]->getDesc().mayRaiseFPException();
  62. const uint16_t Flags = State.MIs[0]->getFlags();
  63. enum RejectAction { RejectAndGiveUp, RejectAndResume };
  64. auto handleReject = [&]() -> RejectAction {
  65. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  66. dbgs() << CurrentIdx << ": Rejected\n");
  67. if (OnFailResumeAt.empty())
  68. return RejectAndGiveUp;
  69. CurrentIdx = OnFailResumeAt.pop_back_val();
  70. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  71. dbgs() << CurrentIdx << ": Resume at " << CurrentIdx << " ("
  72. << OnFailResumeAt.size() << " try-blocks remain)\n");
  73. return RejectAndResume;
  74. };
  75. auto propagateFlags = [=](NewMIVector &OutMIs) {
  76. for (auto MIB : OutMIs) {
  77. // Set the NoFPExcept flag when no original matched instruction could
  78. // raise an FP exception, but the new instruction potentially might.
  79. uint16_t MIBFlags = Flags;
  80. if (NoFPException && MIB->mayRaiseFPException())
  81. MIBFlags |= MachineInstr::NoFPExcept;
  82. MIB.setMIFlags(MIBFlags);
  83. }
  84. return true;
  85. };
  86. while (true) {
  87. assert(CurrentIdx != ~0u && "Invalid MatchTable index");
  88. int64_t MatcherOpcode = MatchTable[CurrentIdx++];
  89. switch (MatcherOpcode) {
  90. case GIM_Try: {
  91. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  92. dbgs() << CurrentIdx << ": Begin try-block\n");
  93. OnFailResumeAt.push_back(MatchTable[CurrentIdx++]);
  94. break;
  95. }
  96. case GIM_RecordInsn: {
  97. int64_t NewInsnID = MatchTable[CurrentIdx++];
  98. int64_t InsnID = MatchTable[CurrentIdx++];
  99. int64_t OpIdx = MatchTable[CurrentIdx++];
  100. // As an optimisation we require that MIs[0] is always the root. Refuse
  101. // any attempt to modify it.
  102. assert(NewInsnID != 0 && "Refusing to modify MIs[0]");
  103. MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
  104. if (!MO.isReg()) {
  105. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  106. dbgs() << CurrentIdx << ": Not a register\n");
  107. if (handleReject() == RejectAndGiveUp)
  108. return false;
  109. break;
  110. }
  111. if (MO.getReg().isPhysical()) {
  112. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  113. dbgs() << CurrentIdx << ": Is a physical register\n");
  114. if (handleReject() == RejectAndGiveUp)
  115. return false;
  116. break;
  117. }
  118. MachineInstr *NewMI = MRI.getVRegDef(MO.getReg());
  119. if ((size_t)NewInsnID < State.MIs.size())
  120. State.MIs[NewInsnID] = NewMI;
  121. else {
  122. assert((size_t)NewInsnID == State.MIs.size() &&
  123. "Expected to store MIs in order");
  124. State.MIs.push_back(NewMI);
  125. }
  126. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  127. dbgs() << CurrentIdx << ": MIs[" << NewInsnID
  128. << "] = GIM_RecordInsn(" << InsnID << ", " << OpIdx
  129. << ")\n");
  130. break;
  131. }
  132. case GIM_CheckFeatures: {
  133. int64_t ExpectedBitsetID = MatchTable[CurrentIdx++];
  134. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  135. dbgs() << CurrentIdx
  136. << ": GIM_CheckFeatures(ExpectedBitsetID="
  137. << ExpectedBitsetID << ")\n");
  138. if ((AvailableFeatures & ISelInfo.FeatureBitsets[ExpectedBitsetID]) !=
  139. ISelInfo.FeatureBitsets[ExpectedBitsetID]) {
  140. if (handleReject() == RejectAndGiveUp)
  141. return false;
  142. }
  143. break;
  144. }
  145. case GIM_CheckOpcode:
  146. case GIM_CheckOpcodeIsEither: {
  147. int64_t InsnID = MatchTable[CurrentIdx++];
  148. int64_t Expected0 = MatchTable[CurrentIdx++];
  149. int64_t Expected1 = -1;
  150. if (MatcherOpcode == GIM_CheckOpcodeIsEither)
  151. Expected1 = MatchTable[CurrentIdx++];
  152. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  153. unsigned Opcode = State.MIs[InsnID]->getOpcode();
  154. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  155. dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID
  156. << "], ExpectedOpcode=" << Expected0;
  157. if (MatcherOpcode == GIM_CheckOpcodeIsEither)
  158. dbgs() << " || " << Expected1;
  159. dbgs() << ") // Got=" << Opcode << "\n";
  160. );
  161. if (Opcode != Expected0 && Opcode != Expected1) {
  162. if (handleReject() == RejectAndGiveUp)
  163. return false;
  164. }
  165. break;
  166. }
  167. case GIM_SwitchOpcode: {
  168. int64_t InsnID = MatchTable[CurrentIdx++];
  169. int64_t LowerBound = MatchTable[CurrentIdx++];
  170. int64_t UpperBound = MatchTable[CurrentIdx++];
  171. int64_t Default = MatchTable[CurrentIdx++];
  172. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  173. const int64_t Opcode = State.MIs[InsnID]->getOpcode();
  174. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), {
  175. dbgs() << CurrentIdx << ": GIM_SwitchOpcode(MIs[" << InsnID << "], ["
  176. << LowerBound << ", " << UpperBound << "), Default=" << Default
  177. << ", JumpTable...) // Got=" << Opcode << "\n";
  178. });
  179. if (Opcode < LowerBound || UpperBound <= Opcode) {
  180. CurrentIdx = Default;
  181. break;
  182. }
  183. CurrentIdx = MatchTable[CurrentIdx + (Opcode - LowerBound)];
  184. if (!CurrentIdx) {
  185. CurrentIdx = Default;
  186. break;
  187. }
  188. OnFailResumeAt.push_back(Default);
  189. break;
  190. }
  191. case GIM_SwitchType: {
  192. int64_t InsnID = MatchTable[CurrentIdx++];
  193. int64_t OpIdx = MatchTable[CurrentIdx++];
  194. int64_t LowerBound = MatchTable[CurrentIdx++];
  195. int64_t UpperBound = MatchTable[CurrentIdx++];
  196. int64_t Default = MatchTable[CurrentIdx++];
  197. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  198. MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
  199. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), {
  200. dbgs() << CurrentIdx << ": GIM_SwitchType(MIs[" << InsnID
  201. << "]->getOperand(" << OpIdx << "), [" << LowerBound << ", "
  202. << UpperBound << "), Default=" << Default
  203. << ", JumpTable...) // Got=";
  204. if (!MO.isReg())
  205. dbgs() << "Not a VReg\n";
  206. else
  207. dbgs() << MRI.getType(MO.getReg()) << "\n";
  208. });
  209. if (!MO.isReg()) {
  210. CurrentIdx = Default;
  211. break;
  212. }
  213. const LLT Ty = MRI.getType(MO.getReg());
  214. const auto TyI = ISelInfo.TypeIDMap.find(Ty);
  215. if (TyI == ISelInfo.TypeIDMap.end()) {
  216. CurrentIdx = Default;
  217. break;
  218. }
  219. const int64_t TypeID = TyI->second;
  220. if (TypeID < LowerBound || UpperBound <= TypeID) {
  221. CurrentIdx = Default;
  222. break;
  223. }
  224. CurrentIdx = MatchTable[CurrentIdx + (TypeID - LowerBound)];
  225. if (!CurrentIdx) {
  226. CurrentIdx = Default;
  227. break;
  228. }
  229. OnFailResumeAt.push_back(Default);
  230. break;
  231. }
  232. case GIM_CheckNumOperands: {
  233. int64_t InsnID = MatchTable[CurrentIdx++];
  234. int64_t Expected = MatchTable[CurrentIdx++];
  235. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  236. dbgs() << CurrentIdx << ": GIM_CheckNumOperands(MIs["
  237. << InsnID << "], Expected=" << Expected << ")\n");
  238. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  239. if (State.MIs[InsnID]->getNumOperands() != Expected) {
  240. if (handleReject() == RejectAndGiveUp)
  241. return false;
  242. }
  243. break;
  244. }
  245. case GIM_CheckI64ImmPredicate:
  246. case GIM_CheckImmOperandPredicate: {
  247. int64_t InsnID = MatchTable[CurrentIdx++];
  248. int64_t OpIdx = MatcherOpcode == GIM_CheckImmOperandPredicate
  249. ? MatchTable[CurrentIdx++]
  250. : 1;
  251. int64_t Predicate = MatchTable[CurrentIdx++];
  252. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  253. dbgs() << CurrentIdx << ": GIM_CheckImmPredicate(MIs["
  254. << InsnID << "]->getOperand(" << OpIdx
  255. << "), Predicate=" << Predicate << ")\n");
  256. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  257. assert((State.MIs[InsnID]->getOperand(OpIdx).isImm() ||
  258. State.MIs[InsnID]->getOperand(OpIdx).isCImm()) &&
  259. "Expected immediate operand");
  260. assert(Predicate > GIPFP_I64_Invalid && "Expected a valid predicate");
  261. int64_t Value = 0;
  262. if (State.MIs[InsnID]->getOperand(OpIdx).isCImm())
  263. Value = State.MIs[InsnID]->getOperand(OpIdx).getCImm()->getSExtValue();
  264. else if (State.MIs[InsnID]->getOperand(OpIdx).isImm())
  265. Value = State.MIs[InsnID]->getOperand(OpIdx).getImm();
  266. else
  267. llvm_unreachable("Expected Imm or CImm operand");
  268. if (!testImmPredicate_I64(Predicate, Value))
  269. if (handleReject() == RejectAndGiveUp)
  270. return false;
  271. break;
  272. }
  273. case GIM_CheckAPIntImmPredicate: {
  274. int64_t InsnID = MatchTable[CurrentIdx++];
  275. int64_t Predicate = MatchTable[CurrentIdx++];
  276. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  277. dbgs()
  278. << CurrentIdx << ": GIM_CheckAPIntImmPredicate(MIs["
  279. << InsnID << "], Predicate=" << Predicate << ")\n");
  280. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  281. assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
  282. "Expected G_CONSTANT");
  283. assert(Predicate > GIPFP_APInt_Invalid && "Expected a valid predicate");
  284. APInt Value;
  285. if (State.MIs[InsnID]->getOperand(1).isCImm())
  286. Value = State.MIs[InsnID]->getOperand(1).getCImm()->getValue();
  287. else
  288. llvm_unreachable("Expected Imm or CImm operand");
  289. if (!testImmPredicate_APInt(Predicate, Value))
  290. if (handleReject() == RejectAndGiveUp)
  291. return false;
  292. break;
  293. }
  294. case GIM_CheckAPFloatImmPredicate: {
  295. int64_t InsnID = MatchTable[CurrentIdx++];
  296. int64_t Predicate = MatchTable[CurrentIdx++];
  297. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  298. dbgs()
  299. << CurrentIdx << ": GIM_CheckAPFloatImmPredicate(MIs["
  300. << InsnID << "], Predicate=" << Predicate << ")\n");
  301. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  302. assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
  303. "Expected G_FCONSTANT");
  304. assert(State.MIs[InsnID]->getOperand(1).isFPImm() && "Expected FPImm operand");
  305. assert(Predicate > GIPFP_APFloat_Invalid && "Expected a valid predicate");
  306. APFloat Value = State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
  307. if (!testImmPredicate_APFloat(Predicate, Value))
  308. if (handleReject() == RejectAndGiveUp)
  309. return false;
  310. break;
  311. }
  312. case GIM_CheckIsBuildVectorAllOnes:
  313. case GIM_CheckIsBuildVectorAllZeros: {
  314. int64_t InsnID = MatchTable[CurrentIdx++];
  315. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  316. dbgs() << CurrentIdx
  317. << ": GIM_CheckBuildVectorAll{Zeros|Ones}(MIs["
  318. << InsnID << "])\n");
  319. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  320. const MachineInstr *MI = State.MIs[InsnID];
  321. assert((MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR ||
  322. MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC) &&
  323. "Expected G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC");
  324. if (MatcherOpcode == GIM_CheckIsBuildVectorAllOnes) {
  325. if (!isBuildVectorAllOnes(*MI, MRI)) {
  326. if (handleReject() == RejectAndGiveUp)
  327. return false;
  328. }
  329. } else {
  330. if (!isBuildVectorAllZeros(*MI, MRI)) {
  331. if (handleReject() == RejectAndGiveUp)
  332. return false;
  333. }
  334. }
  335. break;
  336. }
  337. case GIM_CheckCxxInsnPredicate: {
  338. int64_t InsnID = MatchTable[CurrentIdx++];
  339. int64_t Predicate = MatchTable[CurrentIdx++];
  340. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  341. dbgs()
  342. << CurrentIdx << ": GIM_CheckCxxPredicate(MIs["
  343. << InsnID << "], Predicate=" << Predicate << ")\n");
  344. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  345. assert(Predicate > GIPFP_MI_Invalid && "Expected a valid predicate");
  346. if (!testMIPredicate_MI(Predicate, *State.MIs[InsnID],
  347. State.RecordedOperands))
  348. if (handleReject() == RejectAndGiveUp)
  349. return false;
  350. break;
  351. }
  352. case GIM_CheckHasNoUse: {
  353. int64_t InsnID = MatchTable[CurrentIdx++];
  354. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  355. dbgs() << CurrentIdx << ": GIM_CheckHasNoUse(MIs["
  356. << InsnID << "]\n");
  357. const MachineInstr *MI = State.MIs[InsnID];
  358. assert(MI && "Used insn before defined");
  359. assert(MI->getNumDefs() > 0 && "No defs");
  360. const Register Res = MI->getOperand(0).getReg();
  361. if (!MRI.use_nodbg_empty(Res)) {
  362. if (handleReject() == RejectAndGiveUp)
  363. return false;
  364. }
  365. break;
  366. }
  367. case GIM_CheckAtomicOrdering: {
  368. int64_t InsnID = MatchTable[CurrentIdx++];
  369. AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
  370. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  371. dbgs() << CurrentIdx << ": GIM_CheckAtomicOrdering(MIs["
  372. << InsnID << "], " << (uint64_t)Ordering << ")\n");
  373. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  374. if (!State.MIs[InsnID]->hasOneMemOperand())
  375. if (handleReject() == RejectAndGiveUp)
  376. return false;
  377. for (const auto &MMO : State.MIs[InsnID]->memoperands())
  378. if (MMO->getMergedOrdering() != Ordering)
  379. if (handleReject() == RejectAndGiveUp)
  380. return false;
  381. break;
  382. }
  383. case GIM_CheckAtomicOrderingOrStrongerThan: {
  384. int64_t InsnID = MatchTable[CurrentIdx++];
  385. AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
  386. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  387. dbgs() << CurrentIdx
  388. << ": GIM_CheckAtomicOrderingOrStrongerThan(MIs["
  389. << InsnID << "], " << (uint64_t)Ordering << ")\n");
  390. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  391. if (!State.MIs[InsnID]->hasOneMemOperand())
  392. if (handleReject() == RejectAndGiveUp)
  393. return false;
  394. for (const auto &MMO : State.MIs[InsnID]->memoperands())
  395. if (!isAtLeastOrStrongerThan(MMO->getMergedOrdering(), Ordering))
  396. if (handleReject() == RejectAndGiveUp)
  397. return false;
  398. break;
  399. }
  400. case GIM_CheckAtomicOrderingWeakerThan: {
  401. int64_t InsnID = MatchTable[CurrentIdx++];
  402. AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
  403. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  404. dbgs() << CurrentIdx
  405. << ": GIM_CheckAtomicOrderingWeakerThan(MIs["
  406. << InsnID << "], " << (uint64_t)Ordering << ")\n");
  407. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  408. if (!State.MIs[InsnID]->hasOneMemOperand())
  409. if (handleReject() == RejectAndGiveUp)
  410. return false;
  411. for (const auto &MMO : State.MIs[InsnID]->memoperands())
  412. if (!isStrongerThan(Ordering, MMO->getMergedOrdering()))
  413. if (handleReject() == RejectAndGiveUp)
  414. return false;
  415. break;
  416. }
  417. case GIM_CheckMemoryAddressSpace: {
  418. int64_t InsnID = MatchTable[CurrentIdx++];
  419. int64_t MMOIdx = MatchTable[CurrentIdx++];
  420. // This accepts a list of possible address spaces.
  421. const int NumAddrSpace = MatchTable[CurrentIdx++];
  422. if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
  423. if (handleReject() == RejectAndGiveUp)
  424. return false;
  425. break;
  426. }
  427. // Need to still jump to the end of the list of address spaces if we find
  428. // a match earlier.
  429. const uint64_t LastIdx = CurrentIdx + NumAddrSpace;
  430. const MachineMemOperand *MMO
  431. = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
  432. const unsigned MMOAddrSpace = MMO->getAddrSpace();
  433. bool Success = false;
  434. for (int I = 0; I != NumAddrSpace; ++I) {
  435. unsigned AddrSpace = MatchTable[CurrentIdx++];
  436. DEBUG_WITH_TYPE(
  437. TgtInstructionSelector::getName(),
  438. dbgs() << "addrspace(" << MMOAddrSpace << ") vs "
  439. << AddrSpace << '\n');
  440. if (AddrSpace == MMOAddrSpace) {
  441. Success = true;
  442. break;
  443. }
  444. }
  445. CurrentIdx = LastIdx;
  446. if (!Success && handleReject() == RejectAndGiveUp)
  447. return false;
  448. break;
  449. }
  450. case GIM_CheckMemoryAlignment: {
  451. int64_t InsnID = MatchTable[CurrentIdx++];
  452. int64_t MMOIdx = MatchTable[CurrentIdx++];
  453. unsigned MinAlign = MatchTable[CurrentIdx++];
  454. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  455. if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
  456. if (handleReject() == RejectAndGiveUp)
  457. return false;
  458. break;
  459. }
  460. MachineMemOperand *MMO
  461. = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
  462. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  463. dbgs() << CurrentIdx << ": GIM_CheckMemoryAlignment"
  464. << "(MIs[" << InsnID << "]->memoperands() + " << MMOIdx
  465. << ")->getAlignment() >= " << MinAlign << ")\n");
  466. if (MMO->getAlign() < MinAlign && handleReject() == RejectAndGiveUp)
  467. return false;
  468. break;
  469. }
  470. case GIM_CheckMemorySizeEqualTo: {
  471. int64_t InsnID = MatchTable[CurrentIdx++];
  472. int64_t MMOIdx = MatchTable[CurrentIdx++];
  473. uint64_t Size = MatchTable[CurrentIdx++];
  474. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  475. dbgs() << CurrentIdx
  476. << ": GIM_CheckMemorySizeEqual(MIs[" << InsnID
  477. << "]->memoperands() + " << MMOIdx
  478. << ", Size=" << Size << ")\n");
  479. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  480. if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
  481. if (handleReject() == RejectAndGiveUp)
  482. return false;
  483. break;
  484. }
  485. MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
  486. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  487. dbgs() << MMO->getSize() << " bytes vs " << Size
  488. << " bytes\n");
  489. if (MMO->getSize() != Size)
  490. if (handleReject() == RejectAndGiveUp)
  491. return false;
  492. break;
  493. }
  494. case GIM_CheckMemorySizeEqualToLLT:
  495. case GIM_CheckMemorySizeLessThanLLT:
  496. case GIM_CheckMemorySizeGreaterThanLLT: {
  497. int64_t InsnID = MatchTable[CurrentIdx++];
  498. int64_t MMOIdx = MatchTable[CurrentIdx++];
  499. int64_t OpIdx = MatchTable[CurrentIdx++];
  500. DEBUG_WITH_TYPE(
  501. TgtInstructionSelector::getName(),
  502. dbgs() << CurrentIdx << ": GIM_CheckMemorySize"
  503. << (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT
  504. ? "EqualTo"
  505. : MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT
  506. ? "GreaterThan"
  507. : "LessThan")
  508. << "LLT(MIs[" << InsnID << "]->memoperands() + " << MMOIdx
  509. << ", OpIdx=" << OpIdx << ")\n");
  510. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  511. MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
  512. if (!MO.isReg()) {
  513. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  514. dbgs() << CurrentIdx << ": Not a register\n");
  515. if (handleReject() == RejectAndGiveUp)
  516. return false;
  517. break;
  518. }
  519. if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
  520. if (handleReject() == RejectAndGiveUp)
  521. return false;
  522. break;
  523. }
  524. MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
  525. unsigned Size = MRI.getType(MO.getReg()).getSizeInBits();
  526. if (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT &&
  527. MMO->getSizeInBits() != Size) {
  528. if (handleReject() == RejectAndGiveUp)
  529. return false;
  530. } else if (MatcherOpcode == GIM_CheckMemorySizeLessThanLLT &&
  531. MMO->getSizeInBits() >= Size) {
  532. if (handleReject() == RejectAndGiveUp)
  533. return false;
  534. } else if (MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT &&
  535. MMO->getSizeInBits() <= Size)
  536. if (handleReject() == RejectAndGiveUp)
  537. return false;
  538. break;
  539. }
  540. case GIM_CheckType: {
  541. int64_t InsnID = MatchTable[CurrentIdx++];
  542. int64_t OpIdx = MatchTable[CurrentIdx++];
  543. int64_t TypeID = MatchTable[CurrentIdx++];
  544. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  545. dbgs() << CurrentIdx << ": GIM_CheckType(MIs[" << InsnID
  546. << "]->getOperand(" << OpIdx
  547. << "), TypeID=" << TypeID << ")\n");
  548. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  549. MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
  550. if (!MO.isReg() ||
  551. MRI.getType(MO.getReg()) != ISelInfo.TypeObjects[TypeID]) {
  552. if (handleReject() == RejectAndGiveUp)
  553. return false;
  554. }
  555. break;
  556. }
  557. case GIM_CheckPointerToAny: {
  558. int64_t InsnID = MatchTable[CurrentIdx++];
  559. int64_t OpIdx = MatchTable[CurrentIdx++];
  560. uint64_t SizeInBits = MatchTable[CurrentIdx++];
  561. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  562. dbgs() << CurrentIdx << ": GIM_CheckPointerToAny(MIs["
  563. << InsnID << "]->getOperand(" << OpIdx
  564. << "), SizeInBits=" << SizeInBits << ")\n");
  565. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  566. MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
  567. const LLT Ty = MRI.getType(MO.getReg());
  568. // iPTR must be looked up in the target.
  569. if (SizeInBits == 0) {
  570. MachineFunction *MF = State.MIs[InsnID]->getParent()->getParent();
  571. const unsigned AddrSpace = Ty.getAddressSpace();
  572. SizeInBits = MF->getDataLayout().getPointerSizeInBits(AddrSpace);
  573. }
  574. assert(SizeInBits != 0 && "Pointer size must be known");
  575. if (MO.isReg()) {
  576. if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits)
  577. if (handleReject() == RejectAndGiveUp)
  578. return false;
  579. } else if (handleReject() == RejectAndGiveUp)
  580. return false;
  581. break;
  582. }
  583. case GIM_RecordNamedOperand: {
  584. int64_t InsnID = MatchTable[CurrentIdx++];
  585. int64_t OpIdx = MatchTable[CurrentIdx++];
  586. uint64_t StoreIdx = MatchTable[CurrentIdx++];
  587. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  588. dbgs() << CurrentIdx << ": GIM_RecordNamedOperand(MIs["
  589. << InsnID << "]->getOperand(" << OpIdx
  590. << "), StoreIdx=" << StoreIdx << ")\n");
  591. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  592. assert(StoreIdx < State.RecordedOperands.size() && "Index out of range");
  593. State.RecordedOperands[StoreIdx] = &State.MIs[InsnID]->getOperand(OpIdx);
  594. break;
  595. }
  596. case GIM_CheckRegBankForClass: {
  597. int64_t InsnID = MatchTable[CurrentIdx++];
  598. int64_t OpIdx = MatchTable[CurrentIdx++];
  599. int64_t RCEnum = MatchTable[CurrentIdx++];
  600. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  601. dbgs() << CurrentIdx << ": GIM_CheckRegBankForClass(MIs["
  602. << InsnID << "]->getOperand(" << OpIdx
  603. << "), RCEnum=" << RCEnum << ")\n");
  604. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  605. MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
  606. if (!MO.isReg() ||
  607. &RBI.getRegBankFromRegClass(*TRI.getRegClass(RCEnum),
  608. MRI.getType(MO.getReg())) !=
  609. RBI.getRegBank(MO.getReg(), MRI, TRI)) {
  610. if (handleReject() == RejectAndGiveUp)
  611. return false;
  612. }
  613. break;
  614. }
  615. case GIM_CheckComplexPattern: {
  616. int64_t InsnID = MatchTable[CurrentIdx++];
  617. int64_t OpIdx = MatchTable[CurrentIdx++];
  618. int64_t RendererID = MatchTable[CurrentIdx++];
  619. int64_t ComplexPredicateID = MatchTable[CurrentIdx++];
  620. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  621. dbgs() << CurrentIdx << ": State.Renderers[" << RendererID
  622. << "] = GIM_CheckComplexPattern(MIs[" << InsnID
  623. << "]->getOperand(" << OpIdx
  624. << "), ComplexPredicateID=" << ComplexPredicateID
  625. << ")\n");
  626. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  627. // FIXME: Use std::invoke() when it's available.
  628. ComplexRendererFns Renderer =
  629. (ISel.*ISelInfo.ComplexPredicates[ComplexPredicateID])(
  630. State.MIs[InsnID]->getOperand(OpIdx));
  631. if (Renderer)
  632. State.Renderers[RendererID] = *Renderer;
  633. else
  634. if (handleReject() == RejectAndGiveUp)
  635. return false;
  636. break;
  637. }
  638. case GIM_CheckConstantInt: {
  639. int64_t InsnID = MatchTable[CurrentIdx++];
  640. int64_t OpIdx = MatchTable[CurrentIdx++];
  641. int64_t Value = MatchTable[CurrentIdx++];
  642. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  643. dbgs() << CurrentIdx << ": GIM_CheckConstantInt(MIs["
  644. << InsnID << "]->getOperand(" << OpIdx
  645. << "), Value=" << Value << ")\n");
  646. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  647. MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
  648. if (MO.isReg()) {
  649. // isOperandImmEqual() will sign-extend to 64-bits, so should we.
  650. LLT Ty = MRI.getType(MO.getReg());
  651. Value = SignExtend64(Value, Ty.getSizeInBits());
  652. if (!isOperandImmEqual(MO, Value, MRI)) {
  653. if (handleReject() == RejectAndGiveUp)
  654. return false;
  655. }
  656. } else if (handleReject() == RejectAndGiveUp)
  657. return false;
  658. break;
  659. }
  660. case GIM_CheckLiteralInt: {
  661. int64_t InsnID = MatchTable[CurrentIdx++];
  662. int64_t OpIdx = MatchTable[CurrentIdx++];
  663. int64_t Value = MatchTable[CurrentIdx++];
  664. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  665. dbgs() << CurrentIdx << ": GIM_CheckLiteralInt(MIs["
  666. << InsnID << "]->getOperand(" << OpIdx
  667. << "), Value=" << Value << ")\n");
  668. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  669. MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
  670. if (MO.isImm() && MO.getImm() == Value)
  671. break;
  672. if (MO.isCImm() && MO.getCImm()->equalsInt(Value))
  673. break;
  674. if (handleReject() == RejectAndGiveUp)
  675. return false;
  676. break;
  677. }
  678. case GIM_CheckIntrinsicID: {
  679. int64_t InsnID = MatchTable[CurrentIdx++];
  680. int64_t OpIdx = MatchTable[CurrentIdx++];
  681. int64_t Value = MatchTable[CurrentIdx++];
  682. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  683. dbgs() << CurrentIdx << ": GIM_CheckIntrinsicID(MIs["
  684. << InsnID << "]->getOperand(" << OpIdx
  685. << "), Value=" << Value << ")\n");
  686. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  687. MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
  688. if (!MO.isIntrinsicID() || MO.getIntrinsicID() != Value)
  689. if (handleReject() == RejectAndGiveUp)
  690. return false;
  691. break;
  692. }
  693. case GIM_CheckCmpPredicate: {
  694. int64_t InsnID = MatchTable[CurrentIdx++];
  695. int64_t OpIdx = MatchTable[CurrentIdx++];
  696. int64_t Value = MatchTable[CurrentIdx++];
  697. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  698. dbgs() << CurrentIdx << ": GIM_CheckCmpPredicate(MIs["
  699. << InsnID << "]->getOperand(" << OpIdx
  700. << "), Value=" << Value << ")\n");
  701. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  702. MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
  703. if (!MO.isPredicate() || MO.getPredicate() != Value)
  704. if (handleReject() == RejectAndGiveUp)
  705. return false;
  706. break;
  707. }
  708. case GIM_CheckIsMBB: {
  709. int64_t InsnID = MatchTable[CurrentIdx++];
  710. int64_t OpIdx = MatchTable[CurrentIdx++];
  711. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  712. dbgs() << CurrentIdx << ": GIM_CheckIsMBB(MIs[" << InsnID
  713. << "]->getOperand(" << OpIdx << "))\n");
  714. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  715. if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB()) {
  716. if (handleReject() == RejectAndGiveUp)
  717. return false;
  718. }
  719. break;
  720. }
  721. case GIM_CheckIsImm: {
  722. int64_t InsnID = MatchTable[CurrentIdx++];
  723. int64_t OpIdx = MatchTable[CurrentIdx++];
  724. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  725. dbgs() << CurrentIdx << ": GIM_CheckIsImm(MIs[" << InsnID
  726. << "]->getOperand(" << OpIdx << "))\n");
  727. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  728. if (!State.MIs[InsnID]->getOperand(OpIdx).isImm()) {
  729. if (handleReject() == RejectAndGiveUp)
  730. return false;
  731. }
  732. break;
  733. }
  734. case GIM_CheckIsSafeToFold: {
  735. int64_t InsnID = MatchTable[CurrentIdx++];
  736. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  737. dbgs() << CurrentIdx << ": GIM_CheckIsSafeToFold(MIs["
  738. << InsnID << "])\n");
  739. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  740. if (!isObviouslySafeToFold(*State.MIs[InsnID], *State.MIs[0])) {
  741. if (handleReject() == RejectAndGiveUp)
  742. return false;
  743. }
  744. break;
  745. }
  746. case GIM_CheckIsSameOperand: {
  747. int64_t InsnID = MatchTable[CurrentIdx++];
  748. int64_t OpIdx = MatchTable[CurrentIdx++];
  749. int64_t OtherInsnID = MatchTable[CurrentIdx++];
  750. int64_t OtherOpIdx = MatchTable[CurrentIdx++];
  751. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  752. dbgs() << CurrentIdx << ": GIM_CheckIsSameOperand(MIs["
  753. << InsnID << "][" << OpIdx << "], MIs["
  754. << OtherInsnID << "][" << OtherOpIdx << "])\n");
  755. assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
  756. assert(State.MIs[OtherInsnID] != nullptr && "Used insn before defined");
  757. if (!State.MIs[InsnID]->getOperand(OpIdx).isIdenticalTo(
  758. State.MIs[OtherInsnID]->getOperand(OtherOpIdx))) {
  759. if (handleReject() == RejectAndGiveUp)
  760. return false;
  761. }
  762. break;
  763. }
  764. case GIM_Reject:
  765. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  766. dbgs() << CurrentIdx << ": GIM_Reject\n");
  767. if (handleReject() == RejectAndGiveUp)
  768. return false;
  769. break;
  770. case GIR_MutateOpcode: {
  771. int64_t OldInsnID = MatchTable[CurrentIdx++];
  772. uint64_t NewInsnID = MatchTable[CurrentIdx++];
  773. int64_t NewOpcode = MatchTable[CurrentIdx++];
  774. if (NewInsnID >= OutMIs.size())
  775. OutMIs.resize(NewInsnID + 1);
  776. OutMIs[NewInsnID] = MachineInstrBuilder(*State.MIs[OldInsnID]->getMF(),
  777. State.MIs[OldInsnID]);
  778. OutMIs[NewInsnID]->setDesc(TII.get(NewOpcode));
  779. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  780. dbgs() << CurrentIdx << ": GIR_MutateOpcode(OutMIs["
  781. << NewInsnID << "], MIs[" << OldInsnID << "], "
  782. << NewOpcode << ")\n");
  783. break;
  784. }
  785. case GIR_BuildMI: {
  786. uint64_t NewInsnID = MatchTable[CurrentIdx++];
  787. int64_t Opcode = MatchTable[CurrentIdx++];
  788. if (NewInsnID >= OutMIs.size())
  789. OutMIs.resize(NewInsnID + 1);
  790. OutMIs[NewInsnID] = BuildMI(*State.MIs[0]->getParent(), State.MIs[0],
  791. MIMetadata(*State.MIs[0]), TII.get(Opcode));
  792. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  793. dbgs() << CurrentIdx << ": GIR_BuildMI(OutMIs["
  794. << NewInsnID << "], " << Opcode << ")\n");
  795. break;
  796. }
  797. case GIR_Copy: {
  798. int64_t NewInsnID = MatchTable[CurrentIdx++];
  799. int64_t OldInsnID = MatchTable[CurrentIdx++];
  800. int64_t OpIdx = MatchTable[CurrentIdx++];
  801. assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
  802. OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
  803. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  804. dbgs()
  805. << CurrentIdx << ": GIR_Copy(OutMIs[" << NewInsnID
  806. << "], MIs[" << OldInsnID << "], " << OpIdx << ")\n");
  807. break;
  808. }
  809. case GIR_CopyOrAddZeroReg: {
  810. int64_t NewInsnID = MatchTable[CurrentIdx++];
  811. int64_t OldInsnID = MatchTable[CurrentIdx++];
  812. int64_t OpIdx = MatchTable[CurrentIdx++];
  813. int64_t ZeroReg = MatchTable[CurrentIdx++];
  814. assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
  815. MachineOperand &MO = State.MIs[OldInsnID]->getOperand(OpIdx);
  816. if (isOperandImmEqual(MO, 0, MRI))
  817. OutMIs[NewInsnID].addReg(ZeroReg);
  818. else
  819. OutMIs[NewInsnID].add(MO);
  820. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  821. dbgs() << CurrentIdx << ": GIR_CopyOrAddZeroReg(OutMIs["
  822. << NewInsnID << "], MIs[" << OldInsnID << "], "
  823. << OpIdx << ", " << ZeroReg << ")\n");
  824. break;
  825. }
  826. case GIR_CopySubReg: {
  827. int64_t NewInsnID = MatchTable[CurrentIdx++];
  828. int64_t OldInsnID = MatchTable[CurrentIdx++];
  829. int64_t OpIdx = MatchTable[CurrentIdx++];
  830. int64_t SubRegIdx = MatchTable[CurrentIdx++];
  831. assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
  832. OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
  833. 0, SubRegIdx);
  834. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  835. dbgs() << CurrentIdx << ": GIR_CopySubReg(OutMIs["
  836. << NewInsnID << "], MIs[" << OldInsnID << "], "
  837. << OpIdx << ", " << SubRegIdx << ")\n");
  838. break;
  839. }
  840. case GIR_AddImplicitDef: {
  841. int64_t InsnID = MatchTable[CurrentIdx++];
  842. int64_t RegNum = MatchTable[CurrentIdx++];
  843. assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
  844. OutMIs[InsnID].addDef(RegNum, RegState::Implicit);
  845. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  846. dbgs() << CurrentIdx << ": GIR_AddImplicitDef(OutMIs["
  847. << InsnID << "], " << RegNum << ")\n");
  848. break;
  849. }
  850. case GIR_AddImplicitUse: {
  851. int64_t InsnID = MatchTable[CurrentIdx++];
  852. int64_t RegNum = MatchTable[CurrentIdx++];
  853. assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
  854. OutMIs[InsnID].addUse(RegNum, RegState::Implicit);
  855. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  856. dbgs() << CurrentIdx << ": GIR_AddImplicitUse(OutMIs["
  857. << InsnID << "], " << RegNum << ")\n");
  858. break;
  859. }
  860. case GIR_AddRegister: {
  861. int64_t InsnID = MatchTable[CurrentIdx++];
  862. int64_t RegNum = MatchTable[CurrentIdx++];
  863. uint64_t RegFlags = MatchTable[CurrentIdx++];
  864. assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
  865. OutMIs[InsnID].addReg(RegNum, RegFlags);
  866. DEBUG_WITH_TYPE(
  867. TgtInstructionSelector::getName(),
  868. dbgs() << CurrentIdx << ": GIR_AddRegister(OutMIs["
  869. << InsnID << "], " << RegNum << ", " << RegFlags << ")\n");
  870. break;
  871. }
  872. case GIR_AddTempRegister:
  873. case GIR_AddTempSubRegister: {
  874. int64_t InsnID = MatchTable[CurrentIdx++];
  875. int64_t TempRegID = MatchTable[CurrentIdx++];
  876. uint64_t TempRegFlags = MatchTable[CurrentIdx++];
  877. unsigned SubReg = 0;
  878. if (MatcherOpcode == GIR_AddTempSubRegister)
  879. SubReg = MatchTable[CurrentIdx++];
  880. assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
  881. OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags, SubReg);
  882. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  883. dbgs() << CurrentIdx << ": GIR_AddTempRegister(OutMIs["
  884. << InsnID << "], TempRegisters[" << TempRegID
  885. << "]";
  886. if (SubReg)
  887. dbgs() << '.' << TRI.getSubRegIndexName(SubReg);
  888. dbgs() << ", " << TempRegFlags << ")\n");
  889. break;
  890. }
  891. case GIR_AddImm: {
  892. int64_t InsnID = MatchTable[CurrentIdx++];
  893. int64_t Imm = MatchTable[CurrentIdx++];
  894. assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
  895. OutMIs[InsnID].addImm(Imm);
  896. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  897. dbgs() << CurrentIdx << ": GIR_AddImm(OutMIs[" << InsnID
  898. << "], " << Imm << ")\n");
  899. break;
  900. }
  901. case GIR_ComplexRenderer: {
  902. int64_t InsnID = MatchTable[CurrentIdx++];
  903. int64_t RendererID = MatchTable[CurrentIdx++];
  904. assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
  905. for (const auto &RenderOpFn : State.Renderers[RendererID])
  906. RenderOpFn(OutMIs[InsnID]);
  907. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  908. dbgs() << CurrentIdx << ": GIR_ComplexRenderer(OutMIs["
  909. << InsnID << "], " << RendererID << ")\n");
  910. break;
  911. }
  912. case GIR_ComplexSubOperandRenderer: {
  913. int64_t InsnID = MatchTable[CurrentIdx++];
  914. int64_t RendererID = MatchTable[CurrentIdx++];
  915. int64_t RenderOpID = MatchTable[CurrentIdx++];
  916. assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
  917. State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
  918. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  919. dbgs() << CurrentIdx
  920. << ": GIR_ComplexSubOperandRenderer(OutMIs["
  921. << InsnID << "], " << RendererID << ", "
  922. << RenderOpID << ")\n");
  923. break;
  924. }
  925. case GIR_CopyConstantAsSImm: {
  926. int64_t NewInsnID = MatchTable[CurrentIdx++];
  927. int64_t OldInsnID = MatchTable[CurrentIdx++];
  928. assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
  929. assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT");
  930. if (State.MIs[OldInsnID]->getOperand(1).isCImm()) {
  931. OutMIs[NewInsnID].addImm(
  932. State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
  933. } else if (State.MIs[OldInsnID]->getOperand(1).isImm())
  934. OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1));
  935. else
  936. llvm_unreachable("Expected Imm or CImm operand");
  937. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  938. dbgs() << CurrentIdx << ": GIR_CopyConstantAsSImm(OutMIs["
  939. << NewInsnID << "], MIs[" << OldInsnID << "])\n");
  940. break;
  941. }
  942. // TODO: Needs a test case once we have a pattern that uses this.
  943. case GIR_CopyFConstantAsFPImm: {
  944. int64_t NewInsnID = MatchTable[CurrentIdx++];
  945. int64_t OldInsnID = MatchTable[CurrentIdx++];
  946. assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
  947. assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT && "Expected G_FCONSTANT");
  948. if (State.MIs[OldInsnID]->getOperand(1).isFPImm())
  949. OutMIs[NewInsnID].addFPImm(
  950. State.MIs[OldInsnID]->getOperand(1).getFPImm());
  951. else
  952. llvm_unreachable("Expected FPImm operand");
  953. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  954. dbgs() << CurrentIdx << ": GIR_CopyFPConstantAsFPImm(OutMIs["
  955. << NewInsnID << "], MIs[" << OldInsnID << "])\n");
  956. break;
  957. }
  958. case GIR_CustomRenderer: {
  959. int64_t InsnID = MatchTable[CurrentIdx++];
  960. int64_t OldInsnID = MatchTable[CurrentIdx++];
  961. int64_t RendererFnID = MatchTable[CurrentIdx++];
  962. assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
  963. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  964. dbgs() << CurrentIdx << ": GIR_CustomRenderer(OutMIs["
  965. << InsnID << "], MIs[" << OldInsnID << "], "
  966. << RendererFnID << ")\n");
  967. (ISel.*ISelInfo.CustomRenderers[RendererFnID])(
  968. OutMIs[InsnID], *State.MIs[OldInsnID],
  969. -1); // Not a source operand of the old instruction.
  970. break;
  971. }
  972. case GIR_CustomOperandRenderer: {
  973. int64_t InsnID = MatchTable[CurrentIdx++];
  974. int64_t OldInsnID = MatchTable[CurrentIdx++];
  975. int64_t OpIdx = MatchTable[CurrentIdx++];
  976. int64_t RendererFnID = MatchTable[CurrentIdx++];
  977. assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
  978. DEBUG_WITH_TYPE(
  979. TgtInstructionSelector::getName(),
  980. dbgs() << CurrentIdx << ": GIR_CustomOperandRenderer(OutMIs["
  981. << InsnID << "], MIs[" << OldInsnID << "]->getOperand("
  982. << OpIdx << "), "
  983. << RendererFnID << ")\n");
  984. (ISel.*ISelInfo.CustomRenderers[RendererFnID])(OutMIs[InsnID],
  985. *State.MIs[OldInsnID],
  986. OpIdx);
  987. break;
  988. }
  989. case GIR_ConstrainOperandRC: {
  990. int64_t InsnID = MatchTable[CurrentIdx++];
  991. int64_t OpIdx = MatchTable[CurrentIdx++];
  992. int64_t RCEnum = MatchTable[CurrentIdx++];
  993. assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
  994. MachineInstr &I = *OutMIs[InsnID].getInstr();
  995. MachineFunction &MF = *I.getParent()->getParent();
  996. MachineRegisterInfo &MRI = MF.getRegInfo();
  997. const TargetRegisterClass &RC = *TRI.getRegClass(RCEnum);
  998. MachineOperand &MO = I.getOperand(OpIdx);
  999. constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, RC, MO);
  1000. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  1001. dbgs() << CurrentIdx << ": GIR_ConstrainOperandRC(OutMIs["
  1002. << InsnID << "], " << OpIdx << ", " << RCEnum
  1003. << ")\n");
  1004. break;
  1005. }
  1006. case GIR_ConstrainSelectedInstOperands: {
  1007. int64_t InsnID = MatchTable[CurrentIdx++];
  1008. assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
  1009. constrainSelectedInstRegOperands(*OutMIs[InsnID].getInstr(), TII, TRI,
  1010. RBI);
  1011. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  1012. dbgs() << CurrentIdx
  1013. << ": GIR_ConstrainSelectedInstOperands(OutMIs["
  1014. << InsnID << "])\n");
  1015. break;
  1016. }
  1017. case GIR_MergeMemOperands: {
  1018. int64_t InsnID = MatchTable[CurrentIdx++];
  1019. assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
  1020. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  1021. dbgs() << CurrentIdx << ": GIR_MergeMemOperands(OutMIs["
  1022. << InsnID << "]");
  1023. int64_t MergeInsnID = GIU_MergeMemOperands_EndOfList;
  1024. while ((MergeInsnID = MatchTable[CurrentIdx++]) !=
  1025. GIU_MergeMemOperands_EndOfList) {
  1026. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  1027. dbgs() << ", MIs[" << MergeInsnID << "]");
  1028. for (const auto &MMO : State.MIs[MergeInsnID]->memoperands())
  1029. OutMIs[InsnID].addMemOperand(MMO);
  1030. }
  1031. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), dbgs() << ")\n");
  1032. break;
  1033. }
  1034. case GIR_EraseFromParent: {
  1035. int64_t InsnID = MatchTable[CurrentIdx++];
  1036. assert(State.MIs[InsnID] &&
  1037. "Attempted to erase an undefined instruction");
  1038. State.MIs[InsnID]->eraseFromParent();
  1039. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  1040. dbgs() << CurrentIdx << ": GIR_EraseFromParent(MIs["
  1041. << InsnID << "])\n");
  1042. break;
  1043. }
  1044. case GIR_MakeTempReg: {
  1045. int64_t TempRegID = MatchTable[CurrentIdx++];
  1046. int64_t TypeID = MatchTable[CurrentIdx++];
  1047. State.TempRegisters[TempRegID] =
  1048. MRI.createGenericVirtualRegister(ISelInfo.TypeObjects[TypeID]);
  1049. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  1050. dbgs() << CurrentIdx << ": TempRegs[" << TempRegID
  1051. << "] = GIR_MakeTempReg(" << TypeID << ")\n");
  1052. break;
  1053. }
  1054. case GIR_Coverage: {
  1055. int64_t RuleID = MatchTable[CurrentIdx++];
  1056. CoverageInfo.setCovered(RuleID);
  1057. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  1058. dbgs()
  1059. << CurrentIdx << ": GIR_Coverage(" << RuleID << ")");
  1060. break;
  1061. }
  1062. case GIR_Done:
  1063. DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
  1064. dbgs() << CurrentIdx << ": GIR_Done\n");
  1065. propagateFlags(OutMIs);
  1066. return true;
  1067. default:
  1068. llvm_unreachable("Unexpected command");
  1069. }
  1070. }
  1071. }
  1072. } // end namespace llvm
  1073. #endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
  1074. #ifdef __GNUC__
  1075. #pragma GCC diagnostic pop
  1076. #endif