LLVM  4.0.0
X86SelectionDAGInfo.cpp
Go to the documentation of this file.
1 //===-- X86SelectionDAGInfo.cpp - X86 SelectionDAG Info -------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the X86SelectionDAGInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "X86InstrInfo.h"
15 #include "X86ISelLowering.h"
16 #include "X86RegisterInfo.h"
17 #include "X86Subtarget.h"
18 #include "X86SelectionDAGInfo.h"
20 #include "llvm/IR/DerivedTypes.h"
22 
23 using namespace llvm;
24 
25 #define DEBUG_TYPE "x86-selectiondag-info"
26 
27 bool X86SelectionDAGInfo::isBaseRegConflictPossible(
28  SelectionDAG &DAG, ArrayRef<MCPhysReg> ClobberSet) const {
29  // We cannot use TRI->hasBasePointer() until *after* we select all basic
30  // blocks. Legalization may introduce new stack temporaries with large
31  // alignment requirements. Fall back to generic code if there are any
32  // dynamic stack adjustments (hopefully rare) and the base pointer would
33  // conflict if we had to use it.
35  if (!MFI.hasVarSizedObjects() && !MFI.hasOpaqueSPAdjustment())
36  return false;
37 
38  const X86RegisterInfo *TRI = static_cast<const X86RegisterInfo *>(
40  unsigned BaseReg = TRI->getBaseRegister();
41  for (unsigned R : ClobberSet)
42  if (BaseReg == R)
43  return true;
44  return false;
45 }
46 
48  SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
49  SDValue Size, unsigned Align, bool isVolatile,
50  MachinePointerInfo DstPtrInfo) const {
51  ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
52  const X86Subtarget &Subtarget =
54 
55 #ifndef NDEBUG
56  // If the base register might conflict with our physical registers, bail out.
57  const MCPhysReg ClobberSet[] = {X86::RCX, X86::RAX, X86::RDI,
58  X86::ECX, X86::EAX, X86::EDI};
59  assert(!isBaseRegConflictPossible(DAG, ClobberSet));
60 #endif
61 
62  // If to a segment-relative address space, use the default lowering.
63  if (DstPtrInfo.getAddrSpace() >= 256)
64  return SDValue();
65 
66  // If not DWORD aligned or size is more than the threshold, call the library.
67  // The libc version is likely to be faster for these cases. It can use the
68  // address value and run time information about the CPU.
69  if ((Align & 3) != 0 || !ConstantSize ||
70  ConstantSize->getZExtValue() > Subtarget.getMaxInlineSizeThreshold()) {
71  // Check to see if there is a specialized entry-point for memory zeroing.
73 
74  if (const char *bzeroEntry = V &&
75  V->isNullValue() ? Subtarget.getBZeroEntry() : nullptr) {
76  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
77  EVT IntPtr = TLI.getPointerTy(DAG.getDataLayout());
78  Type *IntPtrTy = DAG.getDataLayout().getIntPtrType(*DAG.getContext());
81  Entry.Node = Dst;
82  Entry.Ty = IntPtrTy;
83  Args.push_back(Entry);
84  Entry.Node = Size;
85  Args.push_back(Entry);
86 
88  CLI.setDebugLoc(dl).setChain(Chain)
90  DAG.getExternalSymbol(bzeroEntry, IntPtr), std::move(Args))
91  .setDiscardResult();
92 
93  std::pair<SDValue,SDValue> CallResult = TLI.LowerCallTo(CLI);
94  return CallResult.second;
95  }
96 
97  // Otherwise have the target-independent code call memset.
98  return SDValue();
99  }
100 
101  uint64_t SizeVal = ConstantSize->getZExtValue();
102  SDValue InFlag;
103  EVT AVT;
104  SDValue Count;
105  ConstantSDNode *ValC = dyn_cast<ConstantSDNode>(Src);
106  unsigned BytesLeft = 0;
107  bool TwoRepStos = false;
108  if (ValC) {
109  unsigned ValReg;
110  uint64_t Val = ValC->getZExtValue() & 255;
111 
112  // If the value is a constant, then we can potentially use larger sets.
113  switch (Align & 3) {
114  case 2: // WORD aligned
115  AVT = MVT::i16;
116  ValReg = X86::AX;
117  Val = (Val << 8) | Val;
118  break;
119  case 0: // DWORD aligned
120  AVT = MVT::i32;
121  ValReg = X86::EAX;
122  Val = (Val << 8) | Val;
123  Val = (Val << 16) | Val;
124  if (Subtarget.is64Bit() && ((Align & 0x7) == 0)) { // QWORD aligned
125  AVT = MVT::i64;
126  ValReg = X86::RAX;
127  Val = (Val << 32) | Val;
128  }
129  break;
130  default: // Byte aligned
131  AVT = MVT::i8;
132  ValReg = X86::AL;
133  Count = DAG.getIntPtrConstant(SizeVal, dl);
134  break;
135  }
136 
137  if (AVT.bitsGT(MVT::i8)) {
138  unsigned UBytes = AVT.getSizeInBits() / 8;
139  Count = DAG.getIntPtrConstant(SizeVal / UBytes, dl);
140  BytesLeft = SizeVal % UBytes;
141  }
142 
143  Chain = DAG.getCopyToReg(Chain, dl, ValReg, DAG.getConstant(Val, dl, AVT),
144  InFlag);
145  InFlag = Chain.getValue(1);
146  } else {
147  AVT = MVT::i8;
148  Count = DAG.getIntPtrConstant(SizeVal, dl);
149  Chain = DAG.getCopyToReg(Chain, dl, X86::AL, Src, InFlag);
150  InFlag = Chain.getValue(1);
151  }
152 
153  Chain = DAG.getCopyToReg(Chain, dl, Subtarget.is64Bit() ? X86::RCX : X86::ECX,
154  Count, InFlag);
155  InFlag = Chain.getValue(1);
156  Chain = DAG.getCopyToReg(Chain, dl, Subtarget.is64Bit() ? X86::RDI : X86::EDI,
157  Dst, InFlag);
158  InFlag = Chain.getValue(1);
159 
161  SDValue Ops[] = { Chain, DAG.getValueType(AVT), InFlag };
162  Chain = DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops);
163 
164  if (TwoRepStos) {
165  InFlag = Chain.getValue(1);
166  Count = Size;
167  EVT CVT = Count.getValueType();
168  SDValue Left = DAG.getNode(ISD::AND, dl, CVT, Count,
169  DAG.getConstant((AVT == MVT::i64) ? 7 : 3, dl,
170  CVT));
171  Chain = DAG.getCopyToReg(Chain, dl, (CVT == MVT::i64) ? X86::RCX : X86::ECX,
172  Left, InFlag);
173  InFlag = Chain.getValue(1);
174  Tys = DAG.getVTList(MVT::Other, MVT::Glue);
175  SDValue Ops[] = { Chain, DAG.getValueType(MVT::i8), InFlag };
176  Chain = DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops);
177  } else if (BytesLeft) {
178  // Handle the last 1 - 7 bytes.
179  unsigned Offset = SizeVal - BytesLeft;
180  EVT AddrVT = Dst.getValueType();
181  EVT SizeVT = Size.getValueType();
182 
183  Chain = DAG.getMemset(Chain, dl,
184  DAG.getNode(ISD::ADD, dl, AddrVT, Dst,
185  DAG.getConstant(Offset, dl, AddrVT)),
186  Src,
187  DAG.getConstant(BytesLeft, dl, SizeVT),
188  Align, isVolatile, false,
189  DstPtrInfo.getWithOffset(Offset));
190  }
191 
192  // TODO: Use a Tokenfactor, as in memcpy, instead of a single chain.
193  return Chain;
194 }
195 
197  SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
198  SDValue Size, unsigned Align, bool isVolatile, bool AlwaysInline,
199  MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
200  // This requires the copy size to be a constant, preferably
201  // within a subtarget-specific limit.
202  ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
203  const X86Subtarget &Subtarget =
205  if (!ConstantSize)
206  return SDValue();
207  uint64_t SizeVal = ConstantSize->getZExtValue();
208  if (!AlwaysInline && SizeVal > Subtarget.getMaxInlineSizeThreshold())
209  return SDValue();
210 
211  /// If not DWORD aligned, it is more efficient to call the library. However
212  /// if calling the library is not allowed (AlwaysInline), then soldier on as
213  /// the code generated here is better than the long load-store sequence we
214  /// would otherwise get.
215  if (!AlwaysInline && (Align & 3) != 0)
216  return SDValue();
217 
218  // If to a segment-relative address space, use the default lowering.
219  if (DstPtrInfo.getAddrSpace() >= 256 ||
220  SrcPtrInfo.getAddrSpace() >= 256)
221  return SDValue();
222 
223  // If the base register might conflict with our physical registers, bail out.
224  const MCPhysReg ClobberSet[] = {X86::RCX, X86::RSI, X86::RDI,
225  X86::ECX, X86::ESI, X86::EDI};
226  if (isBaseRegConflictPossible(DAG, ClobberSet))
227  return SDValue();
228 
229  MVT AVT;
230  if (Align & 1)
231  AVT = MVT::i8;
232  else if (Align & 2)
233  AVT = MVT::i16;
234  else if (Align & 4)
235  // DWORD aligned
236  AVT = MVT::i32;
237  else
238  // QWORD aligned
239  AVT = Subtarget.is64Bit() ? MVT::i64 : MVT::i32;
240 
241  unsigned UBytes = AVT.getSizeInBits() / 8;
242  unsigned CountVal = SizeVal / UBytes;
243  SDValue Count = DAG.getIntPtrConstant(CountVal, dl);
244  unsigned BytesLeft = SizeVal % UBytes;
245 
246  SDValue InFlag;
247  Chain = DAG.getCopyToReg(Chain, dl, Subtarget.is64Bit() ? X86::RCX : X86::ECX,
248  Count, InFlag);
249  InFlag = Chain.getValue(1);
250  Chain = DAG.getCopyToReg(Chain, dl, Subtarget.is64Bit() ? X86::RDI : X86::EDI,
251  Dst, InFlag);
252  InFlag = Chain.getValue(1);
253  Chain = DAG.getCopyToReg(Chain, dl, Subtarget.is64Bit() ? X86::RSI : X86::ESI,
254  Src, InFlag);
255  InFlag = Chain.getValue(1);
256 
258  SDValue Ops[] = { Chain, DAG.getValueType(AVT), InFlag };
259  SDValue RepMovs = DAG.getNode(X86ISD::REP_MOVS, dl, Tys, Ops);
260 
262  Results.push_back(RepMovs);
263  if (BytesLeft) {
264  // Handle the last 1 - 7 bytes.
265  unsigned Offset = SizeVal - BytesLeft;
266  EVT DstVT = Dst.getValueType();
267  EVT SrcVT = Src.getValueType();
268  EVT SizeVT = Size.getValueType();
269  Results.push_back(DAG.getMemcpy(Chain, dl,
270  DAG.getNode(ISD::ADD, dl, DstVT, Dst,
271  DAG.getConstant(Offset, dl,
272  DstVT)),
273  DAG.getNode(ISD::ADD, dl, SrcVT, Src,
274  DAG.getConstant(Offset, dl,
275  SrcVT)),
276  DAG.getConstant(BytesLeft, dl, SizeVT),
277  Align, isVolatile, AlwaysInline, false,
278  DstPtrInfo.getWithOffset(Offset),
279  SrcPtrInfo.getWithOffset(Offset)));
280  }
281 
282  return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Results);
283 }
SDValue getValue(unsigned R) const
Repeat move, corresponds to X86::REP_MOVSx.
LLVMContext * getContext() const
Definition: SelectionDAG.h:333
SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool isVolatile, bool AlwaysInline, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const override
Emit target-specific code that performs a memcpy.
const TargetSubtargetInfo & getSubtarget() const
Definition: SelectionDAG.h:330
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Function Alias Analysis Results
unsigned getSizeInBits() const
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getExternalSymbol(const char *Sym, EVT VT)
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:327
CallLoweringInfo & setChain(SDValue InChain)
MachinePointerInfo getWithOffset(int64_t O) const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:200
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:328
MVT - Machine Value Type.
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
C - The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Repeat fill, corresponds to X86::REP_STOSx.
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:154
uint32_t Offset
EVT - Extended Value Type.
Definition: ValueTypes.h:31
std::vector< ArgListEntry > ArgListTy
This structure contains all information that is necessary for lowering calls.
This class contains a discriminated union of information about pointers in memory operands...
unsigned getBaseRegister() const
bool bitsGT(EVT VT) const
bitsGT - Return true if this has more bits than VT.
Definition: ValueTypes.h:200
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...
Definition: DataLayout.cpp:709
TokenFactor - This node takes multiple tokens as input and produces a single token result...
Definition: ISDOpcodes.h:50
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:166
CallLoweringInfo & setCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo)
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:584
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:333
unsigned getSizeInBits() const
getSizeInBits - Return the size of the specified value type in bits.
Definition: ValueTypes.h:256
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:287
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
EVT getValueType() const
Return the ValueType of the referenced return value.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool isVolatile, MachinePointerInfo DstPtrInfo) const override
Emit target-specific code that performs a memset.
SDValue getValueType(EVT)
const TargetLowering & getTargetLoweringInfo() const
Definition: SelectionDAG.h:331
bool hasOpaqueSPAdjustment() const
Returns true if the function contains opaque dynamic stack adjustments.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
static bool isVolatile(Instruction *Inst)
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
SDValue getMemset(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool isVol, bool isTailCall, MachinePointerInfo DstPtrInfo)
This file describes how to lower LLVM code to machine code.
uint64_t getZExtValue() const