]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp
Merge ^/head r317216 through r317280.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / AMDGPU / AMDGPUCallLowering.cpp
1 //===-- llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp - Call lowering -----===//
2 //
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"
17 #include "AMDGPU.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"
26
27 using namespace llvm;
28
29 #ifndef LLVM_BUILD_GLOBAL_ISEL
30 #error "This shouldn't be built without GISel"
31 #endif
32
33 AMDGPUCallLowering::AMDGPUCallLowering(const AMDGPUTargetLowering &TLI)
34   : CallLowering(&TLI), AMDGPUASI(TLI.getAMDGPUAS()) {
35 }
36
37 bool AMDGPUCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
38                                      const Value *Val, unsigned VReg) const {
39   MIRBuilder.buildInstr(AMDGPU::S_ENDPGM);
40   return true;
41 }
42
43 unsigned 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();
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);
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
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);
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
88 bool AMDGPUCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
89                                               const Function &F,
90                                               ArrayRef<unsigned> VRegs) const {
91
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) {
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(),
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
167   return true;
168 }