Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/GlobalISelEmitter.cpp
35258 views
1//===- GlobalISelEmitter.cpp - Generate an instruction selector -----------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9/// \file10/// This tablegen backend emits code for use by the GlobalISel instruction11/// selector. See include/llvm/Target/GlobalISel/Target.td.12///13/// This file analyzes the patterns recognized by the SelectionDAGISel tablegen14/// backend, filters out the ones that are unsupported, maps15/// SelectionDAG-specific constructs to their GlobalISel counterpart16/// (when applicable: MVT to LLT; SDNode to generic Instruction).17///18/// Not all patterns are supported: pass the tablegen invocation19/// "-warn-on-skipped-patterns" to emit a warning when a pattern is skipped,20/// as well as why.21///22/// The generated file defines a single method:23/// bool <Target>InstructionSelector::selectImpl(MachineInstr &I) const;24/// intended to be used in InstructionSelector::select as the first-step25/// selector for the patterns that don't require complex C++.26///27/// FIXME: We'll probably want to eventually define a base28/// "TargetGenInstructionSelector" class.29///30//===----------------------------------------------------------------------===//3132#include "Basic/CodeGenIntrinsics.h"33#include "Common/CodeGenDAGPatterns.h"34#include "Common/CodeGenInstruction.h"35#include "Common/CodeGenRegisters.h"36#include "Common/CodeGenTarget.h"37#include "Common/GlobalISel/GlobalISelMatchTable.h"38#include "Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.h"39#include "Common/InfoByHwMode.h"40#include "Common/SubtargetFeatureInfo.h"41#include "llvm/ADT/Statistic.h"42#include "llvm/CodeGenTypes/LowLevelType.h"43#include "llvm/CodeGenTypes/MachineValueType.h"44#include "llvm/Support/CodeGenCoverage.h"45#include "llvm/Support/CommandLine.h"46#include "llvm/Support/Error.h"47#include "llvm/Support/ScopedPrinter.h"48#include "llvm/TableGen/Error.h"49#include "llvm/TableGen/Record.h"50#include "llvm/TableGen/TableGenBackend.h"51#include <string>5253using namespace llvm;54using namespace llvm::gi;5556using action_iterator = RuleMatcher::action_iterator;5758#define DEBUG_TYPE "gisel-emitter"5960STATISTIC(NumPatternTotal, "Total number of patterns");61STATISTIC(NumPatternImported, "Number of patterns imported from SelectionDAG");62STATISTIC(NumPatternImportsSkipped, "Number of SelectionDAG imports skipped");63STATISTIC(NumPatternsTested,64"Number of patterns executed according to coverage information");6566cl::OptionCategory GlobalISelEmitterCat("Options for -gen-global-isel");6768static cl::opt<bool> WarnOnSkippedPatterns(69"warn-on-skipped-patterns",70cl::desc("Explain why a pattern was skipped for inclusion "71"in the GlobalISel selector"),72cl::init(false), cl::cat(GlobalISelEmitterCat));7374static cl::opt<bool> GenerateCoverage(75"instrument-gisel-coverage",76cl::desc("Generate coverage instrumentation for GlobalISel"),77cl::init(false), cl::cat(GlobalISelEmitterCat));7879static cl::opt<std::string> UseCoverageFile(80"gisel-coverage-file", cl::init(""),81cl::desc("Specify file to retrieve coverage information from"),82cl::cat(GlobalISelEmitterCat));8384static cl::opt<bool> OptimizeMatchTable(85"optimize-match-table",86cl::desc("Generate an optimized version of the match table"),87cl::init(true), cl::cat(GlobalISelEmitterCat));8889namespace {9091static std::string explainPredicates(const TreePatternNode &N) {92std::string Explanation;93StringRef Separator = "";94for (const TreePredicateCall &Call : N.getPredicateCalls()) {95const TreePredicateFn &P = Call.Fn;96Explanation +=97(Separator + P.getOrigPatFragRecord()->getRecord()->getName()).str();98Separator = ", ";99100if (P.isAlwaysTrue())101Explanation += " always-true";102if (P.isImmediatePattern())103Explanation += " immediate";104105if (P.isUnindexed())106Explanation += " unindexed";107108if (P.isNonExtLoad())109Explanation += " non-extload";110if (P.isAnyExtLoad())111Explanation += " extload";112if (P.isSignExtLoad())113Explanation += " sextload";114if (P.isZeroExtLoad())115Explanation += " zextload";116117if (P.isNonTruncStore())118Explanation += " non-truncstore";119if (P.isTruncStore())120Explanation += " truncstore";121122if (Record *VT = P.getMemoryVT())123Explanation += (" MemVT=" + VT->getName()).str();124if (Record *VT = P.getScalarMemoryVT())125Explanation += (" ScalarVT(MemVT)=" + VT->getName()).str();126127if (ListInit *AddrSpaces = P.getAddressSpaces()) {128raw_string_ostream OS(Explanation);129OS << " AddressSpaces=[";130131StringRef AddrSpaceSeparator;132for (Init *Val : AddrSpaces->getValues()) {133IntInit *IntVal = dyn_cast<IntInit>(Val);134if (!IntVal)135continue;136137OS << AddrSpaceSeparator << IntVal->getValue();138AddrSpaceSeparator = ", ";139}140141OS << ']';142}143144int64_t MinAlign = P.getMinAlignment();145if (MinAlign > 0)146Explanation += " MinAlign=" + utostr(MinAlign);147148if (P.isAtomicOrderingMonotonic())149Explanation += " monotonic";150if (P.isAtomicOrderingAcquire())151Explanation += " acquire";152if (P.isAtomicOrderingRelease())153Explanation += " release";154if (P.isAtomicOrderingAcquireRelease())155Explanation += " acq_rel";156if (P.isAtomicOrderingSequentiallyConsistent())157Explanation += " seq_cst";158if (P.isAtomicOrderingAcquireOrStronger())159Explanation += " >=acquire";160if (P.isAtomicOrderingWeakerThanAcquire())161Explanation += " <acquire";162if (P.isAtomicOrderingReleaseOrStronger())163Explanation += " >=release";164if (P.isAtomicOrderingWeakerThanRelease())165Explanation += " <release";166}167return Explanation;168}169170std::string explainOperator(Record *Operator) {171if (Operator->isSubClassOf("SDNode"))172return (" (" + Operator->getValueAsString("Opcode") + ")").str();173174if (Operator->isSubClassOf("Intrinsic"))175return (" (Operator is an Intrinsic, " + Operator->getName() + ")").str();176177if (Operator->isSubClassOf("ComplexPattern"))178return (" (Operator is an unmapped ComplexPattern, " + Operator->getName() +179")")180.str();181182if (Operator->isSubClassOf("SDNodeXForm"))183return (" (Operator is an unmapped SDNodeXForm, " + Operator->getName() +184")")185.str();186187return (" (Operator " + Operator->getName() + " not understood)").str();188}189190/// Helper function to let the emitter report skip reason error messages.191static Error failedImport(const Twine &Reason) {192return make_error<StringError>(Reason, inconvertibleErrorCode());193}194195static Error isTrivialOperatorNode(const TreePatternNode &N) {196std::string Explanation;197std::string Separator;198199bool HasUnsupportedPredicate = false;200for (const TreePredicateCall &Call : N.getPredicateCalls()) {201const TreePredicateFn &Predicate = Call.Fn;202203if (Predicate.isAlwaysTrue())204continue;205206if (Predicate.isImmediatePattern())207continue;208209if (Predicate.hasNoUse() || Predicate.hasOneUse())210continue;211212if (Predicate.isNonExtLoad() || Predicate.isAnyExtLoad() ||213Predicate.isSignExtLoad() || Predicate.isZeroExtLoad())214continue;215216if (Predicate.isNonTruncStore() || Predicate.isTruncStore())217continue;218219if (Predicate.isLoad() && Predicate.getMemoryVT())220continue;221222if (Predicate.isLoad() || Predicate.isStore()) {223if (Predicate.isUnindexed())224continue;225}226227if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {228const ListInit *AddrSpaces = Predicate.getAddressSpaces();229if (AddrSpaces && !AddrSpaces->empty())230continue;231232if (Predicate.getMinAlignment() > 0)233continue;234}235236if (Predicate.isAtomic() && Predicate.getMemoryVT())237continue;238239if (Predicate.isAtomic() &&240(Predicate.isAtomicOrderingMonotonic() ||241Predicate.isAtomicOrderingAcquire() ||242Predicate.isAtomicOrderingRelease() ||243Predicate.isAtomicOrderingAcquireRelease() ||244Predicate.isAtomicOrderingSequentiallyConsistent() ||245Predicate.isAtomicOrderingAcquireOrStronger() ||246Predicate.isAtomicOrderingWeakerThanAcquire() ||247Predicate.isAtomicOrderingReleaseOrStronger() ||248Predicate.isAtomicOrderingWeakerThanRelease()))249continue;250251if (Predicate.hasGISelPredicateCode())252continue;253254HasUnsupportedPredicate = true;255Explanation = Separator + "Has a predicate (" + explainPredicates(N) + ")";256Separator = ", ";257Explanation += (Separator + "first-failing:" +258Predicate.getOrigPatFragRecord()->getRecord()->getName())259.str();260break;261}262263if (!HasUnsupportedPredicate)264return Error::success();265266return failedImport(Explanation);267}268269static Record *getInitValueAsRegClass(Init *V) {270if (DefInit *VDefInit = dyn_cast<DefInit>(V)) {271if (VDefInit->getDef()->isSubClassOf("RegisterOperand"))272return VDefInit->getDef()->getValueAsDef("RegClass");273if (VDefInit->getDef()->isSubClassOf("RegisterClass"))274return VDefInit->getDef();275}276return nullptr;277}278279static std::string getScopedName(unsigned Scope, const std::string &Name) {280return ("pred:" + Twine(Scope) + ":" + Name).str();281}282283static std::string getMangledRootDefName(StringRef DefOperandName) {284return ("DstI[" + DefOperandName + "]").str();285}286287//===- GlobalISelEmitter class --------------------------------------------===//288289static Expected<LLTCodeGen> getInstResultType(const TreePatternNode &Dst,290const CodeGenTarget &Target) {291// While we allow more than one output (both implicit and explicit defs)292// below, we only expect one explicit def here.293assert(Dst.getOperator()->isSubClassOf("Instruction"));294CodeGenInstruction &InstInfo = Target.getInstruction(Dst.getOperator());295if (!InstInfo.Operands.NumDefs)296return failedImport("Dst pattern child needs a def");297298ArrayRef<TypeSetByHwMode> ChildTypes = Dst.getExtTypes();299if (ChildTypes.size() < 1)300return failedImport("Dst pattern child has no result");301302// If there are multiple results, just take the first one (this is how303// SelectionDAG does it).304std::optional<LLTCodeGen> MaybeOpTy;305if (ChildTypes.front().isMachineValueType()) {306MaybeOpTy = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);307}308309if (!MaybeOpTy)310return failedImport("Dst operand has an unsupported type");311return *MaybeOpTy;312}313314class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter {315public:316explicit GlobalISelEmitter(RecordKeeper &RK);317318void emitAdditionalImpl(raw_ostream &OS) override;319320void emitMIPredicateFns(raw_ostream &OS) override;321void emitI64ImmPredicateFns(raw_ostream &OS) override;322void emitAPFloatImmPredicateFns(raw_ostream &OS) override;323void emitAPIntImmPredicateFns(raw_ostream &OS) override;324void emitTestSimplePredicate(raw_ostream &OS) override;325void emitRunCustomAction(raw_ostream &OS) override;326327void postProcessRule(RuleMatcher &M);328329const CodeGenTarget &getTarget() const override { return Target; }330StringRef getClassName() const override { return ClassName; }331332void run(raw_ostream &OS);333334private:335std::string ClassName;336337const RecordKeeper &RK;338const CodeGenDAGPatterns CGP;339const CodeGenTarget &Target;340CodeGenRegBank &CGRegs;341342std::vector<Record *> AllPatFrags;343344/// Keep track of the equivalence between SDNodes and Instruction by mapping345/// SDNodes to the GINodeEquiv mapping. We need to map to the GINodeEquiv to346/// check for attributes on the relation such as CheckMMOIsNonAtomic.347/// This is defined using 'GINodeEquiv' in the target description.348DenseMap<Record *, Record *> NodeEquivs;349350/// Keep track of the equivalence between ComplexPattern's and351/// GIComplexOperandMatcher. Map entries are specified by subclassing352/// GIComplexPatternEquiv.353DenseMap<const Record *, const Record *> ComplexPatternEquivs;354355/// Keep track of the equivalence between SDNodeXForm's and356/// GICustomOperandRenderer. Map entries are specified by subclassing357/// GISDNodeXFormEquiv.358DenseMap<const Record *, const Record *> SDNodeXFormEquivs;359360/// Keep track of Scores of PatternsToMatch similar to how the DAG does.361/// This adds compatibility for RuleMatchers to use this for ordering rules.362DenseMap<uint64_t, int> RuleMatcherScores;363364// Rule coverage information.365std::optional<CodeGenCoverage> RuleCoverage;366367/// Variables used to help with collecting of named operands for predicates368/// with 'let PredicateCodeUsesOperands = 1'. WaitingForNamedOperands is set369/// to the number of named operands that predicate expects. Store locations in370/// StoreIdxForName correspond to the order in which operand names appear in371/// predicate's argument list.372/// When we visit named operand and WaitingForNamedOperands is not zero, add373/// matcher that will record operand and decrease counter.374unsigned WaitingForNamedOperands = 0;375StringMap<unsigned> StoreIdxForName;376377void gatherOpcodeValues();378void gatherTypeIDValues();379void gatherNodeEquivs();380381Record *findNodeEquiv(Record *N) const;382const CodeGenInstruction *getEquivNode(Record &Equiv,383const TreePatternNode &N) const;384385Error importRulePredicates(RuleMatcher &M, ArrayRef<Record *> Predicates);386Expected<InstructionMatcher &>387createAndImportSelDAGMatcher(RuleMatcher &Rule,388InstructionMatcher &InsnMatcher,389const TreePatternNode &Src, unsigned &TempOpIdx);390Error importComplexPatternOperandMatcher(OperandMatcher &OM, Record *R,391unsigned &TempOpIdx) const;392Error importChildMatcher(RuleMatcher &Rule, InstructionMatcher &InsnMatcher,393const TreePatternNode &SrcChild,394bool OperandIsAPointer, bool OperandIsImmArg,395unsigned OpIdx, unsigned &TempOpIdx);396397Expected<BuildMIAction &> createAndImportInstructionRenderer(398RuleMatcher &M, InstructionMatcher &InsnMatcher,399const TreePatternNode &Src, const TreePatternNode &Dst);400Expected<action_iterator> createAndImportSubInstructionRenderer(401action_iterator InsertPt, RuleMatcher &M, const TreePatternNode &Dst,402const TreePatternNode &Src, unsigned TempReg);403Expected<action_iterator>404createInstructionRenderer(action_iterator InsertPt, RuleMatcher &M,405const TreePatternNode &Dst);406407Expected<action_iterator>408importExplicitDefRenderers(action_iterator InsertPt, RuleMatcher &M,409BuildMIAction &DstMIBuilder,410const TreePatternNode &Src,411const TreePatternNode &Dst, unsigned Start = 0);412413Expected<action_iterator> importExplicitUseRenderers(414action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,415const llvm::TreePatternNode &Dst, const TreePatternNode &Src);416Expected<action_iterator> importExplicitUseRenderer(417action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder,418const TreePatternNode &DstChild, const TreePatternNode &Src);419Error importDefaultOperandRenderers(action_iterator InsertPt, RuleMatcher &M,420BuildMIAction &DstMIBuilder,421const DAGDefaultOperand &DefaultOp) const;422Error423importImplicitDefRenderers(BuildMIAction &DstMIBuilder,424const std::vector<Record *> &ImplicitDefs) const;425426/// Analyze pattern \p P, returning a matcher for it if possible.427/// Otherwise, return an Error explaining why we don't support it.428Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);429430void declareSubtargetFeature(Record *Predicate);431432unsigned declareHwModeCheck(StringRef HwModeFeatures);433434MatchTable buildMatchTable(MutableArrayRef<RuleMatcher> Rules, bool Optimize,435bool WithCoverage);436437/// Infer a CodeGenRegisterClass for the type of \p SuperRegNode. The returned438/// CodeGenRegisterClass will support the CodeGenRegisterClass of439/// \p SubRegNode, and the subregister index defined by \p SubRegIdxNode.440/// If no register class is found, return std::nullopt.441std::optional<const CodeGenRegisterClass *>442inferSuperRegisterClassForNode(const TypeSetByHwMode &Ty,443const TreePatternNode &SuperRegNode,444const TreePatternNode &SubRegIdxNode);445std::optional<CodeGenSubRegIndex *>446inferSubRegIndexForNode(const TreePatternNode &SubRegIdxNode);447448/// Infer a CodeGenRegisterClass which suppoorts \p Ty and \p SubRegIdxNode.449/// Return std::nullopt if no such class exists.450std::optional<const CodeGenRegisterClass *>451inferSuperRegisterClass(const TypeSetByHwMode &Ty,452const TreePatternNode &SubRegIdxNode);453454/// Return the CodeGenRegisterClass associated with \p Leaf if it has one.455std::optional<const CodeGenRegisterClass *>456getRegClassFromLeaf(const TreePatternNode &Leaf);457458/// Return a CodeGenRegisterClass for \p N if one can be found. Return459/// std::nullopt otherwise.460std::optional<const CodeGenRegisterClass *>461inferRegClassFromPattern(const TreePatternNode &N);462463/// Return the size of the MemoryVT in this predicate, if possible.464std::optional<unsigned>465getMemSizeBitsFromPredicate(const TreePredicateFn &Predicate);466467// Add builtin predicates.468Expected<InstructionMatcher &>469addBuiltinPredicates(const Record *SrcGIEquivOrNull,470const TreePredicateFn &Predicate,471InstructionMatcher &InsnMatcher, bool &HasAddedMatcher);472};473474StringRef getPatFragPredicateEnumName(Record *R) { return R->getName(); }475476void GlobalISelEmitter::gatherOpcodeValues() {477InstructionOpcodeMatcher::initOpcodeValuesMap(Target);478}479480void GlobalISelEmitter::gatherTypeIDValues() {481LLTOperandMatcher::initTypeIDValuesMap();482}483484void GlobalISelEmitter::gatherNodeEquivs() {485assert(NodeEquivs.empty());486for (Record *Equiv : RK.getAllDerivedDefinitions("GINodeEquiv"))487NodeEquivs[Equiv->getValueAsDef("Node")] = Equiv;488489assert(ComplexPatternEquivs.empty());490for (Record *Equiv : RK.getAllDerivedDefinitions("GIComplexPatternEquiv")) {491Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");492if (!SelDAGEquiv)493continue;494ComplexPatternEquivs[SelDAGEquiv] = Equiv;495}496497assert(SDNodeXFormEquivs.empty());498for (Record *Equiv : RK.getAllDerivedDefinitions("GISDNodeXFormEquiv")) {499Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");500if (!SelDAGEquiv)501continue;502SDNodeXFormEquivs[SelDAGEquiv] = Equiv;503}504}505506Record *GlobalISelEmitter::findNodeEquiv(Record *N) const {507return NodeEquivs.lookup(N);508}509510const CodeGenInstruction *511GlobalISelEmitter::getEquivNode(Record &Equiv, const TreePatternNode &N) const {512if (N.getNumChildren() >= 1) {513// setcc operation maps to two different G_* instructions based on the type.514if (!Equiv.isValueUnset("IfFloatingPoint") &&515MVT(N.getChild(0).getSimpleType(0)).isFloatingPoint())516return &Target.getInstruction(Equiv.getValueAsDef("IfFloatingPoint"));517}518519if (!Equiv.isValueUnset("IfConvergent") &&520N.getIntrinsicInfo(CGP)->isConvergent)521return &Target.getInstruction(Equiv.getValueAsDef("IfConvergent"));522523for (const TreePredicateCall &Call : N.getPredicateCalls()) {524const TreePredicateFn &Predicate = Call.Fn;525if (!Equiv.isValueUnset("IfSignExtend") &&526(Predicate.isLoad() || Predicate.isAtomic()) &&527Predicate.isSignExtLoad())528return &Target.getInstruction(Equiv.getValueAsDef("IfSignExtend"));529if (!Equiv.isValueUnset("IfZeroExtend") &&530(Predicate.isLoad() || Predicate.isAtomic()) &&531Predicate.isZeroExtLoad())532return &Target.getInstruction(Equiv.getValueAsDef("IfZeroExtend"));533}534535return &Target.getInstruction(Equiv.getValueAsDef("I"));536}537538GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)539: GlobalISelMatchTableExecutorEmitter(), RK(RK), CGP(RK),540Target(CGP.getTargetInfo()), CGRegs(Target.getRegBank()) {541ClassName = Target.getName().str() + "InstructionSelector";542}543544//===- Emitter ------------------------------------------------------------===//545546Error GlobalISelEmitter::importRulePredicates(RuleMatcher &M,547ArrayRef<Record *> Predicates) {548for (Record *Pred : Predicates) {549if (Pred->getValueAsString("CondString").empty())550continue;551declareSubtargetFeature(Pred);552M.addRequiredFeature(Pred);553}554555return Error::success();556}557558std::optional<unsigned> GlobalISelEmitter::getMemSizeBitsFromPredicate(559const TreePredicateFn &Predicate) {560std::optional<LLTCodeGen> MemTyOrNone =561MVTToLLT(getValueType(Predicate.getMemoryVT()));562563if (!MemTyOrNone)564return std::nullopt;565566// Align so unusual types like i1 don't get rounded down.567return llvm::alignTo(568static_cast<unsigned>(MemTyOrNone->get().getSizeInBits()), 8);569}570571Expected<InstructionMatcher &> GlobalISelEmitter::addBuiltinPredicates(572const Record *SrcGIEquivOrNull, const TreePredicateFn &Predicate,573InstructionMatcher &InsnMatcher, bool &HasAddedMatcher) {574if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {575if (const ListInit *AddrSpaces = Predicate.getAddressSpaces()) {576SmallVector<unsigned, 4> ParsedAddrSpaces;577578for (Init *Val : AddrSpaces->getValues()) {579IntInit *IntVal = dyn_cast<IntInit>(Val);580if (!IntVal)581return failedImport("Address space is not an integer");582ParsedAddrSpaces.push_back(IntVal->getValue());583}584585if (!ParsedAddrSpaces.empty()) {586InsnMatcher.addPredicate<MemoryAddressSpacePredicateMatcher>(5870, ParsedAddrSpaces);588return InsnMatcher;589}590}591592int64_t MinAlign = Predicate.getMinAlignment();593if (MinAlign > 0) {594InsnMatcher.addPredicate<MemoryAlignmentPredicateMatcher>(0, MinAlign);595return InsnMatcher;596}597}598599// G_LOAD is used for both non-extending and any-extending loads.600if (Predicate.isLoad() && Predicate.isNonExtLoad()) {601InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(6020, MemoryVsLLTSizePredicateMatcher::EqualTo, 0);603return InsnMatcher;604}605if (Predicate.isLoad() && Predicate.isAnyExtLoad()) {606InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(6070, MemoryVsLLTSizePredicateMatcher::LessThan, 0);608return InsnMatcher;609}610611if (Predicate.isStore()) {612if (Predicate.isTruncStore()) {613if (Predicate.getMemoryVT() != nullptr) {614// FIXME: If MemoryVT is set, we end up with 2 checks for the MMO size.615auto MemSizeInBits = getMemSizeBitsFromPredicate(Predicate);616if (!MemSizeInBits)617return failedImport("MemVT could not be converted to LLT");618619InsnMatcher.addPredicate<MemorySizePredicateMatcher>(0, *MemSizeInBits /6208);621} else {622InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(6230, MemoryVsLLTSizePredicateMatcher::LessThan, 0);624}625return InsnMatcher;626}627if (Predicate.isNonTruncStore()) {628// We need to check the sizes match here otherwise we could incorrectly629// match truncating stores with non-truncating ones.630InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(6310, MemoryVsLLTSizePredicateMatcher::EqualTo, 0);632}633}634635assert(SrcGIEquivOrNull != nullptr && "Invalid SrcGIEquivOrNull value");636// No check required. We already did it by swapping the opcode.637if (!SrcGIEquivOrNull->isValueUnset("IfSignExtend") &&638Predicate.isSignExtLoad())639return InsnMatcher;640641// No check required. We already did it by swapping the opcode.642if (!SrcGIEquivOrNull->isValueUnset("IfZeroExtend") &&643Predicate.isZeroExtLoad())644return InsnMatcher;645646// No check required. G_STORE by itself is a non-extending store.647if (Predicate.isNonTruncStore())648return InsnMatcher;649650if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {651if (Predicate.getMemoryVT() != nullptr) {652auto MemSizeInBits = getMemSizeBitsFromPredicate(Predicate);653if (!MemSizeInBits)654return failedImport("MemVT could not be converted to LLT");655656InsnMatcher.addPredicate<MemorySizePredicateMatcher>(0,657*MemSizeInBits / 8);658return InsnMatcher;659}660}661662if (Predicate.isLoad() || Predicate.isStore()) {663// No check required. A G_LOAD/G_STORE is an unindexed load.664if (Predicate.isUnindexed())665return InsnMatcher;666}667668if (Predicate.isAtomic()) {669if (Predicate.isAtomicOrderingMonotonic()) {670InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Monotonic");671return InsnMatcher;672}673if (Predicate.isAtomicOrderingAcquire()) {674InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Acquire");675return InsnMatcher;676}677if (Predicate.isAtomicOrderingRelease()) {678InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Release");679return InsnMatcher;680}681if (Predicate.isAtomicOrderingAcquireRelease()) {682InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(683"AcquireRelease");684return InsnMatcher;685}686if (Predicate.isAtomicOrderingSequentiallyConsistent()) {687InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(688"SequentiallyConsistent");689return InsnMatcher;690}691}692693if (Predicate.isAtomicOrderingAcquireOrStronger()) {694InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(695"Acquire", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);696return InsnMatcher;697}698if (Predicate.isAtomicOrderingWeakerThanAcquire()) {699InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(700"Acquire", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);701return InsnMatcher;702}703704if (Predicate.isAtomicOrderingReleaseOrStronger()) {705InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(706"Release", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);707return InsnMatcher;708}709if (Predicate.isAtomicOrderingWeakerThanRelease()) {710InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(711"Release", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);712return InsnMatcher;713}714HasAddedMatcher = false;715return InsnMatcher;716}717718Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(719RuleMatcher &Rule, InstructionMatcher &InsnMatcher,720const TreePatternNode &Src, unsigned &TempOpIdx) {721const auto SavedFlags = Rule.setGISelFlags(Src.getGISelFlagsRecord());722723Record *SrcGIEquivOrNull = nullptr;724const CodeGenInstruction *SrcGIOrNull = nullptr;725726// Start with the defined operands (i.e., the results of the root operator).727if (Src.isLeaf()) {728Init *SrcInit = Src.getLeafValue();729if (isa<IntInit>(SrcInit)) {730InsnMatcher.addPredicate<InstructionOpcodeMatcher>(731&Target.getInstruction(RK.getDef("G_CONSTANT")));732} else733return failedImport(734"Unable to deduce gMIR opcode to handle Src (which is a leaf)");735} else {736SrcGIEquivOrNull = findNodeEquiv(Src.getOperator());737if (!SrcGIEquivOrNull)738return failedImport("Pattern operator lacks an equivalent Instruction" +739explainOperator(Src.getOperator()));740SrcGIOrNull = getEquivNode(*SrcGIEquivOrNull, Src);741742// The operators look good: match the opcode743InsnMatcher.addPredicate<InstructionOpcodeMatcher>(SrcGIOrNull);744}745746unsigned OpIdx = 0;747for (const TypeSetByHwMode &VTy : Src.getExtTypes()) {748// Results don't have a name unless they are the root node. The caller will749// set the name if appropriate.750const bool OperandIsAPointer =751SrcGIOrNull && SrcGIOrNull->isOutOperandAPointer(OpIdx);752OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);753if (auto Error = OM.addTypeCheckPredicate(VTy, OperandIsAPointer))754return failedImport(toString(std::move(Error)) +755" for result of Src pattern operator");756}757758for (const TreePredicateCall &Call : Src.getPredicateCalls()) {759const TreePredicateFn &Predicate = Call.Fn;760bool HasAddedBuiltinMatcher = true;761if (Predicate.isAlwaysTrue())762continue;763764if (Predicate.isImmediatePattern()) {765InsnMatcher.addPredicate<InstructionImmPredicateMatcher>(Predicate);766continue;767}768769auto InsnMatcherOrError = addBuiltinPredicates(770SrcGIEquivOrNull, Predicate, InsnMatcher, HasAddedBuiltinMatcher);771if (auto Error = InsnMatcherOrError.takeError())772return std::move(Error);773774// FIXME: This should be part of addBuiltinPredicates(). If we add this at775// the start of addBuiltinPredicates() without returning, then there might776// be cases where we hit the last return before which the777// HasAddedBuiltinMatcher will be set to false. The predicate could be778// missed if we add it in the middle or at the end due to return statements779// after the addPredicate<>() calls.780if (Predicate.hasNoUse()) {781InsnMatcher.addPredicate<NoUsePredicateMatcher>();782HasAddedBuiltinMatcher = true;783}784if (Predicate.hasOneUse()) {785InsnMatcher.addPredicate<OneUsePredicateMatcher>();786HasAddedBuiltinMatcher = true;787}788789if (Predicate.hasGISelPredicateCode()) {790if (Predicate.usesOperands()) {791assert(WaitingForNamedOperands == 0 &&792"previous predicate didn't find all operands or "793"nested predicate that uses operands");794TreePattern *TP = Predicate.getOrigPatFragRecord();795WaitingForNamedOperands = TP->getNumArgs();796for (unsigned I = 0; I < WaitingForNamedOperands; ++I)797StoreIdxForName[getScopedName(Call.Scope, TP->getArgName(I))] = I;798}799InsnMatcher.addPredicate<GenericInstructionPredicateMatcher>(Predicate);800continue;801}802if (!HasAddedBuiltinMatcher) {803return failedImport("Src pattern child has predicate (" +804explainPredicates(Src) + ")");805}806}807808if (SrcGIEquivOrNull &&809SrcGIEquivOrNull->getValueAsBit("CheckMMOIsNonAtomic"))810InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("NotAtomic");811else if (SrcGIEquivOrNull &&812SrcGIEquivOrNull->getValueAsBit("CheckMMOIsAtomic")) {813InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(814"Unordered", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);815}816817if (Src.isLeaf()) {818Init *SrcInit = Src.getLeafValue();819if (IntInit *SrcIntInit = dyn_cast<IntInit>(SrcInit)) {820OperandMatcher &OM =821InsnMatcher.addOperand(OpIdx++, Src.getName(), TempOpIdx);822OM.addPredicate<LiteralIntOperandMatcher>(SrcIntInit->getValue());823} else824return failedImport(825"Unable to deduce gMIR opcode to handle Src (which is a leaf)");826} else {827assert(SrcGIOrNull &&828"Expected to have already found an equivalent Instruction");829if (SrcGIOrNull->TheDef->getName() == "G_CONSTANT" ||830SrcGIOrNull->TheDef->getName() == "G_FCONSTANT") {831// imm/fpimm still have operands but we don't need to do anything with it832// here since we don't support ImmLeaf predicates yet. However, we still833// need to note the hidden operand to get GIM_CheckNumOperands correct.834InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);835return InsnMatcher;836}837838if (SrcGIOrNull->TheDef->getName() == "G_FRAME_INDEX") {839InsnMatcher.addOperand(OpIdx++, Src.getName(), TempOpIdx);840return InsnMatcher;841}842843// Special case because the operand order is changed from setcc. The844// predicate operand needs to be swapped from the last operand to the first845// source.846847unsigned NumChildren = Src.getNumChildren();848bool IsFCmp = SrcGIOrNull->TheDef->getName() == "G_FCMP";849850if (IsFCmp || SrcGIOrNull->TheDef->getName() == "G_ICMP") {851const TreePatternNode &SrcChild = Src.getChild(NumChildren - 1);852if (SrcChild.isLeaf()) {853DefInit *DI = dyn_cast<DefInit>(SrcChild.getLeafValue());854Record *CCDef = DI ? DI->getDef() : nullptr;855if (!CCDef || !CCDef->isSubClassOf("CondCode"))856return failedImport("Unable to handle CondCode");857858OperandMatcher &OM =859InsnMatcher.addOperand(OpIdx++, SrcChild.getName(), TempOpIdx);860StringRef PredType = IsFCmp ? CCDef->getValueAsString("FCmpPredicate")861: CCDef->getValueAsString("ICmpPredicate");862863if (!PredType.empty()) {864OM.addPredicate<CmpPredicateOperandMatcher>(std::string(PredType));865// Process the other 2 operands normally.866--NumChildren;867}868}869}870871// Match the used operands (i.e. the children of the operator).872bool IsIntrinsic =873SrcGIOrNull->TheDef->getName() == "G_INTRINSIC" ||874SrcGIOrNull->TheDef->getName() == "G_INTRINSIC_W_SIDE_EFFECTS" ||875SrcGIOrNull->TheDef->getName() == "G_INTRINSIC_CONVERGENT" ||876SrcGIOrNull->TheDef->getName() ==877"G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS";878const CodeGenIntrinsic *II = Src.getIntrinsicInfo(CGP);879if (IsIntrinsic && !II)880return failedImport("Expected IntInit containing intrinsic ID)");881882for (unsigned I = 0; I != NumChildren; ++I) {883const TreePatternNode &SrcChild = Src.getChild(I);884885// We need to determine the meaning of a literal integer based on the886// context. If this is a field required to be an immediate (such as an887// immarg intrinsic argument), the required predicates are different than888// a constant which may be materialized in a register. If we have an889// argument that is required to be an immediate, we should not emit an LLT890// type check, and should not be looking for a G_CONSTANT defined891// register.892bool OperandIsImmArg = SrcGIOrNull->isInOperandImmArg(I);893894// SelectionDAG allows pointers to be represented with iN since it doesn't895// distinguish between pointers and integers but they are different types896// in GlobalISel. Coerce integers to pointers to address space 0 if the897// context indicates a pointer.898//899bool OperandIsAPointer = SrcGIOrNull->isInOperandAPointer(I);900901if (IsIntrinsic) {902// For G_INTRINSIC/G_INTRINSIC_W_SIDE_EFFECTS, the operand immediately903// following the defs is an intrinsic ID.904if (I == 0) {905OperandMatcher &OM =906InsnMatcher.addOperand(OpIdx++, SrcChild.getName(), TempOpIdx);907OM.addPredicate<IntrinsicIDOperandMatcher>(II);908continue;909}910911// We have to check intrinsics for llvm_anyptr_ty and immarg parameters.912//913// Note that we have to look at the i-1th parameter, because we don't914// have the intrinsic ID in the intrinsic's parameter list.915OperandIsAPointer |= II->isParamAPointer(I - 1);916OperandIsImmArg |= II->isParamImmArg(I - 1);917}918919if (auto Error =920importChildMatcher(Rule, InsnMatcher, SrcChild, OperandIsAPointer,921OperandIsImmArg, OpIdx++, TempOpIdx))922return std::move(Error);923}924}925926return InsnMatcher;927}928929Error GlobalISelEmitter::importComplexPatternOperandMatcher(930OperandMatcher &OM, Record *R, unsigned &TempOpIdx) const {931const auto &ComplexPattern = ComplexPatternEquivs.find(R);932if (ComplexPattern == ComplexPatternEquivs.end())933return failedImport("SelectionDAG ComplexPattern (" + R->getName() +934") not mapped to GlobalISel");935936OM.addPredicate<ComplexPatternOperandMatcher>(OM, *ComplexPattern->second);937TempOpIdx++;938return Error::success();939}940941// Get the name to use for a pattern operand. For an anonymous physical register942// input, this should use the register name.943static StringRef getSrcChildName(const TreePatternNode &SrcChild,944Record *&PhysReg) {945StringRef SrcChildName = SrcChild.getName();946if (SrcChildName.empty() && SrcChild.isLeaf()) {947if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild.getLeafValue())) {948auto *ChildRec = ChildDefInit->getDef();949if (ChildRec->isSubClassOf("Register")) {950SrcChildName = ChildRec->getName();951PhysReg = ChildRec;952}953}954}955956return SrcChildName;957}958959Error GlobalISelEmitter::importChildMatcher(960RuleMatcher &Rule, InstructionMatcher &InsnMatcher,961const TreePatternNode &SrcChild, bool OperandIsAPointer,962bool OperandIsImmArg, unsigned OpIdx, unsigned &TempOpIdx) {963964Record *PhysReg = nullptr;965std::string SrcChildName = std::string(getSrcChildName(SrcChild, PhysReg));966if (!SrcChild.isLeaf() &&967SrcChild.getOperator()->isSubClassOf("ComplexPattern")) {968// The "name" of a non-leaf complex pattern (MY_PAT $op1, $op2) is969// "MY_PAT:op1:op2" and the ones with same "name" represent same operand.970std::string PatternName = std::string(SrcChild.getOperator()->getName());971for (unsigned I = 0; I < SrcChild.getNumChildren(); ++I) {972PatternName += ":";973PatternName += SrcChild.getChild(I).getName();974}975SrcChildName = PatternName;976}977978OperandMatcher &OM =979PhysReg ? InsnMatcher.addPhysRegInput(PhysReg, OpIdx, TempOpIdx)980: InsnMatcher.addOperand(OpIdx, SrcChildName, TempOpIdx);981if (OM.isSameAsAnotherOperand())982return Error::success();983984ArrayRef<TypeSetByHwMode> ChildTypes = SrcChild.getExtTypes();985if (ChildTypes.size() != 1)986return failedImport("Src pattern child has multiple results");987988// Check MBB's before the type check since they are not a known type.989if (!SrcChild.isLeaf()) {990if (SrcChild.getOperator()->isSubClassOf("SDNode")) {991auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild.getOperator());992if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {993OM.addPredicate<MBBOperandMatcher>();994return Error::success();995}996if (SrcChild.getOperator()->getName() == "timm") {997OM.addPredicate<ImmOperandMatcher>();998999// Add predicates, if any1000for (const TreePredicateCall &Call : SrcChild.getPredicateCalls()) {1001const TreePredicateFn &Predicate = Call.Fn;10021003// Only handle immediate patterns for now1004if (Predicate.isImmediatePattern()) {1005OM.addPredicate<OperandImmPredicateMatcher>(Predicate);1006}1007}10081009return Error::success();1010}1011}1012}10131014// Immediate arguments have no meaningful type to check as they don't have1015// registers.1016if (!OperandIsImmArg) {1017if (auto Error =1018OM.addTypeCheckPredicate(ChildTypes.front(), OperandIsAPointer))1019return failedImport(toString(std::move(Error)) + " for Src operand (" +1020to_string(SrcChild) + ")");1021}10221023// Try look up SrcChild for a (named) predicate operand if there is any.1024if (WaitingForNamedOperands) {1025auto &ScopedNames = SrcChild.getNamesAsPredicateArg();1026if (!ScopedNames.empty()) {1027auto PA = ScopedNames.begin();1028std::string Name = getScopedName(PA->getScope(), PA->getIdentifier());1029OM.addPredicate<RecordNamedOperandMatcher>(StoreIdxForName[Name], Name);1030--WaitingForNamedOperands;1031}1032}10331034// Check for nested instructions.1035if (!SrcChild.isLeaf()) {1036if (SrcChild.getOperator()->isSubClassOf("ComplexPattern")) {1037// When a ComplexPattern is used as an operator, it should do the same1038// thing as when used as a leaf. However, the children of the operator1039// name the sub-operands that make up the complex operand and we must1040// prepare to reference them in the renderer too.1041unsigned RendererID = TempOpIdx;1042if (auto Error = importComplexPatternOperandMatcher(1043OM, SrcChild.getOperator(), TempOpIdx))1044return Error;10451046for (unsigned I = 0, E = SrcChild.getNumChildren(); I != E; ++I) {1047auto &SubOperand = SrcChild.getChild(I);1048if (!SubOperand.getName().empty()) {1049if (auto Error = Rule.defineComplexSubOperand(1050SubOperand.getName(), SrcChild.getOperator(), RendererID, I,1051SrcChildName))1052return Error;1053}1054}10551056return Error::success();1057}10581059auto MaybeInsnOperand = OM.addPredicate<InstructionOperandMatcher>(1060InsnMatcher.getRuleMatcher(), SrcChild.getName());1061if (!MaybeInsnOperand) {1062// This isn't strictly true. If the user were to provide exactly the same1063// matchers as the original operand then we could allow it. However, it's1064// simpler to not permit the redundant specification.1065return failedImport(1066"Nested instruction cannot be the same as another operand");1067}10681069// Map the node to a gMIR instruction.1070InstructionOperandMatcher &InsnOperand = **MaybeInsnOperand;1071auto InsnMatcherOrError = createAndImportSelDAGMatcher(1072Rule, InsnOperand.getInsnMatcher(), SrcChild, TempOpIdx);1073if (auto Error = InsnMatcherOrError.takeError())1074return Error;10751076return Error::success();1077}10781079if (SrcChild.hasAnyPredicate())1080return failedImport("Src pattern child has unsupported predicate");10811082// Check for constant immediates.1083if (auto *ChildInt = dyn_cast<IntInit>(SrcChild.getLeafValue())) {1084if (OperandIsImmArg) {1085// Checks for argument directly in operand list1086OM.addPredicate<LiteralIntOperandMatcher>(ChildInt->getValue());1087} else {1088// Checks for materialized constant1089OM.addPredicate<ConstantIntOperandMatcher>(ChildInt->getValue());1090}1091return Error::success();1092}10931094// Check for def's like register classes or ComplexPattern's.1095if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild.getLeafValue())) {1096auto *ChildRec = ChildDefInit->getDef();10971098// Check for register classes.1099if (ChildRec->isSubClassOf("RegisterClass") ||1100ChildRec->isSubClassOf("RegisterOperand")) {1101OM.addPredicate<RegisterBankOperandMatcher>(1102Target.getRegisterClass(getInitValueAsRegClass(ChildDefInit)));1103return Error::success();1104}11051106if (ChildRec->isSubClassOf("Register")) {1107// This just be emitted as a copy to the specific register.1108ValueTypeByHwMode VT = ChildTypes.front().getValueTypeByHwMode();1109const CodeGenRegisterClass *RC =1110CGRegs.getMinimalPhysRegClass(ChildRec, &VT);1111if (!RC) {1112return failedImport(1113"Could not determine physical register class of pattern source");1114}11151116OM.addPredicate<RegisterBankOperandMatcher>(*RC);1117return Error::success();1118}11191120// Check for ValueType.1121if (ChildRec->isSubClassOf("ValueType")) {1122// We already added a type check as standard practice so this doesn't need1123// to do anything.1124return Error::success();1125}11261127// Check for ComplexPattern's.1128if (ChildRec->isSubClassOf("ComplexPattern"))1129return importComplexPatternOperandMatcher(OM, ChildRec, TempOpIdx);11301131if (ChildRec->isSubClassOf("ImmLeaf")) {1132return failedImport(1133"Src pattern child def is an unsupported tablegen class (ImmLeaf)");1134}11351136// Place holder for SRCVALUE nodes. Nothing to do here.1137if (ChildRec->getName() == "srcvalue")1138return Error::success();11391140const bool ImmAllOnesV = ChildRec->getName() == "immAllOnesV";1141if (ImmAllOnesV || ChildRec->getName() == "immAllZerosV") {1142auto MaybeInsnOperand = OM.addPredicate<InstructionOperandMatcher>(1143InsnMatcher.getRuleMatcher(), SrcChild.getName(), false);1144InstructionOperandMatcher &InsnOperand = **MaybeInsnOperand;11451146ValueTypeByHwMode VTy = ChildTypes.front().getValueTypeByHwMode();11471148const CodeGenInstruction &BuildVector =1149Target.getInstruction(RK.getDef("G_BUILD_VECTOR"));1150const CodeGenInstruction &BuildVectorTrunc =1151Target.getInstruction(RK.getDef("G_BUILD_VECTOR_TRUNC"));11521153// Treat G_BUILD_VECTOR as the canonical opcode, and G_BUILD_VECTOR_TRUNC1154// as an alternative.1155InsnOperand.getInsnMatcher().addPredicate<InstructionOpcodeMatcher>(1156ArrayRef({&BuildVector, &BuildVectorTrunc}));11571158// TODO: Handle both G_BUILD_VECTOR and G_BUILD_VECTOR_TRUNC We could1159// theoretically not emit any opcode check, but getOpcodeMatcher currently1160// has to succeed.1161OperandMatcher &OM =1162InsnOperand.getInsnMatcher().addOperand(0, "", TempOpIdx);1163if (auto Error =1164OM.addTypeCheckPredicate(VTy, false /* OperandIsAPointer */))1165return failedImport(toString(std::move(Error)) +1166" for result of Src pattern operator");11671168InsnOperand.getInsnMatcher().addPredicate<VectorSplatImmPredicateMatcher>(1169ImmAllOnesV ? VectorSplatImmPredicateMatcher::AllOnes1170: VectorSplatImmPredicateMatcher::AllZeros);1171return Error::success();1172}11731174return failedImport(1175"Src pattern child def is an unsupported tablegen class");1176}11771178return failedImport("Src pattern child is an unsupported kind");1179}11801181Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(1182action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder,1183const TreePatternNode &DstChild, const TreePatternNode &Src) {11841185const auto &SubOperand = Rule.getComplexSubOperand(DstChild.getName());1186if (SubOperand) {1187DstMIBuilder.addRenderer<RenderComplexPatternOperand>(1188*std::get<0>(*SubOperand), DstChild.getName(), std::get<1>(*SubOperand),1189std::get<2>(*SubOperand));1190return InsertPt;1191}11921193if (!DstChild.isLeaf()) {1194if (DstChild.getOperator()->isSubClassOf("SDNodeXForm")) {1195auto &Child = DstChild.getChild(0);1196auto I = SDNodeXFormEquivs.find(DstChild.getOperator());1197if (I != SDNodeXFormEquivs.end()) {1198Record *XFormOpc = DstChild.getOperator()->getValueAsDef("Opcode");1199if (XFormOpc->getName() == "timm") {1200// If this is a TargetConstant, there won't be a corresponding1201// instruction to transform. Instead, this will refer directly to an1202// operand in an instruction's operand list.1203DstMIBuilder.addRenderer<CustomOperandRenderer>(*I->second,1204Child.getName());1205} else {1206DstMIBuilder.addRenderer<CustomRenderer>(*I->second, Child.getName());1207}12081209return InsertPt;1210}1211return failedImport("SDNodeXForm " + Child.getName() +1212" has no custom renderer");1213}12141215// We accept 'bb' here. It's an operator because BasicBlockSDNode isn't1216// inline, but in MI it's just another operand.1217if (DstChild.getOperator()->isSubClassOf("SDNode")) {1218auto &ChildSDNI = CGP.getSDNodeInfo(DstChild.getOperator());1219if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {1220DstMIBuilder.addRenderer<CopyRenderer>(DstChild.getName());1221return InsertPt;1222}1223}12241225// Similarly, imm is an operator in TreePatternNode's view but must be1226// rendered as operands.1227// FIXME: The target should be able to choose sign-extended when appropriate1228// (e.g. on Mips).1229if (DstChild.getOperator()->getName() == "timm") {1230DstMIBuilder.addRenderer<CopyRenderer>(DstChild.getName());1231return InsertPt;1232}1233if (DstChild.getOperator()->getName() == "tframeindex") {1234DstMIBuilder.addRenderer<CopyRenderer>(DstChild.getName());1235return InsertPt;1236}1237if (DstChild.getOperator()->getName() == "imm") {1238DstMIBuilder.addRenderer<CopyConstantAsImmRenderer>(DstChild.getName());1239return InsertPt;1240}1241if (DstChild.getOperator()->getName() == "fpimm") {1242DstMIBuilder.addRenderer<CopyFConstantAsFPImmRenderer>(1243DstChild.getName());1244return InsertPt;1245}12461247if (DstChild.getOperator()->isSubClassOf("Instruction")) {1248auto OpTy = getInstResultType(DstChild, Target);1249if (!OpTy)1250return OpTy.takeError();12511252unsigned TempRegID = Rule.allocateTempRegID();1253InsertPt =1254Rule.insertAction<MakeTempRegisterAction>(InsertPt, *OpTy, TempRegID);1255DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID);12561257auto InsertPtOrError = createAndImportSubInstructionRenderer(1258++InsertPt, Rule, DstChild, Src, TempRegID);1259if (auto Error = InsertPtOrError.takeError())1260return std::move(Error);1261return InsertPtOrError.get();1262}12631264return failedImport("Dst pattern child isn't a leaf node or an MBB" +1265llvm::to_string(DstChild));1266}12671268// It could be a specific immediate in which case we should just check for1269// that immediate.1270if (const IntInit *ChildIntInit =1271dyn_cast<IntInit>(DstChild.getLeafValue())) {1272DstMIBuilder.addRenderer<ImmRenderer>(ChildIntInit->getValue());1273return InsertPt;1274}12751276// Otherwise, we're looking for a bog-standard RegisterClass operand.1277if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild.getLeafValue())) {1278auto *ChildRec = ChildDefInit->getDef();12791280ArrayRef<TypeSetByHwMode> ChildTypes = DstChild.getExtTypes();1281if (ChildTypes.size() != 1)1282return failedImport("Dst pattern child has multiple results");12831284std::optional<LLTCodeGen> OpTyOrNone;1285if (ChildTypes.front().isMachineValueType())1286OpTyOrNone = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);1287if (!OpTyOrNone)1288return failedImport("Dst operand has an unsupported type");12891290if (ChildRec->isSubClassOf("Register")) {1291DstMIBuilder.addRenderer<AddRegisterRenderer>(Target, ChildRec);1292return InsertPt;1293}12941295if (ChildRec->isSubClassOf("RegisterClass") ||1296ChildRec->isSubClassOf("RegisterOperand") ||1297ChildRec->isSubClassOf("ValueType")) {1298if (ChildRec->isSubClassOf("RegisterOperand") &&1299!ChildRec->isValueUnset("GIZeroRegister")) {1300DstMIBuilder.addRenderer<CopyOrAddZeroRegRenderer>(1301DstChild.getName(), ChildRec->getValueAsDef("GIZeroRegister"));1302return InsertPt;1303}13041305DstMIBuilder.addRenderer<CopyRenderer>(DstChild.getName());1306return InsertPt;1307}13081309if (ChildRec->isSubClassOf("SubRegIndex")) {1310CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(ChildRec);1311DstMIBuilder.addRenderer<ImmRenderer>(SubIdx->EnumValue);1312return InsertPt;1313}13141315if (ChildRec->isSubClassOf("ComplexPattern")) {1316const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);1317if (ComplexPattern == ComplexPatternEquivs.end())1318return failedImport(1319"SelectionDAG ComplexPattern not mapped to GlobalISel");13201321const OperandMatcher &OM = Rule.getOperandMatcher(DstChild.getName());1322DstMIBuilder.addRenderer<RenderComplexPatternOperand>(1323*ComplexPattern->second, DstChild.getName(),1324OM.getAllocatedTemporariesBaseID());1325return InsertPt;1326}13271328return failedImport(1329"Dst pattern child def is an unsupported tablegen class");1330}13311332// Handle the case where the MVT/register class is omitted in the dest pattern1333// but MVT exists in the source pattern.1334if (isa<UnsetInit>(DstChild.getLeafValue())) {1335for (unsigned NumOp = 0; NumOp < Src.getNumChildren(); NumOp++)1336if (Src.getChild(NumOp).getName() == DstChild.getName()) {1337DstMIBuilder.addRenderer<CopyRenderer>(Src.getChild(NumOp).getName());1338return InsertPt;1339}1340}1341return failedImport("Dst pattern child is an unsupported kind");1342}13431344Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(1345RuleMatcher &M, InstructionMatcher &InsnMatcher, const TreePatternNode &Src,1346const TreePatternNode &Dst) {1347auto InsertPtOrError = createInstructionRenderer(M.actions_end(), M, Dst);1348if (auto Error = InsertPtOrError.takeError())1349return std::move(Error);13501351action_iterator InsertPt = InsertPtOrError.get();1352BuildMIAction &DstMIBuilder = *static_cast<BuildMIAction *>(InsertPt->get());13531354for (auto PhysInput : InsnMatcher.getPhysRegInputs()) {1355InsertPt = M.insertAction<BuildMIAction>(1356InsertPt, M.allocateOutputInsnID(),1357&Target.getInstruction(RK.getDef("COPY")));1358BuildMIAction &CopyToPhysRegMIBuilder =1359*static_cast<BuildMIAction *>(InsertPt->get());1360CopyToPhysRegMIBuilder.addRenderer<AddRegisterRenderer>(1361Target, PhysInput.first, true);1362CopyToPhysRegMIBuilder.addRenderer<CopyPhysRegRenderer>(PhysInput.first);1363}13641365if (auto Error =1366importExplicitDefRenderers(InsertPt, M, DstMIBuilder, Src, Dst)1367.takeError())1368return std::move(Error);13691370if (auto Error =1371importExplicitUseRenderers(InsertPt, M, DstMIBuilder, Dst, Src)1372.takeError())1373return std::move(Error);13741375return DstMIBuilder;1376}13771378Expected<action_iterator>1379GlobalISelEmitter::createAndImportSubInstructionRenderer(1380const action_iterator InsertPt, RuleMatcher &M, const TreePatternNode &Dst,1381const TreePatternNode &Src, unsigned TempRegID) {1382auto InsertPtOrError = createInstructionRenderer(InsertPt, M, Dst);13831384// TODO: Assert there's exactly one result.13851386if (auto Error = InsertPtOrError.takeError())1387return std::move(Error);13881389BuildMIAction &DstMIBuilder =1390*static_cast<BuildMIAction *>(InsertPtOrError.get()->get());13911392// Assign the result to TempReg.1393DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, true);13941395// Handle additional (ignored) results.1396if (DstMIBuilder.getCGI()->Operands.NumDefs > 1) {1397InsertPtOrError = importExplicitDefRenderers(1398std::prev(*InsertPtOrError), M, DstMIBuilder, Src, Dst, /*Start=*/1);1399if (auto Error = InsertPtOrError.takeError())1400return std::move(Error);1401}14021403InsertPtOrError = importExplicitUseRenderers(InsertPtOrError.get(), M,1404DstMIBuilder, Dst, Src);1405if (auto Error = InsertPtOrError.takeError())1406return std::move(Error);14071408// We need to make sure that when we import an INSERT_SUBREG as a1409// subinstruction that it ends up being constrained to the correct super1410// register and subregister classes.1411auto OpName = Target.getInstruction(Dst.getOperator()).TheDef->getName();1412if (OpName == "INSERT_SUBREG") {1413auto SubClass = inferRegClassFromPattern(Dst.getChild(1));1414if (!SubClass)1415return failedImport(1416"Cannot infer register class from INSERT_SUBREG operand #1");1417std::optional<const CodeGenRegisterClass *> SuperClass =1418inferSuperRegisterClassForNode(Dst.getExtType(0), Dst.getChild(0),1419Dst.getChild(2));1420if (!SuperClass)1421return failedImport(1422"Cannot infer register class for INSERT_SUBREG operand #0");1423// The destination and the super register source of an INSERT_SUBREG must1424// be the same register class.1425M.insertAction<ConstrainOperandToRegClassAction>(1426InsertPt, DstMIBuilder.getInsnID(), 0, **SuperClass);1427M.insertAction<ConstrainOperandToRegClassAction>(1428InsertPt, DstMIBuilder.getInsnID(), 1, **SuperClass);1429M.insertAction<ConstrainOperandToRegClassAction>(1430InsertPt, DstMIBuilder.getInsnID(), 2, **SubClass);1431return InsertPtOrError.get();1432}14331434if (OpName == "EXTRACT_SUBREG") {1435// EXTRACT_SUBREG selects into a subregister COPY but unlike most1436// instructions, the result register class is controlled by the1437// subregisters of the operand. As a result, we must constrain the result1438// class rather than check that it's already the right one.1439auto SuperClass = inferRegClassFromPattern(Dst.getChild(0));1440if (!SuperClass)1441return failedImport(1442"Cannot infer register class from EXTRACT_SUBREG operand #0");14431444auto SubIdx = inferSubRegIndexForNode(Dst.getChild(1));1445if (!SubIdx)1446return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");14471448const auto SrcRCDstRCPair =1449(*SuperClass)->getMatchingSubClassWithSubRegs(CGRegs, *SubIdx);1450assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");1451M.insertAction<ConstrainOperandToRegClassAction>(1452InsertPt, DstMIBuilder.getInsnID(), 0, *SrcRCDstRCPair->second);1453M.insertAction<ConstrainOperandToRegClassAction>(1454InsertPt, DstMIBuilder.getInsnID(), 1, *SrcRCDstRCPair->first);14551456// We're done with this pattern! It's eligible for GISel emission; return1457// it.1458return InsertPtOrError.get();1459}14601461// Similar to INSERT_SUBREG, we also have to handle SUBREG_TO_REG as a1462// subinstruction.1463if (OpName == "SUBREG_TO_REG") {1464auto SubClass = inferRegClassFromPattern(Dst.getChild(1));1465if (!SubClass)1466return failedImport(1467"Cannot infer register class from SUBREG_TO_REG child #1");1468auto SuperClass =1469inferSuperRegisterClass(Dst.getExtType(0), Dst.getChild(2));1470if (!SuperClass)1471return failedImport(1472"Cannot infer register class for SUBREG_TO_REG operand #0");1473M.insertAction<ConstrainOperandToRegClassAction>(1474InsertPt, DstMIBuilder.getInsnID(), 0, **SuperClass);1475M.insertAction<ConstrainOperandToRegClassAction>(1476InsertPt, DstMIBuilder.getInsnID(), 2, **SubClass);1477return InsertPtOrError.get();1478}14791480if (OpName == "REG_SEQUENCE") {1481auto SuperClass = inferRegClassFromPattern(Dst.getChild(0));1482M.insertAction<ConstrainOperandToRegClassAction>(1483InsertPt, DstMIBuilder.getInsnID(), 0, **SuperClass);14841485unsigned Num = Dst.getNumChildren();1486for (unsigned I = 1; I != Num; I += 2) {1487const TreePatternNode &SubRegChild = Dst.getChild(I + 1);14881489auto SubIdx = inferSubRegIndexForNode(SubRegChild);1490if (!SubIdx)1491return failedImport("REG_SEQUENCE child is not a subreg index");14921493const auto SrcRCDstRCPair =1494(*SuperClass)->getMatchingSubClassWithSubRegs(CGRegs, *SubIdx);1495assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");1496M.insertAction<ConstrainOperandToRegClassAction>(1497InsertPt, DstMIBuilder.getInsnID(), I, *SrcRCDstRCPair->second);1498}14991500return InsertPtOrError.get();1501}15021503M.insertAction<ConstrainOperandsToDefinitionAction>(InsertPt,1504DstMIBuilder.getInsnID());1505return InsertPtOrError.get();1506}15071508Expected<action_iterator> GlobalISelEmitter::createInstructionRenderer(1509action_iterator InsertPt, RuleMatcher &M, const TreePatternNode &Dst) {1510Record *DstOp = Dst.getOperator();1511if (!DstOp->isSubClassOf("Instruction")) {1512if (DstOp->isSubClassOf("ValueType"))1513return failedImport(1514"Pattern operator isn't an instruction (it's a ValueType)");1515return failedImport("Pattern operator isn't an instruction");1516}1517CodeGenInstruction *DstI = &Target.getInstruction(DstOp);15181519// COPY_TO_REGCLASS is just a copy with a ConstrainOperandToRegClassAction1520// attached. Similarly for EXTRACT_SUBREG except that's a subregister copy.1521StringRef Name = DstI->TheDef->getName();1522if (Name == "COPY_TO_REGCLASS" || Name == "EXTRACT_SUBREG")1523DstI = &Target.getInstruction(RK.getDef("COPY"));15241525return M.insertAction<BuildMIAction>(InsertPt, M.allocateOutputInsnID(),1526DstI);1527}15281529Expected<action_iterator> GlobalISelEmitter::importExplicitDefRenderers(1530action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,1531const TreePatternNode &Src, const TreePatternNode &Dst, unsigned Start) {1532const CodeGenInstruction *DstI = DstMIBuilder.getCGI();1533const unsigned SrcNumDefs = Src.getExtTypes().size();1534const unsigned DstNumDefs = DstI->Operands.NumDefs;1535if (DstNumDefs == 0)1536return InsertPt;15371538for (unsigned I = Start; I < SrcNumDefs; ++I) {1539std::string OpName = getMangledRootDefName(DstI->Operands[I].Name);1540// CopyRenderer saves a StringRef, so cannot pass OpName itself -1541// let's use a string with an appropriate lifetime.1542StringRef PermanentRef = M.getOperandMatcher(OpName).getSymbolicName();1543DstMIBuilder.addRenderer<CopyRenderer>(PermanentRef);1544}15451546// Some instructions have multiple defs, but are missing a type entry1547// (e.g. s_cc_out operands).1548if (Dst.getExtTypes().size() < DstNumDefs)1549return failedImport("unhandled discarded def");15501551for (unsigned I = SrcNumDefs; I < DstNumDefs; ++I) {1552const TypeSetByHwMode &ExtTy = Dst.getExtType(I);1553if (!ExtTy.isMachineValueType())1554return failedImport("unsupported typeset");15551556auto OpTy = MVTToLLT(ExtTy.getMachineValueType().SimpleTy);1557if (!OpTy)1558return failedImport("unsupported type");15591560unsigned TempRegID = M.allocateTempRegID();1561InsertPt =1562M.insertAction<MakeTempRegisterAction>(InsertPt, *OpTy, TempRegID);1563DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, true, nullptr, true);1564}15651566return InsertPt;1567}15681569Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(1570action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,1571const llvm::TreePatternNode &Dst, const llvm::TreePatternNode &Src) {1572const CodeGenInstruction *DstI = DstMIBuilder.getCGI();1573CodeGenInstruction *OrigDstI = &Target.getInstruction(Dst.getOperator());15741575StringRef Name = OrigDstI->TheDef->getName();1576unsigned ExpectedDstINumUses = Dst.getNumChildren();15771578// EXTRACT_SUBREG needs to use a subregister COPY.1579if (Name == "EXTRACT_SUBREG") {1580if (!Dst.getChild(1).isLeaf())1581return failedImport("EXTRACT_SUBREG child #1 is not a leaf");1582DefInit *SubRegInit = dyn_cast<DefInit>(Dst.getChild(1).getLeafValue());1583if (!SubRegInit)1584return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");15851586CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());1587const TreePatternNode &ValChild = Dst.getChild(0);1588if (!ValChild.isLeaf()) {1589// We really have to handle the source instruction, and then insert a1590// copy from the subregister.1591auto ExtractSrcTy = getInstResultType(ValChild, Target);1592if (!ExtractSrcTy)1593return ExtractSrcTy.takeError();15941595unsigned TempRegID = M.allocateTempRegID();1596InsertPt = M.insertAction<MakeTempRegisterAction>(InsertPt, *ExtractSrcTy,1597TempRegID);15981599auto InsertPtOrError = createAndImportSubInstructionRenderer(1600++InsertPt, M, ValChild, Src, TempRegID);1601if (auto Error = InsertPtOrError.takeError())1602return std::move(Error);16031604DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, false, SubIdx);1605return InsertPt;1606}16071608// If this is a source operand, this is just a subregister copy.1609Record *RCDef = getInitValueAsRegClass(ValChild.getLeafValue());1610if (!RCDef)1611return failedImport("EXTRACT_SUBREG child #0 could not "1612"be coerced to a register class");16131614CodeGenRegisterClass *RC = CGRegs.getRegClass(RCDef);16151616const auto SrcRCDstRCPair =1617RC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);1618if (SrcRCDstRCPair) {1619assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");1620if (SrcRCDstRCPair->first != RC)1621return failedImport("EXTRACT_SUBREG requires an additional COPY");1622}16231624StringRef RegOperandName = Dst.getChild(0).getName();1625if (const auto &SubOperand = M.getComplexSubOperand(RegOperandName)) {1626DstMIBuilder.addRenderer<RenderComplexPatternOperand>(1627*std::get<0>(*SubOperand), RegOperandName, std::get<1>(*SubOperand),1628std::get<2>(*SubOperand), SubIdx);1629return InsertPt;1630}16311632DstMIBuilder.addRenderer<CopySubRegRenderer>(RegOperandName, SubIdx);1633return InsertPt;1634}16351636if (Name == "REG_SEQUENCE") {1637if (!Dst.getChild(0).isLeaf())1638return failedImport("REG_SEQUENCE child #0 is not a leaf");16391640Record *RCDef = getInitValueAsRegClass(Dst.getChild(0).getLeafValue());1641if (!RCDef)1642return failedImport("REG_SEQUENCE child #0 could not "1643"be coerced to a register class");16441645if ((ExpectedDstINumUses - 1) % 2 != 0)1646return failedImport("Malformed REG_SEQUENCE");16471648for (unsigned I = 1; I != ExpectedDstINumUses; I += 2) {1649const TreePatternNode &ValChild = Dst.getChild(I);1650const TreePatternNode &SubRegChild = Dst.getChild(I + 1);16511652if (DefInit *SubRegInit = dyn_cast<DefInit>(SubRegChild.getLeafValue())) {1653CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());16541655auto InsertPtOrError =1656importExplicitUseRenderer(InsertPt, M, DstMIBuilder, ValChild, Src);1657if (auto Error = InsertPtOrError.takeError())1658return std::move(Error);1659InsertPt = InsertPtOrError.get();1660DstMIBuilder.addRenderer<SubRegIndexRenderer>(SubIdx);1661}1662}16631664return InsertPt;1665}16661667// Render the explicit uses.1668unsigned DstINumUses = OrigDstI->Operands.size() - OrigDstI->Operands.NumDefs;1669if (Name == "COPY_TO_REGCLASS") {1670DstINumUses--; // Ignore the class constraint.1671ExpectedDstINumUses--;1672}16731674// NumResults - This is the number of results produced by the instruction in1675// the "outs" list.1676unsigned NumResults = OrigDstI->Operands.NumDefs;16771678// Number of operands we know the output instruction must have. If it is1679// variadic, we could have more operands.1680unsigned NumFixedOperands = DstI->Operands.size();16811682// Loop over all of the fixed operands of the instruction pattern, emitting1683// code to fill them all in. The node 'N' usually has number children equal to1684// the number of input operands of the instruction. However, in cases where1685// there are predicate operands for an instruction, we need to fill in the1686// 'execute always' values. Match up the node operands to the instruction1687// operands to do this.1688unsigned Child = 0;16891690// Similarly to the code in TreePatternNode::ApplyTypeConstraints, count the1691// number of operands at the end of the list which have default values.1692// Those can come from the pattern if it provides enough arguments, or be1693// filled in with the default if the pattern hasn't provided them. But any1694// operand with a default value _before_ the last mandatory one will be1695// filled in with their defaults unconditionally.1696unsigned NonOverridableOperands = NumFixedOperands;1697while (NonOverridableOperands > NumResults &&1698CGP.operandHasDefault(DstI->Operands[NonOverridableOperands - 1].Rec))1699--NonOverridableOperands;17001701unsigned NumDefaultOps = 0;1702for (unsigned I = 0; I != DstINumUses; ++I) {1703unsigned InstOpNo = DstI->Operands.NumDefs + I;17041705// Determine what to emit for this operand.1706Record *OperandNode = DstI->Operands[InstOpNo].Rec;17071708// If the operand has default values, introduce them now.1709if (CGP.operandHasDefault(OperandNode) &&1710(InstOpNo < NonOverridableOperands || Child >= Dst.getNumChildren())) {1711// This is a predicate or optional def operand which the pattern has not1712// overridden, or which we aren't letting it override; emit the 'default1713// ops' operands.17141715Record *OperandNode = DstI->Operands[InstOpNo].Rec;1716if (auto Error = importDefaultOperandRenderers(1717InsertPt, M, DstMIBuilder, CGP.getDefaultOperand(OperandNode)))1718return std::move(Error);17191720++NumDefaultOps;1721continue;1722}17231724auto InsertPtOrError = importExplicitUseRenderer(InsertPt, M, DstMIBuilder,1725Dst.getChild(Child), Src);1726if (auto Error = InsertPtOrError.takeError())1727return std::move(Error);1728InsertPt = InsertPtOrError.get();1729++Child;1730}17311732if (NumDefaultOps + ExpectedDstINumUses != DstINumUses)1733return failedImport("Expected " + llvm::to_string(DstINumUses) +1734" used operands but found " +1735llvm::to_string(ExpectedDstINumUses) +1736" explicit ones and " + llvm::to_string(NumDefaultOps) +1737" default ones");17381739return InsertPt;1740}17411742Error GlobalISelEmitter::importDefaultOperandRenderers(1743action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,1744const DAGDefaultOperand &DefaultOp) const {1745for (const auto &Op : DefaultOp.DefaultOps) {1746const auto &N = *Op;1747if (!N.isLeaf())1748return failedImport("Could not add default op");17491750const auto *DefaultOp = N.getLeafValue();17511752if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) {1753std::optional<LLTCodeGen> OpTyOrNone = MVTToLLT(N.getSimpleType(0));1754auto *Def = DefaultDefOp->getDef();1755if (Def->getName() == "undef_tied_input") {1756unsigned TempRegID = M.allocateTempRegID();1757M.insertAction<MakeTempRegisterAction>(InsertPt, *OpTyOrNone,1758TempRegID);1759InsertPt = M.insertAction<BuildMIAction>(1760InsertPt, M.allocateOutputInsnID(),1761&Target.getInstruction(RK.getDef("IMPLICIT_DEF")));1762BuildMIAction &IDMIBuilder =1763*static_cast<BuildMIAction *>(InsertPt->get());1764IDMIBuilder.addRenderer<TempRegRenderer>(TempRegID);1765DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID);1766} else {1767DstMIBuilder.addRenderer<AddRegisterRenderer>(Target, Def);1768}1769continue;1770}17711772if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) {1773DstMIBuilder.addRenderer<ImmRenderer>(DefaultIntOp->getValue());1774continue;1775}17761777return failedImport("Could not add default op");1778}17791780return Error::success();1781}17821783Error GlobalISelEmitter::importImplicitDefRenderers(1784BuildMIAction &DstMIBuilder,1785const std::vector<Record *> &ImplicitDefs) const {1786if (!ImplicitDefs.empty())1787return failedImport("Pattern defines a physical register");1788return Error::success();1789}17901791std::optional<const CodeGenRegisterClass *>1792GlobalISelEmitter::getRegClassFromLeaf(const TreePatternNode &Leaf) {1793assert(Leaf.isLeaf() && "Expected leaf?");1794Record *RCRec = getInitValueAsRegClass(Leaf.getLeafValue());1795if (!RCRec)1796return std::nullopt;1797CodeGenRegisterClass *RC = CGRegs.getRegClass(RCRec);1798if (!RC)1799return std::nullopt;1800return RC;1801}18021803std::optional<const CodeGenRegisterClass *>1804GlobalISelEmitter::inferRegClassFromPattern(const TreePatternNode &N) {1805if (N.isLeaf())1806return getRegClassFromLeaf(N);18071808// We don't have a leaf node, so we have to try and infer something. Check1809// that we have an instruction that we can infer something from.18101811// Only handle things that produce at least one value (if multiple values,1812// just take the first one).1813if (N.getNumTypes() < 1)1814return std::nullopt;1815Record *OpRec = N.getOperator();18161817// We only want instructions.1818if (!OpRec->isSubClassOf("Instruction"))1819return std::nullopt;18201821// Don't want to try and infer things when there could potentially be more1822// than one candidate register class.1823auto &Inst = Target.getInstruction(OpRec);18241825// Handle any special-case instructions which we can safely infer register1826// classes from.1827StringRef InstName = Inst.TheDef->getName();1828bool IsRegSequence = InstName == "REG_SEQUENCE";1829if (IsRegSequence || InstName == "COPY_TO_REGCLASS") {1830// If we have a COPY_TO_REGCLASS, then we need to handle it specially. It1831// has the desired register class as the first child.1832const TreePatternNode &RCChild = N.getChild(IsRegSequence ? 0 : 1);1833if (!RCChild.isLeaf())1834return std::nullopt;1835return getRegClassFromLeaf(RCChild);1836}1837if (InstName == "INSERT_SUBREG") {1838const TreePatternNode &Child0 = N.getChild(0);1839assert(Child0.getNumTypes() == 1 && "Unexpected number of types!");1840const TypeSetByHwMode &VTy = Child0.getExtType(0);1841return inferSuperRegisterClassForNode(VTy, Child0, N.getChild(2));1842}1843if (InstName == "EXTRACT_SUBREG") {1844assert(N.getNumTypes() == 1 && "Unexpected number of types!");1845const TypeSetByHwMode &VTy = N.getExtType(0);1846return inferSuperRegisterClass(VTy, N.getChild(1));1847}18481849// Handle destination record types that we can safely infer a register class1850// from.1851const auto &DstIOperand = Inst.Operands[0];1852Record *DstIOpRec = DstIOperand.Rec;1853if (DstIOpRec->isSubClassOf("RegisterOperand")) {1854DstIOpRec = DstIOpRec->getValueAsDef("RegClass");1855const CodeGenRegisterClass &RC = Target.getRegisterClass(DstIOpRec);1856return &RC;1857}18581859if (DstIOpRec->isSubClassOf("RegisterClass")) {1860const CodeGenRegisterClass &RC = Target.getRegisterClass(DstIOpRec);1861return &RC;1862}18631864return std::nullopt;1865}18661867std::optional<const CodeGenRegisterClass *>1868GlobalISelEmitter::inferSuperRegisterClass(1869const TypeSetByHwMode &Ty, const TreePatternNode &SubRegIdxNode) {1870// We need a ValueTypeByHwMode for getSuperRegForSubReg.1871if (!Ty.isValueTypeByHwMode(false))1872return std::nullopt;1873if (!SubRegIdxNode.isLeaf())1874return std::nullopt;1875DefInit *SubRegInit = dyn_cast<DefInit>(SubRegIdxNode.getLeafValue());1876if (!SubRegInit)1877return std::nullopt;1878CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());18791880// Use the information we found above to find a minimal register class which1881// supports the subregister and type we want.1882auto RC =1883Target.getSuperRegForSubReg(Ty.getValueTypeByHwMode(), CGRegs, SubIdx,1884/* MustBeAllocatable */ true);1885if (!RC)1886return std::nullopt;1887return *RC;1888}18891890std::optional<const CodeGenRegisterClass *>1891GlobalISelEmitter::inferSuperRegisterClassForNode(1892const TypeSetByHwMode &Ty, const TreePatternNode &SuperRegNode,1893const TreePatternNode &SubRegIdxNode) {1894// Check if we already have a defined register class for the super register1895// node. If we do, then we should preserve that rather than inferring anything1896// from the subregister index node. We can assume that whoever wrote the1897// pattern in the first place made sure that the super register and1898// subregister are compatible.1899if (std::optional<const CodeGenRegisterClass *> SuperRegisterClass =1900inferRegClassFromPattern(SuperRegNode))1901return *SuperRegisterClass;1902return inferSuperRegisterClass(Ty, SubRegIdxNode);1903}19041905std::optional<CodeGenSubRegIndex *> GlobalISelEmitter::inferSubRegIndexForNode(1906const TreePatternNode &SubRegIdxNode) {1907if (!SubRegIdxNode.isLeaf())1908return std::nullopt;19091910DefInit *SubRegInit = dyn_cast<DefInit>(SubRegIdxNode.getLeafValue());1911if (!SubRegInit)1912return std::nullopt;1913return CGRegs.getSubRegIdx(SubRegInit->getDef());1914}19151916Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {1917// Keep track of the matchers and actions to emit.1918int Score = P.getPatternComplexity(CGP);1919RuleMatcher M(P.getSrcRecord()->getLoc());1920RuleMatcherScores[M.getRuleID()] = Score;1921M.addAction<DebugCommentAction>(llvm::to_string(P.getSrcPattern()) +1922" => " +1923llvm::to_string(P.getDstPattern()));19241925SmallVector<Record *, 4> Predicates;1926P.getPredicateRecords(Predicates);1927if (auto Error = importRulePredicates(M, Predicates))1928return std::move(Error);19291930if (!P.getHwModeFeatures().empty())1931M.addHwModeIdx(declareHwModeCheck(P.getHwModeFeatures()));19321933// Next, analyze the pattern operators.1934TreePatternNode &Src = P.getSrcPattern();1935TreePatternNode &Dst = P.getDstPattern();19361937// If the root of either pattern isn't a simple operator, ignore it.1938if (auto Err = isTrivialOperatorNode(Dst))1939return failedImport("Dst pattern root isn't a trivial operator (" +1940toString(std::move(Err)) + ")");1941if (auto Err = isTrivialOperatorNode(Src))1942return failedImport("Src pattern root isn't a trivial operator (" +1943toString(std::move(Err)) + ")");19441945// The different predicates and matchers created during1946// addInstructionMatcher use the RuleMatcher M to set up their1947// instruction ID (InsnVarID) that are going to be used when1948// M is going to be emitted.1949// However, the code doing the emission still relies on the IDs1950// returned during that process by the RuleMatcher when issuing1951// the recordInsn opcodes.1952// Because of that:1953// 1. The order in which we created the predicates1954// and such must be the same as the order in which we emit them,1955// and1956// 2. We need to reset the generation of the IDs in M somewhere between1957// addInstructionMatcher and emit1958//1959// FIXME: Long term, we don't want to have to rely on this implicit1960// naming being the same. One possible solution would be to have1961// explicit operator for operation capture and reference those.1962// The plus side is that it would expose opportunities to share1963// the capture accross rules. The downside is that it would1964// introduce a dependency between predicates (captures must happen1965// before their first use.)1966InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher(Src.getName());1967unsigned TempOpIdx = 0;19681969const auto SavedFlags = M.setGISelFlags(P.getSrcRecord());19701971auto InsnMatcherOrError =1972createAndImportSelDAGMatcher(M, InsnMatcherTemp, Src, TempOpIdx);1973if (auto Error = InsnMatcherOrError.takeError())1974return std::move(Error);1975InstructionMatcher &InsnMatcher = InsnMatcherOrError.get();19761977if (Dst.isLeaf()) {1978Record *RCDef = getInitValueAsRegClass(Dst.getLeafValue());1979if (RCDef) {1980const CodeGenRegisterClass &RC = Target.getRegisterClass(RCDef);19811982// We need to replace the def and all its uses with the specified1983// operand. However, we must also insert COPY's wherever needed.1984// For now, emit a copy and let the register allocator clean up.1985auto &DstI = Target.getInstruction(RK.getDef("COPY"));1986const auto &DstIOperand = DstI.Operands[0];19871988OperandMatcher &OM0 = InsnMatcher.getOperand(0);1989OM0.setSymbolicName(DstIOperand.Name);1990M.defineOperand(OM0.getSymbolicName(), OM0);1991OM0.addPredicate<RegisterBankOperandMatcher>(RC);19921993auto &DstMIBuilder =1994M.addAction<BuildMIAction>(M.allocateOutputInsnID(), &DstI);1995DstMIBuilder.addRenderer<CopyRenderer>(DstIOperand.Name);1996DstMIBuilder.addRenderer<CopyRenderer>(Dst.getName());1997M.addAction<ConstrainOperandToRegClassAction>(0, 0, RC);19981999// Erase the root.2000unsigned RootInsnID = M.getInsnVarID(InsnMatcher);2001M.addAction<EraseInstAction>(RootInsnID);20022003// We're done with this pattern! It's eligible for GISel emission; return2004// it.2005++NumPatternImported;2006return std::move(M);2007}20082009return failedImport("Dst pattern root isn't a known leaf");2010}20112012// Start with the defined operands (i.e., the results of the root operator).2013Record *DstOp = Dst.getOperator();2014if (!DstOp->isSubClassOf("Instruction"))2015return failedImport("Pattern operator isn't an instruction");20162017auto &DstI = Target.getInstruction(DstOp);2018StringRef DstIName = DstI.TheDef->getName();20192020unsigned DstNumDefs = DstI.Operands.NumDefs,2021SrcNumDefs = Src.getExtTypes().size();2022if (DstNumDefs < SrcNumDefs) {2023if (DstNumDefs != 0)2024return failedImport("Src pattern result has more defs than dst MI (" +2025to_string(SrcNumDefs) + " def(s) vs " +2026to_string(DstNumDefs) + " def(s))");20272028bool FoundNoUsePred = false;2029for (const auto &Pred : InsnMatcher.predicates()) {2030if ((FoundNoUsePred = isa<NoUsePredicateMatcher>(Pred.get())))2031break;2032}2033if (!FoundNoUsePred)2034return failedImport("Src pattern result has " + to_string(SrcNumDefs) +2035" def(s) without the HasNoUse predicate set to true "2036"but Dst MI has no def");2037}20382039// The root of the match also has constraints on the register bank so that it2040// matches the result instruction.2041unsigned OpIdx = 0;2042unsigned N = std::min(DstNumDefs, SrcNumDefs);2043for (unsigned I = 0; I < N; ++I) {2044const TypeSetByHwMode &VTy = Src.getExtType(I);20452046const auto &DstIOperand = DstI.Operands[OpIdx];2047PointerUnion<Record *, const CodeGenRegisterClass *> MatchedRC =2048DstIOperand.Rec;2049if (DstIName == "COPY_TO_REGCLASS") {2050MatchedRC = getInitValueAsRegClass(Dst.getChild(1).getLeafValue());20512052if (MatchedRC.isNull())2053return failedImport(2054"COPY_TO_REGCLASS operand #1 isn't a register class");2055} else if (DstIName == "REG_SEQUENCE") {2056MatchedRC = getInitValueAsRegClass(Dst.getChild(0).getLeafValue());2057if (MatchedRC.isNull())2058return failedImport("REG_SEQUENCE operand #0 isn't a register class");2059} else if (DstIName == "EXTRACT_SUBREG") {2060auto InferredClass = inferRegClassFromPattern(Dst.getChild(0));2061if (!InferredClass)2062return failedImport(2063"Could not infer class for EXTRACT_SUBREG operand #0");20642065// We can assume that a subregister is in the same bank as it's super2066// register.2067MatchedRC = (*InferredClass)->getDef();2068} else if (DstIName == "INSERT_SUBREG") {2069auto MaybeSuperClass =2070inferSuperRegisterClassForNode(VTy, Dst.getChild(0), Dst.getChild(2));2071if (!MaybeSuperClass)2072return failedImport(2073"Cannot infer register class for INSERT_SUBREG operand #0");2074// Move to the next pattern here, because the register class we found2075// doesn't necessarily have a record associated with it. So, we can't2076// set DstIOpRec using this.2077MatchedRC = *MaybeSuperClass;2078} else if (DstIName == "SUBREG_TO_REG") {2079auto MaybeRegClass = inferSuperRegisterClass(VTy, Dst.getChild(2));2080if (!MaybeRegClass)2081return failedImport(2082"Cannot infer register class for SUBREG_TO_REG operand #0");2083MatchedRC = *MaybeRegClass;2084} else if (MatchedRC.get<Record *>()->isSubClassOf("RegisterOperand"))2085MatchedRC = MatchedRC.get<Record *>()->getValueAsDef("RegClass");2086else if (!MatchedRC.get<Record *>()->isSubClassOf("RegisterClass"))2087return failedImport("Dst MI def isn't a register class" + to_string(Dst));20882089OperandMatcher &OM = InsnMatcher.getOperand(OpIdx);2090// The operand names declared in the DstI instruction are unrelated to2091// those used in pattern's source and destination DAGs, so mangle the2092// former to prevent implicitly adding unexpected2093// GIM_CheckIsSameOperand predicates by the defineOperand method.2094OM.setSymbolicName(getMangledRootDefName(DstIOperand.Name));2095M.defineOperand(OM.getSymbolicName(), OM);2096if (MatchedRC.is<Record *>())2097MatchedRC = &Target.getRegisterClass(MatchedRC.get<Record *>());2098OM.addPredicate<RegisterBankOperandMatcher>(2099*MatchedRC.get<const CodeGenRegisterClass *>());2100++OpIdx;2101}21022103auto DstMIBuilderOrError =2104createAndImportInstructionRenderer(M, InsnMatcher, Src, Dst);2105if (auto Error = DstMIBuilderOrError.takeError())2106return std::move(Error);2107BuildMIAction &DstMIBuilder = DstMIBuilderOrError.get();21082109// Render the implicit defs.2110// These are only added to the root of the result.2111if (auto Error = importImplicitDefRenderers(DstMIBuilder, P.getDstRegs()))2112return std::move(Error);21132114DstMIBuilder.chooseInsnToMutate(M);21152116// Constrain the registers to classes. This is normally derived from the2117// emitted instruction but a few instructions require special handling.2118if (DstIName == "COPY_TO_REGCLASS") {2119// COPY_TO_REGCLASS does not provide operand constraints itself but the2120// result is constrained to the class given by the second child.2121Record *DstIOpRec = getInitValueAsRegClass(Dst.getChild(1).getLeafValue());21222123if (DstIOpRec == nullptr)2124return failedImport("COPY_TO_REGCLASS operand #1 isn't a register class");21252126M.addAction<ConstrainOperandToRegClassAction>(21270, 0, Target.getRegisterClass(DstIOpRec));2128} else if (DstIName == "EXTRACT_SUBREG") {2129auto SuperClass = inferRegClassFromPattern(Dst.getChild(0));2130if (!SuperClass)2131return failedImport(2132"Cannot infer register class from EXTRACT_SUBREG operand #0");21332134auto SubIdx = inferSubRegIndexForNode(Dst.getChild(1));2135if (!SubIdx)2136return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");21372138// It would be nice to leave this constraint implicit but we're required2139// to pick a register class so constrain the result to a register class2140// that can hold the correct MVT.2141//2142// FIXME: This may introduce an extra copy if the chosen class doesn't2143// actually contain the subregisters.2144assert(Src.getExtTypes().size() == 1 &&2145"Expected Src of EXTRACT_SUBREG to have one result type");21462147const auto SrcRCDstRCPair =2148(*SuperClass)->getMatchingSubClassWithSubRegs(CGRegs, *SubIdx);2149if (!SrcRCDstRCPair) {2150return failedImport("subreg index is incompatible "2151"with inferred reg class");2152}21532154assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");2155M.addAction<ConstrainOperandToRegClassAction>(0, 0,2156*SrcRCDstRCPair->second);2157M.addAction<ConstrainOperandToRegClassAction>(0, 1, *SrcRCDstRCPair->first);2158} else if (DstIName == "INSERT_SUBREG") {2159assert(Src.getExtTypes().size() == 1 &&2160"Expected Src of INSERT_SUBREG to have one result type");2161// We need to constrain the destination, a super regsister source, and a2162// subregister source.2163auto SubClass = inferRegClassFromPattern(Dst.getChild(1));2164if (!SubClass)2165return failedImport(2166"Cannot infer register class from INSERT_SUBREG operand #1");2167auto SuperClass = inferSuperRegisterClassForNode(2168Src.getExtType(0), Dst.getChild(0), Dst.getChild(2));2169if (!SuperClass)2170return failedImport(2171"Cannot infer register class for INSERT_SUBREG operand #0");2172M.addAction<ConstrainOperandToRegClassAction>(0, 0, **SuperClass);2173M.addAction<ConstrainOperandToRegClassAction>(0, 1, **SuperClass);2174M.addAction<ConstrainOperandToRegClassAction>(0, 2, **SubClass);2175} else if (DstIName == "SUBREG_TO_REG") {2176// We need to constrain the destination and subregister source.2177assert(Src.getExtTypes().size() == 1 &&2178"Expected Src of SUBREG_TO_REG to have one result type");21792180// Attempt to infer the subregister source from the first child. If it has2181// an explicitly given register class, we'll use that. Otherwise, we will2182// fail.2183auto SubClass = inferRegClassFromPattern(Dst.getChild(1));2184if (!SubClass)2185return failedImport(2186"Cannot infer register class from SUBREG_TO_REG child #1");2187// We don't have a child to look at that might have a super register node.2188auto SuperClass =2189inferSuperRegisterClass(Src.getExtType(0), Dst.getChild(2));2190if (!SuperClass)2191return failedImport(2192"Cannot infer register class for SUBREG_TO_REG operand #0");2193M.addAction<ConstrainOperandToRegClassAction>(0, 0, **SuperClass);2194M.addAction<ConstrainOperandToRegClassAction>(0, 2, **SubClass);2195} else if (DstIName == "REG_SEQUENCE") {2196auto SuperClass = inferRegClassFromPattern(Dst.getChild(0));21972198M.addAction<ConstrainOperandToRegClassAction>(0, 0, **SuperClass);21992200unsigned Num = Dst.getNumChildren();2201for (unsigned I = 1; I != Num; I += 2) {2202TreePatternNode &SubRegChild = Dst.getChild(I + 1);22032204auto SubIdx = inferSubRegIndexForNode(SubRegChild);2205if (!SubIdx)2206return failedImport("REG_SEQUENCE child is not a subreg index");22072208const auto SrcRCDstRCPair =2209(*SuperClass)->getMatchingSubClassWithSubRegs(CGRegs, *SubIdx);22102211M.addAction<ConstrainOperandToRegClassAction>(0, I,2212*SrcRCDstRCPair->second);2213}2214} else {2215M.addAction<ConstrainOperandsToDefinitionAction>(0);2216}22172218// Erase the root.2219unsigned RootInsnID = M.getInsnVarID(InsnMatcher);2220M.addAction<EraseInstAction>(RootInsnID);22212222// We're done with this pattern! It's eligible for GISel emission; return it.2223++NumPatternImported;2224return std::move(M);2225}22262227MatchTable2228GlobalISelEmitter::buildMatchTable(MutableArrayRef<RuleMatcher> Rules,2229bool Optimize, bool WithCoverage) {2230std::vector<Matcher *> InputRules;2231for (Matcher &Rule : Rules)2232InputRules.push_back(&Rule);22332234if (!Optimize)2235return MatchTable::buildTable(InputRules, WithCoverage);22362237unsigned CurrentOrdering = 0;2238StringMap<unsigned> OpcodeOrder;2239for (RuleMatcher &Rule : Rules) {2240const StringRef Opcode = Rule.getOpcode();2241assert(!Opcode.empty() && "Didn't expect an undefined opcode");2242if (OpcodeOrder.count(Opcode) == 0)2243OpcodeOrder[Opcode] = CurrentOrdering++;2244}22452246llvm::stable_sort(InputRules, [&OpcodeOrder](const Matcher *A,2247const Matcher *B) {2248auto *L = static_cast<const RuleMatcher *>(A);2249auto *R = static_cast<const RuleMatcher *>(B);2250return std::tuple(OpcodeOrder[L->getOpcode()], L->getNumOperands()) <2251std::tuple(OpcodeOrder[R->getOpcode()], R->getNumOperands());2252});22532254for (Matcher *Rule : InputRules)2255Rule->optimize();22562257std::vector<std::unique_ptr<Matcher>> MatcherStorage;2258std::vector<Matcher *> OptRules =2259optimizeRules<GroupMatcher>(InputRules, MatcherStorage);22602261for (Matcher *Rule : OptRules)2262Rule->optimize();22632264OptRules = optimizeRules<SwitchMatcher>(OptRules, MatcherStorage);22652266return MatchTable::buildTable(OptRules, WithCoverage);2267}22682269void GlobalISelEmitter::emitAdditionalImpl(raw_ostream &OS) {2270OS << "bool " << getClassName()2271<< "::selectImpl(MachineInstr &I, CodeGenCoverage "2272"&CoverageInfo) const {\n"2273<< " const PredicateBitset AvailableFeatures = "2274"getAvailableFeatures();\n"2275<< " MachineIRBuilder B(I);\n"2276<< " State.MIs.clear();\n"2277<< " State.MIs.push_back(&I);\n\n"2278<< " if (executeMatchTable(*this, State, ExecInfo, B"2279<< ", getMatchTable(), TII, MF->getRegInfo(), TRI, RBI, AvailableFeatures"2280<< ", &CoverageInfo)) {\n"2281<< " return true;\n"2282<< " }\n\n"2283<< " return false;\n"2284<< "}\n\n";2285}22862287void GlobalISelEmitter::emitMIPredicateFns(raw_ostream &OS) {2288std::vector<Record *> MatchedRecords;2289std::copy_if(AllPatFrags.begin(), AllPatFrags.end(),2290std::back_inserter(MatchedRecords), [&](Record *R) {2291return !R->getValueAsString("GISelPredicateCode").empty();2292});2293emitMIPredicateFnsImpl<Record *>(2294OS,2295" const MachineFunction &MF = *MI.getParent()->getParent();\n"2296" const MachineRegisterInfo &MRI = MF.getRegInfo();\n"2297" const auto &Operands = State.RecordedOperands;\n"2298" (void)Operands;\n"2299" (void)MRI;",2300ArrayRef<Record *>(MatchedRecords), &getPatFragPredicateEnumName,2301[&](Record *R) { return R->getValueAsString("GISelPredicateCode"); },2302"PatFrag predicates.");2303}23042305void GlobalISelEmitter::emitI64ImmPredicateFns(raw_ostream &OS) {2306std::vector<Record *> MatchedRecords;2307std::copy_if(AllPatFrags.begin(), AllPatFrags.end(),2308std::back_inserter(MatchedRecords), [&](Record *R) {2309bool Unset;2310return !R->getValueAsString("ImmediateCode").empty() &&2311!R->getValueAsBitOrUnset("IsAPFloat", Unset) &&2312!R->getValueAsBit("IsAPInt");2313});2314emitImmPredicateFnsImpl<Record *>(2315OS, "I64", "int64_t", ArrayRef<Record *>(MatchedRecords),2316&getPatFragPredicateEnumName,2317[&](Record *R) { return R->getValueAsString("ImmediateCode"); },2318"PatFrag predicates.");2319}23202321void GlobalISelEmitter::emitAPFloatImmPredicateFns(raw_ostream &OS) {2322std::vector<Record *> MatchedRecords;2323std::copy_if(AllPatFrags.begin(), AllPatFrags.end(),2324std::back_inserter(MatchedRecords), [&](Record *R) {2325bool Unset;2326return !R->getValueAsString("ImmediateCode").empty() &&2327R->getValueAsBitOrUnset("IsAPFloat", Unset);2328});2329emitImmPredicateFnsImpl<Record *>(2330OS, "APFloat", "const APFloat &", ArrayRef<Record *>(MatchedRecords),2331&getPatFragPredicateEnumName,2332[&](Record *R) { return R->getValueAsString("ImmediateCode"); },2333"PatFrag predicates.");2334}23352336void GlobalISelEmitter::emitAPIntImmPredicateFns(raw_ostream &OS) {2337std::vector<Record *> MatchedRecords;2338std::copy_if(AllPatFrags.begin(), AllPatFrags.end(),2339std::back_inserter(MatchedRecords), [&](Record *R) {2340return !R->getValueAsString("ImmediateCode").empty() &&2341R->getValueAsBit("IsAPInt");2342});2343emitImmPredicateFnsImpl<Record *>(2344OS, "APInt", "const APInt &", ArrayRef<Record *>(MatchedRecords),2345&getPatFragPredicateEnumName,2346[&](Record *R) { return R->getValueAsString("ImmediateCode"); },2347"PatFrag predicates.");2348}23492350void GlobalISelEmitter::emitTestSimplePredicate(raw_ostream &OS) {2351OS << "bool " << getClassName() << "::testSimplePredicate(unsigned) const {\n"2352<< " llvm_unreachable(\"" + getClassName() +2353" does not support simple predicates!\");\n"2354<< " return false;\n"2355<< "}\n";2356}23572358void GlobalISelEmitter::emitRunCustomAction(raw_ostream &OS) {2359OS << "bool " << getClassName()2360<< "::runCustomAction(unsigned, const MatcherState&, NewMIVector &) const "2361"{\n"2362<< " llvm_unreachable(\"" + getClassName() +2363" does not support custom C++ actions!\");\n"2364<< "}\n";2365}23662367void GlobalISelEmitter::postProcessRule(RuleMatcher &M) {2368SmallPtrSet<Record *, 16> UsedRegs;23692370// TODO: deal with subregs?2371for (auto &A : M.actions()) {2372auto *MI = dyn_cast<BuildMIAction>(A.get());2373if (!MI)2374continue;23752376for (auto *Use : MI->getCGI()->ImplicitUses)2377UsedRegs.insert(Use);2378}23792380for (auto &A : M.actions()) {2381auto *MI = dyn_cast<BuildMIAction>(A.get());2382if (!MI)2383continue;23842385for (auto *Def : MI->getCGI()->ImplicitDefs) {2386if (!UsedRegs.contains(Def))2387MI->setDeadImplicitDef(Def);2388}2389}2390}23912392void GlobalISelEmitter::run(raw_ostream &OS) {2393if (!UseCoverageFile.empty()) {2394RuleCoverage = CodeGenCoverage();2395auto RuleCoverageBufOrErr = MemoryBuffer::getFile(UseCoverageFile);2396if (!RuleCoverageBufOrErr) {2397PrintWarning(SMLoc(), "Missing rule coverage data");2398RuleCoverage = std::nullopt;2399} else {2400if (!RuleCoverage->parse(*RuleCoverageBufOrErr.get(), Target.getName())) {2401PrintWarning(SMLoc(), "Ignoring invalid or missing rule coverage data");2402RuleCoverage = std::nullopt;2403}2404}2405}24062407// Track the run-time opcode values2408gatherOpcodeValues();2409// Track the run-time LLT ID values2410gatherTypeIDValues();24112412// Track the GINodeEquiv definitions.2413gatherNodeEquivs();24142415AllPatFrags = RK.getAllDerivedDefinitions("PatFrags");24162417emitSourceFileHeader(2418("Global Instruction Selector for the " + Target.getName() + " target")2419.str(),2420OS);2421std::vector<RuleMatcher> Rules;2422// Look through the SelectionDAG patterns we found, possibly emitting some.2423for (const PatternToMatch &Pat : CGP.ptms()) {2424++NumPatternTotal;24252426if (Pat.getGISelShouldIgnore())2427continue; // skip without warning2428auto MatcherOrErr = runOnPattern(Pat);24292430// The pattern analysis can fail, indicating an unsupported pattern.2431// Report that if we've been asked to do so.2432if (auto Err = MatcherOrErr.takeError()) {2433if (WarnOnSkippedPatterns) {2434PrintWarning(Pat.getSrcRecord()->getLoc(),2435"Skipped pattern: " + toString(std::move(Err)));2436} else {2437consumeError(std::move(Err));2438}2439++NumPatternImportsSkipped;2440continue;2441}24422443if (RuleCoverage) {2444if (RuleCoverage->isCovered(MatcherOrErr->getRuleID()))2445++NumPatternsTested;2446else2447PrintWarning(Pat.getSrcRecord()->getLoc(),2448"Pattern is not covered by a test");2449}2450Rules.push_back(std::move(MatcherOrErr.get()));2451postProcessRule(Rules.back());2452}24532454// Comparison function to order records by name.2455auto OrderByName = [](const Record *A, const Record *B) {2456return A->getName() < B->getName();2457};24582459std::vector<Record *> ComplexPredicates =2460RK.getAllDerivedDefinitions("GIComplexOperandMatcher");2461llvm::sort(ComplexPredicates, OrderByName);24622463std::vector<StringRef> CustomRendererFns;2464transform(RK.getAllDerivedDefinitions("GICustomOperandRenderer"),2465std::back_inserter(CustomRendererFns), [](const auto &Record) {2466return Record->getValueAsString("RendererFn");2467});2468// Sort and remove duplicates to get a list of unique renderer functions, in2469// case some were mentioned more than once.2470llvm::sort(CustomRendererFns);2471CustomRendererFns.erase(llvm::unique(CustomRendererFns),2472CustomRendererFns.end());24732474// Create a table containing the LLT objects needed by the matcher and an enum2475// for the matcher to reference them with.2476std::vector<LLTCodeGen> TypeObjects;2477append_range(TypeObjects, KnownTypes);2478llvm::sort(TypeObjects);24792480// Sort rules.2481llvm::stable_sort(Rules, [&](const RuleMatcher &A, const RuleMatcher &B) {2482int ScoreA = RuleMatcherScores[A.getRuleID()];2483int ScoreB = RuleMatcherScores[B.getRuleID()];2484if (ScoreA > ScoreB)2485return true;2486if (ScoreB > ScoreA)2487return false;2488if (A.isHigherPriorityThan(B)) {2489assert(!B.isHigherPriorityThan(A) && "Cannot be more important "2490"and less important at "2491"the same time");2492return true;2493}2494return false;2495});24962497unsigned MaxTemporaries = 0;2498for (const auto &Rule : Rules)2499MaxTemporaries = std::max(MaxTemporaries, Rule.countRendererFns());25002501// Build match table2502const MatchTable Table =2503buildMatchTable(Rules, OptimizeMatchTable, GenerateCoverage);25042505emitPredicateBitset(OS, "GET_GLOBALISEL_PREDICATE_BITSET");2506emitTemporariesDecl(OS, "GET_GLOBALISEL_TEMPORARIES_DECL");2507emitTemporariesInit(OS, MaxTemporaries, "GET_GLOBALISEL_TEMPORARIES_INIT");2508emitExecutorImpl(OS, Table, TypeObjects, Rules, ComplexPredicates,2509CustomRendererFns, "GET_GLOBALISEL_IMPL");2510emitPredicatesDecl(OS, "GET_GLOBALISEL_PREDICATES_DECL");2511emitPredicatesInit(OS, "GET_GLOBALISEL_PREDICATES_INIT");2512}25132514void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {2515SubtargetFeatures.try_emplace(Predicate, Predicate, SubtargetFeatures.size());2516}25172518unsigned GlobalISelEmitter::declareHwModeCheck(StringRef HwModeFeatures) {2519return HwModes.emplace(HwModeFeatures.str(), HwModes.size()).first->second;2520}25212522} // end anonymous namespace25232524//===----------------------------------------------------------------------===//25252526static TableGen::Emitter::OptClass<GlobalISelEmitter>2527X("gen-global-isel", "Generate GlobalISel selector");252825292530