xref: /freebsd/contrib/llvm-project/llvm/utils/TableGen/FastISelEmitter.cpp (revision fe6060f10f634930ff71b7c50291ddc610da2475)
10b57cec5SDimitry 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 
190b57cec5SDimitry Andric #include "CodeGenDAGPatterns.h"
200b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
210b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
220b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
230b57cec5SDimitry Andric #include "llvm/TableGen/Error.h"
240b57cec5SDimitry Andric #include "llvm/TableGen/Record.h"
250b57cec5SDimitry Andric #include "llvm/TableGen/TableGenBackend.h"
260b57cec5SDimitry Andric #include <utility>
270b57cec5SDimitry Andric using namespace llvm;
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric /// InstructionMemo - This class holds additional information about an
310b57cec5SDimitry Andric /// instruction needed to emit code for it.
320b57cec5SDimitry Andric ///
330b57cec5SDimitry Andric namespace {
340b57cec5SDimitry Andric struct InstructionMemo {
350b57cec5SDimitry Andric   std::string Name;
360b57cec5SDimitry Andric   const CodeGenRegisterClass *RC;
370b57cec5SDimitry Andric   std::string SubRegNo;
380b57cec5SDimitry Andric   std::vector<std::string> PhysRegs;
390b57cec5SDimitry Andric   std::string PredicateCheck;
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric   InstructionMemo(StringRef Name, const CodeGenRegisterClass *RC,
420b57cec5SDimitry Andric                   std::string SubRegNo, std::vector<std::string> PhysRegs,
430b57cec5SDimitry Andric                   std::string PredicateCheck)
440b57cec5SDimitry Andric       : Name(Name), RC(RC), SubRegNo(std::move(SubRegNo)),
450b57cec5SDimitry Andric         PhysRegs(std::move(PhysRegs)),
460b57cec5SDimitry Andric         PredicateCheck(std::move(PredicateCheck)) {}
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric   // Make sure we do not copy InstructionMemo.
490b57cec5SDimitry Andric   InstructionMemo(const InstructionMemo &Other) = delete;
500b57cec5SDimitry Andric   InstructionMemo(InstructionMemo &&Other) = default;
510b57cec5SDimitry Andric };
520b57cec5SDimitry Andric } // End anonymous namespace
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric /// ImmPredicateSet - This uniques predicates (represented as a string) and
550b57cec5SDimitry Andric /// gives them unique (small) integer ID's that start at 0.
560b57cec5SDimitry Andric namespace {
570b57cec5SDimitry Andric class ImmPredicateSet {
580b57cec5SDimitry Andric   DenseMap<TreePattern *, unsigned> ImmIDs;
590b57cec5SDimitry Andric   std::vector<TreePredicateFn> PredsByName;
600b57cec5SDimitry Andric public:
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   unsigned getIDFor(TreePredicateFn Pred) {
630b57cec5SDimitry Andric     unsigned &Entry = ImmIDs[Pred.getOrigPatFragRecord()];
640b57cec5SDimitry Andric     if (Entry == 0) {
650b57cec5SDimitry Andric       PredsByName.push_back(Pred);
660b57cec5SDimitry Andric       Entry = PredsByName.size();
670b57cec5SDimitry Andric     }
680b57cec5SDimitry Andric     return Entry-1;
690b57cec5SDimitry Andric   }
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   const TreePredicateFn &getPredicate(unsigned i) {
720b57cec5SDimitry Andric     assert(i < PredsByName.size());
730b57cec5SDimitry Andric     return PredsByName[i];
740b57cec5SDimitry Andric   }
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   typedef std::vector<TreePredicateFn>::const_iterator iterator;
770b57cec5SDimitry Andric   iterator begin() const { return PredsByName.begin(); }
780b57cec5SDimitry Andric   iterator end() const { return PredsByName.end(); }
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric };
810b57cec5SDimitry Andric } // End anonymous namespace
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric /// OperandsSignature - This class holds a description of a list of operand
840b57cec5SDimitry Andric /// types. It has utility methods for emitting text based on the operands.
850b57cec5SDimitry Andric ///
860b57cec5SDimitry Andric namespace {
870b57cec5SDimitry Andric struct OperandsSignature {
880b57cec5SDimitry Andric   class OpKind {
890b57cec5SDimitry Andric     enum { OK_Reg, OK_FP, OK_Imm, OK_Invalid = -1 };
900b57cec5SDimitry Andric     char Repr;
910b57cec5SDimitry Andric   public:
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric     OpKind() : Repr(OK_Invalid) {}
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric     bool operator<(OpKind RHS) const { return Repr < RHS.Repr; }
960b57cec5SDimitry Andric     bool operator==(OpKind RHS) const { return Repr == RHS.Repr; }
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric     static OpKind getReg() { OpKind K; K.Repr = OK_Reg; return K; }
990b57cec5SDimitry Andric     static OpKind getFP()  { OpKind K; K.Repr = OK_FP; return K; }
1000b57cec5SDimitry Andric     static OpKind getImm(unsigned V) {
1010b57cec5SDimitry Andric       assert((unsigned)OK_Imm+V < 128 &&
1020b57cec5SDimitry Andric              "Too many integer predicates for the 'Repr' char");
1030b57cec5SDimitry Andric       OpKind K; K.Repr = OK_Imm+V; return K;
1040b57cec5SDimitry Andric     }
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric     bool isReg() const { return Repr == OK_Reg; }
1070b57cec5SDimitry Andric     bool isFP() const  { return Repr == OK_FP; }
1080b57cec5SDimitry Andric     bool isImm() const { return Repr >= OK_Imm; }
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric     unsigned getImmCode() const { assert(isImm()); return Repr-OK_Imm; }
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric     void printManglingSuffix(raw_ostream &OS, ImmPredicateSet &ImmPredicates,
1130b57cec5SDimitry Andric                              bool StripImmCodes) const {
1140b57cec5SDimitry Andric       if (isReg())
1150b57cec5SDimitry Andric         OS << 'r';
1160b57cec5SDimitry Andric       else if (isFP())
1170b57cec5SDimitry Andric         OS << 'f';
1180b57cec5SDimitry Andric       else {
1190b57cec5SDimitry Andric         OS << 'i';
1200b57cec5SDimitry Andric         if (!StripImmCodes)
1210b57cec5SDimitry Andric           if (unsigned Code = getImmCode())
1220b57cec5SDimitry Andric             OS << "_" << ImmPredicates.getPredicate(Code-1).getFnName();
1230b57cec5SDimitry Andric       }
1240b57cec5SDimitry Andric     }
1250b57cec5SDimitry Andric   };
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric   SmallVector<OpKind, 3> Operands;
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric   bool operator<(const OperandsSignature &O) const {
1310b57cec5SDimitry Andric     return Operands < O.Operands;
1320b57cec5SDimitry Andric   }
1330b57cec5SDimitry Andric   bool operator==(const OperandsSignature &O) const {
1340b57cec5SDimitry Andric     return Operands == O.Operands;
1350b57cec5SDimitry Andric   }
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   bool empty() const { return Operands.empty(); }
1380b57cec5SDimitry Andric 
1390b57cec5SDimitry Andric   bool hasAnyImmediateCodes() const {
1400b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i)
1410b57cec5SDimitry Andric       if (Operands[i].isImm() && Operands[i].getImmCode() != 0)
1420b57cec5SDimitry Andric         return true;
1430b57cec5SDimitry Andric     return false;
1440b57cec5SDimitry Andric   }
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric   /// getWithoutImmCodes - Return a copy of this with any immediate codes forced
1470b57cec5SDimitry Andric   /// to zero.
1480b57cec5SDimitry Andric   OperandsSignature getWithoutImmCodes() const {
1490b57cec5SDimitry Andric     OperandsSignature Result;
1500b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i)
1510b57cec5SDimitry Andric       if (!Operands[i].isImm())
1520b57cec5SDimitry Andric         Result.Operands.push_back(Operands[i]);
1530b57cec5SDimitry Andric       else
1540b57cec5SDimitry Andric         Result.Operands.push_back(OpKind::getImm(0));
1550b57cec5SDimitry Andric     return Result;
1560b57cec5SDimitry Andric   }
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric   void emitImmediatePredicate(raw_ostream &OS, ImmPredicateSet &ImmPredicates) {
1590b57cec5SDimitry Andric     bool EmittedAnything = false;
1600b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
1610b57cec5SDimitry Andric       if (!Operands[i].isImm()) continue;
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric       unsigned Code = Operands[i].getImmCode();
1640b57cec5SDimitry Andric       if (Code == 0) continue;
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric       if (EmittedAnything)
1670b57cec5SDimitry Andric         OS << " &&\n        ";
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric       TreePredicateFn PredFn = ImmPredicates.getPredicate(Code-1);
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric       // Emit the type check.
1720b57cec5SDimitry Andric       TreePattern *TP = PredFn.getOrigPatFragRecord();
1730b57cec5SDimitry Andric       ValueTypeByHwMode VVT = TP->getTree(0)->getType(0);
1740b57cec5SDimitry Andric       assert(VVT.isSimple() &&
1750b57cec5SDimitry Andric              "Cannot use variable value types with fast isel");
1760b57cec5SDimitry Andric       OS << "VT == " << getEnumName(VVT.getSimple().SimpleTy) << " && ";
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric       OS << PredFn.getFnName() << "(imm" << i <<')';
1790b57cec5SDimitry Andric       EmittedAnything = true;
1800b57cec5SDimitry Andric     }
1810b57cec5SDimitry Andric   }
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric   /// initialize - Examine the given pattern and initialize the contents
1840b57cec5SDimitry Andric   /// of the Operands array accordingly. Return true if all the operands
1850b57cec5SDimitry Andric   /// are supported, false otherwise.
1860b57cec5SDimitry Andric   ///
1870b57cec5SDimitry Andric   bool initialize(TreePatternNode *InstPatNode, const CodeGenTarget &Target,
1880b57cec5SDimitry Andric                   MVT::SimpleValueType VT,
1890b57cec5SDimitry Andric                   ImmPredicateSet &ImmediatePredicates,
1900b57cec5SDimitry Andric                   const CodeGenRegisterClass *OrigDstRC) {
1910b57cec5SDimitry Andric     if (InstPatNode->isLeaf())
1920b57cec5SDimitry Andric       return false;
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric     if (InstPatNode->getOperator()->getName() == "imm") {
1950b57cec5SDimitry Andric       Operands.push_back(OpKind::getImm(0));
1960b57cec5SDimitry Andric       return true;
1970b57cec5SDimitry Andric     }
1980b57cec5SDimitry Andric 
1990b57cec5SDimitry Andric     if (InstPatNode->getOperator()->getName() == "fpimm") {
2000b57cec5SDimitry Andric       Operands.push_back(OpKind::getFP());
2010b57cec5SDimitry Andric       return true;
2020b57cec5SDimitry Andric     }
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric     const CodeGenRegisterClass *DstRC = nullptr;
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric     for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) {
2070b57cec5SDimitry Andric       TreePatternNode *Op = InstPatNode->getChild(i);
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric       // Handle imm operands specially.
2100b57cec5SDimitry Andric       if (!Op->isLeaf() && Op->getOperator()->getName() == "imm") {
2110b57cec5SDimitry Andric         unsigned PredNo = 0;
2120b57cec5SDimitry Andric         if (!Op->getPredicateCalls().empty()) {
2130b57cec5SDimitry Andric           TreePredicateFn PredFn = Op->getPredicateCalls()[0].Fn;
2140b57cec5SDimitry Andric           // If there is more than one predicate weighing in on this operand
2150b57cec5SDimitry Andric           // then we don't handle it.  This doesn't typically happen for
2160b57cec5SDimitry Andric           // immediates anyway.
2170b57cec5SDimitry Andric           if (Op->getPredicateCalls().size() > 1 ||
2180b57cec5SDimitry Andric               !PredFn.isImmediatePattern() || PredFn.usesOperands())
2190b57cec5SDimitry Andric             return false;
2200b57cec5SDimitry Andric           // Ignore any instruction with 'FastIselShouldIgnore', these are
2210b57cec5SDimitry Andric           // not needed and just bloat the fast instruction selector.  For
2220b57cec5SDimitry Andric           // example, X86 doesn't need to generate code to match ADD16ri8 since
2230b57cec5SDimitry Andric           // ADD16ri will do just fine.
2240b57cec5SDimitry Andric           Record *Rec = PredFn.getOrigPatFragRecord()->getRecord();
2250b57cec5SDimitry Andric           if (Rec->getValueAsBit("FastIselShouldIgnore"))
2260b57cec5SDimitry Andric             return false;
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric           PredNo = ImmediatePredicates.getIDFor(PredFn)+1;
2290b57cec5SDimitry Andric         }
2300b57cec5SDimitry Andric 
2310b57cec5SDimitry Andric         Operands.push_back(OpKind::getImm(PredNo));
2320b57cec5SDimitry Andric         continue;
2330b57cec5SDimitry Andric       }
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric       // For now, filter out any operand with a predicate.
2370b57cec5SDimitry Andric       // For now, filter out any operand with multiple values.
2380b57cec5SDimitry Andric       if (!Op->getPredicateCalls().empty() || Op->getNumTypes() != 1)
2390b57cec5SDimitry Andric         return false;
2400b57cec5SDimitry Andric 
2410b57cec5SDimitry Andric       if (!Op->isLeaf()) {
2420b57cec5SDimitry Andric          if (Op->getOperator()->getName() == "fpimm") {
2430b57cec5SDimitry Andric           Operands.push_back(OpKind::getFP());
2440b57cec5SDimitry Andric           continue;
2450b57cec5SDimitry Andric         }
2460b57cec5SDimitry Andric         // For now, ignore other non-leaf nodes.
2470b57cec5SDimitry Andric         return false;
2480b57cec5SDimitry Andric       }
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric       assert(Op->hasConcreteType(0) && "Type infererence not done?");
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric       // For now, all the operands must have the same type (if they aren't
2530b57cec5SDimitry Andric       // immediates).  Note that this causes us to reject variable sized shifts
2540b57cec5SDimitry Andric       // on X86.
2550b57cec5SDimitry Andric       if (Op->getSimpleType(0) != VT)
2560b57cec5SDimitry Andric         return false;
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric       DefInit *OpDI = dyn_cast<DefInit>(Op->getLeafValue());
2590b57cec5SDimitry Andric       if (!OpDI)
2600b57cec5SDimitry Andric         return false;
2610b57cec5SDimitry Andric       Record *OpLeafRec = OpDI->getDef();
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric       // For now, the only other thing we accept is register operands.
2640b57cec5SDimitry Andric       const CodeGenRegisterClass *RC = nullptr;
2650b57cec5SDimitry Andric       if (OpLeafRec->isSubClassOf("RegisterOperand"))
2660b57cec5SDimitry Andric         OpLeafRec = OpLeafRec->getValueAsDef("RegClass");
2670b57cec5SDimitry Andric       if (OpLeafRec->isSubClassOf("RegisterClass"))
2680b57cec5SDimitry Andric         RC = &Target.getRegisterClass(OpLeafRec);
2690b57cec5SDimitry Andric       else if (OpLeafRec->isSubClassOf("Register"))
2700b57cec5SDimitry Andric         RC = Target.getRegBank().getRegClassForRegister(OpLeafRec);
2710b57cec5SDimitry Andric       else if (OpLeafRec->isSubClassOf("ValueType")) {
2720b57cec5SDimitry Andric         RC = OrigDstRC;
2730b57cec5SDimitry Andric       } else
2740b57cec5SDimitry Andric         return false;
2750b57cec5SDimitry Andric 
2760b57cec5SDimitry Andric       // For now, this needs to be a register class of some sort.
2770b57cec5SDimitry Andric       if (!RC)
2780b57cec5SDimitry Andric         return false;
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric       // For now, all the operands must have the same register class or be
2810b57cec5SDimitry Andric       // a strict subclass of the destination.
2820b57cec5SDimitry Andric       if (DstRC) {
2830b57cec5SDimitry Andric         if (DstRC != RC && !DstRC->hasSubClass(RC))
2840b57cec5SDimitry Andric           return false;
2850b57cec5SDimitry Andric       } else
2860b57cec5SDimitry Andric         DstRC = RC;
2870b57cec5SDimitry Andric       Operands.push_back(OpKind::getReg());
2880b57cec5SDimitry Andric     }
2890b57cec5SDimitry Andric     return true;
2900b57cec5SDimitry Andric   }
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric   void PrintParameters(raw_ostream &OS) const {
293*fe6060f1SDimitry Andric     ListSeparator LS;
2940b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
295*fe6060f1SDimitry Andric       OS << LS;
2960b57cec5SDimitry Andric       if (Operands[i].isReg()) {
297*fe6060f1SDimitry Andric         OS << "unsigned Op" << i;
2980b57cec5SDimitry Andric       } else if (Operands[i].isImm()) {
2990b57cec5SDimitry Andric         OS << "uint64_t imm" << i;
3000b57cec5SDimitry Andric       } else if (Operands[i].isFP()) {
3010b57cec5SDimitry Andric         OS << "const ConstantFP *f" << i;
3020b57cec5SDimitry Andric       } else {
3030b57cec5SDimitry Andric         llvm_unreachable("Unknown operand kind!");
3040b57cec5SDimitry Andric       }
3050b57cec5SDimitry Andric     }
3060b57cec5SDimitry Andric   }
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric   void PrintArguments(raw_ostream &OS,
3090b57cec5SDimitry Andric                       const std::vector<std::string> &PR) const {
3100b57cec5SDimitry Andric     assert(PR.size() == Operands.size());
311*fe6060f1SDimitry Andric     ListSeparator LS;
3120b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
3130b57cec5SDimitry Andric       if (PR[i] != "")
3140b57cec5SDimitry Andric         // Implicit physical register operand.
3150b57cec5SDimitry Andric         continue;
3160b57cec5SDimitry Andric 
317*fe6060f1SDimitry Andric       OS << LS;
3180b57cec5SDimitry Andric       if (Operands[i].isReg()) {
319*fe6060f1SDimitry Andric         OS << "Op" << i;
3200b57cec5SDimitry Andric       } else if (Operands[i].isImm()) {
3210b57cec5SDimitry Andric         OS << "imm" << i;
3220b57cec5SDimitry Andric       } else if (Operands[i].isFP()) {
3230b57cec5SDimitry Andric         OS << "f" << i;
3240b57cec5SDimitry Andric       } else {
3250b57cec5SDimitry Andric         llvm_unreachable("Unknown operand kind!");
3260b57cec5SDimitry Andric       }
3270b57cec5SDimitry Andric     }
3280b57cec5SDimitry Andric   }
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric   void PrintArguments(raw_ostream &OS) const {
331*fe6060f1SDimitry Andric     ListSeparator LS;
3320b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
333*fe6060f1SDimitry Andric       OS << LS;
3340b57cec5SDimitry Andric       if (Operands[i].isReg()) {
335*fe6060f1SDimitry Andric         OS << "Op" << i;
3360b57cec5SDimitry Andric       } else if (Operands[i].isImm()) {
3370b57cec5SDimitry Andric         OS << "imm" << i;
3380b57cec5SDimitry Andric       } else if (Operands[i].isFP()) {
3390b57cec5SDimitry Andric         OS << "f" << i;
3400b57cec5SDimitry Andric       } else {
3410b57cec5SDimitry Andric         llvm_unreachable("Unknown operand kind!");
3420b57cec5SDimitry Andric       }
3430b57cec5SDimitry Andric     }
3440b57cec5SDimitry Andric   }
3450b57cec5SDimitry Andric 
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric   void PrintManglingSuffix(raw_ostream &OS, const std::vector<std::string> &PR,
3480b57cec5SDimitry Andric                            ImmPredicateSet &ImmPredicates,
3490b57cec5SDimitry Andric                            bool StripImmCodes = false) const {
3500b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
3510b57cec5SDimitry Andric       if (PR[i] != "")
3520b57cec5SDimitry Andric         // Implicit physical register operand. e.g. Instruction::Mul expect to
3530b57cec5SDimitry Andric         // select to a binary op. On x86, mul may take a single operand with
3540b57cec5SDimitry Andric         // the other operand being implicit. We must emit something that looks
3550b57cec5SDimitry Andric         // like a binary instruction except for the very inner fastEmitInst_*
3560b57cec5SDimitry Andric         // call.
3570b57cec5SDimitry Andric         continue;
3580b57cec5SDimitry Andric       Operands[i].printManglingSuffix(OS, ImmPredicates, StripImmCodes);
3590b57cec5SDimitry Andric     }
3600b57cec5SDimitry Andric   }
3610b57cec5SDimitry Andric 
3620b57cec5SDimitry Andric   void PrintManglingSuffix(raw_ostream &OS, ImmPredicateSet &ImmPredicates,
3630b57cec5SDimitry Andric                            bool StripImmCodes = false) const {
3640b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i)
3650b57cec5SDimitry Andric       Operands[i].printManglingSuffix(OS, ImmPredicates, StripImmCodes);
3660b57cec5SDimitry Andric   }
3670b57cec5SDimitry Andric };
3680b57cec5SDimitry Andric } // End anonymous namespace
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric namespace {
3710b57cec5SDimitry Andric class FastISelMap {
3720b57cec5SDimitry Andric   // A multimap is needed instead of a "plain" map because the key is
3730b57cec5SDimitry Andric   // the instruction's complexity (an int) and they are not unique.
3740b57cec5SDimitry Andric   typedef std::multimap<int, InstructionMemo> PredMap;
3750b57cec5SDimitry Andric   typedef std::map<MVT::SimpleValueType, PredMap> RetPredMap;
3760b57cec5SDimitry Andric   typedef std::map<MVT::SimpleValueType, RetPredMap> TypeRetPredMap;
3770b57cec5SDimitry Andric   typedef std::map<std::string, TypeRetPredMap> OpcodeTypeRetPredMap;
3780b57cec5SDimitry Andric   typedef std::map<OperandsSignature, OpcodeTypeRetPredMap>
3790b57cec5SDimitry Andric             OperandsOpcodeTypeRetPredMap;
3800b57cec5SDimitry Andric 
3810b57cec5SDimitry Andric   OperandsOpcodeTypeRetPredMap SimplePatterns;
3820b57cec5SDimitry Andric 
3830b57cec5SDimitry Andric   // This is used to check that there are no duplicate predicates
3840b57cec5SDimitry Andric   typedef std::multimap<std::string, bool> PredCheckMap;
3850b57cec5SDimitry Andric   typedef std::map<MVT::SimpleValueType, PredCheckMap> RetPredCheckMap;
3860b57cec5SDimitry Andric   typedef std::map<MVT::SimpleValueType, RetPredCheckMap> TypeRetPredCheckMap;
3870b57cec5SDimitry Andric   typedef std::map<std::string, TypeRetPredCheckMap> OpcodeTypeRetPredCheckMap;
3880b57cec5SDimitry Andric   typedef std::map<OperandsSignature, OpcodeTypeRetPredCheckMap>
3890b57cec5SDimitry Andric             OperandsOpcodeTypeRetPredCheckMap;
3900b57cec5SDimitry Andric 
3910b57cec5SDimitry Andric   OperandsOpcodeTypeRetPredCheckMap SimplePatternsCheck;
3920b57cec5SDimitry Andric 
3930b57cec5SDimitry Andric   std::map<OperandsSignature, std::vector<OperandsSignature> >
3940b57cec5SDimitry Andric     SignaturesWithConstantForms;
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric   StringRef InstNS;
3970b57cec5SDimitry Andric   ImmPredicateSet ImmediatePredicates;
3980b57cec5SDimitry Andric public:
3990b57cec5SDimitry Andric   explicit FastISelMap(StringRef InstNS);
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric   void collectPatterns(CodeGenDAGPatterns &CGP);
4020b57cec5SDimitry Andric   void printImmediatePredicates(raw_ostream &OS);
4030b57cec5SDimitry Andric   void printFunctionDefinitions(raw_ostream &OS);
4040b57cec5SDimitry Andric private:
4050b57cec5SDimitry Andric   void emitInstructionCode(raw_ostream &OS,
4060b57cec5SDimitry Andric                            const OperandsSignature &Operands,
4070b57cec5SDimitry Andric                            const PredMap &PM,
4080b57cec5SDimitry Andric                            const std::string &RetVTName);
4090b57cec5SDimitry Andric };
4100b57cec5SDimitry Andric } // End anonymous namespace
4110b57cec5SDimitry Andric 
4120b57cec5SDimitry Andric static std::string getOpcodeName(Record *Op, CodeGenDAGPatterns &CGP) {
4135ffd83dbSDimitry Andric   return std::string(CGP.getSDNodeInfo(Op).getEnumName());
4140b57cec5SDimitry Andric }
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric static std::string getLegalCName(std::string OpName) {
4170b57cec5SDimitry Andric   std::string::size_type pos = OpName.find("::");
4180b57cec5SDimitry Andric   if (pos != std::string::npos)
4190b57cec5SDimitry Andric     OpName.replace(pos, 2, "_");
4200b57cec5SDimitry Andric   return OpName;
4210b57cec5SDimitry Andric }
4220b57cec5SDimitry Andric 
4230b57cec5SDimitry Andric FastISelMap::FastISelMap(StringRef instns) : InstNS(instns) {}
4240b57cec5SDimitry Andric 
4250b57cec5SDimitry Andric static std::string PhyRegForNode(TreePatternNode *Op,
4260b57cec5SDimitry Andric                                  const CodeGenTarget &Target) {
4270b57cec5SDimitry Andric   std::string PhysReg;
4280b57cec5SDimitry Andric 
4290b57cec5SDimitry Andric   if (!Op->isLeaf())
4300b57cec5SDimitry Andric     return PhysReg;
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric   Record *OpLeafRec = cast<DefInit>(Op->getLeafValue())->getDef();
4330b57cec5SDimitry Andric   if (!OpLeafRec->isSubClassOf("Register"))
4340b57cec5SDimitry Andric     return PhysReg;
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric   PhysReg += cast<StringInit>(OpLeafRec->getValue("Namespace")->getValue())
4370b57cec5SDimitry Andric                ->getValue();
4380b57cec5SDimitry Andric   PhysReg += "::";
4390b57cec5SDimitry Andric   PhysReg += Target.getRegBank().getReg(OpLeafRec)->getName();
4400b57cec5SDimitry Andric   return PhysReg;
4410b57cec5SDimitry Andric }
4420b57cec5SDimitry Andric 
4430b57cec5SDimitry Andric void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) {
4440b57cec5SDimitry Andric   const CodeGenTarget &Target = CGP.getTargetInfo();
4450b57cec5SDimitry Andric 
4460b57cec5SDimitry Andric   // Scan through all the patterns and record the simple ones.
4470b57cec5SDimitry Andric   for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(),
4480b57cec5SDimitry Andric        E = CGP.ptm_end(); I != E; ++I) {
4490b57cec5SDimitry Andric     const PatternToMatch &Pattern = *I;
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric     // For now, just look at Instructions, so that we don't have to worry
4520b57cec5SDimitry Andric     // about emitting multiple instructions for a pattern.
4530b57cec5SDimitry Andric     TreePatternNode *Dst = Pattern.getDstPattern();
4540b57cec5SDimitry Andric     if (Dst->isLeaf()) continue;
4550b57cec5SDimitry Andric     Record *Op = Dst->getOperator();
4560b57cec5SDimitry Andric     if (!Op->isSubClassOf("Instruction"))
4570b57cec5SDimitry Andric       continue;
4580b57cec5SDimitry Andric     CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op);
4590b57cec5SDimitry Andric     if (II.Operands.empty())
4600b57cec5SDimitry Andric       continue;
4610b57cec5SDimitry Andric 
4620b57cec5SDimitry Andric     // Allow instructions to be marked as unavailable for FastISel for
4630b57cec5SDimitry Andric     // certain cases, i.e. an ISA has two 'and' instruction which differ
4640b57cec5SDimitry Andric     // by what registers they can use but are otherwise identical for
4650b57cec5SDimitry Andric     // codegen purposes.
4660b57cec5SDimitry Andric     if (II.FastISelShouldIgnore)
4670b57cec5SDimitry Andric       continue;
4680b57cec5SDimitry Andric 
4690b57cec5SDimitry Andric     // For now, ignore multi-instruction patterns.
4700b57cec5SDimitry Andric     bool MultiInsts = false;
4710b57cec5SDimitry Andric     for (unsigned i = 0, e = Dst->getNumChildren(); i != e; ++i) {
4720b57cec5SDimitry Andric       TreePatternNode *ChildOp = Dst->getChild(i);
4730b57cec5SDimitry Andric       if (ChildOp->isLeaf())
4740b57cec5SDimitry Andric         continue;
4750b57cec5SDimitry Andric       if (ChildOp->getOperator()->isSubClassOf("Instruction")) {
4760b57cec5SDimitry Andric         MultiInsts = true;
4770b57cec5SDimitry Andric         break;
4780b57cec5SDimitry Andric       }
4790b57cec5SDimitry Andric     }
4800b57cec5SDimitry Andric     if (MultiInsts)
4810b57cec5SDimitry Andric       continue;
4820b57cec5SDimitry Andric 
4830b57cec5SDimitry Andric     // For now, ignore instructions where the first operand is not an
4840b57cec5SDimitry Andric     // output register.
4850b57cec5SDimitry Andric     const CodeGenRegisterClass *DstRC = nullptr;
4860b57cec5SDimitry Andric     std::string SubRegNo;
4870b57cec5SDimitry Andric     if (Op->getName() != "EXTRACT_SUBREG") {
4880b57cec5SDimitry Andric       Record *Op0Rec = II.Operands[0].Rec;
4890b57cec5SDimitry Andric       if (Op0Rec->isSubClassOf("RegisterOperand"))
4900b57cec5SDimitry Andric         Op0Rec = Op0Rec->getValueAsDef("RegClass");
4910b57cec5SDimitry Andric       if (!Op0Rec->isSubClassOf("RegisterClass"))
4920b57cec5SDimitry Andric         continue;
4930b57cec5SDimitry Andric       DstRC = &Target.getRegisterClass(Op0Rec);
4940b57cec5SDimitry Andric       if (!DstRC)
4950b57cec5SDimitry Andric         continue;
4960b57cec5SDimitry Andric     } else {
4970b57cec5SDimitry Andric       // If this isn't a leaf, then continue since the register classes are
4980b57cec5SDimitry Andric       // a bit too complicated for now.
4990b57cec5SDimitry Andric       if (!Dst->getChild(1)->isLeaf()) continue;
5000b57cec5SDimitry Andric 
5010b57cec5SDimitry Andric       DefInit *SR = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
5020b57cec5SDimitry Andric       if (SR)
5030b57cec5SDimitry Andric         SubRegNo = getQualifiedName(SR->getDef());
5040b57cec5SDimitry Andric       else
5050b57cec5SDimitry Andric         SubRegNo = Dst->getChild(1)->getLeafValue()->getAsString();
5060b57cec5SDimitry Andric     }
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric     // Inspect the pattern.
5090b57cec5SDimitry Andric     TreePatternNode *InstPatNode = Pattern.getSrcPattern();
5100b57cec5SDimitry Andric     if (!InstPatNode) continue;
5110b57cec5SDimitry Andric     if (InstPatNode->isLeaf()) continue;
5120b57cec5SDimitry Andric 
5130b57cec5SDimitry Andric     // Ignore multiple result nodes for now.
5140b57cec5SDimitry Andric     if (InstPatNode->getNumTypes() > 1) continue;
5150b57cec5SDimitry Andric 
5160b57cec5SDimitry Andric     Record *InstPatOp = InstPatNode->getOperator();
5170b57cec5SDimitry Andric     std::string OpcodeName = getOpcodeName(InstPatOp, CGP);
5180b57cec5SDimitry Andric     MVT::SimpleValueType RetVT = MVT::isVoid;
5190b57cec5SDimitry Andric     if (InstPatNode->getNumTypes()) RetVT = InstPatNode->getSimpleType(0);
5200b57cec5SDimitry Andric     MVT::SimpleValueType VT = RetVT;
5210b57cec5SDimitry Andric     if (InstPatNode->getNumChildren()) {
5220b57cec5SDimitry Andric       assert(InstPatNode->getChild(0)->getNumTypes() == 1);
5230b57cec5SDimitry Andric       VT = InstPatNode->getChild(0)->getSimpleType(0);
5240b57cec5SDimitry Andric     }
5250b57cec5SDimitry Andric 
5260b57cec5SDimitry Andric     // For now, filter out any instructions with predicates.
5270b57cec5SDimitry Andric     if (!InstPatNode->getPredicateCalls().empty())
5280b57cec5SDimitry Andric       continue;
5290b57cec5SDimitry Andric 
5300b57cec5SDimitry Andric     // Check all the operands.
5310b57cec5SDimitry Andric     OperandsSignature Operands;
5320b57cec5SDimitry Andric     if (!Operands.initialize(InstPatNode, Target, VT, ImmediatePredicates,
5330b57cec5SDimitry Andric                              DstRC))
5340b57cec5SDimitry Andric       continue;
5350b57cec5SDimitry Andric 
5360b57cec5SDimitry Andric     std::vector<std::string> PhysRegInputs;
5370b57cec5SDimitry Andric     if (InstPatNode->getOperator()->getName() == "imm" ||
5380b57cec5SDimitry Andric         InstPatNode->getOperator()->getName() == "fpimm")
5390b57cec5SDimitry Andric       PhysRegInputs.push_back("");
5400b57cec5SDimitry Andric     else {
5410b57cec5SDimitry Andric       // Compute the PhysRegs used by the given pattern, and check that
5420b57cec5SDimitry Andric       // the mapping from the src to dst patterns is simple.
5430b57cec5SDimitry Andric       bool FoundNonSimplePattern = false;
5440b57cec5SDimitry Andric       unsigned DstIndex = 0;
5450b57cec5SDimitry Andric       for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) {
5460b57cec5SDimitry Andric         std::string PhysReg = PhyRegForNode(InstPatNode->getChild(i), Target);
5470b57cec5SDimitry Andric         if (PhysReg.empty()) {
5480b57cec5SDimitry Andric           if (DstIndex >= Dst->getNumChildren() ||
5490b57cec5SDimitry Andric               Dst->getChild(DstIndex)->getName() !=
5500b57cec5SDimitry Andric               InstPatNode->getChild(i)->getName()) {
5510b57cec5SDimitry Andric             FoundNonSimplePattern = true;
5520b57cec5SDimitry Andric             break;
5530b57cec5SDimitry Andric           }
5540b57cec5SDimitry Andric           ++DstIndex;
5550b57cec5SDimitry Andric         }
5560b57cec5SDimitry Andric 
5570b57cec5SDimitry Andric         PhysRegInputs.push_back(PhysReg);
5580b57cec5SDimitry Andric       }
5590b57cec5SDimitry Andric 
5600b57cec5SDimitry Andric       if (Op->getName() != "EXTRACT_SUBREG" && DstIndex < Dst->getNumChildren())
5610b57cec5SDimitry Andric         FoundNonSimplePattern = true;
5620b57cec5SDimitry Andric 
5630b57cec5SDimitry Andric       if (FoundNonSimplePattern)
5640b57cec5SDimitry Andric         continue;
5650b57cec5SDimitry Andric     }
5660b57cec5SDimitry Andric 
5670b57cec5SDimitry Andric     // Check if the operands match one of the patterns handled by FastISel.
5680b57cec5SDimitry Andric     std::string ManglingSuffix;
5690b57cec5SDimitry Andric     raw_string_ostream SuffixOS(ManglingSuffix);
5700b57cec5SDimitry Andric     Operands.PrintManglingSuffix(SuffixOS, ImmediatePredicates, true);
5710b57cec5SDimitry Andric     SuffixOS.flush();
5720b57cec5SDimitry Andric     if (!StringSwitch<bool>(ManglingSuffix)
5730b57cec5SDimitry Andric         .Cases("", "r", "rr", "ri", "i", "f", true)
5740b57cec5SDimitry Andric         .Default(false))
5750b57cec5SDimitry Andric       continue;
5760b57cec5SDimitry Andric 
5770b57cec5SDimitry Andric     // Get the predicate that guards this pattern.
5780b57cec5SDimitry Andric     std::string PredicateCheck = Pattern.getPredicateCheck();
5790b57cec5SDimitry Andric 
5800b57cec5SDimitry Andric     // Ok, we found a pattern that we can handle. Remember it.
5810b57cec5SDimitry Andric     InstructionMemo Memo(
5820b57cec5SDimitry Andric       Pattern.getDstPattern()->getOperator()->getName(),
5830b57cec5SDimitry Andric       DstRC,
5840b57cec5SDimitry Andric       SubRegNo,
5850b57cec5SDimitry Andric       PhysRegInputs,
5860b57cec5SDimitry Andric       PredicateCheck
5870b57cec5SDimitry Andric     );
5880b57cec5SDimitry Andric 
5890b57cec5SDimitry Andric     int complexity = Pattern.getPatternComplexity(CGP);
5900b57cec5SDimitry Andric 
5910b57cec5SDimitry Andric     if (SimplePatternsCheck[Operands][OpcodeName][VT]
5920b57cec5SDimitry Andric          [RetVT].count(PredicateCheck)) {
5930b57cec5SDimitry Andric       PrintFatalError(Pattern.getSrcRecord()->getLoc(),
5940b57cec5SDimitry Andric                     "Duplicate predicate in FastISel table!");
5950b57cec5SDimitry Andric     }
5960b57cec5SDimitry Andric     SimplePatternsCheck[Operands][OpcodeName][VT][RetVT].insert(
5970b57cec5SDimitry Andric             std::make_pair(PredicateCheck, true));
5980b57cec5SDimitry Andric 
5990b57cec5SDimitry Andric        // Note: Instructions with the same complexity will appear in the order
6000b57cec5SDimitry Andric           // that they are encountered.
6010b57cec5SDimitry Andric     SimplePatterns[Operands][OpcodeName][VT][RetVT].emplace(complexity,
6020b57cec5SDimitry Andric                                                             std::move(Memo));
6030b57cec5SDimitry Andric 
6040b57cec5SDimitry Andric     // If any of the operands were immediates with predicates on them, strip
6050b57cec5SDimitry Andric     // them down to a signature that doesn't have predicates so that we can
6060b57cec5SDimitry Andric     // associate them with the stripped predicate version.
6070b57cec5SDimitry Andric     if (Operands.hasAnyImmediateCodes()) {
6080b57cec5SDimitry Andric       SignaturesWithConstantForms[Operands.getWithoutImmCodes()]
6090b57cec5SDimitry Andric         .push_back(Operands);
6100b57cec5SDimitry Andric     }
6110b57cec5SDimitry Andric   }
6120b57cec5SDimitry Andric }
6130b57cec5SDimitry Andric 
6140b57cec5SDimitry Andric void FastISelMap::printImmediatePredicates(raw_ostream &OS) {
6150b57cec5SDimitry Andric   if (ImmediatePredicates.begin() == ImmediatePredicates.end())
6160b57cec5SDimitry Andric     return;
6170b57cec5SDimitry Andric 
6180b57cec5SDimitry Andric   OS << "\n// FastEmit Immediate Predicate functions.\n";
619*fe6060f1SDimitry Andric   for (auto ImmediatePredicate : ImmediatePredicates) {
620*fe6060f1SDimitry Andric     OS << "static bool " << ImmediatePredicate.getFnName()
621*fe6060f1SDimitry Andric        << "(int64_t Imm) {\n";
622*fe6060f1SDimitry Andric     OS << ImmediatePredicate.getImmediatePredicateCode() << "\n}\n";
6230b57cec5SDimitry Andric   }
6240b57cec5SDimitry Andric 
6250b57cec5SDimitry Andric   OS << "\n\n";
6260b57cec5SDimitry Andric }
6270b57cec5SDimitry Andric 
6280b57cec5SDimitry Andric void FastISelMap::emitInstructionCode(raw_ostream &OS,
6290b57cec5SDimitry Andric                                       const OperandsSignature &Operands,
6300b57cec5SDimitry Andric                                       const PredMap &PM,
6310b57cec5SDimitry Andric                                       const std::string &RetVTName) {
6320b57cec5SDimitry Andric   // Emit code for each possible instruction. There may be
6330b57cec5SDimitry Andric   // multiple if there are subtarget concerns.  A reverse iterator
6340b57cec5SDimitry Andric   // is used to produce the ones with highest complexity first.
6350b57cec5SDimitry Andric 
6360b57cec5SDimitry Andric   bool OneHadNoPredicate = false;
6370b57cec5SDimitry Andric   for (PredMap::const_reverse_iterator PI = PM.rbegin(), PE = PM.rend();
6380b57cec5SDimitry Andric        PI != PE; ++PI) {
6390b57cec5SDimitry Andric     const InstructionMemo &Memo = PI->second;
6400b57cec5SDimitry Andric     std::string PredicateCheck = Memo.PredicateCheck;
6410b57cec5SDimitry Andric 
6420b57cec5SDimitry Andric     if (PredicateCheck.empty()) {
6430b57cec5SDimitry Andric       assert(!OneHadNoPredicate &&
6440b57cec5SDimitry Andric              "Multiple instructions match and more than one had "
6450b57cec5SDimitry Andric              "no predicate!");
6460b57cec5SDimitry Andric       OneHadNoPredicate = true;
6470b57cec5SDimitry Andric     } else {
6480b57cec5SDimitry Andric       if (OneHadNoPredicate) {
6490b57cec5SDimitry Andric         PrintFatalError("Multiple instructions match and one with no "
6500b57cec5SDimitry Andric                         "predicate came before one with a predicate!  "
6510b57cec5SDimitry Andric                         "name:" + Memo.Name + "  predicate: " + PredicateCheck);
6520b57cec5SDimitry Andric       }
6530b57cec5SDimitry Andric       OS << "  if (" + PredicateCheck + ") {\n";
6540b57cec5SDimitry Andric       OS << "  ";
6550b57cec5SDimitry Andric     }
6560b57cec5SDimitry Andric 
6570b57cec5SDimitry Andric     for (unsigned i = 0; i < Memo.PhysRegs.size(); ++i) {
6580b57cec5SDimitry Andric       if (Memo.PhysRegs[i] != "")
6590b57cec5SDimitry Andric         OS << "  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, "
6600b57cec5SDimitry Andric            << "TII.get(TargetOpcode::COPY), " << Memo.PhysRegs[i]
6610b57cec5SDimitry Andric            << ").addReg(Op" << i << ");\n";
6620b57cec5SDimitry Andric     }
6630b57cec5SDimitry Andric 
6640b57cec5SDimitry Andric     OS << "  return fastEmitInst_";
6650b57cec5SDimitry Andric     if (Memo.SubRegNo.empty()) {
6660b57cec5SDimitry Andric       Operands.PrintManglingSuffix(OS, Memo.PhysRegs, ImmediatePredicates,
6670b57cec5SDimitry Andric                                    true);
6680b57cec5SDimitry Andric       OS << "(" << InstNS << "::" << Memo.Name << ", ";
6690b57cec5SDimitry Andric       OS << "&" << InstNS << "::" << Memo.RC->getName() << "RegClass";
6700b57cec5SDimitry Andric       if (!Operands.empty())
6710b57cec5SDimitry Andric         OS << ", ";
6720b57cec5SDimitry Andric       Operands.PrintArguments(OS, Memo.PhysRegs);
6730b57cec5SDimitry Andric       OS << ");\n";
6740b57cec5SDimitry Andric     } else {
6750b57cec5SDimitry Andric       OS << "extractsubreg(" << RetVTName
676*fe6060f1SDimitry Andric          << ", Op0, " << Memo.SubRegNo << ");\n";
6770b57cec5SDimitry Andric     }
6780b57cec5SDimitry Andric 
6790b57cec5SDimitry Andric     if (!PredicateCheck.empty()) {
6800b57cec5SDimitry Andric       OS << "  }\n";
6810b57cec5SDimitry Andric     }
6820b57cec5SDimitry Andric   }
6830b57cec5SDimitry Andric   // Return 0 if all of the possibilities had predicates but none
6840b57cec5SDimitry Andric   // were satisfied.
6850b57cec5SDimitry Andric   if (!OneHadNoPredicate)
6860b57cec5SDimitry Andric     OS << "  return 0;\n";
6870b57cec5SDimitry Andric   OS << "}\n";
6880b57cec5SDimitry Andric   OS << "\n";
6890b57cec5SDimitry Andric }
6900b57cec5SDimitry Andric 
6910b57cec5SDimitry Andric 
6920b57cec5SDimitry Andric void FastISelMap::printFunctionDefinitions(raw_ostream &OS) {
6930b57cec5SDimitry Andric   // Now emit code for all the patterns that we collected.
694*fe6060f1SDimitry Andric   for (const auto &SimplePattern : SimplePatterns) {
695*fe6060f1SDimitry Andric     const OperandsSignature &Operands = SimplePattern.first;
696*fe6060f1SDimitry Andric     const OpcodeTypeRetPredMap &OTM = SimplePattern.second;
6970b57cec5SDimitry Andric 
698*fe6060f1SDimitry Andric     for (const auto &I : OTM) {
699*fe6060f1SDimitry Andric       const std::string &Opcode = I.first;
700*fe6060f1SDimitry Andric       const TypeRetPredMap &TM = I.second;
7010b57cec5SDimitry Andric 
7020b57cec5SDimitry Andric       OS << "// FastEmit functions for " << Opcode << ".\n";
7030b57cec5SDimitry Andric       OS << "\n";
7040b57cec5SDimitry Andric 
7050b57cec5SDimitry Andric       // Emit one function for each opcode,type pair.
706*fe6060f1SDimitry Andric       for (const auto &TI : TM) {
707*fe6060f1SDimitry Andric         MVT::SimpleValueType VT = TI.first;
708*fe6060f1SDimitry Andric         const RetPredMap &RM = TI.second;
7090b57cec5SDimitry Andric         if (RM.size() != 1) {
710*fe6060f1SDimitry Andric           for (const auto &RI : RM) {
711*fe6060f1SDimitry Andric             MVT::SimpleValueType RetVT = RI.first;
712*fe6060f1SDimitry Andric             const PredMap &PM = RI.second;
7130b57cec5SDimitry Andric 
7145ffd83dbSDimitry Andric             OS << "unsigned fastEmit_" << getLegalCName(Opcode) << "_"
7155ffd83dbSDimitry Andric                << getLegalCName(std::string(getName(VT))) << "_"
7165ffd83dbSDimitry Andric                << getLegalCName(std::string(getName(RetVT))) << "_";
7170b57cec5SDimitry Andric             Operands.PrintManglingSuffix(OS, ImmediatePredicates);
7180b57cec5SDimitry Andric             OS << "(";
7190b57cec5SDimitry Andric             Operands.PrintParameters(OS);
7200b57cec5SDimitry Andric             OS << ") {\n";
7210b57cec5SDimitry Andric 
7225ffd83dbSDimitry Andric             emitInstructionCode(OS, Operands, PM, std::string(getName(RetVT)));
7230b57cec5SDimitry Andric           }
7240b57cec5SDimitry Andric 
7250b57cec5SDimitry Andric           // Emit one function for the type that demultiplexes on return type.
7265ffd83dbSDimitry Andric           OS << "unsigned fastEmit_" << getLegalCName(Opcode) << "_"
7275ffd83dbSDimitry Andric              << getLegalCName(std::string(getName(VT))) << "_";
7280b57cec5SDimitry Andric           Operands.PrintManglingSuffix(OS, ImmediatePredicates);
7290b57cec5SDimitry Andric           OS << "(MVT RetVT";
7300b57cec5SDimitry Andric           if (!Operands.empty())
7310b57cec5SDimitry Andric             OS << ", ";
7320b57cec5SDimitry Andric           Operands.PrintParameters(OS);
7330b57cec5SDimitry Andric           OS << ") {\nswitch (RetVT.SimpleTy) {\n";
734*fe6060f1SDimitry Andric           for (const auto &RI : RM) {
735*fe6060f1SDimitry Andric             MVT::SimpleValueType RetVT = RI.first;
7360b57cec5SDimitry Andric             OS << "  case " << getName(RetVT) << ": return fastEmit_"
7375ffd83dbSDimitry Andric                << getLegalCName(Opcode) << "_"
7385ffd83dbSDimitry Andric                << getLegalCName(std::string(getName(VT))) << "_"
7395ffd83dbSDimitry Andric                << getLegalCName(std::string(getName(RetVT))) << "_";
7400b57cec5SDimitry Andric             Operands.PrintManglingSuffix(OS, ImmediatePredicates);
7410b57cec5SDimitry Andric             OS << "(";
7420b57cec5SDimitry Andric             Operands.PrintArguments(OS);
7430b57cec5SDimitry Andric             OS << ");\n";
7440b57cec5SDimitry Andric           }
7450b57cec5SDimitry Andric           OS << "  default: return 0;\n}\n}\n\n";
7460b57cec5SDimitry Andric 
7470b57cec5SDimitry Andric         } else {
7480b57cec5SDimitry Andric           // Non-variadic return type.
7495ffd83dbSDimitry Andric           OS << "unsigned fastEmit_" << getLegalCName(Opcode) << "_"
7505ffd83dbSDimitry Andric              << getLegalCName(std::string(getName(VT))) << "_";
7510b57cec5SDimitry Andric           Operands.PrintManglingSuffix(OS, ImmediatePredicates);
7520b57cec5SDimitry Andric           OS << "(MVT RetVT";
7530b57cec5SDimitry Andric           if (!Operands.empty())
7540b57cec5SDimitry Andric             OS << ", ";
7550b57cec5SDimitry Andric           Operands.PrintParameters(OS);
7560b57cec5SDimitry Andric           OS << ") {\n";
7570b57cec5SDimitry Andric 
7580b57cec5SDimitry Andric           OS << "  if (RetVT.SimpleTy != " << getName(RM.begin()->first)
7590b57cec5SDimitry Andric              << ")\n    return 0;\n";
7600b57cec5SDimitry Andric 
7610b57cec5SDimitry Andric           const PredMap &PM = RM.begin()->second;
7620b57cec5SDimitry Andric 
7630b57cec5SDimitry Andric           emitInstructionCode(OS, Operands, PM, "RetVT");
7640b57cec5SDimitry Andric         }
7650b57cec5SDimitry Andric       }
7660b57cec5SDimitry Andric 
7670b57cec5SDimitry Andric       // Emit one function for the opcode that demultiplexes based on the type.
7680b57cec5SDimitry Andric       OS << "unsigned fastEmit_"
7690b57cec5SDimitry Andric          << getLegalCName(Opcode) << "_";
7700b57cec5SDimitry Andric       Operands.PrintManglingSuffix(OS, ImmediatePredicates);
7710b57cec5SDimitry Andric       OS << "(MVT VT, MVT RetVT";
7720b57cec5SDimitry Andric       if (!Operands.empty())
7730b57cec5SDimitry Andric         OS << ", ";
7740b57cec5SDimitry Andric       Operands.PrintParameters(OS);
7750b57cec5SDimitry Andric       OS << ") {\n";
7760b57cec5SDimitry Andric       OS << "  switch (VT.SimpleTy) {\n";
777*fe6060f1SDimitry Andric       for (const auto &TI : TM) {
778*fe6060f1SDimitry Andric         MVT::SimpleValueType VT = TI.first;
7795ffd83dbSDimitry Andric         std::string TypeName = std::string(getName(VT));
7800b57cec5SDimitry Andric         OS << "  case " << TypeName << ": return fastEmit_"
7810b57cec5SDimitry Andric            << getLegalCName(Opcode) << "_" << getLegalCName(TypeName) << "_";
7820b57cec5SDimitry Andric         Operands.PrintManglingSuffix(OS, ImmediatePredicates);
7830b57cec5SDimitry Andric         OS << "(RetVT";
7840b57cec5SDimitry Andric         if (!Operands.empty())
7850b57cec5SDimitry Andric           OS << ", ";
7860b57cec5SDimitry Andric         Operands.PrintArguments(OS);
7870b57cec5SDimitry Andric         OS << ");\n";
7880b57cec5SDimitry Andric       }
7890b57cec5SDimitry Andric       OS << "  default: return 0;\n";
7900b57cec5SDimitry Andric       OS << "  }\n";
7910b57cec5SDimitry Andric       OS << "}\n";
7920b57cec5SDimitry Andric       OS << "\n";
7930b57cec5SDimitry Andric     }
7940b57cec5SDimitry Andric 
7950b57cec5SDimitry Andric     OS << "// Top-level FastEmit function.\n";
7960b57cec5SDimitry Andric     OS << "\n";
7970b57cec5SDimitry Andric 
7980b57cec5SDimitry Andric     // Emit one function for the operand signature that demultiplexes based
7990b57cec5SDimitry Andric     // on opcode and type.
8000b57cec5SDimitry Andric     OS << "unsigned fastEmit_";
8010b57cec5SDimitry Andric     Operands.PrintManglingSuffix(OS, ImmediatePredicates);
8020b57cec5SDimitry Andric     OS << "(MVT VT, MVT RetVT, unsigned Opcode";
8030b57cec5SDimitry Andric     if (!Operands.empty())
8040b57cec5SDimitry Andric       OS << ", ";
8050b57cec5SDimitry Andric     Operands.PrintParameters(OS);
8060b57cec5SDimitry Andric     OS << ") ";
8070b57cec5SDimitry Andric     if (!Operands.hasAnyImmediateCodes())
8080b57cec5SDimitry Andric       OS << "override ";
8090b57cec5SDimitry Andric     OS << "{\n";
8100b57cec5SDimitry Andric 
8110b57cec5SDimitry Andric     // If there are any forms of this signature available that operate on
8120b57cec5SDimitry Andric     // constrained forms of the immediate (e.g., 32-bit sext immediate in a
8130b57cec5SDimitry Andric     // 64-bit operand), check them first.
8140b57cec5SDimitry Andric 
8150b57cec5SDimitry Andric     std::map<OperandsSignature, std::vector<OperandsSignature> >::iterator MI
8160b57cec5SDimitry Andric       = SignaturesWithConstantForms.find(Operands);
8170b57cec5SDimitry Andric     if (MI != SignaturesWithConstantForms.end()) {
8180b57cec5SDimitry Andric       // Unique any duplicates out of the list.
8190b57cec5SDimitry Andric       llvm::sort(MI->second);
8200b57cec5SDimitry Andric       MI->second.erase(std::unique(MI->second.begin(), MI->second.end()),
8210b57cec5SDimitry Andric                        MI->second.end());
8220b57cec5SDimitry Andric 
8230b57cec5SDimitry Andric       // Check each in order it was seen.  It would be nice to have a good
8240b57cec5SDimitry Andric       // relative ordering between them, but we're not going for optimality
8250b57cec5SDimitry Andric       // here.
8260b57cec5SDimitry Andric       for (unsigned i = 0, e = MI->second.size(); i != e; ++i) {
8270b57cec5SDimitry Andric         OS << "  if (";
8280b57cec5SDimitry Andric         MI->second[i].emitImmediatePredicate(OS, ImmediatePredicates);
8290b57cec5SDimitry Andric         OS << ")\n    if (unsigned Reg = fastEmit_";
8300b57cec5SDimitry Andric         MI->second[i].PrintManglingSuffix(OS, ImmediatePredicates);
8310b57cec5SDimitry Andric         OS << "(VT, RetVT, Opcode";
8320b57cec5SDimitry Andric         if (!MI->second[i].empty())
8330b57cec5SDimitry Andric           OS << ", ";
8340b57cec5SDimitry Andric         MI->second[i].PrintArguments(OS);
8350b57cec5SDimitry Andric         OS << "))\n      return Reg;\n\n";
8360b57cec5SDimitry Andric       }
8370b57cec5SDimitry Andric 
8380b57cec5SDimitry Andric       // Done with this, remove it.
8390b57cec5SDimitry Andric       SignaturesWithConstantForms.erase(MI);
8400b57cec5SDimitry Andric     }
8410b57cec5SDimitry Andric 
8420b57cec5SDimitry Andric     OS << "  switch (Opcode) {\n";
843*fe6060f1SDimitry Andric     for (const auto &I : OTM) {
844*fe6060f1SDimitry Andric       const std::string &Opcode = I.first;
8450b57cec5SDimitry Andric 
8460b57cec5SDimitry Andric       OS << "  case " << Opcode << ": return fastEmit_"
8470b57cec5SDimitry Andric          << getLegalCName(Opcode) << "_";
8480b57cec5SDimitry Andric       Operands.PrintManglingSuffix(OS, ImmediatePredicates);
8490b57cec5SDimitry Andric       OS << "(VT, RetVT";
8500b57cec5SDimitry Andric       if (!Operands.empty())
8510b57cec5SDimitry Andric         OS << ", ";
8520b57cec5SDimitry Andric       Operands.PrintArguments(OS);
8530b57cec5SDimitry Andric       OS << ");\n";
8540b57cec5SDimitry Andric     }
8550b57cec5SDimitry Andric     OS << "  default: return 0;\n";
8560b57cec5SDimitry Andric     OS << "  }\n";
8570b57cec5SDimitry Andric     OS << "}\n";
8580b57cec5SDimitry Andric     OS << "\n";
8590b57cec5SDimitry Andric   }
8600b57cec5SDimitry Andric 
8610b57cec5SDimitry Andric   // TODO: SignaturesWithConstantForms should be empty here.
8620b57cec5SDimitry Andric }
8630b57cec5SDimitry Andric 
8640b57cec5SDimitry Andric namespace llvm {
8650b57cec5SDimitry Andric 
8660b57cec5SDimitry Andric void EmitFastISel(RecordKeeper &RK, raw_ostream &OS) {
8670b57cec5SDimitry Andric   CodeGenDAGPatterns CGP(RK);
8680b57cec5SDimitry Andric   const CodeGenTarget &Target = CGP.getTargetInfo();
8690b57cec5SDimitry Andric   emitSourceFileHeader("\"Fast\" Instruction Selector for the " +
8700b57cec5SDimitry Andric                        Target.getName().str() + " target", OS);
8710b57cec5SDimitry Andric 
8720b57cec5SDimitry Andric   // Determine the target's namespace name.
8730b57cec5SDimitry Andric   StringRef InstNS = Target.getInstNamespace();
8740b57cec5SDimitry Andric   assert(!InstNS.empty() && "Can't determine target-specific namespace!");
8750b57cec5SDimitry Andric 
8760b57cec5SDimitry Andric   FastISelMap F(InstNS);
8770b57cec5SDimitry Andric   F.collectPatterns(CGP);
8780b57cec5SDimitry Andric   F.printImmediatePredicates(OS);
8790b57cec5SDimitry Andric   F.printFunctionDefinitions(OS);
8800b57cec5SDimitry Andric }
8810b57cec5SDimitry Andric 
8820b57cec5SDimitry Andric } // End llvm namespace
883