LLVM  10.0.0svn
AArch64SelectionDAGInfo.cpp
Go to the documentation of this file.
1 //===-- AArch64SelectionDAGInfo.cpp - AArch64 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 AArch64SelectionDAGInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "AArch64TargetMachine.h"
14 using namespace llvm;
15 
16 #define DEBUG_TYPE "aarch64-selectiondag-info"
17 
19  SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
20  SDValue Size, unsigned Align, bool isVolatile,
21  MachinePointerInfo DstPtrInfo) const {
22  // Check to see if there is a specialized entry-point for memory zeroing.
25  const AArch64Subtarget &STI =
27  const char *bzeroName = (V && V->isNullValue())
28  ? DAG.getTargetLoweringInfo().getLibcallName(RTLIB::BZERO) : nullptr;
29  // For small size (< 256), it is not beneficial to use bzero
30  // instead of memset.
31  if (bzeroName && (!SizeValue || SizeValue->getZExtValue() > 256)) {
32  const AArch64TargetLowering &TLI = *STI.getTargetLowering();
33 
34  EVT IntPtr = TLI.getPointerTy(DAG.getDataLayout());
35  Type *IntPtrTy = DAG.getDataLayout().getIntPtrType(*DAG.getContext());
38  Entry.Node = Dst;
39  Entry.Ty = IntPtrTy;
40  Args.push_back(Entry);
41  Entry.Node = Size;
42  Args.push_back(Entry);
44  CLI.setDebugLoc(dl)
45  .setChain(Chain)
47  DAG.getExternalSymbol(bzeroName, IntPtr),
48  std::move(Args))
49  .setDiscardResult();
50  std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
51  return CallResult.second;
52  }
53  return SDValue();
54 }
56  CodeGenOpt::Level OptLevel) const {
57  return OptLevel >= CodeGenOpt::Aggressive;
58 }
59 
60 static const int kSetTagLoopThreshold = 176;
61 
63  SDValue Chain, SDValue Ptr, uint64_t ObjSize,
64  const MachineMemOperand *BaseMemOperand,
65  bool ZeroData) {
67  unsigned ObjSizeScaled = ObjSize / 16;
68 
69  SDValue TagSrc = Ptr;
70  if (Ptr.getOpcode() == ISD::FrameIndex) {
71  int FI = cast<FrameIndexSDNode>(Ptr)->getIndex();
72  Ptr = DAG.getTargetFrameIndex(FI, MVT::i64);
73  // A frame index operand may end up as [SP + offset] => it is fine to use SP
74  // register as the tag source.
75  TagSrc = DAG.getRegister(AArch64::SP, MVT::i64);
76  }
77 
78  const unsigned OpCode1 = ZeroData ? AArch64ISD::STZG : AArch64ISD::STG;
79  const unsigned OpCode2 = ZeroData ? AArch64ISD::STZ2G : AArch64ISD::ST2G;
80 
81  SmallVector<SDValue, 8> OutChains;
82  unsigned OffsetScaled = 0;
83  while (OffsetScaled < ObjSizeScaled) {
84  if (ObjSizeScaled - OffsetScaled >= 2) {
85  SDValue AddrNode = DAG.getMemBasePlusOffset(Ptr, OffsetScaled * 16, dl);
87  OpCode2, dl, DAG.getVTList(MVT::Other),
88  {Chain, TagSrc, AddrNode},
89  MVT::v4i64,
90  MF.getMachineMemOperand(BaseMemOperand, OffsetScaled * 16, 16 * 2));
91  OffsetScaled += 2;
92  OutChains.push_back(St);
93  continue;
94  }
95 
96  if (ObjSizeScaled - OffsetScaled > 0) {
97  SDValue AddrNode = DAG.getMemBasePlusOffset(Ptr, OffsetScaled * 16, dl);
99  OpCode1, dl, DAG.getVTList(MVT::Other),
100  {Chain, TagSrc, AddrNode},
101  MVT::v2i64,
102  MF.getMachineMemOperand(BaseMemOperand, OffsetScaled * 16, 16));
103  OffsetScaled += 1;
104  OutChains.push_back(St);
105  }
106  }
107 
108  SDValue Res = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
109  return Res;
110 }
111 
113  SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Addr,
114  SDValue Size, MachinePointerInfo DstPtrInfo, bool ZeroData) const {
115  uint64_t ObjSize = cast<ConstantSDNode>(Size)->getZExtValue();
116  assert(ObjSize % 16 == 0);
117 
119  MachineMemOperand *BaseMemOperand = MF.getMachineMemOperand(
120  DstPtrInfo, MachineMemOperand::MOStore, ObjSize, 16);
121 
122  bool UseSetTagRangeLoop =
123  kSetTagLoopThreshold >= 0 && (int)ObjSize >= kSetTagLoopThreshold;
124  if (!UseSetTagRangeLoop)
125  return EmitUnrolledSetTag(DAG, dl, Chain, Addr, ObjSize, BaseMemOperand,
126  ZeroData);
127 
128  if (ObjSize % 32 != 0) {
129  SDNode *St1 = DAG.getMachineNode(
130  ZeroData ? AArch64::STZGPostIndex : AArch64::STGPostIndex, dl,
131  {MVT::i64, MVT::Other},
132  {Addr, Addr, DAG.getTargetConstant(1, dl, MVT::i64), Chain});
133  DAG.setNodeMemRefs(cast<MachineSDNode>(St1), {BaseMemOperand});
134  ObjSize -= 16;
135  Addr = SDValue(St1, 0);
136  Chain = SDValue(St1, 1);
137  }
138 
139  const EVT ResTys[] = {MVT::i64, MVT::i64, MVT::Other};
140  SDValue Ops[] = {DAG.getConstant(ObjSize, dl, MVT::i64), Addr, Chain};
141  SDNode *St = DAG.getMachineNode(
142  ZeroData ? AArch64::STZGloop : AArch64::STGloop, dl, ResTys, Ops);
143 
144  DAG.setNodeMemRefs(cast<MachineSDNode>(St), {BaseMemOperand});
145  return SDValue(St, 2);
146 }
C - The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
This class represents lattice values for constants.
Definition: AllocatorList.h:23
SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, unsigned Align=0, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, unsigned Size=0, const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
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 getMemBasePlusOffset(SDValue Base, unsigned Offset, const SDLoc &DL)
Returns sum of the base pointer and offset.
static SDValue EmitUnrolledSetTag(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Ptr, uint64_t ObjSize, const MachineMemOperand *BaseMemOperand, bool ZeroData)
A description of a memory reference used in the backend.
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s), MachineInstr opcode, and operands.
CallLoweringInfo & setChain(SDValue InChain)
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:413
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:410
SDValue getTargetFrameIndex(int FI, EVT VT)
Definition: SelectionDAG.h:643
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:592
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:772
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
bool generateFMAsInMachineCombiner(CodeGenOpt::Level OptLevel) const override
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:160
virtual 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...
std::vector< ArgListEntry > ArgListTy
Extended Value Type.
Definition: ValueTypes.h:33
This structure contains all information that is necessary for lowering calls.
This class contains a discriminated union of information about pointers in memory operands...
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:40
static const int kSetTagLoopThreshold
The memory access writes data.
SDValue EmitTargetCodeForSetTag(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Op1, SDValue Op2, MachinePointerInfo DstPtrInfo, bool ZeroData) const override
TokenFactor - This node takes multiple tokens as input and produces a single token result...
Definition: ISDOpcodes.h:49
const TargetLowering & getTargetLoweringInfo() const
Definition: SelectionDAG.h:416
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:221
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
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.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
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:332
uint32_t Size
Definition: Profile.cpp:46
unsigned getOpcode() const
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())
SDValue getRegister(unsigned Reg, EVT VT)
static bool isVolatile(Instruction *Inst)
void setNodeMemRefs(MachineSDNode *N, ArrayRef< MachineMemOperand *> NewMemRefs)
Mutate the specified machine node&#39;s memory references to the provided list.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
LLVMContext * getContext() const
Definition: SelectionDAG.h:420
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
const char * getLibcallName(RTLIB::Libcall Call) const
Get the libcall routine name for the specified libcall.