/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp
Line | Count | Source (jump to first uncovered line) |
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 "SIMachineFunctionInfo.h" |
22 | | #include "SIRegisterInfo.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 | | AMDGPUCallLowering::AMDGPUCallLowering(const AMDGPUTargetLowering &TLI) |
30 | 1.81k | : CallLowering(&TLI), AMDGPUASI(TLI.getAMDGPUAS()) { |
31 | 1.81k | } |
32 | | |
33 | | bool AMDGPUCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, |
34 | 20 | const Value *Val, unsigned VReg) const { |
35 | 20 | MIRBuilder.buildInstr(AMDGPU::S_ENDPGM); |
36 | 20 | return true; |
37 | 20 | } |
38 | | |
39 | | unsigned AMDGPUCallLowering::lowerParameterPtr(MachineIRBuilder &MIRBuilder, |
40 | | Type *ParamTy, |
41 | 26 | unsigned Offset) const { |
42 | 26 | |
43 | 26 | MachineFunction &MF = MIRBuilder.getMF(); |
44 | 26 | const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>(); |
45 | 26 | MachineRegisterInfo &MRI = MF.getRegInfo(); |
46 | 26 | const Function &F = *MF.getFunction(); |
47 | 26 | const DataLayout &DL = F.getParent()->getDataLayout(); |
48 | 26 | PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUASI.CONSTANT_ADDRESS); |
49 | 26 | LLT PtrType = getLLTForType(*PtrTy, DL); |
50 | 26 | unsigned DstReg = MRI.createGenericVirtualRegister(PtrType); |
51 | 26 | unsigned KernArgSegmentPtr = |
52 | 26 | MFI->getPreloadedReg(AMDGPUFunctionArgInfo::KERNARG_SEGMENT_PTR); |
53 | 26 | unsigned KernArgSegmentVReg = MRI.getLiveInVirtReg(KernArgSegmentPtr); |
54 | 26 | |
55 | 26 | unsigned OffsetReg = MRI.createGenericVirtualRegister(LLT::scalar(64)); |
56 | 26 | MIRBuilder.buildConstant(OffsetReg, Offset); |
57 | 26 | |
58 | 26 | MIRBuilder.buildGEP(DstReg, KernArgSegmentVReg, OffsetReg); |
59 | 26 | |
60 | 26 | return DstReg; |
61 | 26 | } |
62 | | |
63 | | void AMDGPUCallLowering::lowerParameter(MachineIRBuilder &MIRBuilder, |
64 | | Type *ParamTy, unsigned Offset, |
65 | 26 | unsigned DstReg) const { |
66 | 26 | MachineFunction &MF = MIRBuilder.getMF(); |
67 | 26 | const Function &F = *MF.getFunction(); |
68 | 26 | const DataLayout &DL = F.getParent()->getDataLayout(); |
69 | 26 | PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUASI.CONSTANT_ADDRESS); |
70 | 26 | MachinePointerInfo PtrInfo(UndefValue::get(PtrTy)); |
71 | 26 | unsigned TypeSize = DL.getTypeStoreSize(ParamTy); |
72 | 26 | unsigned Align = DL.getABITypeAlignment(ParamTy); |
73 | 26 | unsigned PtrReg = lowerParameterPtr(MIRBuilder, ParamTy, Offset); |
74 | 26 | |
75 | 26 | MachineMemOperand *MMO = |
76 | 26 | MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad | |
77 | 26 | MachineMemOperand::MONonTemporal | |
78 | 26 | MachineMemOperand::MOInvariant, |
79 | 26 | TypeSize, Align); |
80 | 26 | |
81 | 26 | MIRBuilder.buildLoad(DstReg, PtrReg, *MMO); |
82 | 26 | } |
83 | | |
84 | | bool AMDGPUCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, |
85 | | const Function &F, |
86 | 20 | ArrayRef<unsigned> VRegs) const { |
87 | 20 | |
88 | 20 | MachineFunction &MF = MIRBuilder.getMF(); |
89 | 20 | const SISubtarget *Subtarget = static_cast<const SISubtarget *>(&MF.getSubtarget()); |
90 | 20 | MachineRegisterInfo &MRI = MF.getRegInfo(); |
91 | 20 | SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>(); |
92 | 20 | const SIRegisterInfo *TRI = MF.getSubtarget<SISubtarget>().getRegisterInfo(); |
93 | 20 | const DataLayout &DL = F.getParent()->getDataLayout(); |
94 | 20 | |
95 | 20 | SmallVector<CCValAssign, 16> ArgLocs; |
96 | 20 | CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext()); |
97 | 20 | |
98 | 20 | // FIXME: How should these inputs interact with inreg / custom SGPR inputs? |
99 | 20 | if (Info->hasPrivateSegmentBuffer()20 ) { |
100 | 0 | unsigned PrivateSegmentBufferReg = Info->addPrivateSegmentBuffer(*TRI); |
101 | 0 | MF.addLiveIn(PrivateSegmentBufferReg, &AMDGPU::SReg_128RegClass); |
102 | 0 | CCInfo.AllocateReg(PrivateSegmentBufferReg); |
103 | 0 | } |
104 | 20 | |
105 | 20 | if (Info->hasDispatchPtr()20 ) { |
106 | 0 | unsigned DispatchPtrReg = Info->addDispatchPtr(*TRI); |
107 | 0 | // FIXME: Need to add reg as live-in |
108 | 0 | CCInfo.AllocateReg(DispatchPtrReg); |
109 | 0 | } |
110 | 20 | |
111 | 20 | if (Info->hasQueuePtr()20 ) { |
112 | 0 | unsigned QueuePtrReg = Info->addQueuePtr(*TRI); |
113 | 0 | // FIXME: Need to add reg as live-in |
114 | 0 | CCInfo.AllocateReg(QueuePtrReg); |
115 | 0 | } |
116 | 20 | |
117 | 20 | if (Info->hasKernargSegmentPtr()20 ) { |
118 | 13 | unsigned InputPtrReg = Info->addKernargSegmentPtr(*TRI); |
119 | 13 | const LLT P2 = LLT::pointer(2, 64); |
120 | 13 | unsigned VReg = MRI.createGenericVirtualRegister(P2); |
121 | 13 | MRI.addLiveIn(InputPtrReg, VReg); |
122 | 13 | MIRBuilder.getMBB().addLiveIn(InputPtrReg); |
123 | 13 | MIRBuilder.buildCopy(VReg, InputPtrReg); |
124 | 13 | CCInfo.AllocateReg(InputPtrReg); |
125 | 13 | } |
126 | 20 | |
127 | 20 | if (Info->hasDispatchID()20 ) { |
128 | 0 | unsigned DispatchIDReg = Info->addDispatchID(*TRI); |
129 | 0 | // FIXME: Need to add reg as live-in |
130 | 0 | CCInfo.AllocateReg(DispatchIDReg); |
131 | 0 | } |
132 | 20 | |
133 | 20 | if (Info->hasFlatScratchInit()20 ) { |
134 | 0 | unsigned FlatScratchInitReg = Info->addFlatScratchInit(*TRI); |
135 | 0 | // FIXME: Need to add reg as live-in |
136 | 0 | CCInfo.AllocateReg(FlatScratchInitReg); |
137 | 0 | } |
138 | 20 | |
139 | 20 | unsigned NumArgs = F.arg_size(); |
140 | 20 | Function::const_arg_iterator CurOrigArg = F.arg_begin(); |
141 | 20 | const AMDGPUTargetLowering &TLI = *getTLI<AMDGPUTargetLowering>(); |
142 | 56 | for (unsigned i = 0; i != NumArgs56 ; ++i, ++CurOrigArg36 ) { |
143 | 36 | EVT ValEVT = TLI.getValueType(DL, CurOrigArg->getType()); |
144 | 36 | |
145 | 36 | // We can only hanlde simple value types at the moment. |
146 | 36 | if (!ValEVT.isSimple()) |
147 | 0 | return false; |
148 | 36 | MVT ValVT = ValEVT.getSimpleVT(); |
149 | 36 | ISD::ArgFlagsTy Flags; |
150 | 36 | ArgInfo OrigArg{VRegs[i], CurOrigArg->getType()}; |
151 | 36 | setArgFlags(OrigArg, i + 1, DL, F); |
152 | 36 | Flags.setOrigAlign(DL.getABITypeAlignment(CurOrigArg->getType())); |
153 | 36 | CCAssignFn *AssignFn = CCAssignFnForCall(F.getCallingConv(), |
154 | 36 | /*IsVarArg=*/false); |
155 | 36 | bool Res = |
156 | 36 | AssignFn(i, ValVT, ValVT, CCValAssign::Full, OrigArg.Flags, CCInfo); |
157 | 36 | |
158 | 36 | // Fail if we don't know how to handle this type. |
159 | 36 | if (Res) |
160 | 0 | return false; |
161 | 36 | } |
162 | 20 | |
163 | 20 | Function::const_arg_iterator Arg = F.arg_begin(); |
164 | 20 | |
165 | 20 | if (F.getCallingConv() == CallingConv::AMDGPU_VS20 ) { |
166 | 17 | for (unsigned i = 0; i != NumArgs17 ; ++i, ++Arg10 ) { |
167 | 10 | CCValAssign &VA = ArgLocs[i]; |
168 | 10 | MRI.addLiveIn(VA.getLocReg(), VRegs[i]); |
169 | 10 | MIRBuilder.getMBB().addLiveIn(VA.getLocReg()); |
170 | 10 | MIRBuilder.buildCopy(VRegs[i], VA.getLocReg()); |
171 | 10 | } |
172 | 7 | return true; |
173 | 7 | } |
174 | 13 | |
175 | 39 | for (unsigned i = 0; 13 i != NumArgs39 ; ++i, ++Arg26 ) { |
176 | 26 | // FIXME: We should be getting DebugInfo from the arguments some how. |
177 | 26 | CCValAssign &VA = ArgLocs[i]; |
178 | 26 | lowerParameter(MIRBuilder, Arg->getType(), |
179 | 26 | VA.getLocMemOffset() + |
180 | 26 | Subtarget->getExplicitKernelArgOffset(MF), VRegs[i]); |
181 | 26 | } |
182 | 20 | |
183 | 20 | return true; |
184 | 20 | } |