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