Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/BPF/BPFRegisterInfo.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- BPFRegisterInfo.cpp - BPF 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 BPF implementation of the TargetRegisterInfo class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "BPFRegisterInfo.h"
14
#include "BPF.h"
15
#include "BPFSubtarget.h"
16
#include "llvm/CodeGen/MachineFrameInfo.h"
17
#include "llvm/CodeGen/MachineFunction.h"
18
#include "llvm/CodeGen/MachineInstrBuilder.h"
19
#include "llvm/CodeGen/RegisterScavenging.h"
20
#include "llvm/CodeGen/TargetFrameLowering.h"
21
#include "llvm/CodeGen/TargetInstrInfo.h"
22
#include "llvm/IR/DiagnosticInfo.h"
23
#include "llvm/Support/ErrorHandling.h"
24
25
#define GET_REGINFO_TARGET_DESC
26
#include "BPFGenRegisterInfo.inc"
27
using namespace llvm;
28
29
BPFRegisterInfo::BPFRegisterInfo()
30
212
    : BPFGenRegisterInfo(BPF::R0) {}
31
32
const MCPhysReg *
33
2.17k
BPFRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
34
2.17k
  return CSR_SaveList;
35
2.17k
}
36
37
852
BitVector BPFRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
38
852
  BitVector Reserved(getNumRegs());
39
852
  markSuperRegs(Reserved, BPF::W10); // [W|R]10 is read only frame pointer
40
852
  markSuperRegs(Reserved, BPF::W11); // [W|R]11 is pseudo stack pointer
41
852
  return Reserved;
42
852
}
43
44
static void WarnSize(int Offset, MachineFunction &MF, DebugLoc& DL)
45
145
{
46
145
  if (Offset <= -512) {
47
1
      const Function &F = MF.getFunction();
48
1
      DiagnosticInfoUnsupported DiagStackSize(F,
49
1
          "Looks like the BPF stack limit of 512 bytes is exceeded. "
50
1
          "Please move large on stack variables into BPF per-cpu array map.\n",
51
1
          DL);
52
1
      F.getContext().diagnose(DiagStackSize);
53
1
  }
54
145
}
55
56
void BPFRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
57
                                          int SPAdj, unsigned FIOperandNum,
58
145
                                          RegScavenger *RS) const {
59
145
  assert(SPAdj == 0 && "Unexpected");
60
145
61
145
  unsigned i = 0;
62
145
  MachineInstr &MI = *II;
63
145
  MachineBasicBlock &MBB = *MI.getParent();
64
145
  MachineFunction &MF = *MBB.getParent();
65
145
  DebugLoc DL = MI.getDebugLoc();
66
145
67
145
  if (!DL)
68
129
    /* try harder to get some debug loc */
69
129
    for (auto &I : MBB)
70
1.95k
      if (I.getDebugLoc()) {
71
12
        DL = I.getDebugLoc();
72
12
        break;
73
12
      }
74
145
75
298
  while (!MI.getOperand(i).isFI()) {
76
153
    ++i;
77
153
    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
78
153
  }
79
145
80
145
  unsigned FrameReg = getFrameRegister(MF);
81
145
  int FrameIndex = MI.getOperand(i).getIndex();
82
145
  const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
83
145
84
145
  if (MI.getOpcode() == BPF::MOV_rr) {
85
24
    int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex);
86
24
87
24
    WarnSize(Offset, MF, DL);
88
24
    MI.getOperand(i).ChangeToRegister(FrameReg, false);
89
24
    unsigned reg = MI.getOperand(i - 1).getReg();
90
24
    BuildMI(MBB, ++II, DL, TII.get(BPF::ADD_ri), reg)
91
24
        .addReg(reg)
92
24
        .addImm(Offset);
93
24
    return;
94
24
  }
95
121
96
121
  int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) +
97
121
               MI.getOperand(i + 1).getImm();
98
121
99
121
  if (!isInt<32>(Offset))
100
121
    
llvm_unreachable0
("bug in frame offset");
101
121
102
121
  WarnSize(Offset, MF, DL);
103
121
104
121
  if (MI.getOpcode() == BPF::FI_ri) {
105
1
    // architecture does not really support FI_ri, replace it with
106
1
    //    MOV_rr <target_reg>, frame_reg
107
1
    //    ADD_ri <target_reg>, imm
108
1
    unsigned reg = MI.getOperand(i - 1).getReg();
109
1
110
1
    BuildMI(MBB, ++II, DL, TII.get(BPF::MOV_rr), reg)
111
1
        .addReg(FrameReg);
112
1
    BuildMI(MBB, II, DL, TII.get(BPF::ADD_ri), reg)
113
1
        .addReg(reg)
114
1
        .addImm(Offset);
115
1
116
1
    // Remove FI_ri instruction
117
1
    MI.eraseFromParent();
118
120
  } else {
119
120
    MI.getOperand(i).ChangeToRegister(FrameReg, false);
120
120
    MI.getOperand(i + 1).ChangeToImmediate(Offset);
121
120
  }
122
121
}
123
124
409
Register BPFRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
125
409
  return BPF::R10;
126
409
}