Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/BPF/BPFMIChecking.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-------------- BPFMIChecking.cpp - MI Checking Legality -------------===//
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 pass performs checking to signal errors for certain illegal usages at
10
// MachineInstruction layer. Specially, the result of XADD{32,64} insn should
11
// not be used. The pass is done at the PreEmit pass right before the
12
// machine code is emitted at which point the register liveness information
13
// is still available.
14
//
15
//===----------------------------------------------------------------------===//
16
17
#include "BPF.h"
18
#include "BPFInstrInfo.h"
19
#include "BPFTargetMachine.h"
20
#include "llvm/CodeGen/MachineInstrBuilder.h"
21
#include "llvm/CodeGen/MachineRegisterInfo.h"
22
23
using namespace llvm;
24
25
#define DEBUG_TYPE "bpf-mi-checking"
26
27
namespace {
28
29
struct BPFMIPreEmitChecking : public MachineFunctionPass {
30
31
  static char ID;
32
  MachineFunction *MF;
33
  const TargetRegisterInfo *TRI;
34
35
206
  BPFMIPreEmitChecking() : MachineFunctionPass(ID) {
36
206
    initializeBPFMIPreEmitCheckingPass(*PassRegistry::getPassRegistry());
37
206
  }
38
39
private:
40
  // Initialize class variables.
41
  void initialize(MachineFunction &MFParm);
42
43
  void checkingIllegalXADD(void);
44
45
public:
46
47
  // Main entry point for this pass.
48
284
  bool runOnMachineFunction(MachineFunction &MF) override {
49
284
    if (!skipFunction(MF.getFunction())) {
50
284
      initialize(MF);
51
284
      checkingIllegalXADD();
52
284
    }
53
284
    return false;
54
284
  }
55
};
56
57
// Initialize class variables.
58
284
void BPFMIPreEmitChecking::initialize(MachineFunction &MFParm) {
59
284
  MF = &MFParm;
60
284
  TRI = MF->getSubtarget<BPFSubtarget>().getRegisterInfo();
61
284
  LLVM_DEBUG(dbgs() << "*** BPF PreEmit checking pass ***\n\n");
62
284
}
63
64
// Make sure all Defs of XADD are dead, meaning any result of XADD insn is not
65
// used.
66
//
67
// NOTE: BPF backend hasn't enabled sub-register liveness track, so when the
68
// source and destination operands of XADD are GPR32, there is no sub-register
69
// dead info. If we rely on the generic MachineInstr::allDefsAreDead, then we
70
// will raise false alarm on GPR32 Def.
71
//
72
// To support GPR32 Def, ideally we could just enable sub-registr liveness track
73
// on BPF backend, then allDefsAreDead could work on GPR32 Def. This requires
74
// implementing TargetSubtargetInfo::enableSubRegLiveness on BPF.
75
//
76
// However, sub-register liveness tracking module inside LLVM is actually
77
// designed for the situation where one register could be split into more than
78
// one sub-registers for which case each sub-register could have their own
79
// liveness and kill one of them doesn't kill others. So, tracking liveness for
80
// each make sense.
81
//
82
// For BPF, each 64-bit register could only have one 32-bit sub-register. This
83
// is exactly the case which LLVM think brings no benefits for doing
84
// sub-register tracking, because the live range of sub-register must always
85
// equal to its parent register, therefore liveness tracking is disabled even
86
// the back-end has implemented enableSubRegLiveness. The detailed information
87
// is at r232695:
88
//
89
//   Author: Matthias Braun <matze@braunis.de>
90
//   Date:   Thu Mar 19 00:21:58 2015 +0000
91
//   Do not track subregister liveness when it brings no benefits
92
//
93
// Hence, for BPF, we enhance MachineInstr::allDefsAreDead. Given the solo
94
// sub-register always has the same liveness as its parent register, LLVM is
95
// already attaching a implicit 64-bit register Def whenever the there is
96
// a sub-register Def. The liveness of the implicit 64-bit Def is available.
97
// For example, for "lock *(u32 *)(r0 + 4) += w9", the MachineOperand info could
98
// be:
99
//
100
//   $w9 = XADDW32 killed $r0, 4, $w9(tied-def 0),
101
//                        implicit killed $r9, implicit-def dead $r9
102
//
103
// Even though w9 is not marked as Dead, the parent register r9 is marked as
104
// Dead correctly, and it is safe to use such information or our purpose.
105
17
static bool hasLiveDefs(const MachineInstr &MI, const TargetRegisterInfo *TRI) {
106
17
  const MCRegisterClass *GPR64RegClass =
107
17
    &BPFMCRegisterClasses[BPF::GPRRegClassID];
108
17
  std::vector<unsigned> GPR32LiveDefs;
109
17
  std::vector<unsigned> GPR64DeadDefs;
110
17
111
66
  for (const MachineOperand &MO : MI.operands()) {
112
66
    bool RegIsGPR64;
113
66
114
66
    if (!MO.isReg() || 
MO.isUse()51
)
115
47
      continue;
116
19
117
19
    RegIsGPR64 = GPR64RegClass->contains(MO.getReg());
118
19
    if (!MO.isDead()) {
119
6
      // It is a GPR64 live Def, we are sure it is live. */
120
6
      if (RegIsGPR64)
121
2
        return true;
122
4
      // It is a GPR32 live Def, we are unsure whether it is really dead due to
123
4
      // no sub-register liveness tracking. Push it to vector for deferred
124
4
      // check.
125
4
      GPR32LiveDefs.push_back(MO.getReg());
126
4
      continue;
127
4
    }
128
13
129
13
    // Record any GPR64 dead Def as some unmarked GPR32 could be alias of its
130
13
    // low 32-bit.
131
13
    if (RegIsGPR64)
132
11
      GPR64DeadDefs.push_back(MO.getReg());
133
13
  }
134
17
135
17
  // No GPR32 live Def, safe to return false.
136
17
  
if (15
GPR32LiveDefs.empty()15
)
137
11
    return false;
138
4
139
4
  // No GPR64 dead Def, so all those GPR32 live Def can't have alias, therefore
140
4
  // must be truely live, safe to return true.
141
4
  if (GPR64DeadDefs.empty())
142
2
    return true;
143
2
144
2
  // Otherwise, return true if any aliased SuperReg of GPR32 is not dead.
145
2
  std::vector<unsigned>::iterator search_begin = GPR64DeadDefs.begin();
146
2
  std::vector<unsigned>::iterator search_end = GPR64DeadDefs.end();
147
2
  for (auto I : GPR32LiveDefs)
148
4
    
for (MCSuperRegIterator SR(I, TRI); 2
SR.isValid();
++SR2
)
149
2
       if (std::find(search_begin, search_end, *SR) == search_end)
150
0
         return true;
151
2
152
2
  return false;
153
2
}
154
155
284
void BPFMIPreEmitChecking::checkingIllegalXADD(void) {
156
488
  for (MachineBasicBlock &MBB : *MF) {
157
2.24k
    for (MachineInstr &MI : MBB) {
158
2.24k
      if (MI.getOpcode() != BPF::XADDW &&
159
2.24k
          
MI.getOpcode() != BPF::XADDD2.23k
&&
160
2.24k
          
MI.getOpcode() != BPF::XADDW322.23k
)
161
2.23k
        continue;
162
17
163
17
      LLVM_DEBUG(MI.dump());
164
17
      if (hasLiveDefs(MI, TRI)) {
165
4
        DebugLoc Empty;
166
4
        const DebugLoc &DL = MI.getDebugLoc();
167
4
        if (DL != Empty)
168
4
          report_fatal_error("line " + std::to_string(DL.getLine()) +
169
4
                             ": Invalid usage of the XADD return value", false);
170
0
        else
171
0
          report_fatal_error("Invalid usage of the XADD return value", false);
172
4
      }
173
17
    }
174
488
  }
175
284
176
284
  
return280
;
177
284
}
178
179
} // end default namespace
180
181
INITIALIZE_PASS(BPFMIPreEmitChecking, "bpf-mi-pemit-checking",
182
                "BPF PreEmit Checking", false, false)
183
184
char BPFMIPreEmitChecking::ID = 0;
185
FunctionPass* llvm::createBPFMIPreEmitCheckingPass()
186
206
{
187
206
  return new BPFMIPreEmitChecking();
188
206
}