diff --git a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h copy from llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h copy to llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h --- a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h @@ -1,4 +1,4 @@ -//===- llvm/CodeGen/GlobalISel/InstructionSelector.h ------------*- C++ -*-===// +//===- llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h -----------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,14 +6,14 @@ // //===----------------------------------------------------------------------===// // -/// \file This file declares the API for the instruction selector. -/// This class is responsible for selecting machine instructions. -/// It's implemented by the target. It's used by the InstructionSelect pass. +/// \file This file declares the GIMatchTableExecutor API, the opcodes supported +/// by the match table, and some associated data structures used by the +/// executor's implementation (see `GIMatchTableExecutorImpl.h`). // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H -#define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H +#ifndef LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTOR_H +#define LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTOR_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" @@ -51,7 +51,7 @@ /// This is convenient because std::bitset does not have a constructor /// with an initializer list of set bits. /// -/// Each InstructionSelector subclass should define a PredicateBitset class +/// Each GIMatchTableExecutor subclass should define a PredicateBitset class /// with: /// const unsigned MAX_SUBTARGET_PREDICATES = 192; /// using PredicateBitset = PredicateBitsetImpl; @@ -73,6 +73,13 @@ } }; +enum { + GICXXPred_I64_Invalid = 0, + GICXXPred_APInt_Invalid = 0, + GICXXPred_APFloat_Invalid = 0, + GICXXPred_MI_Invalid = 0, +}; + enum { /// Begin a try-block to attempt a match and jump to OnFail if it is /// unsuccessful. @@ -438,22 +445,12 @@ GIU_MergeMemOperands_EndOfList = -1, }; -/// Provides the logic to select generic machine instructions. -class InstructionSelector { +/// Provides the logic to execute GlobalISel match tables, why are used by the +/// instruction selector and instruction combiners as their engine to match and +/// apply MIR patterns. +class GIMatchTableExecutor { public: - virtual ~InstructionSelector() = default; - - /// Select the (possibly generic) instruction \p I to only use target-specific - /// opcodes. It is OK to insert multiple instructions, but they cannot be - /// generic pre-isel instructions. - /// - /// \returns whether selection succeeded. - /// \pre I.getParent() && I.getParent()->getParent() - /// \post - /// if returns true: - /// for I in all mutated/inserted instructions: - /// !isPreISelGenericOpcode(I.getOpcode()) - virtual bool select(MachineInstr &I) = 0; + virtual ~GIMatchTableExecutor() = default; CodeGenCoverage *CoverageInfo = nullptr; GISelKnownBits *KnownBits = nullptr; @@ -467,7 +464,7 @@ llvm_unreachable("TableGen should have emitted implementation"); } - /// Setup per-MF selector state. + /// Setup per-MF executor state. virtual void setupMF(MachineFunction &mf, GISelKnownBits *KB, CodeGenCoverage &covinfo, ProfileSummaryInfo *psi, BlockFrequencyInfo *bfi) { @@ -508,13 +505,12 @@ public: template - struct ISelInfoTy { - ISelInfoTy(const LLT *TypeObjects, size_t NumTypeObjects, + struct ExecInfoTy { + ExecInfoTy(const LLT *TypeObjects, size_t NumTypeObjects, const PredicateBitset *FeatureBitsets, const ComplexMatcherMemFn *ComplexPredicates, const CustomRendererFn *CustomRenderers) - : TypeObjects(TypeObjects), - FeatureBitsets(FeatureBitsets), + : TypeObjects(TypeObjects), FeatureBitsets(FeatureBitsets), ComplexPredicates(ComplexPredicates), CustomRenderers(CustomRenderers) { @@ -530,20 +526,20 @@ }; protected: - InstructionSelector(); + GIMatchTableExecutor(); /// Execute a given matcher table and return true if the match was successful /// and false otherwise. - template + template bool executeMatchTable( - TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State, - const ISelInfoTy + TgtExecutor &Exec, NewMIVector &OutMIs, MatcherState &State, + const ExecInfoTy &ISelInfo, const int64_t *MatchTable, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures, - CodeGenCoverage &CoverageInfo) const; + CodeGenCoverage *CoverageInfo) const; virtual const int64_t *getMatchTable() const { llvm_unreachable("Should have been overridden by tablegen if used"); @@ -561,9 +557,8 @@ llvm_unreachable( "Subclasses must override this with a tablegen-erated function"); } - virtual bool testMIPredicate_MI( - unsigned, const MachineInstr &, - const std::array &Operands) const { + virtual bool testMIPredicate_MI(unsigned, const MachineInstr &, + const MatcherState &State) const { llvm_unreachable( "Subclasses must override this with a tablegen-erated function"); } @@ -571,8 +566,8 @@ bool isOperandImmEqual(const MachineOperand &MO, int64_t Value, const MachineRegisterInfo &MRI) const; - /// Return true if the specified operand is a G_PTR_ADD with a G_CONSTANT on the - /// right-hand side. GlobalISel's separation of pointer and integer types + /// Return true if the specified operand is a G_PTR_ADD with a G_CONSTANT on + /// the right-hand side. GlobalISel's separation of pointer and integer types /// means that we don't need to worry about G_OR with equivalent semantics. bool isBaseWithConstantOffset(const MachineOperand &Root, const MachineRegisterInfo &MRI) const; @@ -585,4 +580,4 @@ } // end namespace llvm -#endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H +#endif // LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTOR_H diff --git a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h rename from llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h rename to llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h --- a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h @@ -1,4 +1,4 @@ -//===- llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h --------*- C++ -*-===// +//===- llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h -------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,17 +6,17 @@ // //===----------------------------------------------------------------------===// // -/// \file This file declares the API for the instruction selector. -/// This class is responsible for selecting machine instructions. -/// It's implemented by the target. It's used by the InstructionSelect pass. +/// \file This file implements GIMatchTableExecutor's `executeMatchTable` +/// function. This is implemented in a separate file because the function is +/// quite large. // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H -#define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H +#ifndef LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H +#define LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H #include "llvm/ADT/SmallVector.h" -#include "llvm/CodeGen/GlobalISel/InstructionSelector.h" +#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h" #include "llvm/CodeGen/GlobalISel/Utils.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineOperand.h" @@ -37,24 +37,16 @@ namespace llvm { -/// GlobalISel PatFrag Predicates -enum { - GIPFP_I64_Invalid = 0, - GIPFP_APInt_Invalid = 0, - GIPFP_APFloat_Invalid = 0, - GIPFP_MI_Invalid = 0, -}; - -template -bool InstructionSelector::executeMatchTable( - TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State, - const ISelInfoTy - &ISelInfo, +template +bool GIMatchTableExecutor::executeMatchTable( + TgtExecutor &Exec, NewMIVector &OutMIs, MatcherState &State, + const ExecInfoTy + &ExecInfo, const int64_t *MatchTable, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures, - CodeGenCoverage &CoverageInfo) const { + CodeGenCoverage *CoverageInfo) const { uint64_t CurrentIdx = 0; SmallVector OnFailResumeAt; @@ -66,12 +58,12 @@ enum RejectAction { RejectAndGiveUp, RejectAndResume }; auto handleReject = [&]() -> RejectAction { - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": Rejected\n"); if (OnFailResumeAt.empty()) return RejectAndGiveUp; CurrentIdx = OnFailResumeAt.pop_back_val(); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": Resume at " << CurrentIdx << " (" << OnFailResumeAt.size() << " try-blocks remain)\n"); return RejectAndResume; @@ -95,7 +87,7 @@ int64_t MatcherOpcode = MatchTable[CurrentIdx++]; switch (MatcherOpcode) { case GIM_Try: { - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": Begin try-block\n"); OnFailResumeAt.push_back(MatchTable[CurrentIdx++]); break; @@ -113,14 +105,14 @@ MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); if (!MO.isReg()) { - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": Not a register\n"); if (handleReject() == RejectAndGiveUp) return false; break; } if (MO.getReg().isPhysical()) { - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": Is a physical register\n"); if (handleReject() == RejectAndGiveUp) return false; @@ -140,7 +132,7 @@ "Expected to store MIs in order"); State.MIs.push_back(NewMI); } - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": MIs[" << NewInsnID << "] = GIM_RecordInsn(" << InsnID << ", " << OpIdx << ")\n"); @@ -149,18 +141,17 @@ case GIM_CheckFeatures: { int64_t ExpectedBitsetID = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckFeatures(ExpectedBitsetID=" << ExpectedBitsetID << ")\n"); - if ((AvailableFeatures & ISelInfo.FeatureBitsets[ExpectedBitsetID]) != - ISelInfo.FeatureBitsets[ExpectedBitsetID]) { + if ((AvailableFeatures & ExecInfo.FeatureBitsets[ExpectedBitsetID]) != + ExecInfo.FeatureBitsets[ExpectedBitsetID]) { if (handleReject() == RejectAndGiveUp) return false; } break; } - case GIM_CheckOpcode: case GIM_CheckOpcodeIsEither: { int64_t InsnID = MatchTable[CurrentIdx++]; @@ -172,13 +163,12 @@ assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); unsigned Opcode = State.MIs[InsnID]->getOpcode(); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), - dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID - << "], ExpectedOpcode=" << Expected0; - if (MatcherOpcode == GIM_CheckOpcodeIsEither) - dbgs() << " || " << Expected1; - dbgs() << ") // Got=" << Opcode << "\n"; - ); + DEBUG_WITH_TYPE(TgtExecutor::getName(), + dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID + << "], ExpectedOpcode=" << Expected0; + if (MatcherOpcode == GIM_CheckOpcodeIsEither) dbgs() + << " || " << Expected1; + dbgs() << ") // Got=" << Opcode << "\n";); if (Opcode != Expected0 && Opcode != Expected1) { if (handleReject() == RejectAndGiveUp) @@ -195,7 +185,7 @@ assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); const int64_t Opcode = State.MIs[InsnID]->getOpcode(); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), { + DEBUG_WITH_TYPE(TgtExecutor::getName(), { dbgs() << CurrentIdx << ": GIM_SwitchOpcode(MIs[" << InsnID << "], [" << LowerBound << ", " << UpperBound << "), Default=" << Default << ", JumpTable...) // Got=" << Opcode << "\n"; @@ -223,7 +213,7 @@ assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), { + DEBUG_WITH_TYPE(TgtExecutor::getName(), { dbgs() << CurrentIdx << ": GIM_SwitchType(MIs[" << InsnID << "]->getOperand(" << OpIdx << "), [" << LowerBound << ", " << UpperBound << "), Default=" << Default @@ -238,8 +228,8 @@ break; } const LLT Ty = MRI.getType(MO.getReg()); - const auto TyI = ISelInfo.TypeIDMap.find(Ty); - if (TyI == ISelInfo.TypeIDMap.end()) { + const auto TyI = ExecInfo.TypeIDMap.find(Ty); + if (TyI == ExecInfo.TypeIDMap.end()) { CurrentIdx = Default; break; } @@ -260,7 +250,7 @@ case GIM_CheckNumOperands: { int64_t InsnID = MatchTable[CurrentIdx++]; int64_t Expected = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckNumOperands(MIs[" << InsnID << "], Expected=" << Expected << ")\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); @@ -277,7 +267,7 @@ ? MatchTable[CurrentIdx++] : 1; int64_t Predicate = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckImmPredicate(MIs[" << InsnID << "]->getOperand(" << OpIdx << "), Predicate=" << Predicate << ")\n"); @@ -285,7 +275,7 @@ assert((State.MIs[InsnID]->getOperand(OpIdx).isImm() || State.MIs[InsnID]->getOperand(OpIdx).isCImm()) && "Expected immediate operand"); - assert(Predicate > GIPFP_I64_Invalid && "Expected a valid predicate"); + assert(Predicate > GICXXPred_I64_Invalid && "Expected a valid predicate"); int64_t Value = 0; if (State.MIs[InsnID]->getOperand(OpIdx).isCImm()) Value = State.MIs[InsnID]->getOperand(OpIdx).getCImm()->getSExtValue(); @@ -302,14 +292,15 @@ case GIM_CheckAPIntImmPredicate: { int64_t InsnID = MatchTable[CurrentIdx++]; int64_t Predicate = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckAPIntImmPredicate(MIs[" << InsnID << "], Predicate=" << Predicate << ")\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT"); - assert(Predicate > GIPFP_APInt_Invalid && "Expected a valid predicate"); + assert(Predicate > GICXXPred_APInt_Invalid && + "Expected a valid predicate"); APInt Value; if (State.MIs[InsnID]->getOperand(1).isCImm()) Value = State.MIs[InsnID]->getOperand(1).getCImm()->getValue(); @@ -324,16 +315,19 @@ case GIM_CheckAPFloatImmPredicate: { int64_t InsnID = MatchTable[CurrentIdx++]; int64_t Predicate = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckAPFloatImmPredicate(MIs[" << InsnID << "], Predicate=" << Predicate << ")\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT && "Expected G_FCONSTANT"); - assert(State.MIs[InsnID]->getOperand(1).isFPImm() && "Expected FPImm operand"); - assert(Predicate > GIPFP_APFloat_Invalid && "Expected a valid predicate"); - APFloat Value = State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF(); + assert(State.MIs[InsnID]->getOperand(1).isFPImm() && + "Expected FPImm operand"); + assert(Predicate > GICXXPred_APFloat_Invalid && + "Expected a valid predicate"); + APFloat Value = + State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF(); if (!testImmPredicate_APFloat(Predicate, Value)) if (handleReject() == RejectAndGiveUp) @@ -344,7 +338,7 @@ case GIM_CheckIsBuildVectorAllZeros: { int64_t InsnID = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckBuildVectorAll{Zeros|Ones}(MIs[" << InsnID << "])\n"); @@ -372,15 +366,14 @@ case GIM_CheckCxxInsnPredicate: { int64_t InsnID = MatchTable[CurrentIdx++]; int64_t Predicate = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckCxxPredicate(MIs[" << InsnID << "], Predicate=" << Predicate << ")\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); - assert(Predicate > GIPFP_MI_Invalid && "Expected a valid predicate"); + assert(Predicate > GICXXPred_MI_Invalid && "Expected a valid predicate"); - if (!testMIPredicate_MI(Predicate, *State.MIs[InsnID], - State.RecordedOperands)) + if (!testMIPredicate_MI(Predicate, *State.MIs[InsnID], State)) if (handleReject() == RejectAndGiveUp) return false; break; @@ -388,7 +381,7 @@ case GIM_CheckHasNoUse: { int64_t InsnID = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckHasNoUse(MIs[" << InsnID << "]\n"); @@ -407,7 +400,7 @@ case GIM_CheckAtomicOrdering: { int64_t InsnID = MatchTable[CurrentIdx++]; AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckAtomicOrdering(MIs[" << InsnID << "], " << (uint64_t)Ordering << ")\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); @@ -424,7 +417,7 @@ case GIM_CheckAtomicOrderingOrStrongerThan: { int64_t InsnID = MatchTable[CurrentIdx++]; AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckAtomicOrderingOrStrongerThan(MIs[" << InsnID << "], " << (uint64_t)Ordering << ")\n"); @@ -442,7 +435,7 @@ case GIM_CheckAtomicOrderingWeakerThan: { int64_t InsnID = MatchTable[CurrentIdx++]; AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckAtomicOrderingWeakerThan(MIs[" << InsnID << "], " << (uint64_t)Ordering << ")\n"); @@ -473,17 +466,16 @@ // a match earlier. const uint64_t LastIdx = CurrentIdx + NumAddrSpace; - const MachineMemOperand *MMO - = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); + const MachineMemOperand *MMO = + *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); const unsigned MMOAddrSpace = MMO->getAddrSpace(); bool Success = false; for (int I = 0; I != NumAddrSpace; ++I) { unsigned AddrSpace = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE( - TgtInstructionSelector::getName(), - dbgs() << "addrspace(" << MMOAddrSpace << ") vs " - << AddrSpace << '\n'); + DEBUG_WITH_TYPE(TgtExecutor::getName(), + dbgs() << "addrspace(" << MMOAddrSpace << ") vs " + << AddrSpace << '\n'); if (AddrSpace == MMOAddrSpace) { Success = true; @@ -509,12 +501,13 @@ break; } - MachineMemOperand *MMO - = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + MachineMemOperand *MMO = + *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckMemoryAlignment" - << "(MIs[" << InsnID << "]->memoperands() + " << MMOIdx - << ")->getAlignment() >= " << MinAlign << ")\n"); + << "(MIs[" << InsnID << "]->memoperands() + " + << MMOIdx << ")->getAlignment() >= " << MinAlign + << ")\n"); if (MMO->getAlign() < MinAlign && handleReject() == RejectAndGiveUp) return false; @@ -525,10 +518,9 @@ int64_t MMOIdx = MatchTable[CurrentIdx++]; uint64_t Size = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), - dbgs() << CurrentIdx - << ": GIM_CheckMemorySizeEqual(MIs[" << InsnID - << "]->memoperands() + " << MMOIdx + DEBUG_WITH_TYPE(TgtExecutor::getName(), + dbgs() << CurrentIdx << ": GIM_CheckMemorySizeEqual(MIs[" + << InsnID << "]->memoperands() + " << MMOIdx << ", Size=" << Size << ")\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); @@ -538,11 +530,12 @@ break; } - MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); + MachineMemOperand *MMO = + *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), - dbgs() << MMO->getSize() << " bytes vs " << Size - << " bytes\n"); + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << MMO->getSize() + << " bytes vs " << Size + << " bytes\n"); if (MMO->getSize() != Size) if (handleReject() == RejectAndGiveUp) return false; @@ -557,20 +550,19 @@ int64_t OpIdx = MatchTable[CurrentIdx++]; DEBUG_WITH_TYPE( - TgtInstructionSelector::getName(), + TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckMemorySize" - << (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT - ? "EqualTo" - : MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT - ? "GreaterThan" - : "LessThan") + << (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT ? "EqualTo" + : MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT + ? "GreaterThan" + : "LessThan") << "LLT(MIs[" << InsnID << "]->memoperands() + " << MMOIdx << ", OpIdx=" << OpIdx << ")\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); if (!MO.isReg()) { - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": Not a register\n"); if (handleReject() == RejectAndGiveUp) return false; @@ -583,7 +575,8 @@ break; } - MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); + MachineMemOperand *MMO = + *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); unsigned Size = MRI.getType(MO.getReg()).getSizeInBits(); if (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT && @@ -605,14 +598,14 @@ int64_t InsnID = MatchTable[CurrentIdx++]; int64_t OpIdx = MatchTable[CurrentIdx++]; int64_t TypeID = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckType(MIs[" << InsnID << "]->getOperand(" << OpIdx << "), TypeID=" << TypeID << ")\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); if (!MO.isReg() || - MRI.getType(MO.getReg()) != ISelInfo.TypeObjects[TypeID]) { + MRI.getType(MO.getReg()) != ExecInfo.TypeObjects[TypeID]) { if (handleReject() == RejectAndGiveUp) return false; } @@ -623,7 +616,7 @@ int64_t OpIdx = MatchTable[CurrentIdx++]; uint64_t SizeInBits = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckPointerToAny(MIs[" << InsnID << "]->getOperand(" << OpIdx << "), SizeInBits=" << SizeInBits << ")\n"); @@ -654,7 +647,7 @@ int64_t OpIdx = MatchTable[CurrentIdx++]; uint64_t StoreIdx = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_RecordNamedOperand(MIs[" << InsnID << "]->getOperand(" << OpIdx << "), StoreIdx=" << StoreIdx << ")\n"); @@ -667,7 +660,7 @@ int64_t InsnID = MatchTable[CurrentIdx++]; int64_t OpIdx = MatchTable[CurrentIdx++]; int64_t RCEnum = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckRegBankForClass(MIs[" << InsnID << "]->getOperand(" << OpIdx << "), RCEnum=" << RCEnum << ")\n"); @@ -688,7 +681,7 @@ int64_t OpIdx = MatchTable[CurrentIdx++]; int64_t RendererID = MatchTable[CurrentIdx++]; int64_t ComplexPredicateID = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": State.Renderers[" << RendererID << "] = GIM_CheckComplexPattern(MIs[" << InsnID << "]->getOperand(" << OpIdx @@ -697,13 +690,12 @@ assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); // FIXME: Use std::invoke() when it's available. ComplexRendererFns Renderer = - (ISel.*ISelInfo.ComplexPredicates[ComplexPredicateID])( + (Exec.*ExecInfo.ComplexPredicates[ComplexPredicateID])( State.MIs[InsnID]->getOperand(OpIdx)); if (Renderer) State.Renderers[RendererID] = *Renderer; - else - if (handleReject() == RejectAndGiveUp) - return false; + else if (handleReject() == RejectAndGiveUp) + return false; break; } @@ -711,7 +703,7 @@ int64_t InsnID = MatchTable[CurrentIdx++]; int64_t OpIdx = MatchTable[CurrentIdx++]; int64_t Value = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckConstantInt(MIs[" << InsnID << "]->getOperand(" << OpIdx << "), Value=" << Value << ")\n"); @@ -736,7 +728,7 @@ int64_t InsnID = MatchTable[CurrentIdx++]; int64_t OpIdx = MatchTable[CurrentIdx++]; int64_t Value = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckLiteralInt(MIs[" << InsnID << "]->getOperand(" << OpIdx << "), Value=" << Value << ")\n"); @@ -758,7 +750,7 @@ int64_t InsnID = MatchTable[CurrentIdx++]; int64_t OpIdx = MatchTable[CurrentIdx++]; int64_t Value = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckIntrinsicID(MIs[" << InsnID << "]->getOperand(" << OpIdx << "), Value=" << Value << ")\n"); @@ -773,7 +765,7 @@ int64_t InsnID = MatchTable[CurrentIdx++]; int64_t OpIdx = MatchTable[CurrentIdx++]; int64_t Value = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckCmpPredicate(MIs[" << InsnID << "]->getOperand(" << OpIdx << "), Value=" << Value << ")\n"); @@ -787,7 +779,7 @@ case GIM_CheckIsMBB: { int64_t InsnID = MatchTable[CurrentIdx++]; int64_t OpIdx = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckIsMBB(MIs[" << InsnID << "]->getOperand(" << OpIdx << "))\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); @@ -800,7 +792,7 @@ case GIM_CheckIsImm: { int64_t InsnID = MatchTable[CurrentIdx++]; int64_t OpIdx = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckIsImm(MIs[" << InsnID << "]->getOperand(" << OpIdx << "))\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); @@ -812,7 +804,7 @@ } case GIM_CheckIsSafeToFold: { int64_t InsnID = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckIsSafeToFold(MIs[" << InsnID << "])\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); @@ -828,7 +820,7 @@ int64_t OpIdx = MatchTable[CurrentIdx++]; int64_t OtherInsnID = MatchTable[CurrentIdx++]; int64_t OtherOpIdx = MatchTable[CurrentIdx++]; - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_CheckIsSameOperand(MIs[" << InsnID << "][" << OpIdx << "], MIs[" << OtherInsnID << "][" << OtherOpIdx << "])\n"); @@ -854,12 +846,11 @@ break; } case GIM_Reject: - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIM_Reject\n"); if (handleReject() == RejectAndGiveUp) return false; break; - case GIR_MutateOpcode: { int64_t OldInsnID = MatchTable[CurrentIdx++]; uint64_t NewInsnID = MatchTable[CurrentIdx++]; @@ -870,7 +861,7 @@ OutMIs[NewInsnID] = MachineInstrBuilder(*State.MIs[OldInsnID]->getMF(), State.MIs[OldInsnID]); OutMIs[NewInsnID]->setDesc(TII.get(NewOpcode)); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_MutateOpcode(OutMIs[" << NewInsnID << "], MIs[" << OldInsnID << "], " << NewOpcode << ")\n"); @@ -885,7 +876,7 @@ OutMIs[NewInsnID] = BuildMI(*State.MIs[0]->getParent(), State.MIs[0], MIMetadata(*State.MIs[0]), TII.get(Opcode)); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_BuildMI(OutMIs[" << NewInsnID << "], " << Opcode << ")\n"); break; @@ -897,7 +888,7 @@ int64_t OpIdx = MatchTable[CurrentIdx++]; assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction"); OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx)); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_Copy(OutMIs[" << NewInsnID << "], MIs[" << OldInsnID << "], " << OpIdx << ")\n"); @@ -915,7 +906,7 @@ OutMIs[NewInsnID].addReg(ZeroReg); else OutMIs[NewInsnID].add(MO); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_CopyOrAddZeroReg(OutMIs[" << NewInsnID << "], MIs[" << OldInsnID << "], " << OpIdx << ", " << ZeroReg << ")\n"); @@ -930,7 +921,7 @@ assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction"); OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(), 0, SubRegIdx); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_CopySubReg(OutMIs[" << NewInsnID << "], MIs[" << OldInsnID << "], " << OpIdx << ", " << SubRegIdx << ")\n"); @@ -942,7 +933,7 @@ int64_t RegNum = MatchTable[CurrentIdx++]; assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); OutMIs[InsnID].addDef(RegNum, RegState::Implicit); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_AddImplicitDef(OutMIs[" << InsnID << "], " << RegNum << ")\n"); break; @@ -953,7 +944,7 @@ int64_t RegNum = MatchTable[CurrentIdx++]; assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); OutMIs[InsnID].addUse(RegNum, RegState::Implicit); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_AddImplicitUse(OutMIs[" << InsnID << "], " << RegNum << ")\n"); break; @@ -965,10 +956,10 @@ uint64_t RegFlags = MatchTable[CurrentIdx++]; assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); OutMIs[InsnID].addReg(RegNum, RegFlags); - DEBUG_WITH_TYPE( - TgtInstructionSelector::getName(), - dbgs() << CurrentIdx << ": GIR_AddRegister(OutMIs[" - << InsnID << "], " << RegNum << ", " << RegFlags << ")\n"); + DEBUG_WITH_TYPE(TgtExecutor::getName(), + dbgs() + << CurrentIdx << ": GIR_AddRegister(OutMIs[" << InsnID + << "], " << RegNum << ", " << RegFlags << ")\n"); break; } @@ -983,14 +974,14 @@ assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); - OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags, SubReg); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), - dbgs() << CurrentIdx << ": GIR_AddTempRegister(OutMIs[" - << InsnID << "], TempRegisters[" << TempRegID - << "]"; - if (SubReg) - dbgs() << '.' << TRI.getSubRegIndexName(SubReg); - dbgs() << ", " << TempRegFlags << ")\n"); + OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags, + SubReg); + DEBUG_WITH_TYPE( + TgtExecutor::getName(), + dbgs() << CurrentIdx << ": GIR_AddTempRegister(OutMIs[" << InsnID + << "], TempRegisters[" << TempRegID << "]"; + if (SubReg) dbgs() << '.' << TRI.getSubRegIndexName(SubReg); + dbgs() << ", " << TempRegFlags << ")\n"); break; } @@ -999,7 +990,7 @@ int64_t Imm = MatchTable[CurrentIdx++]; assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); OutMIs[InsnID].addImm(Imm); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_AddImm(OutMIs[" << InsnID << "], " << Imm << ")\n"); break; @@ -1011,7 +1002,7 @@ assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); for (const auto &RenderOpFn : State.Renderers[RendererID]) RenderOpFn(OutMIs[InsnID]); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_ComplexRenderer(OutMIs[" << InsnID << "], " << RendererID << ")\n"); break; @@ -1022,7 +1013,7 @@ int64_t RenderOpID = MatchTable[CurrentIdx++]; assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_ComplexSubOperandRenderer(OutMIs[" << InsnID << "], " << RendererID << ", " @@ -1038,7 +1029,7 @@ assert(MI && "Attempted to add to undefined instruction"); State.Renderers[RendererID][RenderOpID](MI); MI->getOperand(MI->getNumOperands() - 1).setSubReg(SubRegIdx); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_ComplexSubOperandSubRegRenderer(OutMIs[" << InsnID << "], " << RendererID << ", " @@ -1050,7 +1041,8 @@ int64_t NewInsnID = MatchTable[CurrentIdx++]; int64_t OldInsnID = MatchTable[CurrentIdx++]; assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction"); - assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT"); + assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT && + "Expected G_CONSTANT"); if (State.MIs[OldInsnID]->getOperand(1).isCImm()) { OutMIs[NewInsnID].addImm( State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue()); @@ -1058,7 +1050,7 @@ OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1)); else llvm_unreachable("Expected Imm or CImm operand"); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_CopyConstantAsSImm(OutMIs[" << NewInsnID << "], MIs[" << OldInsnID << "])\n"); break; @@ -1069,15 +1061,17 @@ int64_t NewInsnID = MatchTable[CurrentIdx++]; int64_t OldInsnID = MatchTable[CurrentIdx++]; assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction"); - assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT && "Expected G_FCONSTANT"); + assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT && + "Expected G_FCONSTANT"); if (State.MIs[OldInsnID]->getOperand(1).isFPImm()) OutMIs[NewInsnID].addFPImm( State.MIs[OldInsnID]->getOperand(1).getFPImm()); else llvm_unreachable("Expected FPImm operand"); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), - dbgs() << CurrentIdx << ": GIR_CopyFPConstantAsFPImm(OutMIs[" - << NewInsnID << "], MIs[" << OldInsnID << "])\n"); + DEBUG_WITH_TYPE(TgtExecutor::getName(), + dbgs() + << CurrentIdx << ": GIR_CopyFPConstantAsFPImm(OutMIs[" + << NewInsnID << "], MIs[" << OldInsnID << "])\n"); break; } @@ -1086,13 +1080,13 @@ int64_t OldInsnID = MatchTable[CurrentIdx++]; int64_t RendererFnID = MatchTable[CurrentIdx++]; assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_CustomRenderer(OutMIs[" << InsnID << "], MIs[" << OldInsnID << "], " << RendererFnID << ")\n"); - (ISel.*ISelInfo.CustomRenderers[RendererFnID])( - OutMIs[InsnID], *State.MIs[OldInsnID], - -1); // Not a source operand of the old instruction. + (Exec.*ExecInfo.CustomRenderers[RendererFnID])( + OutMIs[InsnID], *State.MIs[OldInsnID], + -1); // Not a source operand of the old instruction. break; } case GIR_CustomOperandRenderer: { @@ -1102,15 +1096,13 @@ int64_t RendererFnID = MatchTable[CurrentIdx++]; assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); - DEBUG_WITH_TYPE( - TgtInstructionSelector::getName(), - dbgs() << CurrentIdx << ": GIR_CustomOperandRenderer(OutMIs[" - << InsnID << "], MIs[" << OldInsnID << "]->getOperand(" - << OpIdx << "), " - << RendererFnID << ")\n"); - (ISel.*ISelInfo.CustomRenderers[RendererFnID])(OutMIs[InsnID], - *State.MIs[OldInsnID], - OpIdx); + DEBUG_WITH_TYPE(TgtExecutor::getName(), + dbgs() << CurrentIdx + << ": GIR_CustomOperandRenderer(OutMIs[" << InsnID + << "], MIs[" << OldInsnID << "]->getOperand(" + << OpIdx << "), " << RendererFnID << ")\n"); + (Exec.*ExecInfo.CustomRenderers[RendererFnID])( + OutMIs[InsnID], *State.MIs[OldInsnID], OpIdx); break; } case GIR_ConstrainOperandRC: { @@ -1124,7 +1116,7 @@ const TargetRegisterClass &RC = *TRI.getRegClass(RCEnum); MachineOperand &MO = I.getOperand(OpIdx); constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, RC, MO); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_ConstrainOperandRC(OutMIs[" << InsnID << "], " << OpIdx << ", " << RCEnum << ")\n"); @@ -1136,7 +1128,7 @@ assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); constrainSelectedInstRegOperands(*OutMIs[InsnID].getInstr(), TII, TRI, RBI); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_ConstrainSelectedInstOperands(OutMIs[" << InsnID << "])\n"); @@ -1147,18 +1139,18 @@ int64_t InsnID = MatchTable[CurrentIdx++]; assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_MergeMemOperands(OutMIs[" << InsnID << "]"); int64_t MergeInsnID = GIU_MergeMemOperands_EndOfList; while ((MergeInsnID = MatchTable[CurrentIdx++]) != GIU_MergeMemOperands_EndOfList) { - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << ", MIs[" << MergeInsnID << "]"); for (const auto &MMO : State.MIs[MergeInsnID]->memoperands()) OutMIs[InsnID].addMemOperand(MMO); } - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), dbgs() << ")\n"); + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << ")\n"); break; } @@ -1167,7 +1159,7 @@ assert(State.MIs[InsnID] && "Attempted to erase an undefined instruction"); State.MIs[InsnID]->eraseFromParent(); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_EraseFromParent(MIs[" << InsnID << "])\n"); break; @@ -1178,8 +1170,8 @@ int64_t TypeID = MatchTable[CurrentIdx++]; State.TempRegisters[TempRegID] = - MRI.createGenericVirtualRegister(ISelInfo.TypeObjects[TypeID]); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + MRI.createGenericVirtualRegister(ExecInfo.TypeObjects[TypeID]); + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": TempRegs[" << TempRegID << "] = GIR_MakeTempReg(" << TypeID << ")\n"); break; @@ -1187,20 +1179,20 @@ case GIR_Coverage: { int64_t RuleID = MatchTable[CurrentIdx++]; - CoverageInfo.setCovered(RuleID); + assert(CoverageInfo); + CoverageInfo->setCovered(RuleID); - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), - dbgs() - << CurrentIdx << ": GIR_Coverage(" << RuleID << ")"); + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx + << ": GIR_Coverage(" + << RuleID << ")"); break; } case GIR_Done: - DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx << ": GIR_Done\n"); propagateFlags(OutMIs); return true; - default: llvm_unreachable("Unexpected command"); } @@ -1209,4 +1201,4 @@ } // end namespace llvm -#endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H +#endif // LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H diff --git a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h --- a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h @@ -7,441 +7,18 @@ //===----------------------------------------------------------------------===// // /// \file This file declares the API for the instruction selector. -/// This class is responsible for selecting machine instructions. -/// It's implemented by the target. It's used by the InstructionSelect pass. // //===----------------------------------------------------------------------===// #ifndef LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H #define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/CodeGen/GlobalISel/Utils.h" -#include "llvm/CodeGen/LowLevelType.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/IR/Function.h" -#include -#include -#include -#include -#include -#include -#include +#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h" namespace llvm { - -class BlockFrequencyInfo; -class CodeGenCoverage; -class MachineBasicBlock; -class ProfileSummaryInfo; -class APInt; -class APFloat; -class GISelKnownBits; -class MachineInstr; -class MachineInstrBuilder; -class MachineFunction; -class MachineOperand; -class MachineRegisterInfo; -class RegisterBankInfo; -class TargetInstrInfo; -class TargetRegisterInfo; - -/// Container class for CodeGen predicate results. -/// This is convenient because std::bitset does not have a constructor -/// with an initializer list of set bits. -/// -/// Each InstructionSelector subclass should define a PredicateBitset class -/// with: -/// const unsigned MAX_SUBTARGET_PREDICATES = 192; -/// using PredicateBitset = PredicateBitsetImpl; -/// and updating the constant to suit the target. Tablegen provides a suitable -/// definition for the predicates in use in GenGlobalISel.inc when -/// GET_GLOBALISEL_PREDICATE_BITSET is defined. -template -class PredicateBitsetImpl : public std::bitset { -public: - // Cannot inherit constructors because it's not supported by VC++.. - PredicateBitsetImpl() = default; - - PredicateBitsetImpl(const std::bitset &B) - : std::bitset(B) {} - - PredicateBitsetImpl(std::initializer_list Init) { - for (auto I : Init) - std::bitset::set(I); - } -}; - -enum { - /// Begin a try-block to attempt a match and jump to OnFail if it is - /// unsuccessful. - /// - OnFail - The MatchTable entry at which to resume if the match fails. - /// - /// FIXME: This ought to take an argument indicating the number of try-blocks - /// to exit on failure. It's usually one but the last match attempt of - /// a block will need more. The (implemented) alternative is to tack a - /// GIM_Reject on the end of each try-block which is simpler but - /// requires an extra opcode and iteration in the interpreter on each - /// failed match. - GIM_Try, - - /// Switch over the opcode on the specified instruction - /// - InsnID - Instruction ID - /// - LowerBound - numerically minimum opcode supported - /// - UpperBound - numerically maximum + 1 opcode supported - /// - Default - failure jump target - /// - JumpTable... - (UpperBound - LowerBound) (at least 2) jump targets - GIM_SwitchOpcode, - - /// Switch over the LLT on the specified instruction operand - /// - InsnID - Instruction ID - /// - OpIdx - Operand index - /// - LowerBound - numerically minimum Type ID supported - /// - UpperBound - numerically maximum + 1 Type ID supported - /// - Default - failure jump target - /// - JumpTable... - (UpperBound - LowerBound) (at least 2) jump targets - GIM_SwitchType, - - /// Record the specified instruction. - /// The IgnoreCopies variant ignores COPY instructions. - /// - NewInsnID - Instruction ID to define - /// - InsnID - Instruction ID - /// - OpIdx - Operand index - GIM_RecordInsn, - GIM_RecordInsnIgnoreCopies, - - /// Check the feature bits - /// - Expected features - GIM_CheckFeatures, - - /// Check the opcode on the specified instruction - /// - InsnID - Instruction ID - /// - Expected opcode - GIM_CheckOpcode, - - /// Check the opcode on the specified instruction, checking 2 acceptable - /// alternatives. - /// - InsnID - Instruction ID - /// - Expected opcode - /// - Alternative expected opcode - GIM_CheckOpcodeIsEither, - - /// Check the instruction has the right number of operands - /// - InsnID - Instruction ID - /// - Expected number of operands - GIM_CheckNumOperands, - /// Check an immediate predicate on the specified instruction - /// - InsnID - Instruction ID - /// - The predicate to test - GIM_CheckI64ImmPredicate, - /// Check an immediate predicate on the specified instruction via an APInt. - /// - InsnID - Instruction ID - /// - The predicate to test - GIM_CheckAPIntImmPredicate, - /// Check a floating point immediate predicate on the specified instruction. - /// - InsnID - Instruction ID - /// - The predicate to test - GIM_CheckAPFloatImmPredicate, - /// Check an immediate predicate on the specified instruction - /// - InsnID - Instruction ID - /// - OpIdx - Operand index - /// - The predicate to test - GIM_CheckImmOperandPredicate, - /// Check a memory operation has the specified atomic ordering. - /// - InsnID - Instruction ID - /// - Ordering - The AtomicOrdering value - GIM_CheckAtomicOrdering, - GIM_CheckAtomicOrderingOrStrongerThan, - GIM_CheckAtomicOrderingWeakerThan, - /// Check the size of the memory access for the given machine memory operand. - /// - InsnID - Instruction ID - /// - MMOIdx - MMO index - /// - Size - The size in bytes of the memory access - GIM_CheckMemorySizeEqualTo, - - /// Check the address space of the memory access for the given machine memory - /// operand. - /// - InsnID - Instruction ID - /// - MMOIdx - MMO index - /// - NumAddrSpace - Number of valid address spaces - /// - AddrSpaceN - An allowed space of the memory access - /// - AddrSpaceN+1 ... - GIM_CheckMemoryAddressSpace, - - /// Check the minimum alignment of the memory access for the given machine - /// memory operand. - /// - InsnID - Instruction ID - /// - MMOIdx - MMO index - /// - MinAlign - Minimum acceptable alignment - GIM_CheckMemoryAlignment, - - /// Check the size of the memory access for the given machine memory operand - /// against the size of an operand. - /// - InsnID - Instruction ID - /// - MMOIdx - MMO index - /// - OpIdx - The operand index to compare the MMO against - GIM_CheckMemorySizeEqualToLLT, - GIM_CheckMemorySizeLessThanLLT, - GIM_CheckMemorySizeGreaterThanLLT, - - /// Check if this is a vector that can be treated as a vector splat - /// constant. This is valid for both G_BUILD_VECTOR as well as - /// G_BUILD_VECTOR_TRUNC. For AllOnes refers to individual bits, so a -1 - /// element. - /// - InsnID - Instruction ID - GIM_CheckIsBuildVectorAllOnes, - GIM_CheckIsBuildVectorAllZeros, - - /// Check a generic C++ instruction predicate - /// - InsnID - Instruction ID - /// - PredicateID - The ID of the predicate function to call - GIM_CheckCxxInsnPredicate, - - /// Check if there's no use of the first result. - /// - InsnID - Instruction ID - GIM_CheckHasNoUse, - - /// Check the type for the specified operand - /// - InsnID - Instruction ID - /// - OpIdx - Operand index - /// - Expected type - GIM_CheckType, - /// Check the type of a pointer to any address space. - /// - InsnID - Instruction ID - /// - OpIdx - Operand index - /// - SizeInBits - The size of the pointer value in bits. - GIM_CheckPointerToAny, - /// Check the register bank for the specified operand - /// - InsnID - Instruction ID - /// - OpIdx - Operand index - /// - Expected register bank (specified as a register class) - GIM_CheckRegBankForClass, - - /// Check the operand matches a complex predicate - /// - InsnID - Instruction ID - /// - OpIdx - Operand index - /// - RendererID - The renderer to hold the result - /// - Complex predicate ID - GIM_CheckComplexPattern, - - /// Check the operand is a specific integer - /// - InsnID - Instruction ID - /// - OpIdx - Operand index - /// - Expected integer - GIM_CheckConstantInt, - /// Check the operand is a specific literal integer (i.e. MO.isImm() or - /// MO.isCImm() is true). - /// - InsnID - Instruction ID - /// - OpIdx - Operand index - /// - Expected integer - GIM_CheckLiteralInt, - /// Check the operand is a specific intrinsic ID - /// - InsnID - Instruction ID - /// - OpIdx - Operand index - /// - Expected Intrinsic ID - GIM_CheckIntrinsicID, - - /// Check the operand is a specific predicate - /// - InsnID - Instruction ID - /// - OpIdx - Operand index - /// - Expected predicate - GIM_CheckCmpPredicate, - - /// Check the specified operand is an MBB - /// - InsnID - Instruction ID - /// - OpIdx - Operand index - GIM_CheckIsMBB, - - /// Check the specified operand is an Imm - /// - InsnID - Instruction ID - /// - OpIdx - Operand index - GIM_CheckIsImm, - - /// Check if the specified operand is safe to fold into the current - /// instruction. - /// - InsnID - Instruction ID - GIM_CheckIsSafeToFold, - - /// Check the specified operands are identical. - /// The IgnoreCopies variant looks through COPY instructions before - /// comparing the operands. - /// - InsnID - Instruction ID - /// - OpIdx - Operand index - /// - OtherInsnID - Other instruction ID - /// - OtherOpIdx - Other operand index - GIM_CheckIsSameOperand, - GIM_CheckIsSameOperandIgnoreCopies, - - /// Predicates with 'let PredicateCodeUsesOperands = 1' need to examine some - /// named operands that will be recorded in RecordedOperands. Names of these - /// operands are referenced in predicate argument list. Emitter determines - /// StoreIdx(corresponds to the order in which names appear in argument list). - /// - InsnID - Instruction ID - /// - OpIdx - Operand index - /// - StoreIdx - Store location in RecordedOperands. - GIM_RecordNamedOperand, - - /// Fail the current try-block, or completely fail to match if there is no - /// current try-block. - GIM_Reject, - - //=== Renderers === - - /// Mutate an instruction - /// - NewInsnID - Instruction ID to define - /// - OldInsnID - Instruction ID to mutate - /// - NewOpcode - The new opcode to use - GIR_MutateOpcode, - - /// Build a new instruction - /// - InsnID - Instruction ID to define - /// - Opcode - The new opcode to use - GIR_BuildMI, - - /// Copy an operand to the specified instruction - /// - NewInsnID - Instruction ID to modify - /// - OldInsnID - Instruction ID to copy from - /// - OpIdx - The operand to copy - GIR_Copy, - - /// Copy an operand to the specified instruction or add a zero register if the - /// operand is a zero immediate. - /// - NewInsnID - Instruction ID to modify - /// - OldInsnID - Instruction ID to copy from - /// - OpIdx - The operand to copy - /// - ZeroReg - The zero register to use - GIR_CopyOrAddZeroReg, - /// Copy an operand to the specified instruction - /// - NewInsnID - Instruction ID to modify - /// - OldInsnID - Instruction ID to copy from - /// - OpIdx - The operand to copy - /// - SubRegIdx - The subregister to copy - GIR_CopySubReg, - - /// Add an implicit register def to the specified instruction - /// - InsnID - Instruction ID to modify - /// - RegNum - The register to add - GIR_AddImplicitDef, - /// Add an implicit register use to the specified instruction - /// - InsnID - Instruction ID to modify - /// - RegNum - The register to add - GIR_AddImplicitUse, - /// Add an register to the specified instruction - /// - InsnID - Instruction ID to modify - /// - RegNum - The register to add - GIR_AddRegister, - - /// Add a temporary register to the specified instruction - /// - InsnID - Instruction ID to modify - /// - TempRegID - The temporary register ID to add - /// - TempRegFlags - The register flags to set - GIR_AddTempRegister, - - /// Add a temporary register to the specified instruction - /// - InsnID - Instruction ID to modify - /// - TempRegID - The temporary register ID to add - /// - TempRegFlags - The register flags to set - /// - SubRegIndex - The subregister index to set - GIR_AddTempSubRegister, - - /// Add an immediate to the specified instruction - /// - InsnID - Instruction ID to modify - /// - Imm - The immediate to add - GIR_AddImm, - - /// Render complex operands to the specified instruction - /// - InsnID - Instruction ID to modify - /// - RendererID - The renderer to call - GIR_ComplexRenderer, - /// Render sub-operands of complex operands to the specified instruction - /// - InsnID - Instruction ID to modify - /// - RendererID - The renderer to call - /// - RenderOpID - The suboperand to render. - GIR_ComplexSubOperandRenderer, - /// Render subregisters of suboperands of complex operands to the - /// specified instruction - /// - InsnID - Instruction ID to modify - /// - RendererID - The renderer to call - /// - RenderOpID - The suboperand to render - /// - SubRegIdx - The subregister to extract - GIR_ComplexSubOperandSubRegRenderer, - - /// Render operands to the specified instruction using a custom function - /// - InsnID - Instruction ID to modify - /// - OldInsnID - Instruction ID to get the matched operand from - /// - RendererFnID - Custom renderer function to call - GIR_CustomRenderer, - - /// Render operands to the specified instruction using a custom function, - /// reading from a specific operand. - /// - InsnID - Instruction ID to modify - /// - OldInsnID - Instruction ID to get the matched operand from - /// - OpIdx - Operand index in OldInsnID the render function should read - /// from.. - /// - RendererFnID - Custom renderer function to call - GIR_CustomOperandRenderer, - - /// Render a G_CONSTANT operator as a sign-extended immediate. - /// - NewInsnID - Instruction ID to modify - /// - OldInsnID - Instruction ID to copy from - /// The operand index is implicitly 1. - GIR_CopyConstantAsSImm, - - /// Render a G_FCONSTANT operator as a sign-extended immediate. - /// - NewInsnID - Instruction ID to modify - /// - OldInsnID - Instruction ID to copy from - /// The operand index is implicitly 1. - GIR_CopyFConstantAsFPImm, - - /// Constrain an instruction operand to a register class. - /// - InsnID - Instruction ID to modify - /// - OpIdx - Operand index - /// - RCEnum - Register class enumeration value - GIR_ConstrainOperandRC, - - /// Constrain an instructions operands according to the instruction - /// description. - /// - InsnID - Instruction ID to modify - GIR_ConstrainSelectedInstOperands, - - /// Merge all memory operands into instruction. - /// - InsnID - Instruction ID to modify - /// - MergeInsnID... - One or more Instruction ID to merge into the result. - /// - GIU_MergeMemOperands_EndOfList - Terminates the list of instructions to - /// merge. - GIR_MergeMemOperands, - - /// Erase from parent. - /// - InsnID - Instruction ID to erase - GIR_EraseFromParent, - - /// Create a new temporary register that's not constrained. - /// - TempRegID - The temporary register ID to initialize. - /// - Expected type - GIR_MakeTempReg, - - /// A successful emission - GIR_Done, - - /// Increment the rule coverage counter. - /// - RuleID - The ID of the rule that was covered. - GIR_Coverage, - - /// Keeping track of the number of the GI opcodes. Must be the last entry. - GIU_NumOpcodes, -}; - -enum { - /// Indicates the end of the variable-length MergeInsnID list in a - /// GIR_MergeMemOperands opcode. - GIU_MergeMemOperands_EndOfList = -1, -}; - -/// Provides the logic to select generic machine instructions. -class InstructionSelector { +class InstructionSelector : public GIMatchTableExecutor { public: - virtual ~InstructionSelector() = default; + virtual ~InstructionSelector(); /// Select the (possibly generic) instruction \p I to only use target-specific /// opcodes. It is OK to insert multiple instructions, but they cannot be @@ -454,135 +31,7 @@ /// for I in all mutated/inserted instructions: /// !isPreISelGenericOpcode(I.getOpcode()) virtual bool select(MachineInstr &I) = 0; - - CodeGenCoverage *CoverageInfo = nullptr; - GISelKnownBits *KnownBits = nullptr; - MachineFunction *MF = nullptr; - ProfileSummaryInfo *PSI = nullptr; - BlockFrequencyInfo *BFI = nullptr; - // For some predicates, we need to track the current MBB. - MachineBasicBlock *CurMBB = nullptr; - - virtual void setupGeneratedPerFunctionState(MachineFunction &MF) { - llvm_unreachable("TableGen should have emitted implementation"); - } - - /// Setup per-MF selector state. - virtual void setupMF(MachineFunction &mf, GISelKnownBits *KB, - CodeGenCoverage &covinfo, ProfileSummaryInfo *psi, - BlockFrequencyInfo *bfi) { - CoverageInfo = &covinfo; - KnownBits = KB; - MF = &mf; - PSI = psi; - BFI = bfi; - CurMBB = nullptr; - setupGeneratedPerFunctionState(mf); - } - -protected: - using ComplexRendererFns = - std::optional, 4>>; - using RecordedMIVector = SmallVector; - using NewMIVector = SmallVector; - - struct MatcherState { - std::vector Renderers; - RecordedMIVector MIs; - DenseMap TempRegisters; - /// Named operands that predicate with 'let PredicateCodeUsesOperands = 1' - /// referenced in its argument list. Operands are inserted at index set by - /// emitter, it corresponds to the order in which names appear in argument - /// list. Currently such predicates don't have more then 3 arguments. - std::array RecordedOperands; - - MatcherState(unsigned MaxRenderers); - }; - - bool shouldOptForSize(const MachineFunction *MF) const { - const auto &F = MF->getFunction(); - return F.hasOptSize() || F.hasMinSize() || - (PSI && BFI && CurMBB && llvm::shouldOptForSize(*CurMBB, PSI, BFI)); - } - -public: - template - struct ISelInfoTy { - ISelInfoTy(const LLT *TypeObjects, size_t NumTypeObjects, - const PredicateBitset *FeatureBitsets, - const ComplexMatcherMemFn *ComplexPredicates, - const CustomRendererFn *CustomRenderers) - : TypeObjects(TypeObjects), - FeatureBitsets(FeatureBitsets), - ComplexPredicates(ComplexPredicates), - CustomRenderers(CustomRenderers) { - - for (size_t I = 0; I < NumTypeObjects; ++I) - TypeIDMap[TypeObjects[I]] = I; - } - const LLT *TypeObjects; - const PredicateBitset *FeatureBitsets; - const ComplexMatcherMemFn *ComplexPredicates; - const CustomRendererFn *CustomRenderers; - - SmallDenseMap TypeIDMap; - }; - -protected: - InstructionSelector(); - - /// Execute a given matcher table and return true if the match was successful - /// and false otherwise. - template - bool executeMatchTable( - TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State, - const ISelInfoTy - &ISelInfo, - const int64_t *MatchTable, const TargetInstrInfo &TII, - MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, - const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures, - CodeGenCoverage &CoverageInfo) const; - - virtual const int64_t *getMatchTable() const { - llvm_unreachable("Should have been overridden by tablegen if used"); - } - - virtual bool testImmPredicate_I64(unsigned, int64_t) const { - llvm_unreachable( - "Subclasses must override this with a tablegen-erated function"); - } - virtual bool testImmPredicate_APInt(unsigned, const APInt &) const { - llvm_unreachable( - "Subclasses must override this with a tablegen-erated function"); - } - virtual bool testImmPredicate_APFloat(unsigned, const APFloat &) const { - llvm_unreachable( - "Subclasses must override this with a tablegen-erated function"); - } - virtual bool testMIPredicate_MI( - unsigned, const MachineInstr &, - const std::array &Operands) const { - llvm_unreachable( - "Subclasses must override this with a tablegen-erated function"); - } - - bool isOperandImmEqual(const MachineOperand &MO, int64_t Value, - const MachineRegisterInfo &MRI) const; - - /// Return true if the specified operand is a G_PTR_ADD with a G_CONSTANT on the - /// right-hand side. GlobalISel's separation of pointer and integer types - /// means that we don't need to worry about G_OR with equivalent semantics. - bool isBaseWithConstantOffset(const MachineOperand &Root, - const MachineRegisterInfo &MRI) const; - - /// Return true if MI can obviously be folded into IntoMI. - /// MI and IntoMI do not need to be in the same basic blocks, but MI must - /// preceed IntoMI. - bool isObviouslySafeToFold(MachineInstr &MI, MachineInstr &IntoMI) const; }; +} // namespace llvm -} // end namespace llvm - -#endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H +#endif diff --git a/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt b/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt --- a/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt +++ b/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt @@ -6,6 +6,7 @@ GlobalISel.cpp Combiner.cpp CombinerHelper.cpp + GIMatchTableExecutor.cpp GISelChangeObserver.cpp IRTranslator.cpp InlineAsmLowering.cpp diff --git a/llvm/lib/CodeGen/GlobalISel/InstructionSelector.cpp b/llvm/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp copy from llvm/lib/CodeGen/GlobalISel/InstructionSelector.cpp copy to llvm/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp --- a/llvm/lib/CodeGen/GlobalISel/InstructionSelector.cpp +++ b/llvm/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp @@ -1,4 +1,4 @@ -//===- llvm/CodeGen/GlobalISel/InstructionSelector.cpp --------------------===// +//===- llvm/CodeGen/GlobalISel/GIMatchTableExecutor.cpp -------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,26 +7,26 @@ //===----------------------------------------------------------------------===// // /// \file -/// This file implements the InstructionSelector class. +/// This file implements the GIMatchTableExecutor class. // //===----------------------------------------------------------------------===// -#include "llvm/CodeGen/GlobalISel/InstructionSelector.h" +#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h" #include "llvm/CodeGen/GlobalISel/Utils.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#define DEBUG_TYPE "instructionselector" +#define DEBUG_TYPE "gi-match-table-executor" using namespace llvm; -InstructionSelector::MatcherState::MatcherState(unsigned MaxRenderers) +GIMatchTableExecutor::MatcherState::MatcherState(unsigned MaxRenderers) : Renderers(MaxRenderers) {} -InstructionSelector::InstructionSelector() = default; +GIMatchTableExecutor::GIMatchTableExecutor() = default; -bool InstructionSelector::isOperandImmEqual( +bool GIMatchTableExecutor::isOperandImmEqual( const MachineOperand &MO, int64_t Value, const MachineRegisterInfo &MRI) const { if (MO.isReg() && MO.getReg()) @@ -35,7 +35,7 @@ return false; } -bool InstructionSelector::isBaseWithConstantOffset( +bool GIMatchTableExecutor::isBaseWithConstantOffset( const MachineOperand &Root, const MachineRegisterInfo &MRI) const { if (!Root.isReg()) return false; @@ -52,8 +52,8 @@ return true; } -bool InstructionSelector::isObviouslySafeToFold(MachineInstr &MI, - MachineInstr &IntoMI) const { +bool GIMatchTableExecutor::isObviouslySafeToFold(MachineInstr &MI, + MachineInstr &IntoMI) const { // Immediate neighbours are already folded. if (MI.getParent() == IntoMI.getParent() && std::next(MI.getIterator()) == IntoMI.getIterator()) diff --git a/llvm/lib/CodeGen/GlobalISel/InstructionSelector.cpp b/llvm/lib/CodeGen/GlobalISel/InstructionSelector.cpp --- a/llvm/lib/CodeGen/GlobalISel/InstructionSelector.cpp +++ b/llvm/lib/CodeGen/GlobalISel/InstructionSelector.cpp @@ -5,64 +5,12 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// -/// \file -/// This file implements the InstructionSelector class. -// -//===----------------------------------------------------------------------===// #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" -#include "llvm/CodeGen/GlobalISel/Utils.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/MachineOperand.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" - -#define DEBUG_TYPE "instructionselector" - -using namespace llvm; - -InstructionSelector::MatcherState::MatcherState(unsigned MaxRenderers) - : Renderers(MaxRenderers) {} - -InstructionSelector::InstructionSelector() = default; - -bool InstructionSelector::isOperandImmEqual( - const MachineOperand &MO, int64_t Value, - const MachineRegisterInfo &MRI) const { - if (MO.isReg() && MO.getReg()) - if (auto VRegVal = getIConstantVRegValWithLookThrough(MO.getReg(), MRI)) - return VRegVal->Value.getSExtValue() == Value; - return false; -} - -bool InstructionSelector::isBaseWithConstantOffset( - const MachineOperand &Root, const MachineRegisterInfo &MRI) const { - if (!Root.isReg()) - return false; - - MachineInstr *RootI = MRI.getVRegDef(Root.getReg()); - if (RootI->getOpcode() != TargetOpcode::G_PTR_ADD) - return false; - - MachineOperand &RHS = RootI->getOperand(2); - MachineInstr *RHSI = MRI.getVRegDef(RHS.getReg()); - if (RHSI->getOpcode() != TargetOpcode::G_CONSTANT) - return false; - - return true; -} -bool InstructionSelector::isObviouslySafeToFold(MachineInstr &MI, - MachineInstr &IntoMI) const { - // Immediate neighbours are already folded. - if (MI.getParent() == IntoMI.getParent() && - std::next(MI.getIterator()) == IntoMI.getIterator()) - return true; +namespace llvm { - // Convergent instructions cannot be moved in the CFG. - if (MI.isConvergent() && MI.getParent() != IntoMI.getParent()) - return false; +// vtable anchor +InstructionSelector::~InstructionSelector() = default; - return !MI.mayLoadOrStore() && !MI.mayRaiseFPException() && - !MI.hasUnmodeledSideEffects() && MI.implicit_operands().empty(); -} +} // namespace llvm diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp --- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp @@ -21,9 +21,9 @@ #include "MCTargetDesc/AArch64AddressingModes.h" #include "MCTargetDesc/AArch64MCTargetDesc.h" #include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h" #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" -#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/GlobalISel/Utils.h" diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp @@ -19,8 +19,8 @@ #include "AMDGPUTargetMachine.h" #include "SIMachineFunctionInfo.h" #include "Utils/AMDGPUBaseInfo.h" +#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" -#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/MachineFrameInfo.h" diff --git a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp --- a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp +++ b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp @@ -13,8 +13,8 @@ #include "ARMRegisterBankInfo.h" #include "ARMSubtarget.h" #include "ARMTargetMachine.h" +#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" -#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/IR/IntrinsicsARM.h" diff --git a/llvm/lib/Target/M68k/GISel/M68kInstructionSelector.cpp b/llvm/lib/Target/M68k/GISel/M68kInstructionSelector.cpp --- a/llvm/lib/Target/M68k/GISel/M68kInstructionSelector.cpp +++ b/llvm/lib/Target/M68k/GISel/M68kInstructionSelector.cpp @@ -9,8 +9,8 @@ #include "M68kRegisterBankInfo.h" #include "M68kSubtarget.h" #include "M68kTargetMachine.h" +#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" -#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" #include "llvm/Support/Debug.h" #define DEBUG_TYPE "m68k-isel" diff --git a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp --- a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp +++ b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp @@ -15,7 +15,7 @@ #include "MipsMachineFunction.h" #include "MipsRegisterBankInfo.h" #include "MipsTargetMachine.h" -#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" +#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/IR/IntrinsicsMips.h" diff --git a/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp b/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp --- a/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp +++ b/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp @@ -16,9 +16,9 @@ #include "PPCRegisterBankInfo.h" #include "PPCSubtarget.h" #include "PPCTargetMachine.h" +#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h" #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" -#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunction.h" diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp --- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp @@ -14,8 +14,8 @@ #include "RISCVRegisterBankInfo.h" #include "RISCVSubtarget.h" #include "RISCVTargetMachine.h" +#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" -#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" #include "llvm/IR/IntrinsicsRISCV.h" #include "llvm/Support/Debug.h" diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -20,8 +20,8 @@ #include "SPIRVTargetMachine.h" #include "SPIRVUtils.h" #include "llvm/ADT/APFloat.h" +#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" -#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/IR/IntrinsicsSPIRV.h" diff --git a/llvm/lib/Target/X86/X86InstructionSelector.cpp b/llvm/lib/Target/X86/X86InstructionSelector.cpp --- a/llvm/lib/Target/X86/X86InstructionSelector.cpp +++ b/llvm/lib/Target/X86/X86InstructionSelector.cpp @@ -19,8 +19,8 @@ #include "X86RegisterInfo.h" #include "X86Subtarget.h" #include "X86TargetMachine.h" +#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" -#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" #include "llvm/CodeGen/GlobalISel/Utils.h" #include "llvm/CodeGen/LowLevelType.h" #include "llvm/CodeGen/MachineBasicBlock.h" diff --git a/llvm/test/TableGen/ContextlessPredicates.td b/llvm/test/TableGen/ContextlessPredicates.td --- a/llvm/test/TableGen/ContextlessPredicates.td +++ b/llvm/test/TableGen/ContextlessPredicates.td @@ -14,7 +14,7 @@ let IsAtomic = 1; let MemoryVT = i32; } - + def INSN : I<(outs GPR32:$dst), (ins GPR32Op:$src1, GPR32Op:$src2), []>; def : Pat<(test_atomic_op_frag GPR32:$ptr, GPR32:$val) , @@ -35,7 +35,7 @@ // CHECK_NOPT-NEXT: // MIs[0] val // CHECK_NOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, // CHECK_NOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, -// CHECK_NOPT-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_test_atomic_op_frag, +// CHECK_NOPT-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GICXXPred_MI_Predicate_test_atomic_op_frag, // CHECK_NOPT-NEXT: // (atomic_swap:{ *:[i32] } GPR32:{ *:[i32] }:$ptr, GPR32:{ *:[i32] }:$val)<> => (INSN:{ *:[i32] } GPR32:{ *:[i32] }:$ptr, GPR32:{ *:[i32] }:$val) // CHECK_NOPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::INSN, // CHECK_NOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, @@ -61,7 +61,7 @@ // CHECK_OPT-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32, // CHECK_OPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, // CHECK_OPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, -// CHECK_OPT-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_test_atomic_op_frag, +// CHECK_OPT-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GICXXPred_MI_Predicate_test_atomic_op_frag, // CHECK_OPT-NEXT: // (atomic_swap:{ *:[i32] } GPR32:{ *:[i32] }:$ptr, GPR32:{ *:[i32] }:$val)<> => (INSN:{ *:[i32] } GPR32:{ *:[i32] }:$ptr, GPR32:{ *:[i32] }:$val) // CHECK_OPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::INSN, // CHECK_OPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, diff --git a/llvm/test/TableGen/GlobalISelEmitter-PR39045.td b/llvm/test/TableGen/GlobalISelEmitter-PR39045.td --- a/llvm/test/TableGen/GlobalISelEmitter-PR39045.td +++ b/llvm/test/TableGen/GlobalISelEmitter-PR39045.td @@ -2,8 +2,8 @@ // RUN: FileCheck %s < %t // Both predicates should be tested -// CHECK-DAG: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_pat_frag_b, -// CHECK-DAG: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_pat_frag_a, +// CHECK-DAG: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GICXXPred_MI_Predicate_pat_frag_b, +// CHECK-DAG: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GICXXPred_MI_Predicate_pat_frag_a, include "llvm/Target/Target.td" include "GlobalISelEmitterCommon.td" @@ -37,4 +37,3 @@ (pat_frag_b GPR32:$src), (inst_b GPR32:$src) >; - diff --git a/llvm/test/TableGen/GlobalISelEmitter.td b/llvm/test/TableGen/GlobalISelEmitter.td --- a/llvm/test/TableGen/GlobalISelEmitter.td +++ b/llvm/test/TableGen/GlobalISelEmitter.td @@ -73,19 +73,19 @@ // CHECK-NEXT: mutable MatcherState State; // CHECK-NEXT: typedef ComplexRendererFns(MyTargetInstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const; // CHECK-NEXT: typedef void(MyTargetInstructionSelector::*CustomRendererFn)(MachineInstrBuilder &, const MachineInstr &, int) const; -// CHECK-NEXT: const ISelInfoTy ISelInfo; +// CHECK-NEXT: const ExecInfoTy ExecInfo; // CHECK-NEXT: static MyTargetInstructionSelector::ComplexMatcherMemFn ComplexPredicateFns[]; // CHECK-NEXT: static MyTargetInstructionSelector::CustomRendererFn CustomRenderers[]; // CHECK-NEXT: bool testImmPredicate_I64(unsigned PredicateID, int64_t Imm) const override; // CHECK-NEXT: bool testImmPredicate_APInt(unsigned PredicateID, const APInt &Imm) const override; // CHECK-NEXT: bool testImmPredicate_APFloat(unsigned PredicateID, const APFloat &Imm) const override; // CHECK-NEXT: const int64_t *getMatchTable() const override; -// CHECK-NEXT: bool testMIPredicate_MI(unsigned PredicateID, const MachineInstr &MI, const std::array &Operands) const override; +// CHECK-NEXT: bool testMIPredicate_MI(unsigned PredicateID, const MachineInstr &MI, const MatcherState &State) const override; // CHECK-NEXT: #endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL // CHECK-LABEL: #ifdef GET_GLOBALISEL_TEMPORARIES_INIT // CHECK-NEXT: , State(3), -// CHECK-NEXT: ISelInfo(TypeObjects, NumTypeObjects, FeatureBitsets, ComplexPredicateFns, CustomRenderers) +// CHECK-NEXT: ExecInfo(TypeObjects, NumTypeObjects, FeatureBitsets, ComplexPredicateFns, CustomRenderers) // CHECK-NEXT: #endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT // CHECK-LABEL: enum SubtargetFeatureBits : uint8_t { @@ -144,19 +144,19 @@ // CHECK-LABEL: // PatFrag predicates. // CHECK-NEXT: enum { -// CHECK-NEXT: GIPFP_I64_Predicate_cimm8 = GIPFP_I64_Invalid + 1, -// CHECK-NEXT: GIPFP_I64_Predicate_simm8, +// CHECK-NEXT: GICXXPred_I64_Predicate_cimm8 = GICXXPred_I64_Invalid + 1, +// CHECK-NEXT: GICXXPred_I64_Predicate_simm8, // CHECK-NEXT: }; // CHECK-NEXT: bool MyTargetInstructionSelector::testImmPredicate_I64(unsigned PredicateID, int64_t Imm) const { // CHECK-NEXT: switch (PredicateID) { -// CHECK-NEXT: case GIPFP_I64_Predicate_cimm8: { +// CHECK-NEXT: case GICXXPred_I64_Predicate_cimm8: { // CHECK-NEXT: return isInt<8>(Imm); // CHECK-NEXT: llvm_unreachable("ImmediateCode should have returned"); // CHECK-NEXT: return false; // CHECK-NEXT: } -// CHECK-NEXT: case GIPFP_I64_Predicate_simm8: { +// CHECK-NEXT: case GICXXPred_I64_Predicate_simm8: { // CHECK-NEXT: return isInt<8>(Imm); // CHECK-NEXT: llvm_unreachable("ImmediateCode should have returned"); // CHECK-NEXT: return false; @@ -168,11 +168,11 @@ // CHECK-LABEL: // PatFrag predicates. // CHECK-NEXT: enum { -// CHECK-NEXT: GIPFP_APFloat_Predicate_fpimmz = GIPFP_APFloat_Invalid + 1, +// CHECK-NEXT: GICXXPred_APFloat_Predicate_fpimmz = GICXXPred_APFloat_Invalid + 1, // CHECK-NEXT: }; // CHECK-NEXT: bool MyTargetInstructionSelector::testImmPredicate_APFloat(unsigned PredicateID, const APFloat & Imm) const { // CHECK-NEXT: switch (PredicateID) { -// CHECK-NEXT: case GIPFP_APFloat_Predicate_fpimmz: { +// CHECK-NEXT: case GICXXPred_APFloat_Predicate_fpimmz: { // CHECK-NEXT: return Imm->isExactlyValue(0.0); // CHECK-NEXT: llvm_unreachable("ImmediateCode should have returned"); // CHECK-NEXT: return false; @@ -184,11 +184,11 @@ // CHECK-LABEL: // PatFrag predicates. // CHECK-NEXT: enum { -// CHECK-NEXT: GIPFP_APInt_Predicate_simm9 = GIPFP_APInt_Invalid + 1, +// CHECK-NEXT: GICXXPred_APInt_Predicate_simm9 = GICXXPred_APInt_Invalid + 1, // CHECK-NEXT: }; // CHECK-NEXT: bool MyTargetInstructionSelector::testImmPredicate_APInt(unsigned PredicateID, const APInt & Imm) const { // CHECK-NEXT: switch (PredicateID) { -// CHECK-NEXT: case GIPFP_APInt_Predicate_simm9: { +// CHECK-NEXT: case GICXXPred_APInt_Predicate_simm9: { // CHECK-NEXT: return isInt<9>(Imm->getSExtValue()); // CHECK-NEXT: llvm_unreachable("ImmediateCode should have returned"); // CHECK-NEXT: return false; @@ -224,7 +224,7 @@ // CHECK-NEXT: State.MIs.clear(); // CHECK-NEXT: State.MIs.push_back(&I); -// CHECK: if (executeMatchTable(*this, OutMIs, State, ISelInfo, getMatchTable(), TII, MRI, TRI, RBI, AvailableFeatures, CoverageInfo)) { +// CHECK: if (executeMatchTable(*this, OutMIs, State, ExecInfo, getMatchTable(), TII, MRI, TRI, RBI, AvailableFeatures, &CoverageInfo)) { // CHECK-NEXT: return true; // CHECK-NEXT: } @@ -354,12 +354,12 @@ // R21N-NEXT: // MIs[0] src2 // R21N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, // -// R21O-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_frag, +// R21O-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GICXXPred_MI_Predicate_frag, // R21C-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex, // R21N-NEXT: // MIs[0] src3 // R21N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32, // R21C-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/3, /*Renderer*/1, GICP_gi_complex, -// R21N-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_frag, +// R21N-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GICXXPred_MI_Predicate_frag, // R21C-NEXT: // (select:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src2, complex:{ *:[i32] }:$src3)<> => (INSN2:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src3, complex:{ *:[i32] }:$src2) // R21C-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN2, @@ -851,7 +851,7 @@ // NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], // NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT, -// NOOPT-NEXT: GIM_CheckI64ImmPredicate, /*MI*/0, /*Predicate*/GIPFP_I64_Predicate_simm8, +// NOOPT-NEXT: GIM_CheckI64ImmPredicate, /*MI*/0, /*Predicate*/GICXXPred_I64_Predicate_simm8, // NOOPT-NEXT: // MIs[0] dst // NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, // NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, @@ -875,7 +875,7 @@ // NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], // NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT, -// NOOPT-NEXT: GIM_CheckAPIntImmPredicate, /*MI*/0, /*Predicate*/GIPFP_APInt_Predicate_simm9, +// NOOPT-NEXT: GIM_CheckAPIntImmPredicate, /*MI*/0, /*Predicate*/GICXXPred_APInt_Predicate_simm9, // NOOPT-NEXT: // MIs[0] dst // NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, // NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, @@ -899,7 +899,7 @@ // NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], // NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT, -// NOOPT-NEXT: GIM_CheckI64ImmPredicate, /*MI*/0, /*Predicate*/GIPFP_I64_Predicate_cimm8, +// NOOPT-NEXT: GIM_CheckI64ImmPredicate, /*MI*/0, /*Predicate*/GICXXPred_I64_Predicate_cimm8, // NOOPT-NEXT: // MIs[0] dst // NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, // NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, @@ -922,7 +922,7 @@ // NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], // NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_FCONSTANT, -// NOOPT-NEXT: GIM_CheckAPFloatImmPredicate, /*MI*/0, /*Predicate*/GIPFP_APFloat_Predicate_fpimmz, +// NOOPT-NEXT: GIM_CheckAPFloatImmPredicate, /*MI*/0, /*Predicate*/GICXXPred_APFloat_Predicate_fpimmz, // NOOPT-NEXT: // MIs[0] dst // NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, // NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::FPR32RegClassID, diff --git a/llvm/test/TableGen/GlobalISelEmitterCustomPredicate.td b/llvm/test/TableGen/GlobalISelEmitterCustomPredicate.td --- a/llvm/test/TableGen/GlobalISelEmitterCustomPredicate.td +++ b/llvm/test/TableGen/GlobalISelEmitterCustomPredicate.td @@ -4,22 +4,22 @@ // // CHECK: // PatFrag predicates. // CHECK-NEXT: enum { -// CHECK-NEXT: GIPFP_MI_Predicate_and_or_pat = GIPFP_MI_Invalid + 1, -// CHECK-NEXT: GIPFP_MI_Predicate_or_oneuse, -// CHECK-NEXT: GIPFP_MI_Predicate_patfrags_test_pat, -// CHECK-NEXT: GIPFP_MI_Predicate_sub3_pat, +// CHECK-NEXT: GICXXPred_MI_Predicate_and_or_pat = GICXXPred_MI_Invalid + 1, +// CHECK-NEXT: GICXXPred_MI_Predicate_or_oneuse, +// CHECK-NEXT: GICXXPred_MI_Predicate_patfrags_test_pat, +// CHECK-NEXT: GICXXPred_MI_Predicate_sub3_pat, // CHECK-NEXT: }; // Verify that we emit cases for all MI predicates. // // CHECK: bool MyTargetInstructionSelector::testMIPredicate_MI( -// CHECK: case GIPFP_MI_Predicate_and_or_pat: { +// CHECK: case GICXXPred_MI_Predicate_and_or_pat: { // CHECK: llvm_unreachable("GISelPredicateCode should have returned"); -// CHECK: case GIPFP_MI_Predicate_or_oneuse: { +// CHECK: case GICXXPred_MI_Predicate_or_oneuse: { // CHECK: llvm_unreachable("GISelPredicateCode should have returned"); -// CHECK: case GIPFP_MI_Predicate_patfrags_test_pat: { +// CHECK: case GICXXPred_MI_Predicate_patfrags_test_pat: { // CHECK: llvm_unreachable("GISelPredicateCode should have returned"); -// CHECK: case GIPFP_MI_Predicate_sub3_pat: { +// CHECK: case GICXXPred_MI_Predicate_sub3_pat: { // CHECK: llvm_unreachable("GISelPredicateCode should have returned"); include "llvm/Target/Target.td" @@ -94,7 +94,7 @@ // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32, // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/1, /*Op*/2, /*StoreIdx*/1, // Name : pred:3:y // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/Test::DRegsRegClassID, -// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_and_or_pat, +// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GICXXPred_MI_Predicate_and_or_pat, // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1, // CHECK-NEXT: // (and:{ *:[i32] } DOP:{ *:[i32] }:$src2:$pred:3:z, (or:{ *:[i32] } DOP:{ *:[i32] }:$src0:$pred:3:x, DOP:{ *:[i32] }:$src1:$pred:3:y))<> => (AND_OR:{ *:[i32] } DOP:{ *:[i32] }:$src0, DOP:{ *:[i32] }:$src1, DOP:{ *:[i32] }:$src2) // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::AND_OR, @@ -124,7 +124,7 @@ // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/0, /*Op*/2, /*StoreIdx*/2, // Name : pred:3:z // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/Test::DRegsRegClassID, -// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_and_or_pat, +// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GICXXPred_MI_Predicate_and_or_pat, // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1, // CHECK-NEXT: // (and:{ *:[i32] } (or:{ *:[i32] } DOP:{ *:[i32] }:$src0:$pred:3:x, DOP:{ *:[i32] }:$src1:$pred:3:y), DOP:{ *:[i32] }:$src2:$pred:3:z)<> => (AND_OR:{ *:[i32] } DOP:{ *:[i32] }:$src0, DOP:{ *:[i32] }:$src1, DOP:{ *:[i32] }:$src2) // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::AND_OR, @@ -168,7 +168,7 @@ // CHECK-NEXT: // MIs[0] src2 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/0, /*Op*/2, /*StoreIdx*/2, // Name : pred:1:z -// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_sub3_pat, +// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GICXXPred_MI_Predicate_sub3_pat, // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1, // CHECK-NEXT: // (sub:{ *:[i32] } (sub:{ *:[i32] } i32:{ *:[i32] }:$src0:$pred:1:x, i32:{ *:[i32] }:$src1:$pred:1:y), i32:{ *:[i32] }:$src2:$pred:1:z)<> => (SUB3:{ *:[i32] } i32:{ *:[i32] }:$src0, i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2) // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::SUB3, diff --git a/llvm/test/TableGen/GlobalISelEmitterOverloadedPtr.td b/llvm/test/TableGen/GlobalISelEmitterOverloadedPtr.td --- a/llvm/test/TableGen/GlobalISelEmitterOverloadedPtr.td +++ b/llvm/test/TableGen/GlobalISelEmitterOverloadedPtr.td @@ -17,7 +17,7 @@ // CHECK-NEXT: // MIs[0] src // CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/2, /*SizeInBits*/32, // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, -// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_frag_anyptr, +// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GICXXPred_MI_Predicate_frag_anyptr, // CHECK-NEXT: // (intrinsic_w_chain:{ *:[i32] } {{[0-9]+}}:{ *:[iPTR] }, GPR32:{ *:[i32] }:$src)<> => (ANYLOAD:{ *:[i32] } GPR32:{ *:[i32] }:$src) // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::ANYLOAD, let hasSideEffects = 1 in { diff --git a/llvm/test/TableGen/immarg-predicated.td b/llvm/test/TableGen/immarg-predicated.td --- a/llvm/test/TableGen/immarg-predicated.td +++ b/llvm/test/TableGen/immarg-predicated.td @@ -12,7 +12,7 @@ // GISEL-NEXT: GIM_CheckIntrinsicID, /*MI*/0, /*Op*/0, Intrinsic::mytarget_sleep0, // GISEL-NEXT: // MIs[0] src // GISEL-NEXT: GIM_CheckIsImm, /*MI*/0, /*Op*/1, -// GISEL-NEXT: GIM_CheckImmOperandPredicate, /*MI*/0, /*MO*/1, /*Predicate*/GIPFP_I64_Predicate_tuimm9, +// GISEL-NEXT: GIM_CheckImmOperandPredicate, /*MI*/0, /*MO*/1, /*Predicate*/GICXXPred_I64_Predicate_tuimm9, // GISEL-NEXT: // (intrinsic_void {{[0-9]+}}:{ *:[iPTR] }, (timm:{ *:[i32] })<>:$src) => (SLEEP0 (timm:{ *:[i32] }):$src) // GISEL-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::SLEEP0, // GISEL-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src diff --git a/llvm/test/TableGen/predicate-patfags.td b/llvm/test/TableGen/predicate-patfags.td --- a/llvm/test/TableGen/predicate-patfags.td +++ b/llvm/test/TableGen/predicate-patfags.td @@ -46,17 +46,17 @@ // GISEL: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS, // GISEL: GIM_CheckIntrinsicID, /*MI*/1, /*Op*/1, Intrinsic::tgt_mul24, -// GISEL: GIM_CheckCxxInsnPredicate, /*MI*/1, /*FnId*/GIPFP_MI_Predicate_TGTmul24_oneuse, +// GISEL: GIM_CheckCxxInsnPredicate, /*MI*/1, /*FnId*/GICXXPred_MI_Predicate_TGTmul24_oneuse, // GISEL: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS, // GISEL: GIM_CheckIntrinsicID, /*MI*/1, /*Op*/1, Intrinsic::tgt_mul24, -// GISEL: GIM_CheckCxxInsnPredicate, /*MI*/1, /*FnId*/GIPFP_MI_Predicate_TGTmul24_oneuse, +// GISEL: GIM_CheckCxxInsnPredicate, /*MI*/1, /*FnId*/GICXXPred_MI_Predicate_TGTmul24_oneuse, // GISEL: GIM_CheckOpcode, /*MI*/1, MyTarget::G_TGT_MUL24, -// GISEL: GIM_CheckCxxInsnPredicate, /*MI*/1, /*FnId*/GIPFP_MI_Predicate_TGTmul24_oneuse, +// GISEL: GIM_CheckCxxInsnPredicate, /*MI*/1, /*FnId*/GICXXPred_MI_Predicate_TGTmul24_oneuse, // GISEL: GIM_CheckOpcode, /*MI*/1, MyTarget::G_TGT_MUL24, -// GISEL: GIM_CheckCxxInsnPredicate, /*MI*/1, /*FnId*/GIPFP_MI_Predicate_TGTmul24_oneuse, +// GISEL: GIM_CheckCxxInsnPredicate, /*MI*/1, /*FnId*/GICXXPred_MI_Predicate_TGTmul24_oneuse, def inst_mad24 : I< (outs GPR32:$dst), (ins GPR32:$src0, GPR32:$src1, GPR32:$src2), diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -2235,10 +2235,10 @@ OS << "// PatFrag predicates.\n" << "enum {\n"; std::string EnumeratorSeparator = - (" = GIPFP_" + TypeIdentifier + "_Invalid + 1,\n").str(); + (" = GICXXPred_" + TypeIdentifier + "_Invalid + 1,\n").str(); for (const auto *Record : MatchedRecords) { - OS << " GIPFP_" << TypeIdentifier << "_Predicate_" << Record->getName() - << EnumeratorSeparator; + OS << " GICXXPred_" << TypeIdentifier << "_Predicate_" + << Record->getName() << EnumeratorSeparator; EnumeratorSeparator = ",\n"; } OS << "};\n"; @@ -2253,7 +2253,7 @@ if (!MatchedRecords.empty()) OS << " switch (PredicateID) {\n"; for (const auto *Record : MatchedRecords) { - OS << " case GIPFP_" << TypeIdentifier << "_Predicate_" + OS << " case GICXXPred_" << TypeIdentifier << "_Predicate_" << Record->getName() << ": {\n" << " " << Record->getValueAsString(CodeFieldName) << "\n" << " llvm_unreachable(\"" << CodeFieldName @@ -2278,9 +2278,11 @@ void GlobalISelEmitter::emitMIPredicateFns(raw_ostream &OS) { return emitCxxPredicateFns( OS, "GISelPredicateCode", "MI", "const MachineInstr &", "MI", - ", const std::array &Operands", + ", const MatcherState &State", " const MachineFunction &MF = *MI.getParent()->getParent();\n" " const MachineRegisterInfo &MRI = MF.getRegInfo();\n" + " const auto &Operands = State.RecordedOperands;\n" + " (void)Operands;\n" " (void)MRI;", [](const Record *R) { return true; }); } @@ -2427,9 +2429,9 @@ << "InstructionSelector::*CustomRendererFn)(MachineInstrBuilder &, const " "MachineInstr &, int) " "const;\n" - << " const ISelInfoTy " - "ISelInfo;\n"; + "ExecInfo;\n"; OS << " static " << Target.getName() << "InstructionSelector::ComplexMatcherMemFn ComplexPredicateFns[];\n" << " static " << Target.getName() @@ -2442,13 +2444,13 @@ "&Imm) const override;\n" << " const int64_t *getMatchTable() const override;\n" << " bool testMIPredicate_MI(unsigned PredicateID, const MachineInstr &MI" - ", const std::array &Operands) " + ", const MatcherState &State) " "const override;\n" << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n"; OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n" << ", State(" << MaxTemporaries << "),\n" - << "ISelInfo(TypeObjects, NumTypeObjects, FeatureBitsets" + << "ExecInfo(TypeObjects, NumTypeObjects, FeatureBitsets" << ", ComplexPredicateFns, CustomRenderers)\n" << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n"; @@ -2629,9 +2631,9 @@ << " NewMIVector OutMIs;\n" << " State.MIs.clear();\n" << " State.MIs.push_back(&I);\n\n" - << " if (executeMatchTable(*this, OutMIs, State, ISelInfo" + << " if (executeMatchTable(*this, OutMIs, State, ExecInfo" << ", getMatchTable(), TII, MRI, TRI, RBI, AvailableFeatures" - << ", CoverageInfo)) {\n" + << ", &CoverageInfo)) {\n" << " return true;\n" << " }\n\n" << " return false;\n" diff --git a/llvm/utils/TableGen/GlobalISelMatchTable.h b/llvm/utils/TableGen/GlobalISelMatchTable.h --- a/llvm/utils/TableGen/GlobalISelMatchTable.h +++ b/llvm/utils/TableGen/GlobalISelMatchTable.h @@ -9,7 +9,7 @@ /// \file /// This file contains the code related to the GlobalISel Match Table emitted by /// GlobalISelEmitter.cpp. The generated match table is interpreted at runtime -/// by `InstructionSelectorImpl.h` to match & apply ISel patterns. +/// by `GIMatchTableExecutorImpl.h` to match & apply ISel patterns. /// //===----------------------------------------------------------------------===// diff --git a/llvm/utils/TableGen/GlobalISelMatchTable.cpp b/llvm/utils/TableGen/GlobalISelMatchTable.cpp --- a/llvm/utils/TableGen/GlobalISelMatchTable.cpp +++ b/llvm/utils/TableGen/GlobalISelMatchTable.cpp @@ -31,8 +31,8 @@ /// Get the name of the enum value used to number the predicate function. std::string getEnumNameForPredicate(const TreePredicateFn &Predicate) { if (Predicate.hasGISelPredicateCode()) - return "GIPFP_MI_" + Predicate.getFnName(); - return "GIPFP_" + Predicate.getImmTypeIdentifier().str() + "_" + + return "GICXXPred_MI_" + Predicate.getFnName(); + return "GICXXPred_" + Predicate.getImmTypeIdentifier().str() + "_" + Predicate.getFnName(); }