LLVM 23.0.0git
X86SelectionDAGInfo.cpp
Go to the documentation of this file.
1//===-- X86SelectionDAGInfo.cpp - X86 SelectionDAG Info -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the X86SelectionDAGInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "X86SelectionDAGInfo.h"
14#include "X86InstrInfo.h"
15#include "X86RegisterInfo.h"
16#include "X86Subtarget.h"
20
21#define GET_SDNODE_DESC
22#include "X86GenSDNodeInfo.inc"
23
24using namespace llvm;
25
26#define DEBUG_TYPE "x86-selectiondag-info"
27
28static cl::opt<bool>
29 UseFSRMForMemcpy("x86-use-fsrm-for-memcpy", cl::Hidden, cl::init(false),
30 cl::desc("Use fast short rep mov in memcpy lowering"));
31
34
35const char *X86SelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
36#define NODE_NAME_CASE(NODE) \
37 case X86ISD::NODE: \
38 return "X86ISD::" #NODE;
39
40 // These nodes don't have corresponding entries in *.td files yet.
41 switch (static_cast<X86ISD::NodeType>(Opcode)) {
42 NODE_NAME_CASE(POP_FROM_X87_REG)
43 NODE_NAME_CASE(GlobalBaseReg)
44 NODE_NAME_CASE(LCMPXCHG16_SAVE_RBX_DAG)
45 NODE_NAME_CASE(PCMPESTR)
46 NODE_NAME_CASE(PCMPISTR)
47 NODE_NAME_CASE(MGATHER)
48 NODE_NAME_CASE(MSCATTER)
49 NODE_NAME_CASE(AESENCWIDE128KL)
50 NODE_NAME_CASE(AESDECWIDE128KL)
51 NODE_NAME_CASE(AESENCWIDE256KL)
52 NODE_NAME_CASE(AESDECWIDE256KL)
53 }
54#undef NODE_NAME_CASE
55
57}
58
59bool X86SelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
60 // These nodes don't have corresponding entries in *.td files yet.
61 if (Opcode >= X86ISD::FIRST_MEMORY_OPCODE &&
63 return true;
64
66}
67
69 const SDNode *N) const {
70 switch (N->getOpcode()) {
71 default:
72 break;
73 case X86ISD::VP2INTERSECT:
74 // invalid number of results; expected 1, got 2
75 case X86ISD::FSETCCM_SAE:
76 // invalid number of operands; expected 3, got 4
77 case X86ISD::CVTTP2SI_SAE:
78 case X86ISD::CVTTP2UI_SAE:
79 case X86ISD::CVTTP2IBS_SAE:
80 // invalid number of operands; expected 1, got 2
81 case X86ISD::CMPMM_SAE:
82 // invalid number of operands; expected 4, got 5
83 case X86ISD::CALL:
84 case X86ISD::NT_BRIND:
85 // operand #1 must have type i32 (iPTR), but has type i64
86 case X86ISD::INSERTQI:
87 case X86ISD::EXTRQI:
88 // result #0 must have type v2i64, but has type v16i8/v8i16
89 case X86ISD::CMPCCXADD:
90 // operand #4 must have type i8, but has type i32
91 return;
92 }
93
95}
96
97/// Returns the best type to use with repmovs/repstos depending on alignment.
98static MVT getOptimalRepType(const X86Subtarget &Subtarget, Align Alignment) {
99 uint64_t Align = Alignment.value();
100 assert((Align != 0) && "Align is normalized");
101 assert(isPowerOf2_64(Align) && "Align is a power of 2");
102 switch (Align) {
103 case 1:
104 return MVT::i8;
105 case 2:
106 return MVT::i16;
107 case 4:
108 return MVT::i32;
109 default:
110 return Subtarget.is64Bit() ? MVT::i64 : MVT::i32;
111 }
112}
113
114bool X86SelectionDAGInfo::isBaseRegConflictPossible(
115 SelectionDAG &DAG, ArrayRef<MCPhysReg> ClobberSet) const {
116 // We cannot use TRI->hasBasePointer() until *after* we select all basic
117 // blocks. Legalization may introduce new stack temporaries with large
118 // alignment requirements. Fall back to generic code if there are any
119 // dynamic stack adjustments (hopefully rare) and the base pointer would
120 // conflict if we had to use it.
121 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
122 if (!MFI.hasVarSizedObjects() && !MFI.hasOpaqueSPAdjustment())
123 return false;
124
125 const X86RegisterInfo *TRI = static_cast<const X86RegisterInfo *>(
126 DAG.getSubtarget().getRegisterInfo());
127 return llvm::is_contained(ClobberSet, TRI->getBaseRegister());
128}
129
130/// Emit a single REP STOSB instruction for a particular constant size.
131static SDValue emitRepstos(const X86Subtarget &Subtarget, SelectionDAG &DAG,
132 const SDLoc &dl, SDValue Chain, SDValue Dst,
133 SDValue Val, SDValue Size, MVT AVT) {
134 const bool Use64BitRegs = Subtarget.isTarget64BitLP64();
135 unsigned AX = X86::AL;
136 switch (AVT.getSizeInBits()) {
137 case 8:
138 AX = X86::AL;
139 break;
140 case 16:
141 AX = X86::AX;
142 break;
143 case 32:
144 AX = X86::EAX;
145 break;
146 default:
147 AX = X86::RAX;
148 break;
149 }
150
151 const unsigned CX = Use64BitRegs ? X86::RCX : X86::ECX;
152 const unsigned DI = Use64BitRegs ? X86::RDI : X86::EDI;
153
154 SDValue InGlue;
155 Chain = DAG.getCopyToReg(Chain, dl, AX, Val, InGlue);
156 InGlue = Chain.getValue(1);
157 Chain = DAG.getCopyToReg(Chain, dl, CX, Size, InGlue);
158 InGlue = Chain.getValue(1);
159 Chain = DAG.getCopyToReg(Chain, dl, DI, Dst, InGlue);
160 InGlue = Chain.getValue(1);
161
162 SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue);
163 SDValue Ops[] = {Chain, DAG.getValueType(AVT), InGlue};
164 return DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops);
165}
166
167/// Emit a single REP STOSB instruction for a particular constant size.
168static SDValue emitRepstosB(const X86Subtarget &Subtarget, SelectionDAG &DAG,
169 const SDLoc &dl, SDValue Chain, SDValue Dst,
170 SDValue Val, uint64_t Size) {
171 return emitRepstos(Subtarget, DAG, dl, Chain, Dst, Val,
172 DAG.getIntPtrConstant(Size, dl), MVT::i8);
173}
174
175/// Returns a REP STOS instruction, possibly with a few load/stores to implement
176/// a constant size memory set. In some cases where we know REP MOVS is
177/// inefficient we return an empty SDValue so the calling code can either
178/// generate a store sequence or call the runtime memset function.
180 const X86Subtarget &Subtarget,
181 const SDLoc &dl, SDValue Chain,
182 SDValue Dst, SDValue Val, uint64_t Size,
183 EVT SizeVT, Align Alignment,
184 bool isVolatile, bool AlwaysInline,
185 MachinePointerInfo DstPtrInfo) {
186 /// In case we optimize for size, we use repstosb even if it's less efficient
187 /// so we can save the loads/stores of the leftover.
189 if (auto *ValC = dyn_cast<ConstantSDNode>(Val)) {
190 // Special case 0 because otherwise we get large literals,
191 // which causes larger encoding.
192 if ((Size & 31) == 0 && (ValC->getZExtValue() & 255) == 0) {
193 MVT BlockType = MVT::i32;
194 const uint64_t BlockBits = BlockType.getSizeInBits();
195 const uint64_t BlockBytes = BlockBits / 8;
196 const uint64_t BlockCount = Size / BlockBytes;
197
198 Val = DAG.getConstant(0, dl, BlockType);
199 // repstosd is same size as repstosb
200 return emitRepstos(Subtarget, DAG, dl, Chain, Dst, Val,
201 DAG.getIntPtrConstant(BlockCount, dl), BlockType);
202 }
203 }
204 return emitRepstosB(Subtarget, DAG, dl, Chain, Dst, Val, Size);
205 }
206
207 if (Size > Subtarget.getMaxInlineSizeThreshold())
208 return SDValue();
209
210 // If not DWORD aligned or size is more than the threshold, call the library.
211 // The libc version is likely to be faster for these cases. It can use the
212 // address value and run time information about the CPU.
213 if (Alignment < Align(4))
214 return SDValue();
215
216 MVT BlockType = MVT::i8;
217 uint64_t BlockCount = Size;
218 uint64_t BytesLeft = 0;
219
220 SDValue OriginalVal = Val;
221 if (auto *ValC = dyn_cast<ConstantSDNode>(Val)) {
222 BlockType = getOptimalRepType(Subtarget, Alignment);
223 uint64_t Value = ValC->getZExtValue() & 255;
224 const uint64_t BlockBits = BlockType.getSizeInBits();
225
226 if (BlockBits >= 16)
227 Value = (Value << 8) | Value;
228
229 if (BlockBits >= 32)
230 Value = (Value << 16) | Value;
231
232 if (BlockBits >= 64)
233 Value = (Value << 32) | Value;
234
235 const uint64_t BlockBytes = BlockBits / 8;
236 BlockCount = Size / BlockBytes;
237 BytesLeft = Size % BlockBytes;
238 Val = DAG.getConstant(Value, dl, BlockType);
239 }
240
241 SDValue RepStos =
242 emitRepstos(Subtarget, DAG, dl, Chain, Dst, Val,
243 DAG.getIntPtrConstant(BlockCount, dl), BlockType);
244 /// RepStos can process the whole length.
245 if (BytesLeft == 0)
246 return RepStos;
247
248 // Handle the last 1 - 7 bytes.
250 Results.push_back(RepStos);
251 unsigned Offset = Size - BytesLeft;
252 EVT AddrVT = Dst.getValueType();
253
254 Results.push_back(
255 DAG.getMemset(Chain, dl,
256 DAG.getNode(ISD::ADD, dl, AddrVT, Dst,
257 DAG.getConstant(Offset, dl, AddrVT)),
258 OriginalVal, DAG.getConstant(BytesLeft, dl, SizeVT),
259 Alignment, isVolatile, AlwaysInline,
260 /* CI */ nullptr, DstPtrInfo.getWithOffset(Offset)));
261
262 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Results);
263}
264
266 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Val,
267 SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
268 MachinePointerInfo DstPtrInfo) const {
269 // If to a segment-relative address space, use the default lowering.
270 if (DstPtrInfo.getAddrSpace() >= 256)
271 return SDValue();
272
273 // If the base register might conflict with our physical registers, bail out.
274 const MCPhysReg ClobberSet[] = {X86::RCX, X86::RAX, X86::RDI,
275 X86::ECX, X86::EAX, X86::EDI};
276 if (isBaseRegConflictPossible(DAG, ClobberSet))
277 return SDValue();
278
280 if (!ConstantSize)
281 return SDValue();
282
283 const X86Subtarget &Subtarget =
286 DAG, Subtarget, dl, Chain, Dst, Val, ConstantSize->getZExtValue(),
287 Size.getValueType(), Alignment, isVolatile, AlwaysInline, DstPtrInfo);
288}
289
290/// Emit a single REP MOVS{B,W,D,Q} instruction.
291static SDValue emitRepmovs(const X86Subtarget &Subtarget, SelectionDAG &DAG,
292 const SDLoc &dl, SDValue Chain, SDValue Dst,
293 SDValue Src, SDValue Size, MVT AVT) {
294 const bool Use64BitRegs = Subtarget.isTarget64BitLP64();
295 const unsigned CX = Use64BitRegs ? X86::RCX : X86::ECX;
296 const unsigned DI = Use64BitRegs ? X86::RDI : X86::EDI;
297 const unsigned SI = Use64BitRegs ? X86::RSI : X86::ESI;
298
299 SDValue InGlue;
300 Chain = DAG.getCopyToReg(Chain, dl, CX, Size, InGlue);
301 InGlue = Chain.getValue(1);
302 Chain = DAG.getCopyToReg(Chain, dl, DI, Dst, InGlue);
303 InGlue = Chain.getValue(1);
304 Chain = DAG.getCopyToReg(Chain, dl, SI, Src, InGlue);
305 InGlue = Chain.getValue(1);
306
307 SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue);
308 SDValue Ops[] = {Chain, DAG.getValueType(AVT), InGlue};
309 return DAG.getNode(X86ISD::REP_MOVS, dl, Tys, Ops);
310}
311
312/// Emit a single REP MOVSB instruction for a particular constant size.
313static SDValue emitRepmovsB(const X86Subtarget &Subtarget, SelectionDAG &DAG,
314 const SDLoc &dl, SDValue Chain, SDValue Dst,
315 SDValue Src, uint64_t Size) {
316 return emitRepmovs(Subtarget, DAG, dl, Chain, Dst, Src,
317 DAG.getIntPtrConstant(Size, dl), MVT::i8);
318}
319
320/// Returns a REP MOVS instruction, possibly with a few load/stores to implement
321/// a constant size memory copy. In some cases where we know REP MOVS is
322/// inefficient we return an empty SDValue so the calling code can either
323/// generate a load/store sequence or call the runtime memcpy function.
325 SelectionDAG &DAG, const X86Subtarget &Subtarget, const SDLoc &dl,
326 SDValue Chain, SDValue Dst, SDValue Src, uint64_t Size, EVT SizeVT,
327 Align Alignment, bool isVolatile, bool AlwaysInline,
328 MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) {
329 /// In case we optimize for size, we use repmovsb even if it's less efficient
330 /// so we can save the loads/stores of the leftover.
332 return emitRepmovsB(Subtarget, DAG, dl, Chain, Dst, Src, Size);
333
334 /// TODO: Revisit next line: big copy with ERMSB on march >= haswell are very
335 /// efficient.
336 if (!AlwaysInline && Size > Subtarget.getMaxInlineSizeThreshold())
337 return SDValue();
338
339 /// If we have enhanced repmovs we use it.
340 if (Subtarget.hasERMSB())
341 return emitRepmovsB(Subtarget, DAG, dl, Chain, Dst, Src, Size);
342
343 assert(!Subtarget.hasERMSB() && "No efficient RepMovs");
344 /// We assume runtime memcpy will do a better job for unaligned copies when
345 /// ERMS is not present.
346 if (!AlwaysInline && (Alignment < Align(4)))
347 return SDValue();
348
349 const MVT BlockType = getOptimalRepType(Subtarget, Alignment);
350 const uint64_t BlockBytes = BlockType.getSizeInBits() / 8;
351 const uint64_t BlockCount = Size / BlockBytes;
352 const uint64_t BytesLeft = Size % BlockBytes;
353 SDValue RepMovs =
354 emitRepmovs(Subtarget, DAG, dl, Chain, Dst, Src,
355 DAG.getIntPtrConstant(BlockCount, dl), BlockType);
356
357 /// RepMov can process the whole length.
358 if (BytesLeft == 0)
359 return RepMovs;
360
361 assert(BytesLeft && "We have leftover at this point");
362
363 // Handle the last 1 - 7 bytes.
365 Results.push_back(RepMovs);
366 unsigned Offset = Size - BytesLeft;
367 EVT DstVT = Dst.getValueType();
368 EVT SrcVT = Src.getValueType();
369 Results.push_back(DAG.getMemcpy(
370 Chain, dl,
371 DAG.getNode(ISD::ADD, dl, DstVT, Dst, DAG.getConstant(Offset, dl, DstVT)),
372 DAG.getNode(ISD::ADD, dl, SrcVT, Src, DAG.getConstant(Offset, dl, SrcVT)),
373 DAG.getConstant(BytesLeft, dl, SizeVT), Alignment, isVolatile,
374 /*AlwaysInline*/ true, /*CI=*/nullptr, std::nullopt,
375 DstPtrInfo.getWithOffset(Offset), SrcPtrInfo.getWithOffset(Offset)));
376 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Results);
377}
378
380 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
381 SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
382 MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
383 // If to a segment-relative address space, use the default lowering.
384 if (DstPtrInfo.getAddrSpace() >= 256 || SrcPtrInfo.getAddrSpace() >= 256)
385 return SDValue();
386
387 // If the base registers conflict with our physical registers, use the default
388 // lowering.
389 const MCPhysReg ClobberSet[] = {X86::RCX, X86::RSI, X86::RDI,
390 X86::ECX, X86::ESI, X86::EDI};
391 if (isBaseRegConflictPossible(DAG, ClobberSet))
392 return SDValue();
393
394 const X86Subtarget &Subtarget =
396
397 // If enabled and available, use fast short rep mov.
398 if (UseFSRMForMemcpy && Subtarget.hasFSRM())
399 return emitRepmovs(Subtarget, DAG, dl, Chain, Dst, Src, Size, MVT::i8);
400
401 /// Handle constant sizes
402 if (ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size))
403 return emitConstantSizeRepmov(DAG, Subtarget, dl, Chain, Dst, Src,
404 ConstantSize->getZExtValue(),
405 Size.getValueType(), Alignment, isVolatile,
406 AlwaysInline, DstPtrInfo, SrcPtrInfo);
407
408 return SDValue();
409}
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define NODE_NAME_CASE(node)
Function Alias Analysis Results
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Register const TargetRegisterInfo * TRI
This file describes how to lower LLVM code to machine code.
static SDValue emitRepstos(const X86Subtarget &Subtarget, SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Val, SDValue Size, MVT AVT)
Emit a single REP STOSB instruction for a particular constant size.
static SDValue emitRepmovsB(const X86Subtarget &Subtarget, SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src, uint64_t Size)
Emit a single REP MOVSB instruction for a particular constant size.
static SDValue emitRepstosB(const X86Subtarget &Subtarget, SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Val, uint64_t Size)
Emit a single REP STOSB instruction for a particular constant size.
static SDValue emitConstantSizeRepmov(SelectionDAG &DAG, const X86Subtarget &Subtarget, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src, uint64_t Size, EVT SizeVT, Align Alignment, bool isVolatile, bool AlwaysInline, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo)
Returns a REP MOVS instruction, possibly with a few load/stores to implement a constant size memory c...
static MVT getOptimalRepType(const X86Subtarget &Subtarget, Align Alignment)
Returns the best type to use with repmovs/repstos depending on alignment.
static cl::opt< bool > UseFSRMForMemcpy("x86-use-fsrm-for-memcpy", cl::Hidden, cl::init(false), cl::desc("Use fast short rep mov in memcpy lowering"))
static SDValue emitConstantSizeRepstos(SelectionDAG &DAG, const X86Subtarget &Subtarget, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Val, uint64_t Size, EVT SizeVT, Align Alignment, bool isVolatile, bool AlwaysInline, MachinePointerInfo DstPtrInfo)
Returns a REP STOS instruction, possibly with a few load/stores to implement a constant size memory s...
static SDValue emitRepmovs(const X86Subtarget &Subtarget, SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src, SDValue Size, MVT AVT)
Emit a single REP MOVS{B,W,D,Q} instruction.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
uint64_t getZExtValue() const
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Definition Function.h:711
Machine Value Type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
bool hasOpaqueSPAdjustment() const
Returns true if the function contains opaque dynamic stack adjustments.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
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.
SDValue getValue(unsigned R) const
const char * getTargetNodeName(unsigned Opcode) const override
Returns the name of the given target-specific opcode, suitable for debug printing.
SelectionDAGGenTargetInfo(const SDNodeInfo &GenNodeInfo)
bool isTargetMemoryOpcode(unsigned Opcode) const override
Returns true if a node with the given target-specific opcode has a memory operand.
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...
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getMemset(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, MachinePointerInfo DstPtrInfo, const AAMDNodes &AAInfo=AAMDNodes())
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
MachineFunction & getMachineFunction() const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM Value Representation.
Definition Value.h:75
bool isTargetMemoryOpcode(unsigned Opcode) const override
Returns true if a node with the given target-specific opcode has a memory operand.
void verifyTargetNode(const SelectionDAG &DAG, const SDNode *N) const override
Checks that the given target-specific node is valid. Aborts if it is not.
const char * getTargetNodeName(unsigned Opcode) const override
Returns the name of the given target-specific opcode, suitable for debug printing.
SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const override
Emit target-specific code that performs a memcpy.
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.
bool isTarget64BitLP64() const
Is this x86_64 with the LP64 programming model (standard AMD64, no x32)?
unsigned getMaxInlineSizeThreshold() const
Returns the maximum memset / memcpy size that still makes it profitable to inline the call.
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:264
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:53
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:284
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1947
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
Extended Value Type.
Definition ValueTypes.h:35
This class contains a discriminated union of information about pointers in memory operands,...
LLVM_ABI unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
MachinePointerInfo getWithOffset(int64_t O) const
This represents a list of ValueType's that has been intern'd by a SelectionDAG.