xref: /freebsd-src/contrib/llvm-project/llvm/utils/TableGen/FastISelEmitter.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1*0fca6ea1SDimitry Andric ///===- FastISelEmitter.cpp - Generate an instruction selector ------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This tablegen backend emits code for use by the "fast" instruction
100b57cec5SDimitry Andric // selection algorithm. See the comments at the top of
110b57cec5SDimitry Andric // lib/CodeGen/SelectionDAG/FastISel.cpp for background.
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric // This file scans through the target's tablegen instruction-info files
140b57cec5SDimitry Andric // and extracts instructions with obvious-looking patterns, and it emits
150b57cec5SDimitry Andric // code to look up these instructions by type and operator.
160b57cec5SDimitry Andric //
170b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
180b57cec5SDimitry Andric 
19*0fca6ea1SDimitry Andric #include "Common/CodeGenDAGPatterns.h"
20*0fca6ea1SDimitry Andric #include "Common/CodeGenInstruction.h"
21*0fca6ea1SDimitry Andric #include "Common/CodeGenRegisters.h"
22*0fca6ea1SDimitry Andric #include "Common/CodeGenTarget.h"
23*0fca6ea1SDimitry Andric #include "Common/InfoByHwMode.h"
240b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
250b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
260b57cec5SDimitry Andric #include "llvm/TableGen/Error.h"
270b57cec5SDimitry Andric #include "llvm/TableGen/Record.h"
280b57cec5SDimitry Andric #include "llvm/TableGen/TableGenBackend.h"
295f757f3fSDimitry Andric #include <set>
300b57cec5SDimitry Andric #include <utility>
310b57cec5SDimitry Andric using namespace llvm;
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric /// InstructionMemo - This class holds additional information about an
340b57cec5SDimitry Andric /// instruction needed to emit code for it.
350b57cec5SDimitry Andric ///
360b57cec5SDimitry Andric namespace {
370b57cec5SDimitry Andric struct InstructionMemo {
380b57cec5SDimitry Andric   std::string Name;
390b57cec5SDimitry Andric   const CodeGenRegisterClass *RC;
400b57cec5SDimitry Andric   std::string SubRegNo;
410b57cec5SDimitry Andric   std::vector<std::string> PhysRegs;
420b57cec5SDimitry Andric   std::string PredicateCheck;
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric   InstructionMemo(StringRef Name, const CodeGenRegisterClass *RC,
450b57cec5SDimitry Andric                   std::string SubRegNo, std::vector<std::string> PhysRegs,
460b57cec5SDimitry Andric                   std::string PredicateCheck)
470b57cec5SDimitry Andric       : Name(Name), RC(RC), SubRegNo(std::move(SubRegNo)),
480b57cec5SDimitry Andric         PhysRegs(std::move(PhysRegs)),
490b57cec5SDimitry Andric         PredicateCheck(std::move(PredicateCheck)) {}
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric   // Make sure we do not copy InstructionMemo.
520b57cec5SDimitry Andric   InstructionMemo(const InstructionMemo &Other) = delete;
530b57cec5SDimitry Andric   InstructionMemo(InstructionMemo &&Other) = default;
540b57cec5SDimitry Andric };
550b57cec5SDimitry Andric } // End anonymous namespace
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric /// ImmPredicateSet - This uniques predicates (represented as a string) and
580b57cec5SDimitry Andric /// gives them unique (small) integer ID's that start at 0.
590b57cec5SDimitry Andric namespace {
600b57cec5SDimitry Andric class ImmPredicateSet {
610b57cec5SDimitry Andric   DenseMap<TreePattern *, unsigned> ImmIDs;
620b57cec5SDimitry Andric   std::vector<TreePredicateFn> PredsByName;
630b57cec5SDimitry Andric 
64*0fca6ea1SDimitry Andric public:
650b57cec5SDimitry Andric   unsigned getIDFor(TreePredicateFn Pred) {
660b57cec5SDimitry Andric     unsigned &Entry = ImmIDs[Pred.getOrigPatFragRecord()];
670b57cec5SDimitry Andric     if (Entry == 0) {
680b57cec5SDimitry Andric       PredsByName.push_back(Pred);
690b57cec5SDimitry Andric       Entry = PredsByName.size();
700b57cec5SDimitry Andric     }
710b57cec5SDimitry Andric     return Entry - 1;
720b57cec5SDimitry Andric   }
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric   const TreePredicateFn &getPredicate(unsigned i) {
750b57cec5SDimitry Andric     assert(i < PredsByName.size());
760b57cec5SDimitry Andric     return PredsByName[i];
770b57cec5SDimitry Andric   }
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric   typedef std::vector<TreePredicateFn>::const_iterator iterator;
800b57cec5SDimitry Andric   iterator begin() const { return PredsByName.begin(); }
810b57cec5SDimitry Andric   iterator end() const { return PredsByName.end(); }
820b57cec5SDimitry Andric };
830b57cec5SDimitry Andric } // End anonymous namespace
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric /// OperandsSignature - This class holds a description of a list of operand
860b57cec5SDimitry Andric /// types. It has utility methods for emitting text based on the operands.
870b57cec5SDimitry Andric ///
880b57cec5SDimitry Andric namespace {
890b57cec5SDimitry Andric struct OperandsSignature {
900b57cec5SDimitry Andric   class OpKind {
910b57cec5SDimitry Andric     enum { OK_Reg, OK_FP, OK_Imm, OK_Invalid = -1 };
920b57cec5SDimitry Andric     char Repr;
930b57cec5SDimitry Andric 
94*0fca6ea1SDimitry Andric   public:
950b57cec5SDimitry Andric     OpKind() : Repr(OK_Invalid) {}
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric     bool operator<(OpKind RHS) const { return Repr < RHS.Repr; }
980b57cec5SDimitry Andric     bool operator==(OpKind RHS) const { return Repr == RHS.Repr; }
990b57cec5SDimitry Andric 
100*0fca6ea1SDimitry Andric     static OpKind getReg() {
101*0fca6ea1SDimitry Andric       OpKind K;
102*0fca6ea1SDimitry Andric       K.Repr = OK_Reg;
103*0fca6ea1SDimitry Andric       return K;
104*0fca6ea1SDimitry Andric     }
105*0fca6ea1SDimitry Andric     static OpKind getFP() {
106*0fca6ea1SDimitry Andric       OpKind K;
107*0fca6ea1SDimitry Andric       K.Repr = OK_FP;
108*0fca6ea1SDimitry Andric       return K;
109*0fca6ea1SDimitry Andric     }
1100b57cec5SDimitry Andric     static OpKind getImm(unsigned V) {
1110b57cec5SDimitry Andric       assert((unsigned)OK_Imm + V < 128 &&
1120b57cec5SDimitry Andric              "Too many integer predicates for the 'Repr' char");
113*0fca6ea1SDimitry Andric       OpKind K;
114*0fca6ea1SDimitry Andric       K.Repr = OK_Imm + V;
115*0fca6ea1SDimitry Andric       return K;
1160b57cec5SDimitry Andric     }
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric     bool isReg() const { return Repr == OK_Reg; }
1190b57cec5SDimitry Andric     bool isFP() const { return Repr == OK_FP; }
1200b57cec5SDimitry Andric     bool isImm() const { return Repr >= OK_Imm; }
1210b57cec5SDimitry Andric 
122*0fca6ea1SDimitry Andric     unsigned getImmCode() const {
123*0fca6ea1SDimitry Andric       assert(isImm());
124*0fca6ea1SDimitry Andric       return Repr - OK_Imm;
125*0fca6ea1SDimitry Andric     }
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric     void printManglingSuffix(raw_ostream &OS, ImmPredicateSet &ImmPredicates,
1280b57cec5SDimitry Andric                              bool StripImmCodes) const {
1290b57cec5SDimitry Andric       if (isReg())
1300b57cec5SDimitry Andric         OS << 'r';
1310b57cec5SDimitry Andric       else if (isFP())
1320b57cec5SDimitry Andric         OS << 'f';
1330b57cec5SDimitry Andric       else {
1340b57cec5SDimitry Andric         OS << 'i';
1350b57cec5SDimitry Andric         if (!StripImmCodes)
1360b57cec5SDimitry Andric           if (unsigned Code = getImmCode())
1370b57cec5SDimitry Andric             OS << "_" << ImmPredicates.getPredicate(Code - 1).getFnName();
1380b57cec5SDimitry Andric       }
1390b57cec5SDimitry Andric     }
1400b57cec5SDimitry Andric   };
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric   SmallVector<OpKind, 3> Operands;
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric   bool operator<(const OperandsSignature &O) const {
1450b57cec5SDimitry Andric     return Operands < O.Operands;
1460b57cec5SDimitry Andric   }
1470b57cec5SDimitry Andric   bool operator==(const OperandsSignature &O) const {
1480b57cec5SDimitry Andric     return Operands == O.Operands;
1490b57cec5SDimitry Andric   }
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric   bool empty() const { return Operands.empty(); }
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric   bool hasAnyImmediateCodes() const {
1540b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i)
1550b57cec5SDimitry Andric       if (Operands[i].isImm() && Operands[i].getImmCode() != 0)
1560b57cec5SDimitry Andric         return true;
1570b57cec5SDimitry Andric     return false;
1580b57cec5SDimitry Andric   }
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   /// getWithoutImmCodes - Return a copy of this with any immediate codes forced
1610b57cec5SDimitry Andric   /// to zero.
1620b57cec5SDimitry Andric   OperandsSignature getWithoutImmCodes() const {
1630b57cec5SDimitry Andric     OperandsSignature Result;
1640b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i)
1650b57cec5SDimitry Andric       if (!Operands[i].isImm())
1660b57cec5SDimitry Andric         Result.Operands.push_back(Operands[i]);
1670b57cec5SDimitry Andric       else
1680b57cec5SDimitry Andric         Result.Operands.push_back(OpKind::getImm(0));
1690b57cec5SDimitry Andric     return Result;
1700b57cec5SDimitry Andric   }
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric   void emitImmediatePredicate(raw_ostream &OS, ImmPredicateSet &ImmPredicates) {
1730b57cec5SDimitry Andric     bool EmittedAnything = false;
1740b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
175*0fca6ea1SDimitry Andric       if (!Operands[i].isImm())
176*0fca6ea1SDimitry Andric         continue;
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric       unsigned Code = Operands[i].getImmCode();
179*0fca6ea1SDimitry Andric       if (Code == 0)
180*0fca6ea1SDimitry Andric         continue;
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric       if (EmittedAnything)
1830b57cec5SDimitry Andric         OS << " &&\n        ";
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric       TreePredicateFn PredFn = ImmPredicates.getPredicate(Code - 1);
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric       // Emit the type check.
1880b57cec5SDimitry Andric       TreePattern *TP = PredFn.getOrigPatFragRecord();
1890b57cec5SDimitry Andric       ValueTypeByHwMode VVT = TP->getTree(0)->getType(0);
1900b57cec5SDimitry Andric       assert(VVT.isSimple() &&
1910b57cec5SDimitry Andric              "Cannot use variable value types with fast isel");
1920b57cec5SDimitry Andric       OS << "VT == " << getEnumName(VVT.getSimple().SimpleTy) << " && ";
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric       OS << PredFn.getFnName() << "(imm" << i << ')';
1950b57cec5SDimitry Andric       EmittedAnything = true;
1960b57cec5SDimitry Andric     }
1970b57cec5SDimitry Andric   }
1980b57cec5SDimitry Andric 
1990b57cec5SDimitry Andric   /// initialize - Examine the given pattern and initialize the contents
2000b57cec5SDimitry Andric   /// of the Operands array accordingly. Return true if all the operands
2010b57cec5SDimitry Andric   /// are supported, false otherwise.
2020b57cec5SDimitry Andric   ///
203*0fca6ea1SDimitry Andric   bool initialize(TreePatternNode &InstPatNode, const CodeGenTarget &Target,
204*0fca6ea1SDimitry Andric                   MVT::SimpleValueType VT, ImmPredicateSet &ImmediatePredicates,
2050b57cec5SDimitry Andric                   const CodeGenRegisterClass *OrigDstRC) {
206*0fca6ea1SDimitry Andric     if (InstPatNode.isLeaf())
2070b57cec5SDimitry Andric       return false;
2080b57cec5SDimitry Andric 
209*0fca6ea1SDimitry Andric     if (InstPatNode.getOperator()->getName() == "imm") {
2100b57cec5SDimitry Andric       Operands.push_back(OpKind::getImm(0));
2110b57cec5SDimitry Andric       return true;
2120b57cec5SDimitry Andric     }
2130b57cec5SDimitry Andric 
214*0fca6ea1SDimitry Andric     if (InstPatNode.getOperator()->getName() == "fpimm") {
2150b57cec5SDimitry Andric       Operands.push_back(OpKind::getFP());
2160b57cec5SDimitry Andric       return true;
2170b57cec5SDimitry Andric     }
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric     const CodeGenRegisterClass *DstRC = nullptr;
2200b57cec5SDimitry Andric 
221*0fca6ea1SDimitry Andric     for (unsigned i = 0, e = InstPatNode.getNumChildren(); i != e; ++i) {
222*0fca6ea1SDimitry Andric       TreePatternNode &Op = InstPatNode.getChild(i);
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric       // Handle imm operands specially.
225*0fca6ea1SDimitry Andric       if (!Op.isLeaf() && Op.getOperator()->getName() == "imm") {
2260b57cec5SDimitry Andric         unsigned PredNo = 0;
227*0fca6ea1SDimitry Andric         if (!Op.getPredicateCalls().empty()) {
228*0fca6ea1SDimitry Andric           TreePredicateFn PredFn = Op.getPredicateCalls()[0].Fn;
2290b57cec5SDimitry Andric           // If there is more than one predicate weighing in on this operand
2300b57cec5SDimitry Andric           // then we don't handle it.  This doesn't typically happen for
2310b57cec5SDimitry Andric           // immediates anyway.
232*0fca6ea1SDimitry Andric           if (Op.getPredicateCalls().size() > 1 ||
2330b57cec5SDimitry Andric               !PredFn.isImmediatePattern() || PredFn.usesOperands())
2340b57cec5SDimitry Andric             return false;
2350b57cec5SDimitry Andric           // Ignore any instruction with 'FastIselShouldIgnore', these are
2360b57cec5SDimitry Andric           // not needed and just bloat the fast instruction selector.  For
2370b57cec5SDimitry Andric           // example, X86 doesn't need to generate code to match ADD16ri8 since
2380b57cec5SDimitry Andric           // ADD16ri will do just fine.
2390b57cec5SDimitry Andric           Record *Rec = PredFn.getOrigPatFragRecord()->getRecord();
2400b57cec5SDimitry Andric           if (Rec->getValueAsBit("FastIselShouldIgnore"))
2410b57cec5SDimitry Andric             return false;
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric           PredNo = ImmediatePredicates.getIDFor(PredFn) + 1;
2440b57cec5SDimitry Andric         }
2450b57cec5SDimitry Andric 
2460b57cec5SDimitry Andric         Operands.push_back(OpKind::getImm(PredNo));
2470b57cec5SDimitry Andric         continue;
2480b57cec5SDimitry Andric       }
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric       // For now, filter out any operand with a predicate.
2510b57cec5SDimitry Andric       // For now, filter out any operand with multiple values.
252*0fca6ea1SDimitry Andric       if (!Op.getPredicateCalls().empty() || Op.getNumTypes() != 1)
2530b57cec5SDimitry Andric         return false;
2540b57cec5SDimitry Andric 
255*0fca6ea1SDimitry Andric       if (!Op.isLeaf()) {
256*0fca6ea1SDimitry Andric         if (Op.getOperator()->getName() == "fpimm") {
2570b57cec5SDimitry Andric           Operands.push_back(OpKind::getFP());
2580b57cec5SDimitry Andric           continue;
2590b57cec5SDimitry Andric         }
2600b57cec5SDimitry Andric         // For now, ignore other non-leaf nodes.
2610b57cec5SDimitry Andric         return false;
2620b57cec5SDimitry Andric       }
2630b57cec5SDimitry Andric 
264*0fca6ea1SDimitry Andric       assert(Op.hasConcreteType(0) && "Type infererence not done?");
2650b57cec5SDimitry Andric 
2660b57cec5SDimitry Andric       // For now, all the operands must have the same type (if they aren't
2670b57cec5SDimitry Andric       // immediates).  Note that this causes us to reject variable sized shifts
2680b57cec5SDimitry Andric       // on X86.
269*0fca6ea1SDimitry Andric       if (Op.getSimpleType(0) != VT)
2700b57cec5SDimitry Andric         return false;
2710b57cec5SDimitry Andric 
272*0fca6ea1SDimitry Andric       DefInit *OpDI = dyn_cast<DefInit>(Op.getLeafValue());
2730b57cec5SDimitry Andric       if (!OpDI)
2740b57cec5SDimitry Andric         return false;
2750b57cec5SDimitry Andric       Record *OpLeafRec = OpDI->getDef();
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric       // For now, the only other thing we accept is register operands.
2780b57cec5SDimitry Andric       const CodeGenRegisterClass *RC = nullptr;
2790b57cec5SDimitry Andric       if (OpLeafRec->isSubClassOf("RegisterOperand"))
2800b57cec5SDimitry Andric         OpLeafRec = OpLeafRec->getValueAsDef("RegClass");
2810b57cec5SDimitry Andric       if (OpLeafRec->isSubClassOf("RegisterClass"))
2820b57cec5SDimitry Andric         RC = &Target.getRegisterClass(OpLeafRec);
2830b57cec5SDimitry Andric       else if (OpLeafRec->isSubClassOf("Register"))
2840b57cec5SDimitry Andric         RC = Target.getRegBank().getRegClassForRegister(OpLeafRec);
2850b57cec5SDimitry Andric       else if (OpLeafRec->isSubClassOf("ValueType")) {
2860b57cec5SDimitry Andric         RC = OrigDstRC;
2870b57cec5SDimitry Andric       } else
2880b57cec5SDimitry Andric         return false;
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric       // For now, this needs to be a register class of some sort.
2910b57cec5SDimitry Andric       if (!RC)
2920b57cec5SDimitry Andric         return false;
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric       // For now, all the operands must have the same register class or be
2950b57cec5SDimitry Andric       // a strict subclass of the destination.
2960b57cec5SDimitry Andric       if (DstRC) {
2970b57cec5SDimitry Andric         if (DstRC != RC && !DstRC->hasSubClass(RC))
2980b57cec5SDimitry Andric           return false;
2990b57cec5SDimitry Andric       } else
3000b57cec5SDimitry Andric         DstRC = RC;
3010b57cec5SDimitry Andric       Operands.push_back(OpKind::getReg());
3020b57cec5SDimitry Andric     }
3030b57cec5SDimitry Andric     return true;
3040b57cec5SDimitry Andric   }
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric   void PrintParameters(raw_ostream &OS) const {
307fe6060f1SDimitry Andric     ListSeparator LS;
3080b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
309fe6060f1SDimitry Andric       OS << LS;
3100b57cec5SDimitry Andric       if (Operands[i].isReg()) {
311fe6060f1SDimitry Andric         OS << "unsigned Op" << i;
3120b57cec5SDimitry Andric       } else if (Operands[i].isImm()) {
3130b57cec5SDimitry Andric         OS << "uint64_t imm" << i;
3140b57cec5SDimitry Andric       } else if (Operands[i].isFP()) {
3150b57cec5SDimitry Andric         OS << "const ConstantFP *f" << i;
3160b57cec5SDimitry Andric       } else {
3170b57cec5SDimitry Andric         llvm_unreachable("Unknown operand kind!");
3180b57cec5SDimitry Andric       }
3190b57cec5SDimitry Andric     }
3200b57cec5SDimitry Andric   }
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric   void PrintArguments(raw_ostream &OS,
3230b57cec5SDimitry Andric                       const std::vector<std::string> &PR) const {
3240b57cec5SDimitry Andric     assert(PR.size() == Operands.size());
325fe6060f1SDimitry Andric     ListSeparator LS;
3260b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
3270b57cec5SDimitry Andric       if (PR[i] != "")
3280b57cec5SDimitry Andric         // Implicit physical register operand.
3290b57cec5SDimitry Andric         continue;
3300b57cec5SDimitry Andric 
331fe6060f1SDimitry Andric       OS << LS;
3320b57cec5SDimitry Andric       if (Operands[i].isReg()) {
333fe6060f1SDimitry Andric         OS << "Op" << i;
3340b57cec5SDimitry Andric       } else if (Operands[i].isImm()) {
3350b57cec5SDimitry Andric         OS << "imm" << i;
3360b57cec5SDimitry Andric       } else if (Operands[i].isFP()) {
3370b57cec5SDimitry Andric         OS << "f" << i;
3380b57cec5SDimitry Andric       } else {
3390b57cec5SDimitry Andric         llvm_unreachable("Unknown operand kind!");
3400b57cec5SDimitry Andric       }
3410b57cec5SDimitry Andric     }
3420b57cec5SDimitry Andric   }
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric   void PrintArguments(raw_ostream &OS) const {
345fe6060f1SDimitry Andric     ListSeparator LS;
3460b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
347fe6060f1SDimitry Andric       OS << LS;
3480b57cec5SDimitry Andric       if (Operands[i].isReg()) {
349fe6060f1SDimitry Andric         OS << "Op" << i;
3500b57cec5SDimitry Andric       } else if (Operands[i].isImm()) {
3510b57cec5SDimitry Andric         OS << "imm" << i;
3520b57cec5SDimitry Andric       } else if (Operands[i].isFP()) {
3530b57cec5SDimitry Andric         OS << "f" << i;
3540b57cec5SDimitry Andric       } else {
3550b57cec5SDimitry Andric         llvm_unreachable("Unknown operand kind!");
3560b57cec5SDimitry Andric       }
3570b57cec5SDimitry Andric     }
3580b57cec5SDimitry Andric   }
3590b57cec5SDimitry Andric 
3600b57cec5SDimitry Andric   void PrintManglingSuffix(raw_ostream &OS, const std::vector<std::string> &PR,
3610b57cec5SDimitry Andric                            ImmPredicateSet &ImmPredicates,
3620b57cec5SDimitry Andric                            bool StripImmCodes = false) const {
3630b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
3640b57cec5SDimitry Andric       if (PR[i] != "")
3650b57cec5SDimitry Andric         // Implicit physical register operand. e.g. Instruction::Mul expect to
3660b57cec5SDimitry Andric         // select to a binary op. On x86, mul may take a single operand with
3670b57cec5SDimitry Andric         // the other operand being implicit. We must emit something that looks
3680b57cec5SDimitry Andric         // like a binary instruction except for the very inner fastEmitInst_*
3690b57cec5SDimitry Andric         // call.
3700b57cec5SDimitry Andric         continue;
3710b57cec5SDimitry Andric       Operands[i].printManglingSuffix(OS, ImmPredicates, StripImmCodes);
3720b57cec5SDimitry Andric     }
3730b57cec5SDimitry Andric   }
3740b57cec5SDimitry Andric 
3750b57cec5SDimitry Andric   void PrintManglingSuffix(raw_ostream &OS, ImmPredicateSet &ImmPredicates,
3760b57cec5SDimitry Andric                            bool StripImmCodes = false) const {
3770b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i)
3780b57cec5SDimitry Andric       Operands[i].printManglingSuffix(OS, ImmPredicates, StripImmCodes);
3790b57cec5SDimitry Andric   }
3800b57cec5SDimitry Andric };
3810b57cec5SDimitry Andric } // End anonymous namespace
3820b57cec5SDimitry Andric 
3830b57cec5SDimitry Andric namespace {
3840b57cec5SDimitry Andric class FastISelMap {
3850b57cec5SDimitry Andric   // A multimap is needed instead of a "plain" map because the key is
3860b57cec5SDimitry Andric   // the instruction's complexity (an int) and they are not unique.
3870b57cec5SDimitry Andric   typedef std::multimap<int, InstructionMemo> PredMap;
3880b57cec5SDimitry Andric   typedef std::map<MVT::SimpleValueType, PredMap> RetPredMap;
3890b57cec5SDimitry Andric   typedef std::map<MVT::SimpleValueType, RetPredMap> TypeRetPredMap;
3900b57cec5SDimitry Andric   typedef std::map<std::string, TypeRetPredMap> OpcodeTypeRetPredMap;
3910b57cec5SDimitry Andric   typedef std::map<OperandsSignature, OpcodeTypeRetPredMap>
3920b57cec5SDimitry Andric       OperandsOpcodeTypeRetPredMap;
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric   OperandsOpcodeTypeRetPredMap SimplePatterns;
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric   // This is used to check that there are no duplicate predicates
397bdd1243dSDimitry Andric   std::set<std::tuple<OperandsSignature, std::string, MVT::SimpleValueType,
398bdd1243dSDimitry Andric                       MVT::SimpleValueType, std::string>>
399bdd1243dSDimitry Andric       SimplePatternsCheck;
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric   std::map<OperandsSignature, std::vector<OperandsSignature>>
4020b57cec5SDimitry Andric       SignaturesWithConstantForms;
4030b57cec5SDimitry Andric 
4040b57cec5SDimitry Andric   StringRef InstNS;
4050b57cec5SDimitry Andric   ImmPredicateSet ImmediatePredicates;
406*0fca6ea1SDimitry Andric 
4070b57cec5SDimitry Andric public:
4080b57cec5SDimitry Andric   explicit FastISelMap(StringRef InstNS);
4090b57cec5SDimitry Andric 
4100b57cec5SDimitry Andric   void collectPatterns(CodeGenDAGPatterns &CGP);
4110b57cec5SDimitry Andric   void printImmediatePredicates(raw_ostream &OS);
4120b57cec5SDimitry Andric   void printFunctionDefinitions(raw_ostream &OS);
413*0fca6ea1SDimitry Andric 
4140b57cec5SDimitry Andric private:
415*0fca6ea1SDimitry Andric   void emitInstructionCode(raw_ostream &OS, const OperandsSignature &Operands,
416*0fca6ea1SDimitry Andric                            const PredMap &PM, const std::string &RetVTName);
4170b57cec5SDimitry Andric };
4180b57cec5SDimitry Andric } // End anonymous namespace
4190b57cec5SDimitry Andric 
4200b57cec5SDimitry Andric static std::string getOpcodeName(Record *Op, CodeGenDAGPatterns &CGP) {
4215ffd83dbSDimitry Andric   return std::string(CGP.getSDNodeInfo(Op).getEnumName());
4220b57cec5SDimitry Andric }
4230b57cec5SDimitry Andric 
4240b57cec5SDimitry Andric static std::string getLegalCName(std::string OpName) {
4250b57cec5SDimitry Andric   std::string::size_type pos = OpName.find("::");
4260b57cec5SDimitry Andric   if (pos != std::string::npos)
4270b57cec5SDimitry Andric     OpName.replace(pos, 2, "_");
4280b57cec5SDimitry Andric   return OpName;
4290b57cec5SDimitry Andric }
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric FastISelMap::FastISelMap(StringRef instns) : InstNS(instns) {}
4320b57cec5SDimitry Andric 
433*0fca6ea1SDimitry Andric static std::string PhyRegForNode(TreePatternNode &Op,
4340b57cec5SDimitry Andric                                  const CodeGenTarget &Target) {
4350b57cec5SDimitry Andric   std::string PhysReg;
4360b57cec5SDimitry Andric 
437*0fca6ea1SDimitry Andric   if (!Op.isLeaf())
4380b57cec5SDimitry Andric     return PhysReg;
4390b57cec5SDimitry Andric 
440*0fca6ea1SDimitry Andric   Record *OpLeafRec = cast<DefInit>(Op.getLeafValue())->getDef();
4410b57cec5SDimitry Andric   if (!OpLeafRec->isSubClassOf("Register"))
4420b57cec5SDimitry Andric     return PhysReg;
4430b57cec5SDimitry Andric 
4440b57cec5SDimitry Andric   PhysReg += cast<StringInit>(OpLeafRec->getValue("Namespace")->getValue())
4450b57cec5SDimitry Andric                  ->getValue();
4460b57cec5SDimitry Andric   PhysReg += "::";
4470b57cec5SDimitry Andric   PhysReg += Target.getRegBank().getReg(OpLeafRec)->getName();
4480b57cec5SDimitry Andric   return PhysReg;
4490b57cec5SDimitry Andric }
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) {
4520b57cec5SDimitry Andric   const CodeGenTarget &Target = CGP.getTargetInfo();
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric   // Scan through all the patterns and record the simple ones.
455*0fca6ea1SDimitry Andric   for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(), E = CGP.ptm_end();
456*0fca6ea1SDimitry Andric        I != E; ++I) {
4570b57cec5SDimitry Andric     const PatternToMatch &Pattern = *I;
4580b57cec5SDimitry Andric 
4590b57cec5SDimitry Andric     // For now, just look at Instructions, so that we don't have to worry
4600b57cec5SDimitry Andric     // about emitting multiple instructions for a pattern.
461*0fca6ea1SDimitry Andric     TreePatternNode &Dst = Pattern.getDstPattern();
462*0fca6ea1SDimitry Andric     if (Dst.isLeaf())
463*0fca6ea1SDimitry Andric       continue;
464*0fca6ea1SDimitry Andric     Record *Op = Dst.getOperator();
4650b57cec5SDimitry Andric     if (!Op->isSubClassOf("Instruction"))
4660b57cec5SDimitry Andric       continue;
4670b57cec5SDimitry Andric     CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op);
4680b57cec5SDimitry Andric     if (II.Operands.empty())
4690b57cec5SDimitry Andric       continue;
4700b57cec5SDimitry Andric 
4710b57cec5SDimitry Andric     // Allow instructions to be marked as unavailable for FastISel for
4720b57cec5SDimitry Andric     // certain cases, i.e. an ISA has two 'and' instruction which differ
4730b57cec5SDimitry Andric     // by what registers they can use but are otherwise identical for
4740b57cec5SDimitry Andric     // codegen purposes.
4750b57cec5SDimitry Andric     if (II.FastISelShouldIgnore)
4760b57cec5SDimitry Andric       continue;
4770b57cec5SDimitry Andric 
4780b57cec5SDimitry Andric     // For now, ignore multi-instruction patterns.
4790b57cec5SDimitry Andric     bool MultiInsts = false;
480*0fca6ea1SDimitry Andric     for (unsigned i = 0, e = Dst.getNumChildren(); i != e; ++i) {
481*0fca6ea1SDimitry Andric       TreePatternNode &ChildOp = Dst.getChild(i);
482*0fca6ea1SDimitry Andric       if (ChildOp.isLeaf())
4830b57cec5SDimitry Andric         continue;
484*0fca6ea1SDimitry Andric       if (ChildOp.getOperator()->isSubClassOf("Instruction")) {
4850b57cec5SDimitry Andric         MultiInsts = true;
4860b57cec5SDimitry Andric         break;
4870b57cec5SDimitry Andric       }
4880b57cec5SDimitry Andric     }
4890b57cec5SDimitry Andric     if (MultiInsts)
4900b57cec5SDimitry Andric       continue;
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric     // For now, ignore instructions where the first operand is not an
4930b57cec5SDimitry Andric     // output register.
4940b57cec5SDimitry Andric     const CodeGenRegisterClass *DstRC = nullptr;
4950b57cec5SDimitry Andric     std::string SubRegNo;
4960b57cec5SDimitry Andric     if (Op->getName() != "EXTRACT_SUBREG") {
4970b57cec5SDimitry Andric       Record *Op0Rec = II.Operands[0].Rec;
4980b57cec5SDimitry Andric       if (Op0Rec->isSubClassOf("RegisterOperand"))
4990b57cec5SDimitry Andric         Op0Rec = Op0Rec->getValueAsDef("RegClass");
5000b57cec5SDimitry Andric       if (!Op0Rec->isSubClassOf("RegisterClass"))
5010b57cec5SDimitry Andric         continue;
5020b57cec5SDimitry Andric       DstRC = &Target.getRegisterClass(Op0Rec);
5030b57cec5SDimitry Andric       if (!DstRC)
5040b57cec5SDimitry Andric         continue;
5050b57cec5SDimitry Andric     } else {
5060b57cec5SDimitry Andric       // If this isn't a leaf, then continue since the register classes are
5070b57cec5SDimitry Andric       // a bit too complicated for now.
508*0fca6ea1SDimitry Andric       if (!Dst.getChild(1).isLeaf())
509*0fca6ea1SDimitry Andric         continue;
5100b57cec5SDimitry Andric 
511*0fca6ea1SDimitry Andric       DefInit *SR = dyn_cast<DefInit>(Dst.getChild(1).getLeafValue());
5120b57cec5SDimitry Andric       if (SR)
5130b57cec5SDimitry Andric         SubRegNo = getQualifiedName(SR->getDef());
5140b57cec5SDimitry Andric       else
515*0fca6ea1SDimitry Andric         SubRegNo = Dst.getChild(1).getLeafValue()->getAsString();
5160b57cec5SDimitry Andric     }
5170b57cec5SDimitry Andric 
5180b57cec5SDimitry Andric     // Inspect the pattern.
519*0fca6ea1SDimitry Andric     TreePatternNode &InstPatNode = Pattern.getSrcPattern();
520*0fca6ea1SDimitry Andric     if (InstPatNode.isLeaf())
521*0fca6ea1SDimitry Andric       continue;
5220b57cec5SDimitry Andric 
5230b57cec5SDimitry Andric     // Ignore multiple result nodes for now.
524*0fca6ea1SDimitry Andric     if (InstPatNode.getNumTypes() > 1)
525*0fca6ea1SDimitry Andric       continue;
5260b57cec5SDimitry Andric 
527*0fca6ea1SDimitry Andric     Record *InstPatOp = InstPatNode.getOperator();
5280b57cec5SDimitry Andric     std::string OpcodeName = getOpcodeName(InstPatOp, CGP);
5290b57cec5SDimitry Andric     MVT::SimpleValueType RetVT = MVT::isVoid;
530*0fca6ea1SDimitry Andric     if (InstPatNode.getNumTypes())
531*0fca6ea1SDimitry Andric       RetVT = InstPatNode.getSimpleType(0);
5320b57cec5SDimitry Andric     MVT::SimpleValueType VT = RetVT;
533*0fca6ea1SDimitry Andric     if (InstPatNode.getNumChildren()) {
534*0fca6ea1SDimitry Andric       assert(InstPatNode.getChild(0).getNumTypes() == 1);
535*0fca6ea1SDimitry Andric       VT = InstPatNode.getChild(0).getSimpleType(0);
5360b57cec5SDimitry Andric     }
5370b57cec5SDimitry Andric 
5380b57cec5SDimitry Andric     // For now, filter out any instructions with predicates.
539*0fca6ea1SDimitry Andric     if (!InstPatNode.getPredicateCalls().empty())
5400b57cec5SDimitry Andric       continue;
5410b57cec5SDimitry Andric 
5420b57cec5SDimitry Andric     // Check all the operands.
5430b57cec5SDimitry Andric     OperandsSignature Operands;
5440b57cec5SDimitry Andric     if (!Operands.initialize(InstPatNode, Target, VT, ImmediatePredicates,
5450b57cec5SDimitry Andric                              DstRC))
5460b57cec5SDimitry Andric       continue;
5470b57cec5SDimitry Andric 
5480b57cec5SDimitry Andric     std::vector<std::string> PhysRegInputs;
549*0fca6ea1SDimitry Andric     if (InstPatNode.getOperator()->getName() == "imm" ||
550*0fca6ea1SDimitry Andric         InstPatNode.getOperator()->getName() == "fpimm")
5510b57cec5SDimitry Andric       PhysRegInputs.push_back("");
5520b57cec5SDimitry Andric     else {
5530b57cec5SDimitry Andric       // Compute the PhysRegs used by the given pattern, and check that
5540b57cec5SDimitry Andric       // the mapping from the src to dst patterns is simple.
5550b57cec5SDimitry Andric       bool FoundNonSimplePattern = false;
5560b57cec5SDimitry Andric       unsigned DstIndex = 0;
557*0fca6ea1SDimitry Andric       for (unsigned i = 0, e = InstPatNode.getNumChildren(); i != e; ++i) {
558*0fca6ea1SDimitry Andric         std::string PhysReg = PhyRegForNode(InstPatNode.getChild(i), Target);
5590b57cec5SDimitry Andric         if (PhysReg.empty()) {
560*0fca6ea1SDimitry Andric           if (DstIndex >= Dst.getNumChildren() ||
561*0fca6ea1SDimitry Andric               Dst.getChild(DstIndex).getName() !=
562*0fca6ea1SDimitry Andric                   InstPatNode.getChild(i).getName()) {
5630b57cec5SDimitry Andric             FoundNonSimplePattern = true;
5640b57cec5SDimitry Andric             break;
5650b57cec5SDimitry Andric           }
5660b57cec5SDimitry Andric           ++DstIndex;
5670b57cec5SDimitry Andric         }
5680b57cec5SDimitry Andric 
5690b57cec5SDimitry Andric         PhysRegInputs.push_back(PhysReg);
5700b57cec5SDimitry Andric       }
5710b57cec5SDimitry Andric 
572*0fca6ea1SDimitry Andric       if (Op->getName() != "EXTRACT_SUBREG" && DstIndex < Dst.getNumChildren())
5730b57cec5SDimitry Andric         FoundNonSimplePattern = true;
5740b57cec5SDimitry Andric 
5750b57cec5SDimitry Andric       if (FoundNonSimplePattern)
5760b57cec5SDimitry Andric         continue;
5770b57cec5SDimitry Andric     }
5780b57cec5SDimitry Andric 
5790b57cec5SDimitry Andric     // Check if the operands match one of the patterns handled by FastISel.
5800b57cec5SDimitry Andric     std::string ManglingSuffix;
5810b57cec5SDimitry Andric     raw_string_ostream SuffixOS(ManglingSuffix);
5820b57cec5SDimitry Andric     Operands.PrintManglingSuffix(SuffixOS, ImmediatePredicates, true);
5830b57cec5SDimitry Andric     if (!StringSwitch<bool>(ManglingSuffix)
5840b57cec5SDimitry Andric              .Cases("", "r", "rr", "ri", "i", "f", true)
5850b57cec5SDimitry Andric              .Default(false))
5860b57cec5SDimitry Andric       continue;
5870b57cec5SDimitry Andric 
5880b57cec5SDimitry Andric     // Get the predicate that guards this pattern.
5890b57cec5SDimitry Andric     std::string PredicateCheck = Pattern.getPredicateCheck();
5900b57cec5SDimitry Andric 
5910b57cec5SDimitry Andric     // Ok, we found a pattern that we can handle. Remember it.
592*0fca6ea1SDimitry Andric     InstructionMemo Memo(Pattern.getDstPattern().getOperator()->getName(),
593*0fca6ea1SDimitry Andric                          DstRC, SubRegNo, PhysRegInputs, PredicateCheck);
5940b57cec5SDimitry Andric 
5950b57cec5SDimitry Andric     int complexity = Pattern.getPatternComplexity(CGP);
5960b57cec5SDimitry Andric 
597bdd1243dSDimitry Andric     auto inserted_simple_pattern = SimplePatternsCheck.insert(
598*0fca6ea1SDimitry Andric         std::tuple(Operands, OpcodeName, VT, RetVT, PredicateCheck));
599bdd1243dSDimitry Andric     if (!inserted_simple_pattern.second) {
6000b57cec5SDimitry Andric       PrintFatalError(Pattern.getSrcRecord()->getLoc(),
6010b57cec5SDimitry Andric                       "Duplicate predicate in FastISel table!");
6020b57cec5SDimitry Andric     }
6030b57cec5SDimitry Andric 
6040b57cec5SDimitry Andric     // Note: Instructions with the same complexity will appear in the order
6050b57cec5SDimitry Andric     // that they are encountered.
6060b57cec5SDimitry Andric     SimplePatterns[Operands][OpcodeName][VT][RetVT].emplace(complexity,
6070b57cec5SDimitry Andric                                                             std::move(Memo));
6080b57cec5SDimitry Andric 
6090b57cec5SDimitry Andric     // If any of the operands were immediates with predicates on them, strip
6100b57cec5SDimitry Andric     // them down to a signature that doesn't have predicates so that we can
6110b57cec5SDimitry Andric     // associate them with the stripped predicate version.
6120b57cec5SDimitry Andric     if (Operands.hasAnyImmediateCodes()) {
613*0fca6ea1SDimitry Andric       SignaturesWithConstantForms[Operands.getWithoutImmCodes()].push_back(
614*0fca6ea1SDimitry Andric           Operands);
6150b57cec5SDimitry Andric     }
6160b57cec5SDimitry Andric   }
6170b57cec5SDimitry Andric }
6180b57cec5SDimitry Andric 
6190b57cec5SDimitry Andric void FastISelMap::printImmediatePredicates(raw_ostream &OS) {
6200b57cec5SDimitry Andric   if (ImmediatePredicates.begin() == ImmediatePredicates.end())
6210b57cec5SDimitry Andric     return;
6220b57cec5SDimitry Andric 
6230b57cec5SDimitry Andric   OS << "\n// FastEmit Immediate Predicate functions.\n";
624fe6060f1SDimitry Andric   for (auto ImmediatePredicate : ImmediatePredicates) {
625fe6060f1SDimitry Andric     OS << "static bool " << ImmediatePredicate.getFnName()
626fe6060f1SDimitry Andric        << "(int64_t Imm) {\n";
627fe6060f1SDimitry Andric     OS << ImmediatePredicate.getImmediatePredicateCode() << "\n}\n";
6280b57cec5SDimitry Andric   }
6290b57cec5SDimitry Andric 
6300b57cec5SDimitry Andric   OS << "\n\n";
6310b57cec5SDimitry Andric }
6320b57cec5SDimitry Andric 
6330b57cec5SDimitry Andric void FastISelMap::emitInstructionCode(raw_ostream &OS,
6340b57cec5SDimitry Andric                                       const OperandsSignature &Operands,
6350b57cec5SDimitry Andric                                       const PredMap &PM,
6360b57cec5SDimitry Andric                                       const std::string &RetVTName) {
6370b57cec5SDimitry Andric   // Emit code for each possible instruction. There may be
6380b57cec5SDimitry Andric   // multiple if there are subtarget concerns.  A reverse iterator
6390b57cec5SDimitry Andric   // is used to produce the ones with highest complexity first.
6400b57cec5SDimitry Andric 
6410b57cec5SDimitry Andric   bool OneHadNoPredicate = false;
6420b57cec5SDimitry Andric   for (PredMap::const_reverse_iterator PI = PM.rbegin(), PE = PM.rend();
6430b57cec5SDimitry Andric        PI != PE; ++PI) {
6440b57cec5SDimitry Andric     const InstructionMemo &Memo = PI->second;
6450b57cec5SDimitry Andric     std::string PredicateCheck = Memo.PredicateCheck;
6460b57cec5SDimitry Andric 
6470b57cec5SDimitry Andric     if (PredicateCheck.empty()) {
6480b57cec5SDimitry Andric       assert(!OneHadNoPredicate &&
6490b57cec5SDimitry Andric              "Multiple instructions match and more than one had "
6500b57cec5SDimitry Andric              "no predicate!");
6510b57cec5SDimitry Andric       OneHadNoPredicate = true;
6520b57cec5SDimitry Andric     } else {
6530b57cec5SDimitry Andric       if (OneHadNoPredicate) {
6540b57cec5SDimitry Andric         PrintFatalError("Multiple instructions match and one with no "
6550b57cec5SDimitry Andric                         "predicate came before one with a predicate!  "
656*0fca6ea1SDimitry Andric                         "name:" +
657*0fca6ea1SDimitry Andric                         Memo.Name + "  predicate: " + PredicateCheck);
6580b57cec5SDimitry Andric       }
6590b57cec5SDimitry Andric       OS << "  if (" + PredicateCheck + ") {\n";
6600b57cec5SDimitry Andric       OS << "  ";
6610b57cec5SDimitry Andric     }
6620b57cec5SDimitry Andric 
6630b57cec5SDimitry Andric     for (unsigned i = 0; i < Memo.PhysRegs.size(); ++i) {
6640b57cec5SDimitry Andric       if (Memo.PhysRegs[i] != "")
665bdd1243dSDimitry Andric         OS << "  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, "
6660b57cec5SDimitry Andric            << "TII.get(TargetOpcode::COPY), " << Memo.PhysRegs[i]
6670b57cec5SDimitry Andric            << ").addReg(Op" << i << ");\n";
6680b57cec5SDimitry Andric     }
6690b57cec5SDimitry Andric 
6700b57cec5SDimitry Andric     OS << "  return fastEmitInst_";
6710b57cec5SDimitry Andric     if (Memo.SubRegNo.empty()) {
6720b57cec5SDimitry Andric       Operands.PrintManglingSuffix(OS, Memo.PhysRegs, ImmediatePredicates,
6730b57cec5SDimitry Andric                                    true);
6740b57cec5SDimitry Andric       OS << "(" << InstNS << "::" << Memo.Name << ", ";
6750b57cec5SDimitry Andric       OS << "&" << InstNS << "::" << Memo.RC->getName() << "RegClass";
6760b57cec5SDimitry Andric       if (!Operands.empty())
6770b57cec5SDimitry Andric         OS << ", ";
6780b57cec5SDimitry Andric       Operands.PrintArguments(OS, Memo.PhysRegs);
6790b57cec5SDimitry Andric       OS << ");\n";
6800b57cec5SDimitry Andric     } else {
681*0fca6ea1SDimitry Andric       OS << "extractsubreg(" << RetVTName << ", Op0, " << Memo.SubRegNo
682*0fca6ea1SDimitry Andric          << ");\n";
6830b57cec5SDimitry Andric     }
6840b57cec5SDimitry Andric 
6850b57cec5SDimitry Andric     if (!PredicateCheck.empty()) {
6860b57cec5SDimitry Andric       OS << "  }\n";
6870b57cec5SDimitry Andric     }
6880b57cec5SDimitry Andric   }
6890b57cec5SDimitry Andric   // Return 0 if all of the possibilities had predicates but none
6900b57cec5SDimitry Andric   // were satisfied.
6910b57cec5SDimitry Andric   if (!OneHadNoPredicate)
6920b57cec5SDimitry Andric     OS << "  return 0;\n";
6930b57cec5SDimitry Andric   OS << "}\n";
6940b57cec5SDimitry Andric   OS << "\n";
6950b57cec5SDimitry Andric }
6960b57cec5SDimitry Andric 
6970b57cec5SDimitry Andric void FastISelMap::printFunctionDefinitions(raw_ostream &OS) {
6980b57cec5SDimitry Andric   // Now emit code for all the patterns that we collected.
699fe6060f1SDimitry Andric   for (const auto &SimplePattern : SimplePatterns) {
700fe6060f1SDimitry Andric     const OperandsSignature &Operands = SimplePattern.first;
701fe6060f1SDimitry Andric     const OpcodeTypeRetPredMap &OTM = SimplePattern.second;
7020b57cec5SDimitry Andric 
703fe6060f1SDimitry Andric     for (const auto &I : OTM) {
704fe6060f1SDimitry Andric       const std::string &Opcode = I.first;
705fe6060f1SDimitry Andric       const TypeRetPredMap &TM = I.second;
7060b57cec5SDimitry Andric 
7070b57cec5SDimitry Andric       OS << "// FastEmit functions for " << Opcode << ".\n";
7080b57cec5SDimitry Andric       OS << "\n";
7090b57cec5SDimitry Andric 
7100b57cec5SDimitry Andric       // Emit one function for each opcode,type pair.
711fe6060f1SDimitry Andric       for (const auto &TI : TM) {
712fe6060f1SDimitry Andric         MVT::SimpleValueType VT = TI.first;
713fe6060f1SDimitry Andric         const RetPredMap &RM = TI.second;
7140b57cec5SDimitry Andric         if (RM.size() != 1) {
715fe6060f1SDimitry Andric           for (const auto &RI : RM) {
716fe6060f1SDimitry Andric             MVT::SimpleValueType RetVT = RI.first;
717fe6060f1SDimitry Andric             const PredMap &PM = RI.second;
7180b57cec5SDimitry Andric 
7195ffd83dbSDimitry Andric             OS << "unsigned fastEmit_" << getLegalCName(Opcode) << "_"
7205ffd83dbSDimitry Andric                << getLegalCName(std::string(getName(VT))) << "_"
7215ffd83dbSDimitry Andric                << getLegalCName(std::string(getName(RetVT))) << "_";
7220b57cec5SDimitry Andric             Operands.PrintManglingSuffix(OS, ImmediatePredicates);
7230b57cec5SDimitry Andric             OS << "(";
7240b57cec5SDimitry Andric             Operands.PrintParameters(OS);
7250b57cec5SDimitry Andric             OS << ") {\n";
7260b57cec5SDimitry Andric 
7275ffd83dbSDimitry Andric             emitInstructionCode(OS, Operands, PM, std::string(getName(RetVT)));
7280b57cec5SDimitry Andric           }
7290b57cec5SDimitry Andric 
7300b57cec5SDimitry Andric           // Emit one function for the type that demultiplexes on return type.
7315ffd83dbSDimitry Andric           OS << "unsigned fastEmit_" << getLegalCName(Opcode) << "_"
7325ffd83dbSDimitry Andric              << getLegalCName(std::string(getName(VT))) << "_";
7330b57cec5SDimitry Andric           Operands.PrintManglingSuffix(OS, ImmediatePredicates);
7340b57cec5SDimitry Andric           OS << "(MVT RetVT";
7350b57cec5SDimitry Andric           if (!Operands.empty())
7360b57cec5SDimitry Andric             OS << ", ";
7370b57cec5SDimitry Andric           Operands.PrintParameters(OS);
7380b57cec5SDimitry Andric           OS << ") {\nswitch (RetVT.SimpleTy) {\n";
739fe6060f1SDimitry Andric           for (const auto &RI : RM) {
740fe6060f1SDimitry Andric             MVT::SimpleValueType RetVT = RI.first;
7410b57cec5SDimitry Andric             OS << "  case " << getName(RetVT) << ": return fastEmit_"
7425ffd83dbSDimitry Andric                << getLegalCName(Opcode) << "_"
7435ffd83dbSDimitry Andric                << getLegalCName(std::string(getName(VT))) << "_"
7445ffd83dbSDimitry Andric                << getLegalCName(std::string(getName(RetVT))) << "_";
7450b57cec5SDimitry Andric             Operands.PrintManglingSuffix(OS, ImmediatePredicates);
7460b57cec5SDimitry Andric             OS << "(";
7470b57cec5SDimitry Andric             Operands.PrintArguments(OS);
7480b57cec5SDimitry Andric             OS << ");\n";
7490b57cec5SDimitry Andric           }
7500b57cec5SDimitry Andric           OS << "  default: return 0;\n}\n}\n\n";
7510b57cec5SDimitry Andric 
7520b57cec5SDimitry Andric         } else {
7530b57cec5SDimitry Andric           // Non-variadic return type.
7545ffd83dbSDimitry Andric           OS << "unsigned fastEmit_" << getLegalCName(Opcode) << "_"
7555ffd83dbSDimitry Andric              << getLegalCName(std::string(getName(VT))) << "_";
7560b57cec5SDimitry Andric           Operands.PrintManglingSuffix(OS, ImmediatePredicates);
7570b57cec5SDimitry Andric           OS << "(MVT RetVT";
7580b57cec5SDimitry Andric           if (!Operands.empty())
7590b57cec5SDimitry Andric             OS << ", ";
7600b57cec5SDimitry Andric           Operands.PrintParameters(OS);
7610b57cec5SDimitry Andric           OS << ") {\n";
7620b57cec5SDimitry Andric 
7630b57cec5SDimitry Andric           OS << "  if (RetVT.SimpleTy != " << getName(RM.begin()->first)
7640b57cec5SDimitry Andric              << ")\n    return 0;\n";
7650b57cec5SDimitry Andric 
7660b57cec5SDimitry Andric           const PredMap &PM = RM.begin()->second;
7670b57cec5SDimitry Andric 
7680b57cec5SDimitry Andric           emitInstructionCode(OS, Operands, PM, "RetVT");
7690b57cec5SDimitry Andric         }
7700b57cec5SDimitry Andric       }
7710b57cec5SDimitry Andric 
7720b57cec5SDimitry Andric       // Emit one function for the opcode that demultiplexes based on the type.
773*0fca6ea1SDimitry Andric       OS << "unsigned fastEmit_" << getLegalCName(Opcode) << "_";
7740b57cec5SDimitry Andric       Operands.PrintManglingSuffix(OS, ImmediatePredicates);
7750b57cec5SDimitry Andric       OS << "(MVT VT, MVT RetVT";
7760b57cec5SDimitry Andric       if (!Operands.empty())
7770b57cec5SDimitry Andric         OS << ", ";
7780b57cec5SDimitry Andric       Operands.PrintParameters(OS);
7790b57cec5SDimitry Andric       OS << ") {\n";
7800b57cec5SDimitry Andric       OS << "  switch (VT.SimpleTy) {\n";
781fe6060f1SDimitry Andric       for (const auto &TI : TM) {
782fe6060f1SDimitry Andric         MVT::SimpleValueType VT = TI.first;
7835ffd83dbSDimitry Andric         std::string TypeName = std::string(getName(VT));
7840b57cec5SDimitry Andric         OS << "  case " << TypeName << ": return fastEmit_"
7850b57cec5SDimitry Andric            << getLegalCName(Opcode) << "_" << getLegalCName(TypeName) << "_";
7860b57cec5SDimitry Andric         Operands.PrintManglingSuffix(OS, ImmediatePredicates);
7870b57cec5SDimitry Andric         OS << "(RetVT";
7880b57cec5SDimitry Andric         if (!Operands.empty())
7890b57cec5SDimitry Andric           OS << ", ";
7900b57cec5SDimitry Andric         Operands.PrintArguments(OS);
7910b57cec5SDimitry Andric         OS << ");\n";
7920b57cec5SDimitry Andric       }
7930b57cec5SDimitry Andric       OS << "  default: return 0;\n";
7940b57cec5SDimitry Andric       OS << "  }\n";
7950b57cec5SDimitry Andric       OS << "}\n";
7960b57cec5SDimitry Andric       OS << "\n";
7970b57cec5SDimitry Andric     }
7980b57cec5SDimitry Andric 
7990b57cec5SDimitry Andric     OS << "// Top-level FastEmit function.\n";
8000b57cec5SDimitry Andric     OS << "\n";
8010b57cec5SDimitry Andric 
8020b57cec5SDimitry Andric     // Emit one function for the operand signature that demultiplexes based
8030b57cec5SDimitry Andric     // on opcode and type.
8040b57cec5SDimitry Andric     OS << "unsigned fastEmit_";
8050b57cec5SDimitry Andric     Operands.PrintManglingSuffix(OS, ImmediatePredicates);
8060b57cec5SDimitry Andric     OS << "(MVT VT, MVT RetVT, unsigned Opcode";
8070b57cec5SDimitry Andric     if (!Operands.empty())
8080b57cec5SDimitry Andric       OS << ", ";
8090b57cec5SDimitry Andric     Operands.PrintParameters(OS);
8100b57cec5SDimitry Andric     OS << ") ";
8110b57cec5SDimitry Andric     if (!Operands.hasAnyImmediateCodes())
8120b57cec5SDimitry Andric       OS << "override ";
8130b57cec5SDimitry Andric     OS << "{\n";
8140b57cec5SDimitry Andric 
8150b57cec5SDimitry Andric     // If there are any forms of this signature available that operate on
8160b57cec5SDimitry Andric     // constrained forms of the immediate (e.g., 32-bit sext immediate in a
8170b57cec5SDimitry Andric     // 64-bit operand), check them first.
8180b57cec5SDimitry Andric 
819*0fca6ea1SDimitry Andric     std::map<OperandsSignature, std::vector<OperandsSignature>>::iterator MI =
820*0fca6ea1SDimitry Andric         SignaturesWithConstantForms.find(Operands);
8210b57cec5SDimitry Andric     if (MI != SignaturesWithConstantForms.end()) {
8220b57cec5SDimitry Andric       // Unique any duplicates out of the list.
8230b57cec5SDimitry Andric       llvm::sort(MI->second);
824*0fca6ea1SDimitry Andric       MI->second.erase(llvm::unique(MI->second), MI->second.end());
8250b57cec5SDimitry Andric 
8260b57cec5SDimitry Andric       // Check each in order it was seen.  It would be nice to have a good
8270b57cec5SDimitry Andric       // relative ordering between them, but we're not going for optimality
8280b57cec5SDimitry Andric       // here.
8290b57cec5SDimitry Andric       for (unsigned i = 0, e = MI->second.size(); i != e; ++i) {
8300b57cec5SDimitry Andric         OS << "  if (";
8310b57cec5SDimitry Andric         MI->second[i].emitImmediatePredicate(OS, ImmediatePredicates);
8320b57cec5SDimitry Andric         OS << ")\n    if (unsigned Reg = fastEmit_";
8330b57cec5SDimitry Andric         MI->second[i].PrintManglingSuffix(OS, ImmediatePredicates);
8340b57cec5SDimitry Andric         OS << "(VT, RetVT, Opcode";
8350b57cec5SDimitry Andric         if (!MI->second[i].empty())
8360b57cec5SDimitry Andric           OS << ", ";
8370b57cec5SDimitry Andric         MI->second[i].PrintArguments(OS);
8380b57cec5SDimitry Andric         OS << "))\n      return Reg;\n\n";
8390b57cec5SDimitry Andric       }
8400b57cec5SDimitry Andric 
8410b57cec5SDimitry Andric       // Done with this, remove it.
8420b57cec5SDimitry Andric       SignaturesWithConstantForms.erase(MI);
8430b57cec5SDimitry Andric     }
8440b57cec5SDimitry Andric 
8450b57cec5SDimitry Andric     OS << "  switch (Opcode) {\n";
846fe6060f1SDimitry Andric     for (const auto &I : OTM) {
847fe6060f1SDimitry Andric       const std::string &Opcode = I.first;
8480b57cec5SDimitry Andric 
849*0fca6ea1SDimitry Andric       OS << "  case " << Opcode << ": return fastEmit_" << getLegalCName(Opcode)
850*0fca6ea1SDimitry Andric          << "_";
8510b57cec5SDimitry Andric       Operands.PrintManglingSuffix(OS, ImmediatePredicates);
8520b57cec5SDimitry Andric       OS << "(VT, RetVT";
8530b57cec5SDimitry Andric       if (!Operands.empty())
8540b57cec5SDimitry Andric         OS << ", ";
8550b57cec5SDimitry Andric       Operands.PrintArguments(OS);
8560b57cec5SDimitry Andric       OS << ");\n";
8570b57cec5SDimitry Andric     }
8580b57cec5SDimitry Andric     OS << "  default: return 0;\n";
8590b57cec5SDimitry Andric     OS << "  }\n";
8600b57cec5SDimitry Andric     OS << "}\n";
8610b57cec5SDimitry Andric     OS << "\n";
8620b57cec5SDimitry Andric   }
8630b57cec5SDimitry Andric 
8640b57cec5SDimitry Andric   // TODO: SignaturesWithConstantForms should be empty here.
8650b57cec5SDimitry Andric }
8660b57cec5SDimitry Andric 
86706c3fb27SDimitry Andric static void EmitFastISel(RecordKeeper &RK, raw_ostream &OS) {
8680b57cec5SDimitry Andric   CodeGenDAGPatterns CGP(RK);
8690b57cec5SDimitry Andric   const CodeGenTarget &Target = CGP.getTargetInfo();
8700b57cec5SDimitry Andric   emitSourceFileHeader("\"Fast\" Instruction Selector for the " +
871*0fca6ea1SDimitry Andric                            Target.getName().str() + " target",
872*0fca6ea1SDimitry Andric                        OS);
8730b57cec5SDimitry Andric 
8740b57cec5SDimitry Andric   // Determine the target's namespace name.
8750b57cec5SDimitry Andric   StringRef InstNS = Target.getInstNamespace();
8760b57cec5SDimitry Andric   assert(!InstNS.empty() && "Can't determine target-specific namespace!");
8770b57cec5SDimitry Andric 
8780b57cec5SDimitry Andric   FastISelMap F(InstNS);
8790b57cec5SDimitry Andric   F.collectPatterns(CGP);
8800b57cec5SDimitry Andric   F.printImmediatePredicates(OS);
8810b57cec5SDimitry Andric   F.printFunctionDefinitions(OS);
8820b57cec5SDimitry Andric }
8830b57cec5SDimitry Andric 
88406c3fb27SDimitry Andric static TableGen::Emitter::Opt X("gen-fast-isel", EmitFastISel,
88506c3fb27SDimitry Andric                                 "Generate a \"fast\" instruction selector");
886