25#define DEBUG_TYPE "x86-selectiondag-info"
29 cl::desc(
"Use fast short rep mov in memcpy lowering"));
31bool X86SelectionDAGInfo::isBaseRegConflictPossible(
56 const MCPhysReg ClobberSet[] = {X86::RCX, X86::RAX, X86::RDI,
57 X86::ECX, X86::EAX, X86::EDI};
58 if (isBaseRegConflictPossible(DAG, ClobberSet))
68 if (Alignment <
Align(4) || !ConstantSize ||
76 unsigned BytesLeft = 0;
77 if (
auto *ValC = dyn_cast<ConstantSDNode>(Val)) {
79 uint64_t Val = ValC->getZExtValue() & 255;
82 if (Alignment >=
Align(4)) {
86 Val = (Val << 8) | Val;
87 Val = (Val << 16) | Val;
88 if (Subtarget.is64Bit() && Alignment >=
Align(8)) {
91 Val = (Val << 32) | Val;
93 }
else if (Alignment ==
Align(2)) {
97 Val = (Val << 8) | Val;
105 if (AVT.
bitsGT(MVT::i8)) {
108 BytesLeft = SizeVal % UBytes;
117 Chain = DAG.
getCopyToReg(Chain, dl, X86::AL, Val, InGlue);
122 Chain = DAG.
getCopyToReg(Chain, dl, Use64BitRegs ? X86::RCX : X86::ECX,
125 Chain = DAG.
getCopyToReg(Chain, dl, Use64BitRegs ? X86::RDI : X86::EDI,
140 unsigned Offset = SizeVal - BytesLeft;
141 EVT AddrVT = Dst.getValueType();
142 EVT SizeVT =
Size.getValueType();
148 Val, DAG.
getConstant(BytesLeft, dl, SizeVT), Alignment,
149 isVolatile, AlwaysInline,
160 const unsigned CX = Use64BitRegs ? X86::RCX : X86::ECX;
161 const unsigned DI = Use64BitRegs ? X86::RDI : X86::EDI;
162 const unsigned SI = Use64BitRegs ? X86::RSI : X86::ESI;
181 return emitRepmovs(Subtarget, DAG, dl, Chain, Dst, Src,
199 return Subtarget.is64Bit() ? MVT::i64 : MVT::i32;
210 Align Alignment,
bool isVolatile,
bool AlwaysInline,
219 if (Subtarget.hasERMSB())
222 assert(!Subtarget.hasERMSB() &&
"No efficient RepMovs");
225 if (!AlwaysInline && (Alignment.
value() & 3) != 0)
229 const uint64_t BlockBytes = BlockType.getSizeInBits() / 8;
240 assert(BytesLeft &&
"We have leftover at this point");
251 EVT DstVT = Dst.getValueType();
252 EVT SrcVT = Src.getValueType();
257 DAG.
getConstant(BytesLeft, dl, SizeVT), Alignment, isVolatile,
258 true,
nullptr, std::nullopt,
273 const MCPhysReg ClobberSet[] = {X86::RCX, X86::RSI, X86::RDI,
274 X86::ECX, X86::ESI, X86::EDI};
275 if (isBaseRegConflictPossible(DAG, ClobberSet))
283 return emitRepmovs(Subtarget, DAG, dl, Chain, Dst, Src,
Size, MVT::i8);
288 ConstantSize->getZExtValue(),
289 Size.getValueType(), Alignment, isVolatile,
290 AlwaysInline, DstPtrInfo, SrcPtrInfo);
Function Alias Analysis Results
unsigned const TargetRegisterInfo * TRI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file describes how to lower LLVM code to machine code.
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 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 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 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.
static MVT getOptimalRepmovsType(const X86Subtarget &Subtarget, Align Alignment)
Returns the best type to use with repmovs depending on alignment.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
uint64_t getZExtValue() const
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
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...
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDValue getValue(unsigned R) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
const TargetSubtargetInfo & getSubtarget() const
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
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(), AAResults *AA=nullptr)
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())
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
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.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
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.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ REP_MOVS
Repeat move, corresponds to X86::REP_MOVSx.
@ REP_STOS
Repeat fill, corresponds to X86::REP_STOSx.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
This class contains a discriminated union of information about pointers in memory operands,...
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.