xref: /llvm-project/llvm/utils/TableGen/Common/CodeGenTarget.cpp (revision 73eecb70c2abb1c6149647ec213cb9312c398569)
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