X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FStackMapLivenessAnalysis.cpp;h=855058358fe49c232305b6592258fdb43df96ed5;hb=c05a5c2c864cd22f86b71f9815f9b83798cf543b;hp=a374417a90e7583a9d3249c87fa2ddc22061c62b;hpb=aaecc0fc0898be1bdd0f5e6f67230cae559f61b8;p=oota-llvm.git diff --git a/lib/CodeGen/StackMapLivenessAnalysis.cpp b/lib/CodeGen/StackMapLivenessAnalysis.cpp index a374417a90e..855058358fe 100644 --- a/lib/CodeGen/StackMapLivenessAnalysis.cpp +++ b/lib/CodeGen/StackMapLivenessAnalysis.cpp @@ -13,25 +13,25 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "stackmaps" #include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/LivePhysRegs.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionAnalysis.h" +#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/Passes.h" -#include "llvm/CodeGen/StackMapLivenessAnalysis.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" - +#include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; -namespace llvm { -cl::opt EnableStackMapLiveness("enable-stackmap-liveness", - cl::Hidden, cl::desc("Enable StackMap Liveness Analysis Pass")); -cl::opt EnablePatchPointLiveness("enable-patchpoint-liveness", - cl::Hidden, cl::desc("Enable PatchPoint Liveness Analysis Pass")); -} +#define DEBUG_TYPE "stackmaps" + +static cl::opt EnablePatchPointLiveness( + "enable-patchpoint-liveness", cl::Hidden, cl::init(true), + cl::desc("Enable PatchPoint Liveness Analysis Pass")); STATISTIC(NumStackMapFuncVisited, "Number of functions visited"); STATISTIC(NumStackMapFuncSkipped, "Number of functions skipped"); @@ -39,6 +39,45 @@ STATISTIC(NumBBsVisited, "Number of basic blocks visited"); STATISTIC(NumBBsHaveNoStackmap, "Number of basic blocks with no stackmap"); STATISTIC(NumStackMaps, "Number of StackMaps visited"); +namespace { +/// \brief This pass calculates the liveness information for each basic block in +/// a function and attaches the register live-out information to a patchpoint +/// intrinsic if present. +/// +/// This pass can be disabled via the -enable-patchpoint-liveness=false flag. +/// The pass skips functions that don't have any patchpoint intrinsics. The +/// information provided by this pass is optional and not required by the +/// aformentioned intrinsic to function. +class StackMapLiveness : public MachineFunctionPass { + const TargetRegisterInfo *TRI; + LivePhysRegs LiveRegs; + +public: + static char ID; + + /// \brief Default construct and initialize the pass. + StackMapLiveness(); + + /// \brief Tell the pass manager which passes we depend on and what + /// information we preserve. + void getAnalysisUsage(AnalysisUsage &AU) const override; + + /// \brief Calculate the liveness information for the given machine function. + bool runOnMachineFunction(MachineFunction &MF) override; + +private: + /// \brief Performs the actual liveness calculation for the function. + bool calculateLiveness(MachineFunction &MF); + + /// \brief Add the current register live set to the instruction. + void addLiveOutSetToMI(MachineFunction &MF, MachineInstr &MI); + + /// \brief Create a register mask and initialize it with the registers from + /// the register live set. + uint32_t *createRegisterMask(MachineFunction &MF) const; +}; +} // namespace + char StackMapLiveness::ID = 0; char &llvm::StackMapLivenessID = StackMapLiveness::ID; INITIALIZE_PASS(StackMapLiveness, "stackmap-liveness", @@ -55,51 +94,46 @@ void StackMapLiveness::getAnalysisUsage(AnalysisUsage &AU) const { // We preserve all information. AU.setPreservesAll(); AU.setPreservesCFG(); - // Default dependencie for all MachineFunction passes. - AU.addRequired(); + MachineFunctionPass::getAnalysisUsage(AU); } /// Calculate the liveness information for the given machine function. -bool StackMapLiveness::runOnMachineFunction(MachineFunction &_MF) { - DEBUG(dbgs() << "********** COMPUTING STACKMAP LIVENESS: " - << _MF.getName() << " **********\n"); - MF = &_MF; - TRI = MF->getTarget().getRegisterInfo(); +bool StackMapLiveness::runOnMachineFunction(MachineFunction &MF) { + if (!EnablePatchPointLiveness) + return false; + + DEBUG(dbgs() << "********** COMPUTING STACKMAP LIVENESS: " << MF.getName() + << " **********\n"); + TRI = MF.getSubtarget().getRegisterInfo(); ++NumStackMapFuncVisited; - // Skip this function if there are no stackmaps or patchpoints to process. - if (!((MF->getFrameInfo()->hasStackMap() && EnableStackMapLiveness) || - (MF->getFrameInfo()->hasPatchPoint() && EnablePatchPointLiveness))) { + // Skip this function if there are no patchpoints to process. + if (!MF.getFrameInfo()->hasPatchPoint()) { ++NumStackMapFuncSkipped; return false; } - return calculateLiveness(); + return calculateLiveness(MF); } /// Performs the actual liveness calculation for the function. -bool StackMapLiveness::calculateLiveness() { +bool StackMapLiveness::calculateLiveness(MachineFunction &MF) { bool HasChanged = false; // For all basic blocks in the function. - for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end(); - MBBI != MBBE; ++MBBI) { - DEBUG(dbgs() << "****** BB " << MBBI->getName() << " ******\n"); + for (auto &MBB : MF) { + DEBUG(dbgs() << "****** BB " << MBB.getName() << " ******\n"); LiveRegs.init(TRI); - LiveRegs.addLiveOuts(MBBI); + LiveRegs.addLiveOuts(&MBB); bool HasStackMap = false; // Reverse iterate over all instructions and add the current live register - // set to an instruction if we encounter a stackmap or patchpoint - // instruction. - for (MachineBasicBlock::reverse_iterator I = MBBI->rbegin(), - E = MBBI->rend(); I != E; ++I) { - int Opc = I->getOpcode(); - if ((EnableStackMapLiveness && (Opc == TargetOpcode::STACKMAP)) || - (EnablePatchPointLiveness && (Opc == TargetOpcode::PATCHPOINT))) { - addLiveOutSetToMI(*I); + // set to an instruction if we encounter a patchpoint instruction. + for (auto I = MBB.rbegin(), E = MBB.rend(); I != E; ++I) { + if (I->getOpcode() == TargetOpcode::PATCHPOINT) { + addLiveOutSetToMI(MF, *I); HasChanged = true; HasStackMap = true; ++NumStackMaps; } - DEBUG(dbgs() << " " << *I << " " << LiveRegs); + DEBUG(dbgs() << " " << LiveRegs << " " << *I); LiveRegs.stepBackward(*I); } ++NumBBsVisited; @@ -110,19 +144,23 @@ bool StackMapLiveness::calculateLiveness() { } /// Add the current register live set to the instruction. -void StackMapLiveness::addLiveOutSetToMI(MachineInstr &MI) { - uint32_t *Mask = createRegisterMask(); +void StackMapLiveness::addLiveOutSetToMI(MachineFunction &MF, + MachineInstr &MI) { + uint32_t *Mask = createRegisterMask(MF); MachineOperand MO = MachineOperand::CreateRegLiveOut(Mask); - MI.addOperand(*MF, MO); + MI.addOperand(MF, MO); } /// Create a register mask and initialize it with the registers from the /// register live set. -uint32_t *StackMapLiveness::createRegisterMask() const { +uint32_t *StackMapLiveness::createRegisterMask(MachineFunction &MF) const { // The mask is owned and cleaned up by the Machine Function. - uint32_t *Mask = MF->allocateRegisterMask(TRI->getNumRegs()); - for (LivePhysRegs::const_iterator RI = LiveRegs.begin(), RE = LiveRegs.end(); - RI != RE; ++RI) - Mask[*RI / 32] |= 1U << (*RI % 32); + uint32_t *Mask = MF.allocateRegisterMask(TRI->getNumRegs()); + for (auto Reg : LiveRegs) + Mask[Reg / 32] |= 1U << (Reg % 32); + + // Give the target a chance to adjust the mask. + TRI->adjustStackMapLiveOutMask(Mask); + return Mask; }