1*09467b48Spatrick //===-- StackMapLivenessAnalysis.cpp - StackMap live Out Analysis ----------===// 2*09467b48Spatrick // 3*09467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*09467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 5*09467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*09467b48Spatrick // 7*09467b48Spatrick //===----------------------------------------------------------------------===// 8*09467b48Spatrick // 9*09467b48Spatrick // This file implements the StackMap Liveness analysis pass. The pass calculates 10*09467b48Spatrick // the liveness for each basic block in a function and attaches the register 11*09467b48Spatrick // live-out information to a stackmap or patchpoint intrinsic if present. 12*09467b48Spatrick // 13*09467b48Spatrick //===----------------------------------------------------------------------===// 14*09467b48Spatrick 15*09467b48Spatrick #include "llvm/ADT/Statistic.h" 16*09467b48Spatrick #include "llvm/CodeGen/LivePhysRegs.h" 17*09467b48Spatrick #include "llvm/CodeGen/MachineFrameInfo.h" 18*09467b48Spatrick #include "llvm/CodeGen/MachineFunction.h" 19*09467b48Spatrick #include "llvm/CodeGen/MachineFunctionPass.h" 20*09467b48Spatrick #include "llvm/CodeGen/Passes.h" 21*09467b48Spatrick #include "llvm/CodeGen/TargetSubtargetInfo.h" 22*09467b48Spatrick #include "llvm/InitializePasses.h" 23*09467b48Spatrick #include "llvm/Support/CommandLine.h" 24*09467b48Spatrick #include "llvm/Support/Debug.h" 25*09467b48Spatrick #include "llvm/Support/raw_ostream.h" 26*09467b48Spatrick 27*09467b48Spatrick using namespace llvm; 28*09467b48Spatrick 29*09467b48Spatrick #define DEBUG_TYPE "stackmaps" 30*09467b48Spatrick 31*09467b48Spatrick static cl::opt<bool> EnablePatchPointLiveness( 32*09467b48Spatrick "enable-patchpoint-liveness", cl::Hidden, cl::init(true), 33*09467b48Spatrick cl::desc("Enable PatchPoint Liveness Analysis Pass")); 34*09467b48Spatrick 35*09467b48Spatrick STATISTIC(NumStackMapFuncVisited, "Number of functions visited"); 36*09467b48Spatrick STATISTIC(NumStackMapFuncSkipped, "Number of functions skipped"); 37*09467b48Spatrick STATISTIC(NumBBsVisited, "Number of basic blocks visited"); 38*09467b48Spatrick STATISTIC(NumBBsHaveNoStackmap, "Number of basic blocks with no stackmap"); 39*09467b48Spatrick STATISTIC(NumStackMaps, "Number of StackMaps visited"); 40*09467b48Spatrick 41*09467b48Spatrick namespace { 42*09467b48Spatrick /// This pass calculates the liveness information for each basic block in 43*09467b48Spatrick /// a function and attaches the register live-out information to a patchpoint 44*09467b48Spatrick /// intrinsic if present. 45*09467b48Spatrick /// 46*09467b48Spatrick /// This pass can be disabled via the -enable-patchpoint-liveness=false flag. 47*09467b48Spatrick /// The pass skips functions that don't have any patchpoint intrinsics. The 48*09467b48Spatrick /// information provided by this pass is optional and not required by the 49*09467b48Spatrick /// aformentioned intrinsic to function. 50*09467b48Spatrick class StackMapLiveness : public MachineFunctionPass { 51*09467b48Spatrick const TargetRegisterInfo *TRI; 52*09467b48Spatrick LivePhysRegs LiveRegs; 53*09467b48Spatrick 54*09467b48Spatrick public: 55*09467b48Spatrick static char ID; 56*09467b48Spatrick 57*09467b48Spatrick /// Default construct and initialize the pass. 58*09467b48Spatrick StackMapLiveness(); 59*09467b48Spatrick 60*09467b48Spatrick /// Tell the pass manager which passes we depend on and what 61*09467b48Spatrick /// information we preserve. 62*09467b48Spatrick void getAnalysisUsage(AnalysisUsage &AU) const override; 63*09467b48Spatrick 64*09467b48Spatrick MachineFunctionProperties getRequiredProperties() const override { 65*09467b48Spatrick return MachineFunctionProperties().set( 66*09467b48Spatrick MachineFunctionProperties::Property::NoVRegs); 67*09467b48Spatrick } 68*09467b48Spatrick 69*09467b48Spatrick /// Calculate the liveness information for the given machine function. 70*09467b48Spatrick bool runOnMachineFunction(MachineFunction &MF) override; 71*09467b48Spatrick 72*09467b48Spatrick private: 73*09467b48Spatrick /// Performs the actual liveness calculation for the function. 74*09467b48Spatrick bool calculateLiveness(MachineFunction &MF); 75*09467b48Spatrick 76*09467b48Spatrick /// Add the current register live set to the instruction. 77*09467b48Spatrick void addLiveOutSetToMI(MachineFunction &MF, MachineInstr &MI); 78*09467b48Spatrick 79*09467b48Spatrick /// Create a register mask and initialize it with the registers from 80*09467b48Spatrick /// the register live set. 81*09467b48Spatrick uint32_t *createRegisterMask(MachineFunction &MF) const; 82*09467b48Spatrick }; 83*09467b48Spatrick } // namespace 84*09467b48Spatrick 85*09467b48Spatrick char StackMapLiveness::ID = 0; 86*09467b48Spatrick char &llvm::StackMapLivenessID = StackMapLiveness::ID; 87*09467b48Spatrick INITIALIZE_PASS(StackMapLiveness, "stackmap-liveness", 88*09467b48Spatrick "StackMap Liveness Analysis", false, false) 89*09467b48Spatrick 90*09467b48Spatrick /// Default construct and initialize the pass. 91*09467b48Spatrick StackMapLiveness::StackMapLiveness() : MachineFunctionPass(ID) { 92*09467b48Spatrick initializeStackMapLivenessPass(*PassRegistry::getPassRegistry()); 93*09467b48Spatrick } 94*09467b48Spatrick 95*09467b48Spatrick /// Tell the pass manager which passes we depend on and what information we 96*09467b48Spatrick /// preserve. 97*09467b48Spatrick void StackMapLiveness::getAnalysisUsage(AnalysisUsage &AU) const { 98*09467b48Spatrick // We preserve all information. 99*09467b48Spatrick AU.setPreservesAll(); 100*09467b48Spatrick AU.setPreservesCFG(); 101*09467b48Spatrick MachineFunctionPass::getAnalysisUsage(AU); 102*09467b48Spatrick } 103*09467b48Spatrick 104*09467b48Spatrick /// Calculate the liveness information for the given machine function. 105*09467b48Spatrick bool StackMapLiveness::runOnMachineFunction(MachineFunction &MF) { 106*09467b48Spatrick if (!EnablePatchPointLiveness) 107*09467b48Spatrick return false; 108*09467b48Spatrick 109*09467b48Spatrick LLVM_DEBUG(dbgs() << "********** COMPUTING STACKMAP LIVENESS: " 110*09467b48Spatrick << MF.getName() << " **********\n"); 111*09467b48Spatrick TRI = MF.getSubtarget().getRegisterInfo(); 112*09467b48Spatrick ++NumStackMapFuncVisited; 113*09467b48Spatrick 114*09467b48Spatrick // Skip this function if there are no patchpoints to process. 115*09467b48Spatrick if (!MF.getFrameInfo().hasPatchPoint()) { 116*09467b48Spatrick ++NumStackMapFuncSkipped; 117*09467b48Spatrick return false; 118*09467b48Spatrick } 119*09467b48Spatrick return calculateLiveness(MF); 120*09467b48Spatrick } 121*09467b48Spatrick 122*09467b48Spatrick /// Performs the actual liveness calculation for the function. 123*09467b48Spatrick bool StackMapLiveness::calculateLiveness(MachineFunction &MF) { 124*09467b48Spatrick bool HasChanged = false; 125*09467b48Spatrick // For all basic blocks in the function. 126*09467b48Spatrick for (auto &MBB : MF) { 127*09467b48Spatrick LLVM_DEBUG(dbgs() << "****** BB " << MBB.getName() << " ******\n"); 128*09467b48Spatrick LiveRegs.init(*TRI); 129*09467b48Spatrick // FIXME: This should probably be addLiveOuts(). 130*09467b48Spatrick LiveRegs.addLiveOutsNoPristines(MBB); 131*09467b48Spatrick bool HasStackMap = false; 132*09467b48Spatrick // Reverse iterate over all instructions and add the current live register 133*09467b48Spatrick // set to an instruction if we encounter a patchpoint instruction. 134*09467b48Spatrick for (auto I = MBB.rbegin(), E = MBB.rend(); I != E; ++I) { 135*09467b48Spatrick if (I->getOpcode() == TargetOpcode::PATCHPOINT) { 136*09467b48Spatrick addLiveOutSetToMI(MF, *I); 137*09467b48Spatrick HasChanged = true; 138*09467b48Spatrick HasStackMap = true; 139*09467b48Spatrick ++NumStackMaps; 140*09467b48Spatrick } 141*09467b48Spatrick LLVM_DEBUG(dbgs() << " " << LiveRegs << " " << *I); 142*09467b48Spatrick LiveRegs.stepBackward(*I); 143*09467b48Spatrick } 144*09467b48Spatrick ++NumBBsVisited; 145*09467b48Spatrick if (!HasStackMap) 146*09467b48Spatrick ++NumBBsHaveNoStackmap; 147*09467b48Spatrick } 148*09467b48Spatrick return HasChanged; 149*09467b48Spatrick } 150*09467b48Spatrick 151*09467b48Spatrick /// Add the current register live set to the instruction. 152*09467b48Spatrick void StackMapLiveness::addLiveOutSetToMI(MachineFunction &MF, 153*09467b48Spatrick MachineInstr &MI) { 154*09467b48Spatrick uint32_t *Mask = createRegisterMask(MF); 155*09467b48Spatrick MachineOperand MO = MachineOperand::CreateRegLiveOut(Mask); 156*09467b48Spatrick MI.addOperand(MF, MO); 157*09467b48Spatrick } 158*09467b48Spatrick 159*09467b48Spatrick /// Create a register mask and initialize it with the registers from the 160*09467b48Spatrick /// register live set. 161*09467b48Spatrick uint32_t *StackMapLiveness::createRegisterMask(MachineFunction &MF) const { 162*09467b48Spatrick // The mask is owned and cleaned up by the Machine Function. 163*09467b48Spatrick uint32_t *Mask = MF.allocateRegMask(); 164*09467b48Spatrick for (auto Reg : LiveRegs) 165*09467b48Spatrick Mask[Reg / 32] |= 1U << (Reg % 32); 166*09467b48Spatrick 167*09467b48Spatrick // Give the target a chance to adjust the mask. 168*09467b48Spatrick TRI->adjustStackMapLiveOutMask(Mask); 169*09467b48Spatrick 170*09467b48Spatrick return Mask; 171*09467b48Spatrick } 172