LLVM 24.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
30
31const char *X86SelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
32#define NODE_NAME_CASE(NODE) \
33 case X86ISD::NODE: \
34 return "X86ISD::" #NODE;
35
36 // These nodes don't have corresponding entries in *.td files yet.
37 switch (static_cast<X86ISD::NodeType>(Opcode)) {
38 NODE_NAME_CASE(POP_FROM_X87_REG)
39 NODE_NAME_CASE(GlobalBaseReg)
40 NODE_NAME_CASE(LCMPXCHG16_SAVE_RBX_DAG)
41 NODE_NAME_CASE(PCMPESTR)
42 NODE_NAME_CASE(PCMPISTR)
43 NODE_NAME_CASE(MGATHER)
44 NODE_NAME_CASE(MSCATTER)
45 NODE_NAME_CASE(AESENCWIDE128KL)
46 NODE_NAME_CASE(AESDECWIDE128KL)
47 NODE_NAME_CASE(AESENCWIDE256KL)
48 NODE_NAME_CASE(AESDECWIDE256KL)
49 }
50#undef NODE_NAME_CASE
51
53}
54
55bool X86SelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
56 // These nodes don't have corresponding entries in *.td files yet.
57 if (Opcode >= X86ISD::FIRST_MEMORY_OPCODE &&
59 return true;
60
62}
63
65 const SDNode *N) const {
67
68 switch (N->getOpcode()) {
69 default:
70 break;
71 case X86ISD::CALL:
72 case X86ISD::TC_RETURN:
73 case X86ISD::TC_RETURN_GLOBALADDR: {
74 // The call target is an integer whose width depends on both the
75 // subtarget and on how the callee is addressed:
76 // * A direct call to a GlobalAddress/ExternalSymbol is i32 on the
77 // x32 ABI (as well as plain 32-bit mode) and i64 under LP64.
78 // * Anything else (register, folded load, or RIP-relative CFGuard call)
79 // uses the register width the subtarget executes in, i.e. i64 whenever
80 // the subtarget runs in 64-bit mode (including x32) and i32 otherwise.
81 const X86Subtarget &Subtarget =
83 SDValue Target = N->getOperand(1);
84 bool IsDirect =
86 bool WantI64 =
87 IsDirect ? Subtarget.isTarget64BitLP64() : Subtarget.is64Bit();
88 EVT ExpectedVT = WantI64 ? MVT::i64 : MVT::i32;
89 EVT VT = Target.getValueType();
90 if (VT != ExpectedVT)
91 report_fatal_error("invalid node: " + Twine(N->getOperationName(&DAG)) +
92 " operand #1 must have type " +
93 ExpectedVT.getEVTString() + ", but has type " +
94 VT.getEVTString());
95 break;
96 }
97 case X86ISD::SETCC_CARRY: {
98 // SETCC_CARRY materializes CF as 0/-1, so the condition must be COND_B.
99 auto *CC = dyn_cast<ConstantSDNode>(N->getOperand(0));
100 if (!CC || CC->getZExtValue() != X86::COND_B)
101 report_fatal_error("invalid node: " + Twine(N->getOperationName(&DAG)) +
102 " operand #0 must be X86::COND_B");
103 break;
104 }
105 }
106}
107
108/// Returns the best type to use with repmovs/repstos depending on alignment.
109static MVT getOptimalRepType(const X86Subtarget &Subtarget, Align Alignment) {
110 uint64_t Align = Alignment.value();
111 assert((Align != 0) && "Align is normalized");
112 assert(isPowerOf2_64(Align) && "Align is a power of 2");
113 switch (Align) {
114 case 1:
115 return MVT::i8;
116 case 2:
117 return MVT::i16;
118 case 4:
119 return MVT::i32;
120 default:
121 return Subtarget.is64Bit() ? MVT::i64 : MVT::i32;
122 }
123}
124
125bool X86SelectionDAGInfo::isBaseRegConflictPossible(
126 SelectionDAG &DAG, ArrayRef<MCPhysReg> ClobberSet) const {
127 // We cannot use TRI->hasBasePointer() until *after* we select all basic
128 // blocks. Legalization may introduce new stack temporaries with large
129 // alignment requirements. Fall back to generic code if there are any
130 // dynamic stack adjustments (hopefully rare) and the base pointer would
131 // conflict if we had to use it.
132 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
133 if (!MFI.hasVarSizedObjects() && !MFI.hasOpaqueSPAdjustment())
134 return false;
135
136 const X86RegisterInfo *TRI = static_cast<const X86RegisterInfo *>(
137 DAG.getSubtarget().getRegisterInfo());
138 return llvm::is_contained(ClobberSet, TRI->getBaseRegister());
139}
140
141/// Emit a single REP STOSB instruction for a particular constant size.
142static SDValue emitRepstos(const X86Subtarget &Subtarget, SelectionDAG &DAG,
143 const SDLoc &dl, SDValue Chain, SDValue Dst,
144 SDValue Val, SDValue Size, MVT AVT) {
145 const bool Use64BitRegs = Subtarget.isTarget64BitLP64();
146 unsigned AX = X86::AL;
147 switch (AVT.getSizeInBits()) {
148 case 8:
149 AX = X86::AL;
150 break;
151 case 16:
152 AX = X86::AX;
153 break;
154 case 32:
155 AX = X86::EAX;
156 break;
157 default:
158 AX = X86::RAX;
159 break;
160 }
161
162 const unsigned CX = Use64BitRegs ? X86::RCX : X86::ECX;
163 const unsigned DI = Use64BitRegs ? X86::RDI : X86::EDI;
164
165 SDValue InGlue;
166 Chain = DAG.getCopyToReg(Chain, dl, AX, Val, InGlue);
167 InGlue = Chain.getValue(1);
168 Chain = DAG.getCopyToReg(Chain, dl, CX, Size, InGlue);
169 InGlue = Chain.getValue(1);
170 Chain = DAG.getCopyToReg(Chain, dl, DI, Dst, InGlue);
171 InGlue = Chain.getValue(1);
172
173 SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue);
174 SDValue Ops[] = {Chain, DAG.getValueType(AVT), InGlue};
175 return DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops);
176}
177
178/// Emit a single REP STOSB instruction for a particular constant size.
179static SDValue emitRepstosB(const X86Subtarget &Subtarget, SelectionDAG &DAG,
180 const SDLoc &dl, SDValue Chain, SDValue Dst,
181 SDValue Val, uint64_t Size) {
182 return emitRepstos(Subtarget, DAG, dl, Chain, Dst, Val,
183 DAG.getIntPtrConstant(Size, dl), MVT::i8);
184}
185
186/// Returns a REP STOS instruction, possibly with a few load/stores to implement
187/// a constant size memory set. In some cases where we know REP MOVS is
188/// inefficient we return an empty SDValue so the calling code can either
189/// generate a store sequence or call the runtime memset function.
191 const X86Subtarget &Subtarget,
192 const SDLoc &dl, SDValue Chain,
193 SDValue Dst, SDValue Val, uint64_t Size,
194 EVT SizeVT, Align Alignment,
195 bool isVolatile, bool AlwaysInline,
196 MachinePointerInfo DstPtrInfo) {
197 /// In case we optimize for size, we use repstosb even if it's less efficient
198 /// so we can save the loads/stores of the leftover.
200 if (auto *ValC = dyn_cast<ConstantSDNode>(Val)) {
201 // Special case 0 because otherwise we get large literals,
202 // which causes larger encoding.
203 if ((Size & 31) == 0 && (ValC->getZExtValue() & 255) == 0) {
204 MVT BlockType = MVT::i32;
205 const uint64_t BlockBits = BlockType.getSizeInBits();
206 const uint64_t BlockBytes = BlockBits / 8;
207 const uint64_t BlockCount = Size / BlockBytes;
208
209 Val = DAG.getConstant(0, dl, BlockType);
210 // repstosd is same size as repstosb
211 return emitRepstos(Subtarget, DAG, dl, Chain, Dst, Val,
212 DAG.getIntPtrConstant(BlockCount, dl), BlockType);
213 }
214 }
215 return emitRepstosB(Subtarget, DAG, dl, Chain, Dst, Val, Size);
216 }
217
218 if (Size > Subtarget.getMaxInlineSizeThreshold())
219 return SDValue();
220
221 // If not DWORD aligned or size is more than the threshold, call the library.
222 // The libc version is likely to be faster for these cases. It can use the
223 // address value and run time information about the CPU.
224 if (Alignment < Align(4))
225 return SDValue();
226
227 MVT BlockType = MVT::i8;
228 uint64_t BlockCount = Size;
229 uint64_t BytesLeft = 0;
230
231 SDValue OriginalVal = Val;
232 if (auto *ValC = dyn_cast<ConstantSDNode>(Val)) {
233 BlockType = getOptimalRepType(Subtarget, Alignment);
234 uint64_t Value = ValC->getZExtValue() & 255;
235 const uint64_t BlockBits = BlockType.getSizeInBits();
236
237 if (BlockBits >= 16)
238 Value = (Value << 8) | Value;
239
240 if (BlockBits >= 32)
241 Value = (Value << 16) | Value;
242
243 if (BlockBits >= 64)
244 Value = (Value << 32) | Value;
245
246 const uint64_t BlockBytes = BlockBits / 8;
247 BlockCount = Size / BlockBytes;
248 BytesLeft = Size % BlockBytes;
249 Val = DAG.getConstant(Value, dl, BlockType);
250 }
251
252 SDValue RepStos =
253 emitRepstos(Subtarget, DAG, dl, Chain, Dst, Val,
254 DAG.getIntPtrConstant(BlockCount, dl), BlockType);
255 /// RepStos can process the whole length.
256 if (BytesLeft == 0)
257 return RepStos;
258
259 // Handle the last 1 - 7 bytes.
261 Results.push_back(RepStos);
262 unsigned Offset = Size - BytesLeft;
263 EVT AddrVT = Dst.getValueType();
264
265 Results.push_back(
266 DAG.getMemset(Chain, dl,
267 DAG.getNode(ISD::ADD, dl, AddrVT, Dst,
268 DAG.getConstant(Offset, dl, AddrVT)),
269 OriginalVal, DAG.getConstant(BytesLeft, dl, SizeVT),
270 Alignment, isVolatile, AlwaysInline,
271 /* CI */ nullptr, DstPtrInfo.getWithOffset(Offset)));
272
273 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Results);
274}
275
277 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Val,
278 SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
279 MachinePointerInfo DstPtrInfo) const {
280 const X86Subtarget &Subtarget =
282
283 // If to a segment-relative address space, use the default lowering.
284 if (DstPtrInfo.getAddrSpace() >= 256)
285 return SDValue();
286
287 // REP STOS uses EDI on x86-32. Fall back if the user reserved EDI, so the
288 // generic expander can avoid emitting REP STOS.
289 if (!Subtarget.is64Bit() && Subtarget.isRegisterReservedByUser(X86::EDI))
290 return SDValue();
291
292 // If the base register might conflict with our physical registers, bail out.
293 const MCPhysReg ClobberSet[] = {X86::RCX, X86::RAX, X86::RDI,
294 X86::ECX, X86::EAX, X86::EDI};
295 if (isBaseRegConflictPossible(DAG, ClobberSet))
296 return SDValue();
297
299 if (!ConstantSize)
300 return SDValue();
301
303 DAG, Subtarget, dl, Chain, Dst, Val, ConstantSize->getZExtValue(),
304 Size.getValueType(), Alignment, isVolatile, AlwaysInline, DstPtrInfo);
305}
306
307/// Emit a single REP MOVS{B,W,D,Q} instruction.
308static SDValue emitRepmovs(const X86Subtarget &Subtarget, SelectionDAG &DAG,
309 const SDLoc &dl, SDValue Chain, SDValue Dst,
310 SDValue Src, SDValue Size, MVT AVT) {
311 const bool Use64BitRegs = Subtarget.isTarget64BitLP64();
312 const unsigned CX = Use64BitRegs ? X86::RCX : X86::ECX;
313 const unsigned DI = Use64BitRegs ? X86::RDI : X86::EDI;
314 const unsigned SI = Use64BitRegs ? X86::RSI : X86::ESI;
315
316 SDValue InGlue;
317 Chain = DAG.getCopyToReg(Chain, dl, CX, Size, InGlue);
318 InGlue = Chain.getValue(1);
319 Chain = DAG.getCopyToReg(Chain, dl, DI, Dst, InGlue);
320 InGlue = Chain.getValue(1);
321 Chain = DAG.getCopyToReg(Chain, dl, SI, Src, InGlue);
322 InGlue = Chain.getValue(1);
323
324 SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue);
325 SDValue Ops[] = {Chain, DAG.getValueType(AVT), InGlue};
326 return DAG.getNode(X86ISD::REP_MOVS, dl, Tys, Ops);
327}
328
329/// Emit a single REP MOVSB instruction for a particular constant size.
330static SDValue emitRepmovsB(const X86Subtarget &Subtarget, SelectionDAG &DAG,
331 const SDLoc &dl, SDValue Chain, SDValue Dst,
332 SDValue Src, uint64_t Size) {
333 return emitRepmovs(Subtarget, DAG, dl, Chain, Dst, Src,
334 DAG.getIntPtrConstant(Size, dl), MVT::i8);
335}
336
337/// Returns a REP MOVS instruction, possibly with a few load/stores to implement
338/// a constant size memory copy. In some cases where we know REP MOVS is
339/// inefficient we return an empty SDValue so the calling code can either
340/// generate a load/store sequence or call the runtime memcpy function.
342 SelectionDAG &DAG, const X86Subtarget &Subtarget, const SDLoc &dl,
343 SDValue Chain, SDValue Dst, SDValue Src, uint64_t Size, EVT SizeVT,
344 Align Alignment, bool isVolatile, bool AlwaysInline,
345 MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) {
346 /// In case we optimize for size, we use repmovsb even if it's less efficient
347 /// so we can save the loads/stores of the leftover.
349 return emitRepmovsB(Subtarget, DAG, dl, Chain, Dst, Src, Size);
350
351 /// TODO: Revisit next line: big copy with ERMSB on march >= haswell are very
352 /// efficient.
353 if (!AlwaysInline && Size > Subtarget.getMaxInlineSizeThreshold())
354 return SDValue();
355
356 /// If we have enhanced repmovs we use it.
357 if (Subtarget.hasERMSB())
358 return emitRepmovsB(Subtarget, DAG, dl, Chain, Dst, Src, Size);
359
360 assert(!Subtarget.hasERMSB() && "No efficient RepMovs");
361 /// We assume runtime memcpy will do a better job for unaligned copies when
362 /// ERMS is not present.
363 if (!AlwaysInline && (Alignment < Align(4)))
364 return SDValue();
365
366 const MVT BlockType = getOptimalRepType(Subtarget, Alignment);
367 const uint64_t BlockBytes = BlockType.getSizeInBits() / 8;
368 const uint64_t BlockCount = Size / BlockBytes;
369 const uint64_t BytesLeft = Size % BlockBytes;
370 SDValue RepMovs =
371 emitRepmovs(Subtarget, DAG, dl, Chain, Dst, Src,
372 DAG.getIntPtrConstant(BlockCount, dl), BlockType);
373
374 /// RepMov can process the whole length.
375 if (BytesLeft == 0)
376 return RepMovs;
377
378 assert(BytesLeft && "We have leftover at this point");
379
380 // Handle the last 1 - 7 bytes.
382 Results.push_back(RepMovs);
383 unsigned Offset = Size - BytesLeft;
384 EVT DstVT = Dst.getValueType();
385 EVT SrcVT = Src.getValueType();
386 Results.push_back(DAG.getMemcpy(
387 Chain, dl,
388 DAG.getNode(ISD::ADD, dl, DstVT, Dst, DAG.getConstant(Offset, dl, DstVT)),
389 DAG.getNode(ISD::ADD, dl, SrcVT, Src, DAG.getConstant(Offset, dl, SrcVT)),
390 DAG.getConstant(BytesLeft, dl, SizeVT), Alignment, Alignment, isVolatile,
391 /*AlwaysInline*/ true, /*CI=*/nullptr, std::nullopt,
392 DstPtrInfo.getWithOffset(Offset), SrcPtrInfo.getWithOffset(Offset)));
393 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Results);
394}
395
397 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
398 SDValue Size, Align DstAlign, Align SrcAlign, bool isVolatile,
399 bool AlwaysInline, MachinePointerInfo DstPtrInfo,
400 MachinePointerInfo SrcPtrInfo) const {
401 const X86Subtarget &Subtarget =
403
404 // If to a segment-relative address space, use the default lowering.
405 if (DstPtrInfo.getAddrSpace() >= 256 || SrcPtrInfo.getAddrSpace() >= 256)
406 return SDValue();
407
408 // REP MOVS uses EDI/ESI on x86-32. fall back only when EDI is
409 // reserved so the generic expander can avoid emitting REP MOVS.
410 if (!Subtarget.is64Bit() && Subtarget.isRegisterReservedByUser(X86::EDI))
411 return SDValue();
412
413 // If the base registers conflict with our physical registers, use the default
414 // lowering.
415 const MCPhysReg ClobberSet[] = {X86::RCX, X86::RSI, X86::RDI,
416 X86::ECX, X86::ESI, X86::EDI};
417 if (isBaseRegConflictPossible(DAG, ClobberSet))
418 return SDValue();
419
420 // If enabled and available, use fast short rep mov.
421 if (Subtarget.getCLOpts().use_fsrm_for_memcpy && Subtarget.hasFSRM())
422 return emitRepmovs(Subtarget, DAG, dl, Chain, Dst, Src, Size, MVT::i8);
423
424 // Handle constant sizes
425 if (ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size)) {
426 Align Alignment = std::min(DstAlign, SrcAlign);
427 return emitConstantSizeRepmov(DAG, Subtarget, dl, Chain, Dst, Src,
428 ConstantSize->getZExtValue(),
429 Size.getValueType(), Alignment, isVolatile,
430 AlwaysInline, DstPtrInfo, SrcPtrInfo);
431 }
432
433 return SDValue();
434}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
#define NODE_NAME_CASE(node)
Function Alias Analysis Results
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Register const TargetRegisterInfo * TRI
RISCVCC::CondCode CC
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 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.
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:696
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 DstAlign, Align SrcAlign, 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.
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
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 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 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.
bool isTarget64BitLP64() const
Is this x86_64 with the LP64 programming model (standard AMD64, no x32)?
bool isRegisterReservedByUser(Register i) const override
unsigned getMaxInlineSizeThreshold() const
Returns the maximum memset / memcpy size that still makes it profitable to inline the call.
const X86Options & getCLOpts() const
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:266
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:55
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
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:285
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
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...
Definition Casting.h:547
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:1963
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Extended Value Type.
Definition ValueTypes.h:35
std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
Definition ValueTypes.h:524
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.