Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Mips/MipsCCState.cpp
Line
Count
Source
1
//===---- MipsCCState.cpp - CCState with Mips specific extensions ---------===//
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
#include "MipsCCState.h"
10
#include "MipsSubtarget.h"
11
#include "llvm/IR/Module.h"
12
13
using namespace llvm;
14
15
/// This function returns true if CallSym is a long double emulation routine.
16
1.18k
static bool isF128SoftLibCall(const char *CallSym) {
17
1.18k
  const char *const LibCalls[] = {
18
1.18k
      "__addtf3",      "__divtf3",     "__eqtf2",       "__extenddftf2",
19
1.18k
      "__extendsftf2", "__fixtfdi",    "__fixtfsi",     "__fixtfti",
20
1.18k
      "__fixunstfdi",  "__fixunstfsi", "__fixunstfti",  "__floatditf",
21
1.18k
      "__floatsitf",   "__floattitf",  "__floatunditf", "__floatunsitf",
22
1.18k
      "__floatuntitf", "__getf2",      "__gttf2",       "__letf2",
23
1.18k
      "__lttf2",       "__multf3",     "__netf2",       "__powitf2",
24
1.18k
      "__subtf3",      "__trunctfdf2", "__trunctfsf2",  "__unordtf2",
25
1.18k
      "ceill",         "copysignl",    "cosl",          "exp2l",
26
1.18k
      "expl",          "floorl",       "fmal",          "fmaxl",
27
1.18k
      "fmodl",         "log10l",       "log2l",         "logl",
28
1.18k
      "nearbyintl",    "powl",         "rintl",         "roundl",
29
1.18k
      "sinl",          "sqrtl",        "truncl"};
30
1.18k
31
1.18k
  // Check that LibCalls is sorted alphabetically.
32
8.03k
  auto Comp = [](const char *S1, const char *S2) { return strcmp(S1, S2) < 0; };
33
1.18k
  assert(std::is_sorted(std::begin(LibCalls), std::end(LibCalls), Comp));
34
1.18k
  return std::binary_search(std::begin(LibCalls), std::end(LibCalls),
35
1.18k
                            CallSym, Comp);
36
1.18k
}
37
38
/// This function returns true if Ty is fp128, {f128} or i128 which was
39
/// originally a fp128.
40
51.1k
static bool originalTypeIsF128(const Type *Ty, const char *Func) {
41
51.1k
  if (Ty->isFP128Ty())
42
1.44k
    return true;
43
49.6k
44
49.6k
  if (Ty->isStructTy() && 
Ty->getStructNumElements() == 1658
&&
45
49.6k
      
Ty->getStructElementType(0)->isFP128Ty()376
)
46
16
    return true;
47
49.6k
48
49.6k
  // If the Ty is i128 and the function being called is a long double emulation
49
49.6k
  // routine, then the original type is f128.
50
49.6k
  return (Func && 
Ty->isIntegerTy(128)3.82k
&&
isF128SoftLibCall(Func)1.18k
);
51
49.6k
}
52
53
/// Return true if the original type was vXfXX.
54
22.2k
static bool originalEVTTypeIsVectorFloat(EVT Ty) {
55
22.2k
  if (Ty.isVector() && 
Ty.getVectorElementType().isFloatingPoint()1.17k
)
56
288
    return true;
57
21.9k
58
21.9k
  return false;
59
21.9k
}
60
61
/// Return true if the original type was vXfXX / vXfXX.
62
2.56k
static bool originalTypeIsVectorFloat(const Type * Ty) {
63
2.56k
  if (Ty->isVectorTy() && 
Ty->isFPOrFPVectorTy()180
)
64
20
    return true;
65
2.54k
66
2.54k
  return false;
67
2.54k
}
68
69
MipsCCState::SpecialCallingConvType
70
MipsCCState::getSpecialCallingConvForCallee(const SDNode *Callee,
71
3.13k
                                            const MipsSubtarget &Subtarget) {
72
3.13k
  MipsCCState::SpecialCallingConvType SpecialCallingConv = NoSpecialCallingConv;
73
3.13k
  if (Subtarget.inMips16HardFloat()) {
74
1.00k
    if (const GlobalAddressSDNode *G =
75
654
            dyn_cast<const GlobalAddressSDNode>(Callee)) {
76
654
      llvm::StringRef Sym = G->getGlobal()->getName();
77
654
      Function *F = G->getGlobal()->getParent()->getFunction(Sym);
78
654
      if (F && F->hasFnAttribute("__Mips16RetHelper")) {
79
30
        SpecialCallingConv = Mips16RetHelperConv;
80
30
      }
81
654
    }
82
1.00k
  }
83
3.13k
  return SpecialCallingConv;
84
3.13k
}
85
86
void MipsCCState::PreAnalyzeCallResultForF128(
87
    const SmallVectorImpl<ISD::InputArg> &Ins,
88
3.05k
    const Type *RetTy, const char *Call) {
89
5.61k
  for (unsigned i = 0; i < Ins.size(); 
++i2.56k
) {
90
2.56k
    OriginalArgWasF128.push_back(
91
2.56k
        originalTypeIsF128(RetTy, Call));
92
2.56k
    OriginalArgWasFloat.push_back(RetTy->isFloatingPointTy());
93
2.56k
  }
94
3.05k
}
95
96
/// Identify lowered values that originated from f128 or float arguments and
97
/// record this for use by RetCC_MipsN.
98
void MipsCCState::PreAnalyzeReturnForF128(
99
28.9k
    const SmallVectorImpl<ISD::OutputArg> &Outs) {
100
28.9k
  const MachineFunction &MF = getMachineFunction();
101
51.1k
  for (unsigned i = 0; i < Outs.size(); 
++i22.2k
) {
102
22.2k
    OriginalArgWasF128.push_back(
103
22.2k
        originalTypeIsF128(MF.getFunction().getReturnType(), nullptr));
104
22.2k
    OriginalArgWasFloat.push_back(
105
22.2k
        MF.getFunction().getReturnType()->isFloatingPointTy());
106
22.2k
  }
107
28.9k
}
108
109
/// Identify lower values that originated from vXfXX and record
110
/// this.
111
void MipsCCState::PreAnalyzeCallResultForVectorFloat(
112
3.05k
    const SmallVectorImpl<ISD::InputArg> &Ins, const Type *RetTy) {
113
5.61k
  for (unsigned i = 0; i < Ins.size(); 
++i2.56k
) {
114
2.56k
    OriginalRetWasFloatVector.push_back(originalTypeIsVectorFloat(RetTy));
115
2.56k
  }
116
3.05k
}
117
118
/// Identify lowered values that originated from vXfXX arguments and record
119
/// this.
120
void MipsCCState::PreAnalyzeReturnForVectorFloat(
121
28.9k
    const SmallVectorImpl<ISD::OutputArg> &Outs) {
122
51.1k
  for (unsigned i = 0; i < Outs.size(); 
++i22.2k
) {
123
22.2k
    ISD::OutputArg Out = Outs[i];
124
22.2k
    OriginalRetWasFloatVector.push_back(
125
22.2k
        originalEVTTypeIsVectorFloat(Out.ArgVT));
126
22.2k
  }
127
28.9k
}
128
129
/// Identify lowered values that originated from f128, float and sret to vXfXX
130
/// arguments and record this.
131
void MipsCCState::PreAnalyzeCallOperands(
132
    const SmallVectorImpl<ISD::OutputArg> &Outs,
133
    std::vector<TargetLowering::ArgListEntry> &FuncArgs,
134
3.23k
    const char *Func) {
135
9.40k
  for (unsigned i = 0; i < Outs.size(); 
++i6.17k
) {
136
6.17k
    TargetLowering::ArgListEntry FuncArg = FuncArgs[Outs[i].OrigArgIndex];
137
6.17k
138
6.17k
    OriginalArgWasF128.push_back(originalTypeIsF128(FuncArg.Ty, Func));
139
6.17k
    OriginalArgWasFloat.push_back(FuncArg.Ty->isFloatingPointTy());
140
6.17k
    OriginalArgWasFloatVector.push_back(FuncArg.Ty->isVectorTy());
141
6.17k
    CallOperandIsFixed.push_back(Outs[i].IsFixed);
142
6.17k
  }
143
3.23k
}
144
145
/// Identify lowered values that originated from f128, float and vXfXX arguments
146
/// and record this.
147
void MipsCCState::PreAnalyzeFormalArgumentsForF128(
148
12.9k
    const SmallVectorImpl<ISD::InputArg> &Ins) {
149
12.9k
  const MachineFunction &MF = getMachineFunction();
150
33.0k
  for (unsigned i = 0; i < Ins.size(); 
++i20.1k
) {
151
20.1k
    Function::const_arg_iterator FuncArg = MF.getFunction().arg_begin();
152
20.1k
153
20.1k
    // SRet arguments cannot originate from f128 or {f128} returns so we just
154
20.1k
    // push false. We have to handle this specially since SRet arguments
155
20.1k
    // aren't mapped to an original argument.
156
20.1k
    if (Ins[i].Flags.isSRet()) {
157
47
      OriginalArgWasF128.push_back(false);
158
47
      OriginalArgWasFloat.push_back(false);
159
47
      OriginalArgWasFloatVector.push_back(false);
160
47
      continue;
161
47
    }
162
20.1k
163
20.1k
    assert(Ins[i].getOrigArgIndex() < MF.getFunction().arg_size());
164
20.1k
    std::advance(FuncArg, Ins[i].getOrigArgIndex());
165
20.1k
166
20.1k
    OriginalArgWasF128.push_back(
167
20.1k
        originalTypeIsF128(FuncArg->getType(), nullptr));
168
20.1k
    OriginalArgWasFloat.push_back(FuncArg->getType()->isFloatingPointTy());
169
20.1k
170
20.1k
    // The MIPS vector ABI exhibits a corner case of sorts or quirk; if the
171
20.1k
    // first argument is actually an SRet pointer to a vector, then the next
172
20.1k
    // argument slot is $a2.
173
20.1k
    OriginalArgWasFloatVector.push_back(FuncArg->getType()->isVectorTy());
174
20.1k
  }
175
12.9k
}