CompressInstEmitter.cpp 38 KB

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