Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/XCore/XCoreRegisterInfo.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- XCoreRegisterInfo.cpp - XCore 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 XCore implementation of the MRegisterInfo class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "XCoreRegisterInfo.h"
14
#include "XCore.h"
15
#include "XCoreInstrInfo.h"
16
#include "XCoreMachineFunctionInfo.h"
17
#include "XCoreSubtarget.h"
18
#include "llvm/ADT/BitVector.h"
19
#include "llvm/ADT/STLExtras.h"
20
#include "llvm/CodeGen/MachineFrameInfo.h"
21
#include "llvm/CodeGen/MachineFunction.h"
22
#include "llvm/CodeGen/MachineInstrBuilder.h"
23
#include "llvm/CodeGen/MachineModuleInfo.h"
24
#include "llvm/CodeGen/MachineRegisterInfo.h"
25
#include "llvm/CodeGen/RegisterScavenging.h"
26
#include "llvm/IR/Function.h"
27
#include "llvm/IR/Type.h"
28
#include "llvm/Support/Debug.h"
29
#include "llvm/Support/ErrorHandling.h"
30
#include "llvm/Support/MathExtras.h"
31
#include "llvm/Support/raw_ostream.h"
32
#include "llvm/CodeGen/TargetFrameLowering.h"
33
#include "llvm/Target/TargetMachine.h"
34
#include "llvm/Target/TargetOptions.h"
35
36
using namespace llvm;
37
38
#define DEBUG_TYPE "xcore-reg-info"
39
40
#define GET_REGINFO_TARGET_DESC
41
#include "XCoreGenRegisterInfo.inc"
42
43
XCoreRegisterInfo::XCoreRegisterInfo()
44
81
  : XCoreGenRegisterInfo(XCore::LR) {
45
81
}
46
47
// helper functions
48
78
static inline bool isImmUs(unsigned val) {
49
78
  return val <= 11;
50
78
}
51
52
153
static inline bool isImmU6(unsigned val) {
53
153
  return val < (1 << 6);
54
153
}
55
56
162
static inline bool isImmU16(unsigned val) {
57
162
  return val < (1 << 16);
58
162
}
59
60
61
static void InsertFPImmInst(MachineBasicBlock::iterator II,
62
                            const XCoreInstrInfo &TII,
63
59
                            unsigned Reg, unsigned FrameReg, int Offset ) {
64
59
  MachineInstr &MI = *II;
65
59
  MachineBasicBlock &MBB = *MI.getParent();
66
59
  DebugLoc dl = MI.getDebugLoc();
67
59
68
59
  switch (MI.getOpcode()) {
69
59
  case XCore::LDWFI:
70
32
    BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg)
71
32
          .addReg(FrameReg)
72
32
          .addImm(Offset)
73
32
          .addMemOperand(*MI.memoperands_begin());
74
32
    break;
75
59
  case XCore::STWFI:
76
25
    BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus))
77
25
          .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
78
25
          .addReg(FrameReg)
79
25
          .addImm(Offset)
80
25
          .addMemOperand(*MI.memoperands_begin());
81
25
    break;
82
59
  case XCore::LDAWFI:
83
2
    BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg)
84
2
          .addReg(FrameReg)
85
2
          .addImm(Offset);
86
2
    break;
87
59
  default:
88
0
    llvm_unreachable("Unexpected Opcode");
89
59
  }
90
59
}
91
92
static void InsertFPConstInst(MachineBasicBlock::iterator II,
93
                              const XCoreInstrInfo &TII,
94
                              unsigned Reg, unsigned FrameReg,
95
19
                              int Offset, RegScavenger *RS ) {
96
19
  assert(RS && "requiresRegisterScavenging failed");
97
19
  MachineInstr &MI = *II;
98
19
  MachineBasicBlock &MBB = *MI.getParent();
99
19
  DebugLoc dl = MI.getDebugLoc();
100
19
  unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
101
19
  RS->setRegUsed(ScratchOffset);
102
19
  TII.loadImmediate(MBB, II, ScratchOffset, Offset);
103
19
104
19
  switch (MI.getOpcode()) {
105
19
  case XCore::LDWFI:
106
8
    BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg)
107
8
          .addReg(FrameReg)
108
8
          .addReg(ScratchOffset, RegState::Kill)
109
8
          .addMemOperand(*MI.memoperands_begin());
110
8
    break;
111
19
  case XCore::STWFI:
112
8
    BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r))
113
8
          .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
114
8
          .addReg(FrameReg)
115
8
          .addReg(ScratchOffset, RegState::Kill)
116
8
          .addMemOperand(*MI.memoperands_begin());
117
8
    break;
118
19
  case XCore::LDAWFI:
119
3
    BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg)
120
3
          .addReg(FrameReg)
121
3
          .addReg(ScratchOffset, RegState::Kill);
122
3
    break;
123
19
  default:
124
0
    llvm_unreachable("Unexpected Opcode");
125
19
  }
126
19
}
127
128
static void InsertSPImmInst(MachineBasicBlock::iterator II,
129
                            const XCoreInstrInfo &TII,
130
153
                            unsigned Reg, int Offset) {
131
153
  MachineInstr &MI = *II;
132
153
  MachineBasicBlock &MBB = *MI.getParent();
133
153
  DebugLoc dl = MI.getDebugLoc();
134
153
  bool isU6 = isImmU6(Offset);
135
153
136
153
  switch (MI.getOpcode()) {
137
153
  int NewOpcode;
138
69
  case XCore::LDWFI:
139
69
    NewOpcode = (isU6) ? 
XCore::LDWSP_ru668
:
XCore::LDWSP_lru61
;
140
69
    BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)
141
69
          .addImm(Offset)
142
69
          .addMemOperand(*MI.memoperands_begin());
143
69
    break;
144
74
  case XCore::STWFI:
145
74
    NewOpcode = (isU6) ? XCore::STWSP_ru6 : 
XCore::STWSP_lru60
;
146
74
    BuildMI(MBB, II, dl, TII.get(NewOpcode))
147
74
          .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
148
74
          .addImm(Offset)
149
74
          .addMemOperand(*MI.memoperands_begin());
150
74
    break;
151
10
  case XCore::LDAWFI:
152
10
    NewOpcode = (isU6) ? 
XCore::LDAWSP_ru68
:
XCore::LDAWSP_lru62
;
153
10
    BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)
154
10
          .addImm(Offset);
155
10
    break;
156
0
  default:
157
0
    llvm_unreachable("Unexpected Opcode");
158
153
  }
159
153
}
160
161
static void InsertSPConstInst(MachineBasicBlock::iterator II,
162
                                const XCoreInstrInfo &TII,
163
9
                                unsigned Reg, int Offset, RegScavenger *RS ) {
164
9
  assert(RS && "requiresRegisterScavenging failed");
165
9
  MachineInstr &MI = *II;
166
9
  MachineBasicBlock &MBB = *MI.getParent();
167
9
  DebugLoc dl = MI.getDebugLoc();
168
9
  unsigned OpCode = MI.getOpcode();
169
9
170
9
  unsigned ScratchBase;
171
9
  if (OpCode==XCore::STWFI) {
172
6
    ScratchBase = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
173
6
    RS->setRegUsed(ScratchBase);
174
6
  } else
175
3
    ScratchBase = Reg;
176
9
  BuildMI(MBB, II, dl, TII.get(XCore::LDAWSP_ru6), ScratchBase).addImm(0);
177
9
  unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
178
9
  RS->setRegUsed(ScratchOffset);
179
9
  TII.loadImmediate(MBB, II, ScratchOffset, Offset);
180
9
181
9
  switch (OpCode) {
182
9
  case XCore::LDWFI:
183
2
    BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg)
184
2
          .addReg(ScratchBase, RegState::Kill)
185
2
          .addReg(ScratchOffset, RegState::Kill)
186
2
          .addMemOperand(*MI.memoperands_begin());
187
2
    break;
188
9
  case XCore::STWFI:
189
6
    BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r))
190
6
          .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
191
6
          .addReg(ScratchBase, RegState::Kill)
192
6
          .addReg(ScratchOffset, RegState::Kill)
193
6
          .addMemOperand(*MI.memoperands_begin());
194
6
    break;
195
9
  case XCore::LDAWFI:
196
1
    BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg)
197
1
          .addReg(ScratchBase, RegState::Kill)
198
1
          .addReg(ScratchOffset, RegState::Kill);
199
1
    break;
200
9
  default:
201
0
    llvm_unreachable("Unexpected Opcode");
202
9
  }
203
9
}
204
205
300
bool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) {
206
300
  return MF.getMMI().hasDebugInfo() || 
MF.getFunction().needsUnwindTableEntry()298
;
207
300
}
208
209
const MCPhysReg *
210
1.78k
XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
211
1.78k
  // The callee saved registers LR & FP are explicitly handled during
212
1.78k
  // emitPrologue & emitEpilogue and related functions.
213
1.78k
  static const MCPhysReg CalleeSavedRegs[] = {
214
1.78k
    XCore::R4, XCore::R5, XCore::R6, XCore::R7,
215
1.78k
    XCore::R8, XCore::R9, XCore::R10,
216
1.78k
    0
217
1.78k
  };
218
1.78k
  static const MCPhysReg CalleeSavedRegsFP[] = {
219
1.78k
    XCore::R4, XCore::R5, XCore::R6, XCore::R7,
220
1.78k
    XCore::R8, XCore::R9,
221
1.78k
    0
222
1.78k
  };
223
1.78k
  const XCoreFrameLowering *TFI = getFrameLowering(*MF);
224
1.78k
  if (TFI->hasFP(*MF))
225
142
    return CalleeSavedRegsFP;
226
1.63k
  return CalleeSavedRegs;
227
1.63k
}
228
229
874
BitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
230
874
  BitVector Reserved(getNumRegs());
231
874
  const XCoreFrameLowering *TFI = getFrameLowering(MF);
232
874
233
874
  Reserved.set(XCore::CP);
234
874
  Reserved.set(XCore::DP);
235
874
  Reserved.set(XCore::SP);
236
874
  Reserved.set(XCore::LR);
237
874
  if (TFI->hasFP(MF)) {
238
79
    Reserved.set(XCore::R10);
239
79
  }
240
874
  return Reserved;
241
874
}
242
243
bool
244
559
XCoreRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
245
559
  return true;
246
559
}
247
248
bool
249
269
XCoreRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const {
250
269
  return true;
251
269
}
252
253
bool
254
20
XCoreRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const {
255
20
  return false;
256
20
}
257
258
void
259
XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
260
                                       int SPAdj, unsigned FIOperandNum,
261
240
                                       RegScavenger *RS) const {
262
240
  assert(SPAdj == 0 && "Unexpected");
263
240
  MachineInstr &MI = *II;
264
240
  MachineOperand &FrameOp = MI.getOperand(FIOperandNum);
265
240
  int FrameIndex = FrameOp.getIndex();
266
240
267
240
  MachineFunction &MF = *MI.getParent()->getParent();
268
240
  const XCoreInstrInfo &TII =
269
240
      *static_cast<const XCoreInstrInfo *>(MF.getSubtarget().getInstrInfo());
270
240
271
240
  const XCoreFrameLowering *TFI = getFrameLowering(MF);
272
240
  int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex);
273
240
  int StackSize = MF.getFrameInfo().getStackSize();
274
240
275
  #ifndef NDEBUG
276
  LLVM_DEBUG(errs() << "\nFunction         : " << MF.getName() << "\n");
277
  LLVM_DEBUG(errs() << "<--------->\n");
278
  LLVM_DEBUG(MI.print(errs()));
279
  LLVM_DEBUG(errs() << "FrameIndex         : " << FrameIndex << "\n");
280
  LLVM_DEBUG(errs() << "FrameOffset        : " << Offset << "\n");
281
  LLVM_DEBUG(errs() << "StackSize          : " << StackSize << "\n");
282
#endif
283
284
240
  Offset += StackSize;
285
240
286
240
  Register FrameReg = getFrameRegister(MF);
287
240
288
240
  // Special handling of DBG_VALUE instructions.
289
240
  if (MI.isDebugValue()) {
290
0
    MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/);
291
0
    MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
292
0
    return;
293
0
  }
294
240
295
240
  // fold constant into offset.
296
240
  Offset += MI.getOperand(FIOperandNum + 1).getImm();
297
240
  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);
298
240
299
240
  assert(Offset%4 == 0 && "Misaligned stack offset");
300
240
  LLVM_DEBUG(errs() << "Offset             : " << Offset << "\n"
301
240
                    << "<--------->\n");
302
240
  Offset/=4;
303
240
304
240
  unsigned Reg = MI.getOperand(0).getReg();
305
240
  assert(XCore::GRRegsRegClass.contains(Reg) && "Unexpected register operand");
306
240
307
240
  if (TFI->hasFP(MF)) {
308
78
    if (isImmUs(Offset))
309
59
      InsertFPImmInst(II, TII, Reg, FrameReg, Offset);
310
19
    else
311
19
      InsertFPConstInst(II, TII, Reg, FrameReg, Offset, RS);
312
162
  } else {
313
162
    if (isImmU16(Offset))
314
153
      InsertSPImmInst(II, TII, Reg, Offset);
315
9
    else
316
9
      InsertSPConstInst(II, TII, Reg, Offset, RS);
317
162
  }
318
240
  // Erase old instruction.
319
240
  MachineBasicBlock &MBB = *MI.getParent();
320
240
  MBB.erase(II);
321
240
}
322
323
324
264
Register XCoreRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
325
264
  const XCoreFrameLowering *TFI = getFrameLowering(MF);
326
264
327
264
  return TFI->hasFP(MF) ? 
XCore::R1086
:
XCore::SP178
;
328
264
}