xref: /freebsd-src/contrib/llvm-project/llvm/utils/TableGen/GlobalISelEmitter.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1*0fca6ea1SDimitry Andric 
20b57cec5SDimitry Andric //===- GlobalISelEmitter.cpp - Generate an instruction selector -----------===//
30b57cec5SDimitry Andric //
40b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric //
80b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric //
100b57cec5SDimitry Andric /// \file
110b57cec5SDimitry Andric /// This tablegen backend emits code for use by the GlobalISel instruction
1206c3fb27SDimitry Andric /// selector. See include/llvm/Target/GlobalISel/Target.td.
130b57cec5SDimitry Andric ///
140b57cec5SDimitry Andric /// This file analyzes the patterns recognized by the SelectionDAGISel tablegen
150b57cec5SDimitry Andric /// backend, filters out the ones that are unsupported, maps
160b57cec5SDimitry Andric /// SelectionDAG-specific constructs to their GlobalISel counterpart
170b57cec5SDimitry Andric /// (when applicable: MVT to LLT;  SDNode to generic Instruction).
180b57cec5SDimitry Andric ///
190b57cec5SDimitry Andric /// Not all patterns are supported: pass the tablegen invocation
200b57cec5SDimitry Andric /// "-warn-on-skipped-patterns" to emit a warning when a pattern is skipped,
210b57cec5SDimitry Andric /// as well as why.
220b57cec5SDimitry Andric ///
230b57cec5SDimitry Andric /// The generated file defines a single method:
240b57cec5SDimitry Andric ///     bool <Target>InstructionSelector::selectImpl(MachineInstr &I) const;
250b57cec5SDimitry Andric /// intended to be used in InstructionSelector::select as the first-step
260b57cec5SDimitry Andric /// selector for the patterns that don't require complex C++.
270b57cec5SDimitry Andric ///
280b57cec5SDimitry Andric /// FIXME: We'll probably want to eventually define a base
290b57cec5SDimitry Andric /// "TargetGenInstructionSelector" class.
300b57cec5SDimitry Andric ///
310b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
320b57cec5SDimitry Andric 
33*0fca6ea1SDimitry Andric #include "Basic/CodeGenIntrinsics.h"
34*0fca6ea1SDimitry Andric #include "Common/CodeGenDAGPatterns.h"
35*0fca6ea1SDimitry Andric #include "Common/CodeGenInstruction.h"
36*0fca6ea1SDimitry Andric #include "Common/CodeGenRegisters.h"
37*0fca6ea1SDimitry Andric #include "Common/CodeGenTarget.h"
38*0fca6ea1SDimitry Andric #include "Common/GlobalISel/GlobalISelMatchTable.h"
39*0fca6ea1SDimitry Andric #include "Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.h"
40*0fca6ea1SDimitry Andric #include "Common/InfoByHwMode.h"
41*0fca6ea1SDimitry Andric #include "Common/SubtargetFeatureInfo.h"
420b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
43*0fca6ea1SDimitry Andric #include "llvm/CodeGenTypes/LowLevelType.h"
44*0fca6ea1SDimitry Andric #include "llvm/CodeGenTypes/MachineValueType.h"
450b57cec5SDimitry Andric #include "llvm/Support/CodeGenCoverage.h"
460b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
470b57cec5SDimitry Andric #include "llvm/Support/Error.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 <string>
5306c3fb27SDimitry Andric 
540b57cec5SDimitry Andric using namespace llvm;
5506c3fb27SDimitry Andric using namespace llvm::gi;
5606c3fb27SDimitry Andric 
5706c3fb27SDimitry Andric using action_iterator = RuleMatcher::action_iterator;
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric #define DEBUG_TYPE "gisel-emitter"
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric STATISTIC(NumPatternTotal, "Total number of patterns");
620b57cec5SDimitry Andric STATISTIC(NumPatternImported, "Number of patterns imported from SelectionDAG");
630b57cec5SDimitry Andric STATISTIC(NumPatternImportsSkipped, "Number of SelectionDAG imports skipped");
6406c3fb27SDimitry Andric STATISTIC(NumPatternsTested,
6506c3fb27SDimitry Andric           "Number of patterns executed according to coverage information");
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric cl::OptionCategory GlobalISelEmitterCat("Options for -gen-global-isel");
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric static cl::opt<bool> WarnOnSkippedPatterns(
700b57cec5SDimitry Andric     "warn-on-skipped-patterns",
710b57cec5SDimitry Andric     cl::desc("Explain why a pattern was skipped for inclusion "
720b57cec5SDimitry Andric              "in the GlobalISel selector"),
730b57cec5SDimitry Andric     cl::init(false), cl::cat(GlobalISelEmitterCat));
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric static cl::opt<bool> GenerateCoverage(
760b57cec5SDimitry Andric     "instrument-gisel-coverage",
770b57cec5SDimitry Andric     cl::desc("Generate coverage instrumentation for GlobalISel"),
780b57cec5SDimitry Andric     cl::init(false), cl::cat(GlobalISelEmitterCat));
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric static cl::opt<std::string> UseCoverageFile(
810b57cec5SDimitry Andric     "gisel-coverage-file", cl::init(""),
820b57cec5SDimitry Andric     cl::desc("Specify file to retrieve coverage information from"),
830b57cec5SDimitry Andric     cl::cat(GlobalISelEmitterCat));
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric static cl::opt<bool> OptimizeMatchTable(
860b57cec5SDimitry Andric     "optimize-match-table",
870b57cec5SDimitry Andric     cl::desc("Generate an optimized version of the match table"),
880b57cec5SDimitry Andric     cl::init(true), cl::cat(GlobalISelEmitterCat));
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric namespace {
910b57cec5SDimitry Andric 
92*0fca6ea1SDimitry Andric static std::string explainPredicates(const TreePatternNode &N) {
93e8d8bef9SDimitry Andric   std::string Explanation;
940b57cec5SDimitry Andric   StringRef Separator = "";
95*0fca6ea1SDimitry Andric   for (const TreePredicateCall &Call : N.getPredicateCalls()) {
960b57cec5SDimitry Andric     const TreePredicateFn &P = Call.Fn;
970b57cec5SDimitry Andric     Explanation +=
980b57cec5SDimitry Andric         (Separator + P.getOrigPatFragRecord()->getRecord()->getName()).str();
990b57cec5SDimitry Andric     Separator = ", ";
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric     if (P.isAlwaysTrue())
1020b57cec5SDimitry Andric       Explanation += " always-true";
1030b57cec5SDimitry Andric     if (P.isImmediatePattern())
1040b57cec5SDimitry Andric       Explanation += " immediate";
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric     if (P.isUnindexed())
1070b57cec5SDimitry Andric       Explanation += " unindexed";
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric     if (P.isNonExtLoad())
1100b57cec5SDimitry Andric       Explanation += " non-extload";
1110b57cec5SDimitry Andric     if (P.isAnyExtLoad())
1120b57cec5SDimitry Andric       Explanation += " extload";
1130b57cec5SDimitry Andric     if (P.isSignExtLoad())
1140b57cec5SDimitry Andric       Explanation += " sextload";
1150b57cec5SDimitry Andric     if (P.isZeroExtLoad())
1160b57cec5SDimitry Andric       Explanation += " zextload";
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric     if (P.isNonTruncStore())
1190b57cec5SDimitry Andric       Explanation += " non-truncstore";
1200b57cec5SDimitry Andric     if (P.isTruncStore())
1210b57cec5SDimitry Andric       Explanation += " truncstore";
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric     if (Record *VT = P.getMemoryVT())
1240b57cec5SDimitry Andric       Explanation += (" MemVT=" + VT->getName()).str();
1250b57cec5SDimitry Andric     if (Record *VT = P.getScalarMemoryVT())
1260b57cec5SDimitry Andric       Explanation += (" ScalarVT(MemVT)=" + VT->getName()).str();
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric     if (ListInit *AddrSpaces = P.getAddressSpaces()) {
1290b57cec5SDimitry Andric       raw_string_ostream OS(Explanation);
1300b57cec5SDimitry Andric       OS << " AddressSpaces=[";
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric       StringRef AddrSpaceSeparator;
1330b57cec5SDimitry Andric       for (Init *Val : AddrSpaces->getValues()) {
1340b57cec5SDimitry Andric         IntInit *IntVal = dyn_cast<IntInit>(Val);
1350b57cec5SDimitry Andric         if (!IntVal)
1360b57cec5SDimitry Andric           continue;
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric         OS << AddrSpaceSeparator << IntVal->getValue();
1390b57cec5SDimitry Andric         AddrSpaceSeparator = ", ";
1400b57cec5SDimitry Andric       }
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric       OS << ']';
1430b57cec5SDimitry Andric     }
1440b57cec5SDimitry Andric 
1458bcb0991SDimitry Andric     int64_t MinAlign = P.getMinAlignment();
1468bcb0991SDimitry Andric     if (MinAlign > 0)
1478bcb0991SDimitry Andric       Explanation += " MinAlign=" + utostr(MinAlign);
1488bcb0991SDimitry Andric 
1490b57cec5SDimitry Andric     if (P.isAtomicOrderingMonotonic())
1500b57cec5SDimitry Andric       Explanation += " monotonic";
1510b57cec5SDimitry Andric     if (P.isAtomicOrderingAcquire())
1520b57cec5SDimitry Andric       Explanation += " acquire";
1530b57cec5SDimitry Andric     if (P.isAtomicOrderingRelease())
1540b57cec5SDimitry Andric       Explanation += " release";
1550b57cec5SDimitry Andric     if (P.isAtomicOrderingAcquireRelease())
1560b57cec5SDimitry Andric       Explanation += " acq_rel";
1570b57cec5SDimitry Andric     if (P.isAtomicOrderingSequentiallyConsistent())
1580b57cec5SDimitry Andric       Explanation += " seq_cst";
1590b57cec5SDimitry Andric     if (P.isAtomicOrderingAcquireOrStronger())
1600b57cec5SDimitry Andric       Explanation += " >=acquire";
1610b57cec5SDimitry Andric     if (P.isAtomicOrderingWeakerThanAcquire())
1620b57cec5SDimitry Andric       Explanation += " <acquire";
1630b57cec5SDimitry Andric     if (P.isAtomicOrderingReleaseOrStronger())
1640b57cec5SDimitry Andric       Explanation += " >=release";
1650b57cec5SDimitry Andric     if (P.isAtomicOrderingWeakerThanRelease())
1660b57cec5SDimitry Andric       Explanation += " <release";
1670b57cec5SDimitry Andric   }
1680b57cec5SDimitry Andric   return Explanation;
1690b57cec5SDimitry Andric }
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric std::string explainOperator(Record *Operator) {
1720b57cec5SDimitry Andric   if (Operator->isSubClassOf("SDNode"))
1730b57cec5SDimitry Andric     return (" (" + Operator->getValueAsString("Opcode") + ")").str();
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric   if (Operator->isSubClassOf("Intrinsic"))
1760b57cec5SDimitry Andric     return (" (Operator is an Intrinsic, " + Operator->getName() + ")").str();
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric   if (Operator->isSubClassOf("ComplexPattern"))
1790b57cec5SDimitry Andric     return (" (Operator is an unmapped ComplexPattern, " + Operator->getName() +
1800b57cec5SDimitry Andric             ")")
1810b57cec5SDimitry Andric         .str();
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric   if (Operator->isSubClassOf("SDNodeXForm"))
1840b57cec5SDimitry Andric     return (" (Operator is an unmapped SDNodeXForm, " + Operator->getName() +
1850b57cec5SDimitry Andric             ")")
1860b57cec5SDimitry Andric         .str();
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric   return (" (Operator " + Operator->getName() + " not understood)").str();
1890b57cec5SDimitry Andric }
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric /// Helper function to let the emitter report skip reason error messages.
1920b57cec5SDimitry Andric static Error failedImport(const Twine &Reason) {
1930b57cec5SDimitry Andric   return make_error<StringError>(Reason, inconvertibleErrorCode());
1940b57cec5SDimitry Andric }
1950b57cec5SDimitry Andric 
196*0fca6ea1SDimitry Andric static Error isTrivialOperatorNode(const TreePatternNode &N) {
197e8d8bef9SDimitry Andric   std::string Explanation;
198e8d8bef9SDimitry Andric   std::string Separator;
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric   bool HasUnsupportedPredicate = false;
201*0fca6ea1SDimitry Andric   for (const TreePredicateCall &Call : N.getPredicateCalls()) {
2020b57cec5SDimitry Andric     const TreePredicateFn &Predicate = Call.Fn;
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric     if (Predicate.isAlwaysTrue())
2050b57cec5SDimitry Andric       continue;
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric     if (Predicate.isImmediatePattern())
2080b57cec5SDimitry Andric       continue;
2090b57cec5SDimitry Andric 
210*0fca6ea1SDimitry Andric     if (Predicate.hasNoUse() || Predicate.hasOneUse())
211753f127fSDimitry Andric       continue;
212753f127fSDimitry Andric 
2130b57cec5SDimitry Andric     if (Predicate.isNonExtLoad() || Predicate.isAnyExtLoad() ||
2140b57cec5SDimitry Andric         Predicate.isSignExtLoad() || Predicate.isZeroExtLoad())
2150b57cec5SDimitry Andric       continue;
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric     if (Predicate.isNonTruncStore() || Predicate.isTruncStore())
2180b57cec5SDimitry Andric       continue;
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric     if (Predicate.isLoad() && Predicate.getMemoryVT())
2210b57cec5SDimitry Andric       continue;
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric     if (Predicate.isLoad() || Predicate.isStore()) {
2240b57cec5SDimitry Andric       if (Predicate.isUnindexed())
2250b57cec5SDimitry Andric         continue;
2260b57cec5SDimitry Andric     }
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric     if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {
2290b57cec5SDimitry Andric       const ListInit *AddrSpaces = Predicate.getAddressSpaces();
2300b57cec5SDimitry Andric       if (AddrSpaces && !AddrSpaces->empty())
2310b57cec5SDimitry Andric         continue;
2328bcb0991SDimitry Andric 
2338bcb0991SDimitry Andric       if (Predicate.getMinAlignment() > 0)
2348bcb0991SDimitry Andric         continue;
2350b57cec5SDimitry Andric     }
2360b57cec5SDimitry Andric 
2370b57cec5SDimitry Andric     if (Predicate.isAtomic() && Predicate.getMemoryVT())
2380b57cec5SDimitry Andric       continue;
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric     if (Predicate.isAtomic() &&
2410b57cec5SDimitry Andric         (Predicate.isAtomicOrderingMonotonic() ||
2420b57cec5SDimitry Andric          Predicate.isAtomicOrderingAcquire() ||
2430b57cec5SDimitry Andric          Predicate.isAtomicOrderingRelease() ||
2440b57cec5SDimitry Andric          Predicate.isAtomicOrderingAcquireRelease() ||
2450b57cec5SDimitry Andric          Predicate.isAtomicOrderingSequentiallyConsistent() ||
2460b57cec5SDimitry Andric          Predicate.isAtomicOrderingAcquireOrStronger() ||
2470b57cec5SDimitry Andric          Predicate.isAtomicOrderingWeakerThanAcquire() ||
2480b57cec5SDimitry Andric          Predicate.isAtomicOrderingReleaseOrStronger() ||
2490b57cec5SDimitry Andric          Predicate.isAtomicOrderingWeakerThanRelease()))
2500b57cec5SDimitry Andric       continue;
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric     if (Predicate.hasGISelPredicateCode())
2530b57cec5SDimitry Andric       continue;
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric     HasUnsupportedPredicate = true;
2560b57cec5SDimitry Andric     Explanation = Separator + "Has a predicate (" + explainPredicates(N) + ")";
2570b57cec5SDimitry Andric     Separator = ", ";
2580b57cec5SDimitry Andric     Explanation += (Separator + "first-failing:" +
2590b57cec5SDimitry Andric                     Predicate.getOrigPatFragRecord()->getRecord()->getName())
2600b57cec5SDimitry Andric                        .str();
2610b57cec5SDimitry Andric     break;
2620b57cec5SDimitry Andric   }
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric   if (!HasUnsupportedPredicate)
2650b57cec5SDimitry Andric     return Error::success();
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric   return failedImport(Explanation);
2680b57cec5SDimitry Andric }
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric static Record *getInitValueAsRegClass(Init *V) {
2710b57cec5SDimitry Andric   if (DefInit *VDefInit = dyn_cast<DefInit>(V)) {
2720b57cec5SDimitry Andric     if (VDefInit->getDef()->isSubClassOf("RegisterOperand"))
2730b57cec5SDimitry Andric       return VDefInit->getDef()->getValueAsDef("RegClass");
2740b57cec5SDimitry Andric     if (VDefInit->getDef()->isSubClassOf("RegisterClass"))
2750b57cec5SDimitry Andric       return VDefInit->getDef();
2760b57cec5SDimitry Andric   }
2770b57cec5SDimitry Andric   return nullptr;
2780b57cec5SDimitry Andric }
2790b57cec5SDimitry Andric 
280e8d8bef9SDimitry Andric static std::string getScopedName(unsigned Scope, const std::string &Name) {
281e8d8bef9SDimitry Andric   return ("pred:" + Twine(Scope) + ":" + Name).str();
282e8d8bef9SDimitry Andric }
283e8d8bef9SDimitry Andric 
2845f757f3fSDimitry Andric static std::string getMangledRootDefName(StringRef DefOperandName) {
2855f757f3fSDimitry Andric   return ("DstI[" + DefOperandName + "]").str();
2865f757f3fSDimitry Andric }
2875f757f3fSDimitry Andric 
2880b57cec5SDimitry Andric //===- GlobalISelEmitter class --------------------------------------------===//
2890b57cec5SDimitry Andric 
290*0fca6ea1SDimitry Andric static Expected<LLTCodeGen> getInstResultType(const TreePatternNode &Dst,
291*0fca6ea1SDimitry Andric                                               const CodeGenTarget &Target) {
292*0fca6ea1SDimitry Andric   // While we allow more than one output (both implicit and explicit defs)
293*0fca6ea1SDimitry Andric   // below, we only expect one explicit def here.
294*0fca6ea1SDimitry Andric   assert(Dst.getOperator()->isSubClassOf("Instruction"));
295*0fca6ea1SDimitry Andric   CodeGenInstruction &InstInfo = Target.getInstruction(Dst.getOperator());
296*0fca6ea1SDimitry Andric   if (!InstInfo.Operands.NumDefs)
297*0fca6ea1SDimitry Andric     return failedImport("Dst pattern child needs a def");
2985ffd83dbSDimitry Andric 
299*0fca6ea1SDimitry Andric   ArrayRef<TypeSetByHwMode> ChildTypes = Dst.getExtTypes();
300*0fca6ea1SDimitry Andric   if (ChildTypes.size() < 1)
301*0fca6ea1SDimitry Andric     return failedImport("Dst pattern child has no result");
302*0fca6ea1SDimitry Andric 
303*0fca6ea1SDimitry Andric   // If there are multiple results, just take the first one (this is how
304*0fca6ea1SDimitry Andric   // SelectionDAG does it).
305bdd1243dSDimitry Andric   std::optional<LLTCodeGen> MaybeOpTy;
3065ffd83dbSDimitry Andric   if (ChildTypes.front().isMachineValueType()) {
30706c3fb27SDimitry Andric     MaybeOpTy = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
3085ffd83dbSDimitry Andric   }
3095ffd83dbSDimitry Andric 
3105ffd83dbSDimitry Andric   if (!MaybeOpTy)
3115ffd83dbSDimitry Andric     return failedImport("Dst operand has an unsupported type");
3125ffd83dbSDimitry Andric   return *MaybeOpTy;
3135ffd83dbSDimitry Andric }
3145ffd83dbSDimitry Andric 
31506c3fb27SDimitry Andric class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter {
3160b57cec5SDimitry Andric public:
3170b57cec5SDimitry Andric   explicit GlobalISelEmitter(RecordKeeper &RK);
31806c3fb27SDimitry Andric 
31906c3fb27SDimitry Andric   void emitAdditionalImpl(raw_ostream &OS) override;
32006c3fb27SDimitry Andric 
32106c3fb27SDimitry Andric   void emitMIPredicateFns(raw_ostream &OS) override;
32206c3fb27SDimitry Andric   void emitI64ImmPredicateFns(raw_ostream &OS) override;
32306c3fb27SDimitry Andric   void emitAPFloatImmPredicateFns(raw_ostream &OS) override;
32406c3fb27SDimitry Andric   void emitAPIntImmPredicateFns(raw_ostream &OS) override;
32506c3fb27SDimitry Andric   void emitTestSimplePredicate(raw_ostream &OS) override;
32606c3fb27SDimitry Andric   void emitRunCustomAction(raw_ostream &OS) override;
32706c3fb27SDimitry Andric 
3285f757f3fSDimitry Andric   void postProcessRule(RuleMatcher &M);
3295f757f3fSDimitry Andric 
33006c3fb27SDimitry Andric   const CodeGenTarget &getTarget() const override { return Target; }
33106c3fb27SDimitry Andric   StringRef getClassName() const override { return ClassName; }
33206c3fb27SDimitry Andric 
3330b57cec5SDimitry Andric   void run(raw_ostream &OS);
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric private:
33606c3fb27SDimitry Andric   std::string ClassName;
33706c3fb27SDimitry Andric 
3380b57cec5SDimitry Andric   const RecordKeeper &RK;
3390b57cec5SDimitry Andric   const CodeGenDAGPatterns CGP;
3400b57cec5SDimitry Andric   const CodeGenTarget &Target;
3415ffd83dbSDimitry Andric   CodeGenRegBank &CGRegs;
3420b57cec5SDimitry Andric 
34306c3fb27SDimitry Andric   std::vector<Record *> AllPatFrags;
34406c3fb27SDimitry Andric 
3450b57cec5SDimitry Andric   /// Keep track of the equivalence between SDNodes and Instruction by mapping
3460b57cec5SDimitry Andric   /// SDNodes to the GINodeEquiv mapping. We need to map to the GINodeEquiv to
3470b57cec5SDimitry Andric   /// check for attributes on the relation such as CheckMMOIsNonAtomic.
3480b57cec5SDimitry Andric   /// This is defined using 'GINodeEquiv' in the target description.
3490b57cec5SDimitry Andric   DenseMap<Record *, Record *> NodeEquivs;
3500b57cec5SDimitry Andric 
3510b57cec5SDimitry Andric   /// Keep track of the equivalence between ComplexPattern's and
3520b57cec5SDimitry Andric   /// GIComplexOperandMatcher. Map entries are specified by subclassing
3530b57cec5SDimitry Andric   /// GIComplexPatternEquiv.
3540b57cec5SDimitry Andric   DenseMap<const Record *, const Record *> ComplexPatternEquivs;
3550b57cec5SDimitry Andric 
3560b57cec5SDimitry Andric   /// Keep track of the equivalence between SDNodeXForm's and
3570b57cec5SDimitry Andric   /// GICustomOperandRenderer. Map entries are specified by subclassing
3580b57cec5SDimitry Andric   /// GISDNodeXFormEquiv.
3590b57cec5SDimitry Andric   DenseMap<const Record *, const Record *> SDNodeXFormEquivs;
3600b57cec5SDimitry Andric 
3610b57cec5SDimitry Andric   /// Keep track of Scores of PatternsToMatch similar to how the DAG does.
3620b57cec5SDimitry Andric   /// This adds compatibility for RuleMatchers to use this for ordering rules.
3630b57cec5SDimitry Andric   DenseMap<uint64_t, int> RuleMatcherScores;
3640b57cec5SDimitry Andric 
3650b57cec5SDimitry Andric   // Rule coverage information.
366bdd1243dSDimitry Andric   std::optional<CodeGenCoverage> RuleCoverage;
3670b57cec5SDimitry Andric 
368e8d8bef9SDimitry Andric   /// Variables used to help with collecting of named operands for predicates
369e8d8bef9SDimitry Andric   /// with 'let PredicateCodeUsesOperands = 1'. WaitingForNamedOperands is set
370e8d8bef9SDimitry Andric   /// to the number of named operands that predicate expects. Store locations in
371e8d8bef9SDimitry Andric   /// StoreIdxForName correspond to the order in which operand names appear in
372e8d8bef9SDimitry Andric   /// predicate's argument list.
3735f757f3fSDimitry Andric   /// When we visit named operand and WaitingForNamedOperands is not zero, add
3745f757f3fSDimitry Andric   /// matcher that will record operand and decrease counter.
375e8d8bef9SDimitry Andric   unsigned WaitingForNamedOperands = 0;
376e8d8bef9SDimitry Andric   StringMap<unsigned> StoreIdxForName;
377e8d8bef9SDimitry Andric 
3780b57cec5SDimitry Andric   void gatherOpcodeValues();
3790b57cec5SDimitry Andric   void gatherTypeIDValues();
3800b57cec5SDimitry Andric   void gatherNodeEquivs();
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric   Record *findNodeEquiv(Record *N) const;
3830b57cec5SDimitry Andric   const CodeGenInstruction *getEquivNode(Record &Equiv,
384*0fca6ea1SDimitry Andric                                          const TreePatternNode &N) const;
3850b57cec5SDimitry Andric 
386fe6060f1SDimitry Andric   Error importRulePredicates(RuleMatcher &M, ArrayRef<Record *> Predicates);
3870b57cec5SDimitry Andric   Expected<InstructionMatcher &>
3880b57cec5SDimitry Andric   createAndImportSelDAGMatcher(RuleMatcher &Rule,
3890b57cec5SDimitry Andric                                InstructionMatcher &InsnMatcher,
390*0fca6ea1SDimitry Andric                                const TreePatternNode &Src, unsigned &TempOpIdx);
3910b57cec5SDimitry Andric   Error importComplexPatternOperandMatcher(OperandMatcher &OM, Record *R,
3920b57cec5SDimitry Andric                                            unsigned &TempOpIdx) const;
3930b57cec5SDimitry Andric   Error importChildMatcher(RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
394*0fca6ea1SDimitry Andric                            const TreePatternNode &SrcChild,
395480093f4SDimitry Andric                            bool OperandIsAPointer, bool OperandIsImmArg,
396480093f4SDimitry Andric                            unsigned OpIdx, unsigned &TempOpIdx);
3970b57cec5SDimitry Andric 
3988bcb0991SDimitry Andric   Expected<BuildMIAction &> createAndImportInstructionRenderer(
3998bcb0991SDimitry Andric       RuleMatcher &M, InstructionMatcher &InsnMatcher,
400*0fca6ea1SDimitry Andric       const TreePatternNode &Src, const TreePatternNode &Dst);
4010b57cec5SDimitry Andric   Expected<action_iterator> createAndImportSubInstructionRenderer(
402*0fca6ea1SDimitry Andric       action_iterator InsertPt, RuleMatcher &M, const TreePatternNode &Dst,
403*0fca6ea1SDimitry Andric       const TreePatternNode &Src, unsigned TempReg);
4040b57cec5SDimitry Andric   Expected<action_iterator>
4050b57cec5SDimitry Andric   createInstructionRenderer(action_iterator InsertPt, RuleMatcher &M,
406*0fca6ea1SDimitry Andric                             const TreePatternNode &Dst);
407e8d8bef9SDimitry Andric 
408*0fca6ea1SDimitry Andric   Expected<action_iterator>
409*0fca6ea1SDimitry Andric   importExplicitDefRenderers(action_iterator InsertPt, RuleMatcher &M,
410*0fca6ea1SDimitry Andric                              BuildMIAction &DstMIBuilder,
411*0fca6ea1SDimitry Andric                              const TreePatternNode &Src,
412*0fca6ea1SDimitry Andric                              const TreePatternNode &Dst, unsigned Start = 0);
4138bcb0991SDimitry Andric 
41406c3fb27SDimitry Andric   Expected<action_iterator> importExplicitUseRenderers(
41506c3fb27SDimitry Andric       action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
416*0fca6ea1SDimitry Andric       const llvm::TreePatternNode &Dst, const TreePatternNode &Src);
41706c3fb27SDimitry Andric   Expected<action_iterator> importExplicitUseRenderer(
41806c3fb27SDimitry Andric       action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
419*0fca6ea1SDimitry Andric       const TreePatternNode &DstChild, const TreePatternNode &Src);
4200b57cec5SDimitry Andric   Error importDefaultOperandRenderers(action_iterator InsertPt, RuleMatcher &M,
4210b57cec5SDimitry Andric                                       BuildMIAction &DstMIBuilder,
4225f757f3fSDimitry Andric                                       const DAGDefaultOperand &DefaultOp) const;
4230b57cec5SDimitry Andric   Error
4240b57cec5SDimitry Andric   importImplicitDefRenderers(BuildMIAction &DstMIBuilder,
4250b57cec5SDimitry Andric                              const std::vector<Record *> &ImplicitDefs) const;
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric   /// Analyze pattern \p P, returning a matcher for it if possible.
4280b57cec5SDimitry Andric   /// Otherwise, return an Error explaining why we don't support it.
4290b57cec5SDimitry Andric   Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric   void declareSubtargetFeature(Record *Predicate);
4320b57cec5SDimitry Andric 
4335f757f3fSDimitry Andric   unsigned declareHwModeCheck(StringRef HwModeFeatures);
4345f757f3fSDimitry Andric 
4350b57cec5SDimitry Andric   MatchTable buildMatchTable(MutableArrayRef<RuleMatcher> Rules, bool Optimize,
4360b57cec5SDimitry Andric                              bool WithCoverage);
4370b57cec5SDimitry Andric 
4388bcb0991SDimitry Andric   /// Infer a CodeGenRegisterClass for the type of \p SuperRegNode. The returned
4398bcb0991SDimitry Andric   /// CodeGenRegisterClass will support the CodeGenRegisterClass of
4408bcb0991SDimitry Andric   /// \p SubRegNode, and the subregister index defined by \p SubRegIdxNode.
441bdd1243dSDimitry Andric   /// If no register class is found, return std::nullopt.
442bdd1243dSDimitry Andric   std::optional<const CodeGenRegisterClass *>
4438bcb0991SDimitry Andric   inferSuperRegisterClassForNode(const TypeSetByHwMode &Ty,
444*0fca6ea1SDimitry Andric                                  const TreePatternNode &SuperRegNode,
445*0fca6ea1SDimitry Andric                                  const TreePatternNode &SubRegIdxNode);
446bdd1243dSDimitry Andric   std::optional<CodeGenSubRegIndex *>
447*0fca6ea1SDimitry Andric   inferSubRegIndexForNode(const TreePatternNode &SubRegIdxNode);
4488bcb0991SDimitry Andric 
4498bcb0991SDimitry Andric   /// Infer a CodeGenRegisterClass which suppoorts \p Ty and \p SubRegIdxNode.
450bdd1243dSDimitry Andric   /// Return std::nullopt if no such class exists.
451bdd1243dSDimitry Andric   std::optional<const CodeGenRegisterClass *>
4528bcb0991SDimitry Andric   inferSuperRegisterClass(const TypeSetByHwMode &Ty,
453*0fca6ea1SDimitry Andric                           const TreePatternNode &SubRegIdxNode);
4548bcb0991SDimitry Andric 
4558bcb0991SDimitry Andric   /// Return the CodeGenRegisterClass associated with \p Leaf if it has one.
456bdd1243dSDimitry Andric   std::optional<const CodeGenRegisterClass *>
457*0fca6ea1SDimitry Andric   getRegClassFromLeaf(const TreePatternNode &Leaf);
4588bcb0991SDimitry Andric 
459bdd1243dSDimitry Andric   /// Return a CodeGenRegisterClass for \p N if one can be found. Return
460bdd1243dSDimitry Andric   /// std::nullopt otherwise.
461bdd1243dSDimitry Andric   std::optional<const CodeGenRegisterClass *>
462*0fca6ea1SDimitry Andric   inferRegClassFromPattern(const TreePatternNode &N);
4638bcb0991SDimitry Andric 
464fe6060f1SDimitry Andric   /// Return the size of the MemoryVT in this predicate, if possible.
465bdd1243dSDimitry Andric   std::optional<unsigned>
466fe6060f1SDimitry Andric   getMemSizeBitsFromPredicate(const TreePredicateFn &Predicate);
467fe6060f1SDimitry Andric 
468e8d8bef9SDimitry Andric   // Add builtin predicates.
469e8d8bef9SDimitry Andric   Expected<InstructionMatcher &>
470e8d8bef9SDimitry Andric   addBuiltinPredicates(const Record *SrcGIEquivOrNull,
471e8d8bef9SDimitry Andric                        const TreePredicateFn &Predicate,
472e8d8bef9SDimitry Andric                        InstructionMatcher &InsnMatcher, bool &HasAddedMatcher);
4730b57cec5SDimitry Andric };
4740b57cec5SDimitry Andric 
47506c3fb27SDimitry Andric StringRef getPatFragPredicateEnumName(Record *R) { return R->getName(); }
47606c3fb27SDimitry Andric 
4770b57cec5SDimitry Andric void GlobalISelEmitter::gatherOpcodeValues() {
4780b57cec5SDimitry Andric   InstructionOpcodeMatcher::initOpcodeValuesMap(Target);
4790b57cec5SDimitry Andric }
4800b57cec5SDimitry Andric 
4810b57cec5SDimitry Andric void GlobalISelEmitter::gatherTypeIDValues() {
4820b57cec5SDimitry Andric   LLTOperandMatcher::initTypeIDValuesMap();
4830b57cec5SDimitry Andric }
4840b57cec5SDimitry Andric 
4850b57cec5SDimitry Andric void GlobalISelEmitter::gatherNodeEquivs() {
4860b57cec5SDimitry Andric   assert(NodeEquivs.empty());
4870b57cec5SDimitry Andric   for (Record *Equiv : RK.getAllDerivedDefinitions("GINodeEquiv"))
4880b57cec5SDimitry Andric     NodeEquivs[Equiv->getValueAsDef("Node")] = Equiv;
4890b57cec5SDimitry Andric 
4900b57cec5SDimitry Andric   assert(ComplexPatternEquivs.empty());
4910b57cec5SDimitry Andric   for (Record *Equiv : RK.getAllDerivedDefinitions("GIComplexPatternEquiv")) {
4920b57cec5SDimitry Andric     Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
4930b57cec5SDimitry Andric     if (!SelDAGEquiv)
4940b57cec5SDimitry Andric       continue;
4950b57cec5SDimitry Andric     ComplexPatternEquivs[SelDAGEquiv] = Equiv;
4960b57cec5SDimitry Andric   }
4970b57cec5SDimitry Andric 
4980b57cec5SDimitry Andric   assert(SDNodeXFormEquivs.empty());
4990b57cec5SDimitry Andric   for (Record *Equiv : RK.getAllDerivedDefinitions("GISDNodeXFormEquiv")) {
5000b57cec5SDimitry Andric     Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
5010b57cec5SDimitry Andric     if (!SelDAGEquiv)
5020b57cec5SDimitry Andric       continue;
5030b57cec5SDimitry Andric     SDNodeXFormEquivs[SelDAGEquiv] = Equiv;
5040b57cec5SDimitry Andric   }
5050b57cec5SDimitry Andric }
5060b57cec5SDimitry Andric 
5070b57cec5SDimitry Andric Record *GlobalISelEmitter::findNodeEquiv(Record *N) const {
5080b57cec5SDimitry Andric   return NodeEquivs.lookup(N);
5090b57cec5SDimitry Andric }
5100b57cec5SDimitry Andric 
5110b57cec5SDimitry Andric const CodeGenInstruction *
512*0fca6ea1SDimitry Andric GlobalISelEmitter::getEquivNode(Record &Equiv, const TreePatternNode &N) const {
513*0fca6ea1SDimitry Andric   if (N.getNumChildren() >= 1) {
5148bcb0991SDimitry Andric     // setcc operation maps to two different G_* instructions based on the type.
5158bcb0991SDimitry Andric     if (!Equiv.isValueUnset("IfFloatingPoint") &&
516*0fca6ea1SDimitry Andric         MVT(N.getChild(0).getSimpleType(0)).isFloatingPoint())
5178bcb0991SDimitry Andric       return &Target.getInstruction(Equiv.getValueAsDef("IfFloatingPoint"));
5188bcb0991SDimitry Andric   }
5198bcb0991SDimitry Andric 
5205f757f3fSDimitry Andric   if (!Equiv.isValueUnset("IfConvergent") &&
521*0fca6ea1SDimitry Andric       N.getIntrinsicInfo(CGP)->isConvergent)
5225f757f3fSDimitry Andric     return &Target.getInstruction(Equiv.getValueAsDef("IfConvergent"));
5235f757f3fSDimitry Andric 
524*0fca6ea1SDimitry Andric   for (const TreePredicateCall &Call : N.getPredicateCalls()) {
5250b57cec5SDimitry Andric     const TreePredicateFn &Predicate = Call.Fn;
526753f127fSDimitry Andric     if (!Equiv.isValueUnset("IfSignExtend") &&
527753f127fSDimitry Andric         (Predicate.isLoad() || Predicate.isAtomic()) &&
5280b57cec5SDimitry Andric         Predicate.isSignExtLoad())
5290b57cec5SDimitry Andric       return &Target.getInstruction(Equiv.getValueAsDef("IfSignExtend"));
530753f127fSDimitry Andric     if (!Equiv.isValueUnset("IfZeroExtend") &&
531753f127fSDimitry Andric         (Predicate.isLoad() || Predicate.isAtomic()) &&
5320b57cec5SDimitry Andric         Predicate.isZeroExtLoad())
5330b57cec5SDimitry Andric       return &Target.getInstruction(Equiv.getValueAsDef("IfZeroExtend"));
5340b57cec5SDimitry Andric   }
5358bcb0991SDimitry Andric 
5360b57cec5SDimitry Andric   return &Target.getInstruction(Equiv.getValueAsDef("I"));
5370b57cec5SDimitry Andric }
5380b57cec5SDimitry Andric 
5390b57cec5SDimitry Andric GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
54006c3fb27SDimitry Andric     : GlobalISelMatchTableExecutorEmitter(), RK(RK), CGP(RK),
54106c3fb27SDimitry Andric       Target(CGP.getTargetInfo()), CGRegs(Target.getRegBank()) {
54206c3fb27SDimitry Andric   ClassName = Target.getName().str() + "InstructionSelector";
54306c3fb27SDimitry Andric }
5440b57cec5SDimitry Andric 
5450b57cec5SDimitry Andric //===- Emitter ------------------------------------------------------------===//
5460b57cec5SDimitry Andric 
547fe6060f1SDimitry Andric Error GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
548fe6060f1SDimitry Andric                                               ArrayRef<Record *> Predicates) {
549fe6060f1SDimitry Andric   for (Record *Pred : Predicates) {
550fe6060f1SDimitry Andric     if (Pred->getValueAsString("CondString").empty())
5510b57cec5SDimitry Andric       continue;
552fe6060f1SDimitry Andric     declareSubtargetFeature(Pred);
553fe6060f1SDimitry Andric     M.addRequiredFeature(Pred);
5540b57cec5SDimitry Andric   }
5550b57cec5SDimitry Andric 
5560b57cec5SDimitry Andric   return Error::success();
5570b57cec5SDimitry Andric }
5580b57cec5SDimitry Andric 
559bdd1243dSDimitry Andric std::optional<unsigned> GlobalISelEmitter::getMemSizeBitsFromPredicate(
560bdd1243dSDimitry Andric     const TreePredicateFn &Predicate) {
561bdd1243dSDimitry Andric   std::optional<LLTCodeGen> MemTyOrNone =
562fe6060f1SDimitry Andric       MVTToLLT(getValueType(Predicate.getMemoryVT()));
563fe6060f1SDimitry Andric 
564fe6060f1SDimitry Andric   if (!MemTyOrNone)
565bdd1243dSDimitry Andric     return std::nullopt;
566fe6060f1SDimitry Andric 
567fe6060f1SDimitry Andric   // Align so unusual types like i1 don't get rounded down.
568fe6060f1SDimitry Andric   return llvm::alignTo(
569fe6060f1SDimitry Andric       static_cast<unsigned>(MemTyOrNone->get().getSizeInBits()), 8);
570fe6060f1SDimitry Andric }
571fe6060f1SDimitry Andric 
572e8d8bef9SDimitry Andric Expected<InstructionMatcher &> GlobalISelEmitter::addBuiltinPredicates(
573e8d8bef9SDimitry Andric     const Record *SrcGIEquivOrNull, const TreePredicateFn &Predicate,
574e8d8bef9SDimitry Andric     InstructionMatcher &InsnMatcher, bool &HasAddedMatcher) {
575e8d8bef9SDimitry Andric   if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {
576e8d8bef9SDimitry Andric     if (const ListInit *AddrSpaces = Predicate.getAddressSpaces()) {
577e8d8bef9SDimitry Andric       SmallVector<unsigned, 4> ParsedAddrSpaces;
578e8d8bef9SDimitry Andric 
579e8d8bef9SDimitry Andric       for (Init *Val : AddrSpaces->getValues()) {
580e8d8bef9SDimitry Andric         IntInit *IntVal = dyn_cast<IntInit>(Val);
581e8d8bef9SDimitry Andric         if (!IntVal)
582e8d8bef9SDimitry Andric           return failedImport("Address space is not an integer");
583e8d8bef9SDimitry Andric         ParsedAddrSpaces.push_back(IntVal->getValue());
584e8d8bef9SDimitry Andric       }
585e8d8bef9SDimitry Andric 
586e8d8bef9SDimitry Andric       if (!ParsedAddrSpaces.empty()) {
587e8d8bef9SDimitry Andric         InsnMatcher.addPredicate<MemoryAddressSpacePredicateMatcher>(
588e8d8bef9SDimitry Andric             0, ParsedAddrSpaces);
58981ad6265SDimitry Andric         return InsnMatcher;
590e8d8bef9SDimitry Andric       }
591e8d8bef9SDimitry Andric     }
592e8d8bef9SDimitry Andric 
593e8d8bef9SDimitry Andric     int64_t MinAlign = Predicate.getMinAlignment();
59481ad6265SDimitry Andric     if (MinAlign > 0) {
595e8d8bef9SDimitry Andric       InsnMatcher.addPredicate<MemoryAlignmentPredicateMatcher>(0, MinAlign);
59681ad6265SDimitry Andric       return InsnMatcher;
59781ad6265SDimitry Andric     }
598e8d8bef9SDimitry Andric   }
599e8d8bef9SDimitry Andric 
600e8d8bef9SDimitry Andric   // G_LOAD is used for both non-extending and any-extending loads.
601e8d8bef9SDimitry Andric   if (Predicate.isLoad() && Predicate.isNonExtLoad()) {
602e8d8bef9SDimitry Andric     InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
603e8d8bef9SDimitry Andric         0, MemoryVsLLTSizePredicateMatcher::EqualTo, 0);
604e8d8bef9SDimitry Andric     return InsnMatcher;
605e8d8bef9SDimitry Andric   }
606e8d8bef9SDimitry Andric   if (Predicate.isLoad() && Predicate.isAnyExtLoad()) {
607e8d8bef9SDimitry Andric     InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
608e8d8bef9SDimitry Andric         0, MemoryVsLLTSizePredicateMatcher::LessThan, 0);
609e8d8bef9SDimitry Andric     return InsnMatcher;
610e8d8bef9SDimitry Andric   }
611e8d8bef9SDimitry Andric 
612e8d8bef9SDimitry Andric   if (Predicate.isStore()) {
613e8d8bef9SDimitry Andric     if (Predicate.isTruncStore()) {
614fe6060f1SDimitry Andric       if (Predicate.getMemoryVT() != nullptr) {
615e8d8bef9SDimitry Andric         // FIXME: If MemoryVT is set, we end up with 2 checks for the MMO size.
616fe6060f1SDimitry Andric         auto MemSizeInBits = getMemSizeBitsFromPredicate(Predicate);
617fe6060f1SDimitry Andric         if (!MemSizeInBits)
618fe6060f1SDimitry Andric           return failedImport("MemVT could not be converted to LLT");
619fe6060f1SDimitry Andric 
620fe6060f1SDimitry Andric         InsnMatcher.addPredicate<MemorySizePredicateMatcher>(0, *MemSizeInBits /
621fe6060f1SDimitry Andric                                                                     8);
622fe6060f1SDimitry Andric       } else {
623e8d8bef9SDimitry Andric         InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
624e8d8bef9SDimitry Andric             0, MemoryVsLLTSizePredicateMatcher::LessThan, 0);
625fe6060f1SDimitry Andric       }
626e8d8bef9SDimitry Andric       return InsnMatcher;
627e8d8bef9SDimitry Andric     }
628e8d8bef9SDimitry Andric     if (Predicate.isNonTruncStore()) {
629e8d8bef9SDimitry Andric       // We need to check the sizes match here otherwise we could incorrectly
630e8d8bef9SDimitry Andric       // match truncating stores with non-truncating ones.
631e8d8bef9SDimitry Andric       InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
632e8d8bef9SDimitry Andric           0, MemoryVsLLTSizePredicateMatcher::EqualTo, 0);
633e8d8bef9SDimitry Andric     }
634e8d8bef9SDimitry Andric   }
635e8d8bef9SDimitry Andric 
63606c3fb27SDimitry Andric   assert(SrcGIEquivOrNull != nullptr && "Invalid SrcGIEquivOrNull value");
637e8d8bef9SDimitry Andric   // No check required. We already did it by swapping the opcode.
638e8d8bef9SDimitry Andric   if (!SrcGIEquivOrNull->isValueUnset("IfSignExtend") &&
639e8d8bef9SDimitry Andric       Predicate.isSignExtLoad())
640e8d8bef9SDimitry Andric     return InsnMatcher;
641e8d8bef9SDimitry Andric 
642e8d8bef9SDimitry Andric   // No check required. We already did it by swapping the opcode.
643e8d8bef9SDimitry Andric   if (!SrcGIEquivOrNull->isValueUnset("IfZeroExtend") &&
644e8d8bef9SDimitry Andric       Predicate.isZeroExtLoad())
645e8d8bef9SDimitry Andric     return InsnMatcher;
646e8d8bef9SDimitry Andric 
647e8d8bef9SDimitry Andric   // No check required. G_STORE by itself is a non-extending store.
648e8d8bef9SDimitry Andric   if (Predicate.isNonTruncStore())
649e8d8bef9SDimitry Andric     return InsnMatcher;
650e8d8bef9SDimitry Andric 
651e8d8bef9SDimitry Andric   if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {
652e8d8bef9SDimitry Andric     if (Predicate.getMemoryVT() != nullptr) {
653fe6060f1SDimitry Andric       auto MemSizeInBits = getMemSizeBitsFromPredicate(Predicate);
654fe6060f1SDimitry Andric       if (!MemSizeInBits)
655e8d8bef9SDimitry Andric         return failedImport("MemVT could not be converted to LLT");
656e8d8bef9SDimitry Andric 
657e8d8bef9SDimitry Andric       InsnMatcher.addPredicate<MemorySizePredicateMatcher>(0,
658fe6060f1SDimitry Andric                                                            *MemSizeInBits / 8);
659e8d8bef9SDimitry Andric       return InsnMatcher;
660e8d8bef9SDimitry Andric     }
661e8d8bef9SDimitry Andric   }
662e8d8bef9SDimitry Andric 
663e8d8bef9SDimitry Andric   if (Predicate.isLoad() || Predicate.isStore()) {
664e8d8bef9SDimitry Andric     // No check required. A G_LOAD/G_STORE is an unindexed load.
665e8d8bef9SDimitry Andric     if (Predicate.isUnindexed())
666e8d8bef9SDimitry Andric       return InsnMatcher;
667e8d8bef9SDimitry Andric   }
668e8d8bef9SDimitry Andric 
669e8d8bef9SDimitry Andric   if (Predicate.isAtomic()) {
670e8d8bef9SDimitry Andric     if (Predicate.isAtomicOrderingMonotonic()) {
671e8d8bef9SDimitry Andric       InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Monotonic");
672e8d8bef9SDimitry Andric       return InsnMatcher;
673e8d8bef9SDimitry Andric     }
674e8d8bef9SDimitry Andric     if (Predicate.isAtomicOrderingAcquire()) {
675e8d8bef9SDimitry Andric       InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Acquire");
676e8d8bef9SDimitry Andric       return InsnMatcher;
677e8d8bef9SDimitry Andric     }
678e8d8bef9SDimitry Andric     if (Predicate.isAtomicOrderingRelease()) {
679e8d8bef9SDimitry Andric       InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Release");
680e8d8bef9SDimitry Andric       return InsnMatcher;
681e8d8bef9SDimitry Andric     }
682e8d8bef9SDimitry Andric     if (Predicate.isAtomicOrderingAcquireRelease()) {
683e8d8bef9SDimitry Andric       InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
684e8d8bef9SDimitry Andric           "AcquireRelease");
685e8d8bef9SDimitry Andric       return InsnMatcher;
686e8d8bef9SDimitry Andric     }
687e8d8bef9SDimitry Andric     if (Predicate.isAtomicOrderingSequentiallyConsistent()) {
688e8d8bef9SDimitry Andric       InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
689e8d8bef9SDimitry Andric           "SequentiallyConsistent");
690e8d8bef9SDimitry Andric       return InsnMatcher;
691e8d8bef9SDimitry Andric     }
692e8d8bef9SDimitry Andric   }
693e8d8bef9SDimitry Andric 
694e8d8bef9SDimitry Andric   if (Predicate.isAtomicOrderingAcquireOrStronger()) {
695e8d8bef9SDimitry Andric     InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
696e8d8bef9SDimitry Andric         "Acquire", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
697e8d8bef9SDimitry Andric     return InsnMatcher;
698e8d8bef9SDimitry Andric   }
699e8d8bef9SDimitry Andric   if (Predicate.isAtomicOrderingWeakerThanAcquire()) {
700e8d8bef9SDimitry Andric     InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
701e8d8bef9SDimitry Andric         "Acquire", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);
702e8d8bef9SDimitry Andric     return InsnMatcher;
703e8d8bef9SDimitry Andric   }
704e8d8bef9SDimitry Andric 
705e8d8bef9SDimitry Andric   if (Predicate.isAtomicOrderingReleaseOrStronger()) {
706e8d8bef9SDimitry Andric     InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
707e8d8bef9SDimitry Andric         "Release", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
708e8d8bef9SDimitry Andric     return InsnMatcher;
709e8d8bef9SDimitry Andric   }
710e8d8bef9SDimitry Andric   if (Predicate.isAtomicOrderingWeakerThanRelease()) {
711e8d8bef9SDimitry Andric     InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
712e8d8bef9SDimitry Andric         "Release", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);
713e8d8bef9SDimitry Andric     return InsnMatcher;
714e8d8bef9SDimitry Andric   }
715e8d8bef9SDimitry Andric   HasAddedMatcher = false;
716e8d8bef9SDimitry Andric   return InsnMatcher;
717e8d8bef9SDimitry Andric }
718e8d8bef9SDimitry Andric 
7190b57cec5SDimitry Andric Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
7200b57cec5SDimitry Andric     RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
721*0fca6ea1SDimitry Andric     const TreePatternNode &Src, unsigned &TempOpIdx) {
722*0fca6ea1SDimitry Andric   const auto SavedFlags = Rule.setGISelFlags(Src.getGISelFlagsRecord());
72306c3fb27SDimitry Andric 
7240b57cec5SDimitry Andric   Record *SrcGIEquivOrNull = nullptr;
7250b57cec5SDimitry Andric   const CodeGenInstruction *SrcGIOrNull = nullptr;
7260b57cec5SDimitry Andric 
7270b57cec5SDimitry Andric   // Start with the defined operands (i.e., the results of the root operator).
728*0fca6ea1SDimitry Andric   if (Src.isLeaf()) {
729*0fca6ea1SDimitry Andric     Init *SrcInit = Src.getLeafValue();
7300b57cec5SDimitry Andric     if (isa<IntInit>(SrcInit)) {
7310b57cec5SDimitry Andric       InsnMatcher.addPredicate<InstructionOpcodeMatcher>(
7320b57cec5SDimitry Andric           &Target.getInstruction(RK.getDef("G_CONSTANT")));
7330b57cec5SDimitry Andric     } else
7340b57cec5SDimitry Andric       return failedImport(
7350b57cec5SDimitry Andric           "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
7360b57cec5SDimitry Andric   } else {
737*0fca6ea1SDimitry Andric     SrcGIEquivOrNull = findNodeEquiv(Src.getOperator());
7380b57cec5SDimitry Andric     if (!SrcGIEquivOrNull)
7390b57cec5SDimitry Andric       return failedImport("Pattern operator lacks an equivalent Instruction" +
740*0fca6ea1SDimitry Andric                           explainOperator(Src.getOperator()));
7410b57cec5SDimitry Andric     SrcGIOrNull = getEquivNode(*SrcGIEquivOrNull, Src);
7420b57cec5SDimitry Andric 
7430b57cec5SDimitry Andric     // The operators look good: match the opcode
7440b57cec5SDimitry Andric     InsnMatcher.addPredicate<InstructionOpcodeMatcher>(SrcGIOrNull);
7450b57cec5SDimitry Andric   }
7460b57cec5SDimitry Andric 
7470b57cec5SDimitry Andric   unsigned OpIdx = 0;
748*0fca6ea1SDimitry Andric   for (const TypeSetByHwMode &VTy : Src.getExtTypes()) {
7490b57cec5SDimitry Andric     // Results don't have a name unless they are the root node. The caller will
7500b57cec5SDimitry Andric     // set the name if appropriate.
751bdd1243dSDimitry Andric     const bool OperandIsAPointer =
752bdd1243dSDimitry Andric         SrcGIOrNull && SrcGIOrNull->isOutOperandAPointer(OpIdx);
7530b57cec5SDimitry Andric     OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
754bdd1243dSDimitry Andric     if (auto Error = OM.addTypeCheckPredicate(VTy, OperandIsAPointer))
7550b57cec5SDimitry Andric       return failedImport(toString(std::move(Error)) +
7560b57cec5SDimitry Andric                           " for result of Src pattern operator");
7570b57cec5SDimitry Andric   }
7580b57cec5SDimitry Andric 
759*0fca6ea1SDimitry Andric   for (const TreePredicateCall &Call : Src.getPredicateCalls()) {
7600b57cec5SDimitry Andric     const TreePredicateFn &Predicate = Call.Fn;
761e8d8bef9SDimitry Andric     bool HasAddedBuiltinMatcher = true;
7620b57cec5SDimitry Andric     if (Predicate.isAlwaysTrue())
7630b57cec5SDimitry Andric       continue;
7640b57cec5SDimitry Andric 
7650b57cec5SDimitry Andric     if (Predicate.isImmediatePattern()) {
7660b57cec5SDimitry Andric       InsnMatcher.addPredicate<InstructionImmPredicateMatcher>(Predicate);
7670b57cec5SDimitry Andric       continue;
7680b57cec5SDimitry Andric     }
7690b57cec5SDimitry Andric 
770e8d8bef9SDimitry Andric     auto InsnMatcherOrError = addBuiltinPredicates(
771e8d8bef9SDimitry Andric         SrcGIEquivOrNull, Predicate, InsnMatcher, HasAddedBuiltinMatcher);
772e8d8bef9SDimitry Andric     if (auto Error = InsnMatcherOrError.takeError())
773e8d8bef9SDimitry Andric       return std::move(Error);
7740b57cec5SDimitry Andric 
775753f127fSDimitry Andric     // FIXME: This should be part of addBuiltinPredicates(). If we add this at
776753f127fSDimitry Andric     // the start of addBuiltinPredicates() without returning, then there might
777753f127fSDimitry Andric     // be cases where we hit the last return before which the
778753f127fSDimitry Andric     // HasAddedBuiltinMatcher will be set to false. The predicate could be
779753f127fSDimitry Andric     // missed if we add it in the middle or at the end due to return statements
780753f127fSDimitry Andric     // after the addPredicate<>() calls.
781753f127fSDimitry Andric     if (Predicate.hasNoUse()) {
782753f127fSDimitry Andric       InsnMatcher.addPredicate<NoUsePredicateMatcher>();
783753f127fSDimitry Andric       HasAddedBuiltinMatcher = true;
784753f127fSDimitry Andric     }
785*0fca6ea1SDimitry Andric     if (Predicate.hasOneUse()) {
786*0fca6ea1SDimitry Andric       InsnMatcher.addPredicate<OneUsePredicateMatcher>();
787*0fca6ea1SDimitry Andric       HasAddedBuiltinMatcher = true;
788*0fca6ea1SDimitry Andric     }
789753f127fSDimitry Andric 
7900b57cec5SDimitry Andric     if (Predicate.hasGISelPredicateCode()) {
791e8d8bef9SDimitry Andric       if (Predicate.usesOperands()) {
792e8d8bef9SDimitry Andric         assert(WaitingForNamedOperands == 0 &&
793e8d8bef9SDimitry Andric                "previous predicate didn't find all operands or "
794e8d8bef9SDimitry Andric                "nested predicate that uses operands");
795e8d8bef9SDimitry Andric         TreePattern *TP = Predicate.getOrigPatFragRecord();
796e8d8bef9SDimitry Andric         WaitingForNamedOperands = TP->getNumArgs();
797*0fca6ea1SDimitry Andric         for (unsigned I = 0; I < WaitingForNamedOperands; ++I)
798*0fca6ea1SDimitry Andric           StoreIdxForName[getScopedName(Call.Scope, TP->getArgName(I))] = I;
799e8d8bef9SDimitry Andric       }
8000b57cec5SDimitry Andric       InsnMatcher.addPredicate<GenericInstructionPredicateMatcher>(Predicate);
8010b57cec5SDimitry Andric       continue;
8020b57cec5SDimitry Andric     }
803e8d8bef9SDimitry Andric     if (!HasAddedBuiltinMatcher) {
8040b57cec5SDimitry Andric       return failedImport("Src pattern child has predicate (" +
8050b57cec5SDimitry Andric                           explainPredicates(Src) + ")");
8060b57cec5SDimitry Andric     }
807e8d8bef9SDimitry Andric   }
808e8d8bef9SDimitry Andric 
80906c3fb27SDimitry Andric   if (SrcGIEquivOrNull &&
81006c3fb27SDimitry Andric       SrcGIEquivOrNull->getValueAsBit("CheckMMOIsNonAtomic"))
8110b57cec5SDimitry Andric     InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("NotAtomic");
81206c3fb27SDimitry Andric   else if (SrcGIEquivOrNull &&
81306c3fb27SDimitry Andric            SrcGIEquivOrNull->getValueAsBit("CheckMMOIsAtomic")) {
8148bcb0991SDimitry Andric     InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
8158bcb0991SDimitry Andric         "Unordered", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
8168bcb0991SDimitry Andric   }
8170b57cec5SDimitry Andric 
818*0fca6ea1SDimitry Andric   if (Src.isLeaf()) {
819*0fca6ea1SDimitry Andric     Init *SrcInit = Src.getLeafValue();
8200b57cec5SDimitry Andric     if (IntInit *SrcIntInit = dyn_cast<IntInit>(SrcInit)) {
8210b57cec5SDimitry Andric       OperandMatcher &OM =
822*0fca6ea1SDimitry Andric           InsnMatcher.addOperand(OpIdx++, Src.getName(), TempOpIdx);
8230b57cec5SDimitry Andric       OM.addPredicate<LiteralIntOperandMatcher>(SrcIntInit->getValue());
8240b57cec5SDimitry Andric     } else
8250b57cec5SDimitry Andric       return failedImport(
8260b57cec5SDimitry Andric           "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
8270b57cec5SDimitry Andric   } else {
8280b57cec5SDimitry Andric     assert(SrcGIOrNull &&
8290b57cec5SDimitry Andric            "Expected to have already found an equivalent Instruction");
8300b57cec5SDimitry Andric     if (SrcGIOrNull->TheDef->getName() == "G_CONSTANT" ||
8310b57cec5SDimitry Andric         SrcGIOrNull->TheDef->getName() == "G_FCONSTANT") {
8320b57cec5SDimitry Andric       // imm/fpimm still have operands but we don't need to do anything with it
8330b57cec5SDimitry Andric       // here since we don't support ImmLeaf predicates yet. However, we still
8340b57cec5SDimitry Andric       // need to note the hidden operand to get GIM_CheckNumOperands correct.
8350b57cec5SDimitry Andric       InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
8360b57cec5SDimitry Andric       return InsnMatcher;
8370b57cec5SDimitry Andric     }
8380b57cec5SDimitry Andric 
839*0fca6ea1SDimitry Andric     if (SrcGIOrNull->TheDef->getName() == "G_FRAME_INDEX") {
840*0fca6ea1SDimitry Andric       InsnMatcher.addOperand(OpIdx++, Src.getName(), TempOpIdx);
841*0fca6ea1SDimitry Andric       return InsnMatcher;
842*0fca6ea1SDimitry Andric     }
843*0fca6ea1SDimitry Andric 
8448bcb0991SDimitry Andric     // Special case because the operand order is changed from setcc. The
8458bcb0991SDimitry Andric     // predicate operand needs to be swapped from the last operand to the first
8468bcb0991SDimitry Andric     // source.
8478bcb0991SDimitry Andric 
848*0fca6ea1SDimitry Andric     unsigned NumChildren = Src.getNumChildren();
8498bcb0991SDimitry Andric     bool IsFCmp = SrcGIOrNull->TheDef->getName() == "G_FCMP";
8508bcb0991SDimitry Andric 
8518bcb0991SDimitry Andric     if (IsFCmp || SrcGIOrNull->TheDef->getName() == "G_ICMP") {
852*0fca6ea1SDimitry Andric       const TreePatternNode &SrcChild = Src.getChild(NumChildren - 1);
853*0fca6ea1SDimitry Andric       if (SrcChild.isLeaf()) {
854*0fca6ea1SDimitry Andric         DefInit *DI = dyn_cast<DefInit>(SrcChild.getLeafValue());
8558bcb0991SDimitry Andric         Record *CCDef = DI ? DI->getDef() : nullptr;
8568bcb0991SDimitry Andric         if (!CCDef || !CCDef->isSubClassOf("CondCode"))
8578bcb0991SDimitry Andric           return failedImport("Unable to handle CondCode");
8588bcb0991SDimitry Andric 
8598bcb0991SDimitry Andric         OperandMatcher &OM =
860*0fca6ea1SDimitry Andric             InsnMatcher.addOperand(OpIdx++, SrcChild.getName(), TempOpIdx);
86106c3fb27SDimitry Andric         StringRef PredType = IsFCmp ? CCDef->getValueAsString("FCmpPredicate")
86206c3fb27SDimitry Andric                                     : CCDef->getValueAsString("ICmpPredicate");
8638bcb0991SDimitry Andric 
8648bcb0991SDimitry Andric         if (!PredType.empty()) {
8655ffd83dbSDimitry Andric           OM.addPredicate<CmpPredicateOperandMatcher>(std::string(PredType));
8668bcb0991SDimitry Andric           // Process the other 2 operands normally.
8678bcb0991SDimitry Andric           --NumChildren;
8688bcb0991SDimitry Andric         }
8698bcb0991SDimitry Andric       }
8708bcb0991SDimitry Andric     }
8718bcb0991SDimitry Andric 
8720b57cec5SDimitry Andric     // Match the used operands (i.e. the children of the operator).
8738bcb0991SDimitry Andric     bool IsIntrinsic =
8748bcb0991SDimitry Andric         SrcGIOrNull->TheDef->getName() == "G_INTRINSIC" ||
8755f757f3fSDimitry Andric         SrcGIOrNull->TheDef->getName() == "G_INTRINSIC_W_SIDE_EFFECTS" ||
8765f757f3fSDimitry Andric         SrcGIOrNull->TheDef->getName() == "G_INTRINSIC_CONVERGENT" ||
8775f757f3fSDimitry Andric         SrcGIOrNull->TheDef->getName() ==
8785f757f3fSDimitry Andric             "G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS";
879*0fca6ea1SDimitry Andric     const CodeGenIntrinsic *II = Src.getIntrinsicInfo(CGP);
8808bcb0991SDimitry Andric     if (IsIntrinsic && !II)
8818bcb0991SDimitry Andric       return failedImport("Expected IntInit containing intrinsic ID)");
8828bcb0991SDimitry Andric 
883*0fca6ea1SDimitry Andric     for (unsigned I = 0; I != NumChildren; ++I) {
884*0fca6ea1SDimitry Andric       const TreePatternNode &SrcChild = Src.getChild(I);
8850b57cec5SDimitry Andric 
886480093f4SDimitry Andric       // We need to determine the meaning of a literal integer based on the
887480093f4SDimitry Andric       // context. If this is a field required to be an immediate (such as an
888480093f4SDimitry Andric       // immarg intrinsic argument), the required predicates are different than
889480093f4SDimitry Andric       // a constant which may be materialized in a register. If we have an
890480093f4SDimitry Andric       // argument that is required to be an immediate, we should not emit an LLT
891480093f4SDimitry Andric       // type check, and should not be looking for a G_CONSTANT defined
892480093f4SDimitry Andric       // register.
893*0fca6ea1SDimitry Andric       bool OperandIsImmArg = SrcGIOrNull->isInOperandImmArg(I);
894480093f4SDimitry Andric 
8950b57cec5SDimitry Andric       // SelectionDAG allows pointers to be represented with iN since it doesn't
89606c3fb27SDimitry Andric       // distinguish between pointers and integers but they are different types
89706c3fb27SDimitry Andric       // in GlobalISel. Coerce integers to pointers to address space 0 if the
89806c3fb27SDimitry Andric       // context indicates a pointer.
899480093f4SDimitry Andric       //
900*0fca6ea1SDimitry Andric       bool OperandIsAPointer = SrcGIOrNull->isInOperandAPointer(I);
9010b57cec5SDimitry Andric 
9028bcb0991SDimitry Andric       if (IsIntrinsic) {
9030b57cec5SDimitry Andric         // For G_INTRINSIC/G_INTRINSIC_W_SIDE_EFFECTS, the operand immediately
9040b57cec5SDimitry Andric         // following the defs is an intrinsic ID.
905*0fca6ea1SDimitry Andric         if (I == 0) {
9060b57cec5SDimitry Andric           OperandMatcher &OM =
907*0fca6ea1SDimitry Andric               InsnMatcher.addOperand(OpIdx++, SrcChild.getName(), TempOpIdx);
9080b57cec5SDimitry Andric           OM.addPredicate<IntrinsicIDOperandMatcher>(II);
9090b57cec5SDimitry Andric           continue;
9100b57cec5SDimitry Andric         }
9110b57cec5SDimitry Andric 
912480093f4SDimitry Andric         // We have to check intrinsics for llvm_anyptr_ty and immarg parameters.
9138bcb0991SDimitry Andric         //
9148bcb0991SDimitry Andric         // Note that we have to look at the i-1th parameter, because we don't
9158bcb0991SDimitry Andric         // have the intrinsic ID in the intrinsic's parameter list.
916*0fca6ea1SDimitry Andric         OperandIsAPointer |= II->isParamAPointer(I - 1);
917*0fca6ea1SDimitry Andric         OperandIsImmArg |= II->isParamImmArg(I - 1);
9180b57cec5SDimitry Andric       }
9190b57cec5SDimitry Andric 
9200b57cec5SDimitry Andric       if (auto Error =
9210b57cec5SDimitry Andric               importChildMatcher(Rule, InsnMatcher, SrcChild, OperandIsAPointer,
922480093f4SDimitry Andric                                  OperandIsImmArg, OpIdx++, TempOpIdx))
9230b57cec5SDimitry Andric         return std::move(Error);
9240b57cec5SDimitry Andric     }
9250b57cec5SDimitry Andric   }
9260b57cec5SDimitry Andric 
9270b57cec5SDimitry Andric   return InsnMatcher;
9280b57cec5SDimitry Andric }
9290b57cec5SDimitry Andric 
9300b57cec5SDimitry Andric Error GlobalISelEmitter::importComplexPatternOperandMatcher(
9310b57cec5SDimitry Andric     OperandMatcher &OM, Record *R, unsigned &TempOpIdx) const {
9320b57cec5SDimitry Andric   const auto &ComplexPattern = ComplexPatternEquivs.find(R);
9330b57cec5SDimitry Andric   if (ComplexPattern == ComplexPatternEquivs.end())
9340b57cec5SDimitry Andric     return failedImport("SelectionDAG ComplexPattern (" + R->getName() +
9350b57cec5SDimitry Andric                         ") not mapped to GlobalISel");
9360b57cec5SDimitry Andric 
9370b57cec5SDimitry Andric   OM.addPredicate<ComplexPatternOperandMatcher>(OM, *ComplexPattern->second);
9380b57cec5SDimitry Andric   TempOpIdx++;
9390b57cec5SDimitry Andric   return Error::success();
9400b57cec5SDimitry Andric }
9410b57cec5SDimitry Andric 
9428bcb0991SDimitry Andric // Get the name to use for a pattern operand. For an anonymous physical register
9438bcb0991SDimitry Andric // input, this should use the register name.
944*0fca6ea1SDimitry Andric static StringRef getSrcChildName(const TreePatternNode &SrcChild,
9458bcb0991SDimitry Andric                                  Record *&PhysReg) {
946*0fca6ea1SDimitry Andric   StringRef SrcChildName = SrcChild.getName();
947*0fca6ea1SDimitry Andric   if (SrcChildName.empty() && SrcChild.isLeaf()) {
948*0fca6ea1SDimitry Andric     if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild.getLeafValue())) {
9498bcb0991SDimitry Andric       auto *ChildRec = ChildDefInit->getDef();
9508bcb0991SDimitry Andric       if (ChildRec->isSubClassOf("Register")) {
9518bcb0991SDimitry Andric         SrcChildName = ChildRec->getName();
9528bcb0991SDimitry Andric         PhysReg = ChildRec;
9538bcb0991SDimitry Andric       }
9548bcb0991SDimitry Andric     }
9558bcb0991SDimitry Andric   }
9568bcb0991SDimitry Andric 
9578bcb0991SDimitry Andric   return SrcChildName;
9588bcb0991SDimitry Andric }
9598bcb0991SDimitry Andric 
960480093f4SDimitry Andric Error GlobalISelEmitter::importChildMatcher(
961480093f4SDimitry Andric     RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
962*0fca6ea1SDimitry Andric     const TreePatternNode &SrcChild, bool OperandIsAPointer,
963480093f4SDimitry Andric     bool OperandIsImmArg, unsigned OpIdx, unsigned &TempOpIdx) {
9648bcb0991SDimitry Andric 
9658bcb0991SDimitry Andric   Record *PhysReg = nullptr;
966e8d8bef9SDimitry Andric   std::string SrcChildName = std::string(getSrcChildName(SrcChild, PhysReg));
967*0fca6ea1SDimitry Andric   if (!SrcChild.isLeaf() &&
968*0fca6ea1SDimitry Andric       SrcChild.getOperator()->isSubClassOf("ComplexPattern")) {
969e8d8bef9SDimitry Andric     // The "name" of a non-leaf complex pattern (MY_PAT $op1, $op2) is
970e8d8bef9SDimitry Andric     // "MY_PAT:op1:op2" and the ones with same "name" represent same operand.
971*0fca6ea1SDimitry Andric     std::string PatternName = std::string(SrcChild.getOperator()->getName());
972*0fca6ea1SDimitry Andric     for (unsigned I = 0; I < SrcChild.getNumChildren(); ++I) {
973e8d8bef9SDimitry Andric       PatternName += ":";
974*0fca6ea1SDimitry Andric       PatternName += SrcChild.getChild(I).getName();
975e8d8bef9SDimitry Andric     }
976e8d8bef9SDimitry Andric     SrcChildName = PatternName;
977e8d8bef9SDimitry Andric   }
9788bcb0991SDimitry Andric 
9795ffd83dbSDimitry Andric   OperandMatcher &OM =
980e8d8bef9SDimitry Andric       PhysReg ? InsnMatcher.addPhysRegInput(PhysReg, OpIdx, TempOpIdx)
981e8d8bef9SDimitry Andric               : InsnMatcher.addOperand(OpIdx, SrcChildName, TempOpIdx);
9820b57cec5SDimitry Andric   if (OM.isSameAsAnotherOperand())
9830b57cec5SDimitry Andric     return Error::success();
9840b57cec5SDimitry Andric 
985*0fca6ea1SDimitry Andric   ArrayRef<TypeSetByHwMode> ChildTypes = SrcChild.getExtTypes();
9860b57cec5SDimitry Andric   if (ChildTypes.size() != 1)
9870b57cec5SDimitry Andric     return failedImport("Src pattern child has multiple results");
9880b57cec5SDimitry Andric 
9890b57cec5SDimitry Andric   // Check MBB's before the type check since they are not a known type.
990*0fca6ea1SDimitry Andric   if (!SrcChild.isLeaf()) {
991*0fca6ea1SDimitry Andric     if (SrcChild.getOperator()->isSubClassOf("SDNode")) {
992*0fca6ea1SDimitry Andric       auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild.getOperator());
9930b57cec5SDimitry Andric       if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
9940b57cec5SDimitry Andric         OM.addPredicate<MBBOperandMatcher>();
9950b57cec5SDimitry Andric         return Error::success();
9960b57cec5SDimitry Andric       }
997*0fca6ea1SDimitry Andric       if (SrcChild.getOperator()->getName() == "timm") {
9988bcb0991SDimitry Andric         OM.addPredicate<ImmOperandMatcher>();
999fe6060f1SDimitry Andric 
1000fe6060f1SDimitry Andric         // Add predicates, if any
1001*0fca6ea1SDimitry Andric         for (const TreePredicateCall &Call : SrcChild.getPredicateCalls()) {
1002fe6060f1SDimitry Andric           const TreePredicateFn &Predicate = Call.Fn;
1003fe6060f1SDimitry Andric 
1004fe6060f1SDimitry Andric           // Only handle immediate patterns for now
1005fe6060f1SDimitry Andric           if (Predicate.isImmediatePattern()) {
1006fe6060f1SDimitry Andric             OM.addPredicate<OperandImmPredicateMatcher>(Predicate);
1007fe6060f1SDimitry Andric           }
1008fe6060f1SDimitry Andric         }
1009fe6060f1SDimitry Andric 
10108bcb0991SDimitry Andric         return Error::success();
10118bcb0991SDimitry Andric       }
10120b57cec5SDimitry Andric     }
10130b57cec5SDimitry Andric   }
10140b57cec5SDimitry Andric 
1015480093f4SDimitry Andric   // Immediate arguments have no meaningful type to check as they don't have
1016480093f4SDimitry Andric   // registers.
1017480093f4SDimitry Andric   if (!OperandIsImmArg) {
10180b57cec5SDimitry Andric     if (auto Error =
10190b57cec5SDimitry Andric             OM.addTypeCheckPredicate(ChildTypes.front(), OperandIsAPointer))
10200b57cec5SDimitry Andric       return failedImport(toString(std::move(Error)) + " for Src operand (" +
1021*0fca6ea1SDimitry Andric                           to_string(SrcChild) + ")");
1022480093f4SDimitry Andric   }
10230b57cec5SDimitry Andric 
10245f757f3fSDimitry Andric   // Try look up SrcChild for a (named) predicate operand if there is any.
10255f757f3fSDimitry Andric   if (WaitingForNamedOperands) {
1026*0fca6ea1SDimitry Andric     auto &ScopedNames = SrcChild.getNamesAsPredicateArg();
10275f757f3fSDimitry Andric     if (!ScopedNames.empty()) {
10285f757f3fSDimitry Andric       auto PA = ScopedNames.begin();
10295f757f3fSDimitry Andric       std::string Name = getScopedName(PA->getScope(), PA->getIdentifier());
10305f757f3fSDimitry Andric       OM.addPredicate<RecordNamedOperandMatcher>(StoreIdxForName[Name], Name);
10315f757f3fSDimitry Andric       --WaitingForNamedOperands;
10325f757f3fSDimitry Andric     }
10335f757f3fSDimitry Andric   }
10345f757f3fSDimitry Andric 
10350b57cec5SDimitry Andric   // Check for nested instructions.
1036*0fca6ea1SDimitry Andric   if (!SrcChild.isLeaf()) {
1037*0fca6ea1SDimitry Andric     if (SrcChild.getOperator()->isSubClassOf("ComplexPattern")) {
10380b57cec5SDimitry Andric       // When a ComplexPattern is used as an operator, it should do the same
10390b57cec5SDimitry Andric       // thing as when used as a leaf. However, the children of the operator
10400b57cec5SDimitry Andric       // name the sub-operands that make up the complex operand and we must
10410b57cec5SDimitry Andric       // prepare to reference them in the renderer too.
10420b57cec5SDimitry Andric       unsigned RendererID = TempOpIdx;
10430b57cec5SDimitry Andric       if (auto Error = importComplexPatternOperandMatcher(
1044*0fca6ea1SDimitry Andric               OM, SrcChild.getOperator(), TempOpIdx))
10450b57cec5SDimitry Andric         return Error;
10460b57cec5SDimitry Andric 
1047*0fca6ea1SDimitry Andric       for (unsigned I = 0, E = SrcChild.getNumChildren(); I != E; ++I) {
1048*0fca6ea1SDimitry Andric         auto &SubOperand = SrcChild.getChild(I);
1049*0fca6ea1SDimitry Andric         if (!SubOperand.getName().empty()) {
1050e8d8bef9SDimitry Andric           if (auto Error = Rule.defineComplexSubOperand(
1051*0fca6ea1SDimitry Andric                   SubOperand.getName(), SrcChild.getOperator(), RendererID, I,
1052e8d8bef9SDimitry Andric                   SrcChildName))
10530b57cec5SDimitry Andric             return Error;
10540b57cec5SDimitry Andric         }
10550b57cec5SDimitry Andric       }
10560b57cec5SDimitry Andric 
10570b57cec5SDimitry Andric       return Error::success();
10580b57cec5SDimitry Andric     }
10590b57cec5SDimitry Andric 
10600b57cec5SDimitry Andric     auto MaybeInsnOperand = OM.addPredicate<InstructionOperandMatcher>(
1061*0fca6ea1SDimitry Andric         InsnMatcher.getRuleMatcher(), SrcChild.getName());
106281ad6265SDimitry Andric     if (!MaybeInsnOperand) {
10630b57cec5SDimitry Andric       // This isn't strictly true. If the user were to provide exactly the same
10640b57cec5SDimitry Andric       // matchers as the original operand then we could allow it. However, it's
10650b57cec5SDimitry Andric       // simpler to not permit the redundant specification.
106606c3fb27SDimitry Andric       return failedImport(
106706c3fb27SDimitry Andric           "Nested instruction cannot be the same as another operand");
10680b57cec5SDimitry Andric     }
10690b57cec5SDimitry Andric 
10700b57cec5SDimitry Andric     // Map the node to a gMIR instruction.
10710b57cec5SDimitry Andric     InstructionOperandMatcher &InsnOperand = **MaybeInsnOperand;
10720b57cec5SDimitry Andric     auto InsnMatcherOrError = createAndImportSelDAGMatcher(
10730b57cec5SDimitry Andric         Rule, InsnOperand.getInsnMatcher(), SrcChild, TempOpIdx);
10740b57cec5SDimitry Andric     if (auto Error = InsnMatcherOrError.takeError())
10750b57cec5SDimitry Andric       return Error;
10760b57cec5SDimitry Andric 
10770b57cec5SDimitry Andric     return Error::success();
10780b57cec5SDimitry Andric   }
10790b57cec5SDimitry Andric 
1080*0fca6ea1SDimitry Andric   if (SrcChild.hasAnyPredicate())
10810b57cec5SDimitry Andric     return failedImport("Src pattern child has unsupported predicate");
10820b57cec5SDimitry Andric 
10830b57cec5SDimitry Andric   // Check for constant immediates.
1084*0fca6ea1SDimitry Andric   if (auto *ChildInt = dyn_cast<IntInit>(SrcChild.getLeafValue())) {
1085480093f4SDimitry Andric     if (OperandIsImmArg) {
1086480093f4SDimitry Andric       // Checks for argument directly in operand list
1087480093f4SDimitry Andric       OM.addPredicate<LiteralIntOperandMatcher>(ChildInt->getValue());
1088480093f4SDimitry Andric     } else {
1089480093f4SDimitry Andric       // Checks for materialized constant
10900b57cec5SDimitry Andric       OM.addPredicate<ConstantIntOperandMatcher>(ChildInt->getValue());
1091480093f4SDimitry Andric     }
10920b57cec5SDimitry Andric     return Error::success();
10930b57cec5SDimitry Andric   }
10940b57cec5SDimitry Andric 
10950b57cec5SDimitry Andric   // Check for def's like register classes or ComplexPattern's.
1096*0fca6ea1SDimitry Andric   if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild.getLeafValue())) {
10970b57cec5SDimitry Andric     auto *ChildRec = ChildDefInit->getDef();
10980b57cec5SDimitry Andric 
10990b57cec5SDimitry Andric     // Check for register classes.
11000b57cec5SDimitry Andric     if (ChildRec->isSubClassOf("RegisterClass") ||
11010b57cec5SDimitry Andric         ChildRec->isSubClassOf("RegisterOperand")) {
11020b57cec5SDimitry Andric       OM.addPredicate<RegisterBankOperandMatcher>(
11030b57cec5SDimitry Andric           Target.getRegisterClass(getInitValueAsRegClass(ChildDefInit)));
11040b57cec5SDimitry Andric       return Error::success();
11050b57cec5SDimitry Andric     }
11060b57cec5SDimitry Andric 
11078bcb0991SDimitry Andric     if (ChildRec->isSubClassOf("Register")) {
11088bcb0991SDimitry Andric       // This just be emitted as a copy to the specific register.
11098bcb0991SDimitry Andric       ValueTypeByHwMode VT = ChildTypes.front().getValueTypeByHwMode();
111006c3fb27SDimitry Andric       const CodeGenRegisterClass *RC =
111106c3fb27SDimitry Andric           CGRegs.getMinimalPhysRegClass(ChildRec, &VT);
11128bcb0991SDimitry Andric       if (!RC) {
11138bcb0991SDimitry Andric         return failedImport(
11148bcb0991SDimitry Andric             "Could not determine physical register class of pattern source");
11158bcb0991SDimitry Andric       }
11168bcb0991SDimitry Andric 
11178bcb0991SDimitry Andric       OM.addPredicate<RegisterBankOperandMatcher>(*RC);
11188bcb0991SDimitry Andric       return Error::success();
11198bcb0991SDimitry Andric     }
11208bcb0991SDimitry Andric 
11210b57cec5SDimitry Andric     // Check for ValueType.
11220b57cec5SDimitry Andric     if (ChildRec->isSubClassOf("ValueType")) {
11230b57cec5SDimitry Andric       // We already added a type check as standard practice so this doesn't need
11240b57cec5SDimitry Andric       // to do anything.
11250b57cec5SDimitry Andric       return Error::success();
11260b57cec5SDimitry Andric     }
11270b57cec5SDimitry Andric 
11280b57cec5SDimitry Andric     // Check for ComplexPattern's.
11290b57cec5SDimitry Andric     if (ChildRec->isSubClassOf("ComplexPattern"))
11300b57cec5SDimitry Andric       return importComplexPatternOperandMatcher(OM, ChildRec, TempOpIdx);
11310b57cec5SDimitry Andric 
11320b57cec5SDimitry Andric     if (ChildRec->isSubClassOf("ImmLeaf")) {
11330b57cec5SDimitry Andric       return failedImport(
11340b57cec5SDimitry Andric           "Src pattern child def is an unsupported tablegen class (ImmLeaf)");
11350b57cec5SDimitry Andric     }
11360b57cec5SDimitry Andric 
11375ffd83dbSDimitry Andric     // Place holder for SRCVALUE nodes. Nothing to do here.
11385ffd83dbSDimitry Andric     if (ChildRec->getName() == "srcvalue")
11395ffd83dbSDimitry Andric       return Error::success();
11405ffd83dbSDimitry Andric 
1141e8d8bef9SDimitry Andric     const bool ImmAllOnesV = ChildRec->getName() == "immAllOnesV";
1142e8d8bef9SDimitry Andric     if (ImmAllOnesV || ChildRec->getName() == "immAllZerosV") {
1143e8d8bef9SDimitry Andric       auto MaybeInsnOperand = OM.addPredicate<InstructionOperandMatcher>(
1144*0fca6ea1SDimitry Andric           InsnMatcher.getRuleMatcher(), SrcChild.getName(), false);
1145e8d8bef9SDimitry Andric       InstructionOperandMatcher &InsnOperand = **MaybeInsnOperand;
1146e8d8bef9SDimitry Andric 
1147e8d8bef9SDimitry Andric       ValueTypeByHwMode VTy = ChildTypes.front().getValueTypeByHwMode();
1148e8d8bef9SDimitry Andric 
114906c3fb27SDimitry Andric       const CodeGenInstruction &BuildVector =
115006c3fb27SDimitry Andric           Target.getInstruction(RK.getDef("G_BUILD_VECTOR"));
115106c3fb27SDimitry Andric       const CodeGenInstruction &BuildVectorTrunc =
115206c3fb27SDimitry Andric           Target.getInstruction(RK.getDef("G_BUILD_VECTOR_TRUNC"));
1153e8d8bef9SDimitry Andric 
1154e8d8bef9SDimitry Andric       // Treat G_BUILD_VECTOR as the canonical opcode, and G_BUILD_VECTOR_TRUNC
1155e8d8bef9SDimitry Andric       // as an alternative.
1156e8d8bef9SDimitry Andric       InsnOperand.getInsnMatcher().addPredicate<InstructionOpcodeMatcher>(
1157bdd1243dSDimitry Andric           ArrayRef({&BuildVector, &BuildVectorTrunc}));
1158e8d8bef9SDimitry Andric 
1159e8d8bef9SDimitry Andric       // TODO: Handle both G_BUILD_VECTOR and G_BUILD_VECTOR_TRUNC We could
1160e8d8bef9SDimitry Andric       // theoretically not emit any opcode check, but getOpcodeMatcher currently
1161e8d8bef9SDimitry Andric       // has to succeed.
1162e8d8bef9SDimitry Andric       OperandMatcher &OM =
1163e8d8bef9SDimitry Andric           InsnOperand.getInsnMatcher().addOperand(0, "", TempOpIdx);
1164e8d8bef9SDimitry Andric       if (auto Error =
1165e8d8bef9SDimitry Andric               OM.addTypeCheckPredicate(VTy, false /* OperandIsAPointer */))
1166e8d8bef9SDimitry Andric         return failedImport(toString(std::move(Error)) +
1167e8d8bef9SDimitry Andric                             " for result of Src pattern operator");
1168e8d8bef9SDimitry Andric 
1169e8d8bef9SDimitry Andric       InsnOperand.getInsnMatcher().addPredicate<VectorSplatImmPredicateMatcher>(
1170e8d8bef9SDimitry Andric           ImmAllOnesV ? VectorSplatImmPredicateMatcher::AllOnes
1171e8d8bef9SDimitry Andric                       : VectorSplatImmPredicateMatcher::AllZeros);
1172e8d8bef9SDimitry Andric       return Error::success();
1173e8d8bef9SDimitry Andric     }
1174e8d8bef9SDimitry Andric 
11750b57cec5SDimitry Andric     return failedImport(
11760b57cec5SDimitry Andric         "Src pattern child def is an unsupported tablegen class");
11770b57cec5SDimitry Andric   }
11780b57cec5SDimitry Andric 
11790b57cec5SDimitry Andric   return failedImport("Src pattern child is an unsupported kind");
11800b57cec5SDimitry Andric }
11810b57cec5SDimitry Andric 
11820b57cec5SDimitry Andric Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
11830b57cec5SDimitry Andric     action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
1184*0fca6ea1SDimitry Andric     const TreePatternNode &DstChild, const TreePatternNode &Src) {
11850b57cec5SDimitry Andric 
1186*0fca6ea1SDimitry Andric   const auto &SubOperand = Rule.getComplexSubOperand(DstChild.getName());
118781ad6265SDimitry Andric   if (SubOperand) {
11880b57cec5SDimitry Andric     DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
1189*0fca6ea1SDimitry Andric         *std::get<0>(*SubOperand), DstChild.getName(), std::get<1>(*SubOperand),
1190*0fca6ea1SDimitry Andric         std::get<2>(*SubOperand));
11910b57cec5SDimitry Andric     return InsertPt;
11920b57cec5SDimitry Andric   }
11930b57cec5SDimitry Andric 
1194*0fca6ea1SDimitry Andric   if (!DstChild.isLeaf()) {
1195*0fca6ea1SDimitry Andric     if (DstChild.getOperator()->isSubClassOf("SDNodeXForm")) {
1196*0fca6ea1SDimitry Andric       auto &Child = DstChild.getChild(0);
1197*0fca6ea1SDimitry Andric       auto I = SDNodeXFormEquivs.find(DstChild.getOperator());
11980b57cec5SDimitry Andric       if (I != SDNodeXFormEquivs.end()) {
1199*0fca6ea1SDimitry Andric         Record *XFormOpc = DstChild.getOperator()->getValueAsDef("Opcode");
1200480093f4SDimitry Andric         if (XFormOpc->getName() == "timm") {
1201480093f4SDimitry Andric           // If this is a TargetConstant, there won't be a corresponding
1202480093f4SDimitry Andric           // instruction to transform. Instead, this will refer directly to an
1203480093f4SDimitry Andric           // operand in an instruction's operand list.
1204480093f4SDimitry Andric           DstMIBuilder.addRenderer<CustomOperandRenderer>(*I->second,
1205*0fca6ea1SDimitry Andric                                                           Child.getName());
1206480093f4SDimitry Andric         } else {
1207*0fca6ea1SDimitry Andric           DstMIBuilder.addRenderer<CustomRenderer>(*I->second, Child.getName());
1208480093f4SDimitry Andric         }
1209480093f4SDimitry Andric 
12100b57cec5SDimitry Andric         return InsertPt;
12110b57cec5SDimitry Andric       }
1212*0fca6ea1SDimitry Andric       return failedImport("SDNodeXForm " + Child.getName() +
12130b57cec5SDimitry Andric                           " has no custom renderer");
12140b57cec5SDimitry Andric     }
12150b57cec5SDimitry Andric 
12160b57cec5SDimitry Andric     // We accept 'bb' here. It's an operator because BasicBlockSDNode isn't
12170b57cec5SDimitry Andric     // inline, but in MI it's just another operand.
1218*0fca6ea1SDimitry Andric     if (DstChild.getOperator()->isSubClassOf("SDNode")) {
1219*0fca6ea1SDimitry Andric       auto &ChildSDNI = CGP.getSDNodeInfo(DstChild.getOperator());
12200b57cec5SDimitry Andric       if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
1221*0fca6ea1SDimitry Andric         DstMIBuilder.addRenderer<CopyRenderer>(DstChild.getName());
12220b57cec5SDimitry Andric         return InsertPt;
12230b57cec5SDimitry Andric       }
12240b57cec5SDimitry Andric     }
12250b57cec5SDimitry Andric 
12260b57cec5SDimitry Andric     // Similarly, imm is an operator in TreePatternNode's view but must be
12270b57cec5SDimitry Andric     // rendered as operands.
12280b57cec5SDimitry Andric     // FIXME: The target should be able to choose sign-extended when appropriate
12290b57cec5SDimitry Andric     //        (e.g. on Mips).
1230*0fca6ea1SDimitry Andric     if (DstChild.getOperator()->getName() == "timm") {
1231*0fca6ea1SDimitry Andric       DstMIBuilder.addRenderer<CopyRenderer>(DstChild.getName());
12328bcb0991SDimitry Andric       return InsertPt;
1233*0fca6ea1SDimitry Andric     }
1234*0fca6ea1SDimitry Andric     if (DstChild.getOperator()->getName() == "tframeindex") {
1235*0fca6ea1SDimitry Andric       DstMIBuilder.addRenderer<CopyRenderer>(DstChild.getName());
12360b57cec5SDimitry Andric       return InsertPt;
1237*0fca6ea1SDimitry Andric     }
1238*0fca6ea1SDimitry Andric     if (DstChild.getOperator()->getName() == "imm") {
1239*0fca6ea1SDimitry Andric       DstMIBuilder.addRenderer<CopyConstantAsImmRenderer>(DstChild.getName());
1240*0fca6ea1SDimitry Andric       return InsertPt;
1241*0fca6ea1SDimitry Andric     }
1242*0fca6ea1SDimitry Andric     if (DstChild.getOperator()->getName() == "fpimm") {
12430b57cec5SDimitry Andric       DstMIBuilder.addRenderer<CopyFConstantAsFPImmRenderer>(
1244*0fca6ea1SDimitry Andric           DstChild.getName());
12450b57cec5SDimitry Andric       return InsertPt;
12460b57cec5SDimitry Andric     }
12470b57cec5SDimitry Andric 
1248*0fca6ea1SDimitry Andric     if (DstChild.getOperator()->isSubClassOf("Instruction")) {
1249*0fca6ea1SDimitry Andric       auto OpTy = getInstResultType(DstChild, Target);
12505ffd83dbSDimitry Andric       if (!OpTy)
12515ffd83dbSDimitry Andric         return OpTy.takeError();
12520b57cec5SDimitry Andric 
12530b57cec5SDimitry Andric       unsigned TempRegID = Rule.allocateTempRegID();
125406c3fb27SDimitry Andric       InsertPt =
125506c3fb27SDimitry Andric           Rule.insertAction<MakeTempRegisterAction>(InsertPt, *OpTy, TempRegID);
12560b57cec5SDimitry Andric       DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
12570b57cec5SDimitry Andric 
12580b57cec5SDimitry Andric       auto InsertPtOrError = createAndImportSubInstructionRenderer(
125906c3fb27SDimitry Andric           ++InsertPt, Rule, DstChild, Src, TempRegID);
12600b57cec5SDimitry Andric       if (auto Error = InsertPtOrError.takeError())
12610b57cec5SDimitry Andric         return std::move(Error);
12620b57cec5SDimitry Andric       return InsertPtOrError.get();
12630b57cec5SDimitry Andric     }
12640b57cec5SDimitry Andric 
126506c3fb27SDimitry Andric     return failedImport("Dst pattern child isn't a leaf node or an MBB" +
1266*0fca6ea1SDimitry Andric                         llvm::to_string(DstChild));
12670b57cec5SDimitry Andric   }
12680b57cec5SDimitry Andric 
12690b57cec5SDimitry Andric   // It could be a specific immediate in which case we should just check for
12700b57cec5SDimitry Andric   // that immediate.
12710b57cec5SDimitry Andric   if (const IntInit *ChildIntInit =
1272*0fca6ea1SDimitry Andric           dyn_cast<IntInit>(DstChild.getLeafValue())) {
12730b57cec5SDimitry Andric     DstMIBuilder.addRenderer<ImmRenderer>(ChildIntInit->getValue());
12740b57cec5SDimitry Andric     return InsertPt;
12750b57cec5SDimitry Andric   }
12760b57cec5SDimitry Andric 
12770b57cec5SDimitry Andric   // Otherwise, we're looking for a bog-standard RegisterClass operand.
1278*0fca6ea1SDimitry Andric   if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild.getLeafValue())) {
12790b57cec5SDimitry Andric     auto *ChildRec = ChildDefInit->getDef();
12800b57cec5SDimitry Andric 
1281*0fca6ea1SDimitry Andric     ArrayRef<TypeSetByHwMode> ChildTypes = DstChild.getExtTypes();
12820b57cec5SDimitry Andric     if (ChildTypes.size() != 1)
12830b57cec5SDimitry Andric       return failedImport("Dst pattern child has multiple results");
12840b57cec5SDimitry Andric 
1285bdd1243dSDimitry Andric     std::optional<LLTCodeGen> OpTyOrNone;
12860b57cec5SDimitry Andric     if (ChildTypes.front().isMachineValueType())
12870b57cec5SDimitry Andric       OpTyOrNone = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
12880b57cec5SDimitry Andric     if (!OpTyOrNone)
12890b57cec5SDimitry Andric       return failedImport("Dst operand has an unsupported type");
12900b57cec5SDimitry Andric 
12910b57cec5SDimitry Andric     if (ChildRec->isSubClassOf("Register")) {
1292e8d8bef9SDimitry Andric       DstMIBuilder.addRenderer<AddRegisterRenderer>(Target, ChildRec);
12930b57cec5SDimitry Andric       return InsertPt;
12940b57cec5SDimitry Andric     }
12950b57cec5SDimitry Andric 
12960b57cec5SDimitry Andric     if (ChildRec->isSubClassOf("RegisterClass") ||
12970b57cec5SDimitry Andric         ChildRec->isSubClassOf("RegisterOperand") ||
12980b57cec5SDimitry Andric         ChildRec->isSubClassOf("ValueType")) {
12990b57cec5SDimitry Andric       if (ChildRec->isSubClassOf("RegisterOperand") &&
13000b57cec5SDimitry Andric           !ChildRec->isValueUnset("GIZeroRegister")) {
13010b57cec5SDimitry Andric         DstMIBuilder.addRenderer<CopyOrAddZeroRegRenderer>(
1302*0fca6ea1SDimitry Andric             DstChild.getName(), ChildRec->getValueAsDef("GIZeroRegister"));
13030b57cec5SDimitry Andric         return InsertPt;
13040b57cec5SDimitry Andric       }
13050b57cec5SDimitry Andric 
1306*0fca6ea1SDimitry Andric       DstMIBuilder.addRenderer<CopyRenderer>(DstChild.getName());
13070b57cec5SDimitry Andric       return InsertPt;
13080b57cec5SDimitry Andric     }
13090b57cec5SDimitry Andric 
13108bcb0991SDimitry Andric     if (ChildRec->isSubClassOf("SubRegIndex")) {
13118bcb0991SDimitry Andric       CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(ChildRec);
13128bcb0991SDimitry Andric       DstMIBuilder.addRenderer<ImmRenderer>(SubIdx->EnumValue);
13138bcb0991SDimitry Andric       return InsertPt;
13148bcb0991SDimitry Andric     }
13158bcb0991SDimitry Andric 
13160b57cec5SDimitry Andric     if (ChildRec->isSubClassOf("ComplexPattern")) {
13170b57cec5SDimitry Andric       const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
13180b57cec5SDimitry Andric       if (ComplexPattern == ComplexPatternEquivs.end())
13190b57cec5SDimitry Andric         return failedImport(
13200b57cec5SDimitry Andric             "SelectionDAG ComplexPattern not mapped to GlobalISel");
13210b57cec5SDimitry Andric 
1322*0fca6ea1SDimitry Andric       const OperandMatcher &OM = Rule.getOperandMatcher(DstChild.getName());
13230b57cec5SDimitry Andric       DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
1324*0fca6ea1SDimitry Andric           *ComplexPattern->second, DstChild.getName(),
13250b57cec5SDimitry Andric           OM.getAllocatedTemporariesBaseID());
13260b57cec5SDimitry Andric       return InsertPt;
13270b57cec5SDimitry Andric     }
13280b57cec5SDimitry Andric 
13290b57cec5SDimitry Andric     return failedImport(
13300b57cec5SDimitry Andric         "Dst pattern child def is an unsupported tablegen class");
13310b57cec5SDimitry Andric   }
133206c3fb27SDimitry Andric 
133306c3fb27SDimitry Andric   // Handle the case where the MVT/register class is omitted in the dest pattern
133406c3fb27SDimitry Andric   // but MVT exists in the source pattern.
1335*0fca6ea1SDimitry Andric   if (isa<UnsetInit>(DstChild.getLeafValue())) {
1336*0fca6ea1SDimitry Andric     for (unsigned NumOp = 0; NumOp < Src.getNumChildren(); NumOp++)
1337*0fca6ea1SDimitry Andric       if (Src.getChild(NumOp).getName() == DstChild.getName()) {
1338*0fca6ea1SDimitry Andric         DstMIBuilder.addRenderer<CopyRenderer>(Src.getChild(NumOp).getName());
133906c3fb27SDimitry Andric         return InsertPt;
134006c3fb27SDimitry Andric       }
134106c3fb27SDimitry Andric   }
13420b57cec5SDimitry Andric   return failedImport("Dst pattern child is an unsupported kind");
13430b57cec5SDimitry Andric }
13440b57cec5SDimitry Andric 
13450b57cec5SDimitry Andric Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
1346*0fca6ea1SDimitry Andric     RuleMatcher &M, InstructionMatcher &InsnMatcher, const TreePatternNode &Src,
1347*0fca6ea1SDimitry Andric     const TreePatternNode &Dst) {
13480b57cec5SDimitry Andric   auto InsertPtOrError = createInstructionRenderer(M.actions_end(), M, Dst);
13490b57cec5SDimitry Andric   if (auto Error = InsertPtOrError.takeError())
13500b57cec5SDimitry Andric     return std::move(Error);
13510b57cec5SDimitry Andric 
13520b57cec5SDimitry Andric   action_iterator InsertPt = InsertPtOrError.get();
13530b57cec5SDimitry Andric   BuildMIAction &DstMIBuilder = *static_cast<BuildMIAction *>(InsertPt->get());
13540b57cec5SDimitry Andric 
13558bcb0991SDimitry Andric   for (auto PhysInput : InsnMatcher.getPhysRegInputs()) {
13568bcb0991SDimitry Andric     InsertPt = M.insertAction<BuildMIAction>(
13578bcb0991SDimitry Andric         InsertPt, M.allocateOutputInsnID(),
13588bcb0991SDimitry Andric         &Target.getInstruction(RK.getDef("COPY")));
13598bcb0991SDimitry Andric     BuildMIAction &CopyToPhysRegMIBuilder =
13608bcb0991SDimitry Andric         *static_cast<BuildMIAction *>(InsertPt->get());
136106c3fb27SDimitry Andric     CopyToPhysRegMIBuilder.addRenderer<AddRegisterRenderer>(
136206c3fb27SDimitry Andric         Target, PhysInput.first, true);
13638bcb0991SDimitry Andric     CopyToPhysRegMIBuilder.addRenderer<CopyPhysRegRenderer>(PhysInput.first);
13648bcb0991SDimitry Andric   }
13658bcb0991SDimitry Andric 
136606c3fb27SDimitry Andric   if (auto Error =
136706c3fb27SDimitry Andric           importExplicitDefRenderers(InsertPt, M, DstMIBuilder, Src, Dst)
1368e8d8bef9SDimitry Andric               .takeError())
1369e8d8bef9SDimitry Andric     return std::move(Error);
13700b57cec5SDimitry Andric 
137106c3fb27SDimitry Andric   if (auto Error =
137206c3fb27SDimitry Andric           importExplicitUseRenderers(InsertPt, M, DstMIBuilder, Dst, Src)
13730b57cec5SDimitry Andric               .takeError())
13740b57cec5SDimitry Andric     return std::move(Error);
13750b57cec5SDimitry Andric 
13760b57cec5SDimitry Andric   return DstMIBuilder;
13770b57cec5SDimitry Andric }
13780b57cec5SDimitry Andric 
13790b57cec5SDimitry Andric Expected<action_iterator>
13800b57cec5SDimitry Andric GlobalISelEmitter::createAndImportSubInstructionRenderer(
1381*0fca6ea1SDimitry Andric     const action_iterator InsertPt, RuleMatcher &M, const TreePatternNode &Dst,
1382*0fca6ea1SDimitry Andric     const TreePatternNode &Src, unsigned TempRegID) {
13830b57cec5SDimitry Andric   auto InsertPtOrError = createInstructionRenderer(InsertPt, M, Dst);
13840b57cec5SDimitry Andric 
13850b57cec5SDimitry Andric   // TODO: Assert there's exactly one result.
13860b57cec5SDimitry Andric 
13870b57cec5SDimitry Andric   if (auto Error = InsertPtOrError.takeError())
13880b57cec5SDimitry Andric     return std::move(Error);
13890b57cec5SDimitry Andric 
13900b57cec5SDimitry Andric   BuildMIAction &DstMIBuilder =
13910b57cec5SDimitry Andric       *static_cast<BuildMIAction *>(InsertPtOrError.get()->get());
13920b57cec5SDimitry Andric 
13930b57cec5SDimitry Andric   // Assign the result to TempReg.
13940b57cec5SDimitry Andric   DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, true);
13950b57cec5SDimitry Andric 
1396*0fca6ea1SDimitry Andric   // Handle additional (ignored) results.
1397*0fca6ea1SDimitry Andric   if (DstMIBuilder.getCGI()->Operands.NumDefs > 1) {
1398*0fca6ea1SDimitry Andric     InsertPtOrError = importExplicitDefRenderers(
1399*0fca6ea1SDimitry Andric         std::prev(*InsertPtOrError), M, DstMIBuilder, Src, Dst, /*Start=*/1);
1400*0fca6ea1SDimitry Andric     if (auto Error = InsertPtOrError.takeError())
1401*0fca6ea1SDimitry Andric       return std::move(Error);
1402*0fca6ea1SDimitry Andric   }
1403*0fca6ea1SDimitry Andric 
140406c3fb27SDimitry Andric   InsertPtOrError = importExplicitUseRenderers(InsertPtOrError.get(), M,
140506c3fb27SDimitry Andric                                                DstMIBuilder, Dst, Src);
14060b57cec5SDimitry Andric   if (auto Error = InsertPtOrError.takeError())
14070b57cec5SDimitry Andric     return std::move(Error);
14080b57cec5SDimitry Andric 
14098bcb0991SDimitry Andric   // We need to make sure that when we import an INSERT_SUBREG as a
14108bcb0991SDimitry Andric   // subinstruction that it ends up being constrained to the correct super
14118bcb0991SDimitry Andric   // register and subregister classes.
1412*0fca6ea1SDimitry Andric   auto OpName = Target.getInstruction(Dst.getOperator()).TheDef->getName();
14138bcb0991SDimitry Andric   if (OpName == "INSERT_SUBREG") {
1414*0fca6ea1SDimitry Andric     auto SubClass = inferRegClassFromPattern(Dst.getChild(1));
14158bcb0991SDimitry Andric     if (!SubClass)
14168bcb0991SDimitry Andric       return failedImport(
14178bcb0991SDimitry Andric           "Cannot infer register class from INSERT_SUBREG operand #1");
1418bdd1243dSDimitry Andric     std::optional<const CodeGenRegisterClass *> SuperClass =
1419*0fca6ea1SDimitry Andric         inferSuperRegisterClassForNode(Dst.getExtType(0), Dst.getChild(0),
1420*0fca6ea1SDimitry Andric                                        Dst.getChild(2));
14218bcb0991SDimitry Andric     if (!SuperClass)
14228bcb0991SDimitry Andric       return failedImport(
14238bcb0991SDimitry Andric           "Cannot infer register class for INSERT_SUBREG operand #0");
14248bcb0991SDimitry Andric     // The destination and the super register source of an INSERT_SUBREG must
14258bcb0991SDimitry Andric     // be the same register class.
14268bcb0991SDimitry Andric     M.insertAction<ConstrainOperandToRegClassAction>(
14278bcb0991SDimitry Andric         InsertPt, DstMIBuilder.getInsnID(), 0, **SuperClass);
14288bcb0991SDimitry Andric     M.insertAction<ConstrainOperandToRegClassAction>(
14298bcb0991SDimitry Andric         InsertPt, DstMIBuilder.getInsnID(), 1, **SuperClass);
14308bcb0991SDimitry Andric     M.insertAction<ConstrainOperandToRegClassAction>(
14318bcb0991SDimitry Andric         InsertPt, DstMIBuilder.getInsnID(), 2, **SubClass);
14328bcb0991SDimitry Andric     return InsertPtOrError.get();
14338bcb0991SDimitry Andric   }
14348bcb0991SDimitry Andric 
14358bcb0991SDimitry Andric   if (OpName == "EXTRACT_SUBREG") {
14368bcb0991SDimitry Andric     // EXTRACT_SUBREG selects into a subregister COPY but unlike most
14378bcb0991SDimitry Andric     // instructions, the result register class is controlled by the
14388bcb0991SDimitry Andric     // subregisters of the operand. As a result, we must constrain the result
14398bcb0991SDimitry Andric     // class rather than check that it's already the right one.
1440*0fca6ea1SDimitry Andric     auto SuperClass = inferRegClassFromPattern(Dst.getChild(0));
14418bcb0991SDimitry Andric     if (!SuperClass)
14428bcb0991SDimitry Andric       return failedImport(
14438bcb0991SDimitry Andric           "Cannot infer register class from EXTRACT_SUBREG operand #0");
14448bcb0991SDimitry Andric 
1445*0fca6ea1SDimitry Andric     auto SubIdx = inferSubRegIndexForNode(Dst.getChild(1));
14468bcb0991SDimitry Andric     if (!SubIdx)
14478bcb0991SDimitry Andric       return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
14488bcb0991SDimitry Andric 
14495ffd83dbSDimitry Andric     const auto SrcRCDstRCPair =
14508bcb0991SDimitry Andric         (*SuperClass)->getMatchingSubClassWithSubRegs(CGRegs, *SubIdx);
14518bcb0991SDimitry Andric     assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
14528bcb0991SDimitry Andric     M.insertAction<ConstrainOperandToRegClassAction>(
14538bcb0991SDimitry Andric         InsertPt, DstMIBuilder.getInsnID(), 0, *SrcRCDstRCPair->second);
14548bcb0991SDimitry Andric     M.insertAction<ConstrainOperandToRegClassAction>(
14558bcb0991SDimitry Andric         InsertPt, DstMIBuilder.getInsnID(), 1, *SrcRCDstRCPair->first);
14568bcb0991SDimitry Andric 
14578bcb0991SDimitry Andric     // We're done with this pattern!  It's eligible for GISel emission; return
14588bcb0991SDimitry Andric     // it.
14598bcb0991SDimitry Andric     return InsertPtOrError.get();
14608bcb0991SDimitry Andric   }
14618bcb0991SDimitry Andric 
14628bcb0991SDimitry Andric   // Similar to INSERT_SUBREG, we also have to handle SUBREG_TO_REG as a
14638bcb0991SDimitry Andric   // subinstruction.
14648bcb0991SDimitry Andric   if (OpName == "SUBREG_TO_REG") {
1465*0fca6ea1SDimitry Andric     auto SubClass = inferRegClassFromPattern(Dst.getChild(1));
14668bcb0991SDimitry Andric     if (!SubClass)
14678bcb0991SDimitry Andric       return failedImport(
14688bcb0991SDimitry Andric           "Cannot infer register class from SUBREG_TO_REG child #1");
146906c3fb27SDimitry Andric     auto SuperClass =
1470*0fca6ea1SDimitry Andric         inferSuperRegisterClass(Dst.getExtType(0), Dst.getChild(2));
14718bcb0991SDimitry Andric     if (!SuperClass)
14728bcb0991SDimitry Andric       return failedImport(
14738bcb0991SDimitry Andric           "Cannot infer register class for SUBREG_TO_REG operand #0");
14748bcb0991SDimitry Andric     M.insertAction<ConstrainOperandToRegClassAction>(
14758bcb0991SDimitry Andric         InsertPt, DstMIBuilder.getInsnID(), 0, **SuperClass);
14768bcb0991SDimitry Andric     M.insertAction<ConstrainOperandToRegClassAction>(
14778bcb0991SDimitry Andric         InsertPt, DstMIBuilder.getInsnID(), 2, **SubClass);
14788bcb0991SDimitry Andric     return InsertPtOrError.get();
14798bcb0991SDimitry Andric   }
14808bcb0991SDimitry Andric 
14815ffd83dbSDimitry Andric   if (OpName == "REG_SEQUENCE") {
1482*0fca6ea1SDimitry Andric     auto SuperClass = inferRegClassFromPattern(Dst.getChild(0));
14835ffd83dbSDimitry Andric     M.insertAction<ConstrainOperandToRegClassAction>(
14845ffd83dbSDimitry Andric         InsertPt, DstMIBuilder.getInsnID(), 0, **SuperClass);
14855ffd83dbSDimitry Andric 
1486*0fca6ea1SDimitry Andric     unsigned Num = Dst.getNumChildren();
14875ffd83dbSDimitry Andric     for (unsigned I = 1; I != Num; I += 2) {
1488*0fca6ea1SDimitry Andric       const TreePatternNode &SubRegChild = Dst.getChild(I + 1);
14895ffd83dbSDimitry Andric 
14905ffd83dbSDimitry Andric       auto SubIdx = inferSubRegIndexForNode(SubRegChild);
14915ffd83dbSDimitry Andric       if (!SubIdx)
14925ffd83dbSDimitry Andric         return failedImport("REG_SEQUENCE child is not a subreg index");
14935ffd83dbSDimitry Andric 
14945ffd83dbSDimitry Andric       const auto SrcRCDstRCPair =
14955ffd83dbSDimitry Andric           (*SuperClass)->getMatchingSubClassWithSubRegs(CGRegs, *SubIdx);
14965ffd83dbSDimitry Andric       assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
14975ffd83dbSDimitry Andric       M.insertAction<ConstrainOperandToRegClassAction>(
14985ffd83dbSDimitry Andric           InsertPt, DstMIBuilder.getInsnID(), I, *SrcRCDstRCPair->second);
14995ffd83dbSDimitry Andric     }
15005ffd83dbSDimitry Andric 
15015ffd83dbSDimitry Andric     return InsertPtOrError.get();
15025ffd83dbSDimitry Andric   }
15035ffd83dbSDimitry Andric 
15040b57cec5SDimitry Andric   M.insertAction<ConstrainOperandsToDefinitionAction>(InsertPt,
15050b57cec5SDimitry Andric                                                       DstMIBuilder.getInsnID());
15060b57cec5SDimitry Andric   return InsertPtOrError.get();
15070b57cec5SDimitry Andric }
15080b57cec5SDimitry Andric 
15090b57cec5SDimitry Andric Expected<action_iterator> GlobalISelEmitter::createInstructionRenderer(
1510*0fca6ea1SDimitry Andric     action_iterator InsertPt, RuleMatcher &M, const TreePatternNode &Dst) {
1511*0fca6ea1SDimitry Andric   Record *DstOp = Dst.getOperator();
15120b57cec5SDimitry Andric   if (!DstOp->isSubClassOf("Instruction")) {
15130b57cec5SDimitry Andric     if (DstOp->isSubClassOf("ValueType"))
15140b57cec5SDimitry Andric       return failedImport(
15150b57cec5SDimitry Andric           "Pattern operator isn't an instruction (it's a ValueType)");
15160b57cec5SDimitry Andric     return failedImport("Pattern operator isn't an instruction");
15170b57cec5SDimitry Andric   }
15180b57cec5SDimitry Andric   CodeGenInstruction *DstI = &Target.getInstruction(DstOp);
15190b57cec5SDimitry Andric 
15200b57cec5SDimitry Andric   // COPY_TO_REGCLASS is just a copy with a ConstrainOperandToRegClassAction
15210b57cec5SDimitry Andric   // attached. Similarly for EXTRACT_SUBREG except that's a subregister copy.
15228bcb0991SDimitry Andric   StringRef Name = DstI->TheDef->getName();
15238bcb0991SDimitry Andric   if (Name == "COPY_TO_REGCLASS" || Name == "EXTRACT_SUBREG")
15240b57cec5SDimitry Andric     DstI = &Target.getInstruction(RK.getDef("COPY"));
15250b57cec5SDimitry Andric 
15260b57cec5SDimitry Andric   return M.insertAction<BuildMIAction>(InsertPt, M.allocateOutputInsnID(),
15270b57cec5SDimitry Andric                                        DstI);
15280b57cec5SDimitry Andric }
15290b57cec5SDimitry Andric 
1530e8d8bef9SDimitry Andric Expected<action_iterator> GlobalISelEmitter::importExplicitDefRenderers(
1531e8d8bef9SDimitry Andric     action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
1532*0fca6ea1SDimitry Andric     const TreePatternNode &Src, const TreePatternNode &Dst, unsigned Start) {
15330b57cec5SDimitry Andric   const CodeGenInstruction *DstI = DstMIBuilder.getCGI();
1534*0fca6ea1SDimitry Andric   const unsigned SrcNumDefs = Src.getExtTypes().size();
153506c3fb27SDimitry Andric   const unsigned DstNumDefs = DstI->Operands.NumDefs;
153606c3fb27SDimitry Andric   if (DstNumDefs == 0)
1537e8d8bef9SDimitry Andric     return InsertPt;
1538e8d8bef9SDimitry Andric 
1539*0fca6ea1SDimitry Andric   for (unsigned I = Start; I < SrcNumDefs; ++I) {
15405f757f3fSDimitry Andric     std::string OpName = getMangledRootDefName(DstI->Operands[I].Name);
15415f757f3fSDimitry Andric     // CopyRenderer saves a StringRef, so cannot pass OpName itself -
15425f757f3fSDimitry Andric     // let's use a string with an appropriate lifetime.
15435f757f3fSDimitry Andric     StringRef PermanentRef = M.getOperandMatcher(OpName).getSymbolicName();
15445f757f3fSDimitry Andric     DstMIBuilder.addRenderer<CopyRenderer>(PermanentRef);
15455f757f3fSDimitry Andric   }
1546e8d8bef9SDimitry Andric 
1547e8d8bef9SDimitry Andric   // Some instructions have multiple defs, but are missing a type entry
1548e8d8bef9SDimitry Andric   // (e.g. s_cc_out operands).
1549*0fca6ea1SDimitry Andric   if (Dst.getExtTypes().size() < DstNumDefs)
1550e8d8bef9SDimitry Andric     return failedImport("unhandled discarded def");
1551e8d8bef9SDimitry Andric 
155206c3fb27SDimitry Andric   for (unsigned I = SrcNumDefs; I < DstNumDefs; ++I) {
1553*0fca6ea1SDimitry Andric     const TypeSetByHwMode &ExtTy = Dst.getExtType(I);
1554e8d8bef9SDimitry Andric     if (!ExtTy.isMachineValueType())
1555e8d8bef9SDimitry Andric       return failedImport("unsupported typeset");
1556e8d8bef9SDimitry Andric 
1557e8d8bef9SDimitry Andric     auto OpTy = MVTToLLT(ExtTy.getMachineValueType().SimpleTy);
1558e8d8bef9SDimitry Andric     if (!OpTy)
1559e8d8bef9SDimitry Andric       return failedImport("unsupported type");
1560e8d8bef9SDimitry Andric 
1561e8d8bef9SDimitry Andric     unsigned TempRegID = M.allocateTempRegID();
1562e8d8bef9SDimitry Andric     InsertPt =
1563e8d8bef9SDimitry Andric         M.insertAction<MakeTempRegisterAction>(InsertPt, *OpTy, TempRegID);
1564e8d8bef9SDimitry Andric     DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, true, nullptr, true);
15650b57cec5SDimitry Andric   }
1566e8d8bef9SDimitry Andric 
1567e8d8bef9SDimitry Andric   return InsertPt;
15680b57cec5SDimitry Andric }
15690b57cec5SDimitry Andric 
15700b57cec5SDimitry Andric Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
15710b57cec5SDimitry Andric     action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
1572*0fca6ea1SDimitry Andric     const llvm::TreePatternNode &Dst, const llvm::TreePatternNode &Src) {
15730b57cec5SDimitry Andric   const CodeGenInstruction *DstI = DstMIBuilder.getCGI();
1574*0fca6ea1SDimitry Andric   CodeGenInstruction *OrigDstI = &Target.getInstruction(Dst.getOperator());
15750b57cec5SDimitry Andric 
15768bcb0991SDimitry Andric   StringRef Name = OrigDstI->TheDef->getName();
1577*0fca6ea1SDimitry Andric   unsigned ExpectedDstINumUses = Dst.getNumChildren();
15788bcb0991SDimitry Andric 
15790b57cec5SDimitry Andric   // EXTRACT_SUBREG needs to use a subregister COPY.
15808bcb0991SDimitry Andric   if (Name == "EXTRACT_SUBREG") {
1581*0fca6ea1SDimitry Andric     if (!Dst.getChild(1).isLeaf())
1582e8d8bef9SDimitry Andric       return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
1583*0fca6ea1SDimitry Andric     DefInit *SubRegInit = dyn_cast<DefInit>(Dst.getChild(1).getLeafValue());
15845ffd83dbSDimitry Andric     if (!SubRegInit)
15855ffd83dbSDimitry Andric       return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
15860b57cec5SDimitry Andric 
15875ffd83dbSDimitry Andric     CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
1588*0fca6ea1SDimitry Andric     const TreePatternNode &ValChild = Dst.getChild(0);
1589*0fca6ea1SDimitry Andric     if (!ValChild.isLeaf()) {
15905ffd83dbSDimitry Andric       // We really have to handle the source instruction, and then insert a
15915ffd83dbSDimitry Andric       // copy from the subregister.
1592*0fca6ea1SDimitry Andric       auto ExtractSrcTy = getInstResultType(ValChild, Target);
15935ffd83dbSDimitry Andric       if (!ExtractSrcTy)
15945ffd83dbSDimitry Andric         return ExtractSrcTy.takeError();
15955ffd83dbSDimitry Andric 
15965ffd83dbSDimitry Andric       unsigned TempRegID = M.allocateTempRegID();
159706c3fb27SDimitry Andric       InsertPt = M.insertAction<MakeTempRegisterAction>(InsertPt, *ExtractSrcTy,
159806c3fb27SDimitry Andric                                                         TempRegID);
15995ffd83dbSDimitry Andric 
16005ffd83dbSDimitry Andric       auto InsertPtOrError = createAndImportSubInstructionRenderer(
160106c3fb27SDimitry Andric           ++InsertPt, M, ValChild, Src, TempRegID);
16025ffd83dbSDimitry Andric       if (auto Error = InsertPtOrError.takeError())
16035ffd83dbSDimitry Andric         return std::move(Error);
16045ffd83dbSDimitry Andric 
16055ffd83dbSDimitry Andric       DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, false, SubIdx);
16065ffd83dbSDimitry Andric       return InsertPt;
16075ffd83dbSDimitry Andric     }
16085ffd83dbSDimitry Andric 
16095ffd83dbSDimitry Andric     // If this is a source operand, this is just a subregister copy.
1610*0fca6ea1SDimitry Andric     Record *RCDef = getInitValueAsRegClass(ValChild.getLeafValue());
16110b57cec5SDimitry Andric     if (!RCDef)
16120b57cec5SDimitry Andric       return failedImport("EXTRACT_SUBREG child #0 could not "
16130b57cec5SDimitry Andric                           "be coerced to a register class");
16140b57cec5SDimitry Andric 
16150b57cec5SDimitry Andric     CodeGenRegisterClass *RC = CGRegs.getRegClass(RCDef);
16160b57cec5SDimitry Andric 
16175ffd83dbSDimitry Andric     const auto SrcRCDstRCPair =
16180b57cec5SDimitry Andric         RC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
161981ad6265SDimitry Andric     if (SrcRCDstRCPair) {
16200b57cec5SDimitry Andric       assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
16210b57cec5SDimitry Andric       if (SrcRCDstRCPair->first != RC)
16220b57cec5SDimitry Andric         return failedImport("EXTRACT_SUBREG requires an additional COPY");
16230b57cec5SDimitry Andric     }
16240b57cec5SDimitry Andric 
1625*0fca6ea1SDimitry Andric     StringRef RegOperandName = Dst.getChild(0).getName();
162606c3fb27SDimitry Andric     if (const auto &SubOperand = M.getComplexSubOperand(RegOperandName)) {
162706c3fb27SDimitry Andric       DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
162806c3fb27SDimitry Andric           *std::get<0>(*SubOperand), RegOperandName, std::get<1>(*SubOperand),
162906c3fb27SDimitry Andric           std::get<2>(*SubOperand), SubIdx);
163006c3fb27SDimitry Andric       return InsertPt;
163106c3fb27SDimitry Andric     }
163206c3fb27SDimitry Andric 
163306c3fb27SDimitry Andric     DstMIBuilder.addRenderer<CopySubRegRenderer>(RegOperandName, SubIdx);
16340b57cec5SDimitry Andric     return InsertPt;
16350b57cec5SDimitry Andric   }
16360b57cec5SDimitry Andric 
16378bcb0991SDimitry Andric   if (Name == "REG_SEQUENCE") {
1638*0fca6ea1SDimitry Andric     if (!Dst.getChild(0).isLeaf())
16398bcb0991SDimitry Andric       return failedImport("REG_SEQUENCE child #0 is not a leaf");
16408bcb0991SDimitry Andric 
1641*0fca6ea1SDimitry Andric     Record *RCDef = getInitValueAsRegClass(Dst.getChild(0).getLeafValue());
16428bcb0991SDimitry Andric     if (!RCDef)
16438bcb0991SDimitry Andric       return failedImport("REG_SEQUENCE child #0 could not "
16448bcb0991SDimitry Andric                           "be coerced to a register class");
16458bcb0991SDimitry Andric 
16468bcb0991SDimitry Andric     if ((ExpectedDstINumUses - 1) % 2 != 0)
16478bcb0991SDimitry Andric       return failedImport("Malformed REG_SEQUENCE");
16488bcb0991SDimitry Andric 
16498bcb0991SDimitry Andric     for (unsigned I = 1; I != ExpectedDstINumUses; I += 2) {
1650*0fca6ea1SDimitry Andric       const TreePatternNode &ValChild = Dst.getChild(I);
1651*0fca6ea1SDimitry Andric       const TreePatternNode &SubRegChild = Dst.getChild(I + 1);
16528bcb0991SDimitry Andric 
1653*0fca6ea1SDimitry Andric       if (DefInit *SubRegInit = dyn_cast<DefInit>(SubRegChild.getLeafValue())) {
16548bcb0991SDimitry Andric         CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
16558bcb0991SDimitry Andric 
16568bcb0991SDimitry Andric         auto InsertPtOrError =
165706c3fb27SDimitry Andric             importExplicitUseRenderer(InsertPt, M, DstMIBuilder, ValChild, Src);
16588bcb0991SDimitry Andric         if (auto Error = InsertPtOrError.takeError())
16598bcb0991SDimitry Andric           return std::move(Error);
16608bcb0991SDimitry Andric         InsertPt = InsertPtOrError.get();
16618bcb0991SDimitry Andric         DstMIBuilder.addRenderer<SubRegIndexRenderer>(SubIdx);
16628bcb0991SDimitry Andric       }
16638bcb0991SDimitry Andric     }
16648bcb0991SDimitry Andric 
16658bcb0991SDimitry Andric     return InsertPt;
16668bcb0991SDimitry Andric   }
16678bcb0991SDimitry Andric 
16680b57cec5SDimitry Andric   // Render the explicit uses.
16690b57cec5SDimitry Andric   unsigned DstINumUses = OrigDstI->Operands.size() - OrigDstI->Operands.NumDefs;
16708bcb0991SDimitry Andric   if (Name == "COPY_TO_REGCLASS") {
16710b57cec5SDimitry Andric     DstINumUses--; // Ignore the class constraint.
16720b57cec5SDimitry Andric     ExpectedDstINumUses--;
16730b57cec5SDimitry Andric   }
16740b57cec5SDimitry Andric 
1675480093f4SDimitry Andric   // NumResults - This is the number of results produced by the instruction in
1676480093f4SDimitry Andric   // the "outs" list.
1677480093f4SDimitry Andric   unsigned NumResults = OrigDstI->Operands.NumDefs;
1678480093f4SDimitry Andric 
1679480093f4SDimitry Andric   // Number of operands we know the output instruction must have. If it is
1680480093f4SDimitry Andric   // variadic, we could have more operands.
1681480093f4SDimitry Andric   unsigned NumFixedOperands = DstI->Operands.size();
1682480093f4SDimitry Andric 
1683480093f4SDimitry Andric   // Loop over all of the fixed operands of the instruction pattern, emitting
1684480093f4SDimitry Andric   // code to fill them all in. The node 'N' usually has number children equal to
1685480093f4SDimitry Andric   // the number of input operands of the instruction.  However, in cases where
1686480093f4SDimitry Andric   // there are predicate operands for an instruction, we need to fill in the
1687480093f4SDimitry Andric   // 'execute always' values. Match up the node operands to the instruction
1688480093f4SDimitry Andric   // operands to do this.
16890b57cec5SDimitry Andric   unsigned Child = 0;
1690480093f4SDimitry Andric 
1691480093f4SDimitry Andric   // Similarly to the code in TreePatternNode::ApplyTypeConstraints, count the
1692480093f4SDimitry Andric   // number of operands at the end of the list which have default values.
1693480093f4SDimitry Andric   // Those can come from the pattern if it provides enough arguments, or be
1694480093f4SDimitry Andric   // filled in with the default if the pattern hasn't provided them. But any
1695480093f4SDimitry Andric   // operand with a default value _before_ the last mandatory one will be
1696480093f4SDimitry Andric   // filled in with their defaults unconditionally.
1697480093f4SDimitry Andric   unsigned NonOverridableOperands = NumFixedOperands;
1698480093f4SDimitry Andric   while (NonOverridableOperands > NumResults &&
1699480093f4SDimitry Andric          CGP.operandHasDefault(DstI->Operands[NonOverridableOperands - 1].Rec))
1700480093f4SDimitry Andric     --NonOverridableOperands;
1701480093f4SDimitry Andric 
17020b57cec5SDimitry Andric   unsigned NumDefaultOps = 0;
17030b57cec5SDimitry Andric   for (unsigned I = 0; I != DstINumUses; ++I) {
1704480093f4SDimitry Andric     unsigned InstOpNo = DstI->Operands.NumDefs + I;
1705480093f4SDimitry Andric 
1706480093f4SDimitry Andric     // Determine what to emit for this operand.
1707480093f4SDimitry Andric     Record *OperandNode = DstI->Operands[InstOpNo].Rec;
17080b57cec5SDimitry Andric 
17090b57cec5SDimitry Andric     // If the operand has default values, introduce them now.
1710480093f4SDimitry Andric     if (CGP.operandHasDefault(OperandNode) &&
1711*0fca6ea1SDimitry Andric         (InstOpNo < NonOverridableOperands || Child >= Dst.getNumChildren())) {
1712480093f4SDimitry Andric       // This is a predicate or optional def operand which the pattern has not
1713480093f4SDimitry Andric       // overridden, or which we aren't letting it override; emit the 'default
1714480093f4SDimitry Andric       // ops' operands.
1715480093f4SDimitry Andric 
17165f757f3fSDimitry Andric       Record *OperandNode = DstI->Operands[InstOpNo].Rec;
17175f757f3fSDimitry Andric       if (auto Error = importDefaultOperandRenderers(
17185f757f3fSDimitry Andric               InsertPt, M, DstMIBuilder, CGP.getDefaultOperand(OperandNode)))
17190b57cec5SDimitry Andric         return std::move(Error);
17205f757f3fSDimitry Andric 
17210b57cec5SDimitry Andric       ++NumDefaultOps;
17220b57cec5SDimitry Andric       continue;
17230b57cec5SDimitry Andric     }
17240b57cec5SDimitry Andric 
17250b57cec5SDimitry Andric     auto InsertPtOrError = importExplicitUseRenderer(InsertPt, M, DstMIBuilder,
1726*0fca6ea1SDimitry Andric                                                      Dst.getChild(Child), Src);
17270b57cec5SDimitry Andric     if (auto Error = InsertPtOrError.takeError())
17280b57cec5SDimitry Andric       return std::move(Error);
17290b57cec5SDimitry Andric     InsertPt = InsertPtOrError.get();
17300b57cec5SDimitry Andric     ++Child;
17310b57cec5SDimitry Andric   }
17320b57cec5SDimitry Andric 
17330b57cec5SDimitry Andric   if (NumDefaultOps + ExpectedDstINumUses != DstINumUses)
17340b57cec5SDimitry Andric     return failedImport("Expected " + llvm::to_string(DstINumUses) +
17350b57cec5SDimitry Andric                         " used operands but found " +
17360b57cec5SDimitry Andric                         llvm::to_string(ExpectedDstINumUses) +
17370b57cec5SDimitry Andric                         " explicit ones and " + llvm::to_string(NumDefaultOps) +
17380b57cec5SDimitry Andric                         " default ones");
17390b57cec5SDimitry Andric 
17400b57cec5SDimitry Andric   return InsertPt;
17410b57cec5SDimitry Andric }
17420b57cec5SDimitry Andric 
17430b57cec5SDimitry Andric Error GlobalISelEmitter::importDefaultOperandRenderers(
17440b57cec5SDimitry Andric     action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
17455f757f3fSDimitry Andric     const DAGDefaultOperand &DefaultOp) const {
17465f757f3fSDimitry Andric   for (const auto &Op : DefaultOp.DefaultOps) {
1747*0fca6ea1SDimitry Andric     const auto &N = *Op;
1748*0fca6ea1SDimitry Andric     if (!N.isLeaf())
17495f757f3fSDimitry Andric       return failedImport("Could not add default op");
17500b57cec5SDimitry Andric 
1751*0fca6ea1SDimitry Andric     const auto *DefaultOp = N.getLeafValue();
17520b57cec5SDimitry Andric 
17530b57cec5SDimitry Andric     if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) {
1754*0fca6ea1SDimitry Andric       std::optional<LLTCodeGen> OpTyOrNone = MVTToLLT(N.getSimpleType(0));
1755*0fca6ea1SDimitry Andric       auto *Def = DefaultDefOp->getDef();
17560b57cec5SDimitry Andric       if (Def->getName() == "undef_tied_input") {
17570b57cec5SDimitry Andric         unsigned TempRegID = M.allocateTempRegID();
1758bdd1243dSDimitry Andric         M.insertAction<MakeTempRegisterAction>(InsertPt, *OpTyOrNone,
1759753f127fSDimitry Andric                                                TempRegID);
17600b57cec5SDimitry Andric         InsertPt = M.insertAction<BuildMIAction>(
17610b57cec5SDimitry Andric             InsertPt, M.allocateOutputInsnID(),
17620b57cec5SDimitry Andric             &Target.getInstruction(RK.getDef("IMPLICIT_DEF")));
176306c3fb27SDimitry Andric         BuildMIAction &IDMIBuilder =
176406c3fb27SDimitry Andric             *static_cast<BuildMIAction *>(InsertPt->get());
17650b57cec5SDimitry Andric         IDMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
17660b57cec5SDimitry Andric         DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
17670b57cec5SDimitry Andric       } else {
1768e8d8bef9SDimitry Andric         DstMIBuilder.addRenderer<AddRegisterRenderer>(Target, Def);
17690b57cec5SDimitry Andric       }
17700b57cec5SDimitry Andric       continue;
17710b57cec5SDimitry Andric     }
17720b57cec5SDimitry Andric 
17730b57cec5SDimitry Andric     if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) {
17740b57cec5SDimitry Andric       DstMIBuilder.addRenderer<ImmRenderer>(DefaultIntOp->getValue());
17750b57cec5SDimitry Andric       continue;
17760b57cec5SDimitry Andric     }
17770b57cec5SDimitry Andric 
17780b57cec5SDimitry Andric     return failedImport("Could not add default op");
17790b57cec5SDimitry Andric   }
17800b57cec5SDimitry Andric 
17810b57cec5SDimitry Andric   return Error::success();
17820b57cec5SDimitry Andric }
17830b57cec5SDimitry Andric 
17840b57cec5SDimitry Andric Error GlobalISelEmitter::importImplicitDefRenderers(
17850b57cec5SDimitry Andric     BuildMIAction &DstMIBuilder,
17860b57cec5SDimitry Andric     const std::vector<Record *> &ImplicitDefs) const {
17870b57cec5SDimitry Andric   if (!ImplicitDefs.empty())
17880b57cec5SDimitry Andric     return failedImport("Pattern defines a physical register");
17890b57cec5SDimitry Andric   return Error::success();
17900b57cec5SDimitry Andric }
17910b57cec5SDimitry Andric 
1792bdd1243dSDimitry Andric std::optional<const CodeGenRegisterClass *>
1793*0fca6ea1SDimitry Andric GlobalISelEmitter::getRegClassFromLeaf(const TreePatternNode &Leaf) {
1794*0fca6ea1SDimitry Andric   assert(Leaf.isLeaf() && "Expected leaf?");
1795*0fca6ea1SDimitry Andric   Record *RCRec = getInitValueAsRegClass(Leaf.getLeafValue());
17968bcb0991SDimitry Andric   if (!RCRec)
1797bdd1243dSDimitry Andric     return std::nullopt;
17988bcb0991SDimitry Andric   CodeGenRegisterClass *RC = CGRegs.getRegClass(RCRec);
17998bcb0991SDimitry Andric   if (!RC)
1800bdd1243dSDimitry Andric     return std::nullopt;
18018bcb0991SDimitry Andric   return RC;
18028bcb0991SDimitry Andric }
18038bcb0991SDimitry Andric 
1804bdd1243dSDimitry Andric std::optional<const CodeGenRegisterClass *>
1805*0fca6ea1SDimitry Andric GlobalISelEmitter::inferRegClassFromPattern(const TreePatternNode &N) {
1806*0fca6ea1SDimitry Andric   if (N.isLeaf())
18078bcb0991SDimitry Andric     return getRegClassFromLeaf(N);
18088bcb0991SDimitry Andric 
18098bcb0991SDimitry Andric   // We don't have a leaf node, so we have to try and infer something. Check
1810*0fca6ea1SDimitry Andric   // that we have an instruction that we can infer something from.
18118bcb0991SDimitry Andric 
1812*0fca6ea1SDimitry Andric   // Only handle things that produce at least one value (if multiple values,
1813*0fca6ea1SDimitry Andric   // just take the first one).
1814*0fca6ea1SDimitry Andric   if (N.getNumTypes() < 1)
1815bdd1243dSDimitry Andric     return std::nullopt;
1816*0fca6ea1SDimitry Andric   Record *OpRec = N.getOperator();
18178bcb0991SDimitry Andric 
18188bcb0991SDimitry Andric   // We only want instructions.
18198bcb0991SDimitry Andric   if (!OpRec->isSubClassOf("Instruction"))
1820bdd1243dSDimitry Andric     return std::nullopt;
18218bcb0991SDimitry Andric 
18228bcb0991SDimitry Andric   // Don't want to try and infer things when there could potentially be more
18238bcb0991SDimitry Andric   // than one candidate register class.
18248bcb0991SDimitry Andric   auto &Inst = Target.getInstruction(OpRec);
18258bcb0991SDimitry Andric 
18268bcb0991SDimitry Andric   // Handle any special-case instructions which we can safely infer register
18278bcb0991SDimitry Andric   // classes from.
18288bcb0991SDimitry Andric   StringRef InstName = Inst.TheDef->getName();
18298bcb0991SDimitry Andric   bool IsRegSequence = InstName == "REG_SEQUENCE";
18308bcb0991SDimitry Andric   if (IsRegSequence || InstName == "COPY_TO_REGCLASS") {
18318bcb0991SDimitry Andric     // If we have a COPY_TO_REGCLASS, then we need to handle it specially. It
18328bcb0991SDimitry Andric     // has the desired register class as the first child.
1833*0fca6ea1SDimitry Andric     const TreePatternNode &RCChild = N.getChild(IsRegSequence ? 0 : 1);
1834*0fca6ea1SDimitry Andric     if (!RCChild.isLeaf())
1835bdd1243dSDimitry Andric       return std::nullopt;
18368bcb0991SDimitry Andric     return getRegClassFromLeaf(RCChild);
18378bcb0991SDimitry Andric   }
1838e8d8bef9SDimitry Andric   if (InstName == "INSERT_SUBREG") {
1839*0fca6ea1SDimitry Andric     const TreePatternNode &Child0 = N.getChild(0);
1840*0fca6ea1SDimitry Andric     assert(Child0.getNumTypes() == 1 && "Unexpected number of types!");
1841*0fca6ea1SDimitry Andric     const TypeSetByHwMode &VTy = Child0.getExtType(0);
1842*0fca6ea1SDimitry Andric     return inferSuperRegisterClassForNode(VTy, Child0, N.getChild(2));
1843e8d8bef9SDimitry Andric   }
1844e8d8bef9SDimitry Andric   if (InstName == "EXTRACT_SUBREG") {
1845*0fca6ea1SDimitry Andric     assert(N.getNumTypes() == 1 && "Unexpected number of types!");
1846*0fca6ea1SDimitry Andric     const TypeSetByHwMode &VTy = N.getExtType(0);
1847*0fca6ea1SDimitry Andric     return inferSuperRegisterClass(VTy, N.getChild(1));
1848e8d8bef9SDimitry Andric   }
18498bcb0991SDimitry Andric 
18508bcb0991SDimitry Andric   // Handle destination record types that we can safely infer a register class
18518bcb0991SDimitry Andric   // from.
18528bcb0991SDimitry Andric   const auto &DstIOperand = Inst.Operands[0];
18538bcb0991SDimitry Andric   Record *DstIOpRec = DstIOperand.Rec;
18548bcb0991SDimitry Andric   if (DstIOpRec->isSubClassOf("RegisterOperand")) {
18558bcb0991SDimitry Andric     DstIOpRec = DstIOpRec->getValueAsDef("RegClass");
18568bcb0991SDimitry Andric     const CodeGenRegisterClass &RC = Target.getRegisterClass(DstIOpRec);
18578bcb0991SDimitry Andric     return &RC;
18588bcb0991SDimitry Andric   }
18598bcb0991SDimitry Andric 
18608bcb0991SDimitry Andric   if (DstIOpRec->isSubClassOf("RegisterClass")) {
18618bcb0991SDimitry Andric     const CodeGenRegisterClass &RC = Target.getRegisterClass(DstIOpRec);
18628bcb0991SDimitry Andric     return &RC;
18638bcb0991SDimitry Andric   }
18648bcb0991SDimitry Andric 
1865bdd1243dSDimitry Andric   return std::nullopt;
18668bcb0991SDimitry Andric }
18678bcb0991SDimitry Andric 
1868bdd1243dSDimitry Andric std::optional<const CodeGenRegisterClass *>
186906c3fb27SDimitry Andric GlobalISelEmitter::inferSuperRegisterClass(
1870*0fca6ea1SDimitry Andric     const TypeSetByHwMode &Ty, const TreePatternNode &SubRegIdxNode) {
18718bcb0991SDimitry Andric   // We need a ValueTypeByHwMode for getSuperRegForSubReg.
18728bcb0991SDimitry Andric   if (!Ty.isValueTypeByHwMode(false))
1873bdd1243dSDimitry Andric     return std::nullopt;
1874*0fca6ea1SDimitry Andric   if (!SubRegIdxNode.isLeaf())
1875bdd1243dSDimitry Andric     return std::nullopt;
1876*0fca6ea1SDimitry Andric   DefInit *SubRegInit = dyn_cast<DefInit>(SubRegIdxNode.getLeafValue());
18778bcb0991SDimitry Andric   if (!SubRegInit)
1878bdd1243dSDimitry Andric     return std::nullopt;
18798bcb0991SDimitry Andric   CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
18808bcb0991SDimitry Andric 
18818bcb0991SDimitry Andric   // Use the information we found above to find a minimal register class which
18828bcb0991SDimitry Andric   // supports the subregister and type we want.
18838bcb0991SDimitry Andric   auto RC =
1884e8d8bef9SDimitry Andric       Target.getSuperRegForSubReg(Ty.getValueTypeByHwMode(), CGRegs, SubIdx,
1885e8d8bef9SDimitry Andric                                   /* MustBeAllocatable */ true);
18868bcb0991SDimitry Andric   if (!RC)
1887bdd1243dSDimitry Andric     return std::nullopt;
18888bcb0991SDimitry Andric   return *RC;
18898bcb0991SDimitry Andric }
18908bcb0991SDimitry Andric 
1891bdd1243dSDimitry Andric std::optional<const CodeGenRegisterClass *>
18928bcb0991SDimitry Andric GlobalISelEmitter::inferSuperRegisterClassForNode(
1893*0fca6ea1SDimitry Andric     const TypeSetByHwMode &Ty, const TreePatternNode &SuperRegNode,
1894*0fca6ea1SDimitry Andric     const TreePatternNode &SubRegIdxNode) {
18958bcb0991SDimitry Andric   // Check if we already have a defined register class for the super register
18968bcb0991SDimitry Andric   // node. If we do, then we should preserve that rather than inferring anything
18978bcb0991SDimitry Andric   // from the subregister index node. We can assume that whoever wrote the
18988bcb0991SDimitry Andric   // pattern in the first place made sure that the super register and
18998bcb0991SDimitry Andric   // subregister are compatible.
1900bdd1243dSDimitry Andric   if (std::optional<const CodeGenRegisterClass *> SuperRegisterClass =
19018bcb0991SDimitry Andric           inferRegClassFromPattern(SuperRegNode))
19028bcb0991SDimitry Andric     return *SuperRegisterClass;
19038bcb0991SDimitry Andric   return inferSuperRegisterClass(Ty, SubRegIdxNode);
19048bcb0991SDimitry Andric }
19058bcb0991SDimitry Andric 
190606c3fb27SDimitry Andric std::optional<CodeGenSubRegIndex *> GlobalISelEmitter::inferSubRegIndexForNode(
1907*0fca6ea1SDimitry Andric     const TreePatternNode &SubRegIdxNode) {
1908*0fca6ea1SDimitry Andric   if (!SubRegIdxNode.isLeaf())
1909bdd1243dSDimitry Andric     return std::nullopt;
19108bcb0991SDimitry Andric 
1911*0fca6ea1SDimitry Andric   DefInit *SubRegInit = dyn_cast<DefInit>(SubRegIdxNode.getLeafValue());
19128bcb0991SDimitry Andric   if (!SubRegInit)
1913bdd1243dSDimitry Andric     return std::nullopt;
19148bcb0991SDimitry Andric   return CGRegs.getSubRegIdx(SubRegInit->getDef());
19158bcb0991SDimitry Andric }
19168bcb0991SDimitry Andric 
19170b57cec5SDimitry Andric Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
19180b57cec5SDimitry Andric   // Keep track of the matchers and actions to emit.
19190b57cec5SDimitry Andric   int Score = P.getPatternComplexity(CGP);
19200b57cec5SDimitry Andric   RuleMatcher M(P.getSrcRecord()->getLoc());
19210b57cec5SDimitry Andric   RuleMatcherScores[M.getRuleID()] = Score;
1922*0fca6ea1SDimitry Andric   M.addAction<DebugCommentAction>(llvm::to_string(P.getSrcPattern()) +
19230b57cec5SDimitry Andric                                   "  =>  " +
1924*0fca6ea1SDimitry Andric                                   llvm::to_string(P.getDstPattern()));
19250b57cec5SDimitry Andric 
1926fe6060f1SDimitry Andric   SmallVector<Record *, 4> Predicates;
1927fe6060f1SDimitry Andric   P.getPredicateRecords(Predicates);
1928fe6060f1SDimitry Andric   if (auto Error = importRulePredicates(M, Predicates))
19290b57cec5SDimitry Andric     return std::move(Error);
19300b57cec5SDimitry Andric 
19315f757f3fSDimitry Andric   if (!P.getHwModeFeatures().empty())
19325f757f3fSDimitry Andric     M.addHwModeIdx(declareHwModeCheck(P.getHwModeFeatures()));
19335f757f3fSDimitry Andric 
19340b57cec5SDimitry Andric   // Next, analyze the pattern operators.
1935*0fca6ea1SDimitry Andric   TreePatternNode &Src = P.getSrcPattern();
1936*0fca6ea1SDimitry Andric   TreePatternNode &Dst = P.getDstPattern();
19370b57cec5SDimitry Andric 
19380b57cec5SDimitry Andric   // If the root of either pattern isn't a simple operator, ignore it.
19390b57cec5SDimitry Andric   if (auto Err = isTrivialOperatorNode(Dst))
19400b57cec5SDimitry Andric     return failedImport("Dst pattern root isn't a trivial operator (" +
19410b57cec5SDimitry Andric                         toString(std::move(Err)) + ")");
19420b57cec5SDimitry Andric   if (auto Err = isTrivialOperatorNode(Src))
19430b57cec5SDimitry Andric     return failedImport("Src pattern root isn't a trivial operator (" +
19440b57cec5SDimitry Andric                         toString(std::move(Err)) + ")");
19450b57cec5SDimitry Andric 
19460b57cec5SDimitry Andric   // The different predicates and matchers created during
19470b57cec5SDimitry Andric   // addInstructionMatcher use the RuleMatcher M to set up their
19480b57cec5SDimitry Andric   // instruction ID (InsnVarID) that are going to be used when
19490b57cec5SDimitry Andric   // M is going to be emitted.
19500b57cec5SDimitry Andric   // However, the code doing the emission still relies on the IDs
19510b57cec5SDimitry Andric   // returned during that process by the RuleMatcher when issuing
19520b57cec5SDimitry Andric   // the recordInsn opcodes.
19530b57cec5SDimitry Andric   // Because of that:
19540b57cec5SDimitry Andric   // 1. The order in which we created the predicates
19550b57cec5SDimitry Andric   //    and such must be the same as the order in which we emit them,
19560b57cec5SDimitry Andric   //    and
19570b57cec5SDimitry Andric   // 2. We need to reset the generation of the IDs in M somewhere between
19580b57cec5SDimitry Andric   //    addInstructionMatcher and emit
19590b57cec5SDimitry Andric   //
19600b57cec5SDimitry Andric   // FIXME: Long term, we don't want to have to rely on this implicit
19610b57cec5SDimitry Andric   // naming being the same. One possible solution would be to have
19620b57cec5SDimitry Andric   // explicit operator for operation capture and reference those.
19630b57cec5SDimitry Andric   // The plus side is that it would expose opportunities to share
19640b57cec5SDimitry Andric   // the capture accross rules. The downside is that it would
19650b57cec5SDimitry Andric   // introduce a dependency between predicates (captures must happen
19660b57cec5SDimitry Andric   // before their first use.)
1967*0fca6ea1SDimitry Andric   InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher(Src.getName());
19680b57cec5SDimitry Andric   unsigned TempOpIdx = 0;
196906c3fb27SDimitry Andric 
197006c3fb27SDimitry Andric   const auto SavedFlags = M.setGISelFlags(P.getSrcRecord());
197106c3fb27SDimitry Andric 
19720b57cec5SDimitry Andric   auto InsnMatcherOrError =
19730b57cec5SDimitry Andric       createAndImportSelDAGMatcher(M, InsnMatcherTemp, Src, TempOpIdx);
19740b57cec5SDimitry Andric   if (auto Error = InsnMatcherOrError.takeError())
19750b57cec5SDimitry Andric     return std::move(Error);
19760b57cec5SDimitry Andric   InstructionMatcher &InsnMatcher = InsnMatcherOrError.get();
19770b57cec5SDimitry Andric 
1978*0fca6ea1SDimitry Andric   if (Dst.isLeaf()) {
1979*0fca6ea1SDimitry Andric     Record *RCDef = getInitValueAsRegClass(Dst.getLeafValue());
19800b57cec5SDimitry Andric     if (RCDef) {
1981e8d8bef9SDimitry Andric       const CodeGenRegisterClass &RC = Target.getRegisterClass(RCDef);
1982e8d8bef9SDimitry Andric 
19830b57cec5SDimitry Andric       // We need to replace the def and all its uses with the specified
19840b57cec5SDimitry Andric       // operand. However, we must also insert COPY's wherever needed.
19850b57cec5SDimitry Andric       // For now, emit a copy and let the register allocator clean up.
19860b57cec5SDimitry Andric       auto &DstI = Target.getInstruction(RK.getDef("COPY"));
19870b57cec5SDimitry Andric       const auto &DstIOperand = DstI.Operands[0];
19880b57cec5SDimitry Andric 
19890b57cec5SDimitry Andric       OperandMatcher &OM0 = InsnMatcher.getOperand(0);
19900b57cec5SDimitry Andric       OM0.setSymbolicName(DstIOperand.Name);
19910b57cec5SDimitry Andric       M.defineOperand(OM0.getSymbolicName(), OM0);
19920b57cec5SDimitry Andric       OM0.addPredicate<RegisterBankOperandMatcher>(RC);
19930b57cec5SDimitry Andric 
19940b57cec5SDimitry Andric       auto &DstMIBuilder =
19950b57cec5SDimitry Andric           M.addAction<BuildMIAction>(M.allocateOutputInsnID(), &DstI);
19960b57cec5SDimitry Andric       DstMIBuilder.addRenderer<CopyRenderer>(DstIOperand.Name);
1997*0fca6ea1SDimitry Andric       DstMIBuilder.addRenderer<CopyRenderer>(Dst.getName());
19980b57cec5SDimitry Andric       M.addAction<ConstrainOperandToRegClassAction>(0, 0, RC);
19990b57cec5SDimitry Andric 
20007a6dacacSDimitry Andric       // Erase the root.
20017a6dacacSDimitry Andric       unsigned RootInsnID = M.getInsnVarID(InsnMatcher);
20027a6dacacSDimitry Andric       M.addAction<EraseInstAction>(RootInsnID);
20037a6dacacSDimitry Andric 
20040b57cec5SDimitry Andric       // We're done with this pattern!  It's eligible for GISel emission; return
20050b57cec5SDimitry Andric       // it.
20060b57cec5SDimitry Andric       ++NumPatternImported;
20070b57cec5SDimitry Andric       return std::move(M);
20080b57cec5SDimitry Andric     }
20090b57cec5SDimitry Andric 
20100b57cec5SDimitry Andric     return failedImport("Dst pattern root isn't a known leaf");
20110b57cec5SDimitry Andric   }
20120b57cec5SDimitry Andric 
20130b57cec5SDimitry Andric   // Start with the defined operands (i.e., the results of the root operator).
2014*0fca6ea1SDimitry Andric   Record *DstOp = Dst.getOperator();
20150b57cec5SDimitry Andric   if (!DstOp->isSubClassOf("Instruction"))
20160b57cec5SDimitry Andric     return failedImport("Pattern operator isn't an instruction");
20170b57cec5SDimitry Andric 
20180b57cec5SDimitry Andric   auto &DstI = Target.getInstruction(DstOp);
20198bcb0991SDimitry Andric   StringRef DstIName = DstI.TheDef->getName();
20208bcb0991SDimitry Andric 
2021753f127fSDimitry Andric   unsigned DstNumDefs = DstI.Operands.NumDefs,
2022*0fca6ea1SDimitry Andric            SrcNumDefs = Src.getExtTypes().size();
2023753f127fSDimitry Andric   if (DstNumDefs < SrcNumDefs) {
2024753f127fSDimitry Andric     if (DstNumDefs != 0)
2025e8d8bef9SDimitry Andric       return failedImport("Src pattern result has more defs than dst MI (" +
2026753f127fSDimitry Andric                           to_string(SrcNumDefs) + " def(s) vs " +
2027753f127fSDimitry Andric                           to_string(DstNumDefs) + " def(s))");
2028753f127fSDimitry Andric 
2029753f127fSDimitry Andric     bool FoundNoUsePred = false;
2030753f127fSDimitry Andric     for (const auto &Pred : InsnMatcher.predicates()) {
2031753f127fSDimitry Andric       if ((FoundNoUsePred = isa<NoUsePredicateMatcher>(Pred.get())))
2032753f127fSDimitry Andric         break;
2033753f127fSDimitry Andric     }
2034753f127fSDimitry Andric     if (!FoundNoUsePred)
2035753f127fSDimitry Andric       return failedImport("Src pattern result has " + to_string(SrcNumDefs) +
2036753f127fSDimitry Andric                           " def(s) without the HasNoUse predicate set to true "
2037753f127fSDimitry Andric                           "but Dst MI has no def");
2038753f127fSDimitry Andric   }
20390b57cec5SDimitry Andric 
20400b57cec5SDimitry Andric   // The root of the match also has constraints on the register bank so that it
20410b57cec5SDimitry Andric   // matches the result instruction.
20420b57cec5SDimitry Andric   unsigned OpIdx = 0;
2043753f127fSDimitry Andric   unsigned N = std::min(DstNumDefs, SrcNumDefs);
2044753f127fSDimitry Andric   for (unsigned I = 0; I < N; ++I) {
2045*0fca6ea1SDimitry Andric     const TypeSetByHwMode &VTy = Src.getExtType(I);
20460b57cec5SDimitry Andric 
20470b57cec5SDimitry Andric     const auto &DstIOperand = DstI.Operands[OpIdx];
20485f757f3fSDimitry Andric     PointerUnion<Record *, const CodeGenRegisterClass *> MatchedRC =
20495f757f3fSDimitry Andric         DstIOperand.Rec;
20508bcb0991SDimitry Andric     if (DstIName == "COPY_TO_REGCLASS") {
2051*0fca6ea1SDimitry Andric       MatchedRC = getInitValueAsRegClass(Dst.getChild(1).getLeafValue());
20520b57cec5SDimitry Andric 
20535f757f3fSDimitry Andric       if (MatchedRC.isNull())
20540b57cec5SDimitry Andric         return failedImport(
20550b57cec5SDimitry Andric             "COPY_TO_REGCLASS operand #1 isn't a register class");
20568bcb0991SDimitry Andric     } else if (DstIName == "REG_SEQUENCE") {
2057*0fca6ea1SDimitry Andric       MatchedRC = getInitValueAsRegClass(Dst.getChild(0).getLeafValue());
20585f757f3fSDimitry Andric       if (MatchedRC.isNull())
20598bcb0991SDimitry Andric         return failedImport("REG_SEQUENCE operand #0 isn't a register class");
20608bcb0991SDimitry Andric     } else if (DstIName == "EXTRACT_SUBREG") {
2061*0fca6ea1SDimitry Andric       auto InferredClass = inferRegClassFromPattern(Dst.getChild(0));
20625ffd83dbSDimitry Andric       if (!InferredClass)
206306c3fb27SDimitry Andric         return failedImport(
206406c3fb27SDimitry Andric             "Could not infer class for EXTRACT_SUBREG operand #0");
20650b57cec5SDimitry Andric 
20660b57cec5SDimitry Andric       // We can assume that a subregister is in the same bank as it's super
20670b57cec5SDimitry Andric       // register.
20685f757f3fSDimitry Andric       MatchedRC = (*InferredClass)->getDef();
20698bcb0991SDimitry Andric     } else if (DstIName == "INSERT_SUBREG") {
2070*0fca6ea1SDimitry Andric       auto MaybeSuperClass =
2071*0fca6ea1SDimitry Andric           inferSuperRegisterClassForNode(VTy, Dst.getChild(0), Dst.getChild(2));
20728bcb0991SDimitry Andric       if (!MaybeSuperClass)
20730b57cec5SDimitry Andric         return failedImport(
20748bcb0991SDimitry Andric             "Cannot infer register class for INSERT_SUBREG operand #0");
20758bcb0991SDimitry Andric       // Move to the next pattern here, because the register class we found
20768bcb0991SDimitry Andric       // doesn't necessarily have a record associated with it. So, we can't
20778bcb0991SDimitry Andric       // set DstIOpRec using this.
20785f757f3fSDimitry Andric       MatchedRC = *MaybeSuperClass;
20798bcb0991SDimitry Andric     } else if (DstIName == "SUBREG_TO_REG") {
2080*0fca6ea1SDimitry Andric       auto MaybeRegClass = inferSuperRegisterClass(VTy, Dst.getChild(2));
20818bcb0991SDimitry Andric       if (!MaybeRegClass)
20828bcb0991SDimitry Andric         return failedImport(
20838bcb0991SDimitry Andric             "Cannot infer register class for SUBREG_TO_REG operand #0");
20845f757f3fSDimitry Andric       MatchedRC = *MaybeRegClass;
20855f757f3fSDimitry Andric     } else if (MatchedRC.get<Record *>()->isSubClassOf("RegisterOperand"))
20865f757f3fSDimitry Andric       MatchedRC = MatchedRC.get<Record *>()->getValueAsDef("RegClass");
20875f757f3fSDimitry Andric     else if (!MatchedRC.get<Record *>()->isSubClassOf("RegisterClass"))
2088*0fca6ea1SDimitry Andric       return failedImport("Dst MI def isn't a register class" + to_string(Dst));
20890b57cec5SDimitry Andric 
20900b57cec5SDimitry Andric     OperandMatcher &OM = InsnMatcher.getOperand(OpIdx);
20915f757f3fSDimitry Andric     // The operand names declared in the DstI instruction are unrelated to
20925f757f3fSDimitry Andric     // those used in pattern's source and destination DAGs, so mangle the
20935f757f3fSDimitry Andric     // former to prevent implicitly adding unexpected
20945f757f3fSDimitry Andric     // GIM_CheckIsSameOperand predicates by the defineOperand method.
20955f757f3fSDimitry Andric     OM.setSymbolicName(getMangledRootDefName(DstIOperand.Name));
20960b57cec5SDimitry Andric     M.defineOperand(OM.getSymbolicName(), OM);
20975f757f3fSDimitry Andric     if (MatchedRC.is<Record *>())
20985f757f3fSDimitry Andric       MatchedRC = &Target.getRegisterClass(MatchedRC.get<Record *>());
20990b57cec5SDimitry Andric     OM.addPredicate<RegisterBankOperandMatcher>(
21005f757f3fSDimitry Andric         *MatchedRC.get<const CodeGenRegisterClass *>());
21010b57cec5SDimitry Andric     ++OpIdx;
21020b57cec5SDimitry Andric   }
21030b57cec5SDimitry Andric 
21048bcb0991SDimitry Andric   auto DstMIBuilderOrError =
21058bcb0991SDimitry Andric       createAndImportInstructionRenderer(M, InsnMatcher, Src, Dst);
21060b57cec5SDimitry Andric   if (auto Error = DstMIBuilderOrError.takeError())
21070b57cec5SDimitry Andric     return std::move(Error);
21080b57cec5SDimitry Andric   BuildMIAction &DstMIBuilder = DstMIBuilderOrError.get();
21090b57cec5SDimitry Andric 
21100b57cec5SDimitry Andric   // Render the implicit defs.
21110b57cec5SDimitry Andric   // These are only added to the root of the result.
21120b57cec5SDimitry Andric   if (auto Error = importImplicitDefRenderers(DstMIBuilder, P.getDstRegs()))
21130b57cec5SDimitry Andric     return std::move(Error);
21140b57cec5SDimitry Andric 
21150b57cec5SDimitry Andric   DstMIBuilder.chooseInsnToMutate(M);
21160b57cec5SDimitry Andric 
21170b57cec5SDimitry Andric   // Constrain the registers to classes. This is normally derived from the
21180b57cec5SDimitry Andric   // emitted instruction but a few instructions require special handling.
21198bcb0991SDimitry Andric   if (DstIName == "COPY_TO_REGCLASS") {
21200b57cec5SDimitry Andric     // COPY_TO_REGCLASS does not provide operand constraints itself but the
21210b57cec5SDimitry Andric     // result is constrained to the class given by the second child.
2122*0fca6ea1SDimitry Andric     Record *DstIOpRec = getInitValueAsRegClass(Dst.getChild(1).getLeafValue());
21230b57cec5SDimitry Andric 
21240b57cec5SDimitry Andric     if (DstIOpRec == nullptr)
21250b57cec5SDimitry Andric       return failedImport("COPY_TO_REGCLASS operand #1 isn't a register class");
21260b57cec5SDimitry Andric 
21270b57cec5SDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(
21280b57cec5SDimitry Andric         0, 0, Target.getRegisterClass(DstIOpRec));
21297a6dacacSDimitry Andric   } else if (DstIName == "EXTRACT_SUBREG") {
2130*0fca6ea1SDimitry Andric     auto SuperClass = inferRegClassFromPattern(Dst.getChild(0));
21318bcb0991SDimitry Andric     if (!SuperClass)
21328bcb0991SDimitry Andric       return failedImport(
21338bcb0991SDimitry Andric           "Cannot infer register class from EXTRACT_SUBREG operand #0");
21340b57cec5SDimitry Andric 
2135*0fca6ea1SDimitry Andric     auto SubIdx = inferSubRegIndexForNode(Dst.getChild(1));
21368bcb0991SDimitry Andric     if (!SubIdx)
21370b57cec5SDimitry Andric       return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
21380b57cec5SDimitry Andric 
21390b57cec5SDimitry Andric     // It would be nice to leave this constraint implicit but we're required
21400b57cec5SDimitry Andric     // to pick a register class so constrain the result to a register class
21410b57cec5SDimitry Andric     // that can hold the correct MVT.
21420b57cec5SDimitry Andric     //
21430b57cec5SDimitry Andric     // FIXME: This may introduce an extra copy if the chosen class doesn't
21440b57cec5SDimitry Andric     //        actually contain the subregisters.
2145*0fca6ea1SDimitry Andric     assert(Src.getExtTypes().size() == 1 &&
21460b57cec5SDimitry Andric            "Expected Src of EXTRACT_SUBREG to have one result type");
21470b57cec5SDimitry Andric 
21485ffd83dbSDimitry Andric     const auto SrcRCDstRCPair =
21498bcb0991SDimitry Andric         (*SuperClass)->getMatchingSubClassWithSubRegs(CGRegs, *SubIdx);
21505ffd83dbSDimitry Andric     if (!SrcRCDstRCPair) {
21515ffd83dbSDimitry Andric       return failedImport("subreg index is incompatible "
21525ffd83dbSDimitry Andric                           "with inferred reg class");
21535ffd83dbSDimitry Andric     }
21545ffd83dbSDimitry Andric 
21550b57cec5SDimitry Andric     assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
215606c3fb27SDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(0, 0,
215706c3fb27SDimitry Andric                                                   *SrcRCDstRCPair->second);
21580b57cec5SDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(0, 1, *SrcRCDstRCPair->first);
21597a6dacacSDimitry Andric   } else if (DstIName == "INSERT_SUBREG") {
2160*0fca6ea1SDimitry Andric     assert(Src.getExtTypes().size() == 1 &&
21618bcb0991SDimitry Andric            "Expected Src of INSERT_SUBREG to have one result type");
21628bcb0991SDimitry Andric     // We need to constrain the destination, a super regsister source, and a
21638bcb0991SDimitry Andric     // subregister source.
2164*0fca6ea1SDimitry Andric     auto SubClass = inferRegClassFromPattern(Dst.getChild(1));
21658bcb0991SDimitry Andric     if (!SubClass)
21668bcb0991SDimitry Andric       return failedImport(
21678bcb0991SDimitry Andric           "Cannot infer register class from INSERT_SUBREG operand #1");
21688bcb0991SDimitry Andric     auto SuperClass = inferSuperRegisterClassForNode(
2169*0fca6ea1SDimitry Andric         Src.getExtType(0), Dst.getChild(0), Dst.getChild(2));
21708bcb0991SDimitry Andric     if (!SuperClass)
21718bcb0991SDimitry Andric       return failedImport(
21728bcb0991SDimitry Andric           "Cannot infer register class for INSERT_SUBREG operand #0");
21738bcb0991SDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(0, 0, **SuperClass);
21748bcb0991SDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(0, 1, **SuperClass);
21758bcb0991SDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(0, 2, **SubClass);
21767a6dacacSDimitry Andric   } else if (DstIName == "SUBREG_TO_REG") {
21778bcb0991SDimitry Andric     // We need to constrain the destination and subregister source.
2178*0fca6ea1SDimitry Andric     assert(Src.getExtTypes().size() == 1 &&
21798bcb0991SDimitry Andric            "Expected Src of SUBREG_TO_REG to have one result type");
21808bcb0991SDimitry Andric 
21818bcb0991SDimitry Andric     // Attempt to infer the subregister source from the first child. If it has
21828bcb0991SDimitry Andric     // an explicitly given register class, we'll use that. Otherwise, we will
21838bcb0991SDimitry Andric     // fail.
2184*0fca6ea1SDimitry Andric     auto SubClass = inferRegClassFromPattern(Dst.getChild(1));
21858bcb0991SDimitry Andric     if (!SubClass)
21868bcb0991SDimitry Andric       return failedImport(
21878bcb0991SDimitry Andric           "Cannot infer register class from SUBREG_TO_REG child #1");
21888bcb0991SDimitry Andric     // We don't have a child to look at that might have a super register node.
21898bcb0991SDimitry Andric     auto SuperClass =
2190*0fca6ea1SDimitry Andric         inferSuperRegisterClass(Src.getExtType(0), Dst.getChild(2));
21918bcb0991SDimitry Andric     if (!SuperClass)
21928bcb0991SDimitry Andric       return failedImport(
21938bcb0991SDimitry Andric           "Cannot infer register class for SUBREG_TO_REG operand #0");
21948bcb0991SDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(0, 0, **SuperClass);
21958bcb0991SDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(0, 2, **SubClass);
21967a6dacacSDimitry Andric   } else if (DstIName == "REG_SEQUENCE") {
2197*0fca6ea1SDimitry Andric     auto SuperClass = inferRegClassFromPattern(Dst.getChild(0));
21985ffd83dbSDimitry Andric 
21995ffd83dbSDimitry Andric     M.addAction<ConstrainOperandToRegClassAction>(0, 0, **SuperClass);
22005ffd83dbSDimitry Andric 
2201*0fca6ea1SDimitry Andric     unsigned Num = Dst.getNumChildren();
22025ffd83dbSDimitry Andric     for (unsigned I = 1; I != Num; I += 2) {
2203*0fca6ea1SDimitry Andric       TreePatternNode &SubRegChild = Dst.getChild(I + 1);
22045ffd83dbSDimitry Andric 
22055ffd83dbSDimitry Andric       auto SubIdx = inferSubRegIndexForNode(SubRegChild);
22065ffd83dbSDimitry Andric       if (!SubIdx)
22075ffd83dbSDimitry Andric         return failedImport("REG_SEQUENCE child is not a subreg index");
22085ffd83dbSDimitry Andric 
22095ffd83dbSDimitry Andric       const auto SrcRCDstRCPair =
22105ffd83dbSDimitry Andric           (*SuperClass)->getMatchingSubClassWithSubRegs(CGRegs, *SubIdx);
22115ffd83dbSDimitry Andric 
22125ffd83dbSDimitry Andric       M.addAction<ConstrainOperandToRegClassAction>(0, I,
22135ffd83dbSDimitry Andric                                                     *SrcRCDstRCPair->second);
22145ffd83dbSDimitry Andric     }
22157a6dacacSDimitry Andric   } else {
22167a6dacacSDimitry Andric     M.addAction<ConstrainOperandsToDefinitionAction>(0);
22175ffd83dbSDimitry Andric   }
22185ffd83dbSDimitry Andric 
22197a6dacacSDimitry Andric   // Erase the root.
22207a6dacacSDimitry Andric   unsigned RootInsnID = M.getInsnVarID(InsnMatcher);
22217a6dacacSDimitry Andric   M.addAction<EraseInstAction>(RootInsnID);
22220b57cec5SDimitry Andric 
22230b57cec5SDimitry Andric   // We're done with this pattern!  It's eligible for GISel emission; return it.
22240b57cec5SDimitry Andric   ++NumPatternImported;
22250b57cec5SDimitry Andric   return std::move(M);
22260b57cec5SDimitry Andric }
22270b57cec5SDimitry Andric 
22280b57cec5SDimitry Andric MatchTable
22290b57cec5SDimitry Andric GlobalISelEmitter::buildMatchTable(MutableArrayRef<RuleMatcher> Rules,
22300b57cec5SDimitry Andric                                    bool Optimize, bool WithCoverage) {
22310b57cec5SDimitry Andric   std::vector<Matcher *> InputRules;
22320b57cec5SDimitry Andric   for (Matcher &Rule : Rules)
22330b57cec5SDimitry Andric     InputRules.push_back(&Rule);
22340b57cec5SDimitry Andric 
22350b57cec5SDimitry Andric   if (!Optimize)
22360b57cec5SDimitry Andric     return MatchTable::buildTable(InputRules, WithCoverage);
22370b57cec5SDimitry Andric 
22380b57cec5SDimitry Andric   unsigned CurrentOrdering = 0;
22390b57cec5SDimitry Andric   StringMap<unsigned> OpcodeOrder;
22400b57cec5SDimitry Andric   for (RuleMatcher &Rule : Rules) {
22410b57cec5SDimitry Andric     const StringRef Opcode = Rule.getOpcode();
22420b57cec5SDimitry Andric     assert(!Opcode.empty() && "Didn't expect an undefined opcode");
22430b57cec5SDimitry Andric     if (OpcodeOrder.count(Opcode) == 0)
22440b57cec5SDimitry Andric       OpcodeOrder[Opcode] = CurrentOrdering++;
22450b57cec5SDimitry Andric   }
22460b57cec5SDimitry Andric 
2247e8d8bef9SDimitry Andric   llvm::stable_sort(InputRules, [&OpcodeOrder](const Matcher *A,
2248e8d8bef9SDimitry Andric                                                const Matcher *B) {
22490b57cec5SDimitry Andric     auto *L = static_cast<const RuleMatcher *>(A);
22500b57cec5SDimitry Andric     auto *R = static_cast<const RuleMatcher *>(B);
2251*0fca6ea1SDimitry Andric     return std::tuple(OpcodeOrder[L->getOpcode()], L->getNumOperands()) <
2252*0fca6ea1SDimitry Andric            std::tuple(OpcodeOrder[R->getOpcode()], R->getNumOperands());
22530b57cec5SDimitry Andric   });
22540b57cec5SDimitry Andric 
22550b57cec5SDimitry Andric   for (Matcher *Rule : InputRules)
22560b57cec5SDimitry Andric     Rule->optimize();
22570b57cec5SDimitry Andric 
22580b57cec5SDimitry Andric   std::vector<std::unique_ptr<Matcher>> MatcherStorage;
22590b57cec5SDimitry Andric   std::vector<Matcher *> OptRules =
22600b57cec5SDimitry Andric       optimizeRules<GroupMatcher>(InputRules, MatcherStorage);
22610b57cec5SDimitry Andric 
22620b57cec5SDimitry Andric   for (Matcher *Rule : OptRules)
22630b57cec5SDimitry Andric     Rule->optimize();
22640b57cec5SDimitry Andric 
22650b57cec5SDimitry Andric   OptRules = optimizeRules<SwitchMatcher>(OptRules, MatcherStorage);
22660b57cec5SDimitry Andric 
22670b57cec5SDimitry Andric   return MatchTable::buildTable(OptRules, WithCoverage);
22680b57cec5SDimitry Andric }
22690b57cec5SDimitry Andric 
227006c3fb27SDimitry Andric void GlobalISelEmitter::emitAdditionalImpl(raw_ostream &OS) {
227106c3fb27SDimitry Andric   OS << "bool " << getClassName()
227206c3fb27SDimitry Andric      << "::selectImpl(MachineInstr &I, CodeGenCoverage "
227306c3fb27SDimitry Andric         "&CoverageInfo) const {\n"
227406c3fb27SDimitry Andric      << "  const PredicateBitset AvailableFeatures = "
227506c3fb27SDimitry Andric         "getAvailableFeatures();\n"
22765f757f3fSDimitry Andric      << "  MachineIRBuilder B(I);\n"
227706c3fb27SDimitry Andric      << "  State.MIs.clear();\n"
227806c3fb27SDimitry Andric      << "  State.MIs.push_back(&I);\n\n"
22795f757f3fSDimitry Andric      << "  if (executeMatchTable(*this, State, ExecInfo, B"
228006c3fb27SDimitry Andric      << ", getMatchTable(), TII, MF->getRegInfo(), TRI, RBI, AvailableFeatures"
228106c3fb27SDimitry Andric      << ", &CoverageInfo)) {\n"
228206c3fb27SDimitry Andric      << "    return true;\n"
228306c3fb27SDimitry Andric      << "  }\n\n"
228406c3fb27SDimitry Andric      << "  return false;\n"
228506c3fb27SDimitry Andric      << "}\n\n";
22860b57cec5SDimitry Andric }
228706c3fb27SDimitry Andric 
228806c3fb27SDimitry Andric void GlobalISelEmitter::emitMIPredicateFns(raw_ostream &OS) {
228906c3fb27SDimitry Andric   std::vector<Record *> MatchedRecords;
229006c3fb27SDimitry Andric   std::copy_if(AllPatFrags.begin(), AllPatFrags.end(),
229106c3fb27SDimitry Andric                std::back_inserter(MatchedRecords), [&](Record *R) {
229206c3fb27SDimitry Andric                  return !R->getValueAsString("GISelPredicateCode").empty();
22930b57cec5SDimitry Andric                });
229406c3fb27SDimitry Andric   emitMIPredicateFnsImpl<Record *>(
229506c3fb27SDimitry Andric       OS,
229606c3fb27SDimitry Andric       "  const MachineFunction &MF = *MI.getParent()->getParent();\n"
229706c3fb27SDimitry Andric       "  const MachineRegisterInfo &MRI = MF.getRegInfo();\n"
229806c3fb27SDimitry Andric       "  const auto &Operands = State.RecordedOperands;\n"
229906c3fb27SDimitry Andric       "  (void)Operands;\n"
230006c3fb27SDimitry Andric       "  (void)MRI;",
230106c3fb27SDimitry Andric       ArrayRef<Record *>(MatchedRecords), &getPatFragPredicateEnumName,
230206c3fb27SDimitry Andric       [&](Record *R) { return R->getValueAsString("GISelPredicateCode"); },
230306c3fb27SDimitry Andric       "PatFrag predicates.");
23040b57cec5SDimitry Andric }
230506c3fb27SDimitry Andric 
230606c3fb27SDimitry Andric void GlobalISelEmitter::emitI64ImmPredicateFns(raw_ostream &OS) {
230706c3fb27SDimitry Andric   std::vector<Record *> MatchedRecords;
230806c3fb27SDimitry Andric   std::copy_if(AllPatFrags.begin(), AllPatFrags.end(),
230906c3fb27SDimitry Andric                std::back_inserter(MatchedRecords), [&](Record *R) {
231006c3fb27SDimitry Andric                  bool Unset;
231106c3fb27SDimitry Andric                  return !R->getValueAsString("ImmediateCode").empty() &&
231206c3fb27SDimitry Andric                         !R->getValueAsBitOrUnset("IsAPFloat", Unset) &&
231306c3fb27SDimitry Andric                         !R->getValueAsBit("IsAPInt");
231406c3fb27SDimitry Andric                });
231506c3fb27SDimitry Andric   emitImmPredicateFnsImpl<Record *>(
231606c3fb27SDimitry Andric       OS, "I64", "int64_t", ArrayRef<Record *>(MatchedRecords),
231706c3fb27SDimitry Andric       &getPatFragPredicateEnumName,
231806c3fb27SDimitry Andric       [&](Record *R) { return R->getValueAsString("ImmediateCode"); },
231906c3fb27SDimitry Andric       "PatFrag predicates.");
232006c3fb27SDimitry Andric }
232106c3fb27SDimitry Andric 
232206c3fb27SDimitry Andric void GlobalISelEmitter::emitAPFloatImmPredicateFns(raw_ostream &OS) {
232306c3fb27SDimitry Andric   std::vector<Record *> MatchedRecords;
232406c3fb27SDimitry Andric   std::copy_if(AllPatFrags.begin(), AllPatFrags.end(),
232506c3fb27SDimitry Andric                std::back_inserter(MatchedRecords), [&](Record *R) {
232606c3fb27SDimitry Andric                  bool Unset;
232706c3fb27SDimitry Andric                  return !R->getValueAsString("ImmediateCode").empty() &&
232806c3fb27SDimitry Andric                         R->getValueAsBitOrUnset("IsAPFloat", Unset);
232906c3fb27SDimitry Andric                });
233006c3fb27SDimitry Andric   emitImmPredicateFnsImpl<Record *>(
233106c3fb27SDimitry Andric       OS, "APFloat", "const APFloat &", ArrayRef<Record *>(MatchedRecords),
233206c3fb27SDimitry Andric       &getPatFragPredicateEnumName,
233306c3fb27SDimitry Andric       [&](Record *R) { return R->getValueAsString("ImmediateCode"); },
233406c3fb27SDimitry Andric       "PatFrag predicates.");
233506c3fb27SDimitry Andric }
233606c3fb27SDimitry Andric 
233706c3fb27SDimitry Andric void GlobalISelEmitter::emitAPIntImmPredicateFns(raw_ostream &OS) {
233806c3fb27SDimitry Andric   std::vector<Record *> MatchedRecords;
233906c3fb27SDimitry Andric   std::copy_if(AllPatFrags.begin(), AllPatFrags.end(),
234006c3fb27SDimitry Andric                std::back_inserter(MatchedRecords), [&](Record *R) {
234106c3fb27SDimitry Andric                  return !R->getValueAsString("ImmediateCode").empty() &&
234206c3fb27SDimitry Andric                         R->getValueAsBit("IsAPInt");
234306c3fb27SDimitry Andric                });
234406c3fb27SDimitry Andric   emitImmPredicateFnsImpl<Record *>(
234506c3fb27SDimitry Andric       OS, "APInt", "const APInt &", ArrayRef<Record *>(MatchedRecords),
234606c3fb27SDimitry Andric       &getPatFragPredicateEnumName,
234706c3fb27SDimitry Andric       [&](Record *R) { return R->getValueAsString("ImmediateCode"); },
234806c3fb27SDimitry Andric       "PatFrag predicates.");
234906c3fb27SDimitry Andric }
235006c3fb27SDimitry Andric 
235106c3fb27SDimitry Andric void GlobalISelEmitter::emitTestSimplePredicate(raw_ostream &OS) {
235206c3fb27SDimitry Andric   OS << "bool " << getClassName() << "::testSimplePredicate(unsigned) const {\n"
235306c3fb27SDimitry Andric      << "    llvm_unreachable(\"" + getClassName() +
235406c3fb27SDimitry Andric             " does not support simple predicates!\");\n"
235506c3fb27SDimitry Andric      << "  return false;\n"
235606c3fb27SDimitry Andric      << "}\n";
235706c3fb27SDimitry Andric }
235806c3fb27SDimitry Andric 
235906c3fb27SDimitry Andric void GlobalISelEmitter::emitRunCustomAction(raw_ostream &OS) {
2360*0fca6ea1SDimitry Andric   OS << "bool " << getClassName()
23615f757f3fSDimitry Andric      << "::runCustomAction(unsigned, const MatcherState&, NewMIVector &) const "
23625f757f3fSDimitry Andric         "{\n"
236306c3fb27SDimitry Andric      << "    llvm_unreachable(\"" + getClassName() +
236406c3fb27SDimitry Andric             " does not support custom C++ actions!\");\n"
236506c3fb27SDimitry Andric      << "}\n";
23660b57cec5SDimitry Andric }
23670b57cec5SDimitry Andric 
23685f757f3fSDimitry Andric void GlobalISelEmitter::postProcessRule(RuleMatcher &M) {
23695f757f3fSDimitry Andric   SmallPtrSet<Record *, 16> UsedRegs;
23705f757f3fSDimitry Andric 
23715f757f3fSDimitry Andric   // TODO: deal with subregs?
23725f757f3fSDimitry Andric   for (auto &A : M.actions()) {
23735f757f3fSDimitry Andric     auto *MI = dyn_cast<BuildMIAction>(A.get());
23745f757f3fSDimitry Andric     if (!MI)
23755f757f3fSDimitry Andric       continue;
23765f757f3fSDimitry Andric 
23775f757f3fSDimitry Andric     for (auto *Use : MI->getCGI()->ImplicitUses)
23785f757f3fSDimitry Andric       UsedRegs.insert(Use);
23795f757f3fSDimitry Andric   }
23805f757f3fSDimitry Andric 
23815f757f3fSDimitry Andric   for (auto &A : M.actions()) {
23825f757f3fSDimitry Andric     auto *MI = dyn_cast<BuildMIAction>(A.get());
23835f757f3fSDimitry Andric     if (!MI)
23845f757f3fSDimitry Andric       continue;
23855f757f3fSDimitry Andric 
23865f757f3fSDimitry Andric     for (auto *Def : MI->getCGI()->ImplicitDefs) {
23875f757f3fSDimitry Andric       if (!UsedRegs.contains(Def))
23885f757f3fSDimitry Andric         MI->setDeadImplicitDef(Def);
23895f757f3fSDimitry Andric     }
23905f757f3fSDimitry Andric   }
23915f757f3fSDimitry Andric }
23925f757f3fSDimitry Andric 
23930b57cec5SDimitry Andric void GlobalISelEmitter::run(raw_ostream &OS) {
23940b57cec5SDimitry Andric   if (!UseCoverageFile.empty()) {
23950b57cec5SDimitry Andric     RuleCoverage = CodeGenCoverage();
23960b57cec5SDimitry Andric     auto RuleCoverageBufOrErr = MemoryBuffer::getFile(UseCoverageFile);
23970b57cec5SDimitry Andric     if (!RuleCoverageBufOrErr) {
23980b57cec5SDimitry Andric       PrintWarning(SMLoc(), "Missing rule coverage data");
2399bdd1243dSDimitry Andric       RuleCoverage = std::nullopt;
24000b57cec5SDimitry Andric     } else {
24010b57cec5SDimitry Andric       if (!RuleCoverage->parse(*RuleCoverageBufOrErr.get(), Target.getName())) {
24020b57cec5SDimitry Andric         PrintWarning(SMLoc(), "Ignoring invalid or missing rule coverage data");
2403bdd1243dSDimitry Andric         RuleCoverage = std::nullopt;
24040b57cec5SDimitry Andric       }
24050b57cec5SDimitry Andric     }
24060b57cec5SDimitry Andric   }
24070b57cec5SDimitry Andric 
24080b57cec5SDimitry Andric   // Track the run-time opcode values
24090b57cec5SDimitry Andric   gatherOpcodeValues();
24100b57cec5SDimitry Andric   // Track the run-time LLT ID values
24110b57cec5SDimitry Andric   gatherTypeIDValues();
24120b57cec5SDimitry Andric 
24130b57cec5SDimitry Andric   // Track the GINodeEquiv definitions.
24140b57cec5SDimitry Andric   gatherNodeEquivs();
24150b57cec5SDimitry Andric 
241606c3fb27SDimitry Andric   AllPatFrags = RK.getAllDerivedDefinitions("PatFrags");
241706c3fb27SDimitry Andric 
241806c3fb27SDimitry Andric   emitSourceFileHeader(
241906c3fb27SDimitry Andric       ("Global Instruction Selector for the " + Target.getName() + " target")
242006c3fb27SDimitry Andric           .str(),
242106c3fb27SDimitry Andric       OS);
24220b57cec5SDimitry Andric   std::vector<RuleMatcher> Rules;
24230b57cec5SDimitry Andric   // Look through the SelectionDAG patterns we found, possibly emitting some.
24240b57cec5SDimitry Andric   for (const PatternToMatch &Pat : CGP.ptms()) {
24250b57cec5SDimitry Andric     ++NumPatternTotal;
24260b57cec5SDimitry Andric 
2427*0fca6ea1SDimitry Andric     if (Pat.getGISelShouldIgnore())
2428*0fca6ea1SDimitry Andric       continue; // skip without warning
24290b57cec5SDimitry Andric     auto MatcherOrErr = runOnPattern(Pat);
24300b57cec5SDimitry Andric 
24310b57cec5SDimitry Andric     // The pattern analysis can fail, indicating an unsupported pattern.
24320b57cec5SDimitry Andric     // Report that if we've been asked to do so.
24330b57cec5SDimitry Andric     if (auto Err = MatcherOrErr.takeError()) {
24340b57cec5SDimitry Andric       if (WarnOnSkippedPatterns) {
24350b57cec5SDimitry Andric         PrintWarning(Pat.getSrcRecord()->getLoc(),
24360b57cec5SDimitry Andric                      "Skipped pattern: " + toString(std::move(Err)));
24370b57cec5SDimitry Andric       } else {
24380b57cec5SDimitry Andric         consumeError(std::move(Err));
24390b57cec5SDimitry Andric       }
24400b57cec5SDimitry Andric       ++NumPatternImportsSkipped;
24410b57cec5SDimitry Andric       continue;
24420b57cec5SDimitry Andric     }
24430b57cec5SDimitry Andric 
24440b57cec5SDimitry Andric     if (RuleCoverage) {
24450b57cec5SDimitry Andric       if (RuleCoverage->isCovered(MatcherOrErr->getRuleID()))
24460b57cec5SDimitry Andric         ++NumPatternsTested;
24470b57cec5SDimitry Andric       else
24480b57cec5SDimitry Andric         PrintWarning(Pat.getSrcRecord()->getLoc(),
24490b57cec5SDimitry Andric                      "Pattern is not covered by a test");
24500b57cec5SDimitry Andric     }
24510b57cec5SDimitry Andric     Rules.push_back(std::move(MatcherOrErr.get()));
24525f757f3fSDimitry Andric     postProcessRule(Rules.back());
24530b57cec5SDimitry Andric   }
24540b57cec5SDimitry Andric 
24550b57cec5SDimitry Andric   // Comparison function to order records by name.
2456*0fca6ea1SDimitry Andric   auto OrderByName = [](const Record *A, const Record *B) {
24570b57cec5SDimitry Andric     return A->getName() < B->getName();
24580b57cec5SDimitry Andric   };
24590b57cec5SDimitry Andric 
24600b57cec5SDimitry Andric   std::vector<Record *> ComplexPredicates =
24610b57cec5SDimitry Andric       RK.getAllDerivedDefinitions("GIComplexOperandMatcher");
2462*0fca6ea1SDimitry Andric   llvm::sort(ComplexPredicates, OrderByName);
24630b57cec5SDimitry Andric 
2464fe6060f1SDimitry Andric   std::vector<StringRef> CustomRendererFns;
2465fe6060f1SDimitry Andric   transform(RK.getAllDerivedDefinitions("GICustomOperandRenderer"),
2466fe6060f1SDimitry Andric             std::back_inserter(CustomRendererFns), [](const auto &Record) {
2467fe6060f1SDimitry Andric               return Record->getValueAsString("RendererFn");
2468fe6060f1SDimitry Andric             });
2469fe6060f1SDimitry Andric   // Sort and remove duplicates to get a list of unique renderer functions, in
2470fe6060f1SDimitry Andric   // case some were mentioned more than once.
2471fe6060f1SDimitry Andric   llvm::sort(CustomRendererFns);
2472*0fca6ea1SDimitry Andric   CustomRendererFns.erase(llvm::unique(CustomRendererFns),
2473fe6060f1SDimitry Andric                           CustomRendererFns.end());
24740b57cec5SDimitry Andric 
247506c3fb27SDimitry Andric   // Create a table containing the LLT objects needed by the matcher and an enum
24760b57cec5SDimitry Andric   // for the matcher to reference them with.
24770b57cec5SDimitry Andric   std::vector<LLTCodeGen> TypeObjects;
2478e8d8bef9SDimitry Andric   append_range(TypeObjects, KnownTypes);
24790b57cec5SDimitry Andric   llvm::sort(TypeObjects);
24800b57cec5SDimitry Andric 
248106c3fb27SDimitry Andric   // Sort rules.
24820b57cec5SDimitry Andric   llvm::stable_sort(Rules, [&](const RuleMatcher &A, const RuleMatcher &B) {
24830b57cec5SDimitry Andric     int ScoreA = RuleMatcherScores[A.getRuleID()];
24840b57cec5SDimitry Andric     int ScoreB = RuleMatcherScores[B.getRuleID()];
24850b57cec5SDimitry Andric     if (ScoreA > ScoreB)
24860b57cec5SDimitry Andric       return true;
24870b57cec5SDimitry Andric     if (ScoreB > ScoreA)
24880b57cec5SDimitry Andric       return false;
24890b57cec5SDimitry Andric     if (A.isHigherPriorityThan(B)) {
24900b57cec5SDimitry Andric       assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
24910b57cec5SDimitry Andric                                            "and less important at "
24920b57cec5SDimitry Andric                                            "the same time");
24930b57cec5SDimitry Andric       return true;
24940b57cec5SDimitry Andric     }
24950b57cec5SDimitry Andric     return false;
24960b57cec5SDimitry Andric   });
24970b57cec5SDimitry Andric 
249806c3fb27SDimitry Andric   unsigned MaxTemporaries = 0;
249906c3fb27SDimitry Andric   for (const auto &Rule : Rules)
250006c3fb27SDimitry Andric     MaxTemporaries = std::max(MaxTemporaries, Rule.countRendererFns());
25010b57cec5SDimitry Andric 
250206c3fb27SDimitry Andric   // Build match table
25030b57cec5SDimitry Andric   const MatchTable Table =
25040b57cec5SDimitry Andric       buildMatchTable(Rules, OptimizeMatchTable, GenerateCoverage);
25050b57cec5SDimitry Andric 
250606c3fb27SDimitry Andric   emitPredicateBitset(OS, "GET_GLOBALISEL_PREDICATE_BITSET");
250706c3fb27SDimitry Andric   emitTemporariesDecl(OS, "GET_GLOBALISEL_TEMPORARIES_DECL");
250806c3fb27SDimitry Andric   emitTemporariesInit(OS, MaxTemporaries, "GET_GLOBALISEL_TEMPORARIES_INIT");
250906c3fb27SDimitry Andric   emitExecutorImpl(OS, Table, TypeObjects, Rules, ComplexPredicates,
251006c3fb27SDimitry Andric                    CustomRendererFns, "GET_GLOBALISEL_IMPL");
251106c3fb27SDimitry Andric   emitPredicatesDecl(OS, "GET_GLOBALISEL_PREDICATES_DECL");
251206c3fb27SDimitry Andric   emitPredicatesInit(OS, "GET_GLOBALISEL_PREDICATES_INIT");
25130b57cec5SDimitry Andric }
25140b57cec5SDimitry Andric 
25150b57cec5SDimitry Andric void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {
25165f757f3fSDimitry Andric   SubtargetFeatures.try_emplace(Predicate, Predicate, SubtargetFeatures.size());
25175f757f3fSDimitry Andric }
25185f757f3fSDimitry Andric 
25195f757f3fSDimitry Andric unsigned GlobalISelEmitter::declareHwModeCheck(StringRef HwModeFeatures) {
25205f757f3fSDimitry Andric   return HwModes.emplace(HwModeFeatures.str(), HwModes.size()).first->second;
25210b57cec5SDimitry Andric }
25220b57cec5SDimitry Andric 
25230b57cec5SDimitry Andric } // end anonymous namespace
25240b57cec5SDimitry Andric 
25250b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
25260b57cec5SDimitry Andric 
252706c3fb27SDimitry Andric static TableGen::Emitter::OptClass<GlobalISelEmitter>
252806c3fb27SDimitry Andric     X("gen-global-isel", "Generate GlobalISel selector");
2529