Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- lib/CodeGen/GlobalISel/CallLowering.cpp - Call lowering -----------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
///
9
/// \file
10
/// This file implements some simple delegations needed for call lowering.
11
///
12
//===----------------------------------------------------------------------===//
13
14
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
15
#include "llvm/CodeGen/Analysis.h"
16
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
17
#include "llvm/CodeGen/MachineOperand.h"
18
#include "llvm/CodeGen/MachineRegisterInfo.h"
19
#include "llvm/CodeGen/TargetLowering.h"
20
#include "llvm/IR/DataLayout.h"
21
#include "llvm/IR/Instructions.h"
22
#include "llvm/IR/Module.h"
23
24
#define DEBUG_TYPE "call-lowering"
25
26
using namespace llvm;
27
28
0
void CallLowering::anchor() {}
29
30
bool CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, ImmutableCallSite CS,
31
                             ArrayRef<Register> ResRegs,
32
                             ArrayRef<ArrayRef<Register>> ArgRegs,
33
                             Register SwiftErrorVReg,
34
1.22M
                             std::function<unsigned()> GetCalleeReg) const {
35
1.22M
  auto &DL = CS.getParent()->getParent()->getParent()->getDataLayout();
36
1.22M
37
1.22M
  // First step is to marshall all the function's parameters into the correct
38
1.22M
  // physregs and memory locations. Gather the sequence of argument types that
39
1.22M
  // we'll pass to the assigner function.
40
1.22M
  SmallVector<ArgInfo, 8> OrigArgs;
41
1.22M
  unsigned i = 0;
42
1.22M
  unsigned NumFixedArgs = CS.getFunctionType()->getNumParams();
43
2.72M
  for (auto &Arg : CS.args()) {
44
2.72M
    ArgInfo OrigArg{ArgRegs[i], Arg->getType(), ISD::ArgFlagsTy{},
45
2.72M
                    i < NumFixedArgs};
46
2.72M
    setArgFlags(OrigArg, i + AttributeList::FirstArgIndex, DL, CS);
47
2.72M
    // We don't currently support swiftself args.
48
2.72M
    if (OrigArg.Flags.isSwiftSelf())
49
0
      return false;
50
2.72M
    OrigArgs.push_back(OrigArg);
51
2.72M
    ++i;
52
2.72M
  }
53
1.22M
54
1.22M
  MachineOperand Callee = MachineOperand::CreateImm(0);
55
1.22M
  if (const Function *F = CS.getCalledFunction())
56
1.15M
    Callee = MachineOperand::CreateGA(F, 0);
57
67.3k
  else
58
67.3k
    Callee = MachineOperand::CreateReg(GetCalleeReg(), false);
59
1.22M
60
1.22M
  ArgInfo OrigRet{ResRegs, CS.getType(), ISD::ArgFlagsTy{}};
61
1.22M
  if (!OrigRet.Ty->isVoidTy())
62
846k
    setArgFlags(OrigRet, AttributeList::ReturnIndex, DL, CS);
63
1.22M
64
1.22M
  return lowerCall(MIRBuilder, CS.getCallingConv(), Callee, OrigRet, OrigArgs,
65
1.22M
                   SwiftErrorVReg);
66
1.22M
}
67
68
template <typename FuncInfoTy>
69
void CallLowering::setArgFlags(CallLowering::ArgInfo &Arg, unsigned OpIdx,
70
                               const DataLayout &DL,
71
4.40M
                               const FuncInfoTy &FuncInfo) const {
72
4.40M
  const AttributeList &Attrs = FuncInfo.getAttributes();
73
4.40M
  if (Attrs.hasAttribute(OpIdx, Attribute::ZExt))
74
42.5k
    Arg.Flags.setZExt();
75
4.40M
  if (Attrs.hasAttribute(OpIdx, Attribute::SExt))
76
6.41k
    Arg.Flags.setSExt();
77
4.40M
  if (Attrs.hasAttribute(OpIdx, Attribute::InReg))
78
10
    Arg.Flags.setInReg();
79
4.40M
  if (Attrs.hasAttribute(OpIdx, Attribute::StructRet))
80
5.53k
    Arg.Flags.setSRet();
81
4.40M
  if (Attrs.hasAttribute(OpIdx, Attribute::SwiftSelf))
82
0
    Arg.Flags.setSwiftSelf();
83
4.40M
  if (Attrs.hasAttribute(OpIdx, Attribute::SwiftError))
84
22
    Arg.Flags.setSwiftError();
85
4.40M
  if (Attrs.hasAttribute(OpIdx, Attribute::ByVal))
86
11
    Arg.Flags.setByVal();
87
4.40M
  if (Attrs.hasAttribute(OpIdx, Attribute::InAlloca))
88
0
    Arg.Flags.setInAlloca();
89
4.40M
90
4.40M
  if (Arg.Flags.isByVal() || 
Arg.Flags.isInAlloca()4.40M
) {
91
11
    Type *ElementTy = cast<PointerType>(Arg.Ty)->getElementType();
92
11
93
11
    auto Ty = Attrs.getAttribute(OpIdx, Attribute::ByVal).getValueAsType();
94
11
    Arg.Flags.setByValSize(DL.getTypeAllocSize(Ty ? 
Ty0
: ElementTy));
95
11
96
11
    // For ByVal, alignment should be passed from FE.  BE will guess if
97
11
    // this info is not there but there are cases it cannot get right.
98
11
    unsigned FrameAlign;
99
11
    if (FuncInfo.getParamAlignment(OpIdx - 2))
100
0
      FrameAlign = FuncInfo.getParamAlignment(OpIdx - 2);
101
11
    else
102
11
      FrameAlign = getTLI()->getByValTypeAlignment(ElementTy, DL);
103
11
    Arg.Flags.setByValAlign(FrameAlign);
104
11
  }
105
4.40M
  if (Attrs.hasAttribute(OpIdx, Attribute::Nest))
106
0
    Arg.Flags.setNest();
107
4.40M
  Arg.Flags.setOrigAlign(DL.getABITypeAlignment(Arg.Ty));
108
4.40M
}
void llvm::CallLowering::setArgFlags<llvm::Function>(llvm::CallLowering::ArgInfo&, unsigned int, llvm::DataLayout const&, llvm::Function const&) const
Line
Count
Source
71
826k
                               const FuncInfoTy &FuncInfo) const {
72
826k
  const AttributeList &Attrs = FuncInfo.getAttributes();
73
826k
  if (Attrs.hasAttribute(OpIdx, Attribute::ZExt))
74
18.6k
    Arg.Flags.setZExt();
75
826k
  if (Attrs.hasAttribute(OpIdx, Attribute::SExt))
76
786
    Arg.Flags.setSExt();
77
826k
  if (Attrs.hasAttribute(OpIdx, Attribute::InReg))
78
10
    Arg.Flags.setInReg();
79
826k
  if (Attrs.hasAttribute(OpIdx, Attribute::StructRet))
80
1.75k
    Arg.Flags.setSRet();
81
826k
  if (Attrs.hasAttribute(OpIdx, Attribute::SwiftSelf))
82
0
    Arg.Flags.setSwiftSelf();
83
826k
  if (Attrs.hasAttribute(OpIdx, Attribute::SwiftError))
84
10
    Arg.Flags.setSwiftError();
85
826k
  if (Attrs.hasAttribute(OpIdx, Attribute::ByVal))
86
5
    Arg.Flags.setByVal();
87
826k
  if (Attrs.hasAttribute(OpIdx, Attribute::InAlloca))
88
0
    Arg.Flags.setInAlloca();
89
826k
90
826k
  if (Arg.Flags.isByVal() || 
Arg.Flags.isInAlloca()826k
) {
91
5
    Type *ElementTy = cast<PointerType>(Arg.Ty)->getElementType();
92
5
93
5
    auto Ty = Attrs.getAttribute(OpIdx, Attribute::ByVal).getValueAsType();
94
5
    Arg.Flags.setByValSize(DL.getTypeAllocSize(Ty ? 
Ty0
: ElementTy));
95
5
96
5
    // For ByVal, alignment should be passed from FE.  BE will guess if
97
5
    // this info is not there but there are cases it cannot get right.
98
5
    unsigned FrameAlign;
99
5
    if (FuncInfo.getParamAlignment(OpIdx - 2))
100
0
      FrameAlign = FuncInfo.getParamAlignment(OpIdx - 2);
101
5
    else
102
5
      FrameAlign = getTLI()->getByValTypeAlignment(ElementTy, DL);
103
5
    Arg.Flags.setByValAlign(FrameAlign);
104
5
  }
105
826k
  if (Attrs.hasAttribute(OpIdx, Attribute::Nest))
106
0
    Arg.Flags.setNest();
107
826k
  Arg.Flags.setOrigAlign(DL.getABITypeAlignment(Arg.Ty));
108
826k
}
Unexecuted instantiation: void llvm::CallLowering::setArgFlags<llvm::CallInst>(llvm::CallLowering::ArgInfo&, unsigned int, llvm::DataLayout const&, llvm::CallInst const&) const
void llvm::CallLowering::setArgFlags<llvm::ImmutableCallSite>(llvm::CallLowering::ArgInfo&, unsigned int, llvm::DataLayout const&, llvm::ImmutableCallSite const&) const
Line
Count
Source
71
3.57M
                               const FuncInfoTy &FuncInfo) const {
72
3.57M
  const AttributeList &Attrs = FuncInfo.getAttributes();
73
3.57M
  if (Attrs.hasAttribute(OpIdx, Attribute::ZExt))
74
23.8k
    Arg.Flags.setZExt();
75
3.57M
  if (Attrs.hasAttribute(OpIdx, Attribute::SExt))
76
5.63k
    Arg.Flags.setSExt();
77
3.57M
  if (Attrs.hasAttribute(OpIdx, Attribute::InReg))
78
0
    Arg.Flags.setInReg();
79
3.57M
  if (Attrs.hasAttribute(OpIdx, Attribute::StructRet))
80
3.77k
    Arg.Flags.setSRet();
81
3.57M
  if (Attrs.hasAttribute(OpIdx, Attribute::SwiftSelf))
82
0
    Arg.Flags.setSwiftSelf();
83
3.57M
  if (Attrs.hasAttribute(OpIdx, Attribute::SwiftError))
84
12
    Arg.Flags.setSwiftError();
85
3.57M
  if (Attrs.hasAttribute(OpIdx, Attribute::ByVal))
86
6
    Arg.Flags.setByVal();
87
3.57M
  if (Attrs.hasAttribute(OpIdx, Attribute::InAlloca))
88
0
    Arg.Flags.setInAlloca();
89
3.57M
90
3.57M
  if (Arg.Flags.isByVal() || 
Arg.Flags.isInAlloca()3.57M
) {
91
6
    Type *ElementTy = cast<PointerType>(Arg.Ty)->getElementType();
92
6
93
6
    auto Ty = Attrs.getAttribute(OpIdx, Attribute::ByVal).getValueAsType();
94
6
    Arg.Flags.setByValSize(DL.getTypeAllocSize(Ty ? 
Ty0
: ElementTy));
95
6
96
6
    // For ByVal, alignment should be passed from FE.  BE will guess if
97
6
    // this info is not there but there are cases it cannot get right.
98
6
    unsigned FrameAlign;
99
6
    if (FuncInfo.getParamAlignment(OpIdx - 2))
100
0
      FrameAlign = FuncInfo.getParamAlignment(OpIdx - 2);
101
6
    else
102
6
      FrameAlign = getTLI()->getByValTypeAlignment(ElementTy, DL);
103
6
    Arg.Flags.setByValAlign(FrameAlign);
104
6
  }
105
3.57M
  if (Attrs.hasAttribute(OpIdx, Attribute::Nest))
106
0
    Arg.Flags.setNest();
107
3.57M
  Arg.Flags.setOrigAlign(DL.getABITypeAlignment(Arg.Ty));
108
3.57M
}
109
110
template void
111
CallLowering::setArgFlags<Function>(CallLowering::ArgInfo &Arg, unsigned OpIdx,
112
                                    const DataLayout &DL,
113
                                    const Function &FuncInfo) const;
114
115
template void
116
CallLowering::setArgFlags<CallInst>(CallLowering::ArgInfo &Arg, unsigned OpIdx,
117
                                    const DataLayout &DL,
118
                                    const CallInst &FuncInfo) const;
119
120
Register CallLowering::packRegs(ArrayRef<Register> SrcRegs, Type *PackedTy,
121
0
                                MachineIRBuilder &MIRBuilder) const {
122
0
  assert(SrcRegs.size() > 1 && "Nothing to pack");
123
0
124
0
  const DataLayout &DL = MIRBuilder.getMF().getDataLayout();
125
0
  MachineRegisterInfo *MRI = MIRBuilder.getMRI();
126
0
127
0
  LLT PackedLLT = getLLTForType(*PackedTy, DL);
128
0
129
0
  SmallVector<LLT, 8> LLTs;
130
0
  SmallVector<uint64_t, 8> Offsets;
131
0
  computeValueLLTs(DL, *PackedTy, LLTs, &Offsets);
132
0
  assert(LLTs.size() == SrcRegs.size() && "Regs / types mismatch");
133
0
134
0
  Register Dst = MRI->createGenericVirtualRegister(PackedLLT);
135
0
  MIRBuilder.buildUndef(Dst);
136
0
  for (unsigned i = 0; i < SrcRegs.size(); ++i) {
137
0
    Register NewDst = MRI->createGenericVirtualRegister(PackedLLT);
138
0
    MIRBuilder.buildInsert(NewDst, Dst, SrcRegs[i], Offsets[i]);
139
0
    Dst = NewDst;
140
0
  }
141
0
142
0
  return Dst;
143
0
}
144
145
void CallLowering::unpackRegs(ArrayRef<Register> DstRegs, Register SrcReg,
146
                              Type *PackedTy,
147
7
                              MachineIRBuilder &MIRBuilder) const {
148
7
  assert(DstRegs.size() > 1 && "Nothing to unpack");
149
7
150
7
  const DataLayout &DL = MIRBuilder.getMF().getDataLayout();
151
7
152
7
  SmallVector<LLT, 8> LLTs;
153
7
  SmallVector<uint64_t, 8> Offsets;
154
7
  computeValueLLTs(DL, *PackedTy, LLTs, &Offsets);
155
7
  assert(LLTs.size() == DstRegs.size() && "Regs / types mismatch");
156
7
157
39
  for (unsigned i = 0; i < DstRegs.size(); 
++i32
)
158
32
    MIRBuilder.buildExtract(DstRegs[i], SrcReg, Offsets[i]);
159
7
}
160
161
bool CallLowering::handleAssignments(MachineIRBuilder &MIRBuilder,
162
                                     ArrayRef<ArgInfo> Args,
163
2.59M
                                     ValueHandler &Handler) const {
164
2.59M
  MachineFunction &MF = MIRBuilder.getMF();
165
2.59M
  const Function &F = MF.getFunction();
166
2.59M
  SmallVector<CCValAssign, 16> ArgLocs;
167
2.59M
  CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
168
2.59M
  return handleAssignments(CCInfo, ArgLocs, MIRBuilder, Args, Handler);
169
2.59M
}
170
171
bool CallLowering::handleAssignments(CCState &CCInfo,
172
                                     SmallVectorImpl<CCValAssign> &ArgLocs,
173
                                     MachineIRBuilder &MIRBuilder,
174
                                     ArrayRef<ArgInfo> Args,
175
2.59M
                                     ValueHandler &Handler) const {
176
2.59M
  MachineFunction &MF = MIRBuilder.getMF();
177
2.59M
  const Function &F = MF.getFunction();
178
2.59M
  const DataLayout &DL = F.getParent()->getDataLayout();
179
2.59M
180
2.59M
  unsigned NumArgs = Args.size();
181
7.09M
  for (unsigned i = 0; i != NumArgs; 
++i4.49M
) {
182
4.49M
    MVT CurVT = MVT::getVT(Args[i].Ty);
183
4.49M
    if (Handler.assignArg(i, CurVT, CurVT, CCValAssign::Full, Args[i], CCInfo)) {
184
40
      // Try to use the register type if we couldn't assign the VT.
185
40
      if (!Handler.isArgumentHandler() || 
!CurVT.isValid()33
)
186
8
        return false;
187
32
      CurVT = TLI->getRegisterTypeForCallingConv(
188
32
          F.getContext(), F.getCallingConv(), EVT(CurVT));
189
32
      if (Handler.assignArg(i, CurVT, CurVT, CCValAssign::Full, Args[i], CCInfo))
190
10
        return false;
191
32
    }
192
4.49M
  }
193
2.59M
194
7.09M
  
for (unsigned i = 0, e = Args.size(), j = 0; 2.59M
i != e;
++i, ++j4.49M
) {
195
4.49M
    assert(j < ArgLocs.size() && "Skipped too many arg locs");
196
4.49M
197
4.49M
    CCValAssign &VA = ArgLocs[j];
198
4.49M
    assert(VA.getValNo() == i && "Location doesn't correspond to current arg");
199
4.49M
200
4.49M
    if (VA.needsCustom()) {
201
347
      j += Handler.assignCustomValue(Args[i], makeArrayRef(ArgLocs).slice(j));
202
347
      continue;
203
347
    }
204
4.49M
205
4.49M
    assert(Args[i].Regs.size() == 1 &&
206
4.49M
           "Can't handle multiple virtual regs yet");
207
4.49M
208
4.49M
    // FIXME: Pack registers if we have more than one.
209
4.49M
    Register ArgReg = Args[i].Regs[0];
210
4.49M
211
4.49M
    if (VA.isRegLoc()) {
212
4.41M
      MVT OrigVT = MVT::getVT(Args[i].Ty);
213
4.41M
      MVT VAVT = VA.getValVT();
214
4.41M
      if (Handler.isArgumentHandler() && 
VAVT != OrigVT1.39M
) {
215
21
        if (VAVT.getSizeInBits() < OrigVT.getSizeInBits())
216
6
          return false; // Can't handle this type of arg yet.
217
15
        const LLT VATy(VAVT);
218
15
        Register NewReg =
219
15
            MIRBuilder.getMRI()->createGenericVirtualRegister(VATy);
220
15
        Handler.assignValueToReg(NewReg, VA.getLocReg(), VA);
221
15
        // If it's a vector type, we either need to truncate the elements
222
15
        // or do an unmerge to get the lower block of elements.
223
15
        if (VATy.isVector() &&
224
15
            
VATy.getNumElements() > OrigVT.getVectorNumElements()3
) {
225
2
          const LLT OrigTy(OrigVT);
226
2
          // Just handle the case where the VA type is 2 * original type.
227
2
          if (VATy.getNumElements() != OrigVT.getVectorNumElements() * 2) {
228
0
            LLVM_DEBUG(dbgs()
229
0
                       << "Incoming promoted vector arg has too many elts");
230
0
            return false;
231
0
          }
232
2
          auto Unmerge = MIRBuilder.buildUnmerge({OrigTy, OrigTy}, {NewReg});
233
2
          MIRBuilder.buildCopy(ArgReg, Unmerge.getReg(0));
234
13
        } else {
235
13
          MIRBuilder.buildTrunc(ArgReg, {NewReg}).getReg(0);
236
13
        }
237
4.41M
      } else {
238
4.41M
        Handler.assignValueToReg(ArgReg, VA.getLocReg(), VA);
239
4.41M
      }
240
4.41M
    } else 
if (79.8k
VA.isMemLoc()79.8k
) {
241
79.8k
      MVT VT = MVT::getVT(Args[i].Ty);
242
79.8k
      unsigned Size = VT == MVT::iPTR ? 
DL.getPointerSize()0
243
79.8k
                                      : alignTo(VT.getSizeInBits(), 8) / 8;
244
79.8k
      unsigned Offset = VA.getLocMemOffset();
245
79.8k
      MachinePointerInfo MPO;
246
79.8k
      Register StackAddr = Handler.getStackAddress(Size, Offset, MPO);
247
79.8k
      Handler.assignValueToAddress(ArgReg, StackAddr, Size, MPO, VA);
248
79.8k
    } else {
249
0
      // FIXME: Support byvals and other weirdness
250
0
      return false;
251
0
    }
252
4.49M
  }
253
2.59M
  
return true2.59M
;
254
2.59M
}
255
256
Register CallLowering::ValueHandler::extendRegister(Register ValReg,
257
3.02M
                                                    CCValAssign &VA) {
258
3.02M
  LLT LocTy{VA.getLocVT()};
259
3.02M
  if (LocTy.getSizeInBits() == MRI.getType(ValReg).getSizeInBits())
260
2.98M
    return ValReg;
261
38.4k
  switch (VA.getLocInfo()) {
262
38.4k
  
default: break0
;
263
38.4k
  case CCValAssign::Full:
264
502
  case CCValAssign::BCvt:
265
502
    // FIXME: bitconverting between vector types may or may not be a
266
502
    // nop in big-endian situations.
267
502
    return ValReg;
268
20.9k
  case CCValAssign::AExt: {
269
20.9k
    auto MIB = MIRBuilder.buildAnyExt(LocTy, ValReg);
270
20.9k
    return MIB->getOperand(0).getReg();
271
502
  }
272
3.99k
  case CCValAssign::SExt: {
273
3.99k
    Register NewReg = MRI.createGenericVirtualRegister(LocTy);
274
3.99k
    MIRBuilder.buildSExt(NewReg, ValReg);
275
3.99k
    return NewReg;
276
502
  }
277
12.9k
  case CCValAssign::ZExt: {
278
12.9k
    Register NewReg = MRI.createGenericVirtualRegister(LocTy);
279
12.9k
    MIRBuilder.buildZExt(NewReg, ValReg);
280
12.9k
    return NewReg;
281
0
  }
282
0
  }
283
0
  llvm_unreachable("unable to extend register");
284
0
}
285
286
0
void CallLowering::ValueHandler::anchor() {}