LLVM 20.0.0git
|
This file implements the targeting of the InstructionSelector class for AArch64. More...
#include "AArch64GlobalISelUtils.h"
#include "AArch64InstrInfo.h"
#include "AArch64MachineFunctionInfo.h"
#include "AArch64RegisterBankInfo.h"
#include "AArch64RegisterInfo.h"
#include "AArch64Subtarget.h"
#include "AArch64TargetMachine.h"
#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/MIPatternMatch.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/GlobalISel/Utils.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicsAArch64.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <optional>
#include "AArch64GenGlobalISel.inc"
Go to the source code of this file.
Namespaces | |
namespace | llvm |
This is an optimization pass for GlobalISel generic memory operations. | |
Macros | |
#define | DEBUG_TYPE "aarch64-isel" |
#define | GET_GLOBALISEL_PREDICATE_BITSET |
#define | GET_GLOBALISEL_PREDICATES_DECL |
#define | GET_GLOBALISEL_TEMPORARIES_DECL |
#define | GET_GLOBALISEL_IMPL |
#define | GET_GLOBALISEL_PREDICATES_INIT |
#define | GET_GLOBALISEL_TEMPORARIES_INIT |
Functions | |
static const TargetRegisterClass * | getMinClassForRegBank (const RegisterBank &RB, TypeSize SizeInBits, bool GetAllRegSet=false) |
Given a register bank, and size in bits, return the smallest register class that can represent that combination. | |
static bool | getSubRegForClass (const TargetRegisterClass *RC, const TargetRegisterInfo &TRI, unsigned &SubReg) |
Returns the correct subregister to use for a given register class. | |
static unsigned | getMinSizeForRegBank (const RegisterBank &RB) |
Returns the minimum size the given register bank can hold. | |
static Register | createTuple (ArrayRef< Register > Regs, const unsigned RegClassIDs[], const unsigned SubRegs[], MachineIRBuilder &MIB) |
Create a REG_SEQUENCE instruction using the registers in Regs . | |
static Register | createDTuple (ArrayRef< Register > Regs, MachineIRBuilder &MIB) |
Create a tuple of D-registers using the registers in Regs . | |
static Register | createQTuple (ArrayRef< Register > Regs, MachineIRBuilder &MIB) |
Create a tuple of Q-registers using the registers in Regs . | |
static std::optional< uint64_t > | getImmedFromMO (const MachineOperand &Root) |
static bool | unsupportedBinOp (const MachineInstr &I, const AArch64RegisterBankInfo &RBI, const MachineRegisterInfo &MRI, const AArch64RegisterInfo &TRI) |
Check whether I is a currently unsupported binary operation: | |
static unsigned | selectBinaryOp (unsigned GenericOpc, unsigned RegBankID, unsigned OpSize) |
Select the AArch64 opcode for the basic binary operation GenericOpc (such as G_OR or G_SDIV), appropriate for the register bank RegBankID and of size OpSize . | |
static unsigned | selectLoadStoreUIOp (unsigned GenericOpc, unsigned RegBankID, unsigned OpSize) |
Select the AArch64 opcode for the G_LOAD or G_STORE operation GenericOpc , appropriate for the (value) register bank RegBankID and of memory access size OpSize . | |
static bool | copySubReg (MachineInstr &I, MachineRegisterInfo &MRI, const RegisterBankInfo &RBI, Register SrcReg, const TargetRegisterClass *To, unsigned SubReg) |
Helper function for selectCopy. | |
static std::pair< const TargetRegisterClass *, const TargetRegisterClass * > | getRegClassesForCopy (MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) |
Helper function to get the source and destination register classes for a copy. | |
static bool | selectDebugInstr (MachineInstr &I, MachineRegisterInfo &MRI, const RegisterBankInfo &RBI) |
static bool | selectCopy (MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) |
static unsigned | selectFPConvOpc (unsigned GenericOpc, LLT DstTy, LLT SrcTy) |
static AArch64CC::CondCode | changeICMPPredToAArch64CC (CmpInst::Predicate P) |
static void | changeFPCCToORAArch64CC (CmpInst::Predicate CC, AArch64CC::CondCode &CondCode, AArch64CC::CondCode &CondCode2) |
changeFPCCToORAArch64CC - Convert an IR fp condition code to an AArch64 CC. | |
static void | changeFPCCToANDAArch64CC (CmpInst::Predicate CC, AArch64CC::CondCode &CondCode, AArch64CC::CondCode &CondCode2) |
Convert an IR fp condition code to an AArch64 CC. | |
static Register | getTestBitReg (Register Reg, uint64_t &Bit, bool &Invert, MachineRegisterInfo &MRI) |
Return a register which can be used as a bit to test in a TB(N)Z. | |
static std::optional< int64_t > | getVectorShiftImm (Register Reg, MachineRegisterInfo &MRI) |
Returns the element immediate value of a vector shift operand if found. | |
static std::optional< int64_t > | getVectorSHLImm (LLT SrcTy, Register Reg, MachineRegisterInfo &MRI) |
Matches and returns the shift immediate value for a SHL instruction given a shift operand. | |
static bool | getLaneCopyOpcode (unsigned &CopyOpc, unsigned &ExtractSubReg, const unsigned EltSize) |
static std::pair< unsigned, unsigned > | getInsertVecEltOpInfo (const RegisterBank &RB, unsigned EltSize) |
Return an <Opcode, SubregIndex> pair to do an vector elt insert of a given size and RB. | |
static bool | canEmitConjunction (Register Val, bool &CanNegate, bool &MustBeFirst, bool WillNegate, MachineRegisterInfo &MRI, unsigned Depth=0) |
Returns true if Val is a tree of AND/OR/CMP operations that can be expressed as a conjunction. | |
static bool | isSignExtendShiftType (AArch64_AM::ShiftExtendType Type) |
static AArch64_AM::ShiftExtendType | getShiftTypeForInst (MachineInstr &MI) |
Given a shift instruction, return the correct shift type for that instruction. | |
static void | fixupPHIOpBanks (MachineInstr &MI, MachineRegisterInfo &MRI, const AArch64RegisterBankInfo &RBI) |
InstructionSelector * | llvm::createAArch64InstructionSelector (const AArch64TargetMachine &, const AArch64Subtarget &, const AArch64RegisterBankInfo &) |
This file implements the targeting of the InstructionSelector class for AArch64.
Definition in file AArch64InstructionSelector.cpp.
#define DEBUG_TYPE "aarch64-isel" |
Definition at line 52 of file AArch64InstructionSelector.cpp.
#define GET_GLOBALISEL_IMPL |
Definition at line 547 of file AArch64InstructionSelector.cpp.
#define GET_GLOBALISEL_PREDICATE_BITSET |
Definition at line 65 of file AArch64InstructionSelector.cpp.
#define GET_GLOBALISEL_PREDICATES_DECL |
Definition at line 534 of file AArch64InstructionSelector.cpp.
#define GET_GLOBALISEL_PREDICATES_INIT |
#define GET_GLOBALISEL_TEMPORARIES_DECL |
Definition at line 540 of file AArch64InstructionSelector.cpp.
#define GET_GLOBALISEL_TEMPORARIES_INIT |
|
static |
Returns true if Val
is a tree of AND/OR/CMP operations that can be expressed as a conjunction.
CanNegate | Set to true if we can negate the whole sub-tree just by changing the conditions on the CMP tests. (this means we can call emitConjunctionRec() with Negate==true on this sub-tree) |
MustBeFirst | Set to true if this subtree needs to be negated and we cannot do the negation naturally. We are required to emit the subtree first in this case. |
WillNegate | Is true if are called when the result of this subexpression must be negated. This happens when the outer expression is an OR. We can use this fact to know that we have a double negation (or (or ...) ...) that can be implemented for free. |
Definition at line 4682 of file AArch64InstructionSelector.cpp.
References assert(), canEmitConjunction(), llvm::Depth, llvm::MachineInstr::getOpcode(), llvm::MachineInstr::getOperand(), llvm::MachineOperand::getReg(), and MRI.
Referenced by canEmitConjunction().
|
static |
Convert an IR fp condition code to an AArch64 CC.
This differs from changeFPCCToAArch64CC in that it returns cond codes that should be AND'ed instead of OR'ed.
Definition at line 1429 of file AArch64InstructionSelector.cpp.
References llvm::AArch64CC::AL, assert(), CC, changeFPCCToORAArch64CC(), llvm::CmpInst::FCMP_ONE, llvm::CmpInst::FCMP_UEQ, llvm::AArch64CC::LE, llvm::AArch64CC::NE, llvm::AArch64CC::PL, and llvm::AArch64CC::VC.
|
static |
changeFPCCToORAArch64CC - Convert an IR fp condition code to an AArch64 CC.
Definition at line 1372 of file AArch64InstructionSelector.cpp.
References llvm::AArch64CC::AL, CC, llvm::AArch64CC::EQ, llvm::CmpInst::FCMP_OEQ, llvm::CmpInst::FCMP_OGE, llvm::CmpInst::FCMP_OGT, llvm::CmpInst::FCMP_OLE, llvm::CmpInst::FCMP_OLT, llvm::CmpInst::FCMP_ONE, llvm::CmpInst::FCMP_ORD, llvm::CmpInst::FCMP_UEQ, llvm::CmpInst::FCMP_UGE, llvm::CmpInst::FCMP_UGT, llvm::CmpInst::FCMP_ULE, llvm::CmpInst::FCMP_ULT, llvm::CmpInst::FCMP_UNE, llvm::CmpInst::FCMP_UNO, llvm::AArch64CC::GE, llvm::AArch64CC::GT, llvm::AArch64CC::HI, llvm::AArch64CC::LE, llvm_unreachable, llvm::AArch64CC::LS, llvm::AArch64CC::LT, llvm::AArch64CC::MI, llvm::AArch64CC::NE, llvm::AArch64CC::PL, llvm::AArch64CC::VC, and llvm::AArch64CC::VS.
Referenced by changeFPCCToANDAArch64CC().
|
static |
Definition at line 1344 of file AArch64InstructionSelector.cpp.
References llvm::AArch64CC::EQ, llvm::AArch64CC::GE, llvm::AArch64CC::GT, llvm::AArch64CC::HI, llvm::AArch64CC::HS, llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_NE, llvm::CmpInst::ICMP_SGE, llvm::CmpInst::ICMP_SGT, llvm::CmpInst::ICMP_SLE, llvm::CmpInst::ICMP_SLT, llvm::CmpInst::ICMP_UGE, llvm::CmpInst::ICMP_UGT, llvm::CmpInst::ICMP_ULE, llvm::CmpInst::ICMP_ULT, llvm::AArch64CC::LE, llvm_unreachable, llvm::AArch64CC::LO, llvm::AArch64CC::LS, llvm::AArch64CC::LT, llvm::AArch64CC::NE, and P.
|
static |
Helper function for selectCopy.
Inserts a subregister copy from SrcReg
to *To
.
E.g "To = COPY SrcReg:SubReg"
Definition at line 922 of file AArch64InstructionSelector.cpp.
References assert(), llvm::MachineIRBuilder::buildInstr(), llvm::RegisterBankInfo::constrainGenericRegister(), I, llvm::Register::isValid(), MRI, llvm::MachineOperand::setReg(), and SubReg.
Referenced by selectCopy().
|
static |
Create a tuple of D-registers using the registers in Regs
.
Definition at line 723 of file AArch64InstructionSelector.cpp.
References createTuple().
|
static |
Create a tuple of Q-registers using the registers in Regs
.
Definition at line 732 of file AArch64InstructionSelector.cpp.
References createTuple().
|
static |
Create a REG_SEQUENCE instruction using the registers in Regs
.
Helper function for functions like createDTuple and createQTuple.
RegClassIDs
- The list of register class IDs available for some tuple of a scalar class. E.g. QQRegClassID, QQQRegClassID, QQQQRegClassID. This is expected to contain between 2 and 4 tuple classes.
SubRegs
- The list of subregister classes associated with each register class ID in RegClassIDs
. E.g., QQRegClassID should use the qsub0 subregister class. The index of each subregister class is expected to correspond with the index of each register class.
Regs
if Regs
contains a single element. Definition at line 703 of file AArch64InstructionSelector.cpp.
References assert(), llvm::MachineIRBuilder::buildInstr(), llvm::MachineIRBuilder::getMF(), llvm::TargetSubtargetInfo::getRegisterInfo(), llvm::MachineFunction::getSubtarget(), I, llvm::ArrayRef< T >::size(), and TRI.
Referenced by createDTuple(), createQTuple(), llvm::RISCVDAGToDAGISel::selectVLSEG(), llvm::RISCVDAGToDAGISel::selectVLSEGFF(), llvm::RISCVDAGToDAGISel::selectVLXSEG(), llvm::RISCVDAGToDAGISel::selectVSSEG(), and llvm::RISCVDAGToDAGISel::selectVSXSEG().
|
static |
Definition at line 7873 of file AArch64InstructionSelector.cpp.
References assert(), llvm::MachineIRBuilder::buildCopy(), llvm::drop_begin(), llvm::MachineBasicBlock::end(), llvm::MachineBasicBlock::getFirstNonPHI(), llvm::MachineBasicBlock::getParent(), MI, MRI, and llvm::MachineIRBuilder::setInsertPt().
|
static |
Definition at line 740 of file AArch64InstructionSelector.cpp.
References llvm::MachineOperand::getCImm(), llvm::getIConstantVRegValWithLookThrough(), llvm::MachineOperand::getImm(), llvm::MachineOperand::getParent(), llvm::MachineBasicBlock::getParent(), llvm::MachineOperand::getReg(), llvm::ConstantInt::getZExtValue(), llvm::MachineOperand::isCImm(), llvm::MachineOperand::isImm(), llvm::MachineOperand::isReg(), MBB, MI, and MRI.
|
static |
Return an <Opcode, SubregIndex> pair to do an vector elt insert of a given size and RB.
Definition at line 4213 of file AArch64InstructionSelector.cpp.
References llvm::RegisterBank::getID(), and llvm_unreachable.
|
static |
Definition at line 3855 of file AArch64InstructionSelector.cpp.
References llvm::dbgs(), and LLVM_DEBUG.
|
static |
Given a register bank, and size in bits, return the smallest register class that can represent that combination.
Definition at line 607 of file AArch64InstructionSelector.cpp.
References assert(), llvm::RegisterBank::getID(), and llvm::details::FixedOrScalableQuantity< LeafTy, ValueTy >::isScalable().
Referenced by getRegClassesForCopy(), and selectCopy().
|
static |
Returns the minimum size the given register bank can hold.
Definition at line 677 of file AArch64InstructionSelector.cpp.
References llvm::RegisterBank::getID(), and llvm_unreachable.
Referenced by selectCopy().
|
static |
Helper function to get the source and destination register classes for a copy.
Returns a std::pair containing the source register class for the copy, and the destination register class for the copy. If a register class cannot be determined, then it will be nullptr.
Definition at line 948 of file AArch64InstructionSelector.cpp.
References llvm::TypeSize::getFixed(), getMinClassForRegBank(), llvm::RegisterBankInfo::getRegBank(), llvm::RegisterBankInfo::getSizeInBits(), I, MRI, and TRI.
Referenced by selectCopy().
|
static |
Given a shift instruction, return the correct shift type for that instruction.
Definition at line 7532 of file AArch64InstructionSelector.cpp.
References llvm::AArch64_AM::ASR, llvm::AArch64_AM::InvalidShiftExtend, llvm::AArch64_AM::LSL, llvm::AArch64_AM::LSR, MI, and llvm::AArch64_AM::ROR.
|
static |
Returns the correct subregister to use for a given register class.
Definition at line 649 of file AArch64InstructionSelector.cpp.
References llvm::dbgs(), LLVM_DEBUG, SubReg, and TRI.
Referenced by selectCopy().
|
static |
Return a register which can be used as a bit to test in a TB(N)Z.
Definition at line 1456 of file AArch64InstructionSelector.cpp.
References assert(), llvm::CallingConv::C, llvm::getDefIgnoringCopies(), llvm::getIConstantVRegValWithLookThrough(), llvm::Register::isValid(), MI, MRI, and std::swap().
|
static |
Returns the element immediate value of a vector shift operand if found.
This needs to detect a splat-like operation, e.g. a G_BUILD_VECTOR.
Definition at line 1849 of file AArch64InstructionSelector.cpp.
References assert(), llvm::AArch64GISelUtils::getAArch64VectorSplatScalar(), and MRI.
Referenced by getVectorSHLImm().
|
static |
Matches and returns the shift immediate value for a SHL instruction given a shift operand.
Definition at line 1858 of file AArch64InstructionSelector.cpp.
References llvm::dbgs(), llvm::LLT::getElementType(), llvm::LLT::getSizeInBits(), getVectorShiftImm(), LLVM_DEBUG, and MRI.
|
static |
Definition at line 7059 of file AArch64InstructionSelector.cpp.
References llvm::AArch64_AM::SXTB, llvm::AArch64_AM::SXTH, and llvm::AArch64_AM::SXTW.
Select the AArch64 opcode for the basic binary operation GenericOpc
(such as G_OR or G_SDIV), appropriate for the register bank RegBankID
and of size OpSize
.
GenericOpc
if the combination is unsupported. Definition at line 813 of file AArch64InstructionSelector.cpp.
|
static |
Definition at line 1006 of file AArch64InstructionSelector.cpp.
References llvm::MachineInstrBuilder::addImm(), llvm::MachineInstrBuilder::addUse(), assert(), llvm::MachineIRBuilder::buildCopy(), llvm::BuildMI(), llvm::RegisterBankInfo::constrainGenericRegister(), copySubReg(), llvm::dbgs(), llvm::RegisterBank::getID(), getMinClassForRegBank(), getMinSizeForRegBank(), llvm::RegisterBankInfo::getRegBank(), getRegClassesForCopy(), llvm::RegisterBankInfo::getSizeInBits(), getSubRegForClass(), I, llvm::Register::isPhysical(), LLVM_DEBUG, MRI, selectCopy(), llvm::MachineOperand::setReg(), SubReg, TII, and TRI.
Referenced by selectCopy().
|
static |
Definition at line 977 of file AArch64InstructionSelector.cpp.
References llvm::RegisterBankInfo::constrainGenericRegister(), llvm::dbgs(), llvm::PointerUnion< PTs >::dyn_cast(), llvm::PointerUnion< PTs >::get(), I, LLVM_DEBUG, and MRI.
Definition at line 1097 of file AArch64InstructionSelector.cpp.
References llvm::LLT::getSizeInBits(), and llvm::LLT::isScalar().
|
static |
Select the AArch64 opcode for the G_LOAD or G_STORE operation GenericOpc
, appropriate for the (value) register bank RegBankID
and of memory access size OpSize
.
This returns the variant with the base+unsigned-immediate addressing mode (e.g., LDRXui).
GenericOpc
if the combination is unsupported. Definition at line 884 of file AArch64InstructionSelector.cpp.
References isStore().
|
static |
Check whether I
is a currently unsupported binary operation:
Definition at line 767 of file AArch64InstructionSelector.cpp.
References llvm::dbgs(), llvm::RegisterBankInfo::getRegBank(), I, llvm::LLT::isValid(), LLVM_DEBUG, MRI, and TRI.