1 //===- CodeGenTarget.cpp - CodeGen Target Class Wrapper -------------------===// 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 //===----------------------------------------------------------------------===// 8 // 9 // This class wraps target description classes used by the various code 10 // generation TableGen backends. This makes it easier to access the data and 11 // provides a single place that needs to check it for validity. All of these 12 // classes abort on error conditions. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "CodeGenTarget.h" 17 #include "CodeGenInstruction.h" 18 #include "CodeGenRegisters.h" 19 #include "CodeGenSchedule.h" 20 #include "llvm/ADT/STLExtras.h" 21 #include "llvm/ADT/Twine.h" 22 #include "llvm/Support/CommandLine.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include "llvm/TableGen/Error.h" 25 #include "llvm/TableGen/Record.h" 26 #include <algorithm> 27 #include <iterator> 28 #include <tuple> 29 using namespace llvm; 30 31 cl::OptionCategory AsmParserCat("Options for -gen-asm-parser"); 32 cl::OptionCategory AsmWriterCat("Options for -gen-asm-writer"); 33 34 static cl::opt<unsigned> 35 AsmParserNum("asmparsernum", cl::init(0), 36 cl::desc("Make -gen-asm-parser emit assembly parser #N"), 37 cl::cat(AsmParserCat)); 38 39 static cl::opt<unsigned> 40 AsmWriterNum("asmwriternum", cl::init(0), 41 cl::desc("Make -gen-asm-writer emit assembly writer #N"), 42 cl::cat(AsmWriterCat)); 43 44 /// getValueType - Return the MVT::SimpleValueType that the specified TableGen 45 /// record corresponds to. 46 MVT::SimpleValueType llvm::getValueType(const Record *Rec) { 47 return (MVT::SimpleValueType)Rec->getValueAsInt("Value"); 48 } 49 50 StringRef llvm::getEnumName(MVT::SimpleValueType T) { 51 // clang-format off 52 switch (T) { 53 #define GET_VT_ATTR(Ty, N, Sz, Any, Int, FP, Vec, Sc, Tup, NF, NElem, EltTy) \ 54 case MVT::Ty: return "MVT::" # Ty; 55 #include "llvm/CodeGen/GenVT.inc" 56 default: llvm_unreachable("ILLEGAL VALUE TYPE!"); 57 } 58 // clang-format on 59 } 60 61 /// getQualifiedName - Return the name of the specified record, with a 62 /// namespace qualifier if the record contains one. 63 /// 64 std::string llvm::getQualifiedName(const Record *R) { 65 std::string Namespace; 66 if (R->getValue("Namespace")) 67 Namespace = std::string(R->getValueAsString("Namespace")); 68 if (Namespace.empty()) 69 return std::string(R->getName()); 70 return Namespace + "::" + R->getName().str(); 71 } 72 73 /// getTarget - Return the current instance of the Target class. 74 /// 75 CodeGenTarget::CodeGenTarget(const RecordKeeper &records) 76 : Records(records), CGH(records), Intrinsics(records) { 77 ArrayRef<const Record *> Targets = Records.getAllDerivedDefinitions("Target"); 78 if (Targets.size() == 0) 79 PrintFatalError("No 'Target' subclasses defined!"); 80 if (Targets.size() != 1) 81 PrintFatalError("Multiple subclasses of Target defined!"); 82 TargetRec = Targets[0]; 83 MacroFusions = Records.getAllDerivedDefinitions("Fusion"); 84 } 85 86 CodeGenTarget::~CodeGenTarget() {} 87 88 StringRef CodeGenTarget::getName() const { return TargetRec->getName(); } 89 90 /// getInstNamespace - Find and return the target machine's instruction 91 /// namespace. The namespace is cached because it is requested multiple times. 92 StringRef CodeGenTarget::getInstNamespace() const { 93 if (InstNamespace.empty()) { 94 for (const CodeGenInstruction *Inst : getInstructionsByEnumValue()) { 95 // We are not interested in the "TargetOpcode" namespace. 96 if (Inst->Namespace != "TargetOpcode") { 97 InstNamespace = Inst->Namespace; 98 break; 99 } 100 } 101 } 102 103 return InstNamespace; 104 } 105 106 StringRef CodeGenTarget::getRegNamespace() const { 107 auto &RegClasses = RegBank->getRegClasses(); 108 return RegClasses.size() > 0 ? RegClasses.front().Namespace : ""; 109 } 110 111 const Record *CodeGenTarget::getInstructionSet() const { 112 return TargetRec->getValueAsDef("InstructionSet"); 113 } 114 115 bool CodeGenTarget::getAllowRegisterRenaming() const { 116 return TargetRec->getValueAsInt("AllowRegisterRenaming"); 117 } 118 119 /// getAsmParser - Return the AssemblyParser definition for this target. 120 /// 121 const Record *CodeGenTarget::getAsmParser() const { 122 std::vector<const Record *> LI = 123 TargetRec->getValueAsListOfDefs("AssemblyParsers"); 124 if (AsmParserNum >= LI.size()) 125 PrintFatalError("Target does not have an AsmParser #" + 126 Twine(AsmParserNum) + "!"); 127 return LI[AsmParserNum]; 128 } 129 130 /// getAsmParserVariant - Return the AssemblyParserVariant definition for 131 /// this target. 132 /// 133 const Record *CodeGenTarget::getAsmParserVariant(unsigned Idx) const { 134 std::vector<const Record *> LI = 135 TargetRec->getValueAsListOfDefs("AssemblyParserVariants"); 136 if (Idx >= LI.size()) 137 PrintFatalError("Target does not have an AsmParserVariant #" + Twine(Idx) + 138 "!"); 139 return LI[Idx]; 140 } 141 142 /// getAsmParserVariantCount - Return the AssemblyParserVariant definition 143 /// available for this target. 144 /// 145 unsigned CodeGenTarget::getAsmParserVariantCount() const { 146 return TargetRec->getValueAsListOfDefs("AssemblyParserVariants").size(); 147 } 148 149 /// getAsmWriter - Return the AssemblyWriter definition for this target. 150 /// 151 const Record *CodeGenTarget::getAsmWriter() const { 152 std::vector<const Record *> LI = 153 TargetRec->getValueAsListOfDefs("AssemblyWriters"); 154 if (AsmWriterNum >= LI.size()) 155 PrintFatalError("Target does not have an AsmWriter #" + 156 Twine(AsmWriterNum) + "!"); 157 return LI[AsmWriterNum]; 158 } 159 160 CodeGenRegBank &CodeGenTarget::getRegBank() const { 161 if (!RegBank) 162 RegBank = std::make_unique<CodeGenRegBank>(Records, getHwModes()); 163 return *RegBank; 164 } 165 166 const CodeGenRegisterClass *CodeGenTarget::getSuperRegForSubReg( 167 const ValueTypeByHwMode &ValueTy, CodeGenRegBank &RegBank, 168 const CodeGenSubRegIndex *SubIdx, bool MustBeAllocatable) const { 169 std::vector<CodeGenRegisterClass *> Candidates; 170 auto &RegClasses = RegBank.getRegClasses(); 171 172 // Try to find a register class which supports ValueTy, and also contains 173 // SubIdx. 174 for (CodeGenRegisterClass &RC : RegClasses) { 175 // Is there a subclass of this class which contains this subregister index? 176 CodeGenRegisterClass *SubClassWithSubReg = RC.getSubClassWithSubReg(SubIdx); 177 if (!SubClassWithSubReg) 178 continue; 179 180 // We have a class. Check if it supports this value type. 181 if (!llvm::is_contained(SubClassWithSubReg->VTs, ValueTy)) 182 continue; 183 184 // If necessary, check that it is allocatable. 185 if (MustBeAllocatable && !SubClassWithSubReg->Allocatable) 186 continue; 187 188 // We have a register class which supports both the value type and 189 // subregister index. Remember it. 190 Candidates.push_back(SubClassWithSubReg); 191 } 192 193 // If we didn't find anything, we're done. 194 if (Candidates.empty()) 195 return nullptr; 196 197 // Find and return the largest of our candidate classes. 198 llvm::stable_sort(Candidates, [&](const CodeGenRegisterClass *A, 199 const CodeGenRegisterClass *B) { 200 if (A->getMembers().size() > B->getMembers().size()) 201 return true; 202 203 if (A->getMembers().size() < B->getMembers().size()) 204 return false; 205 206 // Order by name as a tie-breaker. 207 return StringRef(A->getName()) < B->getName(); 208 }); 209 210 return Candidates[0]; 211 } 212 213 /// getRegisterByName - If there is a register with the specific AsmName, 214 /// return it. 215 const CodeGenRegister *CodeGenTarget::getRegisterByName(StringRef Name) const { 216 return getRegBank().getRegistersByName().lookup(Name); 217 } 218 219 const CodeGenRegisterClass & 220 CodeGenTarget::getRegisterClass(const Record *R) const { 221 return *getRegBank().getRegClass(R); 222 } 223 224 std::vector<ValueTypeByHwMode> 225 CodeGenTarget::getRegisterVTs(const Record *R) const { 226 const CodeGenRegister *Reg = getRegBank().getReg(R); 227 std::vector<ValueTypeByHwMode> Result; 228 for (const auto &RC : getRegBank().getRegClasses()) { 229 if (RC.contains(Reg)) { 230 ArrayRef<ValueTypeByHwMode> InVTs = RC.getValueTypes(); 231 llvm::append_range(Result, InVTs); 232 } 233 } 234 235 // Remove duplicates. 236 llvm::sort(Result); 237 Result.erase(llvm::unique(Result), Result.end()); 238 return Result; 239 } 240 241 void CodeGenTarget::ReadLegalValueTypes() const { 242 for (const auto &RC : getRegBank().getRegClasses()) 243 llvm::append_range(LegalValueTypes, RC.VTs); 244 245 // Remove duplicates. 246 llvm::sort(LegalValueTypes); 247 LegalValueTypes.erase(llvm::unique(LegalValueTypes), LegalValueTypes.end()); 248 } 249 250 CodeGenSchedModels &CodeGenTarget::getSchedModels() const { 251 if (!SchedModels) 252 SchedModels = std::make_unique<CodeGenSchedModels>(Records, *this); 253 return *SchedModels; 254 } 255 256 void CodeGenTarget::ReadInstructions() const { 257 ArrayRef<const Record *> Insts = 258 Records.getAllDerivedDefinitions("Instruction"); 259 if (Insts.size() <= 2) 260 PrintFatalError("No 'Instruction' subclasses defined!"); 261 262 // Parse the instructions defined in the .td file. 263 for (const Record *R : Insts) { 264 Instructions[R] = std::make_unique<CodeGenInstruction>(R); 265 if (Instructions[R]->isVariableLengthEncoding()) 266 HasVariableLengthEncodings = true; 267 } 268 } 269 270 static const CodeGenInstruction *GetInstByName( 271 const char *Name, 272 const DenseMap<const Record *, std::unique_ptr<CodeGenInstruction>> &Insts, 273 const RecordKeeper &Records) { 274 const Record *Rec = Records.getDef(Name); 275 276 const auto I = Insts.find(Rec); 277 if (!Rec || I == Insts.end()) 278 PrintFatalError(Twine("Could not find '") + Name + "' instruction!"); 279 return I->second.get(); 280 } 281 282 static const char *FixedInstrs[] = { 283 #define HANDLE_TARGET_OPCODE(OPC) #OPC, 284 #include "llvm/Support/TargetOpcodes.def" 285 nullptr}; 286 287 unsigned CodeGenTarget::getNumFixedInstructions() { 288 return std::size(FixedInstrs) - 1; 289 } 290 291 /// Return all of the instructions defined by the target, ordered by 292 /// their enum value. 293 void CodeGenTarget::ComputeInstrsByEnum() const { 294 const auto &Insts = getInstructions(); 295 for (const char *const *p = FixedInstrs; *p; ++p) { 296 const CodeGenInstruction *Instr = GetInstByName(*p, Insts, Records); 297 assert(Instr && "Missing target independent instruction"); 298 assert(Instr->Namespace == "TargetOpcode" && "Bad namespace"); 299 InstrsByEnum.push_back(Instr); 300 } 301 unsigned EndOfPredefines = InstrsByEnum.size(); 302 assert(EndOfPredefines == getNumFixedInstructions() && 303 "Missing generic opcode"); 304 305 for (const auto &I : Insts) { 306 const CodeGenInstruction *CGI = I.second.get(); 307 if (CGI->Namespace != "TargetOpcode") { 308 InstrsByEnum.push_back(CGI); 309 if (CGI->TheDef->getValueAsBit("isPseudo")) 310 ++NumPseudoInstructions; 311 } 312 } 313 314 assert(InstrsByEnum.size() == Insts.size() && "Missing predefined instr"); 315 316 // All of the instructions are now in random order based on the map iteration. 317 llvm::sort( 318 InstrsByEnum.begin() + EndOfPredefines, InstrsByEnum.end(), 319 [](const CodeGenInstruction *Rec1, const CodeGenInstruction *Rec2) { 320 const auto &D1 = *Rec1->TheDef; 321 const auto &D2 = *Rec2->TheDef; 322 return std::tuple(!D1.getValueAsBit("isPseudo"), D1.getName()) < 323 std::tuple(!D2.getValueAsBit("isPseudo"), D2.getName()); 324 }); 325 326 // Assign an enum value to each instruction according to the sorted order. 327 unsigned Num = 0; 328 for (const CodeGenInstruction *Inst : InstrsByEnum) 329 Inst->EnumVal = Num++; 330 } 331 332 /// isLittleEndianEncoding - Return whether this target encodes its instruction 333 /// in little-endian format, i.e. bits laid out in the order [0..n] 334 /// 335 bool CodeGenTarget::isLittleEndianEncoding() const { 336 return getInstructionSet()->getValueAsBit("isLittleEndianEncoding"); 337 } 338 339 /// reverseBitsForLittleEndianEncoding - For little-endian instruction bit 340 /// encodings, reverse the bit order of all instructions. 341 void CodeGenTarget::reverseBitsForLittleEndianEncoding() { 342 if (!isLittleEndianEncoding()) 343 return; 344 345 for (const Record *R : 346 Records.getAllDerivedDefinitions("InstructionEncoding")) { 347 if (R->getValueAsString("Namespace") == "TargetOpcode" || 348 R->getValueAsBit("isPseudo")) 349 continue; 350 351 const BitsInit *BI = R->getValueAsBitsInit("Inst"); 352 353 unsigned numBits = BI->getNumBits(); 354 355 SmallVector<const Init *, 16> NewBits(numBits); 356 357 for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) { 358 unsigned bitSwapIdx = numBits - bit - 1; 359 const Init *OrigBit = BI->getBit(bit); 360 const Init *BitSwap = BI->getBit(bitSwapIdx); 361 NewBits[bit] = BitSwap; 362 NewBits[bitSwapIdx] = OrigBit; 363 } 364 if (numBits % 2) { 365 unsigned middle = (numBits + 1) / 2; 366 NewBits[middle] = BI->getBit(middle); 367 } 368 369 RecordKeeper &MutableRC = const_cast<RecordKeeper &>(Records); 370 const BitsInit *NewBI = BitsInit::get(MutableRC, NewBits); 371 372 // Update the bits in reversed order so that emitters will get the correct 373 // endianness. 374 // FIXME: Eliminate mutation of TG records by creating a helper function 375 // to reverse bits and maintain a cache instead of mutating records. 376 Record *MutableR = const_cast<Record *>(R); 377 MutableR->getValue("Inst")->setValue(NewBI); 378 } 379 } 380 381 /// guessInstructionProperties - Return true if it's OK to guess instruction 382 /// properties instead of raising an error. 383 /// 384 /// This is configurable as a temporary migration aid. It will eventually be 385 /// permanently false. 386 bool CodeGenTarget::guessInstructionProperties() const { 387 return getInstructionSet()->getValueAsBit("guessInstructionProperties"); 388 } 389 390 //===----------------------------------------------------------------------===// 391 // ComplexPattern implementation 392 // 393 ComplexPattern::ComplexPattern(const Record *R) { 394 Ty = R->getValueAsDef("Ty"); 395 NumOperands = R->getValueAsInt("NumOperands"); 396 SelectFunc = std::string(R->getValueAsString("SelectFunc")); 397 RootNodes = R->getValueAsListOfDefs("RootNodes"); 398 399 // FIXME: This is a hack to statically increase the priority of patterns which 400 // maps a sub-dag to a complex pattern. e.g. favors LEA over ADD. To get best 401 // possible pattern match we'll need to dynamically calculate the complexity 402 // of all patterns a dag can potentially map to. 403 int64_t RawComplexity = R->getValueAsInt("Complexity"); 404 if (RawComplexity == -1) 405 Complexity = NumOperands * 3; 406 else 407 Complexity = RawComplexity; 408 409 // FIXME: Why is this different from parseSDPatternOperatorProperties? 410 // Parse the properties. 411 Properties = 0; 412 for (const Record *Prop : R->getValueAsListOfDefs("Properties")) { 413 if (Prop->getName() == "SDNPHasChain") { 414 Properties |= 1 << SDNPHasChain; 415 } else if (Prop->getName() == "SDNPOptInGlue") { 416 Properties |= 1 << SDNPOptInGlue; 417 } else if (Prop->getName() == "SDNPMayStore") { 418 Properties |= 1 << SDNPMayStore; 419 } else if (Prop->getName() == "SDNPMayLoad") { 420 Properties |= 1 << SDNPMayLoad; 421 } else if (Prop->getName() == "SDNPSideEffect") { 422 Properties |= 1 << SDNPSideEffect; 423 } else if (Prop->getName() == "SDNPMemOperand") { 424 Properties |= 1 << SDNPMemOperand; 425 } else if (Prop->getName() == "SDNPVariadic") { 426 Properties |= 1 << SDNPVariadic; 427 } else { 428 PrintFatalError(R->getLoc(), 429 "Unsupported SD Node property '" + Prop->getName() + 430 "' on ComplexPattern '" + R->getName() + "'!"); 431 } 432 } 433 434 WantsRoot = R->getValueAsBit("WantsRoot"); 435 WantsParent = R->getValueAsBit("WantsParent"); 436 } 437