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" 1791bc56edSDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 1891bc56edSDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 1991bc56edSDimitry Andric #include "llvm/CodeGen/MachineFunctionAnalysis.h" 2091bc56edSDimitry Andric #include "llvm/CodeGen/Passes.h" 2191bc56edSDimitry Andric #include "llvm/CodeGen/StackMapLivenessAnalysis.h" 2291bc56edSDimitry Andric #include "llvm/Support/CommandLine.h" 2391bc56edSDimitry Andric #include "llvm/Support/Debug.h" 2491bc56edSDimitry Andric 2591bc56edSDimitry Andric 2691bc56edSDimitry Andric using namespace llvm; 2791bc56edSDimitry Andric 2891bc56edSDimitry Andric #define DEBUG_TYPE "stackmaps" 2991bc56edSDimitry Andric 3091bc56edSDimitry Andric namespace llvm { 3191bc56edSDimitry Andric cl::opt<bool> EnablePatchPointLiveness("enable-patchpoint-liveness", 3291bc56edSDimitry Andric cl::Hidden, cl::init(true), 3391bc56edSDimitry Andric cl::desc("Enable PatchPoint Liveness Analysis Pass")); 3491bc56edSDimitry Andric } 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 4291bc56edSDimitry Andric char StackMapLiveness::ID = 0; 4391bc56edSDimitry Andric char &llvm::StackMapLivenessID = StackMapLiveness::ID; 4491bc56edSDimitry Andric INITIALIZE_PASS(StackMapLiveness, "stackmap-liveness", 4591bc56edSDimitry Andric "StackMap Liveness Analysis", false, false) 4691bc56edSDimitry Andric 4791bc56edSDimitry Andric /// Default construct and initialize the pass. 4891bc56edSDimitry Andric StackMapLiveness::StackMapLiveness() : MachineFunctionPass(ID) { 4991bc56edSDimitry Andric initializeStackMapLivenessPass(*PassRegistry::getPassRegistry()); 5091bc56edSDimitry Andric } 5191bc56edSDimitry Andric 5291bc56edSDimitry Andric /// Tell the pass manager which passes we depend on and what information we 5391bc56edSDimitry Andric /// preserve. 5491bc56edSDimitry Andric void StackMapLiveness::getAnalysisUsage(AnalysisUsage &AU) const { 5591bc56edSDimitry Andric // We preserve all information. 5691bc56edSDimitry Andric AU.setPreservesAll(); 5791bc56edSDimitry Andric AU.setPreservesCFG(); 5891bc56edSDimitry Andric // Default dependencie for all MachineFunction passes. 5991bc56edSDimitry Andric AU.addRequired<MachineFunctionAnalysis>(); 6091bc56edSDimitry Andric } 6191bc56edSDimitry Andric 6291bc56edSDimitry Andric /// Calculate the liveness information for the given machine function. 6391bc56edSDimitry Andric bool StackMapLiveness::runOnMachineFunction(MachineFunction &_MF) { 6491bc56edSDimitry Andric if (!EnablePatchPointLiveness) 6591bc56edSDimitry Andric return false; 6691bc56edSDimitry Andric 6791bc56edSDimitry Andric DEBUG(dbgs() << "********** COMPUTING STACKMAP LIVENESS: " 6891bc56edSDimitry Andric << _MF.getName() << " **********\n"); 6991bc56edSDimitry Andric MF = &_MF; 7091bc56edSDimitry Andric TRI = MF->getTarget().getRegisterInfo(); 7191bc56edSDimitry Andric ++NumStackMapFuncVisited; 7291bc56edSDimitry Andric 7391bc56edSDimitry Andric // Skip this function if there are no patchpoints to process. 7491bc56edSDimitry Andric if (!MF->getFrameInfo()->hasPatchPoint()) { 7591bc56edSDimitry Andric ++NumStackMapFuncSkipped; 7691bc56edSDimitry Andric return false; 7791bc56edSDimitry Andric } 7891bc56edSDimitry Andric return calculateLiveness(); 7991bc56edSDimitry Andric } 8091bc56edSDimitry Andric 8191bc56edSDimitry Andric /// Performs the actual liveness calculation for the function. 8291bc56edSDimitry Andric bool StackMapLiveness::calculateLiveness() { 8391bc56edSDimitry Andric bool HasChanged = false; 8491bc56edSDimitry Andric // For all basic blocks in the function. 8591bc56edSDimitry Andric for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end(); 8691bc56edSDimitry Andric MBBI != MBBE; ++MBBI) { 8791bc56edSDimitry Andric DEBUG(dbgs() << "****** BB " << MBBI->getName() << " ******\n"); 8891bc56edSDimitry Andric LiveRegs.init(TRI); 8991bc56edSDimitry Andric LiveRegs.addLiveOuts(MBBI); 9091bc56edSDimitry Andric bool HasStackMap = false; 9191bc56edSDimitry Andric // Reverse iterate over all instructions and add the current live register 9291bc56edSDimitry Andric // set to an instruction if we encounter a patchpoint instruction. 9391bc56edSDimitry Andric for (MachineBasicBlock::reverse_iterator I = MBBI->rbegin(), 9491bc56edSDimitry Andric E = MBBI->rend(); I != E; ++I) { 9591bc56edSDimitry Andric if (I->getOpcode() == TargetOpcode::PATCHPOINT) { 9691bc56edSDimitry Andric addLiveOutSetToMI(*I); 9791bc56edSDimitry Andric HasChanged = true; 9891bc56edSDimitry Andric HasStackMap = true; 9991bc56edSDimitry Andric ++NumStackMaps; 10091bc56edSDimitry Andric } 10191bc56edSDimitry Andric DEBUG(dbgs() << " " << LiveRegs << " " << *I); 10291bc56edSDimitry Andric LiveRegs.stepBackward(*I); 10391bc56edSDimitry Andric } 10491bc56edSDimitry Andric ++NumBBsVisited; 10591bc56edSDimitry Andric if (!HasStackMap) 10691bc56edSDimitry Andric ++NumBBsHaveNoStackmap; 10791bc56edSDimitry Andric } 10891bc56edSDimitry Andric return HasChanged; 10991bc56edSDimitry Andric } 11091bc56edSDimitry Andric 11191bc56edSDimitry Andric /// Add the current register live set to the instruction. 11291bc56edSDimitry Andric void StackMapLiveness::addLiveOutSetToMI(MachineInstr &MI) { 11391bc56edSDimitry Andric uint32_t *Mask = createRegisterMask(); 11491bc56edSDimitry Andric MachineOperand MO = MachineOperand::CreateRegLiveOut(Mask); 11591bc56edSDimitry Andric MI.addOperand(*MF, MO); 11691bc56edSDimitry Andric } 11791bc56edSDimitry Andric 11891bc56edSDimitry Andric /// Create a register mask and initialize it with the registers from the 11991bc56edSDimitry Andric /// register live set. 12091bc56edSDimitry Andric uint32_t *StackMapLiveness::createRegisterMask() const { 12191bc56edSDimitry Andric // The mask is owned and cleaned up by the Machine Function. 12291bc56edSDimitry Andric uint32_t *Mask = MF->allocateRegisterMask(TRI->getNumRegs()); 12391bc56edSDimitry Andric for (LivePhysRegs::const_iterator RI = LiveRegs.begin(), RE = LiveRegs.end(); 12491bc56edSDimitry Andric RI != RE; ++RI) 12591bc56edSDimitry Andric Mask[*RI / 32] |= 1U << (*RI % 32); 12691bc56edSDimitry Andric return Mask; 12791bc56edSDimitry Andric } 128