blob: 7f1b92698b121ad0a48ada6b5bbcc571b8aaa568 [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 Stellard6c814182018-04-30 15:15:23 +000091 // AMDGPU_GS is not supported yet.
92 if (F.getCallingConv() == CallingConv::AMDGPU_GS)
93 return false;
Tom Stellardca166212017-01-30 21:56:46 +000094
95 MachineFunction &MF = MIRBuilder.getMF();
96 const SISubtarget *Subtarget = static_cast<const SISubtarget *>(&MF.getSubtarget());
97 MachineRegisterInfo &MRI = MF.getRegInfo();
98 SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>();
99 const SIRegisterInfo *TRI = MF.getSubtarget<SISubtarget>().getRegisterInfo();
100 const DataLayout &DL = F.getParent()->getDataLayout();
101
102 SmallVector<CCValAssign, 16> ArgLocs;
103 CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
104
105 // FIXME: How should these inputs interact with inreg / custom SGPR inputs?
106 if (Info->hasPrivateSegmentBuffer()) {
107 unsigned PrivateSegmentBufferReg = Info->addPrivateSegmentBuffer(*TRI);
108 MF.addLiveIn(PrivateSegmentBufferReg, &AMDGPU::SReg_128RegClass);
109 CCInfo.AllocateReg(PrivateSegmentBufferReg);
110 }
111
112 if (Info->hasDispatchPtr()) {
113 unsigned DispatchPtrReg = Info->addDispatchPtr(*TRI);
114 // FIXME: Need to add reg as live-in
115 CCInfo.AllocateReg(DispatchPtrReg);
116 }
117
118 if (Info->hasQueuePtr()) {
119 unsigned QueuePtrReg = Info->addQueuePtr(*TRI);
120 // FIXME: Need to add reg as live-in
121 CCInfo.AllocateReg(QueuePtrReg);
122 }
123
124 if (Info->hasKernargSegmentPtr()) {
125 unsigned InputPtrReg = Info->addKernargSegmentPtr(*TRI);
Yaxun Liu0124b542018-02-13 18:00:25 +0000126 const LLT P2 = LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS, 64);
Tom Stellardca166212017-01-30 21:56:46 +0000127 unsigned VReg = MRI.createGenericVirtualRegister(P2);
128 MRI.addLiveIn(InputPtrReg, VReg);
129 MIRBuilder.getMBB().addLiveIn(InputPtrReg);
130 MIRBuilder.buildCopy(VReg, InputPtrReg);
131 CCInfo.AllocateReg(InputPtrReg);
132 }
133
134 if (Info->hasDispatchID()) {
135 unsigned DispatchIDReg = Info->addDispatchID(*TRI);
136 // FIXME: Need to add reg as live-in
137 CCInfo.AllocateReg(DispatchIDReg);
138 }
139
140 if (Info->hasFlatScratchInit()) {
141 unsigned FlatScratchInitReg = Info->addFlatScratchInit(*TRI);
142 // FIXME: Need to add reg as live-in
143 CCInfo.AllocateReg(FlatScratchInitReg);
144 }
145
146 unsigned NumArgs = F.arg_size();
147 Function::const_arg_iterator CurOrigArg = F.arg_begin();
148 const AMDGPUTargetLowering &TLI = *getTLI<AMDGPUTargetLowering>();
Tom Stellardc7709e12018-04-24 20:51:28 +0000149 unsigned PSInputNum = 0;
150 BitVector Skipped(NumArgs);
Tom Stellardca166212017-01-30 21:56:46 +0000151 for (unsigned i = 0; i != NumArgs; ++i, ++CurOrigArg) {
Tom Stellard9d8337d2017-08-01 12:38:33 +0000152 EVT ValEVT = TLI.getValueType(DL, CurOrigArg->getType());
153
154 // We can only hanlde simple value types at the moment.
Tom Stellardca166212017-01-30 21:56:46 +0000155 ISD::ArgFlagsTy Flags;
Tom Stellard9d8337d2017-08-01 12:38:33 +0000156 ArgInfo OrigArg{VRegs[i], CurOrigArg->getType()};
157 setArgFlags(OrigArg, i + 1, DL, F);
Tom Stellardca166212017-01-30 21:56:46 +0000158 Flags.setOrigAlign(DL.getABITypeAlignment(CurOrigArg->getType()));
Tom Stellardc7709e12018-04-24 20:51:28 +0000159
160 if (F.getCallingConv() == CallingConv::AMDGPU_PS &&
161 !OrigArg.Flags.isInReg() && !OrigArg.Flags.isByVal() &&
162 PSInputNum <= 15) {
163 if (CurOrigArg->use_empty() && !Info->isPSInputAllocated(PSInputNum)) {
164 Skipped.set(i);
165 ++PSInputNum;
166 continue;
167 }
168
169 Info->markPSInputAllocated(PSInputNum);
170 if (!CurOrigArg->use_empty())
171 Info->markPSInputEnabled(PSInputNum);
172
173 ++PSInputNum;
174 }
175
Tom Stellardca166212017-01-30 21:56:46 +0000176 CCAssignFn *AssignFn = CCAssignFnForCall(F.getCallingConv(),
177 /*IsVarArg=*/false);
Tom Stellard9d8337d2017-08-01 12:38:33 +0000178
Tom Stellardc7709e12018-04-24 20:51:28 +0000179 if (ValEVT.isVector()) {
180 EVT ElemVT = ValEVT.getVectorElementType();
181 if (!ValEVT.isSimple())
182 return false;
183 MVT ValVT = ElemVT.getSimpleVT();
184 bool Res = AssignFn(i, ValVT, ValVT, CCValAssign::Full,
185 OrigArg.Flags, CCInfo);
186 if (!Res)
187 return false;
188 } else {
189 MVT ValVT = ValEVT.getSimpleVT();
190 if (!ValEVT.isSimple())
191 return false;
192 bool Res =
193 AssignFn(i, ValVT, ValVT, CCValAssign::Full, OrigArg.Flags, CCInfo);
194
195 // Fail if we don't know how to handle this type.
196 if (Res)
197 return false;
198 }
Tom Stellardca166212017-01-30 21:56:46 +0000199 }
200
201 Function::const_arg_iterator Arg = F.arg_begin();
Tom Stellard9d8337d2017-08-01 12:38:33 +0000202
Tom Stellardc7709e12018-04-24 20:51:28 +0000203 if (F.getCallingConv() == CallingConv::AMDGPU_VS ||
204 F.getCallingConv() == CallingConv::AMDGPU_PS) {
205 for (unsigned i = 0, OrigArgIdx = 0;
206 OrigArgIdx != NumArgs && i != ArgLocs.size(); ++Arg, ++OrigArgIdx) {
207 if (Skipped.test(OrigArgIdx))
208 continue;
209 CCValAssign &VA = ArgLocs[i++];
210 MRI.addLiveIn(VA.getLocReg(), VRegs[OrigArgIdx]);
Tom Stellard9d8337d2017-08-01 12:38:33 +0000211 MIRBuilder.getMBB().addLiveIn(VA.getLocReg());
Tom Stellardc7709e12018-04-24 20:51:28 +0000212 MIRBuilder.buildCopy(VRegs[OrigArgIdx], VA.getLocReg());
Tom Stellard9d8337d2017-08-01 12:38:33 +0000213 }
214 return true;
215 }
216
Tom Stellardc7709e12018-04-24 20:51:28 +0000217 for (unsigned i = 0; i != ArgLocs.size(); ++i, ++Arg) {
Tom Stellardca166212017-01-30 21:56:46 +0000218 // FIXME: We should be getting DebugInfo from the arguments some how.
219 CCValAssign &VA = ArgLocs[i];
220 lowerParameter(MIRBuilder, Arg->getType(),
221 VA.getLocMemOffset() +
222 Subtarget->getExplicitKernelArgOffset(MF), VRegs[i]);
223 }
224
Tom Stellard000c5af2016-04-14 19:09:28 +0000225 return true;
226}