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 return;
90 }
91
93}
94
95/// Returns the best type to use with repmovs/repstos depending on alignment.
96static MVT getOptimalRepType(const X86Subtarget &Subtarget, Align Alignment) {
97 uint64_t Align = Alignment.value();
98 assert((Align != 0) && "Align is normalized");
99 assert(isPowerOf2_64(Align) && "Align is a power of 2");
100 switch (Align) {
101 case 1:
102 return MVT::i8;
103 case 2:
104 return MVT::i16;
105 case 4:
106 return MVT::i32;
107 default:
108 return Subtarget.is64Bit() ? MVT::i64 : MVT::i32;
109 }
110}
111
112bool X86SelectionDAGInfo::isBaseRegConflictPossible(
113 SelectionDAG &DAG, ArrayRef<MCPhysReg> ClobberSet) const {
114 // We cannot use TRI->hasBasePointer() until *after* we select all basic
115 // blocks. Legalization may introduce new stack temporaries with large
116 // alignment requirements. Fall back to generic code if there are any
117 // dynamic stack adjustments (hopefully rare) and the base pointer would
118 // conflict if we had to use it.
119 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
120 if (!MFI.hasVarSizedObjects() && !MFI.hasOpaqueSPAdjustment())
121 return false;
122
123 const X86RegisterInfo *TRI = static_cast<const X86RegisterInfo *>(
124 DAG.getSubtarget().getRegisterInfo());
125 return llvm::is_contained(ClobberSet, TRI->getBaseRegister());
126}
127
128/// Emit a single REP STOSB instruction for a particular constant size.
129static SDValue emitRepstos(const X86Subtarget &Subtarget, SelectionDAG &DAG,
130 const SDLoc &dl, SDValue Chain, SDValue Dst,
131 SDValue Val, SDValue Size, MVT AVT) {
132 const bool Use64BitRegs = Subtarget.isTarget64BitLP64();
133 unsigned AX = X86::AL;
134 switch (AVT.getSizeInBits()) {
135 case 8:
136 AX = X86::AL;
137 break;
138 case 16:
139 AX = X86::AX;
140 break;
141 case 32:
142 AX = X86::EAX;
143 break;
144 default:
145 AX = X86::RAX;
146 break;
147 }
148
149 const unsigned CX = Use64BitRegs ? X86::RCX : X86::ECX;
150 const unsigned DI = Use64BitRegs ? X86::RDI : X86::EDI;
151
152 SDValue InGlue;
153 Chain = DAG.getCopyToReg(Chain, dl, AX, Val, InGlue);
154 InGlue = Chain.getValue(1);
155 Chain = DAG.getCopyToReg(Chain, dl, CX, Size, InGlue);
156 InGlue = Chain.getValue(1);
157 Chain = DAG.getCopyToReg(Chain, dl, DI, Dst, InGlue);
158 InGlue = Chain.getValue(1);
159
160 SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue);
161 SDValue Ops[] = {Chain, DAG.getValueType(AVT), InGlue};
162 return DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops);
163}
164
165/// Emit a single REP STOSB instruction for a particular constant size.
166static SDValue emitRepstosB(const X86Subtarget &Subtarget, SelectionDAG &DAG,
167 const SDLoc &dl, SDValue Chain, SDValue Dst,
168 SDValue Val, uint64_t Size) {
169 return emitRepstos(Subtarget, DAG, dl, Chain, Dst, Val,
170 DAG.getIntPtrConstant(Size, dl), MVT::i8);
171}
172
173/// Returns a REP STOS instruction, possibly with a few load/stores to implement
174/// a constant size memory set. In some cases where we know REP MOVS is
175/// inefficient we return an empty SDValue so the calling code can either
176/// generate a store sequence or call the runtime memset function.
178 const X86Subtarget &Subtarget,
179 const SDLoc &dl, SDValue Chain,
180 SDValue Dst, SDValue Val, uint64_t Size,
181 EVT SizeVT, Align Alignment,
182 bool isVolatile, bool AlwaysInline,
183 MachinePointerInfo DstPtrInfo) {
184 /// In case we optimize for size, we use repstosb even if it's less efficient
185 /// so we can save the loads/stores of the leftover.
187 if (auto *ValC = dyn_cast<ConstantSDNode>(Val)) {
188 // Special case 0 because otherwise we get large literals,
189 // which causes larger encoding.
190 if ((Size & 31) == 0 && (ValC->getZExtValue() & 255) == 0) {
191 MVT BlockType = MVT::i32;
192 const uint64_t BlockBits = BlockType.getSizeInBits();
193 const uint64_t BlockBytes = BlockBits / 8;
194 const uint64_t BlockCount = Size / BlockBytes;
195
196 Val = DAG.getConstant(0, dl, BlockType);
197 // repstosd is same size as repstosb
198 return emitRepstos(Subtarget, DAG, dl, Chain, Dst, Val,
199 DAG.getIntPtrConstant(BlockCount, dl), BlockType);
200 }
201 }
202 return emitRepstosB(Subtarget, DAG, dl, Chain, Dst, Val, Size);
203 }
204
205 if (Size > Subtarget.getMaxInlineSizeThreshold())
206 return SDValue();
207
208 // If not DWORD aligned or size is more than the threshold, call the library.
209 // The libc version is likely to be faster for these cases. It can use the
210 // address value and run time information about the CPU.
211 if (Alignment < Align(4))
212 return SDValue();
213
214 MVT BlockType = MVT::i8;
215 uint64_t BlockCount = Size;
216 uint64_t BytesLeft = 0;
217
218 SDValue OriginalVal = Val;
219 if (auto *ValC = dyn_cast<ConstantSDNode>(Val)) {
220 BlockType = getOptimalRepType(Subtarget, Alignment);
221 uint64_t Value = ValC->getZExtValue() & 255;
222 const uint64_t BlockBits = BlockType.getSizeInBits();
223
224 if (BlockBits >= 16)
225 Value = (Value << 8) | Value;
226
227 if (BlockBits >= 32)
228 Value = (Value << 16) | Value;
229
230 if (BlockBits >= 64)
231 Value = (Value << 32) | Value;
232
233 const uint64_t BlockBytes = BlockBits / 8;
234 BlockCount = Size / BlockBytes;
235 BytesLeft = Size % BlockBytes;
236 Val = DAG.getConstant(Value, dl, BlockType);
237 }
238
239 SDValue RepStos =
240 emitRepstos(Subtarget, DAG, dl, Chain, Dst, Val,
241 DAG.getIntPtrConstant(BlockCount, dl), BlockType);
242 /// RepStos can process the whole length.
243 if (BytesLeft == 0)
244 return RepStos;
245
246 // Handle the last 1 - 7 bytes.
248 Results.push_back(RepStos);
249 unsigned Offset = Size - BytesLeft;
250 EVT AddrVT = Dst.getValueType();
251
252 Results.push_back(
253 DAG.getMemset(Chain, dl,
254 DAG.getNode(ISD::ADD, dl, AddrVT, Dst,
255 DAG.getConstant(Offset, dl, AddrVT)),
256 OriginalVal, DAG.getConstant(BytesLeft, dl, SizeVT),
257 Alignment, isVolatile, AlwaysInline,
258 /* CI */ nullptr, DstPtrInfo.getWithOffset(Offset)));
259
260 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Results);
261}
262
264 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Val,
265 SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
266 MachinePointerInfo DstPtrInfo) const {
267 // If to a segment-relative address space, use the default lowering.
268 if (DstPtrInfo.getAddrSpace() >= 256)
269 return SDValue();
270
271 // If the base register might conflict with our physical registers, bail out.
272 const MCPhysReg ClobberSet[] = {X86::RCX, X86::RAX, X86::RDI,
273 X86::ECX, X86::EAX, X86::EDI};
274 if (isBaseRegConflictPossible(DAG, ClobberSet))
275 return SDValue();
276
278 if (!ConstantSize)
279 return SDValue();
280
281 const X86Subtarget &Subtarget =
284 DAG, Subtarget, dl, Chain, Dst, Val, ConstantSize->getZExtValue(),
285 Size.getValueType(), Alignment, isVolatile, AlwaysInline, DstPtrInfo);
286}
287
288/// Emit a single REP MOVS{B,W,D,Q} instruction.
289static SDValue emitRepmovs(const X86Subtarget &Subtarget, SelectionDAG &DAG,
290 const SDLoc &dl, SDValue Chain, SDValue Dst,
291 SDValue Src, SDValue Size, MVT AVT) {
292 const bool Use64BitRegs = Subtarget.isTarget64BitLP64();
293 const unsigned CX = Use64BitRegs ? X86::RCX : X86::ECX;
294 const unsigned DI = Use64BitRegs ? X86::RDI : X86::EDI;
295 const unsigned SI = Use64BitRegs ? X86::RSI : X86::ESI;
296
297 SDValue InGlue;
298 Chain = DAG.getCopyToReg(Chain, dl, CX, Size, InGlue);
299 InGlue = Chain.getValue(1);
300 Chain = DAG.getCopyToReg(Chain, dl, DI, Dst, InGlue);
301 InGlue = Chain.getValue(1);
302 Chain = DAG.getCopyToReg(Chain, dl, SI, Src, InGlue);
303 InGlue = Chain.getValue(1);
304
305 SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue);
306 SDValue Ops[] = {Chain, DAG.getValueType(AVT), InGlue};
307 return DAG.getNode(X86ISD::REP_MOVS, dl, Tys, Ops);
308}
309
310/// Emit a single REP MOVSB instruction for a particular constant size.
311static SDValue emitRepmovsB(const X86Subtarget &Subtarget, SelectionDAG &DAG,
312 const SDLoc &dl, SDValue Chain, SDValue Dst,
313 SDValue Src, uint64_t Size) {
314 return emitRepmovs(Subtarget, DAG, dl, Chain, Dst, Src,
315 DAG.getIntPtrConstant(Size, dl), MVT::i8);
316}
317
318/// Returns a REP MOVS instruction, possibly with a few load/stores to implement
319/// a constant size memory copy. In some cases where we know REP MOVS is
320/// inefficient we return an empty SDValue so the calling code can either
321/// generate a load/store sequence or call the runtime memcpy function.
323 SelectionDAG &DAG, const X86Subtarget &Subtarget, const SDLoc &dl,
324 SDValue Chain, SDValue Dst, SDValue Src, uint64_t Size, EVT SizeVT,
325 Align Alignment, bool isVolatile, bool AlwaysInline,
326 MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) {
327 /// In case we optimize for size, we use repmovsb even if it's less efficient
328 /// so we can save the loads/stores of the leftover.
330 return emitRepmovsB(Subtarget, DAG, dl, Chain, Dst, Src, Size);
331
332 /// TODO: Revisit next line: big copy with ERMSB on march >= haswell are very
333 /// efficient.
334 if (!AlwaysInline && Size > Subtarget.getMaxInlineSizeThreshold())
335 return SDValue();
336
337 /// If we have enhanced repmovs we use it.
338 if (Subtarget.hasERMSB())
339 return emitRepmovsB(Subtarget, DAG, dl, Chain, Dst, Src, Size);
340
341 assert(!Subtarget.hasERMSB() && "No efficient RepMovs");
342 /// We assume runtime memcpy will do a better job for unaligned copies when
343 /// ERMS is not present.
344 if (!AlwaysInline && (Alignment < Align(4)))
345 return SDValue();
346
347 const MVT BlockType = getOptimalRepType(Subtarget, Alignment);
348 const uint64_t BlockBytes = BlockType.getSizeInBits() / 8;
349 const uint64_t BlockCount = Size / BlockBytes;
350 const uint64_t BytesLeft = Size % BlockBytes;
351 SDValue RepMovs =
352 emitRepmovs(Subtarget, DAG, dl, Chain, Dst, Src,
353 DAG.getIntPtrConstant(BlockCount, dl), BlockType);
354
355 /// RepMov can process the whole length.
356 if (BytesLeft == 0)
357 return RepMovs;
358
359 assert(BytesLeft && "We have leftover at this point");
360
361 // Handle the last 1 - 7 bytes.
363 Results.push_back(RepMovs);
364 unsigned Offset = Size - BytesLeft;
365 EVT DstVT = Dst.getValueType();
366 EVT SrcVT = Src.getValueType();
367 Results.push_back(DAG.getMemcpy(
368 Chain, dl,
369 DAG.getNode(ISD::ADD, dl, DstVT, Dst, DAG.getConstant(Offset, dl, DstVT)),
370 DAG.getNode(ISD::ADD, dl, SrcVT, Src, DAG.getConstant(Offset, dl, SrcVT)),
371 DAG.getConstant(BytesLeft, dl, SizeVT), Alignment, isVolatile,
372 /*AlwaysInline*/ true, /*CI=*/nullptr, std::nullopt,
373 DstPtrInfo.getWithOffset(Offset), SrcPtrInfo.getWithOffset(Offset)));
374 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Results);
375}
376
378 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
379 SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
380 MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
381 // If to a segment-relative address space, use the default lowering.
382 if (DstPtrInfo.getAddrSpace() >= 256 || SrcPtrInfo.getAddrSpace() >= 256)
383 return SDValue();
384
385 // If the base registers conflict with our physical registers, use the default
386 // lowering.
387 const MCPhysReg ClobberSet[] = {X86::RCX, X86::RSI, X86::RDI,
388 X86::ECX, X86::ESI, X86::EDI};
389 if (isBaseRegConflictPossible(DAG, ClobberSet))
390 return SDValue();
391
392 const X86Subtarget &Subtarget =
394
395 // If enabled and available, use fast short rep mov.
396 if (UseFSRMForMemcpy && Subtarget.hasFSRM())
397 return emitRepmovs(Subtarget, DAG, dl, Chain, Dst, Src, Size, MVT::i8);
398
399 /// Handle constant sizes
400 if (ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size))
401 return emitConstantSizeRepmov(DAG, Subtarget, dl, Chain, Dst, Src,
402 ConstantSize->getZExtValue(),
403 Size.getValueType(), Alignment, isVolatile,
404 AlwaysInline, DstPtrInfo, SrcPtrInfo);
405
406 return SDValue();
407}
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.