PredicateExpander.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  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. OS << Buffer;
  203. }
  204. void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS,
  205. const Record *Rec) {
  206. const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes");
  207. for (const Record *Opcode : Opcodes) {
  208. OS.indent(getIndentLevel() * 2);
  209. OS << "case " << Opcode->getValueAsString("Namespace")
  210. << "::" << Opcode->getName() << ":\n";
  211. }
  212. increaseIndentLevel();
  213. OS.indent(getIndentLevel() * 2);
  214. expandStatement(OS, Rec->getValueAsDef("CaseStmt"));
  215. decreaseIndentLevel();
  216. }
  217. void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS,
  218. const RecVec &Cases,
  219. const Record *Default) {
  220. std::string Buffer;
  221. raw_string_ostream SS(Buffer);
  222. SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
  223. for (const Record *Rec : Cases) {
  224. expandOpcodeSwitchCase(SS, Rec);
  225. SS << '\n';
  226. }
  227. // Expand the default case.
  228. SS.indent(getIndentLevel() * 2);
  229. SS << "default:\n";
  230. increaseIndentLevel();
  231. SS.indent(getIndentLevel() * 2);
  232. expandStatement(SS, Default);
  233. decreaseIndentLevel();
  234. SS << '\n';
  235. SS.indent(getIndentLevel() * 2);
  236. SS << "} // end of switch-stmt";
  237. OS << Buffer;
  238. }
  239. void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) {
  240. // Assume that padding has been added by the caller.
  241. if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) {
  242. expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"),
  243. Rec->getValueAsDef("DefaultCase"));
  244. return;
  245. }
  246. if (Rec->isSubClassOf("MCReturnStatement")) {
  247. expandReturnStatement(OS, Rec->getValueAsDef("Pred"));
  248. return;
  249. }
  250. llvm_unreachable("No known rules to expand this MCStatement");
  251. }
  252. void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) {
  253. // Assume that padding has been added by the caller.
  254. if (Rec->isSubClassOf("MCTrue")) {
  255. if (shouldNegate())
  256. return expandFalse(OS);
  257. return expandTrue(OS);
  258. }
  259. if (Rec->isSubClassOf("MCFalse")) {
  260. if (shouldNegate())
  261. return expandTrue(OS);
  262. return expandFalse(OS);
  263. }
  264. if (Rec->isSubClassOf("CheckNot")) {
  265. flipNegatePredicate();
  266. expandPredicate(OS, Rec->getValueAsDef("Pred"));
  267. flipNegatePredicate();
  268. return;
  269. }
  270. if (Rec->isSubClassOf("CheckIsRegOperand"))
  271. return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex"));
  272. if (Rec->isSubClassOf("CheckIsImmOperand"))
  273. return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex"));
  274. if (Rec->isSubClassOf("CheckRegOperand"))
  275. return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
  276. Rec->getValueAsDef("Reg"),
  277. Rec->getValueAsString("FunctionMapper"));
  278. if (Rec->isSubClassOf("CheckRegOperandSimple"))
  279. return expandCheckRegOperandSimple(OS, Rec->getValueAsInt("OpIndex"),
  280. Rec->getValueAsString("FunctionMapper"));
  281. if (Rec->isSubClassOf("CheckInvalidRegOperand"))
  282. return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex"));
  283. if (Rec->isSubClassOf("CheckImmOperand"))
  284. return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
  285. Rec->getValueAsInt("ImmVal"),
  286. Rec->getValueAsString("FunctionMapper"));
  287. if (Rec->isSubClassOf("CheckImmOperand_s"))
  288. return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
  289. Rec->getValueAsString("ImmVal"),
  290. Rec->getValueAsString("FunctionMapper"));
  291. if (Rec->isSubClassOf("CheckImmOperandSimple"))
  292. return expandCheckImmOperandSimple(OS, Rec->getValueAsInt("OpIndex"),
  293. Rec->getValueAsString("FunctionMapper"));
  294. if (Rec->isSubClassOf("CheckSameRegOperand"))
  295. return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"),
  296. Rec->getValueAsInt("SecondIndex"));
  297. if (Rec->isSubClassOf("CheckNumOperands"))
  298. return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps"));
  299. if (Rec->isSubClassOf("CheckPseudo"))
  300. return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
  301. if (Rec->isSubClassOf("CheckOpcode"))
  302. return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
  303. if (Rec->isSubClassOf("CheckAll"))
  304. return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
  305. /* AllOf */ true);
  306. if (Rec->isSubClassOf("CheckAny"))
  307. return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
  308. /* AllOf */ false);
  309. if (Rec->isSubClassOf("CheckFunctionPredicate")) {
  310. return expandCheckFunctionPredicate(
  311. OS, Rec->getValueAsString("MCInstFnName"),
  312. Rec->getValueAsString("MachineInstrFnName"));
  313. }
  314. if (Rec->isSubClassOf("CheckFunctionPredicateWithTII")) {
  315. return expandCheckFunctionPredicateWithTII(
  316. OS, Rec->getValueAsString("MCInstFnName"),
  317. Rec->getValueAsString("MachineInstrFnName"),
  318. Rec->getValueAsString("TIIPtrName"));
  319. }
  320. if (Rec->isSubClassOf("CheckNonPortable"))
  321. return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
  322. if (Rec->isSubClassOf("TIIPredicate"))
  323. return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName"));
  324. llvm_unreachable("No known rules to expand this MCInstPredicate");
  325. }
  326. void STIPredicateExpander::expandHeader(raw_ostream &OS,
  327. const STIPredicateFunction &Fn) {
  328. const Record *Rec = Fn.getDeclaration();
  329. StringRef FunctionName = Rec->getValueAsString("Name");
  330. OS.indent(getIndentLevel() * 2);
  331. OS << "bool ";
  332. if (shouldExpandDefinition())
  333. OS << getClassPrefix() << "::";
  334. OS << FunctionName << "(";
  335. if (shouldExpandForMC())
  336. OS << "const MCInst " << (isByRef() ? "&" : "*") << "MI";
  337. else
  338. OS << "const MachineInstr " << (isByRef() ? "&" : "*") << "MI";
  339. if (Rec->getValueAsBit("UpdatesOpcodeMask"))
  340. OS << ", APInt &Mask";
  341. OS << (shouldExpandForMC() ? ", unsigned ProcessorID) const " : ") const ");
  342. if (shouldExpandDefinition()) {
  343. OS << "{\n";
  344. return;
  345. }
  346. if (Rec->getValueAsBit("OverridesBaseClassMember"))
  347. OS << "override";
  348. OS << ";\n";
  349. }
  350. void STIPredicateExpander::expandPrologue(raw_ostream &OS,
  351. const STIPredicateFunction &Fn) {
  352. RecVec Delegates = Fn.getDeclaration()->getValueAsListOfDefs("Delegates");
  353. bool UpdatesOpcodeMask =
  354. Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
  355. increaseIndentLevel();
  356. unsigned IndentLevel = getIndentLevel();
  357. for (const Record *Delegate : Delegates) {
  358. OS.indent(IndentLevel * 2);
  359. OS << "if (" << Delegate->getValueAsString("Name") << "(MI";
  360. if (UpdatesOpcodeMask)
  361. OS << ", Mask";
  362. if (shouldExpandForMC())
  363. OS << ", ProcessorID";
  364. OS << "))\n";
  365. OS.indent((1 + IndentLevel) * 2);
  366. OS << "return true;\n\n";
  367. }
  368. if (shouldExpandForMC())
  369. return;
  370. OS.indent(IndentLevel * 2);
  371. OS << "unsigned ProcessorID = getSchedModel().getProcessorID();\n";
  372. }
  373. void STIPredicateExpander::expandOpcodeGroup(raw_ostream &OS, const OpcodeGroup &Group,
  374. bool ShouldUpdateOpcodeMask) {
  375. const OpcodeInfo &OI = Group.getOpcodeInfo();
  376. for (const PredicateInfo &PI : OI.getPredicates()) {
  377. const APInt &ProcModelMask = PI.ProcModelMask;
  378. bool FirstProcID = true;
  379. for (unsigned I = 0, E = ProcModelMask.getActiveBits(); I < E; ++I) {
  380. if (!ProcModelMask[I])
  381. continue;
  382. if (FirstProcID) {
  383. OS.indent(getIndentLevel() * 2);
  384. OS << "if (ProcessorID == " << I;
  385. } else {
  386. OS << " || ProcessorID == " << I;
  387. }
  388. FirstProcID = false;
  389. }
  390. OS << ") {\n";
  391. increaseIndentLevel();
  392. OS.indent(getIndentLevel() * 2);
  393. if (ShouldUpdateOpcodeMask) {
  394. if (PI.OperandMask.isZero())
  395. OS << "Mask.clearAllBits();\n";
  396. else
  397. OS << "Mask = " << PI.OperandMask << ";\n";
  398. OS.indent(getIndentLevel() * 2);
  399. }
  400. OS << "return ";
  401. expandPredicate(OS, PI.Predicate);
  402. OS << ";\n";
  403. decreaseIndentLevel();
  404. OS.indent(getIndentLevel() * 2);
  405. OS << "}\n";
  406. }
  407. }
  408. void STIPredicateExpander::expandBody(raw_ostream &OS,
  409. const STIPredicateFunction &Fn) {
  410. bool UpdatesOpcodeMask =
  411. Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
  412. unsigned IndentLevel = getIndentLevel();
  413. OS.indent(IndentLevel * 2);
  414. OS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
  415. OS.indent(IndentLevel * 2);
  416. OS << "default:\n";
  417. OS.indent(IndentLevel * 2);
  418. OS << " break;";
  419. for (const OpcodeGroup &Group : Fn.getGroups()) {
  420. for (const Record *Opcode : Group.getOpcodes()) {
  421. OS << '\n';
  422. OS.indent(IndentLevel * 2);
  423. OS << "case " << getTargetName() << "::" << Opcode->getName() << ":";
  424. }
  425. OS << '\n';
  426. increaseIndentLevel();
  427. expandOpcodeGroup(OS, Group, UpdatesOpcodeMask);
  428. OS.indent(getIndentLevel() * 2);
  429. OS << "break;\n";
  430. decreaseIndentLevel();
  431. }
  432. OS.indent(IndentLevel * 2);
  433. OS << "}\n";
  434. }
  435. void STIPredicateExpander::expandEpilogue(raw_ostream &OS,
  436. const STIPredicateFunction &Fn) {
  437. OS << '\n';
  438. OS.indent(getIndentLevel() * 2);
  439. OS << "return ";
  440. expandPredicate(OS, Fn.getDefaultReturnPredicate());
  441. OS << ";\n";
  442. decreaseIndentLevel();
  443. OS.indent(getIndentLevel() * 2);
  444. StringRef FunctionName = Fn.getDeclaration()->getValueAsString("Name");
  445. OS << "} // " << ClassPrefix << "::" << FunctionName << "\n\n";
  446. }
  447. void STIPredicateExpander::expandSTIPredicate(raw_ostream &OS,
  448. const STIPredicateFunction &Fn) {
  449. const Record *Rec = Fn.getDeclaration();
  450. if (shouldExpandForMC() && !Rec->getValueAsBit("ExpandForMC"))
  451. return;
  452. expandHeader(OS, Fn);
  453. if (shouldExpandDefinition()) {
  454. expandPrologue(OS, Fn);
  455. expandBody(OS, Fn);
  456. expandEpilogue(OS, Fn);
  457. }
  458. }
  459. } // namespace llvm