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 MachineFunction *MF; 53ff0cc061SDimitry Andric const TargetRegisterInfo *TRI; 54ff0cc061SDimitry Andric LivePhysRegs LiveRegs; 55ff0cc061SDimitry Andric 56ff0cc061SDimitry Andric public: 57ff0cc061SDimitry Andric static char ID; 58ff0cc061SDimitry Andric 59ff0cc061SDimitry Andric /// \brief Default construct and initialize the pass. 60ff0cc061SDimitry Andric StackMapLiveness(); 61ff0cc061SDimitry Andric 62ff0cc061SDimitry Andric /// \brief Tell the pass manager which passes we depend on and what 63ff0cc061SDimitry Andric /// information we preserve. 64ff0cc061SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override; 65ff0cc061SDimitry Andric 66ff0cc061SDimitry Andric /// \brief Calculate the liveness information for the given machine function. 67ff0cc061SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 68ff0cc061SDimitry Andric 69ff0cc061SDimitry Andric private: 70ff0cc061SDimitry Andric /// \brief Performs the actual liveness calculation for the function. 71ff0cc061SDimitry Andric bool calculateLiveness(); 72ff0cc061SDimitry Andric 73ff0cc061SDimitry Andric /// \brief Add the current register live set to the instruction. 74ff0cc061SDimitry Andric void addLiveOutSetToMI(MachineInstr &MI); 75ff0cc061SDimitry Andric 76ff0cc061SDimitry Andric /// \brief Create a register mask and initialize it with the registers from 77ff0cc061SDimitry Andric /// the register live set. 78ff0cc061SDimitry Andric uint32_t *createRegisterMask() const; 79ff0cc061SDimitry Andric }; 80ff0cc061SDimitry Andric } // namespace 81ff0cc061SDimitry Andric 8291bc56edSDimitry Andric char StackMapLiveness::ID = 0; 8391bc56edSDimitry Andric char &llvm::StackMapLivenessID = StackMapLiveness::ID; 8491bc56edSDimitry Andric INITIALIZE_PASS(StackMapLiveness, "stackmap-liveness", 8591bc56edSDimitry Andric "StackMap Liveness Analysis", false, false) 8691bc56edSDimitry Andric 8791bc56edSDimitry Andric /// Default construct and initialize the pass. 8891bc56edSDimitry Andric StackMapLiveness::StackMapLiveness() : MachineFunctionPass(ID) { 8991bc56edSDimitry Andric initializeStackMapLivenessPass(*PassRegistry::getPassRegistry()); 9091bc56edSDimitry Andric } 9191bc56edSDimitry Andric 9291bc56edSDimitry Andric /// Tell the pass manager which passes we depend on and what information we 9391bc56edSDimitry Andric /// preserve. 9491bc56edSDimitry Andric void StackMapLiveness::getAnalysisUsage(AnalysisUsage &AU) const { 9591bc56edSDimitry Andric // We preserve all information. 9691bc56edSDimitry Andric AU.setPreservesAll(); 9791bc56edSDimitry Andric AU.setPreservesCFG(); 9891bc56edSDimitry Andric // Default dependencie for all MachineFunction passes. 9991bc56edSDimitry Andric AU.addRequired<MachineFunctionAnalysis>(); 10091bc56edSDimitry Andric } 10191bc56edSDimitry Andric 10291bc56edSDimitry Andric /// Calculate the liveness information for the given machine function. 103ff0cc061SDimitry Andric bool StackMapLiveness::runOnMachineFunction(MachineFunction &MF) { 10491bc56edSDimitry Andric if (!EnablePatchPointLiveness) 10591bc56edSDimitry Andric return false; 10691bc56edSDimitry Andric 107ff0cc061SDimitry Andric DEBUG(dbgs() << "********** COMPUTING STACKMAP LIVENESS: " << MF.getName() 108ff0cc061SDimitry Andric << " **********\n"); 109ff0cc061SDimitry Andric this->MF = &MF; 110ff0cc061SDimitry Andric TRI = MF.getSubtarget().getRegisterInfo(); 11191bc56edSDimitry Andric ++NumStackMapFuncVisited; 11291bc56edSDimitry Andric 11391bc56edSDimitry Andric // Skip this function if there are no patchpoints to process. 114ff0cc061SDimitry Andric if (!MF.getFrameInfo()->hasPatchPoint()) { 11591bc56edSDimitry Andric ++NumStackMapFuncSkipped; 11691bc56edSDimitry Andric return false; 11791bc56edSDimitry Andric } 11891bc56edSDimitry Andric return calculateLiveness(); 11991bc56edSDimitry Andric } 12091bc56edSDimitry Andric 12191bc56edSDimitry Andric /// Performs the actual liveness calculation for the function. 12291bc56edSDimitry Andric bool StackMapLiveness::calculateLiveness() { 12391bc56edSDimitry Andric bool HasChanged = false; 12491bc56edSDimitry Andric // For all basic blocks in the function. 12591bc56edSDimitry Andric for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end(); 12691bc56edSDimitry Andric MBBI != MBBE; ++MBBI) { 12791bc56edSDimitry Andric DEBUG(dbgs() << "****** BB " << MBBI->getName() << " ******\n"); 12891bc56edSDimitry Andric LiveRegs.init(TRI); 12991bc56edSDimitry Andric LiveRegs.addLiveOuts(MBBI); 13091bc56edSDimitry Andric bool HasStackMap = false; 13191bc56edSDimitry Andric // Reverse iterate over all instructions and add the current live register 13291bc56edSDimitry Andric // set to an instruction if we encounter a patchpoint instruction. 13391bc56edSDimitry Andric for (MachineBasicBlock::reverse_iterator I = MBBI->rbegin(), 13491bc56edSDimitry Andric E = MBBI->rend(); I != E; ++I) { 13591bc56edSDimitry Andric if (I->getOpcode() == TargetOpcode::PATCHPOINT) { 13691bc56edSDimitry Andric addLiveOutSetToMI(*I); 13791bc56edSDimitry Andric HasChanged = true; 13891bc56edSDimitry Andric HasStackMap = true; 13991bc56edSDimitry Andric ++NumStackMaps; 14091bc56edSDimitry Andric } 14191bc56edSDimitry Andric DEBUG(dbgs() << " " << LiveRegs << " " << *I); 14291bc56edSDimitry Andric LiveRegs.stepBackward(*I); 14391bc56edSDimitry Andric } 14491bc56edSDimitry Andric ++NumBBsVisited; 14591bc56edSDimitry Andric if (!HasStackMap) 14691bc56edSDimitry Andric ++NumBBsHaveNoStackmap; 14791bc56edSDimitry Andric } 14891bc56edSDimitry Andric return HasChanged; 14991bc56edSDimitry Andric } 15091bc56edSDimitry Andric 15191bc56edSDimitry Andric /// Add the current register live set to the instruction. 15291bc56edSDimitry Andric void StackMapLiveness::addLiveOutSetToMI(MachineInstr &MI) { 15391bc56edSDimitry Andric uint32_t *Mask = createRegisterMask(); 15491bc56edSDimitry Andric MachineOperand MO = MachineOperand::CreateRegLiveOut(Mask); 15591bc56edSDimitry Andric MI.addOperand(*MF, MO); 15691bc56edSDimitry Andric } 15791bc56edSDimitry Andric 15891bc56edSDimitry Andric /// Create a register mask and initialize it with the registers from the 15991bc56edSDimitry Andric /// register live set. 16091bc56edSDimitry Andric uint32_t *StackMapLiveness::createRegisterMask() const { 16191bc56edSDimitry Andric // The mask is owned and cleaned up by the Machine Function. 16291bc56edSDimitry Andric uint32_t *Mask = MF->allocateRegisterMask(TRI->getNumRegs()); 16391bc56edSDimitry Andric for (LivePhysRegs::const_iterator RI = LiveRegs.begin(), RE = LiveRegs.end(); 16491bc56edSDimitry Andric RI != RE; ++RI) 16591bc56edSDimitry Andric Mask[*RI / 32] |= 1U << (*RI % 32); 16639d628a0SDimitry Andric 16739d628a0SDimitry Andric TRI->adjustStackMapLiveOutMask(Mask); 16891bc56edSDimitry Andric return Mask; 16991bc56edSDimitry Andric } 170