1343171Sdim//===-------------- BPFMIChecking.cpp - MI Checking Legality -------------===// 2343171Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6343171Sdim// 7343171Sdim//===----------------------------------------------------------------------===// 8343171Sdim// 9343171Sdim// This pass performs checking to signal errors for certain illegal usages at 10343171Sdim// MachineInstruction layer. Specially, the result of XADD{32,64} insn should 11343171Sdim// not be used. The pass is done at the PreEmit pass right before the 12343171Sdim// machine code is emitted at which point the register liveness information 13343171Sdim// is still available. 14343171Sdim// 15343171Sdim//===----------------------------------------------------------------------===// 16343171Sdim 17343171Sdim#include "BPF.h" 18343171Sdim#include "BPFInstrInfo.h" 19343171Sdim#include "BPFTargetMachine.h" 20343171Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 21343171Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 22360784Sdim#include "llvm/Support/Debug.h" 23343171Sdim 24343171Sdimusing namespace llvm; 25343171Sdim 26343171Sdim#define DEBUG_TYPE "bpf-mi-checking" 27343171Sdim 28343171Sdimnamespace { 29343171Sdim 30343171Sdimstruct BPFMIPreEmitChecking : public MachineFunctionPass { 31343171Sdim 32343171Sdim static char ID; 33343171Sdim MachineFunction *MF; 34343171Sdim const TargetRegisterInfo *TRI; 35343171Sdim 36343171Sdim BPFMIPreEmitChecking() : MachineFunctionPass(ID) { 37343171Sdim initializeBPFMIPreEmitCheckingPass(*PassRegistry::getPassRegistry()); 38343171Sdim } 39343171Sdim 40343171Sdimprivate: 41343171Sdim // Initialize class variables. 42343171Sdim void initialize(MachineFunction &MFParm); 43343171Sdim 44343171Sdim void checkingIllegalXADD(void); 45343171Sdim 46343171Sdimpublic: 47343171Sdim 48343171Sdim // Main entry point for this pass. 49343171Sdim bool runOnMachineFunction(MachineFunction &MF) override { 50343171Sdim if (!skipFunction(MF.getFunction())) { 51343171Sdim initialize(MF); 52343171Sdim checkingIllegalXADD(); 53343171Sdim } 54343171Sdim return false; 55343171Sdim } 56343171Sdim}; 57343171Sdim 58343171Sdim// Initialize class variables. 59343171Sdimvoid BPFMIPreEmitChecking::initialize(MachineFunction &MFParm) { 60343171Sdim MF = &MFParm; 61343171Sdim TRI = MF->getSubtarget<BPFSubtarget>().getRegisterInfo(); 62343171Sdim LLVM_DEBUG(dbgs() << "*** BPF PreEmit checking pass ***\n\n"); 63343171Sdim} 64343171Sdim 65353358Sdim// Make sure all Defs of XADD are dead, meaning any result of XADD insn is not 66353358Sdim// used. 67353358Sdim// 68353358Sdim// NOTE: BPF backend hasn't enabled sub-register liveness track, so when the 69353358Sdim// source and destination operands of XADD are GPR32, there is no sub-register 70353358Sdim// dead info. If we rely on the generic MachineInstr::allDefsAreDead, then we 71353358Sdim// will raise false alarm on GPR32 Def. 72353358Sdim// 73353358Sdim// To support GPR32 Def, ideally we could just enable sub-registr liveness track 74353358Sdim// on BPF backend, then allDefsAreDead could work on GPR32 Def. This requires 75353358Sdim// implementing TargetSubtargetInfo::enableSubRegLiveness on BPF. 76353358Sdim// 77353358Sdim// However, sub-register liveness tracking module inside LLVM is actually 78353358Sdim// designed for the situation where one register could be split into more than 79353358Sdim// one sub-registers for which case each sub-register could have their own 80353358Sdim// liveness and kill one of them doesn't kill others. So, tracking liveness for 81353358Sdim// each make sense. 82353358Sdim// 83353358Sdim// For BPF, each 64-bit register could only have one 32-bit sub-register. This 84353358Sdim// is exactly the case which LLVM think brings no benefits for doing 85353358Sdim// sub-register tracking, because the live range of sub-register must always 86353358Sdim// equal to its parent register, therefore liveness tracking is disabled even 87353358Sdim// the back-end has implemented enableSubRegLiveness. The detailed information 88353358Sdim// is at r232695: 89353358Sdim// 90353358Sdim// Author: Matthias Braun <matze@braunis.de> 91353358Sdim// Date: Thu Mar 19 00:21:58 2015 +0000 92353358Sdim// Do not track subregister liveness when it brings no benefits 93353358Sdim// 94353358Sdim// Hence, for BPF, we enhance MachineInstr::allDefsAreDead. Given the solo 95353358Sdim// sub-register always has the same liveness as its parent register, LLVM is 96353358Sdim// already attaching a implicit 64-bit register Def whenever the there is 97353358Sdim// a sub-register Def. The liveness of the implicit 64-bit Def is available. 98353358Sdim// For example, for "lock *(u32 *)(r0 + 4) += w9", the MachineOperand info could 99353358Sdim// be: 100353358Sdim// 101353358Sdim// $w9 = XADDW32 killed $r0, 4, $w9(tied-def 0), 102353358Sdim// implicit killed $r9, implicit-def dead $r9 103353358Sdim// 104353358Sdim// Even though w9 is not marked as Dead, the parent register r9 is marked as 105353358Sdim// Dead correctly, and it is safe to use such information or our purpose. 106353358Sdimstatic bool hasLiveDefs(const MachineInstr &MI, const TargetRegisterInfo *TRI) { 107353358Sdim const MCRegisterClass *GPR64RegClass = 108353358Sdim &BPFMCRegisterClasses[BPF::GPRRegClassID]; 109353358Sdim std::vector<unsigned> GPR32LiveDefs; 110353358Sdim std::vector<unsigned> GPR64DeadDefs; 111353358Sdim 112353358Sdim for (const MachineOperand &MO : MI.operands()) { 113353358Sdim bool RegIsGPR64; 114353358Sdim 115353358Sdim if (!MO.isReg() || MO.isUse()) 116353358Sdim continue; 117353358Sdim 118353358Sdim RegIsGPR64 = GPR64RegClass->contains(MO.getReg()); 119353358Sdim if (!MO.isDead()) { 120353358Sdim // It is a GPR64 live Def, we are sure it is live. */ 121353358Sdim if (RegIsGPR64) 122353358Sdim return true; 123353358Sdim // It is a GPR32 live Def, we are unsure whether it is really dead due to 124353358Sdim // no sub-register liveness tracking. Push it to vector for deferred 125353358Sdim // check. 126353358Sdim GPR32LiveDefs.push_back(MO.getReg()); 127353358Sdim continue; 128353358Sdim } 129353358Sdim 130353358Sdim // Record any GPR64 dead Def as some unmarked GPR32 could be alias of its 131353358Sdim // low 32-bit. 132353358Sdim if (RegIsGPR64) 133353358Sdim GPR64DeadDefs.push_back(MO.getReg()); 134353358Sdim } 135353358Sdim 136353358Sdim // No GPR32 live Def, safe to return false. 137353358Sdim if (GPR32LiveDefs.empty()) 138353358Sdim return false; 139353358Sdim 140353358Sdim // No GPR64 dead Def, so all those GPR32 live Def can't have alias, therefore 141353358Sdim // must be truely live, safe to return true. 142353358Sdim if (GPR64DeadDefs.empty()) 143353358Sdim return true; 144353358Sdim 145353358Sdim // Otherwise, return true if any aliased SuperReg of GPR32 is not dead. 146353358Sdim std::vector<unsigned>::iterator search_begin = GPR64DeadDefs.begin(); 147353358Sdim std::vector<unsigned>::iterator search_end = GPR64DeadDefs.end(); 148353358Sdim for (auto I : GPR32LiveDefs) 149353358Sdim for (MCSuperRegIterator SR(I, TRI); SR.isValid(); ++SR) 150353358Sdim if (std::find(search_begin, search_end, *SR) == search_end) 151353358Sdim return true; 152353358Sdim 153353358Sdim return false; 154353358Sdim} 155353358Sdim 156343171Sdimvoid BPFMIPreEmitChecking::checkingIllegalXADD(void) { 157343171Sdim for (MachineBasicBlock &MBB : *MF) { 158343171Sdim for (MachineInstr &MI : MBB) { 159353358Sdim if (MI.getOpcode() != BPF::XADDW && 160353358Sdim MI.getOpcode() != BPF::XADDD && 161353358Sdim MI.getOpcode() != BPF::XADDW32) 162343171Sdim continue; 163343171Sdim 164343171Sdim LLVM_DEBUG(MI.dump()); 165353358Sdim if (hasLiveDefs(MI, TRI)) { 166343171Sdim DebugLoc Empty; 167343171Sdim const DebugLoc &DL = MI.getDebugLoc(); 168343171Sdim if (DL != Empty) 169343171Sdim report_fatal_error("line " + std::to_string(DL.getLine()) + 170343171Sdim ": Invalid usage of the XADD return value", false); 171343171Sdim else 172343171Sdim report_fatal_error("Invalid usage of the XADD return value", false); 173343171Sdim } 174343171Sdim } 175343171Sdim } 176343171Sdim 177343171Sdim return; 178343171Sdim} 179343171Sdim 180343171Sdim} // end default namespace 181343171Sdim 182343171SdimINITIALIZE_PASS(BPFMIPreEmitChecking, "bpf-mi-pemit-checking", 183343171Sdim "BPF PreEmit Checking", false, false) 184343171Sdim 185343171Sdimchar BPFMIPreEmitChecking::ID = 0; 186343171SdimFunctionPass* llvm::createBPFMIPreEmitCheckingPass() 187343171Sdim{ 188343171Sdim return new BPFMIPreEmitChecking(); 189343171Sdim} 190