blob: fde51d9987a3cb8c58d19c6444d390d0e67ca7e5 [file] [log] [blame]
Tom Stellardd8ea85a2016-12-21 19:06:24 +00001//===-- llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp - Call lowering -----===//
Tom Stellard000c5af2016-04-14 19:09:28 +00002//
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"
Tom Stellardca166212017-01-30 21:56:46 +000017#include "AMDGPU.h"
Tom Stellard000c5af2016-04-14 19:09:28 +000018#include "AMDGPUISelLowering.h"
Tom Stellardca166212017-01-30 21:56:46 +000019#include "AMDGPUSubtarget.h"
20#include "SIISelLowering.h"
Tom Stellardca166212017-01-30 21:56:46 +000021#include "SIMachineFunctionInfo.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000022#include "SIRegisterInfo.h"
Tom Stellardca166212017-01-30 21:56:46 +000023#include "llvm/CodeGen/CallingConvLower.h"
Tom Stellard000c5af2016-04-14 19:09:28 +000024#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
25#include "llvm/CodeGen/MachineInstrBuilder.h"
26
27using namespace llvm;
28
Tom Stellard000c5af2016-04-14 19:09:28 +000029AMDGPUCallLowering::AMDGPUCallLowering(const AMDGPUTargetLowering &TLI)
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000030 : CallLowering(&TLI), AMDGPUASI(TLI.getAMDGPUAS()) {
Tom Stellard000c5af2016-04-14 19:09:28 +000031}
32
33bool AMDGPUCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
Tom Stellardca166212017-01-30 21:56:46 +000034 const Value *Val, unsigned VReg) const {
Tom Stellard257882f2018-04-24 21:29:36 +000035 // FIXME: Add support for non-void returns.
36 if (Val)
37 return false;
38
Tom Stellardca166212017-01-30 21:56:46 +000039 MIRBuilder.buildInstr(AMDGPU::S_ENDPGM);
Tom Stellard000c5af2016-04-14 19:09:28 +000040 return true;
41}
42
Tom Stellardca166212017-01-30 21:56:46 +000043unsigned AMDGPUCallLowering::lowerParameterPtr(MachineIRBuilder &MIRBuilder,
44 Type *ParamTy,
45 unsigned Offset) const {
46
47 MachineFunction &MF = MIRBuilder.getMF();
Matt Arsenault8623e8d2017-08-03 23:00:29 +000048 const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
Tom Stellardca166212017-01-30 21:56:46 +000049 MachineRegisterInfo &MRI = MF.getRegInfo();
Matthias Braunf1caa282017-12-15 22:22:58 +000050 const Function &F = MF.getFunction();
Tom Stellardca166212017-01-30 21:56:46 +000051 const DataLayout &DL = F.getParent()->getDataLayout();
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000052 PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUASI.CONSTANT_ADDRESS);
Daniel Sanders52b4ce72017-03-07 23:20:35 +000053 LLT PtrType = getLLTForType(*PtrTy, DL);
Tom Stellardca166212017-01-30 21:56:46 +000054 unsigned DstReg = MRI.createGenericVirtualRegister(PtrType);
55 unsigned KernArgSegmentPtr =
Matt Arsenault8623e8d2017-08-03 23:00:29 +000056 MFI->getPreloadedReg(AMDGPUFunctionArgInfo::KERNARG_SEGMENT_PTR);
Tom Stellardca166212017-01-30 21:56:46 +000057 unsigned KernArgSegmentVReg = MRI.getLiveInVirtReg(KernArgSegmentPtr);
58
59 unsigned OffsetReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
60 MIRBuilder.buildConstant(OffsetReg, Offset);
61
62 MIRBuilder.buildGEP(DstReg, KernArgSegmentVReg, OffsetReg);
63
64 return DstReg;
65}
66
67void AMDGPUCallLowering::lowerParameter(MachineIRBuilder &MIRBuilder,
68 Type *ParamTy, unsigned Offset,
69 unsigned DstReg) const {
70 MachineFunction &MF = MIRBuilder.getMF();
Matthias Braunf1caa282017-12-15 22:22:58 +000071 const Function &F = MF.getFunction();
Tom Stellardca166212017-01-30 21:56:46 +000072 const DataLayout &DL = F.getParent()->getDataLayout();
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000073 PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUASI.CONSTANT_ADDRESS);
Tom Stellardca166212017-01-30 21:56:46 +000074 MachinePointerInfo PtrInfo(UndefValue::get(PtrTy));
75 unsigned TypeSize = DL.getTypeStoreSize(ParamTy);
76 unsigned Align = DL.getABITypeAlignment(ParamTy);
77 unsigned PtrReg = lowerParameterPtr(MIRBuilder, ParamTy, Offset);
78
79 MachineMemOperand *MMO =
80 MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad |
81 MachineMemOperand::MONonTemporal |
82 MachineMemOperand::MOInvariant,
83 TypeSize, Align);
84
85 MIRBuilder.buildLoad(DstReg, PtrReg, *MMO);
86}
87
Tim Northover862758ec2016-09-21 12:57:35 +000088bool AMDGPUCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
89 const Function &F,
90 ArrayRef<unsigned> VRegs) const {
Tom Stellard37444282018-05-07 22:17:54 +000091 // AMDGPU_GS and AMDGP_HS are not supported yet.
92 if (F.getCallingConv() == CallingConv::AMDGPU_GS ||
93 F.getCallingConv() == CallingConv::AMDGPU_HS)
Tom Stellard6c814182018-04-30 15:15:23 +000094 return false;
Tom Stellardca166212017-01-30 21:56:46 +000095
96 MachineFunction &MF = MIRBuilder.getMF();
97 const SISubtarget *Subtarget = static_cast<const SISubtarget *>(&MF.getSubtarget());
98 MachineRegisterInfo &MRI = MF.getRegInfo();
99 SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>();
100 const SIRegisterInfo *TRI = MF.getSubtarget<SISubtarget>().getRegisterInfo();
101 const DataLayout &DL = F.getParent()->getDataLayout();
102
103 SmallVector<CCValAssign, 16> ArgLocs;
104 CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
105
106 // FIXME: How should these inputs interact with inreg / custom SGPR inputs?
107 if (Info->hasPrivateSegmentBuffer()) {
108 unsigned PrivateSegmentBufferReg = Info->addPrivateSegmentBuffer(*TRI);
109 MF.addLiveIn(PrivateSegmentBufferReg, &AMDGPU::SReg_128RegClass);
110 CCInfo.AllocateReg(PrivateSegmentBufferReg);
111 }
112
113 if (Info->hasDispatchPtr()) {
114 unsigned DispatchPtrReg = Info->addDispatchPtr(*TRI);
115 // FIXME: Need to add reg as live-in
116 CCInfo.AllocateReg(DispatchPtrReg);
117 }
118
119 if (Info->hasQueuePtr()) {
120 unsigned QueuePtrReg = Info->addQueuePtr(*TRI);
121 // FIXME: Need to add reg as live-in
122 CCInfo.AllocateReg(QueuePtrReg);
123 }
124
125 if (Info->hasKernargSegmentPtr()) {
126 unsigned InputPtrReg = Info->addKernargSegmentPtr(*TRI);
Yaxun Liu0124b542018-02-13 18:00:25 +0000127 const LLT P2 = LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS, 64);
Tom Stellardca166212017-01-30 21:56:46 +0000128 unsigned VReg = MRI.createGenericVirtualRegister(P2);
129 MRI.addLiveIn(InputPtrReg, VReg);
130 MIRBuilder.getMBB().addLiveIn(InputPtrReg);
131 MIRBuilder.buildCopy(VReg, InputPtrReg);
132 CCInfo.AllocateReg(InputPtrReg);
133 }
134
135 if (Info->hasDispatchID()) {
136 unsigned DispatchIDReg = Info->addDispatchID(*TRI);
137 // FIXME: Need to add reg as live-in
138 CCInfo.AllocateReg(DispatchIDReg);
139 }
140
141 if (Info->hasFlatScratchInit()) {
142 unsigned FlatScratchInitReg = Info->addFlatScratchInit(*TRI);
143 // FIXME: Need to add reg as live-in
144 CCInfo.AllocateReg(FlatScratchInitReg);
145 }
146
147 unsigned NumArgs = F.arg_size();
148 Function::const_arg_iterator CurOrigArg = F.arg_begin();
149 const AMDGPUTargetLowering &TLI = *getTLI<AMDGPUTargetLowering>();
Tom Stellardc7709e12018-04-24 20:51:28 +0000150 unsigned PSInputNum = 0;
151 BitVector Skipped(NumArgs);
Tom Stellardca166212017-01-30 21:56:46 +0000152 for (unsigned i = 0; i != NumArgs; ++i, ++CurOrigArg) {
Tom Stellard9d8337d2017-08-01 12:38:33 +0000153 EVT ValEVT = TLI.getValueType(DL, CurOrigArg->getType());
154
155 // We can only hanlde simple value types at the moment.
Tom Stellardca166212017-01-30 21:56:46 +0000156 ISD::ArgFlagsTy Flags;
Tom Stellard9d8337d2017-08-01 12:38:33 +0000157 ArgInfo OrigArg{VRegs[i], CurOrigArg->getType()};
158 setArgFlags(OrigArg, i + 1, DL, F);
Tom Stellardca166212017-01-30 21:56:46 +0000159 Flags.setOrigAlign(DL.getABITypeAlignment(CurOrigArg->getType()));
Tom Stellardc7709e12018-04-24 20:51:28 +0000160
161 if (F.getCallingConv() == CallingConv::AMDGPU_PS &&
162 !OrigArg.Flags.isInReg() && !OrigArg.Flags.isByVal() &&
163 PSInputNum <= 15) {
164 if (CurOrigArg->use_empty() && !Info->isPSInputAllocated(PSInputNum)) {
165 Skipped.set(i);
166 ++PSInputNum;
167 continue;
168 }
169
170 Info->markPSInputAllocated(PSInputNum);
171 if (!CurOrigArg->use_empty())
172 Info->markPSInputEnabled(PSInputNum);
173
174 ++PSInputNum;
175 }
176
Tom Stellardca166212017-01-30 21:56:46 +0000177 CCAssignFn *AssignFn = CCAssignFnForCall(F.getCallingConv(),
178 /*IsVarArg=*/false);
Tom Stellard9d8337d2017-08-01 12:38:33 +0000179
Tom Stellardc7709e12018-04-24 20:51:28 +0000180 if (ValEVT.isVector()) {
181 EVT ElemVT = ValEVT.getVectorElementType();
182 if (!ValEVT.isSimple())
183 return false;
184 MVT ValVT = ElemVT.getSimpleVT();
185 bool Res = AssignFn(i, ValVT, ValVT, CCValAssign::Full,
186 OrigArg.Flags, CCInfo);
187 if (!Res)
188 return false;
189 } else {
190 MVT ValVT = ValEVT.getSimpleVT();
191 if (!ValEVT.isSimple())
192 return false;
193 bool Res =
194 AssignFn(i, ValVT, ValVT, CCValAssign::Full, OrigArg.Flags, CCInfo);
195
196 // Fail if we don't know how to handle this type.
197 if (Res)
198 return false;
199 }
Tom Stellardca166212017-01-30 21:56:46 +0000200 }
201
202 Function::const_arg_iterator Arg = F.arg_begin();
Tom Stellard9d8337d2017-08-01 12:38:33 +0000203
Tom Stellardc7709e12018-04-24 20:51:28 +0000204 if (F.getCallingConv() == CallingConv::AMDGPU_VS ||
205 F.getCallingConv() == CallingConv::AMDGPU_PS) {
206 for (unsigned i = 0, OrigArgIdx = 0;
207 OrigArgIdx != NumArgs && i != ArgLocs.size(); ++Arg, ++OrigArgIdx) {
208 if (Skipped.test(OrigArgIdx))
209 continue;
210 CCValAssign &VA = ArgLocs[i++];
211 MRI.addLiveIn(VA.getLocReg(), VRegs[OrigArgIdx]);
Tom Stellard9d8337d2017-08-01 12:38:33 +0000212 MIRBuilder.getMBB().addLiveIn(VA.getLocReg());
Tom Stellardc7709e12018-04-24 20:51:28 +0000213 MIRBuilder.buildCopy(VRegs[OrigArgIdx], VA.getLocReg());
Tom Stellard9d8337d2017-08-01 12:38:33 +0000214 }
215 return true;
216 }
217
Tom Stellardc7709e12018-04-24 20:51:28 +0000218 for (unsigned i = 0; i != ArgLocs.size(); ++i, ++Arg) {
Tom Stellardca166212017-01-30 21:56:46 +0000219 // FIXME: We should be getting DebugInfo from the arguments some how.
220 CCValAssign &VA = ArgLocs[i];
221 lowerParameter(MIRBuilder, Arg->getType(),
222 VA.getLocMemOffset() +
223 Subtarget->getExplicitKernelArgOffset(MF), VRegs[i]);
224 }
225
Tom Stellard000c5af2016-04-14 19:09:28 +0000226 return true;
227}