191bc56edSDimitry Andric //===-- StackMapLivenessAnalysis.cpp - StackMap live Out Analysis ----------===// 291bc56edSDimitry Andric // 391bc56edSDimitry Andric // The LLVM Compiler Infrastructure 491bc56edSDimitry Andric // 591bc56edSDimitry Andric // This file is distributed under the University of Illinois Open Source 691bc56edSDimitry Andric // License. See LICENSE.TXT for details. 791bc56edSDimitry Andric // 891bc56edSDimitry Andric //===----------------------------------------------------------------------===// 991bc56edSDimitry Andric // 1091bc56edSDimitry Andric // This file implements the StackMap Liveness analysis pass. The pass calculates 1191bc56edSDimitry Andric // the liveness for each basic block in a function and attaches the register 1291bc56edSDimitry Andric // live-out information to a stackmap or patchpoint intrinsic if present. 1391bc56edSDimitry Andric // 1491bc56edSDimitry Andric //===----------------------------------------------------------------------===// 1591bc56edSDimitry Andric 1691bc56edSDimitry Andric #include "llvm/ADT/Statistic.h" 17ff0cc061SDimitry Andric #include "llvm/CodeGen/LivePhysRegs.h" 1891bc56edSDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 1991bc56edSDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 2091bc56edSDimitry Andric #include "llvm/CodeGen/MachineFunctionAnalysis.h" 21ff0cc061SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 2291bc56edSDimitry Andric #include "llvm/CodeGen/Passes.h" 2391bc56edSDimitry Andric #include "llvm/Support/CommandLine.h" 2491bc56edSDimitry Andric #include "llvm/Support/Debug.h" 25ff0cc061SDimitry Andric #include "llvm/Support/raw_ostream.h" 2639d628a0SDimitry Andric #include "llvm/Target/TargetSubtargetInfo.h" 2791bc56edSDimitry Andric 2891bc56edSDimitry Andric using namespace llvm; 2991bc56edSDimitry Andric 3091bc56edSDimitry Andric #define DEBUG_TYPE "stackmaps" 3191bc56edSDimitry Andric 32ff0cc061SDimitry Andric static cl::opt<bool> EnablePatchPointLiveness( 33ff0cc061SDimitry Andric "enable-patchpoint-liveness", cl::Hidden, cl::init(true), 3491bc56edSDimitry Andric cl::desc("Enable PatchPoint Liveness Analysis Pass")); 3591bc56edSDimitry Andric 3691bc56edSDimitry Andric STATISTIC(NumStackMapFuncVisited, "Number of functions visited"); 3791bc56edSDimitry Andric STATISTIC(NumStackMapFuncSkipped, "Number of functions skipped"); 3891bc56edSDimitry Andric STATISTIC(NumBBsVisited, "Number of basic blocks visited"); 3991bc56edSDimitry Andric STATISTIC(NumBBsHaveNoStackmap, "Number of basic blocks with no stackmap"); 4091bc56edSDimitry Andric STATISTIC(NumStackMaps, "Number of StackMaps visited"); 4191bc56edSDimitry Andric 42ff0cc061SDimitry Andric namespace { 43ff0cc061SDimitry Andric /// \brief This pass calculates the liveness information for each basic block in 44ff0cc061SDimitry Andric /// a function and attaches the register live-out information to a patchpoint 45ff0cc061SDimitry Andric /// intrinsic if present. 46ff0cc061SDimitry Andric /// 47ff0cc061SDimitry Andric /// This pass can be disabled via the -enable-patchpoint-liveness=false flag. 48ff0cc061SDimitry Andric /// The pass skips functions that don't have any patchpoint intrinsics. The 49ff0cc061SDimitry Andric /// information provided by this pass is optional and not required by the 50ff0cc061SDimitry Andric /// aformentioned intrinsic to function. 51ff0cc061SDimitry Andric class StackMapLiveness : public MachineFunctionPass { 52ff0cc061SDimitry Andric const TargetRegisterInfo *TRI; 53ff0cc061SDimitry Andric LivePhysRegs LiveRegs; 54ff0cc061SDimitry Andric 55ff0cc061SDimitry Andric public: 56ff0cc061SDimitry Andric static char ID; 57ff0cc061SDimitry Andric 58ff0cc061SDimitry Andric /// \brief Default construct and initialize the pass. 59ff0cc061SDimitry Andric StackMapLiveness(); 60ff0cc061SDimitry Andric 61ff0cc061SDimitry Andric /// \brief Tell the pass manager which passes we depend on and what 62ff0cc061SDimitry Andric /// information we preserve. 63ff0cc061SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override; 64ff0cc061SDimitry Andric 65ff0cc061SDimitry Andric /// \brief Calculate the liveness information for the given machine function. 66ff0cc061SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 67ff0cc061SDimitry Andric 68ff0cc061SDimitry Andric private: 69ff0cc061SDimitry Andric /// \brief Performs the actual liveness calculation for the function. 70875ed548SDimitry Andric bool calculateLiveness(MachineFunction &MF); 71ff0cc061SDimitry Andric 72ff0cc061SDimitry Andric /// \brief Add the current register live set to the instruction. 73875ed548SDimitry Andric void addLiveOutSetToMI(MachineFunction &MF, MachineInstr &MI); 74ff0cc061SDimitry Andric 75ff0cc061SDimitry Andric /// \brief Create a register mask and initialize it with the registers from 76ff0cc061SDimitry Andric /// the register live set. 77875ed548SDimitry Andric uint32_t *createRegisterMask(MachineFunction &MF) const; 78ff0cc061SDimitry Andric }; 79ff0cc061SDimitry Andric } // namespace 80ff0cc061SDimitry Andric 8191bc56edSDimitry Andric char StackMapLiveness::ID = 0; 8291bc56edSDimitry Andric char &llvm::StackMapLivenessID = StackMapLiveness::ID; 8391bc56edSDimitry Andric INITIALIZE_PASS(StackMapLiveness, "stackmap-liveness", 8491bc56edSDimitry Andric "StackMap Liveness Analysis", false, false) 8591bc56edSDimitry Andric 8691bc56edSDimitry Andric /// Default construct and initialize the pass. 8791bc56edSDimitry Andric StackMapLiveness::StackMapLiveness() : MachineFunctionPass(ID) { 8891bc56edSDimitry Andric initializeStackMapLivenessPass(*PassRegistry::getPassRegistry()); 8991bc56edSDimitry Andric } 9091bc56edSDimitry Andric 9191bc56edSDimitry Andric /// Tell the pass manager which passes we depend on and what information we 9291bc56edSDimitry Andric /// preserve. 9391bc56edSDimitry Andric void StackMapLiveness::getAnalysisUsage(AnalysisUsage &AU) const { 9491bc56edSDimitry Andric // We preserve all information. 9591bc56edSDimitry Andric AU.setPreservesAll(); 9691bc56edSDimitry Andric AU.setPreservesCFG(); 97875ed548SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 9891bc56edSDimitry Andric } 9991bc56edSDimitry Andric 10091bc56edSDimitry Andric /// Calculate the liveness information for the given machine function. 101ff0cc061SDimitry Andric bool StackMapLiveness::runOnMachineFunction(MachineFunction &MF) { 10291bc56edSDimitry Andric if (!EnablePatchPointLiveness) 10391bc56edSDimitry Andric return false; 10491bc56edSDimitry Andric 105ff0cc061SDimitry Andric DEBUG(dbgs() << "********** COMPUTING STACKMAP LIVENESS: " << MF.getName() 106ff0cc061SDimitry Andric << " **********\n"); 107ff0cc061SDimitry Andric TRI = MF.getSubtarget().getRegisterInfo(); 10891bc56edSDimitry Andric ++NumStackMapFuncVisited; 10991bc56edSDimitry Andric 11091bc56edSDimitry Andric // Skip this function if there are no patchpoints to process. 111ff0cc061SDimitry Andric if (!MF.getFrameInfo()->hasPatchPoint()) { 11291bc56edSDimitry Andric ++NumStackMapFuncSkipped; 11391bc56edSDimitry Andric return false; 11491bc56edSDimitry Andric } 115875ed548SDimitry Andric return calculateLiveness(MF); 11691bc56edSDimitry Andric } 11791bc56edSDimitry Andric 11891bc56edSDimitry Andric /// Performs the actual liveness calculation for the function. 119875ed548SDimitry Andric bool StackMapLiveness::calculateLiveness(MachineFunction &MF) { 12091bc56edSDimitry Andric bool HasChanged = false; 12191bc56edSDimitry Andric // For all basic blocks in the function. 122875ed548SDimitry Andric for (auto &MBB : MF) { 123875ed548SDimitry Andric DEBUG(dbgs() << "****** BB " << MBB.getName() << " ******\n"); 12491bc56edSDimitry Andric LiveRegs.init(TRI); 125875ed548SDimitry Andric LiveRegs.addLiveOuts(&MBB); 12691bc56edSDimitry Andric bool HasStackMap = false; 12791bc56edSDimitry Andric // Reverse iterate over all instructions and add the current live register 12891bc56edSDimitry Andric // set to an instruction if we encounter a patchpoint instruction. 129875ed548SDimitry Andric for (auto I = MBB.rbegin(), E = MBB.rend(); I != E; ++I) { 13091bc56edSDimitry Andric if (I->getOpcode() == TargetOpcode::PATCHPOINT) { 131875ed548SDimitry Andric addLiveOutSetToMI(MF, *I); 13291bc56edSDimitry Andric HasChanged = true; 13391bc56edSDimitry Andric HasStackMap = true; 13491bc56edSDimitry Andric ++NumStackMaps; 13591bc56edSDimitry Andric } 13691bc56edSDimitry Andric DEBUG(dbgs() << " " << LiveRegs << " " << *I); 13791bc56edSDimitry Andric LiveRegs.stepBackward(*I); 13891bc56edSDimitry Andric } 13991bc56edSDimitry Andric ++NumBBsVisited; 14091bc56edSDimitry Andric if (!HasStackMap) 14191bc56edSDimitry Andric ++NumBBsHaveNoStackmap; 14291bc56edSDimitry Andric } 14391bc56edSDimitry Andric return HasChanged; 14491bc56edSDimitry Andric } 14591bc56edSDimitry Andric 14691bc56edSDimitry Andric /// Add the current register live set to the instruction. 147875ed548SDimitry Andric void StackMapLiveness::addLiveOutSetToMI(MachineFunction &MF, 148875ed548SDimitry Andric MachineInstr &MI) { 149875ed548SDimitry Andric uint32_t *Mask = createRegisterMask(MF); 15091bc56edSDimitry Andric MachineOperand MO = MachineOperand::CreateRegLiveOut(Mask); 151875ed548SDimitry Andric MI.addOperand(MF, MO); 15291bc56edSDimitry Andric } 15391bc56edSDimitry Andric 15491bc56edSDimitry Andric /// Create a register mask and initialize it with the registers from the 15591bc56edSDimitry Andric /// register live set. 156875ed548SDimitry Andric uint32_t *StackMapLiveness::createRegisterMask(MachineFunction &MF) const { 15791bc56edSDimitry Andric // The mask is owned and cleaned up by the Machine Function. 158875ed548SDimitry Andric uint32_t *Mask = MF.allocateRegisterMask(TRI->getNumRegs()); 159875ed548SDimitry Andric for (auto Reg : LiveRegs) 160875ed548SDimitry Andric Mask[Reg / 32] |= 1U << (Reg % 32); 16139d628a0SDimitry Andric 162875ed548SDimitry Andric // Give the target a chance to adjust the mask. 16339d628a0SDimitry Andric TRI->adjustStackMapLiveOutMask(Mask); 164875ed548SDimitry Andric 16591bc56edSDimitry Andric return Mask; 16691bc56edSDimitry Andric } 167