//===-------------- BPFMIChecking.cpp - MI Checking Legality -------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // 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/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/Support/Debug.h" usingnamespacellvm; #define DEBUG_TYPE … namespace { struct BPFMIPreEmitChecking : public MachineFunctionPass { … }; // Initialize class variables. void BPFMIPreEmitChecking::initialize(MachineFunction &MFParm) { … } // Make sure all Defs of XADD are dead, meaning any result of XADD insn is not // used. // // NOTE: BPF backend hasn't enabled sub-register liveness track, so when the // source and destination operands of XADD are GPR32, there is no sub-register // dead info. If we rely on the generic MachineInstr::allDefsAreDead, then we // will raise false alarm on GPR32 Def. // // To support GPR32 Def, ideally we could just enable sub-registr liveness track // on BPF backend, then allDefsAreDead could work on GPR32 Def. This requires // implementing TargetSubtargetInfo::enableSubRegLiveness on BPF. // // However, sub-register liveness tracking module inside LLVM is actually // designed for the situation where one register could be split into more than // one sub-registers for which case each sub-register could have their own // liveness and kill one of them doesn't kill others. So, tracking liveness for // each make sense. // // For BPF, each 64-bit register could only have one 32-bit sub-register. This // is exactly the case which LLVM think brings no benefits for doing // sub-register tracking, because the live range of sub-register must always // equal to its parent register, therefore liveness tracking is disabled even // the back-end has implemented enableSubRegLiveness. The detailed information // is at r232695: // // Author: Matthias Braun <[email protected]> // Date: Thu Mar 19 00:21:58 2015 +0000 // Do not track subregister liveness when it brings no benefits // // Hence, for BPF, we enhance MachineInstr::allDefsAreDead. Given the solo // sub-register always has the same liveness as its parent register, LLVM is // already attaching a implicit 64-bit register Def whenever the there is // a sub-register Def. The liveness of the implicit 64-bit Def is available. // For example, for "lock *(u32 *)(r0 + 4) += w9", the MachineOperand info could // be: // // $w9 = XADDW32 killed $r0, 4, $w9(tied-def 0), // implicit killed $r9, implicit-def dead $r9 // // Even though w9 is not marked as Dead, the parent register r9 is marked as // Dead correctly, and it is safe to use such information or our purpose. static bool hasLiveDefs(const MachineInstr &MI, const TargetRegisterInfo *TRI) { … } void BPFMIPreEmitChecking::processAtomicInsts() { … } } // namespace INITIALIZE_PASS(…) char BPFMIPreEmitChecking::ID = …; FunctionPass *llvm::createBPFMIPreEmitCheckingPass() { … }