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