Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Mips/MipsMachineFunction.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- MipsMachineFunctionInfo.cpp - Private data used for Mips ----------===//
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 "MipsMachineFunction.h"
10
#include "MCTargetDesc/MipsABIInfo.h"
11
#include "MipsSubtarget.h"
12
#include "MipsTargetMachine.h"
13
#include "llvm/CodeGen/MachineFrameInfo.h"
14
#include "llvm/CodeGen/MachineRegisterInfo.h"
15
#include "llvm/CodeGen/PseudoSourceValue.h"
16
#include "llvm/CodeGen/TargetRegisterInfo.h"
17
#include "llvm/Support/CommandLine.h"
18
19
using namespace llvm;
20
21
static cl::opt<bool>
22
FixGlobalBaseReg("mips-fix-global-base-reg", cl::Hidden, cl::init(true),
23
                 cl::desc("Always use $gp as the global base register."));
24
25
13.2k
MipsFunctionInfo::~MipsFunctionInfo() = default;
26
27
3.45k
bool MipsFunctionInfo::globalBaseRegSet() const {
28
3.45k
  return GlobalBaseReg;
29
3.45k
}
30
31
3.53k
static const TargetRegisterClass &getGlobalBaseRegClass(MachineFunction &MF) {
32
3.53k
  auto &STI = static_cast<const MipsSubtarget &>(MF.getSubtarget());
33
3.53k
  auto &TM = static_cast<const MipsTargetMachine &>(MF.getTarget());
34
3.53k
35
3.53k
  if (STI.inMips16Mode())
36
198
    return Mips::CPU16RegsRegClass;
37
3.33k
38
3.33k
  if (STI.inMicroMipsMode())
39
163
    return Mips::GPRMM16RegClass;
40
3.17k
41
3.17k
  if (TM.getABI().IsN64())
42
1.14k
    return Mips::GPR64RegClass;
43
2.02k
44
2.02k
  return Mips::GPR32RegClass;
45
2.02k
}
46
47
9.48k
Register MipsFunctionInfo::getGlobalBaseReg() {
48
9.48k
  if (!GlobalBaseReg)
49
3.53k
    GlobalBaseReg =
50
3.53k
        MF.getRegInfo().createVirtualRegister(&getGlobalBaseRegClass(MF));
51
9.48k
  return GlobalBaseReg;
52
9.48k
}
53
54
18
Register MipsFunctionInfo::getGlobalBaseRegForGlobalISel() {
55
18
  if (!GlobalBaseReg) {
56
14
    getGlobalBaseReg();
57
14
    initGlobalBaseReg();
58
14
  }
59
18
  return GlobalBaseReg;
60
18
}
61
62
12.5k
void MipsFunctionInfo::initGlobalBaseReg() {
63
12.5k
  if (!GlobalBaseReg)
64
9.17k
    return;
65
3.33k
66
3.33k
  MachineBasicBlock &MBB = MF.front();
67
3.33k
  MachineBasicBlock::iterator I = MBB.begin();
68
3.33k
  MachineRegisterInfo &RegInfo = MF.getRegInfo();
69
3.33k
  const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
70
3.33k
  DebugLoc DL;
71
3.33k
  unsigned V0, V1;
72
3.33k
  const TargetRegisterClass *RC;
73
3.33k
  const MipsABIInfo &ABI =
74
3.33k
      static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI();
75
3.33k
  RC = (ABI.IsN64()) ? 
&Mips::GPR64RegClass1.14k
:
&Mips::GPR32RegClass2.19k
;
76
3.33k
77
3.33k
  V0 = RegInfo.createVirtualRegister(RC);
78
3.33k
  V1 = RegInfo.createVirtualRegister(RC);
79
3.33k
80
3.33k
  if (ABI.IsN64()) {
81
1.14k
    MF.getRegInfo().addLiveIn(Mips::T9_64);
82
1.14k
    MBB.addLiveIn(Mips::T9_64);
83
1.14k
84
1.14k
    // lui $v0, %hi(%neg(%gp_rel(fname)))
85
1.14k
    // daddu $v1, $v0, $t9
86
1.14k
    // daddiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
87
1.14k
    const GlobalValue *FName = &MF.getFunction();
88
1.14k
    BuildMI(MBB, I, DL, TII.get(Mips::LUi64), V0)
89
1.14k
        .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
90
1.14k
    BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0)
91
1.14k
        .addReg(Mips::T9_64);
92
1.14k
    BuildMI(MBB, I, DL, TII.get(Mips::DADDiu), GlobalBaseReg).addReg(V1)
93
1.14k
        .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
94
1.14k
    return;
95
1.14k
  }
96
2.19k
97
2.19k
  if (!MF.getTarget().isPositionIndependent()) {
98
7
    // Set global register to __gnu_local_gp.
99
7
    //
100
7
    // lui   $v0, %hi(__gnu_local_gp)
101
7
    // addiu $globalbasereg, $v0, %lo(__gnu_local_gp)
102
7
    BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
103
7
        .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI);
104
7
    BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0)
105
7
        .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO);
106
7
    return;
107
7
  }
108
2.18k
109
2.18k
  MF.getRegInfo().addLiveIn(Mips::T9);
110
2.18k
  MBB.addLiveIn(Mips::T9);
111
2.18k
112
2.18k
  if (ABI.IsN32()) {
113
227
    // lui $v0, %hi(%neg(%gp_rel(fname)))
114
227
    // addu $v1, $v0, $t9
115
227
    // addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
116
227
    const GlobalValue *FName = &MF.getFunction();
117
227
    BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
118
227
        .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
119
227
    BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9);
120
227
    BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1)
121
227
        .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
122
227
    return;
123
227
  }
124
1.95k
125
1.95k
  assert(ABI.IsO32());
126
1.95k
127
1.95k
  // For O32 ABI, the following instruction sequence is emitted to initialize
128
1.95k
  // the global base register:
129
1.95k
  //
130
1.95k
  //  0. lui   $2, %hi(_gp_disp)
131
1.95k
  //  1. addiu $2, $2, %lo(_gp_disp)
132
1.95k
  //  2. addu  $globalbasereg, $2, $t9
133
1.95k
  //
134
1.95k
  // We emit only the last instruction here.
135
1.95k
  //
136
1.95k
  // GNU linker requires that the first two instructions appear at the beginning
137
1.95k
  // of a function and no instructions be inserted before or between them.
138
1.95k
  // The two instructions are emitted during lowering to MC layer in order to
139
1.95k
  // avoid any reordering.
140
1.95k
  //
141
1.95k
  // Register $2 (Mips::V0) is added to the list of live-in registers to ensure
142
1.95k
  // the value instruction 1 (addiu) defines is valid when instruction 2 (addu)
143
1.95k
  // reads it.
144
1.95k
  MF.getRegInfo().addLiveIn(Mips::V0);
145
1.95k
  MBB.addLiveIn(Mips::V0);
146
1.95k
  BuildMI(MBB, I, DL, TII.get(Mips::ADDu), GlobalBaseReg)
147
1.95k
      .addReg(Mips::V0).addReg(Mips::T9);
148
1.95k
}
149
150
14
void MipsFunctionInfo::createEhDataRegsFI() {
151
14
  const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
152
70
  for (int I = 0; I < 4; 
++I56
) {
153
56
    const TargetRegisterClass &RC =
154
56
        static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI().IsN64()
155
56
            ? 
Mips::GPR64RegClass32
156
56
            : 
Mips::GPR32RegClass24
;
157
56
158
56
    EhDataRegFI[I] = MF.getFrameInfo().CreateStackObject(TRI.getSpillSize(RC),
159
56
        TRI.getSpillAlignment(RC), false);
160
56
  }
161
14
}
162
163
11
void MipsFunctionInfo::createISRRegFI() {
164
11
  // ISRs require spill slots for Status & ErrorPC Coprocessor 0 registers.
165
11
  // The current implementation only supports Mips32r2+ not Mips64rX. Status
166
11
  // is always 32 bits, ErrorPC is 32 or 64 bits dependent on architecture,
167
11
  // however Mips32r2+ is the supported architecture.
168
11
  const TargetRegisterClass &RC = Mips::GPR32RegClass;
169
11
  const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
170
11
171
33
  for (int I = 0; I < 2; 
++I22
)
172
22
    ISRDataRegFI[I] = MF.getFrameInfo().CreateStackObject(
173
22
        TRI.getSpillSize(RC), TRI.getSpillAlignment(RC), false);
174
11
}
175
176
13.8k
bool MipsFunctionInfo::isEhDataRegFI(int FI) const {
177
13.8k
  return CallsEhReturn && 
(162
FI == EhDataRegFI[0]162
||
FI == EhDataRegFI[1]134
178
162
                        || 
FI == EhDataRegFI[2]106
||
FI == EhDataRegFI[3]78
);
179
13.8k
}
180
181
13.8k
bool MipsFunctionInfo::isISRRegFI(int FI) const {
182
13.8k
  return IsISR && 
(78
FI == ISRDataRegFI[0]78
||
FI == ISRDataRegFI[1]60
);
183
13.8k
}
184
644
MachinePointerInfo MipsFunctionInfo::callPtrInfo(const char *ES) {
185
644
  return MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES));
186
644
}
187
188
1.13k
MachinePointerInfo MipsFunctionInfo::callPtrInfo(const GlobalValue *GV) {
189
1.13k
  return MachinePointerInfo(MF.getPSVManager().getGlobalValueCallEntry(GV));
190
1.13k
}
191
192
29
int MipsFunctionInfo::getMoveF64ViaSpillFI(const TargetRegisterClass *RC) {
193
29
  const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
194
29
  if (MoveF64ViaSpillFI == -1) {
195
23
    MoveF64ViaSpillFI = MF.getFrameInfo().CreateStackObject(
196
23
        TRI.getSpillSize(*RC), TRI.getSpillAlignment(*RC), false);
197
23
  }
198
29
  return MoveF64ViaSpillFI;
199
29
}
200
201
0
void MipsFunctionInfo::anchor() {}