LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ARMSelectionDAGInfo.cpp
Go to the documentation of this file.
1 //===-- ARMSelectionDAGInfo.cpp - ARM 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 ARMSelectionDAGInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #define DEBUG_TYPE "arm-selectiondag-info"
15 #include "ARMTargetMachine.h"
17 #include "llvm/IR/DerivedTypes.h"
18 using namespace llvm;
19 
22  Subtarget(&TM.getSubtarget<ARMSubtarget>()) {
23 }
24 
26 }
27 
28 SDValue
30  SDValue Chain,
31  SDValue Dst, SDValue Src,
32  SDValue Size, unsigned Align,
33  bool isVolatile, bool AlwaysInline,
34  MachinePointerInfo DstPtrInfo,
35  MachinePointerInfo SrcPtrInfo) const {
36  // Do repeated 4-byte loads and stores. To be improved.
37  // This requires 4-byte alignment.
38  if ((Align & 3) != 0)
39  return SDValue();
40  // This requires the copy size to be a constant, preferably
41  // within a subtarget-specific limit.
42  ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
43  if (!ConstantSize)
44  return SDValue();
45  uint64_t SizeVal = ConstantSize->getZExtValue();
46  if (!AlwaysInline && SizeVal > Subtarget->getMaxInlineSizeThreshold())
47  return SDValue();
48 
49  unsigned BytesLeft = SizeVal & 3;
50  unsigned NumMemOps = SizeVal >> 2;
51  unsigned EmittedNumMemOps = 0;
52  EVT VT = MVT::i32;
53  unsigned VTSize = 4;
54  unsigned i = 0;
55  const unsigned MAX_LOADS_IN_LDM = 6;
56  SDValue TFOps[MAX_LOADS_IN_LDM];
57  SDValue Loads[MAX_LOADS_IN_LDM];
58  uint64_t SrcOff = 0, DstOff = 0;
59 
60  // Emit up to MAX_LOADS_IN_LDM loads, then a TokenFactor barrier, then the
61  // same number of stores. The loads and stores will get combined into
62  // ldm/stm later on.
63  while (EmittedNumMemOps < NumMemOps) {
64  for (i = 0;
65  i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) {
66  Loads[i] = DAG.getLoad(VT, dl, Chain,
67  DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
68  DAG.getConstant(SrcOff, MVT::i32)),
69  SrcPtrInfo.getWithOffset(SrcOff), isVolatile,
70  false, false, 0);
71  TFOps[i] = Loads[i].getValue(1);
72  SrcOff += VTSize;
73  }
74  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
75 
76  for (i = 0;
77  i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) {
78  TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
79  DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
80  DAG.getConstant(DstOff, MVT::i32)),
81  DstPtrInfo.getWithOffset(DstOff),
82  isVolatile, false, 0);
83  DstOff += VTSize;
84  }
85  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
86 
87  EmittedNumMemOps += i;
88  }
89 
90  if (BytesLeft == 0)
91  return Chain;
92 
93  // Issue loads / stores for the trailing (1 - 3) bytes.
94  unsigned BytesLeftSave = BytesLeft;
95  i = 0;
96  while (BytesLeft) {
97  if (BytesLeft >= 2) {
98  VT = MVT::i16;
99  VTSize = 2;
100  } else {
101  VT = MVT::i8;
102  VTSize = 1;
103  }
104 
105  Loads[i] = DAG.getLoad(VT, dl, Chain,
106  DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
107  DAG.getConstant(SrcOff, MVT::i32)),
108  SrcPtrInfo.getWithOffset(SrcOff),
109  false, false, false, 0);
110  TFOps[i] = Loads[i].getValue(1);
111  ++i;
112  SrcOff += VTSize;
113  BytesLeft -= VTSize;
114  }
115  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
116 
117  i = 0;
118  BytesLeft = BytesLeftSave;
119  while (BytesLeft) {
120  if (BytesLeft >= 2) {
121  VT = MVT::i16;
122  VTSize = 2;
123  } else {
124  VT = MVT::i8;
125  VTSize = 1;
126  }
127 
128  TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
129  DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
130  DAG.getConstant(DstOff, MVT::i32)),
131  DstPtrInfo.getWithOffset(DstOff), false, false, 0);
132  ++i;
133  DstOff += VTSize;
134  BytesLeft -= VTSize;
135  }
136  return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
137 }
138 
139 // Adjust parameters for memset, EABI uses format (ptr, size, value),
140 // GNU library uses (ptr, value, size)
141 // See RTABI section 4.3.4
144  SDValue Chain, SDValue Dst,
145  SDValue Src, SDValue Size,
146  unsigned Align, bool isVolatile,
147  MachinePointerInfo DstPtrInfo) const {
148  // Use default for non AAPCS (or Darwin) subtargets
149  if (!Subtarget->isAAPCS_ABI() || Subtarget->isTargetDarwin())
150  return SDValue();
151 
152  const ARMTargetLowering &TLI =
153  *static_cast<const ARMTargetLowering*>(DAG.getTarget().getTargetLowering());
156 
157  // First argument: data pointer
158  Type *IntPtrTy = TLI.getDataLayout()->getIntPtrType(*DAG.getContext());
159  Entry.Node = Dst;
160  Entry.Ty = IntPtrTy;
161  Args.push_back(Entry);
162 
163  // Second argument: buffer size
164  Entry.Node = Size;
165  Entry.Ty = IntPtrTy;
166  Entry.isSExt = false;
167  Args.push_back(Entry);
168 
169  // Extend or truncate the argument to be an i32 value for the call.
170  if (Src.getValueType().bitsGT(MVT::i32))
171  Src = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Src);
172  else
173  Src = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, Src);
174 
175  // Third argument: value to fill
176  Entry.Node = Src;
177  Entry.Ty = Type::getInt32Ty(*DAG.getContext());
178  Entry.isSExt = true;
179  Args.push_back(Entry);
180 
181  // Emit __eabi_memset call
183  Type::getVoidTy(*DAG.getContext()), // return type
184  false, // return sign ext
185  false, // return zero ext
186  false, // is var arg
187  false, // is in regs
188  0, // number of fixed arguments
189  TLI.getLibcallCallingConv(RTLIB::MEMSET), // call conv
190  false, // is tail call
191  false, // does not return
192  false, // is return val used
194  TLI.getPointerTy()), // callee
195  Args, DAG, dl);
196  std::pair<SDValue,SDValue> CallResult =
197  TLI.LowerCallTo(CLI);
198 
199  return CallResult.second;
200 }
SDValue getConstant(uint64_t Val, EVT VT, bool isTarget=false)
CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const
Get the CallingConv that should be used for the specified libcall.
SDValue getValue(unsigned R) const
virtual const TargetLowering * getTargetLowering() const
LLVMContext * getContext() const
Definition: SelectionDAG.h:285
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:266
const TargetMachine & getTarget() const
Definition: SelectionDAG.h:281
SDValue getExternalSymbol(const char *Sym, EVT VT)
SDValue getLoad(EVT VT, SDLoc dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, bool isVolatile, bool isNonTemporal, bool isInvariant, unsigned Alignment, const MDNode *TBAAInfo=0, const MDNode *Ranges=0)
SDValue getStore(SDValue Chain, SDLoc dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, bool isVolatile, bool isNonTemporal, unsigned Alignment, const MDNode *TBAAInfo=0)
bool isTargetDarwin() const
Definition: ARMSubtarget.h:303
MachinePointerInfo getWithOffset(int64_t O) const
virtual MVT getPointerTy(uint32_t=0) const
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:176
ARMSelectionDAGInfo(const TargetMachine &TM)
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:227
const DataLayout * getDataLayout() const
std::vector< ArgListEntry > ArgListTy
bool bitsGT(EVT VT) const
bitsGT - Return true if this has more bits than VT.
Definition: ValueTypes.h:723
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Definition: DataLayout.cpp:610
const char * getLibcallName(RTLIB::Libcall Call) const
Get the libcall routine name for the specified libcall.
unsigned getMaxInlineSizeThreshold() const
Definition: ARMSubtarget.h:227
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:357
SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT)
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:241
EVT getValueType() const
virtual SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, SDLoc dl, SDValue Chain, SDValue Op1, SDValue Op2, SDValue Op3, unsigned Align, bool isVolatile, MachinePointerInfo DstPtrInfo) const
bool isAAPCS_ABI() const
Definition: ARMSubtarget.h:317
TRUNCATE - Completely drop the high bits.
Definition: ISDOpcodes.h:363
virtual SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, SDLoc dl, SDValue Chain, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool isVolatile, bool AlwaysInline, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const
uint64_t getZExtValue() const