10b57cec5SDimitry Andric //===- GlobalISelEmitter.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 /// \file
100b57cec5SDimitry Andric /// This tablegen backend emits code for use by the GlobalISel instruction
1106c3fb27SDimitry Andric /// selector. See include/llvm/Target/GlobalISel/Target.td.
120b57cec5SDimitry Andric ///
130b57cec5SDimitry Andric /// This file analyzes the patterns recognized by the SelectionDAGISel tablegen
140b57cec5SDimitry Andric /// backend, filters out the ones that are unsupported, maps
150b57cec5SDimitry Andric /// SelectionDAG-specific constructs to their GlobalISel counterpart
160b57cec5SDimitry Andric /// (when applicable: MVT to LLT;  SDNode to generic Instruction).
170b57cec5SDimitry Andric ///
180b57cec5SDimitry Andric /// Not all patterns are supported: pass the tablegen invocation
190b57cec5SDimitry Andric /// "-warn-on-skipped-patterns" to emit a warning when a pattern is skipped,
200b57cec5SDimitry Andric /// as well as why.
210b57cec5SDimitry Andric ///
220b57cec5SDimitry Andric /// The generated file defines a single method:
230b57cec5SDimitry Andric ///     bool <Target>InstructionSelector::selectImpl(MachineInstr &I) const;
240b57cec5SDimitry Andric /// intended to be used in InstructionSelector::select as the first-step
250b57cec5SDimitry Andric /// selector for the patterns that don't require complex C++.
260b57cec5SDimitry Andric ///
270b57cec5SDimitry Andric /// FIXME: We'll probably want to eventually define a base
280b57cec5SDimitry Andric /// "TargetGenInstructionSelector" class.
290b57cec5SDimitry Andric ///
300b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric #include "CodeGenDAGPatterns.h"
3381ad6265SDimitry Andric #include "CodeGenInstruction.h"
3406c3fb27SDimitry Andric #include "CodeGenIntrinsics.h"
3506c3fb27SDimitry Andric #include "CodeGenRegisters.h"
3606c3fb27SDimitry Andric #include "CodeGenTarget.h"
3706c3fb27SDimitry Andric #include "GlobalISelMatchTable.h"
3806c3fb27SDimitry Andric #include "GlobalISelMatchTableExecutorEmitter.h"
3906c3fb27SDimitry Andric #include "InfoByHwMode.h"
400b57cec5SDimitry Andric #include "SubtargetFeatureInfo.h"
410b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
4206c3fb27SDimitry Andric #include "llvm/CodeGen/LowLevelType.h"
4306c3fb27SDimitry Andric #include "llvm/CodeGen/MachineValueType.h"
440b57cec5SDimitry Andric #include "llvm/Support/CodeGenCoverage.h"
450b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
460b57cec5SDimitry Andric #include "llvm/Support/Error.h"
4706c3fb27SDimitry Andric #include "llvm/Support/SaveAndRestore.h"
480b57cec5SDimitry Andric #include "llvm/Support/ScopedPrinter.h"
490b57cec5SDimitry Andric #include "llvm/TableGen/Error.h"
500b57cec5SDimitry Andric #include "llvm/TableGen/Record.h"
510b57cec5SDimitry Andric #include "llvm/TableGen/TableGenBackend.h"
520b57cec5SDimitry Andric #include <numeric>
530b57cec5SDimitry Andric #include <string>
5406c3fb27SDimitry Andric 
550b57cec5SDimitry Andric using namespace llvm;
5606c3fb27SDimitry Andric using namespace llvm::gi;
5706c3fb27SDimitry Andric 
5806c3fb27SDimitry Andric using action_iterator = RuleMatcher::action_iterator;
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric #define DEBUG_TYPE "gisel-emitter"
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric STATISTIC(NumPatternTotal, "Total number of patterns");
630b57cec5SDimitry Andric STATISTIC(NumPatternImported, "Number of patterns imported from SelectionDAG");
640b57cec5SDimitry Andric STATISTIC(NumPatternImportsSkipped, "Number of SelectionDAG imports skipped");
6506c3fb27SDimitry Andric STATISTIC(NumPatternsTested,
6606c3fb27SDimitry Andric           "Number of patterns executed according to coverage information");
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric cl::OptionCategory GlobalISelEmitterCat("Options for -gen-global-isel");
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric static cl::opt<bool> WarnOnSkippedPatterns(
710b57cec5SDimitry Andric     "warn-on-skipped-patterns",
720b57cec5SDimitry Andric     cl::desc("Explain why a pattern was skipped for inclusion "
730b57cec5SDimitry Andric              "in the GlobalISel selector"),
740b57cec5SDimitry Andric     cl::init(false), cl::cat(GlobalISelEmitterCat));
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric static cl::opt<bool> GenerateCoverage(
770b57cec5SDimitry Andric     "instrument-gisel-coverage",
780b57cec5SDimitry Andric     cl::desc("Generate coverage instrumentation for GlobalISel"),
790b57cec5SDimitry Andric     cl::init(false), cl::cat(GlobalISelEmitterCat));
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric static cl::opt<std::string> UseCoverageFile(
820b57cec5SDimitry Andric     "gisel-coverage-file", cl::init(""),
830b57cec5SDimitry Andric     cl::desc("Specify file to retrieve coverage information from"),
840b57cec5SDimitry Andric     cl::cat(GlobalISelEmitterCat));
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric static cl::opt<bool> OptimizeMatchTable(
870b57cec5SDimitry Andric     "optimize-match-table",
880b57cec5SDimitry Andric     cl::desc("Generate an optimized version of the match table"),
890b57cec5SDimitry Andric     cl::init(true), cl::cat(GlobalISelEmitterCat));
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric namespace {
920b57cec5SDimitry Andric 
explainPredicates(const TreePatternNode * N)930b57cec5SDimitry Andric static std::string explainPredicates(const TreePatternNode *N) {
94e8d8bef9SDimitry Andric   std::string Explanation;
950b57cec5SDimitry Andric   StringRef Separator = "";
960b57cec5SDimitry Andric   for (const TreePredicateCall &Call : N->getPredicateCalls()) {
970b57cec5SDimitry Andric     const TreePredicateFn &P = Call.Fn;
980b57cec5SDimitry Andric     Explanation +=
990b57cec5SDimitry Andric         (Separator + P.getOrigPatFragRecord()->getRecord()->getName()).str();
1000b57cec5SDimitry Andric     Separator = ", ";
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric     if (P.isAlwaysTrue())
1030b57cec5SDimitry Andric       Explanation += " always-true";
1040b57cec5SDimitry Andric     if (P.isImmediatePattern())
1050b57cec5SDimitry Andric       Explanation += " immediate";
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric     if (P.isUnindexed())
1080b57cec5SDimitry Andric       Explanation += " unindexed";
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric     if (P.isNonExtLoad())
1110b57cec5SDimitry Andric       Explanation += " non-extload";
1120b57cec5SDimitry Andric     if (P.isAnyExtLoad())
1130b57cec5SDimitry Andric       Explanation += " extload";
1140b57cec5SDimitry Andric     if (P.isSignExtLoad())
1150b57cec5SDimitry Andric       Explanation += " sextload";
1160b57cec5SDimitry Andric     if (P.isZeroExtLoad())
1170b57cec5SDimitry Andric       Explanation += " zextload";
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric     if (P.isNonTruncStore())
1200b57cec5SDimitry Andric       Explanation += " non-truncstore";
1210b57cec5SDimitry Andric     if (P.isTruncStore())
1220b57cec5SDimitry Andric       Explanation += " truncstore";
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric     if (Record *VT = P.getMemoryVT())
1250b57cec5SDimitry Andric       Explanation += (" MemVT=" + VT->getName()).str();
1260b57cec5SDimitry Andric     if (Record *VT = P.getScalarMemoryVT())
1270b57cec5SDimitry Andric       Explanation += (" ScalarVT(MemVT)=" + VT->getName()).str();
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric     if (ListInit *AddrSpaces = P.getAddressSpaces()) {
1300b57cec5SDimitry Andric       raw_string_ostream OS(Explanation);
1310b57cec5SDimitry Andric       OS << " AddressSpaces=[";
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric       StringRef AddrSpaceSeparator;
1340b57cec5SDimitry Andric       for (Init *Val : AddrSpaces->getValues()) {
1350b57cec5SDimitry Andric         IntInit *IntVal = dyn_cast<IntInit>(Val);
1360b57cec5SDimitry Andric         if (!IntVal)
1370b57cec5SDimitry Andric           continue;
1380b57cec5SDimitry Andric 
1390b57cec5SDimitry Andric         OS << AddrSpaceSeparator << IntVal->getValue();
1400b57cec5SDimitry Andric         AddrSpaceSeparator = ", ";
1410b57cec5SDimitry Andric       }
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric       OS << ']';
1440b57cec5SDimitry Andric     }
1450b57cec5SDimitry Andric 
1468bcb0991SDimitry Andric     int64_t MinAlign = P.getMinAlignment();
1478bcb0991SDimitry Andric     if (MinAlign > 0)
1488bcb0991SDimitry Andric       Explanation += " MinAlign=" + utostr(MinAlign);
1498bcb0991SDimitry Andric 
1500b57cec5SDimitry Andric     if (P.isAtomicOrderingMonotonic())
1510b57cec5SDimitry Andric       Explanation += " monotonic";
1520b57cec5SDimitry Andric     if (P.isAtomicOrderingAcquire())
1530b57cec5SDimitry Andric       Explanation += " acquire";
1540b57cec5SDimitry Andric     if (P.isAtomicOrderingRelease())
1550b57cec5SDimitry Andric       Explanation += " release";
1560b57cec5SDimitry Andric     if (P.isAtomicOrderingAcquireRelease())
1570b57cec5SDimitry Andric       Explanation += " acq_rel";
1580b57cec5SDimitry Andric     if (P.isAtomicOrderingSequentiallyConsistent())
1590b57cec5SDimitry Andric       Explanation += " seq_cst";
1600b57cec5SDimitry Andric     if (P.isAtomicOrderingAcquireOrStronger())
1610b57cec5SDimitry Andric       Explanation += " >=acquire";
1620b57cec5SDimitry Andric     if (P.isAtomicOrderingWeakerThanAcquire())
1630b57cec5SDimitry Andric       Explanation += " <acquire";
1640b57cec5SDimitry Andric     if (P.isAtomicOrderingReleaseOrStronger())
1650b57cec5SDimitry Andric       Explanation += " >=release";
1660b57cec5SDimitry Andric     if (P.isAtomicOrderingWeakerThanRelease())
1670b57cec5SDimitry Andric       Explanation += " <release";
1680b57cec5SDimitry Andric   }
1690b57cec5SDimitry Andric   return Explanation;
1700b57cec5SDimitry Andric }
1710b57cec5SDimitry Andric 
explainOperator(Record * Operator)1720b57cec5SDimitry Andric std::string explainOperator(Record *Operator) {
1730b57cec5SDimitry Andric   if (Operator->isSubClassOf("SDNode"))
1740b57cec5SDimitry Andric     return (" (" + Operator->getValueAsString("Opcode") + ")").str();
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric   if (Operator->isSubClassOf("Intrinsic"))
1770b57cec5SDimitry Andric     return (" (Operator is an Intrinsic, " + Operator->getName() + ")").str();
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric   if (Operator->isSubClassOf("ComplexPattern"))
1800b57cec5SDimitry Andric     return (" (Operator is an unmapped ComplexPattern, " + Operator->getName() +
1810b57cec5SDimitry Andric             ")")
1820b57cec5SDimitry Andric         .str();
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric   if (Operator->isSubClassOf("SDNodeXForm"))
1850b57cec5SDimitry Andric     return (" (Operator is an unmapped SDNodeXForm, " + Operator->getName() +
1860b57cec5SDimitry Andric             ")")
1870b57cec5SDimitry Andric         .str();
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric   return (" (Operator " + Operator->getName() + " not understood)").str();
1900b57cec5SDimitry Andric }
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric /// Helper function to let the emitter report skip reason error messages.
failedImport(const Twine & Reason)1930b57cec5SDimitry Andric static Error failedImport(const Twine &Reason) {
1940b57cec5SDimitry Andric   return make_error<StringError>(Reason, inconvertibleErrorCode());
1950b57cec5SDimitry Andric }
1960b57cec5SDimitry Andric 
isTrivialOperatorNode(const TreePatternNode * N)1970b57cec5SDimitry Andric static Error isTrivialOperatorNode(const TreePatternNode *N) {
198e8d8bef9SDimitry Andric   std::string Explanation;
199e8d8bef9SDimitry Andric   std::string Separator;
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric   bool HasUnsupportedPredicate = false;
2020b57cec5SDimitry Andric   for (const TreePredicateCall &Call : N->getPredicateCalls()) {
2030b57cec5SDimitry Andric     const TreePredicateFn &Predicate = Call.Fn;
2040b57cec5SDimitry Andric 
2050b57cec5SDimitry Andric     if (Predicate.isAlwaysTrue())
2060b57cec5SDimitry Andric       continue;
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric     if (Predicate.isImmediatePattern())
2090b57cec5SDimitry Andric       continue;
2100b57cec5SDimitry Andric 
211753f127fSDimitry Andric     if (Predicate.hasNoUse())
212753f127fSDimitry Andric       continue;
213753f127fSDimitry Andric 
2140b57cec5SDimitry Andric     if (Predicate.isNonExtLoad() || Predicate.isAnyExtLoad() ||
2150b57cec5SDimitry Andric         Predicate.isSignExtLoad() || Predicate.isZeroExtLoad())
2160b57cec5SDimitry Andric       continue;
2170b57cec5SDimitry Andric 
2180b57cec5SDimitry Andric     if (Predicate.isNonTruncStore() || Predicate.isTruncStore())
2190b57cec5SDimitry Andric       continue;
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric     if (Predicate.isLoad() && Predicate.getMemoryVT())
2220b57cec5SDimitry Andric       continue;
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric     if (Predicate.isLoad() || Predicate.isStore()) {
2250b57cec5SDimitry Andric       if (Predicate.isUnindexed())
2260b57cec5SDimitry Andric         continue;
2270b57cec5SDimitry Andric     }
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric     if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {
2300b57cec5SDimitry Andric       const ListInit *AddrSpaces = Predicate.getAddressSpaces();
2310b57cec5SDimitry Andric       if (AddrSpaces && !AddrSpaces->empty())
2320b57cec5SDimitry Andric         continue;
2338bcb0991SDimitry Andric 
2348bcb0991SDimitry Andric       if (Predicate.getMinAlignment() > 0)
2358bcb0991SDimitry Andric         continue;
2360b57cec5SDimitry Andric     }
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric     if (Predicate.isAtomic() && Predicate.getMemoryVT())
2390b57cec5SDimitry Andric       continue;
2400b57cec5SDimitry Andric 
2410b57cec5SDimitry Andric     if (Predicate.isAtomic() &&
2420b57cec5SDimitry Andric         (Predicate.isAtomicOrderingMonotonic() ||
2430b57cec5SDimitry Andric          Predicate.isAtomicOrderingAcquire() ||
2440b57cec5SDimitry Andric          Predicate.isAtomicOrderingRelease() ||
2450b57cec5SDimitry Andric          Predicate.isAtomicOrderingAcquireRelease() ||
2460b57cec5SDimitry Andric          Predicate.isAtomicOrderingSequentiallyConsistent() ||
2470b57cec5SDimitry Andric          Predicate.isAtomicOrderingAcquireOrStronger() ||
2480b57cec5SDimitry Andric          Predicate.isAtomicOrderingWeakerThanAcquire() ||
2490b57cec5SDimitry Andric          Predicate.isAtomicOrderingReleaseOrStronger() ||
2500b57cec5SDimitry Andric          Predicate.isAtomicOrderingWeakerThanRelease()))
2510b57cec5SDimitry Andric       continue;
2520b57cec5SDimitry Andric 
2530b57cec5SDimitry Andric     if (Predicate.hasGISelPredicateCode())
2540b57cec5SDimitry Andric       continue;
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric     HasUnsupportedPredicate = true;
2570b57cec5SDimitry Andric     Explanation = Separator + "Has a predicate (" + explainPredicates(N) + ")";
2580b57cec5SDimitry Andric     Separator = ", ";
2590b57cec5SDimitry Andric     Explanation += (Separator + "first-failing:" +
2600b57cec5SDimitry Andric                     Predicate.getOrigPatFragRecord()->getRecord()->getName())
2610b57cec5SDimitry Andric                        .str();
2620b57cec5SDimitry Andric     break;
2630b57cec5SDimitry Andric   }
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric   if (!HasUnsupportedPredicate)
2660b57cec5SDimitry Andric     return Error::success();
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric   return failedImport(Explanation);
2690b57cec5SDimitry Andric }
2700b57cec5SDimitry Andric 
getInitValueAsRegClass(Init * V)2710b57cec5SDimitry Andric static Record *getInitValueAsRegClass(Init *V) {
2720b57cec5SDimitry Andric   if (DefInit *VDefInit = dyn_cast<DefInit>(V)) {
2730b57cec5SDimitry Andric     if (VDefInit->getDef()->isSubClassOf("RegisterOperand"))
2740b57cec5SDimitry Andric       return VDefInit->getDef()->getValueAsDef("RegClass");
2750b57cec5SDimitry Andric     if (VDefInit->getDef()->isSubClassOf("RegisterClass"))
2760b57cec5SDimitry Andric       return VDefInit->getDef();
2770b57cec5SDimitry Andric   }
2780b57cec5SDimitry Andric   return nullptr;
2790b57cec5SDimitry Andric }
2800b57cec5SDimitry Andric 
getScopedName(unsigned Scope,const std::string & Name)281e8d8bef9SDimitry Andric static std::string getScopedName(unsigned Scope, const std::string &Name) {
282e8d8bef9SDimitry Andric   return ("pred:" + Twine(Scope) + ":" + Name).str();
283e8d8bef9SDimitry Andric }
284e8d8bef9SDimitry Andric 
getMangledRootDefName(StringRef DefOperandName)2855f757f3fSDimitry Andric static std::string getMangledRootDefName(StringRef DefOperandName) {
2865f757f3fSDimitry Andric   return ("DstI[" + DefOperandName + "]").str();
2875f757f3fSDimitry Andric }
2885f757f3fSDimitry Andric 
2890b57cec5SDimitry Andric //===- GlobalISelEmitter class --------------------------------------------===//
2900b57cec5SDimitry Andric 
getInstResultType(const TreePatternNode * Dst)2915ffd83dbSDimitry Andric static Expected<LLTCodeGen> getInstResultType(const TreePatternNode *Dst) {
2925ffd83dbSDimitry Andric   ArrayRef<TypeSetByHwMode> ChildTypes = Dst->getExtTypes();
2935ffd83dbSDimitry Andric   if (ChildTypes.size() != 1)
2945ffd83dbSDimitry Andric     return failedImport("Dst pattern child has multiple results");
2955ffd83dbSDimitry Andric 
296bdd1243dSDimitry Andric   std::optional<LLTCodeGen> MaybeOpTy;
2975ffd83dbSDimitry Andric   if (ChildTypes.front().isMachineValueType()) {
29806c3fb27SDimitry Andric     MaybeOpTy = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
2995ffd83dbSDimitry Andric   }
3005ffd83dbSDimitry Andric 
3015ffd83dbSDimitry Andric   if (!MaybeOpTy)
3025ffd83dbSDimitry Andric     return failedImport("Dst operand has an unsupported type");
3035ffd83dbSDimitry Andric   return *MaybeOpTy;
3045ffd83dbSDimitry Andric }
3055ffd83dbSDimitry Andric 
30606c3fb27SDimitry Andric class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter {
3070b57cec5SDimitry Andric public:
3080b57cec5SDimitry Andric   explicit GlobalISelEmitter(RecordKeeper &RK);
30906c3fb27SDimitry Andric 
31006c3fb27SDimitry Andric   void emitAdditionalImpl(raw_ostream &OS) override;
31106c3fb27SDimitry Andric 
31206c3fb27SDimitry Andric   void emitMIPredicateFns(raw_ostream &OS) override;
31306c3fb27SDimitry Andric   void emitI64ImmPredicateFns(raw_ostream &OS) override;
31406c3fb27SDimitry Andric   void emitAPFloatImmPredicateFns(raw_ostream &OS) override;
31506c3fb27SDimitry Andric   void emitAPIntImmPredicateFns(raw_ostream &OS) override;
31606c3fb27SDimitry Andric   void emitTestSimplePredicate(raw_ostream &OS) override;
31706c3fb27SDimitry Andric   void emitRunCustomAction(raw_ostream &OS) override;
31806c3fb27SDimitry Andric 
3195f757f3fSDimitry Andric   void postProcessRule(RuleMatcher &M);
3205f757f3fSDimitry Andric 
getTarget() const32106c3fb27SDimitry Andric   const CodeGenTarget &getTarget() const override { return Target; }
getClassName() const32206c3fb27SDimitry Andric   StringRef getClassName() const override { return ClassName; }
32306c3fb27SDimitry Andric 
3240b57cec5SDimitry Andric   void run(raw_ostream &OS);
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric private:
32706c3fb27SDimitry Andric   std::string ClassName;
32806c3fb27SDimitry Andric 
3290b57cec5SDimitry Andric   const RecordKeeper &RK;
3300b57cec5SDimitry Andric   const CodeGenDAGPatterns CGP;
3310b57cec5SDimitry Andric   const CodeGenTarget &Target;
3325ffd83dbSDimitry Andric   CodeGenRegBank &CGRegs;
3330b57cec5SDimitry Andric 
33406c3fb27SDimitry Andric   std::vector<Record *> AllPatFrags;
33506c3fb27SDimitry Andric 
3360b57cec5SDimitry Andric   /// Keep track of the equivalence between SDNodes and Instruction by mapping
3370b57cec5SDimitry Andric   /// SDNodes to the GINodeEquiv mapping. We need to map to the GINodeEquiv to
3380b57cec5SDimitry Andric   /// check for attributes on the relation such as CheckMMOIsNonAtomic.
3390b57cec5SDimitry Andric   /// This is defined using 'GINodeEquiv' in the target description.
3400b57cec5SDimitry Andric   DenseMap<Record *, Record *> NodeEquivs;
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric   /// Keep track of the equivalence between ComplexPattern's and
3430b57cec5SDimitry Andric   /// GIComplexOperandMatcher. Map entries are specified by subclassing
3440b57cec5SDimitry Andric   /// GIComplexPatternEquiv.
3450b57cec5SDimitry Andric   DenseMap<const Record *, const Record *> ComplexPatternEquivs;
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric   /// Keep track of the equivalence between SDNodeXForm's and
3480b57cec5SDimitry Andric   /// GICustomOperandRenderer. Map entries are specified by subclassing
3490b57cec5SDimitry Andric   /// GISDNodeXFormEquiv.
3500b57cec5SDimitry Andric   DenseMap<const Record *, const Record *> SDNodeXFormEquivs;
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric   /// Keep track of Scores of PatternsToMatch similar to how the DAG does.
3530b57cec5SDimitry Andric   /// This adds compatibility for RuleMatchers to use this for ordering rules.
3540b57cec5SDimitry Andric   DenseMap<uint64_t, int> RuleMatcherScores;
3550b57cec5SDimitry Andric 
3560b57cec5SDimitry Andric   // Rule coverage information.
357bdd1243dSDimitry Andric   std::optional<CodeGenCoverage> RuleCoverage;
3580b57cec5SDimitry Andric 
359e8d8bef9SDimitry Andric   /// Variables used to help with collecting of named operands for predicates
360e8d8bef9SDimitry Andric   /// with 'let PredicateCodeUsesOperands = 1'. WaitingForNamedOperands is set
361e8d8bef9SDimitry Andric   /// to the number of named operands that predicate expects. Store locations in
362e8d8bef9SDimitry Andric   /// StoreIdxForName correspond to the order in which operand names appear in
363e8d8bef9SDimitry Andric   /// predicate's argument list.
3645f757f3fSDimitry Andric   /// When we visit named operand and WaitingForNamedOperands is not zero, add
3655f757f3fSDimitry Andric   /// matcher that will record operand and decrease counter.
366e8d8bef9SDimitry Andric   unsigned WaitingForNamedOperands = 0;
367e8d8bef9SDimitry Andric   StringMap<unsigned> StoreIdxForName;
368e8d8bef9SDimitry Andric 
3690b57cec5SDimitry Andric   void gatherOpcodeValues();
3700b57cec5SDimitry Andric   void gatherTypeIDValues();
3710b57cec5SDimitry Andric   void gatherNodeEquivs();
3720b57cec5SDimitry Andric 
3730b57cec5SDimitry Andric   Record *findNodeEquiv(Record *N) const;
3740b57cec5SDimitry Andric   const CodeGenInstruction *getEquivNode(Record &Equiv,
3750b57cec5SDimitry Andric                                          const TreePatternNode *N) const;
3760b57cec5SDimitry Andric 
377fe6060f1SDimitry Andric   Error importRulePredicates(RuleMatcher &M, ArrayRef<Record *> Predicates);
3780b57cec5SDimitry Andric   Expected<InstructionMatcher &>
3790b57cec5SDimitry Andric   createAndImportSelDAGMatcher(RuleMatcher &Rule,
3800b57cec5SDimitry Andric                                InstructionMatcher &InsnMatcher,
3810b57cec5SDimitry Andric                                const TreePatternNode *Src, unsigned &TempOpIdx);
3820b57cec5SDimitry Andric   Error importComplexPatternOperandMatcher(OperandMatcher &OM, Record *R,
3830b57cec5SDimitry Andric                                            unsigned &TempOpIdx) const;
3840b57cec5SDimitry Andric   Error importChildMatcher(RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
3850b57cec5SDimitry Andric                            const TreePatternNode *SrcChild,
386480093f4SDimitry Andric                            bool OperandIsAPointer, bool OperandIsImmArg,
387480093f4SDimitry Andric                            unsigned OpIdx, unsigned &TempOpIdx);
3880b57cec5SDimitry Andric 
3898bcb0991SDimitry Andric   Expected<BuildMIAction &> createAndImportInstructionRenderer(
3908bcb0991SDimitry Andric       RuleMatcher &M, InstructionMatcher &InsnMatcher,
3918bcb0991SDimitry Andric       const TreePatternNode *Src, const TreePatternNode *Dst);
3920b57cec5SDimitry Andric   Expected<action_iterator> createAndImportSubInstructionRenderer(
3930b57cec5SDimitry Andric       action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst,
39406c3fb27SDimitry Andric       const TreePatternNode *Src, unsigned TempReg);
3950b57cec5SDimitry Andric   Expected<action_iterator>
3960b57cec5SDimitry Andric   createInstructionRenderer(action_iterator InsertPt, RuleMatcher &M,
3970b57cec5SDimitry Andric                             const TreePatternNode *Dst);
398e8d8bef9SDimitry Andric 
39906c3fb27SDimitry Andric   Expected<action_iterator> importExplicitDefRenderers(
40006c3fb27SDimitry Andric       action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
40106c3fb27SDimitry Andric       const TreePatternNode *Src, const TreePatternNode *Dst);
4028bcb0991SDimitry Andric 
40306c3fb27SDimitry Andric   Expected<action_iterator> importExplicitUseRenderers(
40406c3fb27SDimitry Andric       action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
40506c3fb27SDimitry Andric       const llvm::TreePatternNode *Dst, const TreePatternNode *Src);
40606c3fb27SDimitry Andric   Expected<action_iterator> importExplicitUseRenderer(
40706c3fb27SDimitry Andric       action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
40806c3fb27SDimitry Andric       const TreePatternNode *DstChild, const TreePatternNode *Src);
4090b57cec5SDimitry Andric   Error importDefaultOperandRenderers(action_iterator InsertPt, RuleMatcher &M,
4100b57cec5SDimitry Andric                                       BuildMIAction &DstMIBuilder,
4115f757f3fSDimitry Andric                                       const DAGDefaultOperand &DefaultOp) const;
4120b57cec5SDimitry Andric   Error
4130b57cec5SDimitry Andric   importImplicitDefRenderers(BuildMIAction &DstMIBuilder,
4140b57cec5SDimitry Andric                              const std::vector<Record *> &ImplicitDefs) const;
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   /// Analyze pattern \p P, returning a matcher for it if possible.
4170b57cec5SDimitry Andric   /// Otherwise, return an Error explaining why we don't support it.
4180b57cec5SDimitry Andric   Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);
4190b57cec5SDimitry Andric 
4200b57cec5SDimitry Andric   void declareSubtargetFeature(Record *Predicate);
4210b57cec5SDimitry Andric 
4225f757f3fSDimitry Andric   unsigned declareHwModeCheck(StringRef HwModeFeatures);
4235f757f3fSDimitry Andric 
4240b57cec5SDimitry Andric   MatchTable buildMatchTable(MutableArrayRef<RuleMatcher> Rules, bool Optimize,
4250b57cec5SDimitry Andric                              bool WithCoverage);
4260b57cec5SDimitry Andric 
4278bcb0991SDimitry Andric   /// Infer a CodeGenRegisterClass for the type of \p SuperRegNode. The returned
4288bcb0991SDimitry Andric   /// CodeGenRegisterClass will support the CodeGenRegisterClass of
4298bcb0991SDimitry Andric   /// \p SubRegNode, and the subregister index defined by \p SubRegIdxNode.
430bdd1243dSDimitry Andric   /// If no register class is found, return std::nullopt.
431bdd1243dSDimitry Andric   std::optional<const CodeGenRegisterClass *>
4328bcb0991SDimitry Andric   inferSuperRegisterClassForNode(const TypeSetByHwMode &Ty,
43306c3fb27SDimitry Andric                                  const TreePatternNode *SuperRegNode,
43406c3fb27SDimitry Andric                                  const TreePatternNode *SubRegIdxNode);
435bdd1243dSDimitry Andric   std::optional<CodeGenSubRegIndex *>
43606c3fb27SDimitry Andric   inferSubRegIndexForNode(const TreePatternNode *SubRegIdxNode);
4378bcb0991SDimitry Andric 
4388bcb0991SDimitry Andric   /// Infer a CodeGenRegisterClass which suppoorts \p Ty and \p SubRegIdxNode.
439bdd1243dSDimitry Andric   /// Return std::nullopt if no such class exists.
440bdd1243dSDimitry Andric   std::optional<const CodeGenRegisterClass *>
4418bcb0991SDimitry Andric   inferSuperRegisterClass(const TypeSetByHwMode &Ty,
44206c3fb27SDimitry Andric                           const TreePatternNode *SubRegIdxNode);
4438bcb0991SDimitry Andric 
4448bcb0991SDimitry Andric   /// Return the CodeGenRegisterClass associated with \p Leaf if it has one.
445bdd1243dSDimitry Andric   std::optional<const CodeGenRegisterClass *>
44606c3fb27SDimitry Andric   getRegClassFromLeaf(const TreePatternNode *Leaf);
4478bcb0991SDimitry Andric 
448bdd1243dSDimitry Andric   /// Return a CodeGenRegisterClass for \p N if one can be found. Return
449bdd1243dSDimitry Andric   /// std::nullopt otherwise.
450bdd1243dSDimitry Andric   std::optional<const CodeGenRegisterClass *>
45106c3fb27SDimitry Andric   inferRegClassFromPattern(const TreePatternNode *N);
4528bcb0991SDimitry Andric 
453fe6060f1SDimitry Andric   /// Return the size of the MemoryVT in this predicate, if possible.
454bdd1243dSDimitry Andric   std::optional<unsigned>
455fe6060f1SDimitry Andric   getMemSizeBitsFromPredicate(const TreePredicateFn &Predicate);
456fe6060f1SDimitry Andric 
457e8d8bef9SDimitry Andric   // Add builtin predicates.
458e8d8bef9SDimitry Andric   Expected<InstructionMatcher &>
459e8d8bef9SDimitry Andric   addBuiltinPredicates(const Record *SrcGIEquivOrNull,
460e8d8bef9SDimitry Andric                        const TreePredicateFn &Predicate,
461e8d8bef9SDimitry Andric                        InstructionMatcher &InsnMatcher, bool &HasAddedMatcher);
4620b57cec5SDimitry Andric };
4630b57cec5SDimitry Andric 
getPatFragPredicateEnumName(Record * R)46406c3fb27SDimitry Andric StringRef getPatFragPredicateEnumName(Record *R) { return R->getName(); }
46506c3fb27SDimitry Andric 
gatherOpcodeValues()4660b57cec5SDimitry Andric void GlobalISelEmitter::gatherOpcodeValues() {
4670b57cec5SDimitry Andric   InstructionOpcodeMatcher::initOpcodeValuesMap(Target);
4680b57cec5SDimitry Andric }
4690b57cec5SDimitry Andric 
gatherTypeIDValues()4700b57cec5SDimitry Andric void GlobalISelEmitter::gatherTypeIDValues() {
4710b57cec5SDimitry Andric   LLTOperandMatcher::initTypeIDValuesMap();
4720b57cec5SDimitry Andric }
4730b57cec5SDimitry Andric 
gatherNodeEquivs()4740b57cec5SDimitry Andric void GlobalISelEmitter::gatherNodeEquivs() {
4750b57cec5SDimitry Andric   assert(NodeEquivs.empty());
4760b57cec5SDimitry Andric   for (Record *Equiv : RK.getAllDerivedDefinitions("GINodeEquiv"))
4770b57cec5SDimitry Andric     NodeEquivs[Equiv->getValueAsDef("Node")] = Equiv;
4780b57cec5SDimitry Andric 
4790b57cec5SDimitry Andric   assert(ComplexPatternEquivs.empty());
4800b57cec5SDimitry Andric   for (Record *Equiv : RK.getAllDerivedDefinitions("GIComplexPatternEquiv")) {
4810b57cec5SDimitry Andric     Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
4820b57cec5SDimitry Andric     if (!SelDAGEquiv)
4830b57cec5SDimitry Andric       continue;
4840b57cec5SDimitry Andric     ComplexPatternEquivs[SelDAGEquiv] = Equiv;
4850b57cec5SDimitry Andric   }
4860b57cec5SDimitry Andric 
4870b57cec5SDimitry Andric   assert(SDNodeXFormEquivs.empty());
4880b57cec5SDimitry Andric   for (Record *Equiv : RK.getAllDerivedDefinitions("GISDNodeXFormEquiv")) {
4890b57cec5SDimitry Andric     Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
4900b57cec5SDimitry Andric     if (!SelDAGEquiv)
4910b57cec5SDimitry Andric       continue;
4920b57cec5SDimitry Andric     SDNodeXFormEquivs[SelDAGEquiv] = Equiv;
4930b57cec5SDimitry Andric   }
4940b57cec5SDimitry Andric }
4950b57cec5SDimitry Andric 
findNodeEquiv(Record * N) const4960b57cec5SDimitry Andric Record *GlobalISelEmitter::findNodeEquiv(Record *N) const {
4970b57cec5SDimitry Andric   return NodeEquivs.lookup(N);
4980b57cec5SDimitry Andric }
4990b57cec5SDimitry Andric 
5000b57cec5SDimitry Andric const CodeGenInstruction *
getEquivNode(Record & Equiv,const TreePatternNode * N) const5010b57cec5SDimitry Andric GlobalISelEmitter::getEquivNode(Record &Equiv, const TreePatternNode *N) const {
5028bcb0991SDimitry Andric   if (N->getNumChildren() >= 1) {
5038bcb0991SDimitry Andric     // setcc operation maps to two different G_* instructions based on the type.
5048bcb0991SDimitry Andric     if (!Equiv.isValueUnset("IfFloatingPoint") &&
5058bcb0991SDimitry Andric         MVT(N->getChild(0)->getSimpleType(0)).isFloatingPoint())
5068bcb0991SDimitry Andric       return &Target.getInstruction(Equiv.getValueAsDef("IfFloatingPoint"));
5078bcb0991SDimitry Andric   }
5088bcb0991SDimitry Andric 
5095f757f3fSDimitry Andric   if (!Equiv.isValueUnset("IfConvergent") &&
5105f757f3fSDimitry Andric       N->getIntrinsicInfo(CGP)->isConvergent)
5115f757f3fSDimitry Andric     return &Target.getInstruction(Equiv.getValueAsDef("IfConvergent"));
5125f757f3fSDimitry Andric 
5130b57cec5SDimitry Andric   for (const TreePredicateCall &Call : N->getPredicateCalls()) {
5140b57cec5SDimitry Andric     const TreePredicateFn &Predicate = Call.Fn;
515753f127fSDimitry Andric     if (!Equiv.isValueUnset("IfSignExtend") &&
516753f127fSDimitry Andric         (Predicate.isLoad() || Predicate.isAtomic()) &&
5170b57cec5SDimitry Andric         Predicate.isSignExtLoad())
5180b57cec5SDimitry Andric       return &Target.getInstruction(Equiv.getValueAsDef("IfSignExtend"));
519753f127fSDimitry Andric     if (!Equiv.isValueUnset("IfZeroExtend") &&
520753f127fSDimitry Andric         (Predicate.isLoad() || Predicate.isAtomic()) &&
5210b57cec5SDimitry Andric         Predicate.isZeroExtLoad())
5220b57cec5SDimitry Andric       return &Target.getInstruction(Equiv.getValueAsDef("IfZeroExtend"));
5230b57cec5SDimitry Andric   }
5248bcb0991SDimitry Andric 
5250b57cec5SDimitry Andric   return &Target.getInstruction(Equiv.getValueAsDef("I"));
5260b57cec5SDimitry Andric }
5270b57cec5SDimitry Andric 
GlobalISelEmitter(RecordKeeper & RK)5280b57cec5SDimitry Andric GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
52906c3fb27SDimitry Andric     : GlobalISelMatchTableExecutorEmitter(), RK(RK), CGP(RK),
53006c3fb27SDimitry Andric       Target(CGP.getTargetInfo()), CGRegs(Target.getRegBank()) {
53106c3fb27SDimitry Andric   ClassName = Target.getName().str() + "InstructionSelector";
53206c3fb27SDimitry Andric }
5330b57cec5SDimitry Andric 
5340b57cec5SDimitry Andric //===- Emitter ------------------------------------------------------------===//
5350b57cec5SDimitry Andric 
importRulePredicates(RuleMatcher & M,ArrayRef<Record * > Predicates)536fe6060f1SDimitry Andric Error GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
537fe6060f1SDimitry Andric                                               ArrayRef<Record *> Predicates) {
538fe6060f1SDimitry Andric   for (Record *Pred : Predicates) {
539fe6060f1SDimitry Andric     if (Pred->getValueAsString("CondString").empty())
5400b57cec5SDimitry Andric       continue;
541fe6060f1SDimitry Andric     declareSubtargetFeature(Pred);
542fe6060f1SDimitry Andric     M.addRequiredFeature(Pred);
5430b57cec5SDimitry Andric   }
5440b57cec5SDimitry Andric 
5450b57cec5SDimitry Andric   return Error::success();
5460b57cec5SDimitry Andric }
5470b57cec5SDimitry Andric 
getMemSizeBitsFromPredicate(const TreePredicateFn & Predicate)548bdd1243dSDimitry Andric std::optional<unsigned> GlobalISelEmitter::getMemSizeBitsFromPredicate(
549bdd1243dSDimitry Andric     const TreePredicateFn &Predicate) {
550bdd1243dSDimitry Andric   std::optional<LLTCodeGen> MemTyOrNone =
551fe6060f1SDimitry Andric       MVTToLLT(getValueType(Predicate.getMemoryVT()));
552fe6060f1SDimitry Andric 
553fe6060f1SDimitry Andric   if (!MemTyOrNone)
554bdd1243dSDimitry Andric     return std::nullopt;
555fe6060f1SDimitry Andric 
556fe6060f1SDimitry Andric   // Align so unusual types like i1 don't get rounded down.
557fe6060f1SDimitry Andric   return llvm::alignTo(
558fe6060f1SDimitry Andric       static_cast<unsigned>(MemTyOrNone->get().getSizeInBits()), 8);
559fe6060f1SDimitry Andric }
560fe6060f1SDimitry Andric 
addBuiltinPredicates(const Record * SrcGIEquivOrNull,const TreePredicateFn & Predicate,InstructionMatcher & InsnMatcher,bool & HasAddedMatcher)561e8d8bef9SDimitry Andric Expected<InstructionMatcher &> GlobalISelEmitter::addBuiltinPredicates(
562e8d8bef9SDimitry Andric     const Record *SrcGIEquivOrNull, const TreePredicateFn &Predicate,
563e8d8bef9SDimitry Andric     InstructionMatcher &InsnMatcher, bool &HasAddedMatcher) {
564e8d8bef9SDimitry Andric   if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {
565e8d8bef9SDimitry Andric     if (const ListInit *AddrSpaces = Predicate.getAddressSpaces()) {
566e8d8bef9SDimitry Andric       SmallVector<unsigned, 4> ParsedAddrSpaces;
567e8d8bef9SDimitry Andric 
568e8d8bef9SDimitry Andric       for (Init *Val : AddrSpaces->getValues()) {
569e8d8bef9SDimitry Andric         IntInit *IntVal = dyn_cast<IntInit>(Val);
570e8d8bef9SDimitry Andric         if (!IntVal)
571e8d8bef9SDimitry Andric           return failedImport("Address space is not an integer");
572e8d8bef9SDimitry Andric         ParsedAddrSpaces.push_back(IntVal->getValue());
573e8d8bef9SDimitry Andric       }
574e8d8bef9SDimitry Andric 
575e8d8bef9SDimitry Andric       if (!ParsedAddrSpaces.empty()) {
576e8d8bef9SDimitry Andric         InsnMatcher.addPredicate<MemoryAddressSpacePredicateMatcher>(
577e8d8bef9SDimitry Andric             0, ParsedAddrSpaces);
57881ad6265SDimitry Andric         return InsnMatcher;
579e8d8bef9SDimitry Andric       }
580e8d8bef9SDimitry Andric     }
581e8d8bef9SDimitry Andric 
582e8d8bef9SDimitry Andric     int64_t MinAlign = Predicate.getMinAlignment();
58381ad6265SDimitry Andric     if (MinAlign > 0) {
584e8d8bef9SDimitry Andric       InsnMatcher.addPredicate<MemoryAlignmentPredicateMatcher>(0, MinAlign);
58581ad6265SDimitry Andric       return InsnMatcher;
58681ad6265SDimitry Andric     }
587e8d8bef9SDimitry Andric   }
588e8d8bef9SDimitry Andric 
589e8d8bef9SDimitry Andric   // G_LOAD is used for both non-extending and any-extending loads.
590e8d8bef9SDimitry Andric   if (Predicate.isLoad() && Predicate.isNonExtLoad()) {
591e8d8bef9SDimitry Andric     InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
592e8d8bef9SDimitry Andric         0, MemoryVsLLTSizePredicateMatcher::EqualTo, 0);
593e8d8bef9SDimitry Andric     return InsnMatcher;
594e8d8bef9SDimitry Andric   }
595e8d8bef9SDimitry Andric   if (Predicate.isLoad() && Predicate.isAnyExtLoad()) {
596e8d8bef9SDimitry Andric     InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
597e8d8bef9SDimitry Andric         0, MemoryVsLLTSizePredicateMatcher::LessThan, 0);
598e8d8bef9SDimitry Andric     return InsnMatcher;
599e8d8bef9SDimitry Andric   }
600e8d8bef9SDimitry Andric 
601e8d8bef9SDimitry Andric   if (Predicate.isStore()) {
602e8d8bef9SDimitry Andric     if (Predicate.isTruncStore()) {
603fe6060f1SDimitry Andric       if (Predicate.getMemoryVT() != nullptr) {
604e8d8bef9SDimitry Andric         // FIXME: If MemoryVT is set, we end up with 2 checks for the MMO size.
605fe6060f1SDimitry Andric         auto MemSizeInBits = getMemSizeBitsFromPredicate(Predicate);
606fe6060f1SDimitry Andric         if (!MemSizeInBits)
607fe6060f1SDimitry Andric           return failedImport("MemVT could not be converted to LLT");
608fe6060f1SDimitry Andric 
609fe6060f1SDimitry Andric         InsnMatcher.addPredicate<MemorySizePredicateMatcher>(0, *MemSizeInBits /
610fe6060f1SDimitry Andric                                                                     8);
611fe6060f1SDimitry Andric       } else {
612e8d8bef9SDimitry Andric         InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
613e8d8bef9SDimitry Andric             0, MemoryVsLLTSizePredicateMatcher::LessThan, 0);
614fe6060f1SDimitry Andric       }
615e8d8bef9SDimitry Andric       return InsnMatcher;
616e8d8bef9SDimitry Andric     }
617e8d8bef9SDimitry Andric     if (Predicate.isNonTruncStore()) {
618e8d8bef9SDimitry Andric       // We need to check the sizes match here otherwise we could incorrectly
619e8d8bef9SDimitry Andric       // match truncating stores with non-truncating ones.
620e8d8bef9SDimitry Andric       InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
621e8d8bef9SDimitry Andric           0, MemoryVsLLTSizePredicateMatcher::EqualTo, 0);
622e8d8bef9SDimitry Andric     }
623e8d8bef9SDimitry Andric   }
624e8d8bef9SDimitry Andric 
62506c3fb27SDimitry Andric   assert(SrcGIEquivOrNull != nullptr && "Invalid SrcGIEquivOrNull value");
626e8d8bef9SDimitry Andric   // No check required. We already did it by swapping the opcode.
627e8d8bef9SDimitry Andric   if (!SrcGIEquivOrNull->isValueUnset("IfSignExtend") &&
628e8d8bef9SDimitry Andric       Predicate.isSignExtLoad())
629e8d8bef9SDimitry Andric     return InsnMatcher;
630e8d8bef9SDimitry Andric 
631e8d8bef9SDimitry Andric   // No check required. We already did it by swapping the opcode.
632e8d8bef9SDimitry Andric   if (!SrcGIEquivOrNull->isValueUnset("IfZeroExtend") &&
633e8d8bef9SDimitry Andric       Predicate.isZeroExtLoad())
634e8d8bef9SDimitry Andric     return InsnMatcher;
635e8d8bef9SDimitry Andric 
636e8d8bef9SDimitry Andric   // No check required. G_STORE by itself is a non-extending store.
637e8d8bef9SDimitry Andric   if (Predicate.isNonTruncStore())
638e8d8bef9SDimitry Andric     return InsnMatcher;
639e8d8bef9SDimitry Andric 
640e8d8bef9SDimitry Andric   if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {
641e8d8bef9SDimitry Andric     if (Predicate.getMemoryVT() != nullptr) {
642fe6060f1SDimitry Andric       auto MemSizeInBits = getMemSizeBitsFromPredicate(Predicate);
643fe6060f1SDimitry Andric       if (!MemSizeInBits)
644e8d8bef9SDimitry Andric         return failedImport("MemVT could not be converted to LLT");
645e8d8bef9SDimitry Andric 
646e8d8bef9SDimitry Andric       InsnMatcher.addPredicate<MemorySizePredicateMatcher>(0,
647fe6060f1SDimitry Andric                                                            *MemSizeInBits / 8);
648e8d8bef9SDimitry Andric       return InsnMatcher;
649e8d8bef9SDimitry Andric     }
650e8d8bef9SDimitry Andric   }
651e8d8bef9SDimitry Andric 
652e8d8bef9SDimitry Andric   if (Predicate.isLoad() || Predicate.isStore()) {
653e8d8bef9SDimitry Andric     // No check required. A G_LOAD/G_STORE is an unindexed load.
654e8d8bef9SDimitry Andric     if (Predicate.isUnindexed())
655e8d8bef9SDimitry Andric       return InsnMatcher;
656e8d8bef9SDimitry Andric   }
657e8d8bef9SDimitry Andric 
658e8d8bef9SDimitry Andric   if (Predicate.isAtomic()) {
659e8d8bef9SDimitry Andric     if (Predicate.isAtomicOrderingMonotonic()) {
660e8d8bef9SDimitry Andric       InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Monotonic");
661e8d8bef9SDimitry Andric       return InsnMatcher;
662e8d8bef9SDimitry Andric     }
663e8d8bef9SDimitry Andric     if (Predicate.isAtomicOrderingAcquire()) {
664e8d8bef9SDimitry Andric       InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Acquire");
665e8d8bef9SDimitry Andric       return InsnMatcher;
666e8d8bef9SDimitry Andric     }
667e8d8bef9SDimitry Andric     if (Predicate.isAtomicOrderingRelease()) {
668e8d8bef9SDimitry Andric       InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Release");
669e8d8bef9SDimitry Andric       return InsnMatcher;
670e8d8bef9SDimitry Andric     }
671e8d8bef9SDimitry Andric     if (Predicate.isAtomicOrderingAcquireRelease()) {
672e8d8bef9SDimitry Andric       InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
673e8d8bef9SDimitry Andric           "AcquireRelease");
674e8d8bef9SDimitry Andric       return InsnMatcher;
675e8d8bef9SDimitry Andric     }
676e8d8bef9SDimitry Andric     if (Predicate.isAtomicOrderingSequentiallyConsistent()) {
677e8d8bef9SDimitry Andric       InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
678e8d8bef9SDimitry Andric           "SequentiallyConsistent");
679e8d8bef9SDimitry Andric       return InsnMatcher;
680e8d8bef9SDimitry Andric     }
681e8d8bef9SDimitry Andric   }
682e8d8bef9SDimitry Andric 
683e8d8bef9SDimitry Andric   if (Predicate.isAtomicOrderingAcquireOrStronger()) {
684e8d8bef9SDimitry Andric     InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
685e8d8bef9SDimitry Andric         "Acquire", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
686e8d8bef9SDimitry Andric     return InsnMatcher;
687e8d8bef9SDimitry Andric   }
688e8d8bef9SDimitry Andric   if (Predicate.isAtomicOrderingWeakerThanAcquire()) {
689e8d8bef9SDimitry Andric     InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
690e8d8bef9SDimitry Andric         "Acquire", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);
691e8d8bef9SDimitry Andric     return InsnMatcher;
692e8d8bef9SDimitry Andric   }
693e8d8bef9SDimitry Andric 
694e8d8bef9SDimitry Andric   if (Predicate.isAtomicOrderingReleaseOrStronger()) {
695e8d8bef9SDimitry Andric     InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
696e8d8bef9SDimitry Andric         "Release", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
697e8d8bef9SDimitry Andric     return InsnMatcher;
698e8d8bef9SDimitry Andric   }
699e8d8bef9SDimitry Andric   if (Predicate.isAtomicOrderingWeakerThanRelease()) {
700e8d8bef9SDimitry Andric     InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
701e8d8bef9SDimitry Andric         "Release", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);
702e8d8bef9SDimitry Andric     return InsnMatcher;
703e8d8bef9SDimitry Andric   }
704e8d8bef9SDimitry Andric   HasAddedMatcher = false;
705e8d8bef9SDimitry Andric   return InsnMatcher;
706e8d8bef9SDimitry Andric }
707e8d8bef9SDimitry Andric 
createAndImportSelDAGMatcher(RuleMatcher & Rule,InstructionMatcher & InsnMatcher,const TreePatternNode * Src,unsigned & TempOpIdx)7080b57cec5SDimitry Andric Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
7090b57cec5SDimitry Andric     RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
7100b57cec5SDimitry Andric     const TreePatternNode *Src, unsigned &TempOpIdx) {
71106c3fb27SDimitry Andric   const auto SavedFlags = Rule.setGISelFlags(Src->getGISelFlagsRecord());
71206c3fb27SDimitry Andric 
7130b57cec5SDimitry Andric   Record *SrcGIEquivOrNull = nullptr;
7140b57cec5SDimitry Andric   const CodeGenInstruction *SrcGIOrNull = nullptr;
7150b57cec5SDimitry Andric 
7160b57cec5SDimitry Andric   // Start with the defined operands (i.e., the results of the root operator).
7170b57cec5SDimitry Andric   if (Src->isLeaf()) {
7180b57cec5SDimitry Andric     Init *SrcInit = Src->getLeafValue();
7190b57cec5SDimitry Andric     if (isa<IntInit>(SrcInit)) {
7200b57cec5SDimitry Andric       InsnMatcher.addPredicate<InstructionOpcodeMatcher>(
7210b57cec5SDimitry Andric           &Target.getInstruction(RK.getDef("G_CONSTANT")));
7220b57cec5SDimitry Andric     } else
7230b57cec5SDimitry Andric       return failedImport(
7240b57cec5SDimitry Andric           "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
7250b57cec5SDimitry Andric   } else {
7260b57cec5SDimitry Andric     SrcGIEquivOrNull = findNodeEquiv(Src->getOperator());
7270b57cec5SDimitry Andric     if (!SrcGIEquivOrNull)
7280b57cec5SDimitry Andric       return failedImport("Pattern operator lacks an equivalent Instruction" +
7290b57cec5SDimitry Andric                           explainOperator(Src->getOperator()));
7300b57cec5SDimitry Andric     SrcGIOrNull = getEquivNode(*SrcGIEquivOrNull, Src);
7310b57cec5SDimitry Andric 
7320b57cec5SDimitry Andric     // The operators look good: match the opcode
7330b57cec5SDimitry Andric     InsnMatcher.addPredicate<InstructionOpcodeMatcher>(SrcGIOrNull);
7340b57cec5SDimitry Andric   }
7350b57cec5SDimitry Andric 
7360b57cec5SDimitry Andric   unsigned OpIdx = 0;
7370b57cec5SDimitry Andric   for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
7380b57cec5SDimitry Andric     // Results don't have a name unless they are the root node. The caller will
7390b57cec5SDimitry Andric     // set the name if appropriate.
740bdd1243dSDimitry Andric     const bool OperandIsAPointer =
741bdd1243dSDimitry Andric         SrcGIOrNull && SrcGIOrNull->isOutOperandAPointer(OpIdx);
7420b57cec5SDimitry Andric     OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
743bdd1243dSDimitry Andric     if (auto Error = OM.addTypeCheckPredicate(VTy, OperandIsAPointer))
7440b57cec5SDimitry Andric       return failedImport(toString(std::move(Error)) +
7450b57cec5SDimitry Andric                           " for result of Src pattern operator");
7460b57cec5SDimitry Andric   }
7470b57cec5SDimitry Andric 
7480b57cec5SDimitry Andric   for (const TreePredicateCall &Call : Src->getPredicateCalls()) {
7490b57cec5SDimitry Andric     const TreePredicateFn &Predicate = Call.Fn;
750e8d8bef9SDimitry Andric     bool HasAddedBuiltinMatcher = true;
7510b57cec5SDimitry Andric     if (Predicate.isAlwaysTrue())
7520b57cec5SDimitry Andric       continue;
7530b57cec5SDimitry Andric 
7540b57cec5SDimitry Andric     if (Predicate.isImmediatePattern()) {
7550b57cec5SDimitry Andric       InsnMatcher.addPredicate<InstructionImmPredicateMatcher>(Predicate);
7560b57cec5SDimitry Andric       continue;
7570b57cec5SDimitry Andric     }
7580b57cec5SDimitry Andric 
759e8d8bef9SDimitry Andric     auto InsnMatcherOrError = addBuiltinPredicates(
760e8d8bef9SDimitry Andric         SrcGIEquivOrNull, Predicate, InsnMatcher, HasAddedBuiltinMatcher);
761e8d8bef9SDimitry Andric     if (auto Error = InsnMatcherOrError.takeError())
762e8d8bef9SDimitry Andric       return std::move(Error);
7630b57cec5SDimitry Andric 
764753f127fSDimitry Andric     // FIXME: This should be part of addBuiltinPredicates(). If we add this at
765753f127fSDimitry Andric     // the start of addBuiltinPredicates() without returning, then there might
766753f127fSDimitry Andric     // be cases where we hit the last return before which the
767753f127fSDimitry Andric     // HasAddedBuiltinMatcher will be set to false. The predicate could be
768753f127fSDimitry Andric     // missed if we add it in the middle or at the end due to return statements
769753f127fSDimitry Andric     // after the addPredicate<>() calls.
770753f127fSDimitry Andric     if (Predicate.hasNoUse()) {
771753f127fSDimitry Andric       InsnMatcher.addPredicate<NoUsePredicateMatcher>();
772753f127fSDimitry Andric       HasAddedBuiltinMatcher = true;
773753f127fSDimitry Andric     }
774753f127fSDimitry Andric 
7750b57cec5SDimitry Andric     if (Predicate.hasGISelPredicateCode()) {
776e8d8bef9SDimitry Andric       if (Predicate.usesOperands()) {
777e8d8bef9SDimitry Andric         assert(WaitingForNamedOperands == 0 &&
778e8d8bef9SDimitry Andric                "previous predicate didn't find all operands or "
779e8d8bef9SDimitry Andric                "nested predicate that uses operands");
780e8d8bef9SDimitry Andric         TreePattern *TP = Predicate.getOrigPatFragRecord();
781e8d8bef9SDimitry Andric         WaitingForNamedOperands = TP->getNumArgs();
782e8d8bef9SDimitry Andric         for (unsigned i = 0; i < WaitingForNamedOperands; ++i)
783e8d8bef9SDimitry Andric           StoreIdxForName[getScopedName(Call.Scope, TP->getArgName(i))] = i;
784e8d8bef9SDimitry Andric       }
7850b57cec5SDimitry Andric       InsnMatcher.addPredicate<GenericInstructionPredicateMatcher>(Predicate);
7860b57cec5SDimitry Andric       continue;
7870b57cec5SDimitry Andric     }
788e8d8bef9SDimitry Andric     if (!HasAddedBuiltinMatcher) {
7890b57cec5SDimitry Andric       return failedImport("Src pattern child has predicate (" +
7900b57cec5SDimitry Andric                           explainPredicates(Src) + ")");
7910b57cec5SDimitry Andric     }
792e8d8bef9SDimitry Andric   }
793e8d8bef9SDimitry Andric 
79406c3fb27SDimitry Andric   if (SrcGIEquivOrNull &&
79506c3fb27SDimitry Andric       SrcGIEquivOrNull->getValueAsBit("CheckMMOIsNonAtomic"))
7960b57cec5SDimitry Andric     InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("NotAtomic");
79706c3fb27SDimitry Andric   else if (SrcGIEquivOrNull &&
79806c3fb27SDimitry Andric            SrcGIEquivOrNull->getValueAsBit("CheckMMOIsAtomic")) {
7998bcb0991SDimitry Andric     InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
8008bcb0991SDimitry Andric         "Unordered", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
8018bcb0991SDimitry Andric   }
8020b57cec5SDimitry Andric 
8030b57cec5SDimitry Andric   if (Src->isLeaf()) {
8040b57cec5SDimitry Andric     Init *SrcInit = Src->getLeafValue();
8050b57cec5SDimitry Andric     if (IntInit *SrcIntInit = dyn_cast<IntInit>(SrcInit)) {
8060b57cec5SDimitry Andric       OperandMatcher &OM =
8070b57cec5SDimitry Andric           InsnMatcher.addOperand(OpIdx++, Src->getName(), TempOpIdx);
8080b57cec5SDimitry Andric       OM.addPredicate<LiteralIntOperandMatcher>(SrcIntInit->getValue());
8090b57cec5SDimitry Andric     } else
8100b57cec5SDimitry Andric       return failedImport(
8110b57cec5SDimitry Andric           "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
8120b57cec5SDimitry Andric   } else {
8130b57cec5SDimitry Andric     assert(SrcGIOrNull &&
8140b57cec5SDimitry Andric            "Expected to have already found an equivalent Instruction");
8150b57cec5SDimitry Andric     if (SrcGIOrNull->TheDef->getName() == "G_CONSTANT" ||
8160b57cec5SDimitry Andric         SrcGIOrNull->TheDef->getName() == "G_FCONSTANT") {
8170b57cec5SDimitry Andric       // imm/fpimm still have operands but we don't need to do anything with it
8180b57cec5SDimitry Andric       // here since we don't support ImmLeaf predicates yet. However, we still
8190b57cec5SDimitry Andric       // need to note the hidden operand to get GIM_CheckNumOperands correct.
8200b57cec5SDimitry Andric       InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
8210b57cec5SDimitry Andric       return InsnMatcher;
8220b57cec5SDimitry Andric     }
8230b57cec5SDimitry Andric 
8248bcb0991SDimitry Andric     // Special case because the operand order is changed from setcc. The
8258bcb0991SDimitry Andric     // predicate operand needs to be swapped from the last operand to the first
8268bcb0991SDimitry Andric     // source.
8278bcb0991SDimitry Andric 
8288bcb0991SDimitry Andric     unsigned NumChildren = Src->getNumChildren();
8298bcb0991SDimitry Andric     bool IsFCmp = SrcGIOrNull->TheDef->getName() == "G_FCMP";
8308bcb0991SDimitry Andric 
8318bcb0991SDimitry Andric     if (IsFCmp || SrcGIOrNull->TheDef->getName() == "G_ICMP") {
83206c3fb27SDimitry Andric       const TreePatternNode *SrcChild = Src->getChild(NumChildren - 1);
8338bcb0991SDimitry Andric       if (SrcChild->isLeaf()) {
8348bcb0991SDimitry Andric         DefInit *DI = dyn_cast<DefInit>(SrcChild->getLeafValue());
8358bcb0991SDimitry Andric         Record *CCDef = DI ? DI->getDef() : nullptr;
8368bcb0991SDimitry Andric         if (!CCDef || !CCDef->isSubClassOf("CondCode"))
8378bcb0991SDimitry Andric           return failedImport("Unable to handle CondCode");
8388bcb0991SDimitry Andric 
8398bcb0991SDimitry Andric         OperandMatcher &OM =
8408bcb0991SDimitry Andric             InsnMatcher.addOperand(OpIdx++, SrcChild->getName(), TempOpIdx);
84106c3fb27SDimitry Andric         StringRef PredType = IsFCmp ? CCDef->getValueAsString("FCmpPredicate")
84206c3fb27SDimitry Andric                                     : CCDef->getValueAsString("ICmpPredicate");
8438bcb0991SDimitry Andric 
8448bcb0991SDimitry Andric         if (!PredType.empty()) {
8455ffd83dbSDimitry Andric           OM.addPredicate<CmpPredicateOperandMatcher>(std::string(PredType));
8468bcb0991SDimitry Andric           // Process the other 2 operands normally.
8478bcb0991SDimitry Andric           --NumChildren;
8488bcb0991SDimitry Andric         }
8498bcb0991SDimitry Andric       }
8508bcb0991SDimitry Andric     }
8518bcb0991SDimitry Andric 
8520b57cec5SDimitry Andric     // Match the used operands (i.e. the children of the operator).
8538bcb0991SDimitry Andric     bool IsIntrinsic =
8548bcb0991SDimitry Andric         SrcGIOrNull->TheDef->getName() == "G_INTRINSIC" ||
8555f757f3fSDimitry Andric         SrcGIOrNull->TheDef->getName() == "G_INTRINSIC_W_SIDE_EFFECTS" ||
8565f757f3fSDimitry Andric         SrcGIOrNull->TheDef->getName() == "G_INTRINSIC_CONVERGENT" ||
8575f757f3fSDimitry Andric         SrcGIOrNull->TheDef->getName() ==
8585f757f3fSDimitry Andric             "G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS";
8598bcb0991SDimitry Andric     const CodeGenIntrinsic *II = Src->getIntrinsicInfo(CGP);
8608bcb0991SDimitry Andric     if (IsIntrinsic && !II)
8618bcb0991SDimitry Andric       return failedImport("Expected IntInit containing intrinsic ID)");
8628bcb0991SDimitry Andric 
8638bcb0991SDimitry Andric     for (unsigned i = 0; i != NumChildren; ++i) {
86406c3fb27SDimitry Andric       const TreePatternNode *SrcChild = Src->getChild(i);
8650b57cec5SDimitry Andric 
866480093f4SDimitry Andric       // We need to determine the meaning of a literal integer based on the
867480093f4SDimitry Andric       // context. If this is a field required to be an immediate (such as an
868480093f4SDimitry Andric       // immarg intrinsic argument), the required predicates are different than
869480093f4SDimitry Andric       // a constant which may be materialized in a register. If we have an
870480093f4SDimitry Andric       // argument that is required to be an immediate, we should not emit an LLT
871480093f4SDimitry Andric       // type check, and should not be looking for a G_CONSTANT defined
872480093f4SDimitry Andric       // register.
873bdd1243dSDimitry Andric       bool OperandIsImmArg = SrcGIOrNull->isInOperandImmArg(i);
874480093f4SDimitry Andric 
8750b57cec5SDimitry Andric       // SelectionDAG allows pointers to be represented with iN since it doesn't
87606c3fb27SDimitry Andric       // distinguish between pointers and integers but they are different types
87706c3fb27SDimitry Andric       // in GlobalISel. Coerce integers to pointers to address space 0 if the
87806c3fb27SDimitry Andric       // context indicates a pointer.
879480093f4SDimitry Andric       //
880bdd1243dSDimitry Andric       bool OperandIsAPointer = SrcGIOrNull->isInOperandAPointer(i);
8810b57cec5SDimitry Andric 
8828bcb0991SDimitry Andric       if (IsIntrinsic) {
8830b57cec5SDimitry Andric         // For G_INTRINSIC/G_INTRINSIC_W_SIDE_EFFECTS, the operand immediately
8840b57cec5SDimitry Andric         // following the defs is an intrinsic ID.
8858bcb0991SDimitry Andric         if (i == 0) {
8860b57cec5SDimitry Andric           OperandMatcher &OM =
8870b57cec5SDimitry Andric               InsnMatcher.addOperand(OpIdx++, SrcChild->getName(), TempOpIdx);
8880b57cec5SDimitry Andric           OM.addPredicate<IntrinsicIDOperandMatcher>(II);
8890b57cec5SDimitry Andric           continue;
8900b57cec5SDimitry Andric         }
8910b57cec5SDimitry Andric 
892480093f4SDimitry Andric         // We have to check intrinsics for llvm_anyptr_ty and immarg parameters.
8938bcb0991SDimitry Andric         //
8948bcb0991SDimitry Andric         // Note that we have to look at the i-1th parameter, because we don't
8958bcb0991SDimitry Andric         // have the intrinsic ID in the intrinsic's parameter list.
8968bcb0991SDimitry Andric         OperandIsAPointer |= II->isParamAPointer(i - 1);
897480093f4SDimitry Andric         OperandIsImmArg |= II->isParamImmArg(i - 1);
8980b57cec5SDimitry Andric       }
8990b57cec5SDimitry Andric 
9000b57cec5SDimitry Andric       if (auto Error =
9010b57cec5SDimitry Andric               importChildMatcher(Rule, InsnMatcher, SrcChild, OperandIsAPointer,
902480093f4SDimitry Andric                                  OperandIsImmArg, OpIdx++, TempOpIdx))
9030b57cec5SDimitry Andric         return std::move(Error);
9040b57cec5SDimitry Andric     }
9050b57cec5SDimitry Andric   }
9060b57cec5SDimitry Andric 
9070b57cec5SDimitry Andric   return InsnMatcher;
9080b57cec5SDimitry Andric }
9090b57cec5SDimitry Andric 
importComplexPatternOperandMatcher(OperandMatcher & OM,Record * R,unsigned & TempOpIdx) const9100b57cec5SDimitry Andric Error GlobalISelEmitter::importComplexPatternOperandMatcher(
9110b57cec5SDimitry Andric     OperandMatcher &OM, Record *R, unsigned &TempOpIdx) const {
9120b57cec5SDimitry Andric   const auto &ComplexPattern = ComplexPatternEquivs.find(R);
9130b57cec5SDimitry Andric   if (ComplexPattern == ComplexPatternEquivs.end())
9140b57cec5SDimitry Andric     return failedImport("SelectionDAG ComplexPattern (" + R->getName() +
9150b57cec5SDimitry Andric                         ") not mapped to GlobalISel");
9160b57cec5SDimitry Andric 
9170b57cec5SDimitry Andric   OM.addPredicate<ComplexPatternOperandMatcher>(OM, *ComplexPattern->second);
9180b57cec5SDimitry Andric   TempOpIdx++;
9190b57cec5SDimitry Andric   return Error::success();
9200b57cec5SDimitry Andric }
9210b57cec5SDimitry Andric 
9228bcb0991SDimitry Andric // Get the name to use for a pattern operand. For an anonymous physical register
9238bcb0991SDimitry Andric // input, this should use the register name.
getSrcChildName(const TreePatternNode * SrcChild,Record * & PhysReg)9248bcb0991SDimitry Andric static StringRef getSrcChildName(const TreePatternNode *SrcChild,
9258bcb0991SDimitry Andric                                  Record *&PhysReg) {
9268bcb0991SDimitry Andric   StringRef SrcChildName = SrcChild->getName();
9278bcb0991SDimitry Andric   if (SrcChildName.empty() && SrcChild->isLeaf()) {
9288bcb0991SDimitry Andric     if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
9298bcb0991SDimitry Andric       auto *ChildRec = ChildDefInit->getDef();
9308bcb0991SDimitry Andric       if (ChildRec->isSubClassOf("Register")) {
9318bcb0991SDimitry Andric         SrcChildName = ChildRec->getName();
9328bcb0991SDimitry Andric         PhysReg = ChildRec;
9338bcb0991SDimitry Andric       }
9348bcb0991SDimitry Andric     }
9358bcb0991SDimitry Andric   }
9368bcb0991SDimitry Andric 
9378bcb0991SDimitry Andric   return SrcChildName;
9388bcb0991SDimitry Andric }
9398bcb0991SDimitry Andric 
importChildMatcher(RuleMatcher & Rule,InstructionMatcher & InsnMatcher,const TreePatternNode * SrcChild,bool OperandIsAPointer,bool OperandIsImmArg,unsigned OpIdx,unsigned & TempOpIdx)940480093f4SDimitry Andric Error GlobalISelEmitter::importChildMatcher(
941480093f4SDimitry Andric     RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
942480093f4SDimitry Andric     const TreePatternNode *SrcChild, bool OperandIsAPointer,
943480093f4SDimitry Andric     bool OperandIsImmArg, unsigned OpIdx, unsigned &TempOpIdx) {
9448bcb0991SDimitry Andric 
9458bcb0991SDimitry Andric   Record *PhysReg = nullptr;
946e8d8bef9SDimitry Andric   std::string SrcChildName = std::string(getSrcChildName(SrcChild, PhysReg));
947e8d8bef9SDimitry Andric   if (!SrcChild->isLeaf() &&
948e8d8bef9SDimitry Andric       SrcChild->getOperator()->isSubClassOf("ComplexPattern")) {
949e8d8bef9SDimitry Andric     // The "name" of a non-leaf complex pattern (MY_PAT $op1, $op2) is
950e8d8bef9SDimitry Andric     // "MY_PAT:op1:op2" and the ones with same "name" represent same operand.
951e8d8bef9SDimitry Andric     std::string PatternName = std::string(SrcChild->getOperator()->getName());
952e8d8bef9SDimitry Andric     for (unsigned i = 0; i < SrcChild->getNumChildren(); ++i) {
953e8d8bef9SDimitry Andric       PatternName += ":";
954e8d8bef9SDimitry Andric       PatternName += SrcChild->getChild(i)->getName();
955e8d8bef9SDimitry Andric     }
956e8d8bef9SDimitry Andric     SrcChildName = PatternName;
957e8d8bef9SDimitry Andric   }
9588bcb0991SDimitry Andric 
9595ffd83dbSDimitry Andric   OperandMatcher &OM =
960e8d8bef9SDimitry Andric       PhysReg ? InsnMatcher.addPhysRegInput(PhysReg, OpIdx, TempOpIdx)
961e8d8bef9SDimitry Andric               : InsnMatcher.addOperand(OpIdx, SrcChildName, TempOpIdx);
9620b57cec5SDimitry Andric   if (OM.isSameAsAnotherOperand())
9630b57cec5SDimitry Andric     return Error::success();
9640b57cec5SDimitry Andric 
9650b57cec5SDimitry Andric   ArrayRef<TypeSetByHwMode> ChildTypes = SrcChild->getExtTypes();
9660b57cec5SDimitry Andric   if (ChildTypes.size() != 1)
9670b57cec5SDimitry Andric     return failedImport("Src pattern child has multiple results");
9680b57cec5SDimitry Andric 
9690b57cec5SDimitry Andric   // Check MBB's before the type check since they are not a known type.
9700b57cec5SDimitry Andric   if (!SrcChild->isLeaf()) {
9710b57cec5SDimitry Andric     if (SrcChild->getOperator()->isSubClassOf("SDNode")) {
9720b57cec5SDimitry Andric       auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild->getOperator());
9730b57cec5SDimitry Andric       if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
9740b57cec5SDimitry Andric         OM.addPredicate<MBBOperandMatcher>();
9750b57cec5SDimitry Andric         return Error::success();
9760b57cec5SDimitry Andric       }
9778bcb0991SDimitry Andric       if (SrcChild->getOperator()->getName() == "timm") {
9788bcb0991SDimitry Andric         OM.addPredicate<ImmOperandMatcher>();
979fe6060f1SDimitry Andric 
980fe6060f1SDimitry Andric         // Add predicates, if any
981fe6060f1SDimitry Andric         for (const TreePredicateCall &Call : SrcChild->getPredicateCalls()) {
982fe6060f1SDimitry Andric           const TreePredicateFn &Predicate = Call.Fn;
983fe6060f1SDimitry Andric 
984fe6060f1SDimitry Andric           // Only handle immediate patterns for now
985fe6060f1SDimitry Andric           if (Predicate.isImmediatePattern()) {
986fe6060f1SDimitry Andric             OM.addPredicate<OperandImmPredicateMatcher>(Predicate);
987fe6060f1SDimitry Andric           }
988fe6060f1SDimitry Andric         }
989fe6060f1SDimitry Andric 
9908bcb0991SDimitry Andric         return Error::success();
9918bcb0991SDimitry Andric       }
9920b57cec5SDimitry Andric     }
9930b57cec5SDimitry Andric   }
9940b57cec5SDimitry Andric 
995480093f4SDimitry Andric   // Immediate arguments have no meaningful type to check as they don't have
996480093f4SDimitry Andric   // registers.
997480093f4SDimitry Andric   if (!OperandIsImmArg) {
9980b57cec5SDimitry Andric     if (auto Error =
9990b57cec5SDimitry Andric             OM.addTypeCheckPredicate(ChildTypes.front(), OperandIsAPointer))
10000b57cec5SDimitry Andric       return failedImport(toString(std::move(Error)) + " for Src operand (" +
10010b57cec5SDimitry Andric                           to_string(*SrcChild) + ")");
1002480093f4SDimitry Andric   }
10030b57cec5SDimitry Andric 
10045f757f3fSDimitry Andric   // Try look up SrcChild for a (named) predicate operand if there is any.
10055f757f3fSDimitry Andric   if (WaitingForNamedOperands) {
10065f757f3fSDimitry Andric     auto &ScopedNames = SrcChild->getNamesAsPredicateArg();
10075f757f3fSDimitry Andric     if (!ScopedNames.empty()) {
10085f757f3fSDimitry Andric       auto PA = ScopedNames.begin();
10095f757f3fSDimitry Andric       std::string Name = getScopedName(PA->getScope(), PA->getIdentifier());
10105f757f3fSDimitry Andric       OM.addPredicate<RecordNamedOperandMatcher>(StoreIdxForName[Name], Name);
10115f757f3fSDimitry Andric       --WaitingForNamedOperands;
10125f757f3fSDimitry Andric     }
10135f757f3fSDimitry Andric   }
10145f757f3fSDimitry Andric 
10150b57cec5SDimitry Andric   // Check for nested instructions.
10160b57cec5SDimitry Andric   if (!SrcChild->isLeaf()) {
10170b57cec5SDimitry Andric     if (SrcChild->getOperator()->isSubClassOf("ComplexPattern")) {
10180b57cec5SDimitry Andric       // When a ComplexPattern is used as an operator, it should do the same
10190b57cec5SDimitry Andric       // thing as when used as a leaf. However, the children of the operator
10200b57cec5SDimitry Andric       // name the sub-operands that make up the complex operand and we must
10210b57cec5SDimitry Andric       // prepare to reference them in the renderer too.
10220b57cec5SDimitry Andric       unsigned RendererID = TempOpIdx;
10230b57cec5SDimitry Andric       if (auto Error = importComplexPatternOperandMatcher(
10240b57cec5SDimitry Andric               OM, SrcChild->getOperator(), TempOpIdx))
10250b57cec5SDimitry Andric         return Error;
10260b57cec5SDimitry Andric 
10270b57cec5SDimitry Andric       for (unsigned i = 0, e = SrcChild->getNumChildren(); i != e; ++i) {
10280b57cec5SDimitry Andric         auto *SubOperand = SrcChild->getChild(i);
10290b57cec5SDimitry Andric         if (!SubOperand->getName().empty()) {
1030e8d8bef9SDimitry Andric           if (auto Error = Rule.defineComplexSubOperand(
1031e8d8bef9SDimitry Andric                   SubOperand->getName(), SrcChild->getOperator(), RendererID, i,
1032e8d8bef9SDimitry Andric                   SrcChildName))
10330b57cec5SDimitry Andric             return Error;
10340b57cec5SDimitry Andric         }
10350b57cec5SDimitry Andric       }
10360b57cec5SDimitry Andric 
10370b57cec5SDimitry Andric       return Error::success();
10380b57cec5SDimitry Andric     }
10390b57cec5SDimitry Andric 
10400b57cec5SDimitry Andric     auto MaybeInsnOperand = OM.addPredicate<InstructionOperandMatcher>(
10410b57cec5SDimitry Andric         InsnMatcher.getRuleMatcher(), SrcChild->getName());
104281ad6265SDimitry Andric     if (!MaybeInsnOperand) {
10430b57cec5SDimitry Andric       // This isn't strictly true. If the user were to provide exactly the same
10440b57cec5SDimitry Andric       // matchers as the original operand then we could allow it. However, it's
10450b57cec5SDimitry Andric       // simpler to not permit the redundant specification.
104606c3fb27SDimitry Andric       return failedImport(
104706c3fb27SDimitry Andric           "Nested instruction cannot be the same as another operand");
10480b57cec5SDimitry Andric     }
10490b57cec5SDimitry Andric 
10500b57cec5SDimitry Andric     // Map the node to a gMIR instruction.
10510b57cec5SDimitry Andric     InstructionOperandMatcher &InsnOperand = **MaybeInsnOperand;
10520b57cec5SDimitry Andric     auto InsnMatcherOrError = createAndImportSelDAGMatcher(
10530b57cec5SDimitry Andric         Rule, InsnOperand.getInsnMatcher(), SrcChild, TempOpIdx);
10540b57cec5SDimitry Andric     if (auto Error = InsnMatcherOrError.takeError())
10550b57cec5SDimitry Andric       return Error;
10560b57cec5SDimitry Andric 
10570b57cec5SDimitry Andric     return Error::success();
10580b57cec5SDimitry Andric   }
10590b57cec5SDimitry Andric 
10600b57cec5SDimitry Andric   if (SrcChild->hasAnyPredicate())
10610b57cec5SDimitry Andric     return failedImport("Src pattern child has unsupported predicate");
10620b57cec5SDimitry Andric 
10630b57cec5SDimitry Andric   // Check for constant immediates.
10640b57cec5SDimitry Andric   if (auto *ChildInt = dyn_cast<IntInit>(SrcChild->getLeafValue())) {
1065480093f4SDimitry Andric     if (OperandIsImmArg) {
1066480093f4SDimitry Andric       // Checks for argument directly in operand list
1067480093f4SDimitry Andric       OM.addPredicate<LiteralIntOperandMatcher>(ChildInt->getValue());
1068480093f4SDimitry Andric     } else {
1069480093f4SDimitry Andric       // Checks for materialized constant
10700b57cec5SDimitry Andric       OM.addPredicate<ConstantIntOperandMatcher>(ChildInt->getValue());
1071480093f4SDimitry Andric     }
10720b57cec5SDimitry Andric     return Error::success();
10730b57cec5SDimitry Andric   }
10740b57cec5SDimitry Andric 
10750b57cec5SDimitry Andric   // Check for def's like register classes or ComplexPattern's.
10760b57cec5SDimitry Andric   if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
10770b57cec5SDimitry Andric     auto *ChildRec = ChildDefInit->getDef();
10780b57cec5SDimitry Andric 
10790b57cec5SDimitry Andric     // Check for register classes.
10800b57cec5SDimitry Andric     if (ChildRec->isSubClassOf("RegisterClass") ||
10810b57cec5SDimitry Andric         ChildRec->isSubClassOf("RegisterOperand")) {
10820b57cec5SDimitry Andric       OM.addPredicate<RegisterBankOperandMatcher>(
10830b57cec5SDimitry Andric           Target.getRegisterClass(getInitValueAsRegClass(ChildDefInit)));
10840b57cec5SDimitry Andric       return Error::success();
10850b57cec5SDimitry Andric     }
10860b57cec5SDimitry Andric 
10878bcb0991SDimitry Andric     if (ChildRec->isSubClassOf("Register")) {
10888bcb0991SDimitry Andric       // This just be emitted as a copy to the specific register.
10898bcb0991SDimitry Andric       ValueTypeByHwMode VT = ChildTypes.front().getValueTypeByHwMode();
109006c3fb27SDimitry Andric       const CodeGenRegisterClass *RC =
109106c3fb27SDimitry Andric           CGRegs.getMinimalPhysRegClass(ChildRec, &VT);
10928bcb0991SDimitry Andric       if (!RC) {
10938bcb0991SDimitry Andric         return failedImport(
10948bcb0991SDimitry Andric             "Could not determine physical register class of pattern source");
10958bcb0991SDimitry Andric       }
10968bcb0991SDimitry Andric 
10978bcb0991SDimitry Andric       OM.addPredicate<RegisterBankOperandMatcher>(*RC);
10988bcb0991SDimitry Andric       return Error::success();
10998bcb0991SDimitry Andric     }
11008bcb0991SDimitry Andric 
11010b57cec5SDimitry Andric     // Check for ValueType.
11020b57cec5SDimitry Andric     if (ChildRec->isSubClassOf("ValueType")) {
11030b57cec5SDimitry Andric       // We already added a type check as standard practice so this doesn't need
11040b57cec5SDimitry Andric       // to do anything.
11050b57cec5SDimitry Andric       return Error::success();
11060b57cec5SDimitry Andric     }
11070b57cec5SDimitry Andric 
11080b57cec5SDimitry Andric     // Check for ComplexPattern's.
11090b57cec5SDimitry Andric     if (ChildRec->isSubClassOf("ComplexPattern"))
11100b57cec5SDimitry Andric       return importComplexPatternOperandMatcher(OM, ChildRec, TempOpIdx);
11110b57cec5SDimitry Andric 
11120b57cec5SDimitry Andric     if (ChildRec->isSubClassOf("ImmLeaf")) {
11130b57cec5SDimitry Andric       return failedImport(
11140b57cec5SDimitry Andric           "Src pattern child def is an unsupported tablegen class (ImmLeaf)");
11150b57cec5SDimitry Andric     }
11160b57cec5SDimitry Andric 
11175ffd83dbSDimitry Andric     // Place holder for SRCVALUE nodes. Nothing to do here.
11185ffd83dbSDimitry Andric     if (ChildRec->getName() == "srcvalue")
11195ffd83dbSDimitry Andric       return Error::success();
11205ffd83dbSDimitry Andric 
1121e8d8bef9SDimitry Andric     const bool ImmAllOnesV = ChildRec->getName() == "immAllOnesV";
1122e8d8bef9SDimitry Andric     if (ImmAllOnesV || ChildRec->getName() == "immAllZerosV") {
1123e8d8bef9SDimitry Andric       auto MaybeInsnOperand = OM.addPredicate<InstructionOperandMatcher>(
1124e8d8bef9SDimitry Andric           InsnMatcher.getRuleMatcher(), SrcChild->getName(), false);
1125e8d8bef9SDimitry Andric       InstructionOperandMatcher &InsnOperand = **MaybeInsnOperand;
1126e8d8bef9SDimitry Andric 
1127e8d8bef9SDimitry Andric       ValueTypeByHwMode VTy = ChildTypes.front().getValueTypeByHwMode();
1128e8d8bef9SDimitry Andric 
112906c3fb27SDimitry Andric       const CodeGenInstruction &BuildVector =
113006c3fb27SDimitry Andric           Target.getInstruction(RK.getDef("G_BUILD_VECTOR"));
113106c3fb27SDimitry Andric       const CodeGenInstruction &BuildVectorTrunc =
113206c3fb27SDimitry Andric           Target.getInstruction(RK.getDef("G_BUILD_VECTOR_TRUNC"));
1133e8d8bef9SDimitry Andric 
1134e8d8bef9SDimitry Andric       // Treat G_BUILD_VECTOR as the canonical opcode, and G_BUILD_VECTOR_TRUNC
1135e8d8bef9SDimitry Andric       // as an alternative.
1136e8d8bef9SDimitry Andric       InsnOperand.getInsnMatcher().addPredicate<InstructionOpcodeMatcher>(
1137bdd1243dSDimitry Andric           ArrayRef({&BuildVector, &BuildVectorTrunc}));
1138e8d8bef9SDimitry Andric 
1139e8d8bef9SDimitry Andric       // TODO: Handle both G_BUILD_VECTOR and G_BUILD_VECTOR_TRUNC We could
1140e8d8bef9SDimitry Andric       // theoretically not emit any opcode check, but getOpcodeMatcher currently
1141e8d8bef9SDimitry Andric       // has to succeed.
1142e8d8bef9SDimitry Andric       OperandMatcher &OM =
1143e8d8bef9SDimitry Andric           InsnOperand.getInsnMatcher().addOperand(0, "", TempOpIdx);
1144e8d8bef9SDimitry Andric       if (auto Error =
1145e8d8bef9SDimitry Andric               OM.addTypeCheckPredicate(VTy, false /* OperandIsAPointer */))
1146e8d8bef9SDimitry Andric         return failedImport(toString(std::move(Error)) +
1147e8d8bef9SDimitry Andric                             " for result of Src pattern operator");
1148e8d8bef9SDimitry Andric 
1149e8d8bef9SDimitry Andric       InsnOperand.getInsnMatcher().addPredicate<VectorSplatImmPredicateMatcher>(
1150e8d8bef9SDimitry Andric           ImmAllOnesV ? VectorSplatImmPredicateMatcher::AllOnes
1151e8d8bef9SDimitry Andric                       : VectorSplatImmPredicateMatcher::AllZeros);
1152e8d8bef9SDimitry Andric       return Error::success();
1153e8d8bef9SDimitry Andric     }
1154e8d8bef9SDimitry Andric 
11550b57cec5SDimitry Andric     return failedImport(
11560b57cec5SDimitry Andric         "Src pattern child def is an unsupported tablegen class");
11570b57cec5SDimitry Andric   }
11580b57cec5SDimitry Andric 
11590b57cec5SDimitry Andric   return failedImport("Src pattern child is an unsupported kind");
11600b57cec5SDimitry Andric }
11610b57cec5SDimitry Andric 
importExplicitUseRenderer(action_iterator InsertPt,RuleMatcher & Rule,BuildMIAction & DstMIBuilder,const TreePatternNode * DstChild,const TreePatternNode * Src)11620b57cec5SDimitry Andric Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
11630b57cec5SDimitry Andric     action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
116406c3fb27SDimitry Andric     const TreePatternNode *DstChild, const TreePatternNode *Src) {
11650b57cec5SDimitry Andric 
11660b57cec5SDimitry Andric   const auto &SubOperand = Rule.getComplexSubOperand(DstChild->getName());
116781ad6265SDimitry Andric   if (SubOperand) {
11680b57cec5SDimitry Andric     DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
11690b57cec5SDimitry Andric         *std::get<0>(*SubOperand), DstChild->getName(),
11700b57cec5SDimitry Andric         std::get<1>(*SubOperand), std::get<2>(*SubOperand));
11710b57cec5SDimitry Andric     return InsertPt;
11720b57cec5SDimitry Andric   }
11730b57cec5SDimitry Andric 
11740b57cec5SDimitry Andric   if (!DstChild->isLeaf()) {
11750b57cec5SDimitry Andric     if (DstChild->getOperator()->isSubClassOf("SDNodeXForm")) {
11760b57cec5SDimitry Andric       auto Child = DstChild->getChild(0);
11770b57cec5SDimitry Andric       auto I = SDNodeXFormEquivs.find(DstChild->getOperator());
11780b57cec5SDimitry Andric       if (I != SDNodeXFormEquivs.end()) {
1179480093f4SDimitry Andric         Record *XFormOpc = DstChild->getOperator()->getValueAsDef("Opcode");
1180480093f4SDimitry Andric         if (XFormOpc->getName() == "timm") {
1181480093f4SDimitry Andric           // If this is a TargetConstant, there won't be a corresponding
1182480093f4SDimitry Andric           // instruction to transform. Instead, this will refer directly to an
1183480093f4SDimitry Andric           // operand in an instruction's operand list.
1184480093f4SDimitry Andric           DstMIBuilder.addRenderer<CustomOperandRenderer>(*I->second,
1185480093f4SDimitry Andric                                                           Child->getName());
1186480093f4SDimitry Andric         } else {
1187480093f4SDimitry Andric           DstMIBuilder.addRenderer<CustomRenderer>(*I->second,
1188480093f4SDimitry Andric                                                    Child->getName());
1189480093f4SDimitry Andric         }
1190480093f4SDimitry Andric 
11910b57cec5SDimitry Andric         return InsertPt;
11920b57cec5SDimitry Andric       }
11930b57cec5SDimitry Andric       return failedImport("SDNodeXForm " + Child->getName() +
11940b57cec5SDimitry Andric                           " has no custom renderer");
11950b57cec5SDimitry Andric     }
11960b57cec5SDimitry Andric 
11970b57cec5SDimitry Andric     // We accept 'bb' here. It's an operator because BasicBlockSDNode isn't
11980b57cec5SDimitry Andric     // inline, but in MI it's just another operand.
11990b57cec5SDimitry Andric     if (DstChild->getOperator()->isSubClassOf("SDNode")) {
12000b57cec5SDimitry Andric       auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator());
12010b57cec5SDimitry Andric       if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
12020b57cec5SDimitry Andric         DstMIBuilder.addRenderer<CopyRenderer>(DstChild->getName());
12030b57cec5SDimitry Andric         return InsertPt;
12040b57cec5SDimitry Andric       }
12050b57cec5SDimitry Andric     }
12060b57cec5SDimitry Andric 
12070b57cec5SDimitry Andric     // Similarly, imm is an operator in TreePatternNode's view but must be
12080b57cec5SDimitry Andric     // rendered as operands.
12090b57cec5SDimitry Andric     // FIXME: The target should be able to choose sign-extended when appropriate
12100b57cec5SDimitry Andric     //        (e.g. on Mips).
12118bcb0991SDimitry Andric     if (DstChild->getOperator()->getName() == "timm") {
12128bcb0991SDimitry Andric       DstMIBuilder.addRenderer<CopyRenderer>(DstChild->getName());
12138bcb0991SDimitry Andric       return InsertPt;
12148bcb0991SDimitry Andric     } else if (DstChild->getOperator()->getName() == "imm") {
12150b57cec5SDimitry Andric       DstMIBuilder.addRenderer<CopyConstantAsImmRenderer>(DstChild->getName());
12160b57cec5SDimitry Andric       return InsertPt;
12170b57cec5SDimitry Andric     } else if (DstChild->getOperator()->getName() == "fpimm") {
12180b57cec5SDimitry Andric       DstMIBuilder.addRenderer<CopyFConstantAsFPImmRenderer>(
12190b57cec5SDimitry Andric           DstChild->getName());
12200b57cec5SDimitry Andric       return InsertPt;
12210b57cec5SDimitry Andric     }
12220b57cec5SDimitry Andric 
12230b57cec5SDimitry Andric     if (DstChild->getOperator()->isSubClassOf("Instruction")) {
12245ffd83dbSDimitry Andric       auto OpTy = getInstResultType(DstChild);
12255ffd83dbSDimitry Andric       if (!OpTy)
12265ffd83dbSDimitry Andric         return OpTy.takeError();
12270b57cec5SDimitry Andric 
12280b57cec5SDimitry Andric       unsigned TempRegID = Rule.allocateTempRegID();
122906c3fb27SDimitry Andric       InsertPt =
123006c3fb27SDimitry Andric           Rule.insertAction<MakeTempRegisterAction>(InsertPt, *OpTy, TempRegID);
12310b57cec5SDimitry Andric       DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
12320b57cec5SDimitry Andric 
12330b57cec5SDimitry Andric       auto InsertPtOrError = createAndImportSubInstructionRenderer(
123406c3fb27SDimitry Andric           ++InsertPt, Rule, DstChild, Src, TempRegID);
12350b57cec5SDimitry Andric       if (auto Error = InsertPtOrError.takeError())
12360b57cec5SDimitry Andric         return std::move(Error);
12370b57cec5SDimitry Andric       return InsertPtOrError.get();
12380b57cec5SDimitry Andric     }
12390b57cec5SDimitry Andric 
124006c3fb27SDimitry Andric     return failedImport("Dst pattern child isn't a leaf node or an MBB" +
124106c3fb27SDimitry Andric                         llvm::to_string(*DstChild));
12420b57cec5SDimitry Andric   }
12430b57cec5SDimitry Andric 
12440b57cec5SDimitry Andric   // It could be a specific immediate in which case we should just check for
12450b57cec5SDimitry Andric   // that immediate.
12460b57cec5SDimitry Andric   if (const IntInit *ChildIntInit =
12470b57cec5SDimitry Andric           dyn_cast<IntInit>(DstChild->getLeafValue())) {
12480b57cec5SDimitry Andric     DstMIBuilder.addRenderer<ImmRenderer>(ChildIntInit->getValue());
12490b57cec5SDimitry Andric     return InsertPt;
12500b57cec5SDimitry Andric   }
12510b57cec5SDimitry Andric 
12520b57cec5SDimitry Andric   // Otherwise, we're looking for a bog-standard RegisterClass operand.
12530b57cec5SDimitry Andric   if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild->getLeafValue())) {
12540b57cec5SDimitry Andric     auto *ChildRec = ChildDefInit->getDef();
12550b57cec5SDimitry Andric 
12560b57cec5SDimitry Andric     ArrayRef<TypeSetByHwMode> ChildTypes = DstChild->getExtTypes();
12570b57cec5SDimitry Andric     if (ChildTypes.size() != 1)
12580b57cec5SDimitry Andric       return failedImport("Dst pattern child has multiple results");
12590b57cec5SDimitry Andric 
1260bdd1243dSDimitry Andric     std::optional<LLTCodeGen> OpTyOrNone;
12610b57cec5SDimitry Andric     if (ChildTypes.front().isMachineValueType())
12620b57cec5SDimitry Andric       OpTyOrNone = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
12630b57cec5SDimitry Andric     if (!OpTyOrNone)
12640b57cec5SDimitry Andric       return failedImport("Dst operand has an unsupported type");
12650b57cec5SDimitry Andric 
12660b57cec5SDimitry Andric     if (ChildRec->isSubClassOf("Register")) {
1267e8d8bef9SDimitry Andric       DstMIBuilder.addRenderer<AddRegisterRenderer>(Target, ChildRec);
12680b57cec5SDimitry Andric       return InsertPt;
12690b57cec5SDimitry Andric     }
12700b57cec5SDimitry Andric 
12710b57cec5SDimitry Andric     if (ChildRec->isSubClassOf("RegisterClass") ||
12720b57cec5SDimitry Andric         ChildRec->isSubClassOf("RegisterOperand") ||
12730b57cec5SDimitry Andric         ChildRec->isSubClassOf("ValueType")) {
12740b57cec5SDimitry Andric       if (ChildRec->isSubClassOf("RegisterOperand") &&
12750b57cec5SDimitry Andric           !ChildRec->isValueUnset("GIZeroRegister")) {
12760b57cec5SDimitry Andric         DstMIBuilder.addRenderer<CopyOrAddZeroRegRenderer>(
12770b57cec5SDimitry Andric             DstChild->getName(), ChildRec->getValueAsDef("GIZeroRegister"));
12780b57cec5SDimitry Andric         return InsertPt;
12790b57cec5SDimitry Andric       }
12800b57cec5SDimitry Andric 
12810b57cec5SDimitry Andric       DstMIBuilder.addRenderer<CopyRenderer>(DstChild->getName());
12820b57cec5SDimitry Andric       return InsertPt;
12830b57cec5SDimitry Andric     }
12840b57cec5SDimitry Andric 
12858bcb0991SDimitry Andric     if (ChildRec->isSubClassOf("SubRegIndex")) {
12868bcb0991SDimitry Andric       CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(ChildRec);
12878bcb0991SDimitry Andric       DstMIBuilder.addRenderer<ImmRenderer>(SubIdx->EnumValue);
12888bcb0991SDimitry Andric       return InsertPt;
12898bcb0991SDimitry Andric     }
12908bcb0991SDimitry Andric 
12910b57cec5SDimitry Andric     if (ChildRec->isSubClassOf("ComplexPattern")) {
12920b57cec5SDimitry Andric       const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
12930b57cec5SDimitry Andric       if (ComplexPattern == ComplexPatternEquivs.end())
12940b57cec5SDimitry Andric         return failedImport(
12950b57cec5SDimitry Andric             "SelectionDAG ComplexPattern not mapped to GlobalISel");
12960b57cec5SDimitry Andric 
12970b57cec5SDimitry Andric       const OperandMatcher &OM = Rule.getOperandMatcher(DstChild->getName());
12980b57cec5SDimitry Andric       DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
12990b57cec5SDimitry Andric           *ComplexPattern->second, DstChild->getName(),
13000b57cec5SDimitry Andric           OM.getAllocatedTemporariesBaseID());
13010b57cec5SDimitry Andric       return InsertPt;
13020b57cec5SDimitry Andric     }
13030b57cec5SDimitry Andric 
13040b57cec5SDimitry Andric     return failedImport(
13050b57cec5SDimitry Andric         "Dst pattern child def is an unsupported tablegen class");
13060b57cec5SDimitry Andric   }
130706c3fb27SDimitry Andric 
130806c3fb27SDimitry Andric   // Handle the case where the MVT/register class is omitted in the dest pattern
130906c3fb27SDimitry Andric   // but MVT exists in the source pattern.
131006c3fb27SDimitry Andric   if (isa<UnsetInit>(DstChild->getLeafValue())) {
131106c3fb27SDimitry Andric     for (unsigned NumOp = 0; NumOp < Src->getNumChildren(); NumOp++)
131206c3fb27SDimitry Andric       if (Src->getChild(NumOp)->getName() == DstChild->getName()) {
131306c3fb27SDimitry Andric         DstMIBuilder.addRenderer<CopyRenderer>(Src->getChild(NumOp)->getName());
131406c3fb27SDimitry Andric         return InsertPt;
131506c3fb27SDimitry Andric       }
131606c3fb27SDimitry Andric   }
13170b57cec5SDimitry Andric   return failedImport("Dst pattern child is an unsupported kind");
13180b57cec5SDimitry Andric }
13190b57cec5SDimitry Andric 
createAndImportInstructionRenderer(RuleMatcher & M,InstructionMatcher & InsnMatcher,const TreePatternNode * Src,const TreePatternNode * Dst)13200b57cec5SDimitry Andric Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
13218bcb0991SDimitry Andric     RuleMatcher &M, InstructionMatcher &InsnMatcher, const TreePatternNode *Src,
13228bcb0991SDimitry Andric     const TreePatternNode *Dst) {
13230b57cec5SDimitry Andric   auto InsertPtOrError = createInstructionRenderer(M.actions_end(), M, Dst);
13240b57cec5SDimitry Andric   if (auto Error = InsertPtOrError.takeError())
13250b57cec5SDimitry Andric     return std::move(Error);
13260b57cec5SDimitry Andric 
13270b57cec5SDimitry Andric   action_iterator InsertPt = InsertPtOrError.get();
13280b57cec5SDimitry Andric   BuildMIAction &DstMIBuilder = *static_cast<BuildMIAction *>(InsertPt->get());
13290b57cec5SDimitry Andric 
13308bcb0991SDimitry Andric   for (auto PhysInput : InsnMatcher.getPhysRegInputs()) {
13318bcb0991SDimitry Andric     InsertPt = M.insertAction<BuildMIAction>(
13328bcb0991SDimitry Andric         InsertPt, M.allocateOutputInsnID(),
13338bcb0991SDimitry Andric         &Target.getInstruction(RK.getDef("COPY")));
13348bcb0991SDimitry Andric     BuildMIAction &CopyToPhysRegMIBuilder =
13358bcb0991SDimitry Andric         *static_cast<BuildMIAction *>(InsertPt->get());
133606c3fb27SDimitry Andric     CopyToPhysRegMIBuilder.addRenderer<AddRegisterRenderer>(
133706c3fb27SDimitry Andric         Target, PhysInput.first, true);
13388bcb0991SDimitry Andric     CopyToPhysRegMIBuilder.addRenderer<CopyPhysRegRenderer>(PhysInput.first);
13398bcb0991SDimitry Andric   }
13408bcb0991SDimitry Andric 
134106c3fb27SDimitry Andric   if (auto Error =
134206c3fb27SDimitry Andric           importExplicitDefRenderers(InsertPt, M, DstMIBuilder, Src, Dst)
1343e8d8bef9SDimitry Andric               .takeError())
1344e8d8bef9SDimitry Andric     return std::move(Error);
13450b57cec5SDimitry Andric 
134606c3fb27SDimitry Andric   if (auto Error =
134706c3fb27SDimitry Andric           importExplicitUseRenderers(InsertPt, M, DstMIBuilder, Dst, Src)
13480b57cec5SDimitry Andric               .takeError())
13490b57cec5SDimitry Andric     return std::move(Error);
13500b57cec5SDimitry Andric 
13510b57cec5SDimitry Andric   return DstMIBuilder;
13520b57cec5SDimitry Andric }
13530b57cec5SDimitry Andric 
13540b57cec5SDimitry Andric Expected<action_iterator>
createAndImportSubInstructionRenderer(const action_iterator InsertPt,RuleMatcher & M,const TreePatternNode * Dst,const TreePatternNode * Src,unsigned TempRegID)13550b57cec5SDimitry Andric GlobalISelEmitter::createAndImportSubInstructionRenderer(
13560b57cec5SDimitry Andric     const action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst,
135706c3fb27SDimitry Andric     const TreePatternNode *Src, unsigned TempRegID) {
13580b57cec5SDimitry Andric   auto InsertPtOrError = createInstructionRenderer(InsertPt, M, Dst);
13590b57cec5SDimitry Andric 
13600b57cec5SDimitry Andric   // TODO: Assert there's exactly one result.
13610b57cec5SDimitry Andric 
13620b57cec5SDimitry Andric   if (auto Error = InsertPtOrError.takeError())
13630b57cec5SDimitry Andric     return std::move(Error);
13640b57cec5SDimitry Andric 
13650b57cec5SDimitry Andric   BuildMIAction &DstMIBuilder =
13660b57cec5SDimitry Andric       *static_cast<BuildMIAction *>(InsertPtOrError.get()->get());
13670b57cec5SDimitry Andric 
13680b57cec5SDimitry Andric   // Assign the result to TempReg.
13690b57cec5SDimitry Andric   DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, true);
13700b57cec5SDimitry Andric 
137106c3fb27SDimitry Andric   InsertPtOrError = importExplicitUseRenderers(InsertPtOrError.get(), M,
137206c3fb27SDimitry Andric                                                DstMIBuilder, Dst, Src);
13730b57cec5SDimitry Andric   if (auto Error = InsertPtOrError.takeError())
13740b57cec5SDimitry Andric     return std::move(Error);
13750b57cec5SDimitry Andric 
13768bcb0991SDimitry Andric   // We need to make sure that when we import an INSERT_SUBREG as a
13778bcb0991SDimitry Andric   // subinstruction that it ends up being constrained to the correct super
13788bcb0991SDimitry Andric   // register and subregister classes.
13798bcb0991SDimitry Andric   auto OpName = Target.getInstruction(Dst->getOperator()).TheDef->getName();
13808bcb0991SDimitry Andric   if (OpName == "INSERT_SUBREG") {
13818bcb0991SDimitry Andric     auto SubClass = inferRegClassFromPattern(Dst->getChild(1));
13828bcb0991SDimitry Andric     if (!SubClass)
13838bcb0991SDimitry Andric       return failedImport(
13848bcb0991SDimitry Andric           "Cannot infer register class from INSERT_SUBREG operand #1");
1385bdd1243dSDimitry Andric     std::optional<const CodeGenRegisterClass *> SuperClass =
13868bcb0991SDimitry Andric         inferSuperRegisterClassForNode(Dst->getExtType(0), Dst->getChild(0),
13878bcb0991SDimitry Andric                                        Dst->getChild(2));
13888bcb0991SDimitry Andric     if (!SuperClass)
13898bcb0991SDimitry Andric       return failedImport(
13908bcb0991SDimitry Andric           "Cannot infer register class for INSERT_SUBREG operand #0");
13918bcb0991SDimitry Andric     // The destination and the super register source of an INSERT_SUBREG must
13928bcb0991SDimitry Andric     // be the same register class.
13938bcb0991SDimitry Andric     M.insertAction<ConstrainOperandToRegClassAction>(
13948bcb0991SDimitry Andric         InsertPt, DstMIBuilder.getInsnID(), 0, **SuperClass);
13958bcb0991SDimitry Andric     M.insertAction<ConstrainOperandToRegClassAction>(
13968bcb0991SDimitry Andric         InsertPt, DstMIBuilder.getInsnID(), 1, **SuperClass);
13978bcb0991SDimitry Andric     M.insertAction<ConstrainOperandToRegClassAction>(
13988bcb0991SDimitry Andric         InsertPt, DstMIBuilder.getInsnID(), 2, **SubClass);
13998bcb0991SDimitry Andric     return InsertPtOrError.get();
14008bcb0991SDimitry Andric   }
14018bcb0991SDimitry Andric 
14028bcb0991SDimitry Andric   if (OpName == "EXTRACT_SUBREG") {
14038bcb0991SDimitry Andric     // EXTRACT_SUBREG selects into a subregister COPY but unlike most
14048bcb0991SDimitry Andric     // instructions, the result register class is controlled by the
14058bcb0991SDimitry Andric     // subregisters of the operand. As a result, we must constrain the result
14068bcb0991SDimitry Andric     // class rather than check that it's already the right one.
14078bcb0991SDimitry Andric     auto SuperClass = inferRegClassFromPattern(Dst->getChild(0));
14088bcb0991SDimitry Andric     if (!SuperClass)
14098bcb0991SDimitry Andric       return failedImport(
14108bcb0991SDimitry Andric           "Cannot infer register class from EXTRACT_SUBREG operand #0");
14118bcb0991SDimitry Andric 
14128bcb0991SDimitry Andric     auto SubIdx = inferSubRegIndexForNode(Dst->getChild(1));
14138bcb0991SDimitry Andric     if (!SubIdx)
14148bcb0991SDimitry Andric       return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
14158bcb0991SDimitry Andric 
14165ffd83dbSDimitry Andric     const auto SrcRCDstRCPair =
14178bcb0991SDimitry Andric         (*SuperClass)->getMatchingSubClassWithSubRegs(CGRegs, *SubIdx);
14188bcb0991SDimitry Andric     assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
14198bcb0991SDimitry Andric     M.insertAction<ConstrainOperandToRegClassAction>(
14208bcb0991SDimitry Andric         InsertPt, DstMIBuilder.getInsnID(), 0, *SrcRCDstRCPair->second);
14218bcb0991SDimitry Andric     M.insertAction<ConstrainOperandToRegClassAction>(
14228bcb0991SDimitry Andric         InsertPt, DstMIBuilder.getInsnID(), 1, *SrcRCDstRCPair->first);
14238bcb0991SDimitry Andric 
14248bcb0991SDimitry Andric     // We're done with this pattern!  It's eligible for GISel emission; return
14258bcb0991SDimitry Andric     // it.
14268bcb0991SDimitry Andric     return InsertPtOrError.get();
14278bcb0991SDimitry Andric   }
14288bcb0991SDimitry Andric 
14298bcb0991SDimitry Andric   // Similar to INSERT_SUBREG, we also have to handle SUBREG_TO_REG as a
14308bcb0991SDimitry Andric   // subinstruction.
14318bcb0991SDimitry Andric   if (OpName == "SUBREG_TO_REG") {
14328bcb0991SDimitry Andric     auto SubClass = inferRegClassFromPattern(Dst->getChild(1));
14338bcb0991SDimitry Andric     if (!SubClass)
14348bcb0991SDimitry Andric       return failedImport(
14358bcb0991SDimitry Andric           "Cannot infer register class from SUBREG_TO_REG child #1");
143606c3fb27SDimitry Andric     auto SuperClass =
143706c3fb27SDimitry Andric         inferSuperRegisterClass(Dst->getExtType(0), Dst->getChild(2));
14388bcb0991SDimitry Andric     if (!SuperClass)
14398bcb0991SDimitry Andric       return failedImport(
14408bcb0991SDimitry Andric           "Cannot infer register class for SUBREG_TO_REG operand #0");
14418bcb0991SDimitry Andric     M.insertAction<ConstrainOperandToRegClassAction>(
14428bcb0991SDimitry Andric         InsertPt, DstMIBuilder.getInsnID(), 0, **SuperClass);
14438bcb0991SDimitry Andric     M.insertAction<ConstrainOperandToRegClassAction>(
14448bcb0991SDimitry Andric         InsertPt, DstMIBuilder.getInsnID(), 2, **SubClass);
14458bcb0991SDimitry Andric     return InsertPtOrError.get();
14468bcb0991SDimitry Andric   }
14478bcb0991SDimitry Andric 
14485ffd83dbSDimitry Andric   if (OpName == "REG_SEQUENCE") {
14495ffd83dbSDimitry Andric     auto SuperClass = inferRegClassFromPattern(Dst->getChild(0));
14505ffd83dbSDimitry Andric     M.insertAction<ConstrainOperandToRegClassAction>(
14515ffd83dbSDimitry Andric         InsertPt, DstMIBuilder.getInsnID(), 0, **SuperClass);
14525ffd83dbSDimitry Andric 
14535ffd83dbSDimitry Andric     unsigned Num = Dst->getNumChildren();
14545ffd83dbSDimitry Andric     for (unsigned I = 1; I != Num; I += 2) {
145506c3fb27SDimitry Andric       const TreePatternNode *SubRegChild = Dst->getChild(I + 1);
14565ffd83dbSDimitry Andric 
14575ffd83dbSDimitry Andric       auto SubIdx = inferSubRegIndexForNode(SubRegChild);
14585ffd83dbSDimitry Andric       if (!SubIdx)
14595ffd83dbSDimitry Andric         return failedImport("REG_SEQUENCE child is not a subreg index");
14605ffd83dbSDimitry Andric 
14615ffd83dbSDimitry Andric       const auto SrcRCDstRCPair =
14625ffd83dbSDimitry Andric           (*SuperClass)->getMatchingSubClassWithSubRegs(CGRegs, *SubIdx);
14635ffd83dbSDimitry Andric       assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
14645ffd83dbSDimitry Andric       M.insertAction<ConstrainOperandToRegClassAction>(
14655ffd83dbSDimitry Andric           InsertPt, DstMIBuilder.getInsnID(), I, *SrcRCDstRCPair->second);
14665ffd83dbSDimitry Andric     }
14675ffd83dbSDimitry Andric 
14685ffd83dbSDimitry Andric     return InsertPtOrError.get();
14695ffd83dbSDimitry Andric   }
14705ffd83dbSDimitry Andric 
14710b57cec5SDimitry Andric   M.insertAction<ConstrainOperandsToDefinitionAction>(InsertPt,
14720b57cec5SDimitry Andric                                                       DstMIBuilder.getInsnID());
14730b57cec5SDimitry Andric   return InsertPtOrError.get();
14740b57cec5SDimitry Andric }
14750b57cec5SDimitry Andric 
createInstructionRenderer(action_iterator InsertPt,RuleMatcher & M,const TreePatternNode * Dst)14760b57cec5SDimitry Andric Expected<action_iterator> GlobalISelEmitter::createInstructionRenderer(
14770b57cec5SDimitry Andric     action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst) {
14780b57cec5SDimitry Andric   Record *DstOp = Dst->getOperator();
14790b57cec5SDimitry Andric   if (!DstOp->isSubClassOf("Instruction")) {
14800b57cec5SDimitry Andric     if (DstOp->isSubClassOf("ValueType"))
14810b57cec5SDimitry Andric       return failedImport(
14820b57cec5SDimitry Andric           "Pattern operator isn't an instruction (it's a ValueType)");
14830b57cec5SDimitry Andric     return failedImport("Pattern operator isn't an instruction");
14840b57cec5SDimitry Andric   }
14850b57cec5SDimitry Andric   CodeGenInstruction *DstI = &Target.getInstruction(DstOp);
14860b57cec5SDimitry Andric 
14870b57cec5SDimitry Andric   // COPY_TO_REGCLASS is just a copy with a ConstrainOperandToRegClassAction
14880b57cec5SDimitry Andric   // attached. Similarly for EXTRACT_SUBREG except that's a subregister copy.
14898bcb0991SDimitry Andric   StringRef Name = DstI->TheDef->getName();
14908bcb0991SDimitry Andric   if (Name == "COPY_TO_REGCLASS" || Name == "EXTRACT_SUBREG")
14910b57cec5SDimitry Andric     DstI = &Target.getInstruction(RK.getDef("COPY"));
14920b57cec5SDimitry Andric 
14930b57cec5SDimitry Andric   return M.insertAction<BuildMIAction>(InsertPt, M.allocateOutputInsnID(),
14940b57cec5SDimitry Andric                                        DstI);
14950b57cec5SDimitry Andric }
14960b57cec5SDimitry Andric 
importExplicitDefRenderers(action_iterator InsertPt,RuleMatcher & M,BuildMIAction & DstMIBuilder,const TreePatternNode * Src,const TreePatternNode * Dst)1497e8d8bef9SDimitry Andric Expected<action_iterator> GlobalISelEmitter::importExplicitDefRenderers(
1498e8d8bef9SDimitry Andric     action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
149906c3fb27SDimitry Andric     const TreePatternNode *Src, const TreePatternNode *Dst) {
15000b57cec5SDimitry Andric   const CodeGenInstruction *DstI = DstMIBuilder.getCGI();
150106c3fb27SDimitry Andric   const unsigned SrcNumDefs = Src->getExtTypes().size();
150206c3fb27SDimitry Andric   const unsigned DstNumDefs = DstI->Operands.NumDefs;
150306c3fb27SDimitry Andric   if (DstNumDefs == 0)
1504e8d8bef9SDimitry Andric     return InsertPt;
1505e8d8bef9SDimitry Andric 
15065f757f3fSDimitry Andric   for (unsigned I = 0; I < SrcNumDefs; ++I) {
15075f757f3fSDimitry Andric     std::string OpName = getMangledRootDefName(DstI->Operands[I].Name);
15085f757f3fSDimitry Andric     // CopyRenderer saves a StringRef, so cannot pass OpName itself -
15095f757f3fSDimitry Andric     // let's use a string with an appropriate lifetime.
15105f757f3fSDimitry Andric     StringRef PermanentRef = M.getOperandMatcher(OpName).getSymbolicName();
15115f757f3fSDimitry Andric     DstMIBuilder.addRenderer<CopyRenderer>(PermanentRef);
15125f757f3fSDimitry Andric   }
1513e8d8bef9SDimitry Andric 
1514e8d8bef9SDimitry Andric   // Some instructions have multiple defs, but are missing a type entry
1515e8d8bef9SDimitry Andric   // (e.g. s_cc_out operands).
151606c3fb27SDimitry Andric   if (Dst->getExtTypes().size() < DstNumDefs)
1517e8d8bef9SDimitry Andric     return failedImport("unhandled discarded def");
1518e8d8bef9SDimitry Andric 
151906c3fb27SDimitry Andric   for (unsigned I = SrcNumDefs; I < DstNumDefs; ++I) {
1520e8d8bef9SDimitry Andric     const TypeSetByHwMode &ExtTy = Dst->getExtType(I);
1521e8d8bef9SDimitry Andric     if (!ExtTy.isMachineValueType())
1522e8d8bef9SDimitry Andric       return failedImport("unsupported typeset");
1523e8d8bef9SDimitry Andric 
1524e8d8bef9SDimitry Andric     auto OpTy = MVTToLLT(ExtTy.getMachineValueType().SimpleTy);
1525e8d8bef9SDimitry Andric     if (!OpTy)
1526e8d8bef9SDimitry Andric       return failedImport("unsupported type");
1527e8d8bef9SDimitry Andric 
1528e8d8bef9SDimitry Andric     unsigned TempRegID = M.allocateTempRegID();
1529e8d8bef9SDimitry Andric     InsertPt =
1530e8d8bef9SDimitry Andric         M.insertAction<MakeTempRegisterAction>(InsertPt, *OpTy, TempRegID);
1531e8d8bef9SDimitry Andric     DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, true, nullptr, true);
15320b57cec5SDimitry Andric   }
1533e8d8bef9SDimitry Andric 
1534e8d8bef9SDimitry Andric   return InsertPt;
15350b57cec5SDimitry Andric }
15360b57cec5SDimitry Andric 
importExplicitUseRenderers(action_iterator InsertPt,RuleMatcher & M,BuildMIAction & DstMIBuilder,const llvm::TreePatternNode * Dst,const llvm::TreePatternNode * Src)15370b57cec5SDimitry Andric Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
15380b57cec5SDimitry Andric     action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
153906c3fb27SDimitry Andric     const llvm::TreePatternNode *Dst, const llvm::TreePatternNode *Src) {
15400b57cec5SDimitry Andric   const CodeGenInstruction *DstI = DstMIBuilder.getCGI();
15410b57cec5SDimitry Andric   CodeGenInstruction *OrigDstI = &Target.getInstruction(Dst->getOperator());
15420b57cec5SDimitry Andric 
15438bcb0991SDimitry Andric   StringRef Name = OrigDstI->TheDef->getName();
15448bcb0991SDimitry Andric   unsigned ExpectedDstINumUses = Dst->getNumChildren();
15458bcb0991SDimitry Andric 
15460b57cec5SDimitry Andric   // EXTRACT_SUBREG needs to use a subregister COPY.
15478bcb0991SDimitry Andric   if (Name == "EXTRACT_SUBREG") {
1548e8d8bef9SDimitry Andric     if (!Dst->getChild(1)->isLeaf())
1549e8d8bef9SDimitry Andric       return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
15505ffd83dbSDimitry Andric     DefInit *SubRegInit = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
15515ffd83dbSDimitry Andric     if (!SubRegInit)
15525ffd83dbSDimitry Andric       return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
15530b57cec5SDimitry Andric 
15545ffd83dbSDimitry Andric     CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
155506c3fb27SDimitry Andric     const TreePatternNode *ValChild = Dst->getChild(0);
15565ffd83dbSDimitry Andric     if (!ValChild->isLeaf()) {
15575ffd83dbSDimitry Andric       // We really have to handle the source instruction, and then insert a
15585ffd83dbSDimitry Andric       // copy from the subregister.
15595ffd83dbSDimitry Andric       auto ExtractSrcTy = getInstResultType(ValChild);
15605ffd83dbSDimitry Andric       if (!ExtractSrcTy)
15615ffd83dbSDimitry Andric         return ExtractSrcTy.takeError();
15625ffd83dbSDimitry Andric 
15635ffd83dbSDimitry Andric       unsigned TempRegID = M.allocateTempRegID();
156406c3fb27SDimitry Andric       InsertPt = M.insertAction<MakeTempRegisterAction>(InsertPt, *ExtractSrcTy,
156506c3fb27SDimitry Andric                                                         TempRegID);
15665ffd83dbSDimitry Andric 
15675ffd83dbSDimitry Andric       auto InsertPtOrError = createAndImportSubInstructionRenderer(
156806c3fb27SDimitry Andric           ++InsertPt, M, ValChild, Src, TempRegID);
15695ffd83dbSDimitry Andric       if (auto Error = InsertPtOrError.takeError())
15705ffd83dbSDimitry Andric         return std::move(Error);
15715ffd83dbSDimitry Andric 
15725ffd83dbSDimitry Andric       DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, false, SubIdx);
15735ffd83dbSDimitry Andric       return InsertPt;
15745ffd83dbSDimitry Andric     }
15755ffd83dbSDimitry Andric 
15765ffd83dbSDimitry Andric     // If this is a source operand, this is just a subregister copy.
15775ffd83dbSDimitry Andric     Record *RCDef = getInitValueAsRegClass(ValChild->getLeafValue());
15780b57cec5SDimitry Andric     if (!RCDef)
15790b57cec5SDimitry Andric       return failedImport("EXTRACT_SUBREG child #0 could not "
15800b57cec5SDimitry Andric                           "be coerced to a register class");
15810b57cec5SDimitry Andric 
15820b57cec5SDimitry Andric     CodeGenRegisterClass *RC = CGRegs.getRegClass(RCDef);
15830b57cec5SDimitry Andric 
15845ffd83dbSDimitry Andric     const auto SrcRCDstRCPair =
15850b57cec5SDimitry Andric         RC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
158681ad6265SDimitry Andric     if (SrcRCDstRCPair) {
15870b57cec5SDimitry Andric       assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
15880b57cec5SDimitry Andric       if (SrcRCDstRCPair->first != RC)
15890b57cec5SDimitry Andric         return failedImport("EXTRACT_SUBREG requires an additional COPY");
15900b57cec5SDimitry Andric     }
15910b57cec5SDimitry Andric 
159206c3fb27SDimitry Andric     StringRef RegOperandName = Dst->getChild(0)->getName();
159306c3fb27SDimitry Andric     if (const auto &SubOperand = M.getComplexSubOperand(RegOperandName)) {
159406c3fb27SDimitry Andric       DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
159506c3fb27SDimitry Andric           *std::get<0>(*SubOperand), RegOperandName, std::get<1>(*SubOperand),
159606c3fb27SDimitry Andric           std::get<2>(*SubOperand), SubIdx);
159706c3fb27SDimitry Andric       return InsertPt;
159806c3fb27SDimitry Andric     }
159906c3fb27SDimitry Andric 
160006c3fb27SDimitry Andric     DstMIBuilder.addRenderer<CopySubRegRenderer>(RegOperandName, SubIdx);
16010b57cec5SDimitry Andric     return InsertPt;
16020b57cec5SDimitry Andric   }
16030b57cec5SDimitry Andric 
16048bcb0991SDimitry Andric   if (Name == "REG_SEQUENCE") {
16058bcb0991SDimitry Andric     if (!Dst->getChild(0)->isLeaf())
16068bcb0991SDimitry Andric       return failedImport("REG_SEQUENCE child #0 is not a leaf");
16078bcb0991SDimitry Andric 
16088bcb0991SDimitry Andric     Record *RCDef = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
16098bcb0991SDimitry Andric     if (!RCDef)
16108bcb0991SDimitry Andric       return failedImport("REG_SEQUENCE child #0 could not "
16118bcb0991SDimitry Andric                           "be coerced to a register class");
16128bcb0991SDimitry Andric 
16138bcb0991SDimitry Andric     if ((ExpectedDstINumUses - 1) % 2 != 0)
16148bcb0991SDimitry Andric       return failedImport("Malformed REG_SEQUENCE");
16158bcb0991SDimitry Andric 
16168bcb0991SDimitry Andric     for (unsigned I = 1; I != ExpectedDstINumUses; I += 2) {
161706c3fb27SDimitry Andric       const TreePatternNode *ValChild = Dst->getChild(I);
161806c3fb27SDimitry Andric       const TreePatternNode *SubRegChild = Dst->getChild(I + 1);
16198bcb0991SDimitry Andric 
16208bcb0991SDimitry Andric       if (DefInit *SubRegInit =
16218bcb0991SDimitry Andric               dyn_cast<DefInit>(SubRegChild->getLeafValue())) {
16228bcb0991SDimitry Andric         CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
16238bcb0991SDimitry Andric 
16248bcb0991SDimitry Andric         auto InsertPtOrError =
162506c3fb27SDimitry Andric             importExplicitUseRenderer(InsertPt, M, DstMIBuilder, ValChild, Src);
16268bcb0991SDimitry Andric         if (auto Error = InsertPtOrError.takeError())
16278bcb0991SDimitry Andric           return std::move(Error);
16288bcb0991SDimitry Andric         InsertPt = InsertPtOrError.get();
16298bcb0991SDimitry Andric         DstMIBuilder.addRenderer<SubRegIndexRenderer>(SubIdx);
16308bcb0991SDimitry Andric       }
16318bcb0991SDimitry Andric     }
16328bcb0991SDimitry Andric 
16338bcb0991SDimitry Andric     return InsertPt;
16348bcb0991SDimitry Andric   }
16358bcb0991SDimitry Andric 
16360b57cec5SDimitry Andric   // Render the explicit uses.
16370b57cec5SDimitry Andric   unsigned DstINumUses = OrigDstI->Operands.size() - OrigDstI->Operands.NumDefs;
16388bcb0991SDimitry Andric   if (Name == "COPY_TO_REGCLASS") {
16390b57cec5SDimitry Andric     DstINumUses--; // Ignore the class constraint.
16400b57cec5SDimitry Andric     ExpectedDstINumUses--;
16410b57cec5SDimitry Andric   }
16420b57cec5SDimitry Andric 
1643480093f4SDimitry Andric   // NumResults - This is the number of results produced by the instruction in
1644480093f4SDimitry Andric   // the "outs" list.
1645480093f4SDimitry Andric   unsigned NumResults = OrigDstI->Operands.NumDefs;
1646480093f4SDimitry Andric 
1647480093f4SDimitry Andric   // Number of operands we know the output instruction must have. If it is
1648480093f4SDimitry Andric   // variadic, we could have more operands.
1649480093f4SDimitry Andric   unsigned NumFixedOperands = DstI->Operands.size();
1650480093f4SDimitry Andric 
1651480093f4SDimitry Andric   // Loop over all of the fixed operands of the instruction pattern, emitting
1652480093f4SDimitry Andric   // code to fill them all in. The node 'N' usually has number children equal to
1653480093f4SDimitry Andric   // the number of input operands of the instruction.  However, in cases where
1654480093f4SDimitry Andric   // there are predicate operands for an instruction, we need to fill in the
1655480093f4SDimitry Andric   // 'execute always' values. Match up the node operands to the instruction
1656480093f4SDimitry Andric   // operands to do this.
16570b57cec5SDimitry Andric   unsigned Child = 0;
1658480093f4SDimitry Andric 
1659480093f4SDimitry Andric   // Similarly to the code in TreePatternNode::ApplyTypeConstraints, count the
1660480093f4SDimitry Andric   // number of operands at the end of the list which have default values.
1661480093f4SDimitry Andric   // Those can come from the pattern if it provides enough arguments, or be
1662480093f4SDimitry Andric   // filled in with the default if the pattern hasn't provided them. But any
1663480093f4SDimitry Andric   // operand with a default value _before_ the last mandatory one will be
1664480093f4SDimitry Andric   // filled in with their defaults unconditionally.
1665480093f4SDimitry Andric   unsigned NonOverridableOperands = NumFixedOperands;
1666480093f4SDimitry Andric   while (NonOverridableOperands > NumResults &&
1667480093f4SDimitry Andric          CGP.operandHasDefault(DstI->Operands[NonOverridableOperands - 1].Rec))
1668480093f4SDimitry Andric     --NonOverridableOperands;
1669480093f4SDimitry Andric 
16700b57cec5SDimitry Andric   unsigned NumDefaultOps = 0;
16710b57cec5SDimitry Andric   for (unsigned I = 0; I != DstINumUses; ++I) {
1672480093f4SDimitry Andric     unsigned InstOpNo = DstI->Operands.NumDefs + I;
1673480093f4SDimitry Andric 
1674480093f4SDimitry Andric     // Determine what to emit for this operand.
1675480093f4SDimitry Andric     Record *OperandNode = DstI->Operands[InstOpNo].Rec;
16760b57cec5SDimitry Andric 
16770b57cec5SDimitry Andric     // If the operand has default values, introduce them now.
1678480093f4SDimitry Andric     if (CGP.operandHasDefault(OperandNode) &&
1679480093f4SDimitry Andric         (InstOpNo < NonOverridableOperands || Child >= Dst->getNumChildren())) {
1680480093f4SDimitry Andric       // This is a predicate or optional def operand which the pattern has not
1681480093f4SDimitry Andric       // overridden, or which we aren't letting it override; emit the 'default
1682480093f4SDimitry Andric       // ops' operands.
1683480093f4SDimitry Andric 
16845f757f3fSDimitry Andric       Record *OperandNode = DstI->Operands[InstOpNo].Rec;
16855f757f3fSDimitry Andric       if (auto Error = importDefaultOperandRenderers(
16865f757f3fSDimitry Andric               InsertPt, M, DstMIBuilder, CGP.getDefaultOperand(OperandNode)))
16870b57cec5SDimitry Andric         return std::move(Error);
16885f757f3fSDimitry Andric 
16890b57cec5SDimitry Andric       ++NumDefaultOps;
16900b57cec5SDimitry Andric       continue;
16910b57cec5SDimitry Andric     }
16920b57cec5SDimitry Andric 
16930b57cec5SDimitry Andric     auto InsertPtOrError = importExplicitUseRenderer(InsertPt, M, DstMIBuilder,
169406c3fb27SDimitry Andric                                                      Dst->getChild(Child), Src);
16950b57cec5SDimitry Andric     if (auto Error = InsertPtOrError.takeError())
16960b57cec5SDimitry Andric       return std::move(Error);
16970b57cec5SDimitry Andric     InsertPt = InsertPtOrError.get();
16980b57cec5SDimitry Andric     ++Child;
16990b57cec5SDimitry Andric   }
17000b57cec5SDimitry Andric 
17010b57cec5SDimitry Andric   if (NumDefaultOps + ExpectedDstINumUses != DstINumUses)
17020b57cec5SDimitry Andric     return failedImport("Expected " + llvm::to_string(DstINumUses) +
17030b57cec5SDimitry Andric                         " used operands but found " +
17040b57cec5SDimitry Andric                         llvm::to_string(ExpectedDstINumUses) +
17050b57cec5SDimitry Andric                         " explicit ones and " + llvm::to_string(NumDefaultOps) +
17060b57cec5SDimitry Andric                         " default ones");
17070b57cec5SDimitry Andric 
17080b57cec5SDimitry Andric   return InsertPt;
17090b57cec5SDimitry Andric }
17100b57cec5SDimitry Andric 
importDefaultOperandRenderers(action_iterator InsertPt,RuleMatcher & M,BuildMIAction & DstMIBuilder,const DAGDefaultOperand & DefaultOp) const17110b57cec5SDimitry Andric Error GlobalISelEmitter::importDefaultOperandRenderers(
17120b57cec5SDimitry Andric     action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
17135f757f3fSDimitry Andric     const DAGDefaultOperand &DefaultOp) const {
17145f757f3fSDimitry Andric   for (const auto &Op : DefaultOp.DefaultOps) {
17155f757f3fSDimitry Andric     const auto *N = Op.get();
17165f757f3fSDimitry Andric     if (!N->isLeaf())
17175f757f3fSDimitry Andric       return failedImport("Could not add default op");
17180b57cec5SDimitry Andric 
17195f757f3fSDimitry Andric     const auto *DefaultOp = N->getLeafValue();
17200b57cec5SDimitry Andric 
17210b57cec5SDimitry Andric     if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) {
17225f757f3fSDimitry Andric       std::optional<LLTCodeGen> OpTyOrNone = MVTToLLT(N->getSimpleType(0));
17230b57cec5SDimitry Andric       auto Def = DefaultDefOp->getDef();
17240b57cec5SDimitry Andric       if (Def->getName() == "undef_tied_input") {
17250b57cec5SDimitry Andric         unsigned TempRegID = M.allocateTempRegID();
1726bdd1243dSDimitry Andric         M.insertAction<MakeTempRegisterAction>(InsertPt, *OpTyOrNone,
1727753f127fSDimitry Andric                                                TempRegID);
17280b57cec5SDimitry Andric         InsertPt = M.insertAction<BuildMIAction>(
17290b57cec5SDimitry Andric             InsertPt, M.allocateOutputInsnID(),
17300b57cec5SDimitry Andric             &Target.getInstruction(RK.getDef("IMPLICIT_DEF")));
173106c3fb27SDimitry Andric         BuildMIAction &IDMIBuilder =
173206c3fb27SDimitry Andric             *static_cast<BuildMIAction *>(InsertPt->get());
17330b57cec5SDimitry Andric         IDMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
17340b57cec5SDimitry Andric         DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
17350b57cec5SDimitry Andric       } else {
1736e8d8bef9SDimitry Andric         DstMIBuilder.addRenderer<AddRegisterRenderer>(Target, Def);
17370b57cec5SDimitry Andric       }
17380b57cec5SDimitry Andric       continue;
17390b57cec5SDimitry Andric     }
17400b57cec5SDimitry Andric 
17410b57cec5SDimitry Andric     if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) {
17420b57cec5SDimitry Andric       DstMIBuilder.addRenderer<ImmRenderer>(DefaultIntOp->getValue());
17430b57cec5SDimitry Andric       continue;
17440b57cec5SDimitry Andric     }
17450b57cec5SDimitry Andric 
17460b57cec5SDimitry Andric     return failedImport("Could not add default op");
17470b57cec5SDimitry Andric   }
17480b57cec5SDimitry Andric 
17490b57cec5SDimitry Andric   return Error::success();
17500b57cec5SDimitry Andric }
17510b57cec5SDimitry Andric 
importImplicitDefRenderers(BuildMIAction & DstMIBuilder,const std::vector<Record * > & ImplicitDefs) const17520b57cec5SDimitry Andric Error GlobalISelEmitter::importImplicitDefRenderers(
17530b57cec5SDimitry Andric     BuildMIAction &DstMIBuilder,
17540b57cec5SDimitry Andric     const std::vector<Record *> &ImplicitDefs) const {
17550b57cec5SDimitry Andric   if (!ImplicitDefs.empty())
17560b57cec5SDimitry Andric     return failedImport("Pattern defines a physical register");
17570b57cec5SDimitry Andric   return Error::success();
17580b57cec5SDimitry Andric }
17590b57cec5SDimitry Andric 
1760bdd1243dSDimitry Andric std::optional<const CodeGenRegisterClass *>
getRegClassFromLeaf(const TreePatternNode * Leaf)176106c3fb27SDimitry Andric GlobalISelEmitter::getRegClassFromLeaf(const TreePatternNode *Leaf) {
17628bcb0991SDimitry Andric   assert(Leaf && "Expected node?");
17638bcb0991SDimitry Andric   assert(Leaf->isLeaf() && "Expected leaf?");
17648bcb0991SDimitry Andric   Record *RCRec = getInitValueAsRegClass(Leaf->getLeafValue());
17658bcb0991SDimitry Andric   if (!RCRec)
1766bdd1243dSDimitry Andric     return std::nullopt;
17678bcb0991SDimitry Andric   CodeGenRegisterClass *RC = CGRegs.getRegClass(RCRec);
17688bcb0991SDimitry Andric   if (!RC)
1769bdd1243dSDimitry Andric     return std::nullopt;
17708bcb0991SDimitry Andric   return RC;
17718bcb0991SDimitry Andric }
17728bcb0991SDimitry Andric 
1773bdd1243dSDimitry Andric std::optional<const CodeGenRegisterClass *>
inferRegClassFromPattern(const TreePatternNode * N)177406c3fb27SDimitry Andric GlobalISelEmitter::inferRegClassFromPattern(const TreePatternNode *N) {
17758bcb0991SDimitry Andric   if (!N)
1776bdd1243dSDimitry Andric     return std::nullopt;
17778bcb0991SDimitry Andric 
17788bcb0991SDimitry Andric   if (N->isLeaf())
17798bcb0991SDimitry Andric     return getRegClassFromLeaf(N);
17808bcb0991SDimitry Andric 
17818bcb0991SDimitry Andric   // We don't have a leaf node, so we have to try and infer something. Check
17828bcb0991SDimitry Andric   // that we have an instruction that we an infer something from.
17838bcb0991SDimitry Andric 
17848bcb0991SDimitry Andric   // Only handle things that produce a single type.
17858bcb0991SDimitry Andric   if (N->getNumTypes() != 1)
1786bdd1243dSDimitry Andric     return std::nullopt;
17878bcb0991SDimitry Andric   Record *OpRec = N->getOperator();
17888bcb0991SDimitry Andric 
17898bcb0991SDimitry Andric   // We only want instructions.
17908bcb0991SDimitry Andric   if (!OpRec->isSubClassOf("Instruction"))
1791bdd1243dSDimitry Andric     return std::nullopt;
17928bcb0991SDimitry Andric 
17938bcb0991SDimitry Andric   // Don't want to try and infer things when there could potentially be more
17948bcb0991SDimitry Andric   // than one candidate register class.
17958bcb0991SDimitry Andric   auto &Inst = Target.getInstruction(OpRec);
17968bcb0991SDimitry Andric   if (Inst.Operands.NumDefs > 1)
1797bdd1243dSDimitry Andric     return std::nullopt;
17988bcb0991SDimitry Andric 
17998bcb0991SDimitry Andric   // Handle any special-case instructions which we can safely infer register
18008bcb0991SDimitry Andric   // classes from.
18018bcb0991SDimitry Andric   StringRef InstName = Inst.TheDef->getName();
18028bcb0991SDimitry Andric   bool IsRegSequence = InstName == "REG_SEQUENCE";
18038bcb0991SDimitry Andric   if (IsRegSequence || InstName == "COPY_TO_REGCLASS") {
18048bcb0991SDimitry Andric     // If we have a COPY_TO_REGCLASS, then we need to handle it specially. It
18058bcb0991SDimitry Andric     // has the desired register class as the first child.
180606c3fb27SDimitry Andric     const TreePatternNode *RCChild = N->getChild(IsRegSequence ? 0 : 1);
18078bcb0991SDimitry Andric     if (!RCChild->isLeaf())
1808bdd1243dSDimitry Andric       return std::nullopt;
18098bcb0991SDimitry Andric     return getRegClassFromLeaf(RCChild);
18108bcb0991SDimitry Andric   }
1811e8d8bef9SDimitry Andric   if (InstName == "INSERT_SUBREG") {
181206c3fb27SDimitry Andric     const TreePatternNode *Child0 = N->getChild(0);
1813e8d8bef9SDimitry Andric     assert(Child0->getNumTypes() == 1 && "Unexpected number of types!");
1814e8d8bef9SDimitry Andric     const TypeSetByHwMode &VTy = Child0->getExtType(0);
1815e8d8bef9SDimitry Andric     return inferSuperRegisterClassForNode(VTy, Child0, N->getChild(2));
1816e8d8bef9SDimitry Andric   }
1817e8d8bef9SDimitry Andric   if (InstName == "EXTRACT_SUBREG") {
1818e8d8bef9SDimitry Andric     assert(N->getNumTypes() == 1 && "Unexpected number of types!");
1819e8d8bef9SDimitry Andric     const TypeSetByHwMode &VTy = N->getExtType(0);
1820e8d8bef9SDimitry Andric     return inferSuperRegisterClass(VTy, N->getChild(1));
1821e8d8bef9SDimitry Andric   }
18228bcb0991SDimitry Andric 
18238bcb0991SDimitry Andric   // Handle destination record types that we can safely infer a register class
18248bcb0991SDimitry Andric   // from.
18258bcb0991SDimitry Andric   const auto &DstIOperand = Inst.Operands[0];
18268bcb0991SDimitry Andric   Record *DstIOpRec = DstIOperand.Rec;
18278bcb0991SDimitry Andric   if (DstIOpRec->isSubClassOf("RegisterOperand")) {
18288bcb0991SDimitry Andric     DstIOpRec = DstIOpRec->getValueAsDef("RegClass");
18298bcb0991SDimitry Andric     const CodeGenRegisterClass &RC = Target.getRegisterClass(DstIOpRec);
18308bcb0991SDimitry Andric     return &RC;
18318bcb0991SDimitry Andric   }
18328bcb0991SDimitry Andric 
18338bcb0991SDimitry Andric   if (DstIOpRec->isSubClassOf("RegisterClass")) {
18348bcb0991SDimitry Andric     const CodeGenRegisterClass &RC = Target.getRegisterClass(DstIOpRec);
18358bcb0991SDimitry Andric     return &RC;
18368bcb0991SDimitry Andric   }
18378bcb0991SDimitry Andric 
1838bdd1243dSDimitry Andric   return std::nullopt;
18398bcb0991SDimitry Andric }
18408bcb0991SDimitry Andric 
1841bdd1243dSDimitry Andric std::optional<const CodeGenRegisterClass *>
inferSuperRegisterClass(const TypeSetByHwMode & Ty,const TreePatternNode * SubRegIdxNode)184206c3fb27SDimitry Andric GlobalISelEmitter::inferSuperRegisterClass(
184306c3fb27SDimitry Andric     const TypeSetByHwMode &Ty, const TreePatternNode *SubRegIdxNode) {
18448bcb0991SDimitry Andric   assert(SubRegIdxNode && "Expected subregister index node!");
18458bcb0991SDimitry Andric   // We need a ValueTypeByHwMode for getSuperRegForSubReg.
18468bcb0991SDimitry Andric   if (!Ty.isValueTypeByHwMode(false))
1847bdd1243dSDimitry Andric     return std::nullopt;
18488bcb0991SDimitry Andric   if (!SubRegIdxNode->isLeaf())
1849bdd1243dSDimitry Andric     return std::nullopt;
18508bcb0991SDimitry Andric   DefInit *SubRegInit = dyn_cast<DefInit>(SubRegIdxNode->getLeafValue());
18518bcb0991SDimitry Andric   if (!SubRegInit)
1852bdd1243dSDimitry Andric     return std::nullopt;
18538bcb0991SDimitry Andric   CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
18548bcb0991SDimitry Andric 
18558bcb0991SDimitry Andric   // Use the information we found above to find a minimal register class which
18568bcb0991SDimitry Andric   // supports the subregister and type we want.
18578bcb0991SDimitry Andric   auto RC =
1858e8d8bef9SDimitry Andric       Target.getSuperRegForSubReg(Ty.getValueTypeByHwMode(), CGRegs, SubIdx,
1859e8d8bef9SDimitry Andric                                   /* MustBeAllocatable */ true);
18608bcb0991SDimitry Andric   if (!RC)
1861bdd1243dSDimitry Andric     return std::nullopt;
18628bcb0991SDimitry Andric   return *RC;
18638bcb0991SDimitry Andric }
18648bcb0991SDimitry Andric 
1865bdd1243dSDimitry Andric std::optional<const CodeGenRegisterClass *>
inferSuperRegisterClassForNode(const TypeSetByHwMode & Ty,const TreePatternNode * SuperRegNode,const TreePatternNode * SubRegIdxNode)18668bcb0991SDimitry Andric GlobalISelEmitter::inferSuperRegisterClassForNode(
186706c3fb27SDimitry Andric     const TypeSetByHwMode &Ty, const TreePatternNode *SuperRegNode,
186806c3fb27SDimitry Andric     const TreePatternNode *SubRegIdxNode) {
18698bcb0991SDimitry Andric   assert(SuperRegNode && "Expected super register node!");
18708bcb0991SDimitry Andric   // Check if we already have a defined register class for the super register
18718bcb0991SDimitry Andric   // node. If we do, then we should preserve that rather than inferring anything
18728bcb0991SDimitry Andric   // from the subregister index node. We can assume that whoever wrote the
18738bcb0991SDimitry Andric   // pattern in the first place made sure that the super register and
18748bcb0991SDimitry Andric   // subregister are compatible.
1875bdd1243dSDimitry Andric   if (std::optional<const CodeGenRegisterClass *> SuperRegisterClass =
18768bcb0991SDimitry Andric           inferRegClassFromPattern(SuperRegNode))
18778bcb0991SDimitry Andric     return *SuperRegisterClass;
18788bcb0991SDimitry Andric   return inferSuperRegisterClass(Ty, SubRegIdxNode);
18798bcb0991SDimitry Andric }
18808bcb0991SDimitry Andric 
inferSubRegIndexForNode(const TreePatternNode * SubRegIdxNode)188106c3fb27SDimitry Andric std::optional<CodeGenSubRegIndex *> GlobalISelEmitter::inferSubRegIndexForNode(
188206c3fb27SDimitry Andric     const TreePatternNode *SubRegIdxNode) {
18838bcb0991SDimitry Andric   if (!SubRegIdxNode->isLeaf())
1884bdd1243dSDimitry Andric     return std::nullopt;
18858bcb0991SDimitry Andric 
18868bcb0991SDimitry Andric   DefInit *SubRegInit = dyn_cast<DefInit>(SubRegIdxNode->getLeafValue());
18878bcb0991SDimitry Andric   if (!SubRegInit)
1888bdd1243dSDimitry Andric     return std::nullopt;
18898bcb0991SDimitry Andric   return CGRegs.getSubRegIdx(SubRegInit->getDef());
18908bcb0991SDimitry Andric }
18918bcb0991SDimitry Andric 
runOnPattern(const PatternToMatch & P)18920b57cec5SDimitry Andric Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
18930b57cec5SDimitry Andric   // Keep track of the matchers and actions to emit.
18940b57cec5SDimitry Andric   int Score = P.getPatternComplexity(CGP);
18950b57cec5SDimitry Andric   RuleMatcher M(P.getSrcRecord()->getLoc());
18960b57cec5SDimitry Andric   RuleMatcherScores[M.getRuleID()] = Score;
18970b57cec5SDimitry Andric   M.addAction<DebugCommentAction>(llvm::to_string(*P.getSrcPattern()) +
18980b57cec5SDimitry Andric                                   "  =>  " +
18990b57cec5SDimitry Andric                                   llvm::to_string(*P.getDstPattern()));
19000b57cec5SDimitry Andric 
1901fe6060f1SDimitry Andric   SmallVector<Record *, 4> Predicates;
1902fe6060f1SDimitry Andric   P.getPredicateRecords(Predicates);
1903fe6060f1SDimitry Andric   if (auto Error = importRulePredicates(M, Predicates))
19040b57cec5SDimitry Andric     return std::move(Error);
19050b57cec5SDimitry Andric 
19065f757f3fSDimitry Andric   if (!P.getHwModeFeatures().empty())
19075f757f3fSDimitry Andric     M.addHwModeIdx(declareHwModeCheck(P.getHwModeFeatures()));
19085f757f3fSDimitry Andric 
19090b57cec5SDimitry Andric   // Next, analyze the pattern operators.
19100b57cec5SDimitry Andric   TreePatternNode *Src = P.getSrcPattern();
19110b57cec5SDimitry Andric   TreePatternNode *Dst = P.getDstPattern();
19120b57cec5SDimitry Andric 
19130b57cec5SDimitry Andric   // If the root of either pattern isn't a simple operator, ignore it.
19140b57cec5SDimitry Andric   if (auto Err = isTrivialOperatorNode(Dst))
19150b57cec5SDimitry Andric     return failedImport("Dst pattern root isn't a trivial operator (" +
19160b57cec5SDimitry Andric                         toString(std::move(Err)) + ")");
19170b57cec5SDimitry Andric   if (auto Err = isTrivialOperatorNode(Src))
19180b57cec5SDimitry Andric     return failedImport("Src pattern root isn't a trivial operator (" +
19190b57cec5SDimitry Andric                         toString(std::move(Err)) + ")");
19200b57cec5SDimitry Andric 
19210b57cec5SDimitry Andric   // The different predicates and matchers created during
19220b57cec5SDimitry Andric   // addInstructionMatcher use the RuleMatcher M to set up their
19230b57cec5SDimitry Andric   // instruction ID (InsnVarID) that are going to be used when
19240b57cec5SDimitry Andric   // M is going to be emitted.
19250b57cec5SDimitry Andric   // However, the code doing the emission still relies on the IDs
19260b57cec5SDimitry Andric   // returned during that process by the RuleMatcher when issuing
19270b57cec5SDimitry Andric   // the recordInsn opcodes.
19280b57cec5SDimitry Andric   // Because of that:
19290b57cec5SDimitry Andric   // 1. The order in which we created the predicates
19300b57cec5SDimitry Andric   //    and such must be the same as the order in which we emit them,
19310b57cec5SDimitry Andric   //    and
19320b57cec5SDimitry Andric   // 2. We need to reset the generation of the IDs in M somewhere between
19330b57cec5SDimitry Andric   //    addInstructionMatcher and emit
19340b57cec5SDimitry Andric   //
19350b57cec5SDimitry Andric   // FIXME: Long term, we don't want to have to rely on this implicit
19360b57cec5SDimitry Andric   // naming being the same. One possible solution would be to have
19370b57cec5SDimitry Andric   // explicit operator for operation capture and reference those.
19380b57cec5SDimitry Andric   // The plus side is that it would expose opportunities to share
19390b57cec5SDimitry Andric   // the capture accross rules. The downside is that it would
19400b57cec5SDimitry Andric   // introduce a dependency between predicates (captures must happen
19410b57cec5SDimitry Andric   // before their first use.)
19420b57cec5SDimitry Andric   InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher(Src->getName());
19430b57cec5SDimitry Andric   unsigned TempOpIdx = 0;
194406c3fb27SDimitry Andric 
194506c3fb27SDimitry Andric   const auto SavedFlags = M.setGISelFlags(P.getSrcRecord());
194606c3fb27SDimitry Andric 
19470b57cec5SDimitry Andric   auto InsnMatcherOrError =
19480b57cec5SDimitry Andric       createAndImportSelDAGMatcher(M, InsnMatcherTemp, Src, TempOpIdx);
19490b57cec5SDimitry Andric   if (auto Error = InsnMatcherOrError.takeError())
19500b57cec5SDimitry Andric     return std::move(Error);
19510b57cec5SDimitry Andric   InstructionMatcher &InsnMatcher = InsnMatcherOrError.get();
19520b57cec5SDimitry Andric 
19530b57cec5SDimitry Andric   if (Dst->isLeaf()) {
19540b57cec5SDimitry Andric     Record *RCDef = getInitValueAsRegClass(Dst->getLeafValue());
19550b57cec5SDimitry Andric     if (RCDef) {
1956e8d8bef9SDimitry Andric       const CodeGenRegisterClass &RC = Target.getRegisterClass(RCDef);
1957e8d8bef9SDimitry Andric 
19580b57cec5SDimitry Andric       // We need to replace the def and all its uses with the specified
19590b57cec5SDimitry Andric       // operand. However, we must also insert COPY's wherever needed.
19600b57cec5SDimitry Andric       // For now, emit a copy and let the register allocator clean up.
19610b57cec5SDimitry Andric       auto &DstI = Target.getInstruction(RK.getDef("COPY"));
19620b57cec5SDimitry Andric       const auto &DstIOperand = DstI.Operands[0];
19630b57cec5SDimitry Andric 
19640b57cec5SDimitry Andric       OperandMatcher &OM0 = InsnMatcher.getOperand(0);
19650b57cec5SDimitry Andric       OM0.setSymbolicName(DstIOperand.Name);
19660b57cec5SDimitry Andric       M.defineOperand(OM0.getSymbolicName(), OM0);
19670b57cec5SDimitry Andric       OM0.addPredicate<RegisterBankOperandMatcher>(RC);
19680b57cec5SDimitry Andric 
19690b57cec5SDimitry Andric       auto &DstMIBuilder =
19700b57cec5SDimitry Andric           M.addAction<BuildMIAction>(M.allocateOutputInsnID(), &DstI);
19710b57cec5SDimitry Andric       DstMIBuilder.addRenderer<CopyRenderer>(DstIOperand.Name);
19720b57cec5SDimitry Andric       DstMIBuilder.addRenderer<CopyRenderer>(Dst->getName());
19730b57cec5SDimitry Andric       M.addAction<ConstrainOperandToRegClassAction>(0, 0, RC);
19740b57cec5SDimitry Andric 
19757a6dacacSDimitry Andric       // Erase the root.
19767a6dacacSDimitry Andric       unsigned RootInsnID = M.getInsnVarID(InsnMatcher);
19777a6dacacSDimitry Andric       M.addAction<EraseInstAction>(RootInsnID);
19787a6dacacSDimitry Andric 
19790b57cec5SDimitry Andric       // We're done with this pattern!  It's eligible for GISel emission; return
19800b57cec5SDimitry Andric       // it.
19810b57cec5SDimitry Andric       ++NumPatternImported;
19820b57cec5SDimitry Andric       return std::move(M);
19830b57cec5SDimitry Andric     }
19840b57cec5SDimitry Andric 
19850b57cec5SDimitry Andric     return failedImport("Dst pattern root isn't a known leaf");
19860b57cec5SDimitry Andric   }
19870b57cec5SDimitry Andric 
19880b57cec5SDimitry Andric   // Start with the defined operands (i.e., the results of the root operator).
19890b57cec5SDimitry Andric   Record *DstOp = Dst->getOperator();
19900b57cec5SDimitry Andric   if (!DstOp->isSubClassOf("Instruction"))
19910b57cec5SDimitry Andric     return failedImport("Pattern operator isn't an instruction");
19920b57cec5SDimitry Andric 
19930b57cec5SDimitry Andric   auto &DstI = Target.getInstruction(DstOp);
19948bcb0991SDimitry Andric   StringRef DstIName = DstI.TheDef->getName();
19958bcb0991SDimitry Andric 
1996753f127fSDimitry Andric   unsigned DstNumDefs = DstI.Operands.NumDefs,
1997753f127fSDimitry Andric            SrcNumDefs = Src->getExtTypes().size();
1998753f127fSDimitry Andric   if (DstNumDefs < SrcNumDefs) {
1999753f127fSDimitry Andric     if (DstNumDefs != 0)
2000e8d8bef9SDimitry Andric       return failedImport("Src pattern result has more defs than dst MI (" +
2001753f127fSDimitry Andric                           to_string(SrcNumDefs) + " def(s) vs " +
2002753f127fSDimitry Andric                           to_string(DstNumDefs) + " def(s))");
2003753f127fSDimitry Andric 
2004753f127fSDimitry Andric     bool FoundNoUsePred = false;
2005753f127fSDimitry Andric     for (const auto &Pred : InsnMatcher.predicates()) {
2006753f127fSDimitry Andric       if ((FoundNoUsePred = isa<NoUsePredicateMatcher>(Pred.get())))
2007753f127fSDimitry Andric         break;
2008753f127fSDimitry Andric     }
2009753f127fSDimitry Andric     if (!FoundNoUsePred)
2010753f127fSDimitry Andric       return failedImport("Src pattern result has " + to_string(SrcNumDefs) +
2011753f127fSDimitry Andric                           " def(s) without the HasNoUse predicate set to true "
2012753f127fSDimitry Andric                           "but Dst MI has no def");
2013753f127fSDimitry Andric   }
20140b57cec5SDimitry Andric 
20150b57cec5SDimitry Andric   // The root of the match also has constraints on the register bank so that it
20160b57cec5SDimitry Andric   // matches the result instruction.
20170b57cec5SDimitry Andric   unsigned OpIdx = 0;
2018753f127fSDimitry Andric   unsigned N = std::min(DstNumDefs, SrcNumDefs);
2019753f127fSDimitry Andric   for (unsigned I = 0; I < N; ++I) {
2020753f127fSDimitry Andric     const TypeSetByHwMode &VTy = Src->getExtType(I);
20210b57cec5SDimitry Andric 
20220b57cec5SDimitry Andric     const auto &DstIOperand = DstI.Operands[OpIdx];
20235f757f3fSDimitry Andric     PointerUnion<Record *, const CodeGenRegisterClass *> MatchedRC =
20245f757f3fSDimitry Andric         DstIOperand.Rec;
20258bcb0991SDimitry Andric     if (DstIName == "COPY_TO_REGCLASS") {
20265f757f3fSDimitry Andric       MatchedRC = getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
20270b57cec5SDimitry Andric 
20285f757f3fSDimitry Andric       if (MatchedRC.isNull())
20290b57cec5SDimitry Andric         return failedImport(
20300b57cec5SDimitry Andric             "COPY_TO_REGCLASS operand #1 isn't a register class");
20318bcb0991SDimitry Andric     } else if (DstIName == "REG_SEQUENCE") {
20325f757f3fSDimitry Andric       MatchedRC = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
20335f757f3fSDimitry Andric       if (MatchedRC.isNull())
20348bcb0991SDimitry Andric         return failedImport("REG_SEQUENCE operand #0 isn't a register class");
20358bcb0991SDimitry Andric     } else if (DstIName == "EXTRACT_SUBREG") {
20365ffd83dbSDimitry Andric       auto InferredClass = inferRegClassFromPattern(Dst->getChild(0));
20375ffd83dbSDimitry Andric       if (!InferredClass)
203806c3fb27SDimitry Andric         return failedImport(
203906c3fb27SDimitry Andric             "Could not infer class for EXTRACT_SUBREG operand #0");
20400b57cec5SDimitry Andric 
20410b57cec5SDimitry Andric       // We can assume that a subregister is in the same bank as it's super
20420b57cec5SDimitry Andric       // register.
20435f757f3fSDimitry Andric       MatchedRC = (*InferredClass)->getDef();
20448bcb0991SDimitry Andric     } else if (DstIName == "INSERT_SUBREG") {
20458bcb0991SDimitry Andric       auto MaybeSuperClass = inferSuperRegisterClassForNode(
20468bcb0991SDimitry Andric           VTy, Dst->getChild(0), Dst->getChild(2));
20478bcb0991SDimitry Andric       if (!MaybeSuperClass)
20480b57cec5SDimitry Andric         return failedImport(
20498bcb0991SDimitry Andric             "Cannot infer register class for INSERT_SUBREG operand #0");
20508bcb0991SDimitry Andric       // Move to the next pattern here, because the register class we found
20518bcb0991SDimitry Andric       // doesn't necessarily have a record associated with it. So, we can't
20528bcb0991SDimitry Andric       // set DstIOpRec using this.
20535f757f3fSDimitry Andric       MatchedRC = *MaybeSuperClass;
20548bcb0991SDimitry Andric     } else if (DstIName == "SUBREG_TO_REG") {
20558bcb0991SDimitry Andric       auto MaybeRegClass = inferSuperRegisterClass(VTy, Dst->getChild(2));
20568bcb0991SDimitry Andric       if (!MaybeRegClass)
20578bcb0991SDimitry Andric         return failedImport(
20588bcb0991SDimitry Andric             "Cannot infer register class for SUBREG_TO_REG operand #0");
20595f757f3fSDimitry Andric       MatchedRC = *MaybeRegClass;
20605f757f3fSDimitry Andric     } else if (MatchedRC.get<Record *>()->isSubClassOf("RegisterOperand"))
20615f757f3fSDimitry Andric       MatchedRC = MatchedRC.get<Record *>()->getValueAsDef("RegClass");
20625f757f3fSDimitry Andric     else if (!MatchedRC.get<Record *>()->isSubClassOf("RegisterClass"))
20630b57cec5SDimitry Andric       return failedImport("Dst MI def isn't a register class" +
20640b57cec5SDimitry Andric                           to_string(*Dst));
20650b57cec5SDimitry Andric 
20660b57cec5SDimitry Andric     OperandMatcher &OM = InsnMatcher.getOperand(OpIdx);
20675f757f3fSDimitry Andric     // The operand names declared in the DstI instruction are unrelated to
20685f757f3fSDimitry Andric     // those used in pattern's source and destination DAGs, so mangle the
20695f757f3fSDimitry Andric     // former to prevent implicitly adding unexpected
20705f757f3fSDimitry Andric     // GIM_CheckIsSameOperand predicates by the defineOperand method.
20715f757f3fSDimitry Andric     OM.setSymbolicName(getMangledRootDefName(DstIOperand.Name));
20720b57cec5SDimitry Andric     M.defineOperand(OM.getSymbolicName(), OM);
20735f757f3fSDimitry Andric     if (MatchedRC.is<Record *>())
20745f757f3fSDimitry Andric       MatchedRC = &Target.getRegisterClass(MatchedRC.get<Record *>());
20750b57cec5SDimitry Andric     OM.addPredicate<RegisterBankOperandMatcher>(
20765f757f3fSDimitry Andric         *MatchedRC.get<const CodeGenRegisterClass *>());
20770b57cec5SDimitry Andric     ++OpIdx;
20780b57cec5SDimitry Andric   }
20790b57cec5SDimitry Andric 
20808bcb0991SDimitry Andric   auto DstMIBuilderOrError =
20818bcb0991SDimitry Andric       createAndImportInstructionRenderer(M, InsnMatcher, Src, Dst);
20820b57cec5SDimitry Andric   if (auto Error = DstMIBuilderOrError.takeError())
20830b57cec5SDimitry Andric     return std::move(Error);
20840b57cec5SDimitry Andric   BuildMIAction &DstMIBuilder = DstMIBuilderOrError.get();
20850b57cec5SDimitry Andric 
20860b57cec5SDimitry Andric   // Render the implicit defs.
20870b57cec5SDimitry Andric   // These are only added to the root of the result.
20880b57cec5SDimitry Andric   if (auto Error = importImplicitDefRenderers(DstMIBuilder, P.getDstRegs()))
20890b57cec5SDimitry Andric     return std::move(Error);
20900b57cec5SDimitry Andric 
20910b57cec5SDimitry Andric   DstMIBuilder.chooseInsnToMutate(M);
20920b57cec5SDimitry Andric 
20930b57cec5SDimitry Andric   // Constrain the registers to classes. This is normally derived from the
20940b57cec5SDimitry Andric   // emitted instruction but a few instructions require special handling.
20958bcb0991SDimitry Andric   if (DstIName == "COPY_TO_REGCLASS") {
20960b57cec5SDimitry Andric     // COPY_TO_REGCLASS does not provide operand constraints itself but the
20970b57cec5SDimitry Andric     // result is constrained to the class given by the second child.
20980b57cec5SDimitry Andric     Record *DstIOpRec =
20990b57cec5SDimitry Andric         getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
21000b57cec5SDimitry Andric 
21010b57cec5SDimitry Andric     if (DstIOpRec == nullptr)
21020b57cec5SDimitry Andric       return failedImport("COPY_TO_REGCLASS operand #1 isn't a register class");
21030b57cec5SDimitry Andric 
21040b57cec5SDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(
21050b57cec5SDimitry Andric         0, 0, Target.getRegisterClass(DstIOpRec));
21067a6dacacSDimitry Andric   } else if (DstIName == "EXTRACT_SUBREG") {
21078bcb0991SDimitry Andric     auto SuperClass = inferRegClassFromPattern(Dst->getChild(0));
21088bcb0991SDimitry Andric     if (!SuperClass)
21098bcb0991SDimitry Andric       return failedImport(
21108bcb0991SDimitry Andric           "Cannot infer register class from EXTRACT_SUBREG operand #0");
21110b57cec5SDimitry Andric 
21128bcb0991SDimitry Andric     auto SubIdx = inferSubRegIndexForNode(Dst->getChild(1));
21138bcb0991SDimitry Andric     if (!SubIdx)
21140b57cec5SDimitry Andric       return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
21150b57cec5SDimitry Andric 
21160b57cec5SDimitry Andric     // It would be nice to leave this constraint implicit but we're required
21170b57cec5SDimitry Andric     // to pick a register class so constrain the result to a register class
21180b57cec5SDimitry Andric     // that can hold the correct MVT.
21190b57cec5SDimitry Andric     //
21200b57cec5SDimitry Andric     // FIXME: This may introduce an extra copy if the chosen class doesn't
21210b57cec5SDimitry Andric     //        actually contain the subregisters.
21220b57cec5SDimitry Andric     assert(Src->getExtTypes().size() == 1 &&
21230b57cec5SDimitry Andric            "Expected Src of EXTRACT_SUBREG to have one result type");
21240b57cec5SDimitry Andric 
21255ffd83dbSDimitry Andric     const auto SrcRCDstRCPair =
21268bcb0991SDimitry Andric         (*SuperClass)->getMatchingSubClassWithSubRegs(CGRegs, *SubIdx);
21275ffd83dbSDimitry Andric     if (!SrcRCDstRCPair) {
21285ffd83dbSDimitry Andric       return failedImport("subreg index is incompatible "
21295ffd83dbSDimitry Andric                           "with inferred reg class");
21305ffd83dbSDimitry Andric     }
21315ffd83dbSDimitry Andric 
21320b57cec5SDimitry Andric     assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
213306c3fb27SDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(0, 0,
213406c3fb27SDimitry Andric                                                   *SrcRCDstRCPair->second);
21350b57cec5SDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(0, 1, *SrcRCDstRCPair->first);
21367a6dacacSDimitry Andric   } else if (DstIName == "INSERT_SUBREG") {
21378bcb0991SDimitry Andric     assert(Src->getExtTypes().size() == 1 &&
21388bcb0991SDimitry Andric            "Expected Src of INSERT_SUBREG to have one result type");
21398bcb0991SDimitry Andric     // We need to constrain the destination, a super regsister source, and a
21408bcb0991SDimitry Andric     // subregister source.
21418bcb0991SDimitry Andric     auto SubClass = inferRegClassFromPattern(Dst->getChild(1));
21428bcb0991SDimitry Andric     if (!SubClass)
21438bcb0991SDimitry Andric       return failedImport(
21448bcb0991SDimitry Andric           "Cannot infer register class from INSERT_SUBREG operand #1");
21458bcb0991SDimitry Andric     auto SuperClass = inferSuperRegisterClassForNode(
21468bcb0991SDimitry Andric         Src->getExtType(0), Dst->getChild(0), Dst->getChild(2));
21478bcb0991SDimitry Andric     if (!SuperClass)
21488bcb0991SDimitry Andric       return failedImport(
21498bcb0991SDimitry Andric           "Cannot infer register class for INSERT_SUBREG operand #0");
21508bcb0991SDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(0, 0, **SuperClass);
21518bcb0991SDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(0, 1, **SuperClass);
21528bcb0991SDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(0, 2, **SubClass);
21537a6dacacSDimitry Andric   } else if (DstIName == "SUBREG_TO_REG") {
21548bcb0991SDimitry Andric     // We need to constrain the destination and subregister source.
21558bcb0991SDimitry Andric     assert(Src->getExtTypes().size() == 1 &&
21568bcb0991SDimitry Andric            "Expected Src of SUBREG_TO_REG to have one result type");
21578bcb0991SDimitry Andric 
21588bcb0991SDimitry Andric     // Attempt to infer the subregister source from the first child. If it has
21598bcb0991SDimitry Andric     // an explicitly given register class, we'll use that. Otherwise, we will
21608bcb0991SDimitry Andric     // fail.
21618bcb0991SDimitry Andric     auto SubClass = inferRegClassFromPattern(Dst->getChild(1));
21628bcb0991SDimitry Andric     if (!SubClass)
21638bcb0991SDimitry Andric       return failedImport(
21648bcb0991SDimitry Andric           "Cannot infer register class from SUBREG_TO_REG child #1");
21658bcb0991SDimitry Andric     // We don't have a child to look at that might have a super register node.
21668bcb0991SDimitry Andric     auto SuperClass =
21678bcb0991SDimitry Andric         inferSuperRegisterClass(Src->getExtType(0), Dst->getChild(2));
21688bcb0991SDimitry Andric     if (!SuperClass)
21698bcb0991SDimitry Andric       return failedImport(
21708bcb0991SDimitry Andric           "Cannot infer register class for SUBREG_TO_REG operand #0");
21718bcb0991SDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(0, 0, **SuperClass);
21728bcb0991SDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(0, 2, **SubClass);
21737a6dacacSDimitry Andric   } else if (DstIName == "REG_SEQUENCE") {
21745ffd83dbSDimitry Andric     auto SuperClass = inferRegClassFromPattern(Dst->getChild(0));
21755ffd83dbSDimitry Andric 
21765ffd83dbSDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(0, 0, **SuperClass);
21775ffd83dbSDimitry Andric 
21785ffd83dbSDimitry Andric     unsigned Num = Dst->getNumChildren();
21795ffd83dbSDimitry Andric     for (unsigned I = 1; I != Num; I += 2) {
21805ffd83dbSDimitry Andric       TreePatternNode *SubRegChild = Dst->getChild(I + 1);
21815ffd83dbSDimitry Andric 
21825ffd83dbSDimitry Andric       auto SubIdx = inferSubRegIndexForNode(SubRegChild);
21835ffd83dbSDimitry Andric       if (!SubIdx)
21845ffd83dbSDimitry Andric         return failedImport("REG_SEQUENCE child is not a subreg index");
21855ffd83dbSDimitry Andric 
21865ffd83dbSDimitry Andric       const auto SrcRCDstRCPair =
21875ffd83dbSDimitry Andric           (*SuperClass)->getMatchingSubClassWithSubRegs(CGRegs, *SubIdx);
21885ffd83dbSDimitry Andric 
21895ffd83dbSDimitry Andric       M.addAction<ConstrainOperandToRegClassAction>(0, I,
21905ffd83dbSDimitry Andric                                                     *SrcRCDstRCPair->second);
21915ffd83dbSDimitry Andric     }
21927a6dacacSDimitry Andric   } else {
21937a6dacacSDimitry Andric     M.addAction<ConstrainOperandsToDefinitionAction>(0);
21945ffd83dbSDimitry Andric   }
21955ffd83dbSDimitry Andric 
21967a6dacacSDimitry Andric   // Erase the root.
21977a6dacacSDimitry Andric   unsigned RootInsnID = M.getInsnVarID(InsnMatcher);
21987a6dacacSDimitry Andric   M.addAction<EraseInstAction>(RootInsnID);
21990b57cec5SDimitry Andric 
22000b57cec5SDimitry Andric   // We're done with this pattern!  It's eligible for GISel emission; return it.
22010b57cec5SDimitry Andric   ++NumPatternImported;
22020b57cec5SDimitry Andric   return std::move(M);
22030b57cec5SDimitry Andric }
22040b57cec5SDimitry Andric 
22050b57cec5SDimitry Andric MatchTable
buildMatchTable(MutableArrayRef<RuleMatcher> Rules,bool Optimize,bool WithCoverage)22060b57cec5SDimitry Andric GlobalISelEmitter::buildMatchTable(MutableArrayRef<RuleMatcher> Rules,
22070b57cec5SDimitry Andric                                    bool Optimize, bool WithCoverage) {
22080b57cec5SDimitry Andric   std::vector<Matcher *> InputRules;
22090b57cec5SDimitry Andric   for (Matcher &Rule : Rules)
22100b57cec5SDimitry Andric     InputRules.push_back(&Rule);
22110b57cec5SDimitry Andric 
22120b57cec5SDimitry Andric   if (!Optimize)
22130b57cec5SDimitry Andric     return MatchTable::buildTable(InputRules, WithCoverage);
22140b57cec5SDimitry Andric 
22150b57cec5SDimitry Andric   unsigned CurrentOrdering = 0;
22160b57cec5SDimitry Andric   StringMap<unsigned> OpcodeOrder;
22170b57cec5SDimitry Andric   for (RuleMatcher &Rule : Rules) {
22180b57cec5SDimitry Andric     const StringRef Opcode = Rule.getOpcode();
22190b57cec5SDimitry Andric     assert(!Opcode.empty() && "Didn't expect an undefined opcode");
22200b57cec5SDimitry Andric     if (OpcodeOrder.count(Opcode) == 0)
22210b57cec5SDimitry Andric       OpcodeOrder[Opcode] = CurrentOrdering++;
22220b57cec5SDimitry Andric   }
22230b57cec5SDimitry Andric 
2224e8d8bef9SDimitry Andric   llvm::stable_sort(InputRules, [&OpcodeOrder](const Matcher *A,
2225e8d8bef9SDimitry Andric                                                const Matcher *B) {
22260b57cec5SDimitry Andric     auto *L = static_cast<const RuleMatcher *>(A);
22270b57cec5SDimitry Andric     auto *R = static_cast<const RuleMatcher *>(B);
2228e8d8bef9SDimitry Andric     return std::make_tuple(OpcodeOrder[L->getOpcode()], L->getNumOperands()) <
2229e8d8bef9SDimitry Andric            std::make_tuple(OpcodeOrder[R->getOpcode()], R->getNumOperands());
22300b57cec5SDimitry Andric   });
22310b57cec5SDimitry Andric 
22320b57cec5SDimitry Andric   for (Matcher *Rule : InputRules)
22330b57cec5SDimitry Andric     Rule->optimize();
22340b57cec5SDimitry Andric 
22350b57cec5SDimitry Andric   std::vector<std::unique_ptr<Matcher>> MatcherStorage;
22360b57cec5SDimitry Andric   std::vector<Matcher *> OptRules =
22370b57cec5SDimitry Andric       optimizeRules<GroupMatcher>(InputRules, MatcherStorage);
22380b57cec5SDimitry Andric 
22390b57cec5SDimitry Andric   for (Matcher *Rule : OptRules)
22400b57cec5SDimitry Andric     Rule->optimize();
22410b57cec5SDimitry Andric 
22420b57cec5SDimitry Andric   OptRules = optimizeRules<SwitchMatcher>(OptRules, MatcherStorage);
22430b57cec5SDimitry Andric 
22440b57cec5SDimitry Andric   return MatchTable::buildTable(OptRules, WithCoverage);
22450b57cec5SDimitry Andric }
22460b57cec5SDimitry Andric 
emitAdditionalImpl(raw_ostream & OS)224706c3fb27SDimitry Andric void GlobalISelEmitter::emitAdditionalImpl(raw_ostream &OS) {
224806c3fb27SDimitry Andric   OS << "bool " << getClassName()
224906c3fb27SDimitry Andric      << "::selectImpl(MachineInstr &I, CodeGenCoverage "
225006c3fb27SDimitry Andric         "&CoverageInfo) const {\n"
225106c3fb27SDimitry Andric      << "  const PredicateBitset AvailableFeatures = "
225206c3fb27SDimitry Andric         "getAvailableFeatures();\n"
22535f757f3fSDimitry Andric      << "  MachineIRBuilder B(I);\n"
225406c3fb27SDimitry Andric      << "  State.MIs.clear();\n"
225506c3fb27SDimitry Andric      << "  State.MIs.push_back(&I);\n\n"
22565f757f3fSDimitry Andric      << "  if (executeMatchTable(*this, State, ExecInfo, B"
225706c3fb27SDimitry Andric      << ", getMatchTable(), TII, MF->getRegInfo(), TRI, RBI, AvailableFeatures"
225806c3fb27SDimitry Andric      << ", &CoverageInfo)) {\n"
225906c3fb27SDimitry Andric      << "    return true;\n"
226006c3fb27SDimitry Andric      << "  }\n\n"
226106c3fb27SDimitry Andric      << "  return false;\n"
226206c3fb27SDimitry Andric      << "}\n\n";
22630b57cec5SDimitry Andric }
226406c3fb27SDimitry Andric 
emitMIPredicateFns(raw_ostream & OS)226506c3fb27SDimitry Andric void GlobalISelEmitter::emitMIPredicateFns(raw_ostream &OS) {
226606c3fb27SDimitry Andric   std::vector<Record *> MatchedRecords;
226706c3fb27SDimitry Andric   std::copy_if(AllPatFrags.begin(), AllPatFrags.end(),
226806c3fb27SDimitry Andric                std::back_inserter(MatchedRecords), [&](Record *R) {
226906c3fb27SDimitry Andric                  return !R->getValueAsString("GISelPredicateCode").empty();
22700b57cec5SDimitry Andric                });
227106c3fb27SDimitry Andric   emitMIPredicateFnsImpl<Record *>(
227206c3fb27SDimitry Andric       OS,
227306c3fb27SDimitry Andric       "  const MachineFunction &MF = *MI.getParent()->getParent();\n"
227406c3fb27SDimitry Andric       "  const MachineRegisterInfo &MRI = MF.getRegInfo();\n"
227506c3fb27SDimitry Andric       "  const auto &Operands = State.RecordedOperands;\n"
227606c3fb27SDimitry Andric       "  (void)Operands;\n"
227706c3fb27SDimitry Andric       "  (void)MRI;",
227806c3fb27SDimitry Andric       ArrayRef<Record *>(MatchedRecords), &getPatFragPredicateEnumName,
227906c3fb27SDimitry Andric       [&](Record *R) { return R->getValueAsString("GISelPredicateCode"); },
228006c3fb27SDimitry Andric       "PatFrag predicates.");
22810b57cec5SDimitry Andric }
228206c3fb27SDimitry Andric 
emitI64ImmPredicateFns(raw_ostream & OS)228306c3fb27SDimitry Andric void GlobalISelEmitter::emitI64ImmPredicateFns(raw_ostream &OS) {
228406c3fb27SDimitry Andric   std::vector<Record *> MatchedRecords;
228506c3fb27SDimitry Andric   std::copy_if(AllPatFrags.begin(), AllPatFrags.end(),
228606c3fb27SDimitry Andric                std::back_inserter(MatchedRecords), [&](Record *R) {
228706c3fb27SDimitry Andric                  bool Unset;
228806c3fb27SDimitry Andric                  return !R->getValueAsString("ImmediateCode").empty() &&
228906c3fb27SDimitry Andric                         !R->getValueAsBitOrUnset("IsAPFloat", Unset) &&
229006c3fb27SDimitry Andric                         !R->getValueAsBit("IsAPInt");
229106c3fb27SDimitry Andric                });
229206c3fb27SDimitry Andric   emitImmPredicateFnsImpl<Record *>(
229306c3fb27SDimitry Andric       OS, "I64", "int64_t", ArrayRef<Record *>(MatchedRecords),
229406c3fb27SDimitry Andric       &getPatFragPredicateEnumName,
229506c3fb27SDimitry Andric       [&](Record *R) { return R->getValueAsString("ImmediateCode"); },
229606c3fb27SDimitry Andric       "PatFrag predicates.");
229706c3fb27SDimitry Andric }
229806c3fb27SDimitry Andric 
emitAPFloatImmPredicateFns(raw_ostream & OS)229906c3fb27SDimitry Andric void GlobalISelEmitter::emitAPFloatImmPredicateFns(raw_ostream &OS) {
230006c3fb27SDimitry Andric   std::vector<Record *> MatchedRecords;
230106c3fb27SDimitry Andric   std::copy_if(AllPatFrags.begin(), AllPatFrags.end(),
230206c3fb27SDimitry Andric                std::back_inserter(MatchedRecords), [&](Record *R) {
230306c3fb27SDimitry Andric                  bool Unset;
230406c3fb27SDimitry Andric                  return !R->getValueAsString("ImmediateCode").empty() &&
230506c3fb27SDimitry Andric                         R->getValueAsBitOrUnset("IsAPFloat", Unset);
230606c3fb27SDimitry Andric                });
230706c3fb27SDimitry Andric   emitImmPredicateFnsImpl<Record *>(
230806c3fb27SDimitry Andric       OS, "APFloat", "const APFloat &", ArrayRef<Record *>(MatchedRecords),
230906c3fb27SDimitry Andric       &getPatFragPredicateEnumName,
231006c3fb27SDimitry Andric       [&](Record *R) { return R->getValueAsString("ImmediateCode"); },
231106c3fb27SDimitry Andric       "PatFrag predicates.");
231206c3fb27SDimitry Andric }
231306c3fb27SDimitry Andric 
emitAPIntImmPredicateFns(raw_ostream & OS)231406c3fb27SDimitry Andric void GlobalISelEmitter::emitAPIntImmPredicateFns(raw_ostream &OS) {
231506c3fb27SDimitry Andric   std::vector<Record *> MatchedRecords;
231606c3fb27SDimitry Andric   std::copy_if(AllPatFrags.begin(), AllPatFrags.end(),
231706c3fb27SDimitry Andric                std::back_inserter(MatchedRecords), [&](Record *R) {
231806c3fb27SDimitry Andric                  return !R->getValueAsString("ImmediateCode").empty() &&
231906c3fb27SDimitry Andric                         R->getValueAsBit("IsAPInt");
232006c3fb27SDimitry Andric                });
232106c3fb27SDimitry Andric   emitImmPredicateFnsImpl<Record *>(
232206c3fb27SDimitry Andric       OS, "APInt", "const APInt &", ArrayRef<Record *>(MatchedRecords),
232306c3fb27SDimitry Andric       &getPatFragPredicateEnumName,
232406c3fb27SDimitry Andric       [&](Record *R) { return R->getValueAsString("ImmediateCode"); },
232506c3fb27SDimitry Andric       "PatFrag predicates.");
232606c3fb27SDimitry Andric }
232706c3fb27SDimitry Andric 
emitTestSimplePredicate(raw_ostream & OS)232806c3fb27SDimitry Andric void GlobalISelEmitter::emitTestSimplePredicate(raw_ostream &OS) {
232906c3fb27SDimitry Andric   OS << "bool " << getClassName() << "::testSimplePredicate(unsigned) const {\n"
233006c3fb27SDimitry Andric      << "    llvm_unreachable(\"" + getClassName() +
233106c3fb27SDimitry Andric             " does not support simple predicates!\");\n"
233206c3fb27SDimitry Andric      << "  return false;\n"
233306c3fb27SDimitry Andric      << "}\n";
233406c3fb27SDimitry Andric }
233506c3fb27SDimitry Andric 
emitRunCustomAction(raw_ostream & OS)233606c3fb27SDimitry Andric void GlobalISelEmitter::emitRunCustomAction(raw_ostream &OS) {
233706c3fb27SDimitry Andric   OS << "void " << getClassName()
23385f757f3fSDimitry Andric      << "::runCustomAction(unsigned, const MatcherState&, NewMIVector &) const "
23395f757f3fSDimitry Andric         "{\n"
234006c3fb27SDimitry Andric      << "    llvm_unreachable(\"" + getClassName() +
234106c3fb27SDimitry Andric             " does not support custom C++ actions!\");\n"
234206c3fb27SDimitry Andric      << "}\n";
23430b57cec5SDimitry Andric }
23440b57cec5SDimitry Andric 
postProcessRule(RuleMatcher & M)23455f757f3fSDimitry Andric void GlobalISelEmitter::postProcessRule(RuleMatcher &M) {
23465f757f3fSDimitry Andric   SmallPtrSet<Record *, 16> UsedRegs;
23475f757f3fSDimitry Andric 
23485f757f3fSDimitry Andric   // TODO: deal with subregs?
23495f757f3fSDimitry Andric   for (auto &A : M.actions()) {
23505f757f3fSDimitry Andric     auto *MI = dyn_cast<BuildMIAction>(A.get());
23515f757f3fSDimitry Andric     if (!MI)
23525f757f3fSDimitry Andric       continue;
23535f757f3fSDimitry Andric 
23545f757f3fSDimitry Andric     for (auto *Use : MI->getCGI()->ImplicitUses)
23555f757f3fSDimitry Andric       UsedRegs.insert(Use);
23565f757f3fSDimitry Andric   }
23575f757f3fSDimitry Andric 
23585f757f3fSDimitry Andric   for (auto &A : M.actions()) {
23595f757f3fSDimitry Andric     auto *MI = dyn_cast<BuildMIAction>(A.get());
23605f757f3fSDimitry Andric     if (!MI)
23615f757f3fSDimitry Andric       continue;
23625f757f3fSDimitry Andric 
23635f757f3fSDimitry Andric     for (auto *Def : MI->getCGI()->ImplicitDefs) {
23645f757f3fSDimitry Andric       if (!UsedRegs.contains(Def))
23655f757f3fSDimitry Andric         MI->setDeadImplicitDef(Def);
23665f757f3fSDimitry Andric     }
23675f757f3fSDimitry Andric   }
23685f757f3fSDimitry Andric }
23695f757f3fSDimitry Andric 
run(raw_ostream & OS)23700b57cec5SDimitry Andric void GlobalISelEmitter::run(raw_ostream &OS) {
23710b57cec5SDimitry Andric   if (!UseCoverageFile.empty()) {
23720b57cec5SDimitry Andric     RuleCoverage = CodeGenCoverage();
23730b57cec5SDimitry Andric     auto RuleCoverageBufOrErr = MemoryBuffer::getFile(UseCoverageFile);
23740b57cec5SDimitry Andric     if (!RuleCoverageBufOrErr) {
23750b57cec5SDimitry Andric       PrintWarning(SMLoc(), "Missing rule coverage data");
2376bdd1243dSDimitry Andric       RuleCoverage = std::nullopt;
23770b57cec5SDimitry Andric     } else {
23780b57cec5SDimitry Andric       if (!RuleCoverage->parse(*RuleCoverageBufOrErr.get(), Target.getName())) {
23790b57cec5SDimitry Andric         PrintWarning(SMLoc(), "Ignoring invalid or missing rule coverage data");
2380bdd1243dSDimitry Andric         RuleCoverage = std::nullopt;
23810b57cec5SDimitry Andric       }
23820b57cec5SDimitry Andric     }
23830b57cec5SDimitry Andric   }
23840b57cec5SDimitry Andric 
23850b57cec5SDimitry Andric   // Track the run-time opcode values
23860b57cec5SDimitry Andric   gatherOpcodeValues();
23870b57cec5SDimitry Andric   // Track the run-time LLT ID values
23880b57cec5SDimitry Andric   gatherTypeIDValues();
23890b57cec5SDimitry Andric 
23900b57cec5SDimitry Andric   // Track the GINodeEquiv definitions.
23910b57cec5SDimitry Andric   gatherNodeEquivs();
23920b57cec5SDimitry Andric 
239306c3fb27SDimitry Andric   AllPatFrags = RK.getAllDerivedDefinitions("PatFrags");
239406c3fb27SDimitry Andric 
239506c3fb27SDimitry Andric   emitSourceFileHeader(
239606c3fb27SDimitry Andric       ("Global Instruction Selector for the " + Target.getName() + " target")
239706c3fb27SDimitry Andric           .str(),
239806c3fb27SDimitry Andric       OS);
23990b57cec5SDimitry Andric   std::vector<RuleMatcher> Rules;
24000b57cec5SDimitry Andric   // Look through the SelectionDAG patterns we found, possibly emitting some.
24010b57cec5SDimitry Andric   for (const PatternToMatch &Pat : CGP.ptms()) {
24020b57cec5SDimitry Andric     ++NumPatternTotal;
24030b57cec5SDimitry Andric 
24040b57cec5SDimitry Andric     auto MatcherOrErr = runOnPattern(Pat);
24050b57cec5SDimitry Andric 
24060b57cec5SDimitry Andric     // The pattern analysis can fail, indicating an unsupported pattern.
24070b57cec5SDimitry Andric     // Report that if we've been asked to do so.
24080b57cec5SDimitry Andric     if (auto Err = MatcherOrErr.takeError()) {
24090b57cec5SDimitry Andric       if (WarnOnSkippedPatterns) {
24100b57cec5SDimitry Andric         PrintWarning(Pat.getSrcRecord()->getLoc(),
24110b57cec5SDimitry Andric                      "Skipped pattern: " + toString(std::move(Err)));
24120b57cec5SDimitry Andric       } else {
24130b57cec5SDimitry Andric         consumeError(std::move(Err));
24140b57cec5SDimitry Andric       }
24150b57cec5SDimitry Andric       ++NumPatternImportsSkipped;
24160b57cec5SDimitry Andric       continue;
24170b57cec5SDimitry Andric     }
24180b57cec5SDimitry Andric 
24190b57cec5SDimitry Andric     if (RuleCoverage) {
24200b57cec5SDimitry Andric       if (RuleCoverage->isCovered(MatcherOrErr->getRuleID()))
24210b57cec5SDimitry Andric         ++NumPatternsTested;
24220b57cec5SDimitry Andric       else
24230b57cec5SDimitry Andric         PrintWarning(Pat.getSrcRecord()->getLoc(),
24240b57cec5SDimitry Andric                      "Pattern is not covered by a test");
24250b57cec5SDimitry Andric     }
24260b57cec5SDimitry Andric     Rules.push_back(std::move(MatcherOrErr.get()));
24275f757f3fSDimitry Andric     postProcessRule(Rules.back());
24280b57cec5SDimitry Andric   }
24290b57cec5SDimitry Andric 
24300b57cec5SDimitry Andric   // Comparison function to order records by name.
24310b57cec5SDimitry Andric   auto orderByName = [](const Record *A, const Record *B) {
24320b57cec5SDimitry Andric     return A->getName() < B->getName();
24330b57cec5SDimitry Andric   };
24340b57cec5SDimitry Andric 
24350b57cec5SDimitry Andric   std::vector<Record *> ComplexPredicates =
24360b57cec5SDimitry Andric       RK.getAllDerivedDefinitions("GIComplexOperandMatcher");
24370b57cec5SDimitry Andric   llvm::sort(ComplexPredicates, orderByName);
24380b57cec5SDimitry Andric 
2439fe6060f1SDimitry Andric   std::vector<StringRef> CustomRendererFns;
2440fe6060f1SDimitry Andric   transform(RK.getAllDerivedDefinitions("GICustomOperandRenderer"),
2441fe6060f1SDimitry Andric             std::back_inserter(CustomRendererFns), [](const auto &Record) {
2442fe6060f1SDimitry Andric               return Record->getValueAsString("RendererFn");
2443fe6060f1SDimitry Andric             });
2444fe6060f1SDimitry Andric   // Sort and remove duplicates to get a list of unique renderer functions, in
2445fe6060f1SDimitry Andric   // case some were mentioned more than once.
2446fe6060f1SDimitry Andric   llvm::sort(CustomRendererFns);
2447fe6060f1SDimitry Andric   CustomRendererFns.erase(
2448fe6060f1SDimitry Andric       std::unique(CustomRendererFns.begin(), CustomRendererFns.end()),
2449fe6060f1SDimitry Andric       CustomRendererFns.end());
24500b57cec5SDimitry Andric 
245106c3fb27SDimitry Andric   // Create a table containing the LLT objects needed by the matcher and an enum
24520b57cec5SDimitry Andric   // for the matcher to reference them with.
24530b57cec5SDimitry Andric   std::vector<LLTCodeGen> TypeObjects;
2454e8d8bef9SDimitry Andric   append_range(TypeObjects, KnownTypes);
24550b57cec5SDimitry Andric   llvm::sort(TypeObjects);
24560b57cec5SDimitry Andric 
245706c3fb27SDimitry Andric   // Sort rules.
24580b57cec5SDimitry Andric   llvm::stable_sort(Rules, [&](const RuleMatcher &A, const RuleMatcher &B) {
24590b57cec5SDimitry Andric     int ScoreA = RuleMatcherScores[A.getRuleID()];
24600b57cec5SDimitry Andric     int ScoreB = RuleMatcherScores[B.getRuleID()];
24610b57cec5SDimitry Andric     if (ScoreA > ScoreB)
24620b57cec5SDimitry Andric       return true;
24630b57cec5SDimitry Andric     if (ScoreB > ScoreA)
24640b57cec5SDimitry Andric       return false;
24650b57cec5SDimitry Andric     if (A.isHigherPriorityThan(B)) {
24660b57cec5SDimitry Andric       assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
24670b57cec5SDimitry Andric                                            "and less important at "
24680b57cec5SDimitry Andric                                            "the same time");
24690b57cec5SDimitry Andric       return true;
24700b57cec5SDimitry Andric     }
24710b57cec5SDimitry Andric     return false;
24720b57cec5SDimitry Andric   });
24730b57cec5SDimitry Andric 
247406c3fb27SDimitry Andric   unsigned MaxTemporaries = 0;
247506c3fb27SDimitry Andric   for (const auto &Rule : Rules)
247606c3fb27SDimitry Andric     MaxTemporaries = std::max(MaxTemporaries, Rule.countRendererFns());
24770b57cec5SDimitry Andric 
247806c3fb27SDimitry Andric   // Build match table
24790b57cec5SDimitry Andric   const MatchTable Table =
24800b57cec5SDimitry Andric       buildMatchTable(Rules, OptimizeMatchTable, GenerateCoverage);
24810b57cec5SDimitry Andric 
248206c3fb27SDimitry Andric   emitPredicateBitset(OS, "GET_GLOBALISEL_PREDICATE_BITSET");
248306c3fb27SDimitry Andric   emitTemporariesDecl(OS, "GET_GLOBALISEL_TEMPORARIES_DECL");
248406c3fb27SDimitry Andric   emitTemporariesInit(OS, MaxTemporaries, "GET_GLOBALISEL_TEMPORARIES_INIT");
248506c3fb27SDimitry Andric   emitExecutorImpl(OS, Table, TypeObjects, Rules, ComplexPredicates,
248606c3fb27SDimitry Andric                    CustomRendererFns, "GET_GLOBALISEL_IMPL");
248706c3fb27SDimitry Andric   emitPredicatesDecl(OS, "GET_GLOBALISEL_PREDICATES_DECL");
248806c3fb27SDimitry Andric   emitPredicatesInit(OS, "GET_GLOBALISEL_PREDICATES_INIT");
24890b57cec5SDimitry Andric }
24900b57cec5SDimitry Andric 
declareSubtargetFeature(Record * Predicate)24910b57cec5SDimitry Andric void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {
24925f757f3fSDimitry Andric   SubtargetFeatures.try_emplace(Predicate, Predicate, SubtargetFeatures.size());
24935f757f3fSDimitry Andric }
24945f757f3fSDimitry Andric 
declareHwModeCheck(StringRef HwModeFeatures)24955f757f3fSDimitry Andric unsigned GlobalISelEmitter::declareHwModeCheck(StringRef HwModeFeatures) {
24965f757f3fSDimitry Andric   return HwModes.emplace(HwModeFeatures.str(), HwModes.size()).first->second;
24970b57cec5SDimitry Andric }
24980b57cec5SDimitry Andric 
24990b57cec5SDimitry Andric } // end anonymous namespace
25000b57cec5SDimitry Andric 
25010b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
25020b57cec5SDimitry Andric 
250306c3fb27SDimitry Andric static TableGen::Emitter::OptClass<GlobalISelEmitter>
250406c3fb27SDimitry Andric     X("gen-global-isel", "Generate GlobalISel selector");
2505