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 "SIRegisterInfo.h"
22ca16621bSTom Stellard #include "SIMachineFunctionInfo.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 #ifndef LLVM_BUILD_GLOBAL_ISEL
30000c5af3STom Stellard #error "This shouldn't be built without GISel"
31000c5af3STom Stellard #endif
32000c5af3STom Stellard 
33000c5af3STom Stellard AMDGPUCallLowering::AMDGPUCallLowering(const AMDGPUTargetLowering &TLI)
34000c5af3STom Stellard   : CallLowering(&TLI) {
35000c5af3STom Stellard }
36000c5af3STom Stellard 
37000c5af3STom Stellard bool AMDGPUCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
38000c5af3STom Stellard                                      const Value *Val, unsigned VReg) const {
39ca16621bSTom Stellard   MIRBuilder.buildInstr(AMDGPU::S_ENDPGM);
40000c5af3STom Stellard   return true;
41000c5af3STom Stellard }
42000c5af3STom Stellard 
43ca16621bSTom Stellard unsigned AMDGPUCallLowering::lowerParameterPtr(MachineIRBuilder &MIRBuilder,
44ca16621bSTom Stellard                                                Type *ParamTy,
45ca16621bSTom Stellard                                                unsigned Offset) const {
46ca16621bSTom Stellard 
47ca16621bSTom Stellard   MachineFunction &MF = MIRBuilder.getMF();
48ca16621bSTom Stellard   const SIRegisterInfo *TRI = MF.getSubtarget<SISubtarget>().getRegisterInfo();
49ca16621bSTom Stellard   MachineRegisterInfo &MRI = MF.getRegInfo();
50ca16621bSTom Stellard   const Function &F = *MF.getFunction();
51ca16621bSTom Stellard   const DataLayout &DL = F.getParent()->getDataLayout();
52ca16621bSTom Stellard   PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUAS::CONSTANT_ADDRESS);
53*52b4ce72SDaniel Sanders   LLT PtrType = getLLTForType(*PtrTy, DL);
54ca16621bSTom Stellard   unsigned DstReg = MRI.createGenericVirtualRegister(PtrType);
55ca16621bSTom Stellard   unsigned KernArgSegmentPtr =
56ca16621bSTom Stellard       TRI->getPreloadedValue(MF, SIRegisterInfo::KERNARG_SEGMENT_PTR);
57ca16621bSTom Stellard   unsigned KernArgSegmentVReg = MRI.getLiveInVirtReg(KernArgSegmentPtr);
58ca16621bSTom Stellard 
59ca16621bSTom Stellard   unsigned OffsetReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
60ca16621bSTom Stellard   MIRBuilder.buildConstant(OffsetReg, Offset);
61ca16621bSTom Stellard 
62ca16621bSTom Stellard   MIRBuilder.buildGEP(DstReg, KernArgSegmentVReg, OffsetReg);
63ca16621bSTom Stellard 
64ca16621bSTom Stellard   return DstReg;
65ca16621bSTom Stellard }
66ca16621bSTom Stellard 
67ca16621bSTom Stellard void AMDGPUCallLowering::lowerParameter(MachineIRBuilder &MIRBuilder,
68ca16621bSTom Stellard                                         Type *ParamTy, unsigned Offset,
69ca16621bSTom Stellard                                         unsigned DstReg) const {
70ca16621bSTom Stellard   MachineFunction &MF = MIRBuilder.getMF();
71ca16621bSTom Stellard   const Function &F = *MF.getFunction();
72ca16621bSTom Stellard   const DataLayout &DL = F.getParent()->getDataLayout();
73ca16621bSTom Stellard   PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUAS::CONSTANT_ADDRESS);
74ca16621bSTom Stellard   MachinePointerInfo PtrInfo(UndefValue::get(PtrTy));
75ca16621bSTom Stellard   unsigned TypeSize = DL.getTypeStoreSize(ParamTy);
76ca16621bSTom Stellard   unsigned Align = DL.getABITypeAlignment(ParamTy);
77ca16621bSTom Stellard   unsigned PtrReg = lowerParameterPtr(MIRBuilder, ParamTy, Offset);
78ca16621bSTom Stellard 
79ca16621bSTom Stellard   MachineMemOperand *MMO =
80ca16621bSTom Stellard       MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad |
81ca16621bSTom Stellard                                        MachineMemOperand::MONonTemporal |
82ca16621bSTom Stellard                                        MachineMemOperand::MOInvariant,
83ca16621bSTom Stellard                                        TypeSize, Align);
84ca16621bSTom Stellard 
85ca16621bSTom Stellard   MIRBuilder.buildLoad(DstReg, PtrReg, *MMO);
86ca16621bSTom Stellard }
87ca16621bSTom Stellard 
88862758ecSTim Northover bool AMDGPUCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
89862758ecSTim Northover                                               const Function &F,
90406024a1STim Northover                                               ArrayRef<unsigned> VRegs) const {
91ca16621bSTom Stellard 
92ca16621bSTom Stellard   MachineFunction &MF = MIRBuilder.getMF();
93ca16621bSTom Stellard   const SISubtarget *Subtarget = static_cast<const SISubtarget *>(&MF.getSubtarget());
94ca16621bSTom Stellard   MachineRegisterInfo &MRI = MF.getRegInfo();
95ca16621bSTom Stellard   SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>();
96ca16621bSTom Stellard   const SIRegisterInfo *TRI = MF.getSubtarget<SISubtarget>().getRegisterInfo();
97ca16621bSTom Stellard   const DataLayout &DL = F.getParent()->getDataLayout();
98ca16621bSTom Stellard 
99ca16621bSTom Stellard   SmallVector<CCValAssign, 16> ArgLocs;
100ca16621bSTom Stellard   CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
101ca16621bSTom Stellard 
102ca16621bSTom Stellard   // FIXME: How should these inputs interact with inreg / custom SGPR inputs?
103ca16621bSTom Stellard   if (Info->hasPrivateSegmentBuffer()) {
104ca16621bSTom Stellard     unsigned PrivateSegmentBufferReg = Info->addPrivateSegmentBuffer(*TRI);
105ca16621bSTom Stellard     MF.addLiveIn(PrivateSegmentBufferReg, &AMDGPU::SReg_128RegClass);
106ca16621bSTom Stellard     CCInfo.AllocateReg(PrivateSegmentBufferReg);
107ca16621bSTom Stellard   }
108ca16621bSTom Stellard 
109ca16621bSTom Stellard   if (Info->hasDispatchPtr()) {
110ca16621bSTom Stellard     unsigned DispatchPtrReg = Info->addDispatchPtr(*TRI);
111ca16621bSTom Stellard     // FIXME: Need to add reg as live-in
112ca16621bSTom Stellard     CCInfo.AllocateReg(DispatchPtrReg);
113ca16621bSTom Stellard   }
114ca16621bSTom Stellard 
115ca16621bSTom Stellard   if (Info->hasQueuePtr()) {
116ca16621bSTom Stellard     unsigned QueuePtrReg = Info->addQueuePtr(*TRI);
117ca16621bSTom Stellard     // FIXME: Need to add reg as live-in
118ca16621bSTom Stellard     CCInfo.AllocateReg(QueuePtrReg);
119ca16621bSTom Stellard   }
120ca16621bSTom Stellard 
121ca16621bSTom Stellard   if (Info->hasKernargSegmentPtr()) {
122ca16621bSTom Stellard     unsigned InputPtrReg = Info->addKernargSegmentPtr(*TRI);
123ca16621bSTom Stellard     const LLT P2 = LLT::pointer(2, 64);
124ca16621bSTom Stellard     unsigned VReg = MRI.createGenericVirtualRegister(P2);
125ca16621bSTom Stellard     MRI.addLiveIn(InputPtrReg, VReg);
126ca16621bSTom Stellard     MIRBuilder.getMBB().addLiveIn(InputPtrReg);
127ca16621bSTom Stellard     MIRBuilder.buildCopy(VReg, InputPtrReg);
128ca16621bSTom Stellard     CCInfo.AllocateReg(InputPtrReg);
129ca16621bSTom Stellard   }
130ca16621bSTom Stellard 
131ca16621bSTom Stellard   if (Info->hasDispatchID()) {
132ca16621bSTom Stellard     unsigned DispatchIDReg = Info->addDispatchID(*TRI);
133ca16621bSTom Stellard     // FIXME: Need to add reg as live-in
134ca16621bSTom Stellard     CCInfo.AllocateReg(DispatchIDReg);
135ca16621bSTom Stellard   }
136ca16621bSTom Stellard 
137ca16621bSTom Stellard   if (Info->hasFlatScratchInit()) {
138ca16621bSTom Stellard     unsigned FlatScratchInitReg = Info->addFlatScratchInit(*TRI);
139ca16621bSTom Stellard     // FIXME: Need to add reg as live-in
140ca16621bSTom Stellard     CCInfo.AllocateReg(FlatScratchInitReg);
141ca16621bSTom Stellard   }
142ca16621bSTom Stellard 
143ca16621bSTom Stellard   unsigned NumArgs = F.arg_size();
144ca16621bSTom Stellard   Function::const_arg_iterator CurOrigArg = F.arg_begin();
145ca16621bSTom Stellard   const AMDGPUTargetLowering &TLI = *getTLI<AMDGPUTargetLowering>();
146ca16621bSTom Stellard   for (unsigned i = 0; i != NumArgs; ++i, ++CurOrigArg) {
147ca16621bSTom Stellard     MVT ValVT = TLI.getValueType(DL, CurOrigArg->getType()).getSimpleVT();
148ca16621bSTom Stellard     ISD::ArgFlagsTy Flags;
149ca16621bSTom Stellard     Flags.setOrigAlign(DL.getABITypeAlignment(CurOrigArg->getType()));
150ca16621bSTom Stellard     CCAssignFn *AssignFn = CCAssignFnForCall(F.getCallingConv(),
151ca16621bSTom Stellard                                              /*IsVarArg=*/false);
152ca16621bSTom Stellard     bool Res =
153ca16621bSTom Stellard         AssignFn(i, ValVT, ValVT, CCValAssign::Full, Flags, CCInfo);
154ca16621bSTom Stellard     assert(!Res && "Call operand has unhandled type");
155ca16621bSTom Stellard     (void)Res;
156ca16621bSTom Stellard   }
157ca16621bSTom Stellard 
158ca16621bSTom Stellard   Function::const_arg_iterator Arg = F.arg_begin();
159ca16621bSTom Stellard   for (unsigned i = 0; i != NumArgs; ++i, ++Arg) {
160ca16621bSTom Stellard     // FIXME: We should be getting DebugInfo from the arguments some how.
161ca16621bSTom Stellard     CCValAssign &VA = ArgLocs[i];
162ca16621bSTom Stellard     lowerParameter(MIRBuilder, Arg->getType(),
163ca16621bSTom Stellard                    VA.getLocMemOffset() +
164ca16621bSTom Stellard                    Subtarget->getExplicitKernelArgOffset(MF), VRegs[i]);
165ca16621bSTom Stellard   }
166ca16621bSTom Stellard 
167000c5af3STom Stellard   return true;
168000c5af3STom Stellard }
169