16#define GET_SDNODE_DESC
17#include "AArch64GenSDNodeInfo.inc"
22#define DEBUG_TYPE "aarch64-selectiondag-info"
26 cl::desc(
"Enable AArch64 SME memory operations "
27 "to lower to librt functions"),
31 cl::desc(
"Enable AArch64 MOPS instructions "
32 "for memcpy/memset/memmove"),
40 switch (
N->getOpcode()) {
41 case AArch64ISD::WrapperLarge:
50 switch (
N->getOpcode()) {
51 case AArch64ISD::CTTZ_ELTS:
52 case AArch64ISD::CTTZ_ELTS_ZERO_POISON:
53 assert(
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType() &&
54 "Expected the general-predicate and mask to have matching types");
56 case AArch64ISD::SUNPKLO:
57 case AArch64ISD::SUNPKHI:
58 case AArch64ISD::UUNPKLO:
59 case AArch64ISD::UUNPKHI: {
60 EVT VT =
N->getValueType(0);
61 EVT OpVT =
N->getOperand(0).getValueType();
63 VT.
isInteger() &&
"Expected integer vectors!");
65 "Expected vectors of equal size!");
67 "Expected result vector with half the lanes of its input!");
70 case AArch64ISD::TRN1:
71 case AArch64ISD::TRN2:
72 case AArch64ISD::UZP1:
73 case AArch64ISD::UZP2:
74 case AArch64ISD::ZIP1:
75 case AArch64ISD::ZIP2: {
76 EVT VT =
N->getValueType(0);
77 EVT Op0VT =
N->getOperand(0).getValueType();
78 EVT Op1VT =
N->getOperand(1).getValueType();
81 assert(VT == Op0VT && VT == Op1VT &&
"Expected matching vectors!");
84 case AArch64ISD::RSHRNB_I: {
85 EVT VT =
N->getValueType(0);
86 EVT Op0VT =
N->getOperand(0).getValueType();
88 "Expected integer vector result type!");
90 "Expected first operand to be an integer vector!");
92 "Expected vectors of equal size!");
94 "Expected input vector with half the lanes of its result!");
96 "Expected second operand to be a constant!");
107 Align SrcAlign,
bool isVolatile,
116 const bool IsSet = Opcode == AArch64::MOPSMemorySetPseudo ||
117 Opcode == AArch64::MOPSMemorySetTaggingPseudo;
132 const EVT ResultTys[] = {MVT::i64, MVT::i64, MVT::Other};
138 const EVT ResultTys[] = {MVT::i64, MVT::i64, MVT::i64, MVT::Other};
158 bool UsesResult =
false;
159 RTLIB::Libcall NewLC;
161 case RTLIB::MEMCPY: {
162 NewLC = RTLIB::SC_MEMCPY;
166 case RTLIB::MEMMOVE: {
167 NewLC = RTLIB::SC_MEMMOVE;
171 case RTLIB::MEMSET: {
172 NewLC = RTLIB::SC_MEMSET;
177 case RTLIB::MEMCHR: {
179 NewLC = RTLIB::SC_MEMCHR;
189 if (NewLCImpl == RTLIB::Unsupported)
202 auto [Result, ChainOut] = TLI->LowerCallTo(CLI);
215 return EmitMOPS(AArch64::MOPSMemoryCopyPseudo, DAG,
DL, Chain, Dst, Src,
216 Size, DstAlign, SrcAlign, isVolatile, DstPtrInfo,
220 SMEAttrs Attrs = AFI->getSMEFnAttrs();
235 return EmitMOPS(AArch64::MOPSMemorySetPseudo, DAG, dl, Chain, Dst, Src,
236 Size, Alignment, Alignment, isVolatile, DstPtrInfo,
240 SMEAttrs Attrs = AFI->getSMEFnAttrs();
255 return EmitMOPS(AArch64::MOPSMemoryMovePseudo, DAG, dl, Chain, Dst, Src,
256 Size, DstAlign, SrcAlign, isVolatile, DstPtrInfo,
260 SMEAttrs Attrs = AFI->getSMEFnAttrs();
271 SMEAttrs Attrs = AFI->getSMEFnAttrs();
274 DAG, dl, Chain, Src, Char,
Length, RTLIB::MEMCHR);
275 return std::make_pair(Result.getValue(0), Result.getValue(1));
287 unsigned ObjSizeScaled = ObjSize / 16;
298 const unsigned OpCode1 = ZeroData ? AArch64ISD::STZG : AArch64ISD::STG;
299 const unsigned OpCode2 = ZeroData ? AArch64ISD::STZ2G : AArch64ISD::ST2G;
302 unsigned OffsetScaled = 0;
303 while (OffsetScaled < ObjSizeScaled) {
304 if (ObjSizeScaled - OffsetScaled >= 2) {
309 {Chain, TagSrc, AddrNode},
317 if (ObjSizeScaled - OffsetScaled > 0) {
322 {Chain, TagSrc, AddrNode},
337 uint64_t ObjSize =
Size->getAsZExtVal();
338 assert(ObjSize % 16 == 0);
344 bool UseSetTagRangeLoop =
346 if (!UseSetTagRangeLoop)
350 const EVT ResTys[] = {MVT::i64, MVT::i64, MVT::Other};
356 Opcode = ZeroData ? AArch64::STZGloop : AArch64::STGloop;
358 Opcode = ZeroData ? AArch64::STZGloop_wback : AArch64::STGloop_wback;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static SDValue EmitUnrolledSetTag(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Ptr, uint64_t ObjSize, const MachineMemOperand *BaseMemOperand, bool ZeroData)
static cl::opt< bool > UseMOPS("aarch64-use-mops", cl::Hidden, cl::desc("Enable AArch64 MOPS instructions " "for memcpy/memset/memmove"), cl::init(true))
static cl::opt< bool > LowerToSMERoutines("aarch64-lower-to-sme-routines", cl::Hidden, cl::desc("Enable AArch64 SME memory operations " "to lower to librt functions"), cl::init(true))
static const int kSetTagLoopThreshold
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
void verifyTargetNode(const SelectionDAG &DAG, const SDNode *N) const override
Checks that the given target-specific node is valid. Aborts if it is not.
SDValue EmitMOPS(unsigned Opcode, SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Dst, SDValue SrcOrValue, SDValue Size, Align DstAlign, Align SrcAlign, bool isVolatile, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const
SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline, MachinePointerInfo DstPtrInfo) const override
Emit target-specific code that performs a memset.
SDValue EmitStreamingCompatibleMemLibCall(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Op0, SDValue Op1, SDValue Size, RTLIB::Libcall LC) const
SDValue EmitTargetCodeForSetTag(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Op1, SDValue Op2, MachinePointerInfo DstPtrInfo, bool ZeroData) const override
SDValue EmitTargetCodeForMemmove(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVolatile, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const override
Emit target-specific code that performs a memmove.
AArch64SelectionDAGInfo()
SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVolatile, bool AlwaysInline, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const override
Emit target-specific code that performs a memcpy.
std::pair< SDValue, SDValue > EmitTargetCodeForMemchr(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Src, SDValue Char, SDValue Length, MachinePointerInfo SrcPtrInfo) const override
Emit target-specific code that performs a memchr, in cases where that is faster than a libcall.
const AArch64TargetLowering * getTargetLowering() const override
LLVM_ABI IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const
Get the CallingConv that should be used for the specified libcall.
RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const
Return the lowering's selection of implementation call for Call.
static LocationSize precise(uint64_t Value)
static constexpr LocationSize afterPointer()
Any location after the base pointer (but still within the underlying object).
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
A description of a memory reference used in the backend.
@ MOVolatile
The memory access is volatile.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
An SDNode that represents everything that will be needed to construct a MachineInstr.
Class to represent pointers.
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
EVT getValueType() const
Return the ValueType of the referenced return value.
unsigned getOpcode() const
SMEAttrs is a utility class to parse the SME ACLE attributes on functions.
SelectionDAGGenTargetInfo(const SDNodeInfo &GenNodeInfo)
void verifyTargetNode(const SelectionDAG &DAG, const SDNode *N) const override
Checks that the given target-specific node is valid. Aborts if it is not.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
LLVM_ABI void setNodeMemRefs(MachineSDNode *N, ArrayRef< MachineMemOperand * > NewMemRefs)
Mutate the specified machine node's memory references to the provided list.
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
LLVM_ABI SDValue getMemBasePlusOffset(SDValue Base, TypeSize Offset, const SDLoc &DL, const SDNodeFlags Flags=SDNodeFlags())
Returns sum of the base pointer and offset.
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const LibcallLoweringInfo & getLibcalls() const
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
MachineFunction & getMachineFunction() const
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVMContext * getContext() const
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
std::vector< ArgListEntry > ArgListTy
static constexpr TypeSize getFixed(ScalarTy ExactSize)
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
This struct is a compact representation of a valid (non-zero power of two) alignment.
ElementCount getVectorElementCount() const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
This class contains a discriminated union of information about pointers in memory operands,...
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setChain(SDValue InChain)