]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/BPF/BPFMIChecking.cpp
Merge ^/head r352587 through r352763.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / BPF / BPFMIChecking.cpp
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   BPFMIPreEmitChecking() : MachineFunctionPass(ID) {
36     initializeBPFMIPreEmitCheckingPass(*PassRegistry::getPassRegistry());
37   }
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   bool runOnMachineFunction(MachineFunction &MF) override {
49     if (!skipFunction(MF.getFunction())) {
50       initialize(MF);
51       checkingIllegalXADD();
52     }
53     return false;
54   }
55 };
56
57 // Initialize class variables.
58 void BPFMIPreEmitChecking::initialize(MachineFunction &MFParm) {
59   MF = &MFParm;
60   TRI = MF->getSubtarget<BPFSubtarget>().getRegisterInfo();
61   LLVM_DEBUG(dbgs() << "*** BPF PreEmit checking pass ***\n\n");
62 }
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 static bool hasLiveDefs(const MachineInstr &MI, const TargetRegisterInfo *TRI) {
106   const MCRegisterClass *GPR64RegClass =
107     &BPFMCRegisterClasses[BPF::GPRRegClassID];
108   std::vector<unsigned> GPR32LiveDefs;
109   std::vector<unsigned> GPR64DeadDefs;
110
111   for (const MachineOperand &MO : MI.operands()) {
112     bool RegIsGPR64;
113
114     if (!MO.isReg() || MO.isUse())
115       continue;
116
117     RegIsGPR64 = GPR64RegClass->contains(MO.getReg());
118     if (!MO.isDead()) {
119       // It is a GPR64 live Def, we are sure it is live. */
120       if (RegIsGPR64)
121         return true;
122       // It is a GPR32 live Def, we are unsure whether it is really dead due to
123       // no sub-register liveness tracking. Push it to vector for deferred
124       // check.
125       GPR32LiveDefs.push_back(MO.getReg());
126       continue;
127     }
128
129     // Record any GPR64 dead Def as some unmarked GPR32 could be alias of its
130     // low 32-bit.
131     if (RegIsGPR64)
132       GPR64DeadDefs.push_back(MO.getReg());
133   }
134
135   // No GPR32 live Def, safe to return false.
136   if (GPR32LiveDefs.empty())
137     return false;
138
139   // No GPR64 dead Def, so all those GPR32 live Def can't have alias, therefore
140   // must be truely live, safe to return true.
141   if (GPR64DeadDefs.empty())
142     return true;
143
144   // Otherwise, return true if any aliased SuperReg of GPR32 is not dead.
145   std::vector<unsigned>::iterator search_begin = GPR64DeadDefs.begin();
146   std::vector<unsigned>::iterator search_end = GPR64DeadDefs.end();
147   for (auto I : GPR32LiveDefs)
148     for (MCSuperRegIterator SR(I, TRI); SR.isValid(); ++SR)
149        if (std::find(search_begin, search_end, *SR) == search_end)
150          return true;
151
152   return false;
153 }
154
155 void BPFMIPreEmitChecking::checkingIllegalXADD(void) {
156   for (MachineBasicBlock &MBB : *MF) {
157     for (MachineInstr &MI : MBB) {
158       if (MI.getOpcode() != BPF::XADDW &&
159           MI.getOpcode() != BPF::XADDD &&
160           MI.getOpcode() != BPF::XADDW32)
161         continue;
162
163       LLVM_DEBUG(MI.dump());
164       if (hasLiveDefs(MI, TRI)) {
165         DebugLoc Empty;
166         const DebugLoc &DL = MI.getDebugLoc();
167         if (DL != Empty)
168           report_fatal_error("line " + std::to_string(DL.getLine()) +
169                              ": Invalid usage of the XADD return value", false);
170         else
171           report_fatal_error("Invalid usage of the XADD return value", false);
172       }
173     }
174   }
175
176   return;
177 }
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 {
187   return new BPFMIPreEmitChecking();
188 }