1 //===-- llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp - Call lowering -----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// This file implements the lowering of LLVM calls to machine code calls for
14 //===----------------------------------------------------------------------===//
16 #include "AMDGPUCallLowering.h"
18 #include "AMDGPUISelLowering.h"
19 #include "AMDGPUSubtarget.h"
20 #include "SIISelLowering.h"
21 #include "SIRegisterInfo.h"
22 #include "SIMachineFunctionInfo.h"
23 #include "llvm/CodeGen/CallingConvLower.h"
24 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
25 #include "llvm/CodeGen/MachineInstrBuilder.h"
29 #ifndef LLVM_BUILD_GLOBAL_ISEL
30 #error "This shouldn't be built without GISel"
33 AMDGPUCallLowering::AMDGPUCallLowering(const AMDGPUTargetLowering &TLI)
34 : CallLowering(&TLI), AMDGPUASI(TLI.getAMDGPUAS()) {
37 bool AMDGPUCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
38 const Value *Val, unsigned VReg) const {
39 MIRBuilder.buildInstr(AMDGPU::S_ENDPGM);
43 unsigned AMDGPUCallLowering::lowerParameterPtr(MachineIRBuilder &MIRBuilder,
45 unsigned Offset) const {
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();
52 PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUASI.CONSTANT_ADDRESS);
53 LLT PtrType = getLLTForType(*PtrTy, DL);
54 unsigned DstReg = MRI.createGenericVirtualRegister(PtrType);
55 unsigned KernArgSegmentPtr =
56 TRI->getPreloadedValue(MF, SIRegisterInfo::KERNARG_SEGMENT_PTR);
57 unsigned KernArgSegmentVReg = MRI.getLiveInVirtReg(KernArgSegmentPtr);
59 unsigned OffsetReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
60 MIRBuilder.buildConstant(OffsetReg, Offset);
62 MIRBuilder.buildGEP(DstReg, KernArgSegmentVReg, OffsetReg);
67 void 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();
73 PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUASI.CONSTANT_ADDRESS);
74 MachinePointerInfo PtrInfo(UndefValue::get(PtrTy));
75 unsigned TypeSize = DL.getTypeStoreSize(ParamTy);
76 unsigned Align = DL.getABITypeAlignment(ParamTy);
77 unsigned PtrReg = lowerParameterPtr(MIRBuilder, ParamTy, Offset);
79 MachineMemOperand *MMO =
80 MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad |
81 MachineMemOperand::MONonTemporal |
82 MachineMemOperand::MOInvariant,
85 MIRBuilder.buildLoad(DstReg, PtrReg, *MMO);
88 bool AMDGPUCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
90 ArrayRef<unsigned> VRegs) const {
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();
99 SmallVector<CCValAssign, 16> ArgLocs;
100 CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
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);
109 if (Info->hasDispatchPtr()) {
110 unsigned DispatchPtrReg = Info->addDispatchPtr(*TRI);
111 // FIXME: Need to add reg as live-in
112 CCInfo.AllocateReg(DispatchPtrReg);
115 if (Info->hasQueuePtr()) {
116 unsigned QueuePtrReg = Info->addQueuePtr(*TRI);
117 // FIXME: Need to add reg as live-in
118 CCInfo.AllocateReg(QueuePtrReg);
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);
131 if (Info->hasDispatchID()) {
132 unsigned DispatchIDReg = Info->addDispatchID(*TRI);
133 // FIXME: Need to add reg as live-in
134 CCInfo.AllocateReg(DispatchIDReg);
137 if (Info->hasFlatScratchInit()) {
138 unsigned FlatScratchInitReg = Info->addFlatScratchInit(*TRI);
139 // FIXME: Need to add reg as live-in
140 CCInfo.AllocateReg(FlatScratchInitReg);
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) {
147 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(),
153 AssignFn(i, ValVT, ValVT, CCValAssign::Full, Flags, CCInfo);
154 assert(!Res && "Call operand has unhandled type");
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]);