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