blob: 5a913873193492bfaa4c9bd65be8f4bd0b993333 [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 {
35 MIRBuilder.buildInstr(AMDGPU::S_ENDPGM);
Tom Stellard000c5af2016-04-14 19:09:28 +000036 return true;
37}
38
Tom Stellardca166212017-01-30 21:56:46 +000039unsigned AMDGPUCallLowering::lowerParameterPtr(MachineIRBuilder &MIRBuilder,
40 Type *ParamTy,
41 unsigned Offset) const {
42
43 MachineFunction &MF = MIRBuilder.getMF();
Matt Arsenault8623e8d2017-08-03 23:00:29 +000044 const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
Tom Stellardca166212017-01-30 21:56:46 +000045 MachineRegisterInfo &MRI = MF.getRegInfo();
Matthias Braunf1caa282017-12-15 22:22:58 +000046 const Function &F = MF.getFunction();
Tom Stellardca166212017-01-30 21:56:46 +000047 const DataLayout &DL = F.getParent()->getDataLayout();
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000048 PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUASI.CONSTANT_ADDRESS);
Daniel Sanders52b4ce72017-03-07 23:20:35 +000049 LLT PtrType = getLLTForType(*PtrTy, DL);
Tom Stellardca166212017-01-30 21:56:46 +000050 unsigned DstReg = MRI.createGenericVirtualRegister(PtrType);
51 unsigned KernArgSegmentPtr =
Matt Arsenault8623e8d2017-08-03 23:00:29 +000052 MFI->getPreloadedReg(AMDGPUFunctionArgInfo::KERNARG_SEGMENT_PTR);
Tom Stellardca166212017-01-30 21:56:46 +000053 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
63void AMDGPUCallLowering::lowerParameter(MachineIRBuilder &MIRBuilder,
64 Type *ParamTy, unsigned Offset,
65 unsigned DstReg) const {
66 MachineFunction &MF = MIRBuilder.getMF();
Matthias Braunf1caa282017-12-15 22:22:58 +000067 const Function &F = MF.getFunction();
Tom Stellardca166212017-01-30 21:56:46 +000068 const DataLayout &DL = F.getParent()->getDataLayout();
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000069 PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUASI.CONSTANT_ADDRESS);
Tom Stellardca166212017-01-30 21:56:46 +000070 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 =
76 MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad |
77 MachineMemOperand::MONonTemporal |
78 MachineMemOperand::MOInvariant,
79 TypeSize, Align);
80
81 MIRBuilder.buildLoad(DstReg, PtrReg, *MMO);
82}
83
Tim Northover862758ec2016-09-21 12:57:35 +000084bool AMDGPUCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
85 const Function &F,
86 ArrayRef<unsigned> VRegs) const {
Tom Stellardca166212017-01-30 21:56:46 +000087
88 MachineFunction &MF = MIRBuilder.getMF();
89 const SISubtarget *Subtarget = static_cast<const SISubtarget *>(&MF.getSubtarget());
90 MachineRegisterInfo &MRI = MF.getRegInfo();
91 SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>();
92 const SIRegisterInfo *TRI = MF.getSubtarget<SISubtarget>().getRegisterInfo();
93 const DataLayout &DL = F.getParent()->getDataLayout();
94
95 SmallVector<CCValAssign, 16> ArgLocs;
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) {
Tom Stellard9d8337d2017-08-01 12:38:33 +0000143 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();
Tom Stellardca166212017-01-30 21:56:46 +0000149 ISD::ArgFlagsTy Flags;
Tom Stellard9d8337d2017-08-01 12:38:33 +0000150 ArgInfo OrigArg{VRegs[i], CurOrigArg->getType()};
151 setArgFlags(OrigArg, i + 1, DL, F);
Tom Stellardca166212017-01-30 21:56:46 +0000152 Flags.setOrigAlign(DL.getABITypeAlignment(CurOrigArg->getType()));
153 CCAssignFn *AssignFn = CCAssignFnForCall(F.getCallingConv(),
154 /*IsVarArg=*/false);
155 bool Res =
Tom Stellard9d8337d2017-08-01 12:38:33 +0000156 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;
Tom Stellardca166212017-01-30 21:56:46 +0000161 }
162
163 Function::const_arg_iterator Arg = F.arg_begin();
Tom Stellard9d8337d2017-08-01 12:38:33 +0000164
165 if (F.getCallingConv() == CallingConv::AMDGPU_VS) {
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
Tom Stellardca166212017-01-30 21:56:46 +0000175 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
Tom Stellard000c5af2016-04-14 19:09:28 +0000183 return true;
184}