Coverage Report

Created: 2017-10-03 07:32

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