RISCVCompressInstEmitter.cpp 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893
  1. //===- RISCVCompressInstEmitter.cpp - Generator for RISCV Compression -===//
  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. // RISCVCompressInstEmitter implements a tablegen-driven CompressPat based
  8. // RISCV Instruction Compression mechanism.
  9. //
  10. //===--------------------------------------------------------------===//
  11. //
  12. // RISCVCompressInstEmitter implements a tablegen-driven CompressPat Instruction
  13. // Compression mechanism for generating RISCV compressed instructions
  14. // (C ISA Extension) from the expanded instruction form.
  15. // This tablegen backend processes CompressPat declarations in a
  16. // td file and generates all the required checks to validate the pattern
  17. // declarations; validate the input and output operands to generate the correct
  18. // compressed instructions. The checks include validating different types of
  19. // operands; register operands, immediate operands, fixed register and fixed
  20. // immediate inputs.
  21. //
  22. // Example:
  23. // class CompressPat<dag input, dag output> {
  24. // dag Input = input;
  25. // dag Output = output;
  26. // list<Predicate> Predicates = [];
  27. // }
  28. //
  29. // let Predicates = [HasStdExtC] in {
  30. // def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2),
  31. // (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
  32. // }
  33. //
  34. // The result is an auto-generated header file
  35. // 'RISCVGenCompressInstEmitter.inc' which exports two functions for
  36. // compressing/uncompressing MCInst instructions, plus
  37. // some helper functions:
  38. //
  39. // bool compressInst(MCInst &OutInst, const MCInst &MI,
  40. // const MCSubtargetInfo &STI,
  41. // MCContext &Context);
  42. //
  43. // bool uncompressInst(MCInst &OutInst, const MCInst &MI,
  44. // const MCRegisterInfo &MRI,
  45. // const MCSubtargetInfo &STI);
  46. //
  47. // In addition, it exports a function for checking whether
  48. // an instruction is compressable:
  49. //
  50. // bool isCompressibleInst(const MachineInstr& MI,
  51. // const RISCVSubtarget *Subtarget,
  52. // const MCRegisterInfo &MRI,
  53. // const MCSubtargetInfo &STI);
  54. //
  55. // The clients that include this auto-generated header file and
  56. // invoke these functions can compress an instruction before emitting
  57. // it in the target-specific ASM or ELF streamer or can uncompress
  58. // an instruction before printing it when the expanded instruction
  59. // format aliases is favored.
  60. //===----------------------------------------------------------------------===//
  61. #include "CodeGenInstruction.h"
  62. #include "CodeGenTarget.h"
  63. #include "llvm/ADT/IndexedMap.h"
  64. #include "llvm/ADT/SmallVector.h"
  65. #include "llvm/ADT/StringExtras.h"
  66. #include "llvm/ADT/StringMap.h"
  67. #include "llvm/Support/Debug.h"
  68. #include "llvm/Support/ErrorHandling.h"
  69. #include "llvm/TableGen/Error.h"
  70. #include "llvm/TableGen/Record.h"
  71. #include "llvm/TableGen/TableGenBackend.h"
  72. #include <set>
  73. #include <vector>
  74. using namespace llvm;
  75. #define DEBUG_TYPE "compress-inst-emitter"
  76. namespace {
  77. class RISCVCompressInstEmitter {
  78. struct OpData {
  79. enum MapKind { Operand, Imm, Reg };
  80. MapKind Kind;
  81. union {
  82. unsigned Operand; // Operand number mapped to.
  83. int64_t Imm; // Integer immediate value.
  84. Record *Reg; // Physical register.
  85. } Data;
  86. int TiedOpIdx = -1; // Tied operand index within the instruction.
  87. };
  88. struct CompressPat {
  89. CodeGenInstruction Source; // The source instruction definition.
  90. CodeGenInstruction Dest; // The destination instruction to transform to.
  91. std::vector<Record *>
  92. PatReqFeatures; // Required target features to enable pattern.
  93. IndexedMap<OpData>
  94. SourceOperandMap; // Maps operands in the Source Instruction to
  95. // the corresponding Dest instruction operand.
  96. IndexedMap<OpData>
  97. DestOperandMap; // Maps operands in the Dest Instruction
  98. // to the corresponding Source instruction operand.
  99. bool IsCompressOnly;
  100. CompressPat(CodeGenInstruction &S, CodeGenInstruction &D,
  101. std::vector<Record *> RF, IndexedMap<OpData> &SourceMap,
  102. IndexedMap<OpData> &DestMap, bool IsCompressOnly)
  103. : Source(S), Dest(D), PatReqFeatures(RF), SourceOperandMap(SourceMap),
  104. DestOperandMap(DestMap), IsCompressOnly(IsCompressOnly) {}
  105. };
  106. enum EmitterType { Compress, Uncompress, CheckCompress };
  107. RecordKeeper &Records;
  108. CodeGenTarget Target;
  109. SmallVector<CompressPat, 4> CompressPatterns;
  110. void addDagOperandMapping(Record *Rec, DagInit *Dag, CodeGenInstruction &Inst,
  111. IndexedMap<OpData> &OperandMap, bool IsSourceInst);
  112. void evaluateCompressPat(Record *Compress);
  113. void emitCompressInstEmitter(raw_ostream &o, EmitterType EType);
  114. bool validateTypes(Record *SubType, Record *Type, bool IsSourceInst);
  115. bool validateRegister(Record *Reg, Record *RegClass);
  116. void createDagOperandMapping(Record *Rec, StringMap<unsigned> &SourceOperands,
  117. StringMap<unsigned> &DestOperands,
  118. DagInit *SourceDag, DagInit *DestDag,
  119. IndexedMap<OpData> &SourceOperandMap);
  120. void createInstOperandMapping(Record *Rec, DagInit *SourceDag,
  121. DagInit *DestDag,
  122. IndexedMap<OpData> &SourceOperandMap,
  123. IndexedMap<OpData> &DestOperandMap,
  124. StringMap<unsigned> &SourceOperands,
  125. CodeGenInstruction &DestInst);
  126. public:
  127. RISCVCompressInstEmitter(RecordKeeper &R) : Records(R), Target(R) {}
  128. void run(raw_ostream &o);
  129. };
  130. } // End anonymous namespace.
  131. bool RISCVCompressInstEmitter::validateRegister(Record *Reg, Record *RegClass) {
  132. assert(Reg->isSubClassOf("Register") && "Reg record should be a Register");
  133. assert(RegClass->isSubClassOf("RegisterClass") &&
  134. "RegClass record should be a RegisterClass");
  135. const CodeGenRegisterClass &RC = Target.getRegisterClass(RegClass);
  136. const CodeGenRegister *R = Target.getRegisterByName(Reg->getName().lower());
  137. assert((R != nullptr) && "Register not defined!!");
  138. return RC.contains(R);
  139. }
  140. bool RISCVCompressInstEmitter::validateTypes(Record *DagOpType,
  141. Record *InstOpType,
  142. bool IsSourceInst) {
  143. if (DagOpType == InstOpType)
  144. return true;
  145. // Only source instruction operands are allowed to not match Input Dag
  146. // operands.
  147. if (!IsSourceInst)
  148. return false;
  149. if (DagOpType->isSubClassOf("RegisterClass") &&
  150. InstOpType->isSubClassOf("RegisterClass")) {
  151. const CodeGenRegisterClass &RC = Target.getRegisterClass(InstOpType);
  152. const CodeGenRegisterClass &SubRC = Target.getRegisterClass(DagOpType);
  153. return RC.hasSubClass(&SubRC);
  154. }
  155. // At this point either or both types are not registers, reject the pattern.
  156. if (DagOpType->isSubClassOf("RegisterClass") ||
  157. InstOpType->isSubClassOf("RegisterClass"))
  158. return false;
  159. // Let further validation happen when compress()/uncompress() functions are
  160. // invoked.
  161. LLVM_DEBUG(dbgs() << (IsSourceInst ? "Input" : "Output")
  162. << " Dag Operand Type: '" << DagOpType->getName()
  163. << "' and "
  164. << "Instruction Operand Type: '" << InstOpType->getName()
  165. << "' can't be checked at pattern validation time!\n");
  166. return true;
  167. }
  168. /// The patterns in the Dag contain different types of operands:
  169. /// Register operands, e.g.: GPRC:$rs1; Fixed registers, e.g: X1; Immediate
  170. /// operands, e.g.: simm6:$imm; Fixed immediate operands, e.g.: 0. This function
  171. /// maps Dag operands to its corresponding instruction operands. For register
  172. /// operands and fixed registers it expects the Dag operand type to be contained
  173. /// in the instantiated instruction operand type. For immediate operands and
  174. /// immediates no validation checks are enforced at pattern validation time.
  175. void RISCVCompressInstEmitter::addDagOperandMapping(
  176. Record *Rec, DagInit *Dag, CodeGenInstruction &Inst,
  177. IndexedMap<OpData> &OperandMap, bool IsSourceInst) {
  178. // TiedCount keeps track of the number of operands skipped in Inst
  179. // operands list to get to the corresponding Dag operand. This is
  180. // necessary because the number of operands in Inst might be greater
  181. // than number of operands in the Dag due to how tied operands
  182. // are represented.
  183. unsigned TiedCount = 0;
  184. for (unsigned i = 0, e = Inst.Operands.size(); i != e; ++i) {
  185. int TiedOpIdx = Inst.Operands[i].getTiedRegister();
  186. if (-1 != TiedOpIdx) {
  187. // Set the entry in OperandMap for the tied operand we're skipping.
  188. OperandMap[i].Kind = OperandMap[TiedOpIdx].Kind;
  189. OperandMap[i].Data = OperandMap[TiedOpIdx].Data;
  190. TiedCount++;
  191. continue;
  192. }
  193. if (DefInit *DI = dyn_cast<DefInit>(Dag->getArg(i - TiedCount))) {
  194. if (DI->getDef()->isSubClassOf("Register")) {
  195. // Check if the fixed register belongs to the Register class.
  196. if (!validateRegister(DI->getDef(), Inst.Operands[i].Rec))
  197. PrintFatalError(Rec->getLoc(),
  198. "Error in Dag '" + Dag->getAsString() +
  199. "'Register: '" + DI->getDef()->getName() +
  200. "' is not in register class '" +
  201. Inst.Operands[i].Rec->getName() + "'");
  202. OperandMap[i].Kind = OpData::Reg;
  203. OperandMap[i].Data.Reg = DI->getDef();
  204. continue;
  205. }
  206. // Validate that Dag operand type matches the type defined in the
  207. // corresponding instruction. Operands in the input Dag pattern are
  208. // allowed to be a subclass of the type specified in corresponding
  209. // instruction operand instead of being an exact match.
  210. if (!validateTypes(DI->getDef(), Inst.Operands[i].Rec, IsSourceInst))
  211. PrintFatalError(Rec->getLoc(),
  212. "Error in Dag '" + Dag->getAsString() + "'. Operand '" +
  213. Dag->getArgNameStr(i - TiedCount) + "' has type '" +
  214. DI->getDef()->getName() +
  215. "' which does not match the type '" +
  216. Inst.Operands[i].Rec->getName() +
  217. "' in the corresponding instruction operand!");
  218. OperandMap[i].Kind = OpData::Operand;
  219. } else if (IntInit *II = dyn_cast<IntInit>(Dag->getArg(i - TiedCount))) {
  220. // Validate that corresponding instruction operand expects an immediate.
  221. if (Inst.Operands[i].Rec->isSubClassOf("RegisterClass"))
  222. PrintFatalError(
  223. Rec->getLoc(),
  224. "Error in Dag '" + Dag->getAsString() + "' Found immediate: '" +
  225. II->getAsString() +
  226. "' but corresponding instruction operand expected a register!");
  227. // No pattern validation check possible for values of fixed immediate.
  228. OperandMap[i].Kind = OpData::Imm;
  229. OperandMap[i].Data.Imm = II->getValue();
  230. LLVM_DEBUG(
  231. dbgs() << " Found immediate '" << II->getValue() << "' at "
  232. << (IsSourceInst ? "input " : "output ")
  233. << "Dag. No validation time check possible for values of "
  234. "fixed immediate.\n");
  235. } else
  236. llvm_unreachable("Unhandled CompressPat argument type!");
  237. }
  238. }
  239. // Verify the Dag operand count is enough to build an instruction.
  240. static bool verifyDagOpCount(CodeGenInstruction &Inst, DagInit *Dag,
  241. bool IsSource) {
  242. if (Dag->getNumArgs() == Inst.Operands.size())
  243. return true;
  244. // Source instructions are non compressed instructions and don't have tied
  245. // operands.
  246. if (IsSource)
  247. PrintFatalError(Inst.TheDef->getLoc(),
  248. "Input operands for Inst '" + Inst.TheDef->getName() +
  249. "' and input Dag operand count mismatch");
  250. // The Dag can't have more arguments than the Instruction.
  251. if (Dag->getNumArgs() > Inst.Operands.size())
  252. PrintFatalError(Inst.TheDef->getLoc(),
  253. "Inst '" + Inst.TheDef->getName() +
  254. "' and Dag operand count mismatch");
  255. // The Instruction might have tied operands so the Dag might have
  256. // a fewer operand count.
  257. unsigned RealCount = Inst.Operands.size();
  258. for (unsigned i = 0; i < Inst.Operands.size(); i++)
  259. if (Inst.Operands[i].getTiedRegister() != -1)
  260. --RealCount;
  261. if (Dag->getNumArgs() != RealCount)
  262. PrintFatalError(Inst.TheDef->getLoc(),
  263. "Inst '" + Inst.TheDef->getName() +
  264. "' and Dag operand count mismatch");
  265. return true;
  266. }
  267. static bool validateArgsTypes(Init *Arg1, Init *Arg2) {
  268. return cast<DefInit>(Arg1)->getDef() == cast<DefInit>(Arg2)->getDef();
  269. }
  270. // Creates a mapping between the operand name in the Dag (e.g. $rs1) and
  271. // its index in the list of Dag operands and checks that operands with the same
  272. // name have the same types. For example in 'C_ADD $rs1, $rs2' we generate the
  273. // mapping $rs1 --> 0, $rs2 ---> 1. If the operand appears twice in the (tied)
  274. // same Dag we use the last occurrence for indexing.
  275. void RISCVCompressInstEmitter::createDagOperandMapping(
  276. Record *Rec, StringMap<unsigned> &SourceOperands,
  277. StringMap<unsigned> &DestOperands, DagInit *SourceDag, DagInit *DestDag,
  278. IndexedMap<OpData> &SourceOperandMap) {
  279. for (unsigned i = 0; i < DestDag->getNumArgs(); ++i) {
  280. // Skip fixed immediates and registers, they were handled in
  281. // addDagOperandMapping.
  282. if ("" == DestDag->getArgNameStr(i))
  283. continue;
  284. DestOperands[DestDag->getArgNameStr(i)] = i;
  285. }
  286. for (unsigned i = 0; i < SourceDag->getNumArgs(); ++i) {
  287. // Skip fixed immediates and registers, they were handled in
  288. // addDagOperandMapping.
  289. if ("" == SourceDag->getArgNameStr(i))
  290. continue;
  291. StringMap<unsigned>::iterator it =
  292. SourceOperands.find(SourceDag->getArgNameStr(i));
  293. if (it != SourceOperands.end()) {
  294. // Operand sharing the same name in the Dag should be mapped as tied.
  295. SourceOperandMap[i].TiedOpIdx = it->getValue();
  296. if (!validateArgsTypes(SourceDag->getArg(it->getValue()),
  297. SourceDag->getArg(i)))
  298. PrintFatalError(Rec->getLoc(),
  299. "Input Operand '" + SourceDag->getArgNameStr(i) +
  300. "' has a mismatched tied operand!\n");
  301. }
  302. it = DestOperands.find(SourceDag->getArgNameStr(i));
  303. if (it == DestOperands.end())
  304. PrintFatalError(Rec->getLoc(), "Operand " + SourceDag->getArgNameStr(i) +
  305. " defined in Input Dag but not used in"
  306. " Output Dag!\n");
  307. // Input Dag operand types must match output Dag operand type.
  308. if (!validateArgsTypes(DestDag->getArg(it->getValue()),
  309. SourceDag->getArg(i)))
  310. PrintFatalError(Rec->getLoc(), "Type mismatch between Input and "
  311. "Output Dag operand '" +
  312. SourceDag->getArgNameStr(i) + "'!");
  313. SourceOperands[SourceDag->getArgNameStr(i)] = i;
  314. }
  315. }
  316. /// Map operand names in the Dag to their index in both corresponding input and
  317. /// output instructions. Validate that operands defined in the input are
  318. /// used in the output pattern while populating the maps.
  319. void RISCVCompressInstEmitter::createInstOperandMapping(
  320. Record *Rec, DagInit *SourceDag, DagInit *DestDag,
  321. IndexedMap<OpData> &SourceOperandMap, IndexedMap<OpData> &DestOperandMap,
  322. StringMap<unsigned> &SourceOperands, CodeGenInstruction &DestInst) {
  323. // TiedCount keeps track of the number of operands skipped in Inst
  324. // operands list to get to the corresponding Dag operand.
  325. unsigned TiedCount = 0;
  326. LLVM_DEBUG(dbgs() << " Operand mapping:\n Source Dest\n");
  327. for (unsigned i = 0, e = DestInst.Operands.size(); i != e; ++i) {
  328. int TiedInstOpIdx = DestInst.Operands[i].getTiedRegister();
  329. if (TiedInstOpIdx != -1) {
  330. ++TiedCount;
  331. DestOperandMap[i].Data = DestOperandMap[TiedInstOpIdx].Data;
  332. DestOperandMap[i].Kind = DestOperandMap[TiedInstOpIdx].Kind;
  333. if (DestOperandMap[i].Kind == OpData::Operand)
  334. // No need to fill the SourceOperandMap here since it was mapped to
  335. // destination operand 'TiedInstOpIdx' in a previous iteration.
  336. LLVM_DEBUG(dbgs() << " " << DestOperandMap[i].Data.Operand
  337. << " ====> " << i
  338. << " Dest operand tied with operand '"
  339. << TiedInstOpIdx << "'\n");
  340. continue;
  341. }
  342. // Skip fixed immediates and registers, they were handled in
  343. // addDagOperandMapping.
  344. if (DestOperandMap[i].Kind != OpData::Operand)
  345. continue;
  346. unsigned DagArgIdx = i - TiedCount;
  347. StringMap<unsigned>::iterator SourceOp =
  348. SourceOperands.find(DestDag->getArgNameStr(DagArgIdx));
  349. if (SourceOp == SourceOperands.end())
  350. PrintFatalError(Rec->getLoc(),
  351. "Output Dag operand '" +
  352. DestDag->getArgNameStr(DagArgIdx) +
  353. "' has no matching input Dag operand.");
  354. assert(DestDag->getArgNameStr(DagArgIdx) ==
  355. SourceDag->getArgNameStr(SourceOp->getValue()) &&
  356. "Incorrect operand mapping detected!\n");
  357. DestOperandMap[i].Data.Operand = SourceOp->getValue();
  358. SourceOperandMap[SourceOp->getValue()].Data.Operand = i;
  359. LLVM_DEBUG(dbgs() << " " << SourceOp->getValue() << " ====> " << i
  360. << "\n");
  361. }
  362. }
  363. /// Validates the CompressPattern and create operand mapping.
  364. /// These are the checks to validate a CompressPat pattern declarations.
  365. /// Error out with message under these conditions:
  366. /// - Dag Input opcode is an expanded instruction and Dag Output opcode is a
  367. /// compressed instruction.
  368. /// - Operands in Dag Input must be all used in Dag Output.
  369. /// Register Operand type in Dag Input Type must be contained in the
  370. /// corresponding Source Instruction type.
  371. /// - Register Operand type in Dag Input must be the same as in Dag Ouput.
  372. /// - Register Operand type in Dag Output must be the same as the
  373. /// corresponding Destination Inst type.
  374. /// - Immediate Operand type in Dag Input must be the same as in Dag Ouput.
  375. /// - Immediate Operand type in Dag Ouput must be the same as the corresponding
  376. /// Destination Instruction type.
  377. /// - Fixed register must be contained in the corresponding Source Instruction
  378. /// type.
  379. /// - Fixed register must be contained in the corresponding Destination
  380. /// Instruction type. Warning message printed under these conditions:
  381. /// - Fixed immediate in Dag Input or Dag Ouput cannot be checked at this time
  382. /// and generate warning.
  383. /// - Immediate operand type in Dag Input differs from the corresponding Source
  384. /// Instruction type and generate a warning.
  385. void RISCVCompressInstEmitter::evaluateCompressPat(Record *Rec) {
  386. // Validate input Dag operands.
  387. DagInit *SourceDag = Rec->getValueAsDag("Input");
  388. assert(SourceDag && "Missing 'Input' in compress pattern!");
  389. LLVM_DEBUG(dbgs() << "Input: " << *SourceDag << "\n");
  390. // Checking we are transforming from compressed to uncompressed instructions.
  391. Record *Operator = SourceDag->getOperatorAsDef(Rec->getLoc());
  392. if (!Operator->isSubClassOf("RVInst"))
  393. PrintFatalError(Rec->getLoc(), "Input instruction '" + Operator->getName() +
  394. "' is not a 32 bit wide instruction!");
  395. CodeGenInstruction SourceInst(Operator);
  396. verifyDagOpCount(SourceInst, SourceDag, true);
  397. // Validate output Dag operands.
  398. DagInit *DestDag = Rec->getValueAsDag("Output");
  399. assert(DestDag && "Missing 'Output' in compress pattern!");
  400. LLVM_DEBUG(dbgs() << "Output: " << *DestDag << "\n");
  401. Record *DestOperator = DestDag->getOperatorAsDef(Rec->getLoc());
  402. if (!DestOperator->isSubClassOf("RVInst16"))
  403. PrintFatalError(Rec->getLoc(), "Output instruction '" +
  404. DestOperator->getName() +
  405. "' is not a 16 bit wide instruction!");
  406. CodeGenInstruction DestInst(DestOperator);
  407. verifyDagOpCount(DestInst, DestDag, false);
  408. // Fill the mapping from the source to destination instructions.
  409. IndexedMap<OpData> SourceOperandMap;
  410. SourceOperandMap.grow(SourceInst.Operands.size());
  411. // Create a mapping between source Dag operands and source Inst operands.
  412. addDagOperandMapping(Rec, SourceDag, SourceInst, SourceOperandMap,
  413. /*IsSourceInst*/ true);
  414. IndexedMap<OpData> DestOperandMap;
  415. DestOperandMap.grow(DestInst.Operands.size());
  416. // Create a mapping between destination Dag operands and destination Inst
  417. // operands.
  418. addDagOperandMapping(Rec, DestDag, DestInst, DestOperandMap,
  419. /*IsSourceInst*/ false);
  420. StringMap<unsigned> SourceOperands;
  421. StringMap<unsigned> DestOperands;
  422. createDagOperandMapping(Rec, SourceOperands, DestOperands, SourceDag, DestDag,
  423. SourceOperandMap);
  424. // Create operand mapping between the source and destination instructions.
  425. createInstOperandMapping(Rec, SourceDag, DestDag, SourceOperandMap,
  426. DestOperandMap, SourceOperands, DestInst);
  427. // Get the target features for the CompressPat.
  428. std::vector<Record *> PatReqFeatures;
  429. std::vector<Record *> RF = Rec->getValueAsListOfDefs("Predicates");
  430. copy_if(RF, std::back_inserter(PatReqFeatures), [](Record *R) {
  431. return R->getValueAsBit("AssemblerMatcherPredicate");
  432. });
  433. CompressPatterns.push_back(CompressPat(SourceInst, DestInst, PatReqFeatures,
  434. SourceOperandMap, DestOperandMap,
  435. Rec->getValueAsBit("isCompressOnly")));
  436. }
  437. static void
  438. getReqFeatures(std::set<std::pair<bool, StringRef>> &FeaturesSet,
  439. std::set<std::set<std::pair<bool, StringRef>>> &AnyOfFeatureSets,
  440. const std::vector<Record *> &ReqFeatures) {
  441. for (auto &R : ReqFeatures) {
  442. const DagInit *D = R->getValueAsDag("AssemblerCondDag");
  443. std::string CombineType = D->getOperator()->getAsString();
  444. if (CombineType != "any_of" && CombineType != "all_of")
  445. PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!");
  446. if (D->getNumArgs() == 0)
  447. PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!");
  448. bool IsOr = CombineType == "any_of";
  449. std::set<std::pair<bool, StringRef>> AnyOfSet;
  450. for (auto *Arg : D->getArgs()) {
  451. bool IsNot = false;
  452. if (auto *NotArg = dyn_cast<DagInit>(Arg)) {
  453. if (NotArg->getOperator()->getAsString() != "not" ||
  454. NotArg->getNumArgs() != 1)
  455. PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!");
  456. Arg = NotArg->getArg(0);
  457. IsNot = true;
  458. }
  459. if (!isa<DefInit>(Arg) ||
  460. !cast<DefInit>(Arg)->getDef()->isSubClassOf("SubtargetFeature"))
  461. PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!");
  462. if (IsOr)
  463. AnyOfSet.insert({IsNot, cast<DefInit>(Arg)->getDef()->getName()});
  464. else
  465. FeaturesSet.insert({IsNot, cast<DefInit>(Arg)->getDef()->getName()});
  466. }
  467. if (IsOr)
  468. AnyOfFeatureSets.insert(AnyOfSet);
  469. }
  470. }
  471. static unsigned getPredicates(DenseMap<const Record *, unsigned> &PredicateMap,
  472. std::vector<const Record *> &Predicates,
  473. Record *Rec, StringRef Name) {
  474. unsigned &Entry = PredicateMap[Rec];
  475. if (Entry)
  476. return Entry;
  477. if (!Rec->isValueUnset(Name)) {
  478. Predicates.push_back(Rec);
  479. Entry = Predicates.size();
  480. return Entry;
  481. }
  482. PrintFatalError(Rec->getLoc(), "No " + Name +
  483. " predicate on this operand at all: '" +
  484. Rec->getName() + "'");
  485. return 0;
  486. }
  487. static void printPredicates(const std::vector<const Record *> &Predicates,
  488. StringRef Name, raw_ostream &o) {
  489. for (unsigned i = 0; i < Predicates.size(); ++i) {
  490. StringRef Pred = Predicates[i]->getValueAsString(Name);
  491. o << " case " << i + 1 << ": {\n"
  492. << " // " << Predicates[i]->getName() << "\n"
  493. << " " << Pred << "\n"
  494. << " }\n";
  495. }
  496. }
  497. static void mergeCondAndCode(raw_ostream &CombinedStream, StringRef CondStr,
  498. StringRef CodeStr) {
  499. // Remove first indentation and last '&&'.
  500. CondStr = CondStr.drop_front(6).drop_back(4);
  501. CombinedStream.indent(4) << "if (" << CondStr << ") {\n";
  502. CombinedStream << CodeStr;
  503. CombinedStream.indent(4) << " return true;\n";
  504. CombinedStream.indent(4) << "} // if\n";
  505. }
  506. void RISCVCompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
  507. EmitterType EType) {
  508. Record *AsmWriter = Target.getAsmWriter();
  509. if (!AsmWriter->getValueAsInt("PassSubtarget"))
  510. PrintFatalError(AsmWriter->getLoc(),
  511. "'PassSubtarget' is false. SubTargetInfo object is needed "
  512. "for target features.\n");
  513. StringRef Namespace = Target.getName();
  514. // Sort entries in CompressPatterns to handle instructions that can have more
  515. // than one candidate for compression\uncompression, e.g ADD can be
  516. // transformed to a C_ADD or a C_MV. When emitting 'uncompress()' function the
  517. // source and destination are flipped and the sort key needs to change
  518. // accordingly.
  519. llvm::stable_sort(CompressPatterns, [EType](const CompressPat &LHS,
  520. const CompressPat &RHS) {
  521. if (EType == EmitterType::Compress || EType == EmitterType::CheckCompress)
  522. return (LHS.Source.TheDef->getName() < RHS.Source.TheDef->getName());
  523. else
  524. return (LHS.Dest.TheDef->getName() < RHS.Dest.TheDef->getName());
  525. });
  526. // A list of MCOperandPredicates for all operands in use, and the reverse map.
  527. std::vector<const Record *> MCOpPredicates;
  528. DenseMap<const Record *, unsigned> MCOpPredicateMap;
  529. // A list of ImmLeaf Predicates for all operands in use, and the reverse map.
  530. std::vector<const Record *> ImmLeafPredicates;
  531. DenseMap<const Record *, unsigned> ImmLeafPredicateMap;
  532. std::string F;
  533. std::string FH;
  534. raw_string_ostream Func(F);
  535. raw_string_ostream FuncH(FH);
  536. bool NeedMRI = false;
  537. if (EType == EmitterType::Compress)
  538. o << "\n#ifdef GEN_COMPRESS_INSTR\n"
  539. << "#undef GEN_COMPRESS_INSTR\n\n";
  540. else if (EType == EmitterType::Uncompress)
  541. o << "\n#ifdef GEN_UNCOMPRESS_INSTR\n"
  542. << "#undef GEN_UNCOMPRESS_INSTR\n\n";
  543. else if (EType == EmitterType::CheckCompress)
  544. o << "\n#ifdef GEN_CHECK_COMPRESS_INSTR\n"
  545. << "#undef GEN_CHECK_COMPRESS_INSTR\n\n";
  546. if (EType == EmitterType::Compress) {
  547. FuncH << "static bool compressInst(MCInst &OutInst,\n";
  548. FuncH.indent(25) << "const MCInst &MI,\n";
  549. FuncH.indent(25) << "const MCSubtargetInfo &STI,\n";
  550. FuncH.indent(25) << "MCContext &Context) {\n";
  551. } else if (EType == EmitterType::Uncompress){
  552. FuncH << "static bool uncompressInst(MCInst &OutInst,\n";
  553. FuncH.indent(27) << "const MCInst &MI,\n";
  554. FuncH.indent(27) << "const MCRegisterInfo &MRI,\n";
  555. FuncH.indent(27) << "const MCSubtargetInfo &STI) {\n";
  556. } else if (EType == EmitterType::CheckCompress) {
  557. FuncH << "static bool isCompressibleInst(const MachineInstr &MI,\n";
  558. FuncH.indent(27) << "const RISCVSubtarget *Subtarget,\n";
  559. FuncH.indent(27) << "const MCRegisterInfo &MRI,\n";
  560. FuncH.indent(27) << "const MCSubtargetInfo &STI) {\n";
  561. }
  562. if (CompressPatterns.empty()) {
  563. o << FuncH.str();
  564. o.indent(2) << "return false;\n}\n";
  565. if (EType == EmitterType::Compress)
  566. o << "\n#endif //GEN_COMPRESS_INSTR\n";
  567. else if (EType == EmitterType::Uncompress)
  568. o << "\n#endif //GEN_UNCOMPRESS_INSTR\n\n";
  569. else if (EType == EmitterType::CheckCompress)
  570. o << "\n#endif //GEN_CHECK_COMPRESS_INSTR\n\n";
  571. return;
  572. }
  573. std::string CaseString;
  574. raw_string_ostream CaseStream(CaseString);
  575. StringRef PrevOp;
  576. StringRef CurOp;
  577. CaseStream << " switch (MI.getOpcode()) {\n";
  578. CaseStream << " default: return false;\n";
  579. bool CompressOrCheck =
  580. EType == EmitterType::Compress || EType == EmitterType::CheckCompress;
  581. bool CompressOrUncompress =
  582. EType == EmitterType::Compress || EType == EmitterType::Uncompress;
  583. for (auto &CompressPat : CompressPatterns) {
  584. if (EType == EmitterType::Uncompress && CompressPat.IsCompressOnly)
  585. continue;
  586. std::string CondString;
  587. std::string CodeString;
  588. raw_string_ostream CondStream(CondString);
  589. raw_string_ostream CodeStream(CodeString);
  590. CodeGenInstruction &Source =
  591. CompressOrCheck ? CompressPat.Source : CompressPat.Dest;
  592. CodeGenInstruction &Dest =
  593. CompressOrCheck ? CompressPat.Dest : CompressPat.Source;
  594. IndexedMap<OpData> SourceOperandMap = CompressOrCheck ?
  595. CompressPat.SourceOperandMap : CompressPat.DestOperandMap;
  596. IndexedMap<OpData> &DestOperandMap = CompressOrCheck ?
  597. CompressPat.DestOperandMap : CompressPat.SourceOperandMap;
  598. CurOp = Source.TheDef->getName();
  599. // Check current and previous opcode to decide to continue or end a case.
  600. if (CurOp != PrevOp) {
  601. if (!PrevOp.empty())
  602. CaseStream.indent(6) << "break;\n } // case " + PrevOp + "\n";
  603. CaseStream.indent(4) << "case " + Namespace + "::" + CurOp + ": {\n";
  604. }
  605. std::set<std::pair<bool, StringRef>> FeaturesSet;
  606. std::set<std::set<std::pair<bool, StringRef>>> AnyOfFeatureSets;
  607. // Add CompressPat required features.
  608. getReqFeatures(FeaturesSet, AnyOfFeatureSets, CompressPat.PatReqFeatures);
  609. // Add Dest instruction required features.
  610. std::vector<Record *> ReqFeatures;
  611. std::vector<Record *> RF = Dest.TheDef->getValueAsListOfDefs("Predicates");
  612. copy_if(RF, std::back_inserter(ReqFeatures), [](Record *R) {
  613. return R->getValueAsBit("AssemblerMatcherPredicate");
  614. });
  615. getReqFeatures(FeaturesSet, AnyOfFeatureSets, ReqFeatures);
  616. // Emit checks for all required features.
  617. for (auto &Op : FeaturesSet) {
  618. StringRef Not = Op.first ? "!" : "";
  619. CondStream.indent(6) << Not << "STI.getFeatureBits()[" << Namespace
  620. << "::" << Op.second << "]"
  621. << " &&\n";
  622. }
  623. // Emit checks for all required feature groups.
  624. for (auto &Set : AnyOfFeatureSets) {
  625. CondStream.indent(6) << "(";
  626. for (auto &Op : Set) {
  627. bool isLast = &Op == &*Set.rbegin();
  628. StringRef Not = Op.first ? "!" : "";
  629. CondStream << Not << "STI.getFeatureBits()[" << Namespace
  630. << "::" << Op.second << "]";
  631. if (!isLast)
  632. CondStream << " || ";
  633. }
  634. CondStream << ") &&\n";
  635. }
  636. // Start Source Inst operands validation.
  637. unsigned OpNo = 0;
  638. for (OpNo = 0; OpNo < Source.Operands.size(); ++OpNo) {
  639. if (SourceOperandMap[OpNo].TiedOpIdx != -1) {
  640. if (Source.Operands[OpNo].Rec->isSubClassOf("RegisterClass"))
  641. CondStream.indent(6)
  642. << "(MI.getOperand(" << OpNo << ").getReg() == MI.getOperand("
  643. << SourceOperandMap[OpNo].TiedOpIdx << ").getReg()) &&\n";
  644. else
  645. PrintFatalError("Unexpected tied operand types!\n");
  646. }
  647. // Check for fixed immediates\registers in the source instruction.
  648. switch (SourceOperandMap[OpNo].Kind) {
  649. case OpData::Operand:
  650. // We don't need to do anything for source instruction operand checks.
  651. break;
  652. case OpData::Imm:
  653. CondStream.indent(6)
  654. << "(MI.getOperand(" << OpNo << ").isImm()) &&\n"
  655. << " (MI.getOperand(" << OpNo
  656. << ").getImm() == " << SourceOperandMap[OpNo].Data.Imm << ") &&\n";
  657. break;
  658. case OpData::Reg: {
  659. Record *Reg = SourceOperandMap[OpNo].Data.Reg;
  660. CondStream.indent(6)
  661. << "(MI.getOperand(" << OpNo << ").getReg() == " << Namespace
  662. << "::" << Reg->getName() << ") &&\n";
  663. break;
  664. }
  665. }
  666. }
  667. CodeStream.indent(6) << "// " << Dest.AsmString << "\n";
  668. if (CompressOrUncompress)
  669. CodeStream.indent(6) << "OutInst.setOpcode(" << Namespace
  670. << "::" << Dest.TheDef->getName() << ");\n";
  671. OpNo = 0;
  672. for (const auto &DestOperand : Dest.Operands) {
  673. CodeStream.indent(6) << "// Operand: " << DestOperand.Name << "\n";
  674. switch (DestOperandMap[OpNo].Kind) {
  675. case OpData::Operand: {
  676. unsigned OpIdx = DestOperandMap[OpNo].Data.Operand;
  677. // Check that the operand in the Source instruction fits
  678. // the type for the Dest instruction.
  679. if (DestOperand.Rec->isSubClassOf("RegisterClass")) {
  680. NeedMRI = true;
  681. // This is a register operand. Check the register class.
  682. // Don't check register class if this is a tied operand, it was done
  683. // for the operand its tied to.
  684. if (DestOperand.getTiedRegister() == -1)
  685. CondStream.indent(6) << "(MRI.getRegClass(" << Namespace
  686. << "::" << DestOperand.Rec->getName()
  687. << "RegClassID).contains(MI.getOperand("
  688. << OpIdx << ").getReg())) &&\n";
  689. if (CompressOrUncompress)
  690. CodeStream.indent(6)
  691. << "OutInst.addOperand(MI.getOperand(" << OpIdx << "));\n";
  692. } else {
  693. // Handling immediate operands.
  694. if (CompressOrUncompress) {
  695. unsigned Entry =
  696. getPredicates(MCOpPredicateMap, MCOpPredicates, DestOperand.Rec,
  697. "MCOperandPredicate");
  698. CondStream.indent(6)
  699. << Namespace << "ValidateMCOperand("
  700. << "MI.getOperand(" << OpIdx << "), STI, " << Entry << ") &&\n";
  701. } else {
  702. unsigned Entry =
  703. getPredicates(ImmLeafPredicateMap, ImmLeafPredicates,
  704. DestOperand.Rec, "ImmediateCode");
  705. CondStream.indent(6)
  706. << "MI.getOperand(" << OpIdx << ").isImm() &&\n";
  707. CondStream.indent(6) << Namespace << "ValidateMachineOperand("
  708. << "MI.getOperand(" << OpIdx
  709. << "), Subtarget, " << Entry << ") &&\n";
  710. }
  711. if (CompressOrUncompress)
  712. CodeStream.indent(6)
  713. << "OutInst.addOperand(MI.getOperand(" << OpIdx << "));\n";
  714. }
  715. break;
  716. }
  717. case OpData::Imm: {
  718. if (CompressOrUncompress) {
  719. unsigned Entry = getPredicates(MCOpPredicateMap, MCOpPredicates,
  720. DestOperand.Rec, "MCOperandPredicate");
  721. CondStream.indent(6)
  722. << Namespace << "ValidateMCOperand("
  723. << "MCOperand::createImm(" << DestOperandMap[OpNo].Data.Imm
  724. << "), STI, " << Entry << ") &&\n";
  725. } else {
  726. unsigned Entry = getPredicates(ImmLeafPredicateMap, ImmLeafPredicates,
  727. DestOperand.Rec, "ImmediateCode");
  728. CondStream.indent(6)
  729. << Namespace
  730. << "ValidateMachineOperand(MachineOperand::CreateImm("
  731. << DestOperandMap[OpNo].Data.Imm << "), SubTarget, " << Entry
  732. << ") &&\n";
  733. }
  734. if (CompressOrUncompress)
  735. CodeStream.indent(6) << "OutInst.addOperand(MCOperand::createImm("
  736. << DestOperandMap[OpNo].Data.Imm << "));\n";
  737. } break;
  738. case OpData::Reg: {
  739. if (CompressOrUncompress) {
  740. // Fixed register has been validated at pattern validation time.
  741. Record *Reg = DestOperandMap[OpNo].Data.Reg;
  742. CodeStream.indent(6)
  743. << "OutInst.addOperand(MCOperand::createReg(" << Namespace
  744. << "::" << Reg->getName() << "));\n";
  745. }
  746. } break;
  747. }
  748. ++OpNo;
  749. }
  750. if (CompressOrUncompress)
  751. CodeStream.indent(6) << "OutInst.setLoc(MI.getLoc());\n";
  752. mergeCondAndCode(CaseStream, CondStream.str(), CodeStream.str());
  753. PrevOp = CurOp;
  754. }
  755. Func << CaseStream.str() << "\n";
  756. // Close brace for the last case.
  757. Func.indent(4) << "} // case " << CurOp << "\n";
  758. Func.indent(2) << "} // switch\n";
  759. Func.indent(2) << "return false;\n}\n";
  760. if (!MCOpPredicates.empty()) {
  761. o << "static bool " << Namespace
  762. << "ValidateMCOperand(const MCOperand &MCOp,\n"
  763. << " const MCSubtargetInfo &STI,\n"
  764. << " unsigned PredicateIndex) {\n"
  765. << " switch (PredicateIndex) {\n"
  766. << " default:\n"
  767. << " llvm_unreachable(\"Unknown MCOperandPredicate kind\");\n"
  768. << " break;\n";
  769. printPredicates(MCOpPredicates, "MCOperandPredicate", o);
  770. o << " }\n"
  771. << "}\n\n";
  772. }
  773. if (!ImmLeafPredicates.empty()) {
  774. o << "static bool " << Namespace
  775. << "ValidateMachineOperand(const MachineOperand &MO,\n"
  776. << " const RISCVSubtarget *Subtarget,\n"
  777. << " unsigned PredicateIndex) {\n"
  778. << " int64_t Imm = MO.getImm();\n"
  779. << " switch (PredicateIndex) {\n"
  780. << " default:\n"
  781. << " llvm_unreachable(\"Unknown ImmLeaf Predicate kind\");\n"
  782. << " break;\n";
  783. printPredicates(ImmLeafPredicates, "ImmediateCode", o);
  784. o << " }\n"
  785. << "}\n\n";
  786. }
  787. o << FuncH.str();
  788. if (NeedMRI && EType == EmitterType::Compress)
  789. o.indent(2) << "const MCRegisterInfo &MRI = *Context.getRegisterInfo();\n";
  790. o << Func.str();
  791. if (EType == EmitterType::Compress)
  792. o << "\n#endif //GEN_COMPRESS_INSTR\n";
  793. else if (EType == EmitterType::Uncompress)
  794. o << "\n#endif //GEN_UNCOMPRESS_INSTR\n\n";
  795. else if (EType == EmitterType::CheckCompress)
  796. o << "\n#endif //GEN_CHECK_COMPRESS_INSTR\n\n";
  797. }
  798. void RISCVCompressInstEmitter::run(raw_ostream &o) {
  799. std::vector<Record *> Insts = Records.getAllDerivedDefinitions("CompressPat");
  800. // Process the CompressPat definitions, validating them as we do so.
  801. for (unsigned i = 0, e = Insts.size(); i != e; ++i)
  802. evaluateCompressPat(Insts[i]);
  803. // Emit file header.
  804. emitSourceFileHeader("Compress instruction Source Fragment", o);
  805. // Generate compressInst() function.
  806. emitCompressInstEmitter(o, EmitterType::Compress);
  807. // Generate uncompressInst() function.
  808. emitCompressInstEmitter(o, EmitterType::Uncompress);
  809. // Generate isCompressibleInst() function.
  810. emitCompressInstEmitter(o, EmitterType::CheckCompress);
  811. }
  812. namespace llvm {
  813. void EmitCompressInst(RecordKeeper &RK, raw_ostream &OS) {
  814. RISCVCompressInstEmitter(RK).run(OS);
  815. }
  816. } // namespace llvm