[llvm] 1fe7d9c - [GlobalISel] Generalize `InstructionSelector` Match Tables
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 11 00:42:46 PDT 2023
Author: pvanhout
Date: 2023-07-11T09:42:30+02:00
New Revision: 1fe7d9c79967d1e1456778e5008b8f68bc16d41f
URL: https://github.com/llvm/llvm-project/commit/1fe7d9c79967d1e1456778e5008b8f68bc16d41f
DIFF: https://github.com/llvm/llvm-project/commit/1fe7d9c79967d1e1456778e5008b8f68bc16d41f.diff
LOG: [GlobalISel] Generalize `InstructionSelector` Match Tables
Makes `InstructionSelector.h`/`InstructionSelectorImpl.h` generic so the match tables can also be used for the combiner.
Some notes:
- Coverage was made an optional parameter of `executeMatchTable`, combines won't use it for now.
- `GIPFP_` -> `GICXXPred_` so it's more generic. Those are just C++ predicates and aren't PatFrag-specific.
- Pass the MatcherState directly to testMIPredicate_MI, the combiner will need it.
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D153755
Added:
llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
llvm/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp
Modified:
llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
llvm/lib/CodeGen/GlobalISel/CMakeLists.txt
llvm/lib/CodeGen/GlobalISel/InstructionSelector.cpp
llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
llvm/lib/Target/ARM/ARMInstructionSelector.cpp
llvm/lib/Target/M68k/GISel/M68kInstructionSelector.cpp
llvm/lib/Target/Mips/MipsInstructionSelector.cpp
llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
llvm/lib/Target/X86/X86InstructionSelector.cpp
llvm/test/TableGen/ContextlessPredicates.td
llvm/test/TableGen/GlobalISelEmitter-PR39045.td
llvm/test/TableGen/GlobalISelEmitter.td
llvm/test/TableGen/GlobalISelEmitterCustomPredicate.td
llvm/test/TableGen/GlobalISelEmitterOverloadedPtr.td
llvm/test/TableGen/immarg-predicated.td
llvm/test/TableGen/predicate-patfags.td
llvm/utils/TableGen/GlobalISelEmitter.cpp
llvm/utils/TableGen/GlobalISelMatchTable.cpp
llvm/utils/TableGen/GlobalISelMatchTable.h
Removed:
llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
new file mode 100644
index 00000000000000..a1e0c889dc10eb
--- /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 <bitset>
+#include <cstddef>
+#include <cstdint>
+#include <functional>
+#include <initializer_list>
+#include <optional>
+#include <vector>
+
+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<MAX_SUBTARGET_PREDICATES>;
+/// and updating the constant to suit the target. Tablegen provides a suitable
+/// definition for the predicates in use in <Target>GenGlobalISel.inc when
+/// GET_GLOBALISEL_PREDICATE_BITSET is defined.
+template <std::size_t MaxPredicates>
+class PredicateBitsetImpl : public std::bitset<MaxPredicates> {
+public:
+ // Cannot inherit constructors because it's not supported by VC++..
+ PredicateBitsetImpl() = default;
+
+ PredicateBitsetImpl(const std::bitset<MaxPredicates> &B)
+ : std::bitset<MaxPredicates>(B) {}
+
+ PredicateBitsetImpl(std::initializer_list<unsigned> Init) {
+ for (auto I : Init)
+ std::bitset<MaxPredicates>::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<SmallVector<std::function<void(MachineInstrBuilder &)>, 4>>;
+ using RecordedMIVector = SmallVector<MachineInstr *, 4>;
+ using NewMIVector = SmallVector<MachineInstrBuilder, 4>;
+
+ struct MatcherState {
+ std::vector<ComplexRendererFns::value_type> Renderers;
+ RecordedMIVector MIs;
+ DenseMap<unsigned, unsigned> 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<const MachineOperand *, 3> 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 <class PredicateBitset, class ComplexMatcherMemFn,
+ class CustomRendererFn>
+ 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<LLT, unsigned, 64> TypeIDMap;
+ };
+
+protected:
+ GIMatchTableExecutor();
+
+ /// Execute a given matcher table and return true if the match was successful
+ /// and false otherwise.
+ template <class TgtExecutor, class PredicateBitset, class ComplexMatcherMemFn,
+ class CustomRendererFn>
+ bool executeMatchTable(
+ TgtExecutor &Exec, NewMIVector &OutMIs, MatcherState &State,
+ const ExecInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn>
+ &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 d2a03f119156c7..12bf6bc687ab77 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 <class TgtInstructionSelector, class PredicateBitset,
- class ComplexMatcherMemFn, class CustomRendererFn>
-bool InstructionSelector::executeMatchTable(
- TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State,
- const ISelInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn>
- &ISelInfo,
+template <class TgtExecutor, class PredicateBitset, class ComplexMatcherMemFn,
+ class CustomRendererFn>
+bool GIMatchTableExecutor::executeMatchTable(
+ TgtExecutor &Exec, NewMIVector &OutMIs, MatcherState &State,
+ const ExecInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn>
+ &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<uint64_t, 4> 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 fda84080636b6f..1662136cfa94af 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 <bitset>
-#include <cstddef>
-#include <cstdint>
-#include <functional>
-#include <initializer_list>
-#include <optional>
-#include <vector>
+#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<MAX_SUBTARGET_PREDICATES>;
-/// and updating the constant to suit the target. Tablegen provides a suitable
-/// definition for the predicates in use in <Target>GenGlobalISel.inc when
-/// GET_GLOBALISEL_PREDICATE_BITSET is defined.
-template <std::size_t MaxPredicates>
-class PredicateBitsetImpl : public std::bitset<MaxPredicates> {
-public:
- // Cannot inherit constructors because it's not supported by VC++..
- PredicateBitsetImpl() = default;
-
- PredicateBitsetImpl(const std::bitset<MaxPredicates> &B)
- : std::bitset<MaxPredicates>(B) {}
-
- PredicateBitsetImpl(std::initializer_list<unsigned> Init) {
- for (auto I : Init)
- std::bitset<MaxPredicates>::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<SmallVector<std::function<void(MachineInstrBuilder &)>, 4>>;
- using RecordedMIVector = SmallVector<MachineInstr *, 4>;
- using NewMIVector = SmallVector<MachineInstrBuilder, 4>;
-
- struct MatcherState {
- std::vector<ComplexRendererFns::value_type> Renderers;
- RecordedMIVector MIs;
- DenseMap<unsigned, unsigned> 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<const MachineOperand *, 3> 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 <class PredicateBitset, class ComplexMatcherMemFn,
- class CustomRendererFn>
- 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<LLT, unsigned, 64> TypeIDMap;
- };
-
-protected:
- InstructionSelector();
-
- /// Execute a given matcher table and return true if the match was successful
- /// and false otherwise.
- template <class TgtInstructionSelector, class PredicateBitset,
- class ComplexMatcherMemFn, class CustomRendererFn>
- bool executeMatchTable(
- TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State,
- const ISelInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn>
- &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<const MachineOperand *, 3> &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 09e2abbe89c633..46e6c6df5998e5 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 00000000000000..d747cbf5aadc84
--- /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 8959d215ecd1a3..c48591cc2f02fb 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 657053602d89f1..2f612976aa41a4 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 43c54606a3988c..2a6ab437ccee95 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 a4ab2f86d046f3..f391058a70514c 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 a627eccd110d72..3fddf10aca2ef6 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 04fe0960998dd7..4478a574a24088 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 24f02a3def06ba..3fd7a1ad9efa59 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 f0dc26bff39219..691439b3a18b4c 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 5507e9254faee6..9152c7479d7ee9 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 fc6f3bd876acd7..6157dafb5c5106 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 083e1d214b8b84..7f081e9a0ec00a 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)<<P:Predicate_test_atomic_op_frag>> => (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)<<P:Predicate_test_atomic_op_frag>> => (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 3500e7d8dd6c20..55e5aa2e905d6b 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 2878718457e80d..a2284513cfb752 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<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn> ISelInfo;
+// CHECK-NEXT: const ExecInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn> 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<const MachineOperand *, 3> &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)<<P:Predicate_frag>> => (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 408055da34c985..49e8f4fdfe7de7 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))<<P:3:Predicate_and_or_pat>> => (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)<<P:3:Predicate_and_or_pat>> => (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)<<P:1:Predicate_sub3_pat>> => (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 047af1ca0524fe..0cc3485342cc61 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)<<P:Predicate_frag_anyptr>> => (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 16db4a80f0597b..87326c652356b8 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<ArgIndex<0>>]>;
// 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] })<<P:Predicate_tuimm9>>:$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 a6a44ff6938feb..17cc74206b716b 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 a6dc1b167dacd2..59fa2833b05d9f 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<const MachineOperand *, 3> &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<PredicateBitset, ComplexMatcherMemFn, "
+ << " const ExecInfoTy<PredicateBitset, ComplexMatcherMemFn, "
"CustomRendererFn> "
- "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<const MachineOperand *, 3> &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 a8516ddc3053f3..67c4509904d83d 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 07da626e75aefb..837ff402d071fd 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.
///
//===----------------------------------------------------------------------===//
More information about the llvm-commits
mailing list