1d8ea85acSTom Stellard //===-- llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp - Call lowering -----===//
2000c5af3STom Stellard //
3000c5af3STom Stellard //                     The LLVM Compiler Infrastructure
4000c5af3STom Stellard //
5000c5af3STom Stellard // This file is distributed under the University of Illinois Open Source
6000c5af3STom Stellard // License. See LICENSE.TXT for details.
7000c5af3STom Stellard //
8000c5af3STom Stellard //===----------------------------------------------------------------------===//
9000c5af3STom Stellard ///
10000c5af3STom Stellard /// \file
11000c5af3STom Stellard /// This file implements the lowering of LLVM calls to machine code calls for
12000c5af3STom Stellard /// GlobalISel.
13000c5af3STom Stellard ///
14000c5af3STom Stellard //===----------------------------------------------------------------------===//
15000c5af3STom Stellard 
16000c5af3STom Stellard #include "AMDGPUCallLowering.h"
17ca16621bSTom Stellard #include "AMDGPU.h"
18000c5af3STom Stellard #include "AMDGPUISelLowering.h"
19ca16621bSTom Stellard #include "AMDGPUSubtarget.h"
20ca16621bSTom Stellard #include "SIISelLowering.h"
21ca16621bSTom Stellard #include "SIMachineFunctionInfo.h"
226bda14b3SChandler Carruth #include "SIRegisterInfo.h"
23ca16621bSTom Stellard #include "llvm/CodeGen/CallingConvLower.h"
24000c5af3STom Stellard #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
25000c5af3STom Stellard #include "llvm/CodeGen/MachineInstrBuilder.h"
26000c5af3STom Stellard 
27000c5af3STom Stellard using namespace llvm;
28000c5af3STom Stellard 
29000c5af3STom Stellard AMDGPUCallLowering::AMDGPUCallLowering(const AMDGPUTargetLowering &TLI)
301a14bfa0SYaxun Liu   : CallLowering(&TLI), AMDGPUASI(TLI.getAMDGPUAS()) {
31000c5af3STom Stellard }
32000c5af3STom Stellard 
33000c5af3STom Stellard bool AMDGPUCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
34000c5af3STom Stellard                                      const Value *Val, unsigned VReg) const {
35ca16621bSTom Stellard   MIRBuilder.buildInstr(AMDGPU::S_ENDPGM);
36000c5af3STom Stellard   return true;
37000c5af3STom Stellard }
38000c5af3STom Stellard 
39ca16621bSTom Stellard unsigned AMDGPUCallLowering::lowerParameterPtr(MachineIRBuilder &MIRBuilder,
40ca16621bSTom Stellard                                                Type *ParamTy,
41ca16621bSTom Stellard                                                unsigned Offset) const {
42ca16621bSTom Stellard 
43ca16621bSTom Stellard   MachineFunction &MF = MIRBuilder.getMF();
448623e8d8SMatt Arsenault   const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
45ca16621bSTom Stellard   MachineRegisterInfo &MRI = MF.getRegInfo();
46f1caa283SMatthias Braun   const Function &F = MF.getFunction();
47ca16621bSTom Stellard   const DataLayout &DL = F.getParent()->getDataLayout();
481a14bfa0SYaxun Liu   PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUASI.CONSTANT_ADDRESS);
4952b4ce72SDaniel Sanders   LLT PtrType = getLLTForType(*PtrTy, DL);
50ca16621bSTom Stellard   unsigned DstReg = MRI.createGenericVirtualRegister(PtrType);
51ca16621bSTom Stellard   unsigned KernArgSegmentPtr =
528623e8d8SMatt Arsenault     MFI->getPreloadedReg(AMDGPUFunctionArgInfo::KERNARG_SEGMENT_PTR);
53ca16621bSTom Stellard   unsigned KernArgSegmentVReg = MRI.getLiveInVirtReg(KernArgSegmentPtr);
54ca16621bSTom Stellard 
55ca16621bSTom Stellard   unsigned OffsetReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
56ca16621bSTom Stellard   MIRBuilder.buildConstant(OffsetReg, Offset);
57ca16621bSTom Stellard 
58ca16621bSTom Stellard   MIRBuilder.buildGEP(DstReg, KernArgSegmentVReg, OffsetReg);
59ca16621bSTom Stellard 
60ca16621bSTom Stellard   return DstReg;
61ca16621bSTom Stellard }
62ca16621bSTom Stellard 
63ca16621bSTom Stellard void AMDGPUCallLowering::lowerParameter(MachineIRBuilder &MIRBuilder,
64ca16621bSTom Stellard                                         Type *ParamTy, unsigned Offset,
65ca16621bSTom Stellard                                         unsigned DstReg) const {
66ca16621bSTom Stellard   MachineFunction &MF = MIRBuilder.getMF();
67f1caa283SMatthias Braun   const Function &F = MF.getFunction();
68ca16621bSTom Stellard   const DataLayout &DL = F.getParent()->getDataLayout();
691a14bfa0SYaxun Liu   PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUASI.CONSTANT_ADDRESS);
70ca16621bSTom Stellard   MachinePointerInfo PtrInfo(UndefValue::get(PtrTy));
71ca16621bSTom Stellard   unsigned TypeSize = DL.getTypeStoreSize(ParamTy);
72ca16621bSTom Stellard   unsigned Align = DL.getABITypeAlignment(ParamTy);
73ca16621bSTom Stellard   unsigned PtrReg = lowerParameterPtr(MIRBuilder, ParamTy, Offset);
74ca16621bSTom Stellard 
75ca16621bSTom Stellard   MachineMemOperand *MMO =
76ca16621bSTom Stellard       MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad |
77ca16621bSTom Stellard                                        MachineMemOperand::MONonTemporal |
78ca16621bSTom Stellard                                        MachineMemOperand::MOInvariant,
79ca16621bSTom Stellard                                        TypeSize, Align);
80ca16621bSTom Stellard 
81ca16621bSTom Stellard   MIRBuilder.buildLoad(DstReg, PtrReg, *MMO);
82ca16621bSTom Stellard }
83ca16621bSTom Stellard 
84862758ecSTim Northover bool AMDGPUCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
85862758ecSTim Northover                                               const Function &F,
86406024a1STim Northover                                               ArrayRef<unsigned> VRegs) const {
87ca16621bSTom Stellard 
88ca16621bSTom Stellard   MachineFunction &MF = MIRBuilder.getMF();
89ca16621bSTom Stellard   const SISubtarget *Subtarget = static_cast<const SISubtarget *>(&MF.getSubtarget());
90ca16621bSTom Stellard   MachineRegisterInfo &MRI = MF.getRegInfo();
91ca16621bSTom Stellard   SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>();
92ca16621bSTom Stellard   const SIRegisterInfo *TRI = MF.getSubtarget<SISubtarget>().getRegisterInfo();
93ca16621bSTom Stellard   const DataLayout &DL = F.getParent()->getDataLayout();
94ca16621bSTom Stellard 
95ca16621bSTom Stellard   SmallVector<CCValAssign, 16> ArgLocs;
96ca16621bSTom Stellard   CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
97ca16621bSTom Stellard 
98ca16621bSTom Stellard   // FIXME: How should these inputs interact with inreg / custom SGPR inputs?
99ca16621bSTom Stellard   if (Info->hasPrivateSegmentBuffer()) {
100ca16621bSTom Stellard     unsigned PrivateSegmentBufferReg = Info->addPrivateSegmentBuffer(*TRI);
101ca16621bSTom Stellard     MF.addLiveIn(PrivateSegmentBufferReg, &AMDGPU::SReg_128RegClass);
102ca16621bSTom Stellard     CCInfo.AllocateReg(PrivateSegmentBufferReg);
103ca16621bSTom Stellard   }
104ca16621bSTom Stellard 
105ca16621bSTom Stellard   if (Info->hasDispatchPtr()) {
106ca16621bSTom Stellard     unsigned DispatchPtrReg = Info->addDispatchPtr(*TRI);
107ca16621bSTom Stellard     // FIXME: Need to add reg as live-in
108ca16621bSTom Stellard     CCInfo.AllocateReg(DispatchPtrReg);
109ca16621bSTom Stellard   }
110ca16621bSTom Stellard 
111ca16621bSTom Stellard   if (Info->hasQueuePtr()) {
112ca16621bSTom Stellard     unsigned QueuePtrReg = Info->addQueuePtr(*TRI);
113ca16621bSTom Stellard     // FIXME: Need to add reg as live-in
114ca16621bSTom Stellard     CCInfo.AllocateReg(QueuePtrReg);
115ca16621bSTom Stellard   }
116ca16621bSTom Stellard 
117ca16621bSTom Stellard   if (Info->hasKernargSegmentPtr()) {
118ca16621bSTom Stellard     unsigned InputPtrReg = Info->addKernargSegmentPtr(*TRI);
119*0124b548SYaxun Liu     const LLT P2 = LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS, 64);
120ca16621bSTom Stellard     unsigned VReg = MRI.createGenericVirtualRegister(P2);
121ca16621bSTom Stellard     MRI.addLiveIn(InputPtrReg, VReg);
122ca16621bSTom Stellard     MIRBuilder.getMBB().addLiveIn(InputPtrReg);
123ca16621bSTom Stellard     MIRBuilder.buildCopy(VReg, InputPtrReg);
124ca16621bSTom Stellard     CCInfo.AllocateReg(InputPtrReg);
125ca16621bSTom Stellard   }
126ca16621bSTom Stellard 
127ca16621bSTom Stellard   if (Info->hasDispatchID()) {
128ca16621bSTom Stellard     unsigned DispatchIDReg = Info->addDispatchID(*TRI);
129ca16621bSTom Stellard     // FIXME: Need to add reg as live-in
130ca16621bSTom Stellard     CCInfo.AllocateReg(DispatchIDReg);
131ca16621bSTom Stellard   }
132ca16621bSTom Stellard 
133ca16621bSTom Stellard   if (Info->hasFlatScratchInit()) {
134ca16621bSTom Stellard     unsigned FlatScratchInitReg = Info->addFlatScratchInit(*TRI);
135ca16621bSTom Stellard     // FIXME: Need to add reg as live-in
136ca16621bSTom Stellard     CCInfo.AllocateReg(FlatScratchInitReg);
137ca16621bSTom Stellard   }
138ca16621bSTom Stellard 
139ca16621bSTom Stellard   unsigned NumArgs = F.arg_size();
140ca16621bSTom Stellard   Function::const_arg_iterator CurOrigArg = F.arg_begin();
141ca16621bSTom Stellard   const AMDGPUTargetLowering &TLI = *getTLI<AMDGPUTargetLowering>();
142ca16621bSTom Stellard   for (unsigned i = 0; i != NumArgs; ++i, ++CurOrigArg) {
1439d8337d8STom Stellard     EVT ValEVT = TLI.getValueType(DL, CurOrigArg->getType());
1449d8337d8STom Stellard 
1459d8337d8STom Stellard     // We can only hanlde simple value types at the moment.
1469d8337d8STom Stellard     if (!ValEVT.isSimple())
1479d8337d8STom Stellard       return false;
1489d8337d8STom Stellard     MVT ValVT = ValEVT.getSimpleVT();
149ca16621bSTom Stellard     ISD::ArgFlagsTy Flags;
1509d8337d8STom Stellard     ArgInfo OrigArg{VRegs[i], CurOrigArg->getType()};
1519d8337d8STom Stellard     setArgFlags(OrigArg, i + 1, DL, F);
152ca16621bSTom Stellard     Flags.setOrigAlign(DL.getABITypeAlignment(CurOrigArg->getType()));
153ca16621bSTom Stellard     CCAssignFn *AssignFn = CCAssignFnForCall(F.getCallingConv(),
154ca16621bSTom Stellard                                              /*IsVarArg=*/false);
155ca16621bSTom Stellard     bool Res =
1569d8337d8STom Stellard         AssignFn(i, ValVT, ValVT, CCValAssign::Full, OrigArg.Flags, CCInfo);
1579d8337d8STom Stellard 
1589d8337d8STom Stellard     // Fail if we don't know how to handle this type.
1599d8337d8STom Stellard     if (Res)
1609d8337d8STom Stellard       return false;
161ca16621bSTom Stellard   }
162ca16621bSTom Stellard 
163ca16621bSTom Stellard   Function::const_arg_iterator Arg = F.arg_begin();
1649d8337d8STom Stellard 
1659d8337d8STom Stellard   if (F.getCallingConv() == CallingConv::AMDGPU_VS) {
1669d8337d8STom Stellard     for (unsigned i = 0; i != NumArgs; ++i, ++Arg) {
1679d8337d8STom Stellard       CCValAssign &VA = ArgLocs[i];
1689d8337d8STom Stellard       MRI.addLiveIn(VA.getLocReg(), VRegs[i]);
1699d8337d8STom Stellard       MIRBuilder.getMBB().addLiveIn(VA.getLocReg());
1709d8337d8STom Stellard       MIRBuilder.buildCopy(VRegs[i], VA.getLocReg());
1719d8337d8STom Stellard     }
1729d8337d8STom Stellard     return true;
1739d8337d8STom Stellard   }
1749d8337d8STom Stellard 
175ca16621bSTom Stellard   for (unsigned i = 0; i != NumArgs; ++i, ++Arg) {
176ca16621bSTom Stellard     // FIXME: We should be getting DebugInfo from the arguments some how.
177ca16621bSTom Stellard     CCValAssign &VA = ArgLocs[i];
178ca16621bSTom Stellard     lowerParameter(MIRBuilder, Arg->getType(),
179ca16621bSTom Stellard                    VA.getLocMemOffset() +
180ca16621bSTom Stellard                    Subtarget->getExplicitKernelArgOffset(MF), VRegs[i]);
181ca16621bSTom Stellard   }
182ca16621bSTom Stellard 
183000c5af3STom Stellard   return true;
184000c5af3STom Stellard }
185