LLVM  7.0.0svn
AMDGPUCallLowering.cpp
Go to the documentation of this file.
1 //===-- llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp - Call lowering -----===//
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 /// \file
11 /// This file implements the lowering of LLVM calls to machine code calls for
12 /// GlobalISel.
13 ///
14 //===----------------------------------------------------------------------===//
15 
16 #include "AMDGPUCallLowering.h"
17 #include "AMDGPU.h"
18 #include "AMDGPUISelLowering.h"
19 #include "AMDGPUSubtarget.h"
20 #include "SIISelLowering.h"
21 #include "SIMachineFunctionInfo.h"
22 #include "SIRegisterInfo.h"
27 
28 using namespace llvm;
29 
31  : CallLowering(&TLI), AMDGPUASI(TLI.getAMDGPUAS()) {
32 }
33 
35  const Value *Val, unsigned VReg) const {
36  // FIXME: Add support for non-void returns.
37  if (Val)
38  return false;
39 
40  MIRBuilder.buildInstr(AMDGPU::S_ENDPGM);
41  return true;
42 }
43 
44 unsigned AMDGPUCallLowering::lowerParameterPtr(MachineIRBuilder &MIRBuilder,
45  Type *ParamTy,
46  unsigned Offset) const {
47 
48  MachineFunction &MF = MIRBuilder.getMF();
51  const Function &F = MF.getFunction();
52  const DataLayout &DL = F.getParent()->getDataLayout();
53  PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUASI.CONSTANT_ADDRESS);
54  LLT PtrType = getLLTForType(*PtrTy, DL);
55  unsigned DstReg = MRI.createGenericVirtualRegister(PtrType);
56  unsigned KernArgSegmentPtr =
58  unsigned KernArgSegmentVReg = MRI.getLiveInVirtReg(KernArgSegmentPtr);
59 
60  unsigned OffsetReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
61  MIRBuilder.buildConstant(OffsetReg, Offset);
62 
63  MIRBuilder.buildGEP(DstReg, KernArgSegmentVReg, OffsetReg);
64 
65  return DstReg;
66 }
67 
68 void AMDGPUCallLowering::lowerParameter(MachineIRBuilder &MIRBuilder,
69  Type *ParamTy, unsigned Offset,
70  unsigned DstReg) const {
71  MachineFunction &MF = MIRBuilder.getMF();
72  const Function &F = MF.getFunction();
73  const DataLayout &DL = F.getParent()->getDataLayout();
74  PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUASI.CONSTANT_ADDRESS);
75  MachinePointerInfo PtrInfo(UndefValue::get(PtrTy));
76  unsigned TypeSize = DL.getTypeStoreSize(ParamTy);
77  unsigned Align = DL.getABITypeAlignment(ParamTy);
78  unsigned PtrReg = lowerParameterPtr(MIRBuilder, ParamTy, Offset);
79 
80  MachineMemOperand *MMO =
84  TypeSize, Align);
85 
86  MIRBuilder.buildLoad(DstReg, PtrReg, *MMO);
87 }
88 
90  const Function &F,
91  ArrayRef<unsigned> VRegs) const {
92  // AMDGPU_GS and AMDGP_HS are not supported yet.
95  return false;
96 
97  MachineFunction &MF = MIRBuilder.getMF();
98  const SISubtarget *Subtarget = static_cast<const SISubtarget *>(&MF.getSubtarget());
101  const SIRegisterInfo *TRI = MF.getSubtarget<SISubtarget>().getRegisterInfo();
102  const DataLayout &DL = F.getParent()->getDataLayout();
103 
105  CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
106 
107  // FIXME: How should these inputs interact with inreg / custom SGPR inputs?
108  if (Info->hasPrivateSegmentBuffer()) {
109  unsigned PrivateSegmentBufferReg = Info->addPrivateSegmentBuffer(*TRI);
110  MF.addLiveIn(PrivateSegmentBufferReg, &AMDGPU::SReg_128RegClass);
111  CCInfo.AllocateReg(PrivateSegmentBufferReg);
112  }
113 
114  if (Info->hasDispatchPtr()) {
115  unsigned DispatchPtrReg = Info->addDispatchPtr(*TRI);
116  // FIXME: Need to add reg as live-in
117  CCInfo.AllocateReg(DispatchPtrReg);
118  }
119 
120  if (Info->hasQueuePtr()) {
121  unsigned QueuePtrReg = Info->addQueuePtr(*TRI);
122  // FIXME: Need to add reg as live-in
123  CCInfo.AllocateReg(QueuePtrReg);
124  }
125 
126  if (Info->hasKernargSegmentPtr()) {
127  unsigned InputPtrReg = Info->addKernargSegmentPtr(*TRI);
129  unsigned VReg = MRI.createGenericVirtualRegister(P2);
130  MRI.addLiveIn(InputPtrReg, VReg);
131  MIRBuilder.getMBB().addLiveIn(InputPtrReg);
132  MIRBuilder.buildCopy(VReg, InputPtrReg);
133  CCInfo.AllocateReg(InputPtrReg);
134  }
135 
136  if (Info->hasDispatchID()) {
137  unsigned DispatchIDReg = Info->addDispatchID(*TRI);
138  // FIXME: Need to add reg as live-in
139  CCInfo.AllocateReg(DispatchIDReg);
140  }
141 
142  if (Info->hasFlatScratchInit()) {
143  unsigned FlatScratchInitReg = Info->addFlatScratchInit(*TRI);
144  // FIXME: Need to add reg as live-in
145  CCInfo.AllocateReg(FlatScratchInitReg);
146  }
147 
148  unsigned NumArgs = F.arg_size();
149  Function::const_arg_iterator CurOrigArg = F.arg_begin();
150  const AMDGPUTargetLowering &TLI = *getTLI<AMDGPUTargetLowering>();
151  unsigned PSInputNum = 0;
152  BitVector Skipped(NumArgs);
153  for (unsigned i = 0; i != NumArgs; ++i, ++CurOrigArg) {
154  EVT ValEVT = TLI.getValueType(DL, CurOrigArg->getType());
155 
156  // We can only hanlde simple value types at the moment.
157  ISD::ArgFlagsTy Flags;
158  ArgInfo OrigArg{VRegs[i], CurOrigArg->getType()};
159  setArgFlags(OrigArg, i + 1, DL, F);
160  Flags.setOrigAlign(DL.getABITypeAlignment(CurOrigArg->getType()));
161 
163  !OrigArg.Flags.isInReg() && !OrigArg.Flags.isByVal() &&
164  PSInputNum <= 15) {
165  if (CurOrigArg->use_empty() && !Info->isPSInputAllocated(PSInputNum)) {
166  Skipped.set(i);
167  ++PSInputNum;
168  continue;
169  }
170 
171  Info->markPSInputAllocated(PSInputNum);
172  if (!CurOrigArg->use_empty())
173  Info->markPSInputEnabled(PSInputNum);
174 
175  ++PSInputNum;
176  }
177 
179  /*IsVarArg=*/false);
180 
181  if (ValEVT.isVector()) {
182  EVT ElemVT = ValEVT.getVectorElementType();
183  if (!ValEVT.isSimple())
184  return false;
185  MVT ValVT = ElemVT.getSimpleVT();
186  bool Res = AssignFn(i, ValVT, ValVT, CCValAssign::Full,
187  OrigArg.Flags, CCInfo);
188  if (!Res)
189  return false;
190  } else {
191  MVT ValVT = ValEVT.getSimpleVT();
192  if (!ValEVT.isSimple())
193  return false;
194  bool Res =
195  AssignFn(i, ValVT, ValVT, CCValAssign::Full, OrigArg.Flags, CCInfo);
196 
197  // Fail if we don't know how to handle this type.
198  if (Res)
199  return false;
200  }
201  }
202 
204 
207  for (unsigned i = 0, OrigArgIdx = 0;
208  OrigArgIdx != NumArgs && i != ArgLocs.size(); ++Arg, ++OrigArgIdx) {
209  if (Skipped.test(OrigArgIdx))
210  continue;
211  CCValAssign &VA = ArgLocs[i++];
212  MRI.addLiveIn(VA.getLocReg(), VRegs[OrigArgIdx]);
213  MIRBuilder.getMBB().addLiveIn(VA.getLocReg());
214  MIRBuilder.buildCopy(VRegs[OrigArgIdx], VA.getLocReg());
215  }
216  return true;
217  }
218 
219  for (unsigned i = 0; i != ArgLocs.size(); ++i, ++Arg) {
220  // FIXME: We should be getting DebugInfo from the arguments some how.
221  CCValAssign &VA = ArgLocs[i];
222  lowerParameter(MIRBuilder, Arg->getType(),
223  VA.getLocMemOffset() +
224  Subtarget->getExplicitKernelArgOffset(F), VRegs[i]);
225  }
226 
227  return true;
228 }
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.h:163
MachineInstrBuilder buildCopy(unsigned Res, unsigned Op)
Build and insert Res = COPY Op.
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:111
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
BitVector & set()
Definition: BitVector.h:398
Interface definition for SIRegisterInfo.
This class represents an incoming formal argument to a Function.
Definition: Argument.h:30
AMDGPU specific subclass of TargetSubtarget.
bool isPSInputAllocated(unsigned Index) const
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
MachineInstrBuilder buildGEP(unsigned Res, unsigned Op0, unsigned Op1)
Build and insert Res = G_GEP Op0, Op1.
Calling convention used for Mesa/AMDPAL hull shaders (= tessellation control shaders).
Definition: CallingConv.h:208
void addLiveIn(unsigned Reg, unsigned vreg=0)
addLiveIn - Add the specified register as a live-in.
unsigned addLiveIn(unsigned PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
This file describes how to lower LLVM calls to machine code calls.
unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI)
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:253
AMDGPUAS getAMDGPUAS(const Module &M)
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space...
Definition: Type.cpp:617
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change...
bool test(unsigned Idx) const
Definition: BitVector.h:502
static const MCPhysReg VRegs[32]
static CCAssignFn * CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg)
unsigned const TargetRegisterInfo * TRI
F(f)
void markPSInputEnabled(unsigned Index)
A description of a memory reference used in the backend.
const DataLayout & getDataLayout() const
Get the data layout for the module&#39;s target platform.
Definition: Module.cpp:361
Calling convention used for Mesa vertex shaders, or AMDPAL last shader stage before rasterization (ve...
Definition: CallingConv.h:189
unsigned addDispatchID(const SIRegisterInfo &TRI)
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.
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:245
void setArgFlags(ArgInfo &Arg, unsigned OpNum, const DataLayout &DL, const FuncInfoTy &FuncInfo) const
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
void setOrigAlign(unsigned A)
void markPSInputAllocated(unsigned Index)
Class to represent pointers.
Definition: DerivedTypes.h:467
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
unsigned const MachineRegisterInfo * MRI
Machine Value Type.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
Calling convention used for Mesa/AMDPAL pixel shaders.
Definition: CallingConv.h:195
SI DAG Lowering interface definition.
unsigned addQueuePtr(const SIRegisterInfo &TRI)
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
size_t arg_size() const
Definition: Function.h:684
arg_iterator arg_begin()
Definition: Function.h:657
The memory access is non-temporal.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:193
Extended Value Type.
Definition: ValueTypes.h:34
static UndefValue * get(Type *T)
Static factory methods - Return an &#39;undef&#39; object of the specified type.
Definition: Constants.cpp:1382
This class contains a discriminated union of information about pointers in memory operands...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
unsigned addDispatchPtr(const SIRegisterInfo &TRI)
LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
unsigned createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
CCState - This class holds information needed while lowering arguments and return values...
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition: ValueTypes.h:265
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:199
Interface definition of the TargetLowering class that is common to all AMD GPUs.
unsigned getExplicitKernelArgOffset(const Function &F) const
Returns the offset in bytes from the start of the input buffer of the first explicit kernel argument...
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
CCValAssign - Represent assignment of one arg/retval to a location.
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
Definition: DataLayout.cpp:722
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef< unsigned > VRegs) const override
This hook must be implemented to lower the incoming (formal) arguments, described by Args...
const Function & getFunction() const
Return the LLVM function that this machine code represents.
This file declares the MachineIRBuilder class.
MachineInstrBuilder buildConstant(unsigned Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI)
amdgpu Simplify well known AMD library false Value Value * Arg
unsigned addFlatScratchInit(const SIRegisterInfo &TRI)
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
The memory access reads data.
Calling convention used for Mesa/AMDPAL geometry shaders.
Definition: CallingConv.h:192
Provides AMDGPU specific target descriptions.
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
unsigned getPreloadedReg(AMDGPUFunctionArgInfo::PreloadedValue Value) const
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:151
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
unsigned getLocMemOffset() const
MachineInstrBuilder buildLoad(unsigned Res, unsigned Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
The memory access always returns the same value (or traps).
MachineFunction & getMF()
Getter for the function we currently build.
bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val, unsigned VReg) const override
This hook must be implemented to lower outgoing return values, described by Val, into the specified v...
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:565
LLVM Value Representation.
Definition: Value.h:73
static LLT pointer(uint16_t AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space (defaulting to 0).
uint64_t getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type...
Definition: DataLayout.h:411
MachineBasicBlock & getMBB()
Getter for the basic block we currently build.
MachineInstrBuilder buildInstr(unsigned Opc, DstTy &&Ty, UseArgsTy &&... Args)
DAG like Generic method for building arbitrary instructions as above.
unsigned getLocReg() const
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition: ValueTypes.h:126
Address space for constant memory (VTX2)
Definition: AMDGPU.h:231
bool use_empty() const
Definition: Value.h:322
AMDGPUCallLowering(const AMDGPUTargetLowering &TLI)