Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Lanai/LanaiRegisterInfo.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- LanaiRegisterInfo.cpp - Lanai Register Information ------*- C++ -*-===//
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 Lanai implementation of the TargetRegisterInfo class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "LanaiRegisterInfo.h"
14
#include "LanaiAluCode.h"
15
#include "LanaiCondCode.h"
16
#include "LanaiFrameLowering.h"
17
#include "LanaiInstrInfo.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/RegisterScavenging.h"
24
#include "llvm/CodeGen/TargetFrameLowering.h"
25
#include "llvm/CodeGen/TargetInstrInfo.h"
26
#include "llvm/IR/Function.h"
27
#include "llvm/IR/Type.h"
28
#include "llvm/Support/ErrorHandling.h"
29
30
#define GET_REGINFO_TARGET_DESC
31
#include "LanaiGenRegisterInfo.inc"
32
33
using namespace llvm;
34
35
27
LanaiRegisterInfo::LanaiRegisterInfo() : LanaiGenRegisterInfo(Lanai::RCA) {}
36
37
const uint16_t *
38
775
LanaiRegisterInfo::getCalleeSavedRegs(const MachineFunction * /*MF*/) const {
39
775
  return CSR_SaveList;
40
775
}
41
42
285
BitVector LanaiRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
43
285
  BitVector Reserved(getNumRegs());
44
285
45
285
  Reserved.set(Lanai::R0);
46
285
  Reserved.set(Lanai::R1);
47
285
  Reserved.set(Lanai::PC);
48
285
  Reserved.set(Lanai::R2);
49
285
  Reserved.set(Lanai::SP);
50
285
  Reserved.set(Lanai::R4);
51
285
  Reserved.set(Lanai::FP);
52
285
  Reserved.set(Lanai::R5);
53
285
  Reserved.set(Lanai::RR1);
54
285
  Reserved.set(Lanai::R10);
55
285
  Reserved.set(Lanai::RR2);
56
285
  Reserved.set(Lanai::R11);
57
285
  Reserved.set(Lanai::RCA);
58
285
  Reserved.set(Lanai::R15);
59
285
  if (hasBasePointer(MF))
60
0
    Reserved.set(getBaseRegister());
61
285
  return Reserved;
62
285
}
63
64
bool LanaiRegisterInfo::requiresRegisterScavenging(
65
184
    const MachineFunction & /*MF*/) const {
66
184
  return true;
67
184
}
68
69
bool LanaiRegisterInfo::trackLivenessAfterRegAlloc(
70
95
    const MachineFunction & /*MF*/) const {
71
95
  return true;
72
95
}
73
74
4
static bool isALUArithLoOpcode(unsigned Opcode) {
75
4
  switch (Opcode) {
76
4
  case Lanai::ADD_I_LO:
77
0
  case Lanai::SUB_I_LO:
78
0
  case Lanai::ADD_F_I_LO:
79
0
  case Lanai::SUB_F_I_LO:
80
0
  case Lanai::ADDC_I_LO:
81
0
  case Lanai::SUBB_I_LO:
82
0
  case Lanai::ADDC_F_I_LO:
83
0
  case Lanai::SUBB_F_I_LO:
84
0
    return true;
85
4
  default:
86
4
    return false;
87
4
  }
88
4
}
89
90
0
static unsigned getOppositeALULoOpcode(unsigned Opcode) {
91
0
  switch (Opcode) {
92
0
  case Lanai::ADD_I_LO:
93
0
    return Lanai::SUB_I_LO;
94
0
  case Lanai::SUB_I_LO:
95
0
    return Lanai::ADD_I_LO;
96
0
  case Lanai::ADD_F_I_LO:
97
0
    return Lanai::SUB_F_I_LO;
98
0
  case Lanai::SUB_F_I_LO:
99
0
    return Lanai::ADD_F_I_LO;
100
0
  case Lanai::ADDC_I_LO:
101
0
    return Lanai::SUBB_I_LO;
102
0
  case Lanai::SUBB_I_LO:
103
0
    return Lanai::ADDC_I_LO;
104
0
  case Lanai::ADDC_F_I_LO:
105
0
    return Lanai::SUBB_F_I_LO;
106
0
  case Lanai::SUBB_F_I_LO:
107
0
    return Lanai::ADDC_F_I_LO;
108
0
  default:
109
0
    llvm_unreachable("Invalid ALU lo opcode");
110
0
  }
111
0
}
112
113
0
static unsigned getRRMOpcodeVariant(unsigned Opcode) {
114
0
  switch (Opcode) {
115
0
  case Lanai::LDBs_RI:
116
0
    return Lanai::LDBs_RR;
117
0
  case Lanai::LDBz_RI:
118
0
    return Lanai::LDBz_RR;
119
0
  case Lanai::LDHs_RI:
120
0
    return Lanai::LDHs_RR;
121
0
  case Lanai::LDHz_RI:
122
0
    return Lanai::LDHz_RR;
123
0
  case Lanai::LDW_RI:
124
0
    return Lanai::LDW_RR;
125
0
  case Lanai::STB_RI:
126
0
    return Lanai::STB_RR;
127
0
  case Lanai::STH_RI:
128
0
    return Lanai::STH_RR;
129
0
  case Lanai::SW_RI:
130
0
    return Lanai::SW_RR;
131
0
  default:
132
0
    llvm_unreachable("Opcode has no RRM variant");
133
0
  }
134
0
}
135
136
void LanaiRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
137
                                            int SPAdj, unsigned FIOperandNum,
138
56
                                            RegScavenger *RS) const {
139
56
  assert(SPAdj == 0 && "Unexpected");
140
56
141
56
  MachineInstr &MI = *II;
142
56
  MachineFunction &MF = *MI.getParent()->getParent();
143
56
  const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
144
56
  const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
145
56
  bool HasFP = TFI->hasFP(MF);
146
56
  DebugLoc DL = MI.getDebugLoc();
147
56
148
56
  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
149
56
150
56
  int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) +
151
56
               MI.getOperand(FIOperandNum + 1).getImm();
152
56
153
56
  // Addressable stack objects are addressed using neg. offsets from fp
154
56
  // or pos. offsets from sp/basepointer
155
56
  if (!HasFP || (needsStackRealignment(MF) && 
FrameIndex >= 00
))
156
0
    Offset += MF.getFrameInfo().getStackSize();
157
56
158
56
  unsigned FrameReg = getFrameRegister(MF);
159
56
  if (FrameIndex >= 0) {
160
4
    if (hasBasePointer(MF))
161
0
      FrameReg = getBaseRegister();
162
4
    else if (needsStackRealignment(MF))
163
0
      FrameReg = Lanai::SP;
164
4
  }
165
56
166
56
  // Replace frame index with a frame pointer reference.
167
56
  // If the offset is small enough to fit in the immediate field, directly
168
56
  // encode it.
169
56
  // Otherwise scavenge a register and encode it into a MOVHI, OR_I_LO sequence.
170
56
  if ((isSPLSOpcode(MI.getOpcode()) && 
!isInt<10>(Offset)0
) ||
171
56
      !isInt<16>(Offset)) {
172
0
    assert(RS && "Register scavenging must be on");
173
0
    unsigned Reg = RS->FindUnusedReg(&Lanai::GPRRegClass);
174
0
    if (!Reg)
175
0
      Reg = RS->scavengeRegister(&Lanai::GPRRegClass, II, SPAdj);
176
0
    assert(Reg && "Register scavenger failed");
177
0
178
0
    bool HasNegOffset = false;
179
0
    // ALU ops have unsigned immediate values. If the Offset is negative, we
180
0
    // negate it here and reverse the opcode later.
181
0
    if (Offset < 0) {
182
0
      HasNegOffset = true;
183
0
      Offset = -Offset;
184
0
    }
185
0
186
0
    if (!isInt<16>(Offset)) {
187
0
      // Reg = hi(offset) | lo(offset)
188
0
      BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::MOVHI), Reg)
189
0
          .addImm(static_cast<uint32_t>(Offset) >> 16);
190
0
      BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::OR_I_LO), Reg)
191
0
          .addReg(Reg)
192
0
          .addImm(Offset & 0xffffU);
193
0
    } else {
194
0
      // Reg = mov(offset)
195
0
      BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::ADD_I_LO), Reg)
196
0
          .addImm(0)
197
0
          .addImm(Offset);
198
0
    }
199
0
    // Reg = FrameReg OP Reg
200
0
    if (MI.getOpcode() == Lanai::ADD_I_LO) {
201
0
      BuildMI(*MI.getParent(), II, DL,
202
0
              HasNegOffset ? TII->get(Lanai::SUB_R) : TII->get(Lanai::ADD_R),
203
0
              MI.getOperand(0).getReg())
204
0
          .addReg(FrameReg)
205
0
          .addReg(Reg)
206
0
          .addImm(LPCC::ICC_T);
207
0
      MI.eraseFromParent();
208
0
      return;
209
0
    }
210
0
    if (isSPLSOpcode(MI.getOpcode()) || isRMOpcode(MI.getOpcode())) {
211
0
      MI.setDesc(TII->get(getRRMOpcodeVariant(MI.getOpcode())));
212
0
      if (HasNegOffset) {
213
0
        // Change the ALU op (operand 3) from LPAC::ADD (the default) to
214
0
        // LPAC::SUB with the already negated offset.
215
0
        assert((MI.getOperand(3).getImm() == LPAC::ADD) &&
216
0
               "Unexpected ALU op in RRM instruction");
217
0
        MI.getOperand(3).setImm(LPAC::SUB);
218
0
      }
219
0
    } else
220
0
      llvm_unreachable("Unexpected opcode in frame index operation");
221
0
222
0
    MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/false);
223
0
    MI.getOperand(FIOperandNum + 1)
224
0
        .ChangeToRegister(Reg, /*isDef=*/false, /*isImp=*/false,
225
0
                          /*isKill=*/true);
226
0
    return;
227
56
  }
228
56
229
56
  // ALU arithmetic ops take unsigned immediates. If the offset is negative,
230
56
  // we replace the instruction with one that inverts the opcode and negates
231
56
  // the immediate.
232
56
  if ((Offset < 0) && 
isALUArithLoOpcode(MI.getOpcode())4
) {
233
0
    unsigned NewOpcode = getOppositeALULoOpcode(MI.getOpcode());
234
0
    // We know this is an ALU op, so we know the operands are as follows:
235
0
    // 0: destination register
236
0
    // 1: source register (frame register)
237
0
    // 2: immediate
238
0
    BuildMI(*MI.getParent(), II, DL, TII->get(NewOpcode),
239
0
            MI.getOperand(0).getReg())
240
0
        .addReg(FrameReg)
241
0
        .addImm(-Offset);
242
0
    MI.eraseFromParent();
243
56
  } else {
244
56
    MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/false);
245
56
    MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
246
56
  }
247
56
}
248
249
381
bool LanaiRegisterInfo::hasBasePointer(const MachineFunction &MF) const {
250
381
  const MachineFrameInfo &MFI = MF.getFrameInfo();
251
381
  // When we need stack realignment and there are dynamic allocas, we can't
252
381
  // reference off of the stack pointer, so we reserve a base pointer.
253
381
  if (needsStackRealignment(MF) && 
MFI.hasVarSizedObjects()0
)
254
0
    return true;
255
381
256
381
  return false;
257
381
}
258
259
0
unsigned LanaiRegisterInfo::getRARegister() const { return Lanai::RCA; }
260
261
Register
262
56
LanaiRegisterInfo::getFrameRegister(const MachineFunction & /*MF*/) const {
263
56
  return Lanai::FP;
264
56
}
265
266
0
Register LanaiRegisterInfo::getBaseRegister() const { return Lanai::R14; }
267
268
const uint32_t *
269
LanaiRegisterInfo::getCallPreservedMask(const MachineFunction & /*MF*/,
270
13
                                        CallingConv::ID /*CC*/) const {
271
13
  return CSR_RegMask;
272
13
}