diff options
Diffstat (limited to 'contrib/llvm/lib/Target/BPF/BPFMIChecking.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/BPF/BPFMIChecking.cpp | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Target/BPF/BPFMIChecking.cpp b/contrib/llvm/lib/Target/BPF/BPFMIChecking.cpp new file mode 100644 index 000000000000..0a311378e777 --- /dev/null +++ b/contrib/llvm/lib/Target/BPF/BPFMIChecking.cpp @@ -0,0 +1,96 @@ +//===-------------- BPFMIChecking.cpp - MI Checking Legality -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass performs checking to signal errors for certain illegal usages at +// MachineInstruction layer. Specially, the result of XADD{32,64} insn should +// not be used. The pass is done at the PreEmit pass right before the +// machine code is emitted at which point the register liveness information +// is still available. +// +//===----------------------------------------------------------------------===// + +#include "BPF.h" +#include "BPFInstrInfo.h" +#include "BPFTargetMachine.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" + +using namespace llvm; + +#define DEBUG_TYPE "bpf-mi-checking" + +namespace { + +struct BPFMIPreEmitChecking : public MachineFunctionPass { + + static char ID; + MachineFunction *MF; + const TargetRegisterInfo *TRI; + + BPFMIPreEmitChecking() : MachineFunctionPass(ID) { + initializeBPFMIPreEmitCheckingPass(*PassRegistry::getPassRegistry()); + } + +private: + // Initialize class variables. + void initialize(MachineFunction &MFParm); + + void checkingIllegalXADD(void); + +public: + + // Main entry point for this pass. + bool runOnMachineFunction(MachineFunction &MF) override { + if (!skipFunction(MF.getFunction())) { + initialize(MF); + checkingIllegalXADD(); + } + return false; + } +}; + +// Initialize class variables. +void BPFMIPreEmitChecking::initialize(MachineFunction &MFParm) { + MF = &MFParm; + TRI = MF->getSubtarget<BPFSubtarget>().getRegisterInfo(); + LLVM_DEBUG(dbgs() << "*** BPF PreEmit checking pass ***\n\n"); +} + +void BPFMIPreEmitChecking::checkingIllegalXADD(void) { + for (MachineBasicBlock &MBB : *MF) { + for (MachineInstr &MI : MBB) { + if (MI.getOpcode() != BPF::XADD32 && MI.getOpcode() != BPF::XADD64) + continue; + + LLVM_DEBUG(MI.dump()); + if (!MI.allDefsAreDead()) { + DebugLoc Empty; + const DebugLoc &DL = MI.getDebugLoc(); + if (DL != Empty) + report_fatal_error("line " + std::to_string(DL.getLine()) + + ": Invalid usage of the XADD return value", false); + else + report_fatal_error("Invalid usage of the XADD return value", false); + } + } + } + + return; +} + +} // end default namespace + +INITIALIZE_PASS(BPFMIPreEmitChecking, "bpf-mi-pemit-checking", + "BPF PreEmit Checking", false, false) + +char BPFMIPreEmitChecking::ID = 0; +FunctionPass* llvm::createBPFMIPreEmitCheckingPass() +{ + return new BPFMIPreEmitChecking(); +} |