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