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