]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/BPF/BPFMIChecking.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / BPF / BPFMIChecking.cpp
1 //===-------------- BPFMIChecking.cpp - MI Checking Legality -------------===//
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 pass performs checking to signal errors for certain illegal usages at
11 // MachineInstruction layer. Specially, the result of XADD{32,64} insn should
12 // not be used. The pass is done at the PreEmit pass right before the
13 // machine code is emitted at which point the register liveness information
14 // is still available.
15 //
16 //===----------------------------------------------------------------------===//
17
18 #include "BPF.h"
19 #include "BPFInstrInfo.h"
20 #include "BPFTargetMachine.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/MachineRegisterInfo.h"
23
24 using namespace llvm;
25
26 #define DEBUG_TYPE "bpf-mi-checking"
27
28 namespace {
29
30 struct BPFMIPreEmitChecking : public MachineFunctionPass {
31
32   static char ID;
33   MachineFunction *MF;
34   const TargetRegisterInfo *TRI;
35
36   BPFMIPreEmitChecking() : MachineFunctionPass(ID) {
37     initializeBPFMIPreEmitCheckingPass(*PassRegistry::getPassRegistry());
38   }
39
40 private:
41   // Initialize class variables.
42   void initialize(MachineFunction &MFParm);
43
44   void checkingIllegalXADD(void);
45
46 public:
47
48   // Main entry point for this pass.
49   bool runOnMachineFunction(MachineFunction &MF) override {
50     if (!skipFunction(MF.getFunction())) {
51       initialize(MF);
52       checkingIllegalXADD();
53     }
54     return false;
55   }
56 };
57
58 // Initialize class variables.
59 void BPFMIPreEmitChecking::initialize(MachineFunction &MFParm) {
60   MF = &MFParm;
61   TRI = MF->getSubtarget<BPFSubtarget>().getRegisterInfo();
62   LLVM_DEBUG(dbgs() << "*** BPF PreEmit checking pass ***\n\n");
63 }
64
65 void BPFMIPreEmitChecking::checkingIllegalXADD(void) {
66   for (MachineBasicBlock &MBB : *MF) {
67     for (MachineInstr &MI : MBB) {
68       if (MI.getOpcode() != BPF::XADD32 && MI.getOpcode() != BPF::XADD64)
69         continue;
70
71       LLVM_DEBUG(MI.dump());
72       if (!MI.allDefsAreDead()) {
73         DebugLoc Empty;
74         const DebugLoc &DL = MI.getDebugLoc();
75         if (DL != Empty)
76           report_fatal_error("line " + std::to_string(DL.getLine()) +
77                              ": Invalid usage of the XADD return value", false);
78         else
79           report_fatal_error("Invalid usage of the XADD return value", false);
80       }
81     }
82   }
83
84   return;
85 }
86
87 } // end default namespace
88
89 INITIALIZE_PASS(BPFMIPreEmitChecking, "bpf-mi-pemit-checking",
90                 "BPF PreEmit Checking", false, false)
91
92 char BPFMIPreEmitChecking::ID = 0;
93 FunctionPass* llvm::createBPFMIPreEmitCheckingPass()
94 {
95   return new BPFMIPreEmitChecking();
96 }