brintos

brintos / llvm-project-archived public Read only

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