Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- HexagonRegisterInfo.cpp - Hexagon Register Information ------------===//
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
// This file contains the Hexagon implementation of the TargetRegisterInfo
10
// class.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "HexagonRegisterInfo.h"
15
#include "Hexagon.h"
16
#include "HexagonMachineFunctionInfo.h"
17
#include "HexagonSubtarget.h"
18
#include "HexagonTargetMachine.h"
19
#include "llvm/ADT/BitVector.h"
20
#include "llvm/ADT/STLExtras.h"
21
#include "llvm/CodeGen/LiveIntervals.h"
22
#include "llvm/CodeGen/MachineFrameInfo.h"
23
#include "llvm/CodeGen/MachineFunction.h"
24
#include "llvm/CodeGen/MachineFunctionPass.h"
25
#include "llvm/CodeGen/MachineInstrBuilder.h"
26
#include "llvm/CodeGen/MachineRegisterInfo.h"
27
#include "llvm/CodeGen/PseudoSourceValue.h"
28
#include "llvm/CodeGen/RegisterScavenging.h"
29
#include "llvm/CodeGen/TargetInstrInfo.h"
30
#include "llvm/IR/Function.h"
31
#include "llvm/IR/Type.h"
32
#include "llvm/MC/MachineLocation.h"
33
#include "llvm/Support/Debug.h"
34
#include "llvm/Support/ErrorHandling.h"
35
#include "llvm/Support/raw_ostream.h"
36
#include "llvm/Target/TargetMachine.h"
37
#include "llvm/Target/TargetOptions.h"
38
39
#define GET_REGINFO_TARGET_DESC
40
#include "HexagonGenRegisterInfo.inc"
41
42
using namespace llvm;
43
44
HexagonRegisterInfo::HexagonRegisterInfo(unsigned HwMode)
45
    : HexagonGenRegisterInfo(Hexagon::R31, 0/*DwarfFlavor*/, 0/*EHFlavor*/,
46
1.01k
                             0/*PC*/, HwMode) {}
47
48
49
230
bool HexagonRegisterInfo::isEHReturnCalleeSaveReg(unsigned R) const {
50
230
  return R == Hexagon::R0 || R == Hexagon::R1 || R == Hexagon::R2 ||
51
230
         R == Hexagon::R3 || R == Hexagon::D0 || 
R == Hexagon::D1229
;
52
230
}
53
54
const MCPhysReg *
55
HexagonRegisterInfo::getCallerSavedRegs(const MachineFunction *MF,
56
37
      const TargetRegisterClass *RC) const {
57
37
  using namespace Hexagon;
58
37
59
37
  static const MCPhysReg Int32[] = {
60
37
    R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, 0
61
37
  };
62
37
  static const MCPhysReg Int64[] = {
63
37
    D0, D1, D2, D3, D4, D5, D6, D7, 0
64
37
  };
65
37
  static const MCPhysReg Pred[] = {
66
37
    P0, P1, P2, P3, 0
67
37
  };
68
37
  static const MCPhysReg VecSgl[] = {
69
37
     V0,  V1,  V2,  V3,  V4,  V5,  V6,  V7,  V8,  V9, V10, V11, V12, V13,
70
37
    V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27,
71
37
    V28, V29, V30, V31,   0
72
37
  };
73
37
  static const MCPhysReg VecDbl[] = {
74
37
    W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15, 0
75
37
  };
76
37
77
37
  switch (RC->getID()) {
78
37
    case IntRegsRegClassID:
79
34
      return Int32;
80
37
    case DoubleRegsRegClassID:
81
0
      return Int64;
82
37
    case PredRegsRegClassID:
83
0
      return Pred;
84
37
    case HvxVRRegClassID:
85
3
      return VecSgl;
86
37
    case HvxWRRegClassID:
87
0
      return VecDbl;
88
37
    default:
89
0
      break;
90
0
  }
91
0
92
0
  static const MCPhysReg Empty[] = { 0 };
93
#ifndef NDEBUG
94
  dbgs() << "Register class: " << getRegClassName(RC) << "\n";
95
#endif
96
0
  llvm_unreachable("Unexpected register class");
97
0
  return Empty;
98
0
}
99
100
101
const MCPhysReg *
102
58.1k
HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
103
58.1k
  static const MCPhysReg CalleeSavedRegsV3[] = {
104
58.1k
    Hexagon::R16,   Hexagon::R17,   Hexagon::R18,   Hexagon::R19,
105
58.1k
    Hexagon::R20,   Hexagon::R21,   Hexagon::R22,   Hexagon::R23,
106
58.1k
    Hexagon::R24,   Hexagon::R25,   Hexagon::R26,   Hexagon::R27, 0
107
58.1k
  };
108
58.1k
109
58.1k
  // Functions that contain a call to __builtin_eh_return also save the first 4
110
58.1k
  // parameter registers.
111
58.1k
  static const MCPhysReg CalleeSavedRegsV3EHReturn[] = {
112
58.1k
    Hexagon::R0,    Hexagon::R1,    Hexagon::R2,    Hexagon::R3,
113
58.1k
    Hexagon::R16,   Hexagon::R17,   Hexagon::R18,   Hexagon::R19,
114
58.1k
    Hexagon::R20,   Hexagon::R21,   Hexagon::R22,   Hexagon::R23,
115
58.1k
    Hexagon::R24,   Hexagon::R25,   Hexagon::R26,   Hexagon::R27, 0
116
58.1k
  };
117
58.1k
118
58.1k
  bool HasEHReturn = MF->getInfo<HexagonMachineFunctionInfo>()->hasEHReturn();
119
58.1k
120
58.1k
  return HasEHReturn ? 
CalleeSavedRegsV3EHReturn5
:
CalleeSavedRegsV358.1k
;
121
58.1k
}
122
123
124
const uint32_t *HexagonRegisterInfo::getCallPreservedMask(
125
743
      const MachineFunction &MF, CallingConv::ID) const {
126
743
  return HexagonCSR_RegMask;
127
743
}
128
129
130
BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF)
131
25.7k
  const {
132
25.7k
  BitVector Reserved(getNumRegs());
133
25.7k
  Reserved.set(Hexagon::R29);
134
25.7k
  Reserved.set(Hexagon::R30);
135
25.7k
  Reserved.set(Hexagon::R31);
136
25.7k
  Reserved.set(Hexagon::VTMP);
137
25.7k
138
25.7k
  // Guest registers.
139
25.7k
  Reserved.set(Hexagon::GELR);        // G0
140
25.7k
  Reserved.set(Hexagon::GSR);         // G1
141
25.7k
  Reserved.set(Hexagon::GOSP);        // G2
142
25.7k
  Reserved.set(Hexagon::G3);          // G3
143
25.7k
144
25.7k
  // Control registers.
145
25.7k
  Reserved.set(Hexagon::SA0);         // C0
146
25.7k
  Reserved.set(Hexagon::LC0);         // C1
147
25.7k
  Reserved.set(Hexagon::SA1);         // C2
148
25.7k
  Reserved.set(Hexagon::LC1);         // C3
149
25.7k
  Reserved.set(Hexagon::P3_0);        // C4
150
25.7k
  Reserved.set(Hexagon::USR);         // C8
151
25.7k
  Reserved.set(Hexagon::PC);          // C9
152
25.7k
  Reserved.set(Hexagon::UGP);         // C10
153
25.7k
  Reserved.set(Hexagon::GP);          // C11
154
25.7k
  Reserved.set(Hexagon::CS0);         // C12
155
25.7k
  Reserved.set(Hexagon::CS1);         // C13
156
25.7k
  Reserved.set(Hexagon::UPCYCLELO);   // C14
157
25.7k
  Reserved.set(Hexagon::UPCYCLEHI);   // C15
158
25.7k
  Reserved.set(Hexagon::FRAMELIMIT);  // C16
159
25.7k
  Reserved.set(Hexagon::FRAMEKEY);    // C17
160
25.7k
  Reserved.set(Hexagon::PKTCOUNTLO);  // C18
161
25.7k
  Reserved.set(Hexagon::PKTCOUNTHI);  // C19
162
25.7k
  Reserved.set(Hexagon::UTIMERLO);    // C30
163
25.7k
  Reserved.set(Hexagon::UTIMERHI);    // C31
164
25.7k
  // Out of the control registers, only C8 is explicitly defined in
165
25.7k
  // HexagonRegisterInfo.td. If others are defined, make sure to add
166
25.7k
  // them here as well.
167
25.7k
  Reserved.set(Hexagon::C8);
168
25.7k
  Reserved.set(Hexagon::USR_OVF);
169
25.7k
170
25.7k
  if (MF.getSubtarget<HexagonSubtarget>().hasReservedR19())
171
5
    Reserved.set(Hexagon::R19);
172
25.7k
173
951k
  for (int x = Reserved.find_first(); x >= 0; 
x = Reserved.find_next(x)925k
)
174
925k
    markSuperRegs(Reserved, x);
175
25.7k
176
25.7k
  return Reserved;
177
25.7k
}
178
179
180
void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
181
                                              int SPAdj, unsigned FIOp,
182
1.78k
                                              RegScavenger *RS) const {
183
1.78k
  //
184
1.78k
  // Hexagon_TODO: Do we need to enforce this for Hexagon?
185
1.78k
  assert(SPAdj == 0 && "Unexpected");
186
1.78k
187
1.78k
  MachineInstr &MI = *II;
188
1.78k
  MachineBasicBlock &MB = *MI.getParent();
189
1.78k
  MachineFunction &MF = *MB.getParent();
190
1.78k
  auto &HST = MF.getSubtarget<HexagonSubtarget>();
191
1.78k
  auto &HII = *HST.getInstrInfo();
192
1.78k
  auto &HFI = *HST.getFrameLowering();
193
1.78k
194
1.78k
  unsigned BP = 0;
195
1.78k
  int FI = MI.getOperand(FIOp).getIndex();
196
1.78k
  // Select the base pointer (BP) and calculate the actual offset from BP
197
1.78k
  // to the beginning of the object at index FI.
198
1.78k
  int Offset = HFI.getFrameIndexReference(MF, FI, BP);
199
1.78k
  // Add the offset from the instruction.
200
1.78k
  int RealOffset = Offset + MI.getOperand(FIOp+1).getImm();
201
1.78k
  bool IsKill = false;
202
1.78k
203
1.78k
  unsigned Opc = MI.getOpcode();
204
1.78k
  switch (Opc) {
205
1.78k
    case Hexagon::PS_fia:
206
1
      MI.setDesc(HII.get(Hexagon::A2_addi));
207
1
      MI.getOperand(FIOp).ChangeToImmediate(RealOffset);
208
1
      MI.RemoveOperand(FIOp+1);
209
1
      return;
210
1.78k
    case Hexagon::PS_fi:
211
173
      // Set up the instruction for updating below.
212
173
      MI.setDesc(HII.get(Hexagon::A2_addi));
213
173
      break;
214
1.78k
  }
215
1.78k
216
1.78k
  if (!HII.isValidOffset(Opc, RealOffset, this)) {
217
23
    // If the offset is not valid, calculate the address in a temporary
218
23
    // register and use it with offset 0.
219
23
    auto &MRI = MF.getRegInfo();
220
23
    unsigned TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
221
23
    const DebugLoc &DL = MI.getDebugLoc();
222
23
    BuildMI(MB, II, DL, HII.get(Hexagon::A2_addi), TmpR)
223
23
      .addReg(BP)
224
23
      .addImm(RealOffset);
225
23
    BP = TmpR;
226
23
    RealOffset = 0;
227
23
    IsKill = true;
228
23
  }
229
1.78k
230
1.78k
  MI.getOperand(FIOp).ChangeToRegister(BP, false, false, IsKill);
231
1.78k
  MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset);
232
1.78k
}
233
234
235
bool HexagonRegisterInfo::shouldCoalesce(MachineInstr *MI,
236
      const TargetRegisterClass *SrcRC, unsigned SubReg,
237
      const TargetRegisterClass *DstRC, unsigned DstSubReg,
238
7.54k
      const TargetRegisterClass *NewRC, LiveIntervals &LIS) const {
239
7.54k
  // Coalescing will extend the live interval of the destination register.
240
7.54k
  // If the destination register is a vector pair, avoid introducing function
241
7.54k
  // calls into the interval, since it could result in a spilling of a pair
242
7.54k
  // instead of a single vector.
243
7.54k
  MachineFunction &MF = *MI->getParent()->getParent();
244
7.54k
  const HexagonSubtarget &HST = MF.getSubtarget<HexagonSubtarget>();
245
7.54k
  if (!HST.useHVXOps() || 
NewRC->getID() != Hexagon::HvxWRRegClass.getID()3.67k
)
246
6.38k
    return true;
247
1.16k
  bool SmallSrc = SrcRC->getID() == Hexagon::HvxVRRegClass.getID();
248
1.16k
  bool SmallDst = DstRC->getID() == Hexagon::HvxVRRegClass.getID();
249
1.16k
  if (!SmallSrc && 
!SmallDst364
)
250
319
    return true;
251
850
252
850
  unsigned DstReg = MI->getOperand(0).getReg();
253
850
  unsigned SrcReg = MI->getOperand(1).getReg();
254
850
  const SlotIndexes &Indexes = *LIS.getSlotIndexes();
255
3.30k
  auto HasCall = [&Indexes] (const LiveInterval::Segment &S) {
256
3.30k
    for (SlotIndex I = S.start.getBaseIndex(), E = S.end.getBaseIndex();
257
31.7k
         I != E; 
I = I.getNextIndex()28.3k
) {
258
28.4k
      if (const MachineInstr *MI = Indexes.getInstructionFromIndex(I))
259
16.4k
        if (MI->isCall())
260
3
          return true;
261
28.4k
    }
262
3.30k
    
return false3.30k
;
263
3.30k
  };
264
850
265
850
  if (SmallSrc == SmallDst) {
266
0
    // Both must be true, because the case for both being false was
267
0
    // checked earlier. Both registers will be coalesced into a register
268
0
    // of a wider class (HvxWR), and we don't want its live range to
269
0
    // span over calls.
270
0
    return !any_of(LIS.getInterval(DstReg), HasCall) &&
271
0
           !any_of(LIS.getInterval(SrcReg), HasCall);
272
0
  }
273
850
274
850
  // If one register is large (HvxWR) and the other is small (HvxVR), then
275
850
  // coalescing is ok if the large is already live across a function call,
276
850
  // or if the small one is not.
277
850
  unsigned SmallReg = SmallSrc ? 
SrcReg805
:
DstReg45
;
278
850
  unsigned LargeReg = SmallSrc ? 
DstReg805
:
SrcReg45
;
279
850
  return  any_of(LIS.getInterval(LargeReg), HasCall) ||
280
850
         !any_of(LIS.getInterval(SmallReg), HasCall);
281
850
}
282
283
284
5.30k
unsigned HexagonRegisterInfo::getRARegister() const {
285
5.30k
  return Hexagon::R31;
286
5.30k
}
287
288
289
Register HexagonRegisterInfo::getFrameRegister(const MachineFunction
290
50
                                               &MF) const {
291
50
  const HexagonFrameLowering *TFI = getFrameLowering(MF);
292
50
  if (TFI->hasFP(MF))
293
26
    return getFrameRegister();
294
24
  return getStackRegister();
295
24
}
296
297
298
3.61k
unsigned HexagonRegisterInfo::getFrameRegister() const {
299
3.61k
  return Hexagon::R30;
300
3.61k
}
301
302
303
15.7k
unsigned HexagonRegisterInfo::getStackRegister() const {
304
15.7k
  return Hexagon::R29;
305
15.7k
}
306
307
308
unsigned HexagonRegisterInfo::getHexagonSubRegIndex(
309
46.1k
      const TargetRegisterClass &RC, unsigned GenIdx) const {
310
46.1k
  assert(GenIdx == Hexagon::ps_sub_lo || GenIdx == Hexagon::ps_sub_hi);
311
46.1k
312
46.1k
  static const unsigned ISub[] = { Hexagon::isub_lo, Hexagon::isub_hi };
313
46.1k
  static const unsigned VSub[] = { Hexagon::vsub_lo, Hexagon::vsub_hi };
314
46.1k
  static const unsigned WSub[] = { Hexagon::wsub_lo, Hexagon::wsub_hi };
315
46.1k
316
46.1k
  switch (RC.getID()) {
317
46.1k
    case Hexagon::CtrRegs64RegClassID:
318
12.4k
    case Hexagon::DoubleRegsRegClassID:
319
12.4k
      return ISub[GenIdx];
320
33.6k
    case Hexagon::HvxWRRegClassID:
321
33.6k
      return VSub[GenIdx];
322
12.4k
    case Hexagon::HvxVQRRegClassID:
323
0
      return WSub[GenIdx];
324
0
  }
325
0
326
0
  if (const TargetRegisterClass *SuperRC = *RC.getSuperClasses())
327
0
    return getHexagonSubRegIndex(*SuperRC, GenIdx);
328
0
329
0
  llvm_unreachable("Invalid register class");
330
0
}
331
332
bool HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF)
333
1.88k
      const {
334
1.88k
  return MF.getSubtarget<HexagonSubtarget>().getFrameLowering()->hasFP(MF);
335
1.88k
}
336
337
const TargetRegisterClass *
338
HexagonRegisterInfo::getPointerRegClass(const MachineFunction &MF,
339
0
                                        unsigned Kind) const {
340
0
  return &Hexagon::IntRegsRegClass;
341
0
}
342
343
0
unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const {
344
0
  return Hexagon::R6;
345
0
}
346