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