PredicateExpander.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. //===--------------------- PredicateExpander.cpp --------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. /// \file
  9. /// Functionalities used by the Tablegen backends to expand machine predicates.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "PredicateExpander.h"
  13. #include "CodeGenSchedule.h" // Definition of STIPredicateFunction.
  14. namespace llvm {
  15. void PredicateExpander::expandTrue(raw_ostream &OS) { OS << "true"; }
  16. void PredicateExpander::expandFalse(raw_ostream &OS) { OS << "false"; }
  17. void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
  18. int ImmVal,
  19. StringRef FunctionMapper) {
  20. if (!FunctionMapper.empty())
  21. OS << FunctionMapper << "(";
  22. OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
  23. << ").getImm()";
  24. if (!FunctionMapper.empty())
  25. OS << ")";
  26. OS << (shouldNegate() ? " != " : " == ") << ImmVal;
  27. }
  28. void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
  29. StringRef ImmVal,
  30. StringRef FunctionMapper) {
  31. if (ImmVal.empty())
  32. expandCheckImmOperandSimple(OS, OpIndex, FunctionMapper);
  33. if (!FunctionMapper.empty())
  34. OS << FunctionMapper << "(";
  35. OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
  36. << ").getImm()";
  37. if (!FunctionMapper.empty())
  38. OS << ")";
  39. OS << (shouldNegate() ? " != " : " == ") << ImmVal;
  40. }
  41. void PredicateExpander::expandCheckImmOperandSimple(raw_ostream &OS,
  42. int OpIndex,
  43. StringRef FunctionMapper) {
  44. if (shouldNegate())
  45. OS << "!";
  46. if (!FunctionMapper.empty())
  47. OS << FunctionMapper << "(";
  48. OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
  49. << ").getImm()";
  50. if (!FunctionMapper.empty())
  51. OS << ")";
  52. }
  53. void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex,
  54. const Record *Reg,
  55. StringRef FunctionMapper) {
  56. assert(Reg->isSubClassOf("Register") && "Expected a register Record!");
  57. if (!FunctionMapper.empty())
  58. OS << FunctionMapper << "(";
  59. OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
  60. << ").getReg()";
  61. if (!FunctionMapper.empty())
  62. OS << ")";
  63. OS << (shouldNegate() ? " != " : " == ");
  64. const StringRef Str = Reg->getValueAsString("Namespace");
  65. if (!Str.empty())
  66. OS << Str << "::";
  67. OS << Reg->getName();
  68. }
  69. void PredicateExpander::expandCheckRegOperandSimple(raw_ostream &OS,
  70. int OpIndex,
  71. StringRef FunctionMapper) {
  72. if (shouldNegate())
  73. OS << "!";
  74. if (!FunctionMapper.empty())
  75. OS << FunctionMapper << "(";
  76. OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
  77. << ").getReg()";
  78. if (!FunctionMapper.empty())
  79. OS << ")";
  80. }
  81. void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS,
  82. int OpIndex) {
  83. OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
  84. << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0";
  85. }
  86. void PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First,
  87. int Second) {
  88. OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First
  89. << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI"
  90. << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()";
  91. }
  92. void PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) {
  93. OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
  94. << (shouldNegate() ? "!= " : "== ") << NumOps;
  95. }
  96. void PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) {
  97. OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() "
  98. << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace")
  99. << "::" << Inst->getName();
  100. }
  101. void PredicateExpander::expandCheckOpcode(raw_ostream &OS,
  102. const RecVec &Opcodes) {
  103. assert(!Opcodes.empty() && "Expected at least one opcode to check!");
  104. bool First = true;
  105. if (Opcodes.size() == 1) {
  106. OS << "( ";
  107. expandCheckOpcode(OS, Opcodes[0]);
  108. OS << " )";
  109. return;
  110. }
  111. OS << '(';
  112. increaseIndentLevel();
  113. for (const Record *Rec : Opcodes) {
  114. OS << '\n';
  115. OS.indent(getIndentLevel() * 2);
  116. if (!First)
  117. OS << (shouldNegate() ? "&& " : "|| ");
  118. expandCheckOpcode(OS, Rec);
  119. First = false;
  120. }
  121. OS << '\n';
  122. decreaseIndentLevel();
  123. OS.indent(getIndentLevel() * 2);
  124. OS << ')';
  125. }
  126. void PredicateExpander::expandCheckPseudo(raw_ostream &OS,
  127. const RecVec &Opcodes) {
  128. if (shouldExpandForMC())
  129. expandFalse(OS);
  130. else
  131. expandCheckOpcode(OS, Opcodes);
  132. }
  133. void PredicateExpander::expandPredicateSequence(raw_ostream &OS,
  134. const RecVec &Sequence,
  135. bool IsCheckAll) {
  136. assert(!Sequence.empty() && "Found an invalid empty predicate set!");
  137. if (Sequence.size() == 1)
  138. return expandPredicate(OS, Sequence[0]);
  139. // Okay, there is more than one predicate in the set.
  140. bool First = true;
  141. OS << (shouldNegate() ? "!(" : "(");
  142. increaseIndentLevel();
  143. bool OldValue = shouldNegate();
  144. setNegatePredicate(false);
  145. for (const Record *Rec : Sequence) {
  146. OS << '\n';
  147. OS.indent(getIndentLevel() * 2);
  148. if (!First)
  149. OS << (IsCheckAll ? "&& " : "|| ");
  150. expandPredicate(OS, Rec);
  151. First = false;
  152. }
  153. OS << '\n';
  154. decreaseIndentLevel();
  155. OS.indent(getIndentLevel() * 2);
  156. OS << ')';
  157. setNegatePredicate(OldValue);
  158. }
  159. void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS,
  160. StringRef MethodName) {
  161. OS << (shouldNegate() ? "!" : "");
  162. OS << TargetName << (shouldExpandForMC() ? "_MC::" : "InstrInfo::");
  163. OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
  164. }
  165. void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) {
  166. OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
  167. << "getOperand(" << OpIndex << ").isReg() ";
  168. }
  169. void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) {
  170. OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
  171. << "getOperand(" << OpIndex << ").isImm() ";
  172. }
  173. void PredicateExpander::expandCheckFunctionPredicateWithTII(
  174. raw_ostream &OS, StringRef MCInstFn, StringRef MachineInstrFn,
  175. StringRef TIIPtr) {
  176. if (!shouldExpandForMC()) {
  177. OS << (TIIPtr.empty() ? "TII" : TIIPtr) << "->" << MachineInstrFn;
  178. OS << (isByRef() ? "(MI)" : "(*MI)");
  179. return;
  180. }
  181. OS << MCInstFn << (isByRef() ? "(MI" : "(*MI") << ", MCII)";
  182. }
  183. void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS,
  184. StringRef MCInstFn,
  185. StringRef MachineInstrFn) {
  186. OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
  187. << (isByRef() ? "(MI)" : "(*MI)");
  188. }
  189. void PredicateExpander::expandCheckNonPortable(raw_ostream &OS,
  190. StringRef Code) {
  191. if (shouldExpandForMC())
  192. return expandFalse(OS);
  193. OS << '(' << Code << ')';
  194. }
  195. void PredicateExpander::expandReturnStatement(raw_ostream &OS,
  196. const Record *Rec) {
  197. std::string Buffer;
  198. raw_string_ostream SS(Buffer);
  199. SS << "return ";
  200. expandPredicate(SS, Rec);
  201. SS << ";";
  202. SS.flush();
  203. OS << Buffer;
  204. }
  205. void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS,
  206. const Record *Rec) {
  207. const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes");
  208. for (const Record *Opcode : Opcodes) {
  209. OS.indent(getIndentLevel() * 2);
  210. OS << "case " << Opcode->getValueAsString("Namespace")
  211. << "::" << Opcode->getName() << ":\n";
  212. }
  213. increaseIndentLevel();
  214. OS.indent(getIndentLevel() * 2);
  215. expandStatement(OS, Rec->getValueAsDef("CaseStmt"));
  216. decreaseIndentLevel();
  217. }
  218. void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS,
  219. const RecVec &Cases,
  220. const Record *Default) {
  221. std::string Buffer;
  222. raw_string_ostream SS(Buffer);
  223. SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
  224. for (const Record *Rec : Cases) {
  225. expandOpcodeSwitchCase(SS, Rec);
  226. SS << '\n';
  227. }
  228. // Expand the default case.
  229. SS.indent(getIndentLevel() * 2);
  230. SS << "default:\n";
  231. increaseIndentLevel();
  232. SS.indent(getIndentLevel() * 2);
  233. expandStatement(SS, Default);
  234. decreaseIndentLevel();
  235. SS << '\n';
  236. SS.indent(getIndentLevel() * 2);
  237. SS << "} // end of switch-stmt";
  238. SS.flush();
  239. OS << Buffer;
  240. }
  241. void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) {
  242. // Assume that padding has been added by the caller.
  243. if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) {
  244. expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"),
  245. Rec->getValueAsDef("DefaultCase"));
  246. return;
  247. }
  248. if (Rec->isSubClassOf("MCReturnStatement")) {
  249. expandReturnStatement(OS, Rec->getValueAsDef("Pred"));
  250. return;
  251. }
  252. llvm_unreachable("No known rules to expand this MCStatement");
  253. }
  254. void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) {
  255. // Assume that padding has been added by the caller.
  256. if (Rec->isSubClassOf("MCTrue")) {
  257. if (shouldNegate())
  258. return expandFalse(OS);
  259. return expandTrue(OS);
  260. }
  261. if (Rec->isSubClassOf("MCFalse")) {
  262. if (shouldNegate())
  263. return expandTrue(OS);
  264. return expandFalse(OS);
  265. }
  266. if (Rec->isSubClassOf("CheckNot")) {
  267. flipNegatePredicate();
  268. expandPredicate(OS, Rec->getValueAsDef("Pred"));
  269. flipNegatePredicate();
  270. return;
  271. }
  272. if (Rec->isSubClassOf("CheckIsRegOperand"))
  273. return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex"));
  274. if (Rec->isSubClassOf("CheckIsImmOperand"))
  275. return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex"));
  276. if (Rec->isSubClassOf("CheckRegOperand"))
  277. return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
  278. Rec->getValueAsDef("Reg"),
  279. Rec->getValueAsString("FunctionMapper"));
  280. if (Rec->isSubClassOf("CheckRegOperandSimple"))
  281. return expandCheckRegOperandSimple(OS, Rec->getValueAsInt("OpIndex"),
  282. Rec->getValueAsString("FunctionMapper"));
  283. if (Rec->isSubClassOf("CheckInvalidRegOperand"))
  284. return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex"));
  285. if (Rec->isSubClassOf("CheckImmOperand"))
  286. return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
  287. Rec->getValueAsInt("ImmVal"),
  288. Rec->getValueAsString("FunctionMapper"));
  289. if (Rec->isSubClassOf("CheckImmOperand_s"))
  290. return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
  291. Rec->getValueAsString("ImmVal"),
  292. Rec->getValueAsString("FunctionMapper"));
  293. if (Rec->isSubClassOf("CheckImmOperandSimple"))
  294. return expandCheckImmOperandSimple(OS, Rec->getValueAsInt("OpIndex"),
  295. Rec->getValueAsString("FunctionMapper"));
  296. if (Rec->isSubClassOf("CheckSameRegOperand"))
  297. return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"),
  298. Rec->getValueAsInt("SecondIndex"));
  299. if (Rec->isSubClassOf("CheckNumOperands"))
  300. return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps"));
  301. if (Rec->isSubClassOf("CheckPseudo"))
  302. return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
  303. if (Rec->isSubClassOf("CheckOpcode"))
  304. return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
  305. if (Rec->isSubClassOf("CheckAll"))
  306. return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
  307. /* AllOf */ true);
  308. if (Rec->isSubClassOf("CheckAny"))
  309. return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
  310. /* AllOf */ false);
  311. if (Rec->isSubClassOf("CheckFunctionPredicate")) {
  312. return expandCheckFunctionPredicate(
  313. OS, Rec->getValueAsString("MCInstFnName"),
  314. Rec->getValueAsString("MachineInstrFnName"));
  315. }
  316. if (Rec->isSubClassOf("CheckFunctionPredicateWithTII")) {
  317. return expandCheckFunctionPredicateWithTII(
  318. OS, Rec->getValueAsString("MCInstFnName"),
  319. Rec->getValueAsString("MachineInstrFnName"),
  320. Rec->getValueAsString("TIIPtrName"));
  321. }
  322. if (Rec->isSubClassOf("CheckNonPortable"))
  323. return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
  324. if (Rec->isSubClassOf("TIIPredicate"))
  325. return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName"));
  326. llvm_unreachable("No known rules to expand this MCInstPredicate");
  327. }
  328. void STIPredicateExpander::expandHeader(raw_ostream &OS,
  329. const STIPredicateFunction &Fn) {
  330. const Record *Rec = Fn.getDeclaration();
  331. StringRef FunctionName = Rec->getValueAsString("Name");
  332. OS.indent(getIndentLevel() * 2);
  333. OS << "bool ";
  334. if (shouldExpandDefinition())
  335. OS << getClassPrefix() << "::";
  336. OS << FunctionName << "(";
  337. if (shouldExpandForMC())
  338. OS << "const MCInst " << (isByRef() ? "&" : "*") << "MI";
  339. else
  340. OS << "const MachineInstr " << (isByRef() ? "&" : "*") << "MI";
  341. if (Rec->getValueAsBit("UpdatesOpcodeMask"))
  342. OS << ", APInt &Mask";
  343. OS << (shouldExpandForMC() ? ", unsigned ProcessorID) const " : ") const ");
  344. if (shouldExpandDefinition()) {
  345. OS << "{\n";
  346. return;
  347. }
  348. if (Rec->getValueAsBit("OverridesBaseClassMember"))
  349. OS << "override";
  350. OS << ";\n";
  351. }
  352. void STIPredicateExpander::expandPrologue(raw_ostream &OS,
  353. const STIPredicateFunction &Fn) {
  354. RecVec Delegates = Fn.getDeclaration()->getValueAsListOfDefs("Delegates");
  355. bool UpdatesOpcodeMask =
  356. Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
  357. increaseIndentLevel();
  358. unsigned IndentLevel = getIndentLevel();
  359. for (const Record *Delegate : Delegates) {
  360. OS.indent(IndentLevel * 2);
  361. OS << "if (" << Delegate->getValueAsString("Name") << "(MI";
  362. if (UpdatesOpcodeMask)
  363. OS << ", Mask";
  364. if (shouldExpandForMC())
  365. OS << ", ProcessorID";
  366. OS << "))\n";
  367. OS.indent((1 + IndentLevel) * 2);
  368. OS << "return true;\n\n";
  369. }
  370. if (shouldExpandForMC())
  371. return;
  372. OS.indent(IndentLevel * 2);
  373. OS << "unsigned ProcessorID = getSchedModel().getProcessorID();\n";
  374. }
  375. void STIPredicateExpander::expandOpcodeGroup(raw_ostream &OS, const OpcodeGroup &Group,
  376. bool ShouldUpdateOpcodeMask) {
  377. const OpcodeInfo &OI = Group.getOpcodeInfo();
  378. for (const PredicateInfo &PI : OI.getPredicates()) {
  379. const APInt &ProcModelMask = PI.ProcModelMask;
  380. bool FirstProcID = true;
  381. for (unsigned I = 0, E = ProcModelMask.getActiveBits(); I < E; ++I) {
  382. if (!ProcModelMask[I])
  383. continue;
  384. if (FirstProcID) {
  385. OS.indent(getIndentLevel() * 2);
  386. OS << "if (ProcessorID == " << I;
  387. } else {
  388. OS << " || ProcessorID == " << I;
  389. }
  390. FirstProcID = false;
  391. }
  392. OS << ") {\n";
  393. increaseIndentLevel();
  394. OS.indent(getIndentLevel() * 2);
  395. if (ShouldUpdateOpcodeMask) {
  396. if (PI.OperandMask.isNullValue())
  397. OS << "Mask.clearAllBits();\n";
  398. else
  399. OS << "Mask = " << PI.OperandMask << ";\n";
  400. OS.indent(getIndentLevel() * 2);
  401. }
  402. OS << "return ";
  403. expandPredicate(OS, PI.Predicate);
  404. OS << ";\n";
  405. decreaseIndentLevel();
  406. OS.indent(getIndentLevel() * 2);
  407. OS << "}\n";
  408. }
  409. }
  410. void STIPredicateExpander::expandBody(raw_ostream &OS,
  411. const STIPredicateFunction &Fn) {
  412. bool UpdatesOpcodeMask =
  413. Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
  414. unsigned IndentLevel = getIndentLevel();
  415. OS.indent(IndentLevel * 2);
  416. OS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
  417. OS.indent(IndentLevel * 2);
  418. OS << "default:\n";
  419. OS.indent(IndentLevel * 2);
  420. OS << " break;";
  421. for (const OpcodeGroup &Group : Fn.getGroups()) {
  422. for (const Record *Opcode : Group.getOpcodes()) {
  423. OS << '\n';
  424. OS.indent(IndentLevel * 2);
  425. OS << "case " << getTargetName() << "::" << Opcode->getName() << ":";
  426. }
  427. OS << '\n';
  428. increaseIndentLevel();
  429. expandOpcodeGroup(OS, Group, UpdatesOpcodeMask);
  430. OS.indent(getIndentLevel() * 2);
  431. OS << "break;\n";
  432. decreaseIndentLevel();
  433. }
  434. OS.indent(IndentLevel * 2);
  435. OS << "}\n";
  436. }
  437. void STIPredicateExpander::expandEpilogue(raw_ostream &OS,
  438. const STIPredicateFunction &Fn) {
  439. OS << '\n';
  440. OS.indent(getIndentLevel() * 2);
  441. OS << "return ";
  442. expandPredicate(OS, Fn.getDefaultReturnPredicate());
  443. OS << ";\n";
  444. decreaseIndentLevel();
  445. OS.indent(getIndentLevel() * 2);
  446. StringRef FunctionName = Fn.getDeclaration()->getValueAsString("Name");
  447. OS << "} // " << ClassPrefix << "::" << FunctionName << "\n\n";
  448. }
  449. void STIPredicateExpander::expandSTIPredicate(raw_ostream &OS,
  450. const STIPredicateFunction &Fn) {
  451. const Record *Rec = Fn.getDeclaration();
  452. if (shouldExpandForMC() && !Rec->getValueAsBit("ExpandForMC"))
  453. return;
  454. expandHeader(OS, Fn);
  455. if (shouldExpandDefinition()) {
  456. expandPrologue(OS, Fn);
  457. expandBody(OS, Fn);
  458. expandEpilogue(OS, Fn);
  459. }
  460. }
  461. } // namespace llvm