diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h new file mode 100644 index 0000000000000..a1e0c889dc10e --- /dev/null +++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h @@ -0,0 +1,583 @@ +//===- 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. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +/// \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_GIMATCHTABLEEXECUTOR_H +#define LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTOR_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 + +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 GIMatchTableExecutor 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 { + 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. + /// - 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 execute GlobalISel match tables, which are used by the +/// instruction selector and instruction combiners as their engine to match and +/// apply MIR patterns. +class GIMatchTableExecutor { +public: + virtual ~GIMatchTableExecutor() = default; + + 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 executor 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 ExecInfoTy { + ExecInfoTy(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: + GIMatchTableExecutor(); + + /// Execute a given matcher table and return true if the match was successful + /// and false otherwise. + template + bool executeMatchTable( + 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; + + 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 MatcherState &State) 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; +}; + +} // end namespace llvm + +#endif // LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTOR_H diff --git a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h similarity index 82% rename from llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h rename to llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h index d2a03f119156c..12bf6bc687ab7 100644 --- 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 @@ bool InstructionSelector::executeMatchTable( 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 @@ bool InstructionSelector::executeMatchTable( 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 @@ bool InstructionSelector::executeMatchTable( 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 @@ bool InstructionSelector::executeMatchTable( "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 @@ bool InstructionSelector::executeMatchTable( 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 @@ bool InstructionSelector::executeMatchTable( 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 @@ bool InstructionSelector::executeMatchTable( 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 @@ bool InstructionSelector::executeMatchTable( 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 @@ bool InstructionSelector::executeMatchTable( 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 @@ bool InstructionSelector::executeMatchTable( 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 @@ bool InstructionSelector::executeMatchTable( ? 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 @@ bool InstructionSelector::executeMatchTable( 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,20 +292,20 @@ bool InstructionSelector::executeMatchTable( 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"); - APInt Value; - if (State.MIs[InsnID]->getOperand(1).isCImm()) - Value = State.MIs[InsnID]->getOperand(1).getCImm()->getValue(); - else + assert(Predicate > GICXXPred_APInt_Invalid && + "Expected a valid predicate"); + if (!State.MIs[InsnID]->getOperand(1).isCImm()) llvm_unreachable("Expected Imm or CImm operand"); + const APInt &Value = + State.MIs[InsnID]->getOperand(1).getCImm()->getValue(); if (!testImmPredicate_APInt(Predicate, Value)) if (handleReject() == RejectAndGiveUp) return false; @@ -324,16 +314,19 @@ bool InstructionSelector::executeMatchTable( 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"); + const APFloat &Value = + State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF(); if (!testImmPredicate_APFloat(Predicate, Value)) if (handleReject() == RejectAndGiveUp) @@ -344,7 +337,7 @@ bool InstructionSelector::executeMatchTable( 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 +365,14 @@ bool InstructionSelector::executeMatchTable( 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 +380,7 @@ bool InstructionSelector::executeMatchTable( 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 +399,7 @@ bool InstructionSelector::executeMatchTable( 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 +416,7 @@ bool InstructionSelector::executeMatchTable( 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 +434,7 @@ bool InstructionSelector::executeMatchTable( 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 +465,16 @@ bool InstructionSelector::executeMatchTable( // 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 +500,13 @@ bool InstructionSelector::executeMatchTable( 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 +517,9 @@ bool InstructionSelector::executeMatchTable( 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 +529,12 @@ bool InstructionSelector::executeMatchTable( 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 +549,19 @@ bool InstructionSelector::executeMatchTable( 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 +574,8 @@ bool InstructionSelector::executeMatchTable( 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 +597,14 @@ bool InstructionSelector::executeMatchTable( 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 +615,7 @@ bool InstructionSelector::executeMatchTable( 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 +646,7 @@ bool InstructionSelector::executeMatchTable( 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 +659,7 @@ bool InstructionSelector::executeMatchTable( 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 +680,7 @@ bool InstructionSelector::executeMatchTable( 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 +689,12 @@ bool InstructionSelector::executeMatchTable( 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 +702,7 @@ bool InstructionSelector::executeMatchTable( 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 +727,7 @@ bool InstructionSelector::executeMatchTable( 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 +749,7 @@ bool InstructionSelector::executeMatchTable( 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 +764,7 @@ bool InstructionSelector::executeMatchTable( 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 +778,7 @@ bool InstructionSelector::executeMatchTable( 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 +791,7 @@ bool InstructionSelector::executeMatchTable( 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 +803,7 @@ bool InstructionSelector::executeMatchTable( } 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 +819,7 @@ bool InstructionSelector::executeMatchTable( 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 +845,11 @@ bool InstructionSelector::executeMatchTable( 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 +860,7 @@ bool InstructionSelector::executeMatchTable( 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 +875,7 @@ bool InstructionSelector::executeMatchTable( 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 +887,7 @@ bool InstructionSelector::executeMatchTable( 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 +905,7 @@ bool InstructionSelector::executeMatchTable( 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 +920,7 @@ bool InstructionSelector::executeMatchTable( 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 +932,7 @@ bool InstructionSelector::executeMatchTable( 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 +943,7 @@ bool InstructionSelector::executeMatchTable( 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 +955,10 @@ bool InstructionSelector::executeMatchTable( 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 +973,14 @@ bool InstructionSelector::executeMatchTable( 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 +989,7 @@ bool InstructionSelector::executeMatchTable( 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 +1001,7 @@ bool InstructionSelector::executeMatchTable( 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 +1012,7 @@ bool InstructionSelector::executeMatchTable( 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 +1028,7 @@ bool InstructionSelector::executeMatchTable( 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 +1040,8 @@ bool InstructionSelector::executeMatchTable( 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 +1049,7 @@ bool InstructionSelector::executeMatchTable( 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 +1060,17 @@ bool InstructionSelector::executeMatchTable( 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 +1079,13 @@ bool InstructionSelector::executeMatchTable( 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 +1095,13 @@ bool InstructionSelector::executeMatchTable( 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 +1115,7 @@ bool InstructionSelector::executeMatchTable( 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 +1127,7 @@ bool InstructionSelector::executeMatchTable( 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 +1138,18 @@ bool InstructionSelector::executeMatchTable( 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 +1158,7 @@ bool InstructionSelector::executeMatchTable( 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 +1169,8 @@ bool InstructionSelector::executeMatchTable( 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 +1178,20 @@ bool InstructionSelector::executeMatchTable( 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 +1200,4 @@ bool InstructionSelector::executeMatchTable( } // 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 index fda84080636b6..1662136cfa94a 100644 --- 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 @@ class InstructionSelector { /// 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 index 09e2abbe89c63..46e6c6df5998e 100644 --- a/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt +++ b/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt @@ -6,6 +6,7 @@ add_llvm_component_library(LLVMGlobalISel GlobalISel.cpp Combiner.cpp CombinerHelper.cpp + GIMatchTableExecutor.cpp GISelChangeObserver.cpp IRTranslator.cpp InlineAsmLowering.cpp diff --git a/llvm/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp b/llvm/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp new file mode 100644 index 0000000000000..d747cbf5aadc8 --- /dev/null +++ b/llvm/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp @@ -0,0 +1,68 @@ +//===- 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. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +/// \file +/// This file implements the GIMatchTableExecutor class. +// +//===----------------------------------------------------------------------===// + +#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 "gi-match-table-executor" + +using namespace llvm; + +GIMatchTableExecutor::MatcherState::MatcherState(unsigned MaxRenderers) + : Renderers(MaxRenderers) {} + +GIMatchTableExecutor::GIMatchTableExecutor() = default; + +bool GIMatchTableExecutor::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 GIMatchTableExecutor::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 GIMatchTableExecutor::isObviouslySafeToFold(MachineInstr &MI, + MachineInstr &IntoMI) const { + // Immediate neighbours are already folded. + if (MI.getParent() == IntoMI.getParent() && + std::next(MI.getIterator()) == IntoMI.getIterator()) + return true; + + // Convergent instructions cannot be moved in the CFG. + if (MI.isConvergent() && MI.getParent() != IntoMI.getParent()) + return false; + + return !MI.mayLoadOrStore() && !MI.mayRaiseFPException() && + !MI.hasUnmodeledSideEffects() && MI.implicit_operands().empty(); +} diff --git a/llvm/lib/CodeGen/GlobalISel/InstructionSelector.cpp b/llvm/lib/CodeGen/GlobalISel/InstructionSelector.cpp index 8959d215ecd1a..c48591cc2f02f 100644 --- 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 index 657053602d89f..2f612976aa41a 100644 --- 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 index 43c54606a3988..2a6ab437ccee9 100644 --- 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 index a4ab2f86d046f..f391058a70514 100644 --- 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 index a627eccd110d7..3fddf10aca2ef 100644 --- 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 index 04fe0960998dd..4478a574a2408 100644 --- 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 index 24f02a3def06b..3fd7a1ad9efa5 100644 --- 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 index f0dc26bff3921..691439b3a18b4 100644 --- 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 index 5507e9254faee..9152c7479d7ee 100644 --- 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 index fc6f3bd876acd..6157dafb5c510 100644 --- 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 index 083e1d214b8b8..7f081e9a0ec00 100644 --- a/llvm/test/TableGen/ContextlessPredicates.td +++ b/llvm/test/TableGen/ContextlessPredicates.td @@ -14,7 +14,7 @@ def test_atomic_op_frag : PatFrag<(ops node:$ptr, node:$val), 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 @@ def : Pat<(test_atomic_op_frag GPR32:$ptr, GPR32:$val) , // 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 @@ def : Pat<(test_atomic_op_frag GPR32:$ptr, GPR32:$val) , // 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 index 3500e7d8dd6c2..55e5aa2e905d6 100644 --- 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 @@ def : Pat < (pat_frag_b GPR32:$src), (inst_b GPR32:$src) >; - diff --git a/llvm/test/TableGen/GlobalISelEmitter.td b/llvm/test/TableGen/GlobalISelEmitter.td index 2878718457e80..a2284513cfb75 100644 --- a/llvm/test/TableGen/GlobalISelEmitter.td +++ b/llvm/test/TableGen/GlobalISelEmitter.td @@ -73,19 +73,19 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; } // 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 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; } // 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 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; } // 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 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; } // 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 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; } // 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 @@ def : Pat<(select GPR32:$src1, (complex_rr GPR32:$src2a, GPR32:$src2b), // 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 @@ def MOV1 : I<(outs GPR32:$dst), (ins), [(set GPR32:$dst, 1)]>; // 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 @@ def MOVimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm8:$i // 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 @@ def MOVimm9 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm9:$i // 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 @@ def MOVcimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, cimm8:$ // 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 index 408055da34c98..49e8f4fdfe7de 100644 --- 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 @@ def and_or_pat : PatFrag< // 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 @@ def and_or_pat : PatFrag< // 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 @@ def sub3_pat : PatFrag< // 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 index 047af1ca0524f..0cc3485342cc6 100644 --- a/llvm/test/TableGen/GlobalISelEmitterOverloadedPtr.td +++ b/llvm/test/TableGen/GlobalISelEmitterOverloadedPtr.td @@ -17,7 +17,7 @@ let TargetPrefix = "mytarget" in { // 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 index 16db4a80f0597..87326c652356b 100644 --- a/llvm/test/TableGen/immarg-predicated.td +++ b/llvm/test/TableGen/immarg-predicated.td @@ -12,7 +12,7 @@ def int_mytarget_sleep0 : Intrinsic<[], [llvm_i32_ty], [ImmArg>]>; // 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 index a6a44ff6938fe..17cc74206b716 100644 --- a/llvm/test/TableGen/predicate-patfags.td +++ b/llvm/test/TableGen/predicate-patfags.td @@ -46,17 +46,17 @@ def TGTmul24_oneuse : PatFrag< // 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 index a6dc1b167dacd..59fa2833b05d9 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -2235,10 +2235,10 @@ void GlobalISelEmitter::emitCxxPredicateFns( 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 @@ void GlobalISelEmitter::emitCxxPredicateFns( 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::emitImmPredicateFns( 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 @@ void GlobalISelEmitter::run(raw_ostream &OS) { << "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 @@ void GlobalISelEmitter::run(raw_ostream &OS) { "&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 @@ void GlobalISelEmitter::run(raw_ostream &OS) { << " 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.cpp b/llvm/utils/TableGen/GlobalISelMatchTable.cpp index a8516ddc3053f..67c4509904d83 100644 --- a/llvm/utils/TableGen/GlobalISelMatchTable.cpp +++ b/llvm/utils/TableGen/GlobalISelMatchTable.cpp @@ -31,8 +31,8 @@ Error failUnsupported(const Twine &Reason) { /// 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(); } diff --git a/llvm/utils/TableGen/GlobalISelMatchTable.h b/llvm/utils/TableGen/GlobalISelMatchTable.h index 07da626e75aef..837ff402d071f 100644 --- 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. /// //===----------------------------------------------------------------------===//