Coverage Report

Created: 2017-10-03 07:32

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