LLVM  6.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"
26 
27 using namespace llvm;
28 
30  : CallLowering(&TLI), AMDGPUASI(TLI.getAMDGPUAS()) {
31 }
32 
34  const Value *Val, unsigned VReg) const {
35  MIRBuilder.buildInstr(AMDGPU::S_ENDPGM);
36  return true;
37 }
38 
39 unsigned AMDGPUCallLowering::lowerParameterPtr(MachineIRBuilder &MIRBuilder,
40  Type *ParamTy,
41  unsigned Offset) const {
42 
43  MachineFunction &MF = MIRBuilder.getMF();
46  const Function &F = *MF.getFunction();
47  const DataLayout &DL = F.getParent()->getDataLayout();
48  PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUASI.CONSTANT_ADDRESS);
49  LLT PtrType = getLLTForType(*PtrTy, DL);
50  unsigned DstReg = MRI.createGenericVirtualRegister(PtrType);
51  unsigned KernArgSegmentPtr =
53  unsigned KernArgSegmentVReg = MRI.getLiveInVirtReg(KernArgSegmentPtr);
54 
55  unsigned OffsetReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
56  MIRBuilder.buildConstant(OffsetReg, Offset);
57 
58  MIRBuilder.buildGEP(DstReg, KernArgSegmentVReg, OffsetReg);
59 
60  return DstReg;
61 }
62 
63 void AMDGPUCallLowering::lowerParameter(MachineIRBuilder &MIRBuilder,
64  Type *ParamTy, unsigned Offset,
65  unsigned DstReg) const {
66  MachineFunction &MF = MIRBuilder.getMF();
67  const Function &F = *MF.getFunction();
68  const DataLayout &DL = F.getParent()->getDataLayout();
69  PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUASI.CONSTANT_ADDRESS);
70  MachinePointerInfo PtrInfo(UndefValue::get(PtrTy));
71  unsigned TypeSize = DL.getTypeStoreSize(ParamTy);
72  unsigned Align = DL.getABITypeAlignment(ParamTy);
73  unsigned PtrReg = lowerParameterPtr(MIRBuilder, ParamTy, Offset);
74 
75  MachineMemOperand *MMO =
79  TypeSize, Align);
80 
81  MIRBuilder.buildLoad(DstReg, PtrReg, *MMO);
82 }
83 
85  const Function &F,
86  ArrayRef<unsigned> VRegs) const {
87 
88  MachineFunction &MF = MIRBuilder.getMF();
89  const SISubtarget *Subtarget = static_cast<const SISubtarget *>(&MF.getSubtarget());
92  const SIRegisterInfo *TRI = MF.getSubtarget<SISubtarget>().getRegisterInfo();
93  const DataLayout &DL = F.getParent()->getDataLayout();
94 
96  CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
97 
98  // FIXME: How should these inputs interact with inreg / custom SGPR inputs?
99  if (Info->hasPrivateSegmentBuffer()) {
100  unsigned PrivateSegmentBufferReg = Info->addPrivateSegmentBuffer(*TRI);
101  MF.addLiveIn(PrivateSegmentBufferReg, &AMDGPU::SReg_128RegClass);
102  CCInfo.AllocateReg(PrivateSegmentBufferReg);
103  }
104 
105  if (Info->hasDispatchPtr()) {
106  unsigned DispatchPtrReg = Info->addDispatchPtr(*TRI);
107  // FIXME: Need to add reg as live-in
108  CCInfo.AllocateReg(DispatchPtrReg);
109  }
110 
111  if (Info->hasQueuePtr()) {
112  unsigned QueuePtrReg = Info->addQueuePtr(*TRI);
113  // FIXME: Need to add reg as live-in
114  CCInfo.AllocateReg(QueuePtrReg);
115  }
116 
117  if (Info->hasKernargSegmentPtr()) {
118  unsigned InputPtrReg = Info->addKernargSegmentPtr(*TRI);
119  const LLT P2 = LLT::pointer(2, 64);
120  unsigned VReg = MRI.createGenericVirtualRegister(P2);
121  MRI.addLiveIn(InputPtrReg, VReg);
122  MIRBuilder.getMBB().addLiveIn(InputPtrReg);
123  MIRBuilder.buildCopy(VReg, InputPtrReg);
124  CCInfo.AllocateReg(InputPtrReg);
125  }
126 
127  if (Info->hasDispatchID()) {
128  unsigned DispatchIDReg = Info->addDispatchID(*TRI);
129  // FIXME: Need to add reg as live-in
130  CCInfo.AllocateReg(DispatchIDReg);
131  }
132 
133  if (Info->hasFlatScratchInit()) {
134  unsigned FlatScratchInitReg = Info->addFlatScratchInit(*TRI);
135  // FIXME: Need to add reg as live-in
136  CCInfo.AllocateReg(FlatScratchInitReg);
137  }
138 
139  unsigned NumArgs = F.arg_size();
140  Function::const_arg_iterator CurOrigArg = F.arg_begin();
141  const AMDGPUTargetLowering &TLI = *getTLI<AMDGPUTargetLowering>();
142  for (unsigned i = 0; i != NumArgs; ++i, ++CurOrigArg) {
143  EVT ValEVT = TLI.getValueType(DL, CurOrigArg->getType());
144 
145  // We can only hanlde simple value types at the moment.
146  if (!ValEVT.isSimple())
147  return false;
148  MVT ValVT = ValEVT.getSimpleVT();
149  ISD::ArgFlagsTy Flags;
150  ArgInfo OrigArg{VRegs[i], CurOrigArg->getType()};
151  setArgFlags(OrigArg, i + 1, DL, F);
152  Flags.setOrigAlign(DL.getABITypeAlignment(CurOrigArg->getType()));
154  /*IsVarArg=*/false);
155  bool Res =
156  AssignFn(i, ValVT, ValVT, CCValAssign::Full, OrigArg.Flags, CCInfo);
157 
158  // Fail if we don't know how to handle this type.
159  if (Res)
160  return false;
161  }
162 
164 
166  for (unsigned i = 0; i != NumArgs; ++i, ++Arg) {
167  CCValAssign &VA = ArgLocs[i];
168  MRI.addLiveIn(VA.getLocReg(), VRegs[i]);
169  MIRBuilder.getMBB().addLiveIn(VA.getLocReg());
170  MIRBuilder.buildCopy(VRegs[i], VA.getLocReg());
171  }
172  return true;
173  }
174 
175  for (unsigned i = 0; i != NumArgs; ++i, ++Arg) {
176  // FIXME: We should be getting DebugInfo from the arguments some how.
177  CCValAssign &VA = ArgLocs[i];
178  lowerParameter(MIRBuilder, Arg->getType(),
179  VA.getLocMemOffset() +
180  Subtarget->getExplicitKernelArgOffset(MF), VRegs[i]);
181  }
182 
183  return true;
184 }
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.h:158
MachineBasicBlock & getMBB()
Getter for the basic block we currently build.
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:109
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
Interface definition for SIRegisterInfo.
This class represents an incoming formal argument to a Function.
Definition: Argument.h:30
MachineInstrBuilder buildGEP(unsigned Res, unsigned Op0, unsigned Op1)
Build and insert Res<def> = G_GEP Op0, Op1.
AMDGPU specific subclass of TargetSubtarget.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
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...
static const MCPhysReg VRegs[32]
static CCAssignFn * CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg)
F(f)
unsigned createGenericVirtualRegister(LLT Ty)
Create and return a new generic virtual register with low-level type Ty.
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
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
MachineFunction & getMF()
Getter for the function we currently build.
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
void setOrigAlign(unsigned A)
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
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
Helper class to build MachineInstr.
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:630
arg_iterator arg_begin()
Definition: Function.h:603
The memory access is non-temporal.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:194
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:1320
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)
Calling convention used for Mesa vertex shaders, or AMDPAL last shader stage before rasterization (ve...
Definition: CallingConv.h:189
LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
CCState - This class holds information needed while lowering arguments and return values...
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:194
Interface definition of the TargetLowering class that is common to all AMD GPUs.
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:864
MachineInstrBuilder buildCopy(unsigned Res, unsigned Op)
Build and insert Res<def> = COPY Op.
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:682
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...
This file declares the MachineIRBuilder class.
Address space for constant memory (VTX2)
Definition: AMDGPU.h:225
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.
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
unsigned getPreloadedReg(AMDGPUFunctionArgInfo::PreloadedValue Value) const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
unsigned getLocMemOffset() const
MachineInstrBuilder buildConstant(unsigned Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
The memory access always returns the same value (or traps).
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
unsigned getExplicitKernelArgOffset(const MachineFunction &MF) const
Returns the offset in bytes from the start of the input buffer of the first explicit kernel argument...
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:556
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:386
MachineInstrBuilder buildLoad(unsigned Res, unsigned Addr, MachineMemOperand &MMO)
Build and insert Res<def> = G_LOAD Addr, MMO.
unsigned getLocReg() const
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition: ValueTypes.h:126
AMDGPUCallLowering(const AMDGPUTargetLowering &TLI)