blob: 515cc07dd4498f65a552f03530a2f6555466ed16 [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
29#ifndef LLVM_BUILD_GLOBAL_ISEL
30#error "This shouldn't be built without GISel"
31#endif
32
33AMDGPUCallLowering::AMDGPUCallLowering(const AMDGPUTargetLowering &TLI)
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000034 : CallLowering(&TLI), AMDGPUASI(TLI.getAMDGPUAS()) {
Tom Stellard000c5af2016-04-14 19:09:28 +000035}
36
37bool AMDGPUCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
Tom Stellardca166212017-01-30 21:56:46 +000038 const Value *Val, unsigned VReg) const {
39 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();
48 const SIRegisterInfo *TRI = MF.getSubtarget<SISubtarget>().getRegisterInfo();
49 MachineRegisterInfo &MRI = MF.getRegInfo();
50 const Function &F = *MF.getFunction();
51 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 =
56 TRI->getPreloadedValue(MF, SIRegisterInfo::KERNARG_SEGMENT_PTR);
57 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();
71 const Function &F = *MF.getFunction();
72 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 Stellardca166212017-01-30 21:56:46 +000091
92 MachineFunction &MF = MIRBuilder.getMF();
93 const SISubtarget *Subtarget = static_cast<const SISubtarget *>(&MF.getSubtarget());
94 MachineRegisterInfo &MRI = MF.getRegInfo();
95 SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>();
96 const SIRegisterInfo *TRI = MF.getSubtarget<SISubtarget>().getRegisterInfo();
97 const DataLayout &DL = F.getParent()->getDataLayout();
98
99 SmallVector<CCValAssign, 16> ArgLocs;
100 CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
101
102 // FIXME: How should these inputs interact with inreg / custom SGPR inputs?
103 if (Info->hasPrivateSegmentBuffer()) {
104 unsigned PrivateSegmentBufferReg = Info->addPrivateSegmentBuffer(*TRI);
105 MF.addLiveIn(PrivateSegmentBufferReg, &AMDGPU::SReg_128RegClass);
106 CCInfo.AllocateReg(PrivateSegmentBufferReg);
107 }
108
109 if (Info->hasDispatchPtr()) {
110 unsigned DispatchPtrReg = Info->addDispatchPtr(*TRI);
111 // FIXME: Need to add reg as live-in
112 CCInfo.AllocateReg(DispatchPtrReg);
113 }
114
115 if (Info->hasQueuePtr()) {
116 unsigned QueuePtrReg = Info->addQueuePtr(*TRI);
117 // FIXME: Need to add reg as live-in
118 CCInfo.AllocateReg(QueuePtrReg);
119 }
120
121 if (Info->hasKernargSegmentPtr()) {
122 unsigned InputPtrReg = Info->addKernargSegmentPtr(*TRI);
123 const LLT P2 = LLT::pointer(2, 64);
124 unsigned VReg = MRI.createGenericVirtualRegister(P2);
125 MRI.addLiveIn(InputPtrReg, VReg);
126 MIRBuilder.getMBB().addLiveIn(InputPtrReg);
127 MIRBuilder.buildCopy(VReg, InputPtrReg);
128 CCInfo.AllocateReg(InputPtrReg);
129 }
130
131 if (Info->hasDispatchID()) {
132 unsigned DispatchIDReg = Info->addDispatchID(*TRI);
133 // FIXME: Need to add reg as live-in
134 CCInfo.AllocateReg(DispatchIDReg);
135 }
136
137 if (Info->hasFlatScratchInit()) {
138 unsigned FlatScratchInitReg = Info->addFlatScratchInit(*TRI);
139 // FIXME: Need to add reg as live-in
140 CCInfo.AllocateReg(FlatScratchInitReg);
141 }
142
143 unsigned NumArgs = F.arg_size();
144 Function::const_arg_iterator CurOrigArg = F.arg_begin();
145 const AMDGPUTargetLowering &TLI = *getTLI<AMDGPUTargetLowering>();
146 for (unsigned i = 0; i != NumArgs; ++i, ++CurOrigArg) {
Tom Stellardca166212017-01-30 21:56:46 +0000147 MVT ValVT = TLI.getValueType(DL, CurOrigArg->getType()).getSimpleVT();
148 ISD::ArgFlagsTy Flags;
149 Flags.setOrigAlign(DL.getABITypeAlignment(CurOrigArg->getType()));
150 CCAssignFn *AssignFn = CCAssignFnForCall(F.getCallingConv(),
151 /*IsVarArg=*/false);
152 bool Res =
153 AssignFn(i, ValVT, ValVT, CCValAssign::Full, Flags, CCInfo);
154 assert(!Res && "Call operand has unhandled type");
155 (void)Res;
156 }
157
158 Function::const_arg_iterator Arg = F.arg_begin();
159 for (unsigned i = 0; i != NumArgs; ++i, ++Arg) {
160 // FIXME: We should be getting DebugInfo from the arguments some how.
161 CCValAssign &VA = ArgLocs[i];
162 lowerParameter(MIRBuilder, Arg->getType(),
163 VA.getLocMemOffset() +
164 Subtarget->getExplicitKernelArgOffset(MF), VRegs[i]);
165 }
166
Tom Stellard000c5af2016-04-14 19:09:28 +0000167 return true;
168}