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 "SIRegisterInfo.h" 22ca16621bSTom Stellard #include "SIMachineFunctionInfo.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 #ifndef LLVM_BUILD_GLOBAL_ISEL 30000c5af3STom Stellard #error "This shouldn't be built without GISel" 31000c5af3STom Stellard #endif 32000c5af3STom Stellard 33000c5af3STom Stellard AMDGPUCallLowering::AMDGPUCallLowering(const AMDGPUTargetLowering &TLI) 34000c5af3STom Stellard : CallLowering(&TLI) { 35000c5af3STom Stellard } 36000c5af3STom Stellard 37000c5af3STom Stellard bool AMDGPUCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, 38000c5af3STom Stellard const Value *Val, unsigned VReg) const { 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(); 48ca16621bSTom Stellard const SIRegisterInfo *TRI = MF.getSubtarget<SISubtarget>().getRegisterInfo(); 49ca16621bSTom Stellard MachineRegisterInfo &MRI = MF.getRegInfo(); 50ca16621bSTom Stellard const Function &F = *MF.getFunction(); 51ca16621bSTom Stellard const DataLayout &DL = F.getParent()->getDataLayout(); 52ca16621bSTom Stellard PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUAS::CONSTANT_ADDRESS); 53*52b4ce72SDaniel Sanders LLT PtrType = getLLTForType(*PtrTy, DL); 54ca16621bSTom Stellard unsigned DstReg = MRI.createGenericVirtualRegister(PtrType); 55ca16621bSTom Stellard unsigned KernArgSegmentPtr = 56ca16621bSTom Stellard TRI->getPreloadedValue(MF, SIRegisterInfo::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(); 71ca16621bSTom Stellard const Function &F = *MF.getFunction(); 72ca16621bSTom Stellard const DataLayout &DL = F.getParent()->getDataLayout(); 73ca16621bSTom Stellard PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUAS::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); 123ca16621bSTom Stellard const LLT P2 = LLT::pointer(2, 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>(); 146ca16621bSTom Stellard for (unsigned i = 0; i != NumArgs; ++i, ++CurOrigArg) { 147ca16621bSTom Stellard MVT ValVT = TLI.getValueType(DL, CurOrigArg->getType()).getSimpleVT(); 148ca16621bSTom Stellard ISD::ArgFlagsTy Flags; 149ca16621bSTom Stellard Flags.setOrigAlign(DL.getABITypeAlignment(CurOrigArg->getType())); 150ca16621bSTom Stellard CCAssignFn *AssignFn = CCAssignFnForCall(F.getCallingConv(), 151ca16621bSTom Stellard /*IsVarArg=*/false); 152ca16621bSTom Stellard bool Res = 153ca16621bSTom Stellard AssignFn(i, ValVT, ValVT, CCValAssign::Full, Flags, CCInfo); 154ca16621bSTom Stellard assert(!Res && "Call operand has unhandled type"); 155ca16621bSTom Stellard (void)Res; 156ca16621bSTom Stellard } 157ca16621bSTom Stellard 158ca16621bSTom Stellard Function::const_arg_iterator Arg = F.arg_begin(); 159ca16621bSTom Stellard for (unsigned i = 0; i != NumArgs; ++i, ++Arg) { 160ca16621bSTom Stellard // FIXME: We should be getting DebugInfo from the arguments some how. 161ca16621bSTom Stellard CCValAssign &VA = ArgLocs[i]; 162ca16621bSTom Stellard lowerParameter(MIRBuilder, Arg->getType(), 163ca16621bSTom Stellard VA.getLocMemOffset() + 164ca16621bSTom Stellard Subtarget->getExplicitKernelArgOffset(MF), VRegs[i]); 165ca16621bSTom Stellard } 166ca16621bSTom Stellard 167000c5af3STom Stellard return true; 168000c5af3STom Stellard } 169