LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU - AMDGPUCallLowering.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 83 95 87.4 %
Date: 2017-09-14 15:23:50 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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        1796 : AMDGPUCallLowering::AMDGPUCallLowering(const AMDGPUTargetLowering &TLI)
      30        5388 :   : CallLowering(&TLI), AMDGPUASI(TLI.getAMDGPUAS()) {
      31        1796 : }
      32             : 
      33          20 : bool AMDGPUCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
      34             :                                      const Value *Val, unsigned VReg) const {
      35          20 :   MIRBuilder.buildInstr(AMDGPU::S_ENDPGM);
      36          20 :   return true;
      37             : }
      38             : 
      39          26 : unsigned AMDGPUCallLowering::lowerParameterPtr(MachineIRBuilder &MIRBuilder,
      40             :                                                Type *ParamTy,
      41             :                                                unsigned Offset) const {
      42             : 
      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             :   unsigned KernArgSegmentPtr =
      52          26 :     MFI->getPreloadedReg(AMDGPUFunctionArgInfo::KERNARG_SEGMENT_PTR);
      53          26 :   unsigned KernArgSegmentVReg = MRI.getLiveInVirtReg(KernArgSegmentPtr);
      54             : 
      55          26 :   unsigned OffsetReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
      56          26 :   MIRBuilder.buildConstant(OffsetReg, Offset);
      57             : 
      58          26 :   MIRBuilder.buildGEP(DstReg, KernArgSegmentVReg, OffsetReg);
      59             : 
      60          26 :   return DstReg;
      61             : }
      62             : 
      63          26 : void AMDGPUCallLowering::lowerParameter(MachineIRBuilder &MIRBuilder,
      64             :                                         Type *ParamTy, unsigned Offset,
      65             :                                         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          52 :   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             : 
      75             :   MachineMemOperand *MMO =
      76          78 :       MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad |
      77          26 :                                        MachineMemOperand::MONonTemporal |
      78             :                                        MachineMemOperand::MOInvariant,
      79          26 :                                        TypeSize, Align);
      80             : 
      81          26 :   MIRBuilder.buildLoad(DstReg, PtrReg, *MMO);
      82          26 : }
      83             : 
      84          20 : bool AMDGPUCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
      85             :                                               const Function &F,
      86             :                                               ArrayRef<unsigned> VRegs) const {
      87             : 
      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          40 :   const SIRegisterInfo *TRI = MF.getSubtarget<SISubtarget>().getRegisterInfo();
      93          20 :   const DataLayout &DL = F.getParent()->getDataLayout();
      94             : 
      95          40 :   SmallVector<CCValAssign, 16> ArgLocs;
      96          80 :   CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
      97             : 
      98             :   // FIXME: How should these inputs interact with inreg / custom SGPR inputs?
      99          20 :   if (Info->hasPrivateSegmentBuffer()) {
     100           0 :     unsigned PrivateSegmentBufferReg = Info->addPrivateSegmentBuffer(*TRI);
     101           0 :     MF.addLiveIn(PrivateSegmentBufferReg, &AMDGPU::SReg_128RegClass);
     102           0 :     CCInfo.AllocateReg(PrivateSegmentBufferReg);
     103             :   }
     104             : 
     105          20 :   if (Info->hasDispatchPtr()) {
     106           0 :     unsigned DispatchPtrReg = Info->addDispatchPtr(*TRI);
     107             :     // FIXME: Need to add reg as live-in
     108           0 :     CCInfo.AllocateReg(DispatchPtrReg);
     109             :   }
     110             : 
     111          20 :   if (Info->hasQueuePtr()) {
     112           0 :     unsigned QueuePtrReg = Info->addQueuePtr(*TRI);
     113             :     // FIXME: Need to add reg as live-in
     114           0 :     CCInfo.AllocateReg(QueuePtrReg);
     115             :   }
     116             : 
     117          20 :   if (Info->hasKernargSegmentPtr()) {
     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          26 :     MIRBuilder.getMBB().addLiveIn(InputPtrReg);
     123          13 :     MIRBuilder.buildCopy(VReg, InputPtrReg);
     124          13 :     CCInfo.AllocateReg(InputPtrReg);
     125             :   }
     126             : 
     127          20 :   if (Info->hasDispatchID()) {
     128           0 :     unsigned DispatchIDReg = Info->addDispatchID(*TRI);
     129             :     // FIXME: Need to add reg as live-in
     130           0 :     CCInfo.AllocateReg(DispatchIDReg);
     131             :   }
     132             : 
     133          20 :   if (Info->hasFlatScratchInit()) {
     134           0 :     unsigned FlatScratchInitReg = Info->addFlatScratchInit(*TRI);
     135             :     // FIXME: Need to add reg as live-in
     136           0 :     CCInfo.AllocateReg(FlatScratchInitReg);
     137             :   }
     138             : 
     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 != NumArgs; ++i, ++CurOrigArg) {
     143          36 :     EVT ValEVT = TLI.getValueType(DL, CurOrigArg->getType());
     144             : 
     145             :     // 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         108 :     ArgInfo OrigArg{VRegs[i], CurOrigArg->getType()};
     151          36 :     setArgFlags(OrigArg, i + 1, DL, F);
     152          72 :     Flags.setOrigAlign(DL.getABITypeAlignment(CurOrigArg->getType()));
     153          36 :     CCAssignFn *AssignFn = CCAssignFnForCall(F.getCallingConv(),
     154          36 :                                              /*IsVarArg=*/false);
     155             :     bool Res =
     156          36 :         AssignFn(i, ValVT, ValVT, CCValAssign::Full, OrigArg.Flags, CCInfo);
     157             : 
     158             :     // Fail if we don't know how to handle this type.
     159          36 :     if (Res)
     160             :       return false;
     161             :   }
     162             : 
     163          20 :   Function::const_arg_iterator Arg = F.arg_begin();
     164             : 
     165          20 :   if (F.getCallingConv() == CallingConv::AMDGPU_VS) {
     166          27 :     for (unsigned i = 0; i != NumArgs; ++i, ++Arg) {
     167          20 :       CCValAssign &VA = ArgLocs[i];
     168          30 :       MRI.addLiveIn(VA.getLocReg(), VRegs[i]);
     169          20 :       MIRBuilder.getMBB().addLiveIn(VA.getLocReg());
     170          10 :       MIRBuilder.buildCopy(VRegs[i], VA.getLocReg());
     171             :     }
     172             :     return true;
     173             :   }
     174             : 
     175          65 :   for (unsigned i = 0; i != NumArgs; ++i, ++Arg) {
     176             :     // FIXME: We should be getting DebugInfo from the arguments some how.
     177          52 :     CCValAssign &VA = ArgLocs[i];
     178          52 :     lowerParameter(MIRBuilder, Arg->getType(),
     179             :                    VA.getLocMemOffset() +
     180         104 :                    Subtarget->getExplicitKernelArgOffset(MF), VRegs[i]);
     181             :   }
     182             : 
     183             :   return true;
     184             : }

Generated by: LCOV version 1.13