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 { 35*257882ffSTom Stellard // FIXME: Add support for non-void returns. 36*257882ffSTom Stellard if (Val) 37*257882ffSTom Stellard return false; 38*257882ffSTom Stellard 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(); 488623e8d8SMatt Arsenault const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>(); 49ca16621bSTom Stellard MachineRegisterInfo &MRI = MF.getRegInfo(); 50f1caa283SMatthias Braun const Function &F = MF.getFunction(); 51ca16621bSTom Stellard const DataLayout &DL = F.getParent()->getDataLayout(); 521a14bfa0SYaxun Liu PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUASI.CONSTANT_ADDRESS); 5352b4ce72SDaniel Sanders LLT PtrType = getLLTForType(*PtrTy, DL); 54ca16621bSTom Stellard unsigned DstReg = MRI.createGenericVirtualRegister(PtrType); 55ca16621bSTom Stellard unsigned KernArgSegmentPtr = 568623e8d8SMatt Arsenault MFI->getPreloadedReg(AMDGPUFunctionArgInfo::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(); 71f1caa283SMatthias Braun const Function &F = MF.getFunction(); 72ca16621bSTom Stellard const DataLayout &DL = F.getParent()->getDataLayout(); 731a14bfa0SYaxun Liu PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUASI.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); 1230124b548SYaxun Liu const LLT P2 = LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS, 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>(); 146c7709e1cSTom Stellard unsigned PSInputNum = 0; 147c7709e1cSTom Stellard BitVector Skipped(NumArgs); 148ca16621bSTom Stellard for (unsigned i = 0; i != NumArgs; ++i, ++CurOrigArg) { 1499d8337d8STom Stellard EVT ValEVT = TLI.getValueType(DL, CurOrigArg->getType()); 1509d8337d8STom Stellard 1519d8337d8STom Stellard // We can only hanlde simple value types at the moment. 152ca16621bSTom Stellard ISD::ArgFlagsTy Flags; 1539d8337d8STom Stellard ArgInfo OrigArg{VRegs[i], CurOrigArg->getType()}; 1549d8337d8STom Stellard setArgFlags(OrigArg, i + 1, DL, F); 155ca16621bSTom Stellard Flags.setOrigAlign(DL.getABITypeAlignment(CurOrigArg->getType())); 156c7709e1cSTom Stellard 157c7709e1cSTom Stellard if (F.getCallingConv() == CallingConv::AMDGPU_PS && 158c7709e1cSTom Stellard !OrigArg.Flags.isInReg() && !OrigArg.Flags.isByVal() && 159c7709e1cSTom Stellard PSInputNum <= 15) { 160c7709e1cSTom Stellard if (CurOrigArg->use_empty() && !Info->isPSInputAllocated(PSInputNum)) { 161c7709e1cSTom Stellard Skipped.set(i); 162c7709e1cSTom Stellard ++PSInputNum; 163c7709e1cSTom Stellard continue; 164c7709e1cSTom Stellard } 165c7709e1cSTom Stellard 166c7709e1cSTom Stellard Info->markPSInputAllocated(PSInputNum); 167c7709e1cSTom Stellard if (!CurOrigArg->use_empty()) 168c7709e1cSTom Stellard Info->markPSInputEnabled(PSInputNum); 169c7709e1cSTom Stellard 170c7709e1cSTom Stellard ++PSInputNum; 171c7709e1cSTom Stellard } 172c7709e1cSTom Stellard 173ca16621bSTom Stellard CCAssignFn *AssignFn = CCAssignFnForCall(F.getCallingConv(), 174ca16621bSTom Stellard /*IsVarArg=*/false); 175c7709e1cSTom Stellard 176c7709e1cSTom Stellard if (ValEVT.isVector()) { 177c7709e1cSTom Stellard EVT ElemVT = ValEVT.getVectorElementType(); 178c7709e1cSTom Stellard if (!ValEVT.isSimple()) 179c7709e1cSTom Stellard return false; 180c7709e1cSTom Stellard MVT ValVT = ElemVT.getSimpleVT(); 181c7709e1cSTom Stellard bool Res = AssignFn(i, ValVT, ValVT, CCValAssign::Full, 182c7709e1cSTom Stellard OrigArg.Flags, CCInfo); 183c7709e1cSTom Stellard if (!Res) 184c7709e1cSTom Stellard return false; 185c7709e1cSTom Stellard } else { 186c7709e1cSTom Stellard MVT ValVT = ValEVT.getSimpleVT(); 187c7709e1cSTom Stellard if (!ValEVT.isSimple()) 188c7709e1cSTom Stellard return false; 189ca16621bSTom Stellard bool Res = 1909d8337d8STom Stellard AssignFn(i, ValVT, ValVT, CCValAssign::Full, OrigArg.Flags, CCInfo); 1919d8337d8STom Stellard 1929d8337d8STom Stellard // Fail if we don't know how to handle this type. 1939d8337d8STom Stellard if (Res) 1949d8337d8STom Stellard return false; 195ca16621bSTom Stellard } 196c7709e1cSTom Stellard } 197ca16621bSTom Stellard 198ca16621bSTom Stellard Function::const_arg_iterator Arg = F.arg_begin(); 1999d8337d8STom Stellard 200c7709e1cSTom Stellard if (F.getCallingConv() == CallingConv::AMDGPU_VS || 201c7709e1cSTom Stellard F.getCallingConv() == CallingConv::AMDGPU_PS) { 202c7709e1cSTom Stellard for (unsigned i = 0, OrigArgIdx = 0; 203c7709e1cSTom Stellard OrigArgIdx != NumArgs && i != ArgLocs.size(); ++Arg, ++OrigArgIdx) { 204c7709e1cSTom Stellard if (Skipped.test(OrigArgIdx)) 205c7709e1cSTom Stellard continue; 206c7709e1cSTom Stellard CCValAssign &VA = ArgLocs[i++]; 207c7709e1cSTom Stellard MRI.addLiveIn(VA.getLocReg(), VRegs[OrigArgIdx]); 2089d8337d8STom Stellard MIRBuilder.getMBB().addLiveIn(VA.getLocReg()); 209c7709e1cSTom Stellard MIRBuilder.buildCopy(VRegs[OrigArgIdx], VA.getLocReg()); 2109d8337d8STom Stellard } 2119d8337d8STom Stellard return true; 2129d8337d8STom Stellard } 2139d8337d8STom Stellard 214c7709e1cSTom Stellard for (unsigned i = 0; i != ArgLocs.size(); ++i, ++Arg) { 215ca16621bSTom Stellard // FIXME: We should be getting DebugInfo from the arguments some how. 216ca16621bSTom Stellard CCValAssign &VA = ArgLocs[i]; 217ca16621bSTom Stellard lowerParameter(MIRBuilder, Arg->getType(), 218ca16621bSTom Stellard VA.getLocMemOffset() + 219ca16621bSTom Stellard Subtarget->getExplicitKernelArgOffset(MF), VRegs[i]); 220ca16621bSTom Stellard } 221ca16621bSTom Stellard 222000c5af3STom Stellard return true; 223000c5af3STom Stellard } 224