109467b48Spatrick //===-- StackMapLivenessAnalysis.cpp - StackMap live Out Analysis ----------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file implements the StackMap Liveness analysis pass. The pass calculates
1009467b48Spatrick // the liveness for each basic block in a function and attaches the register
1109467b48Spatrick // live-out information to a stackmap or patchpoint intrinsic if present.
1209467b48Spatrick //
1309467b48Spatrick //===----------------------------------------------------------------------===//
1409467b48Spatrick
1509467b48Spatrick #include "llvm/ADT/Statistic.h"
1609467b48Spatrick #include "llvm/CodeGen/LivePhysRegs.h"
1709467b48Spatrick #include "llvm/CodeGen/MachineFrameInfo.h"
1809467b48Spatrick #include "llvm/CodeGen/MachineFunction.h"
1909467b48Spatrick #include "llvm/CodeGen/MachineFunctionPass.h"
2009467b48Spatrick #include "llvm/CodeGen/TargetSubtargetInfo.h"
2109467b48Spatrick #include "llvm/InitializePasses.h"
22*d415bd75Srobert #include "llvm/Pass.h"
2309467b48Spatrick #include "llvm/Support/CommandLine.h"
2409467b48Spatrick #include "llvm/Support/Debug.h"
2509467b48Spatrick #include "llvm/Support/raw_ostream.h"
2609467b48Spatrick
2709467b48Spatrick using namespace llvm;
2809467b48Spatrick
2909467b48Spatrick #define DEBUG_TYPE "stackmaps"
3009467b48Spatrick
3109467b48Spatrick static cl::opt<bool> EnablePatchPointLiveness(
3209467b48Spatrick "enable-patchpoint-liveness", cl::Hidden, cl::init(true),
3309467b48Spatrick cl::desc("Enable PatchPoint Liveness Analysis Pass"));
3409467b48Spatrick
3509467b48Spatrick STATISTIC(NumStackMapFuncVisited, "Number of functions visited");
3609467b48Spatrick STATISTIC(NumStackMapFuncSkipped, "Number of functions skipped");
3709467b48Spatrick STATISTIC(NumBBsVisited, "Number of basic blocks visited");
3809467b48Spatrick STATISTIC(NumBBsHaveNoStackmap, "Number of basic blocks with no stackmap");
3909467b48Spatrick STATISTIC(NumStackMaps, "Number of StackMaps visited");
4009467b48Spatrick
4109467b48Spatrick namespace {
4209467b48Spatrick /// This pass calculates the liveness information for each basic block in
4309467b48Spatrick /// a function and attaches the register live-out information to a patchpoint
4409467b48Spatrick /// intrinsic if present.
4509467b48Spatrick ///
4609467b48Spatrick /// This pass can be disabled via the -enable-patchpoint-liveness=false flag.
4709467b48Spatrick /// The pass skips functions that don't have any patchpoint intrinsics. The
4809467b48Spatrick /// information provided by this pass is optional and not required by the
4909467b48Spatrick /// aformentioned intrinsic to function.
5009467b48Spatrick class StackMapLiveness : public MachineFunctionPass {
5109467b48Spatrick const TargetRegisterInfo *TRI;
5209467b48Spatrick LivePhysRegs LiveRegs;
5309467b48Spatrick
5409467b48Spatrick public:
5509467b48Spatrick static char ID;
5609467b48Spatrick
5709467b48Spatrick /// Default construct and initialize the pass.
5809467b48Spatrick StackMapLiveness();
5909467b48Spatrick
6009467b48Spatrick /// Tell the pass manager which passes we depend on and what
6109467b48Spatrick /// information we preserve.
6209467b48Spatrick void getAnalysisUsage(AnalysisUsage &AU) const override;
6309467b48Spatrick
getRequiredProperties() const6409467b48Spatrick MachineFunctionProperties getRequiredProperties() const override {
6509467b48Spatrick return MachineFunctionProperties().set(
6609467b48Spatrick MachineFunctionProperties::Property::NoVRegs);
6709467b48Spatrick }
6809467b48Spatrick
6909467b48Spatrick /// Calculate the liveness information for the given machine function.
7009467b48Spatrick bool runOnMachineFunction(MachineFunction &MF) override;
7109467b48Spatrick
7209467b48Spatrick private:
7309467b48Spatrick /// Performs the actual liveness calculation for the function.
7409467b48Spatrick bool calculateLiveness(MachineFunction &MF);
7509467b48Spatrick
7609467b48Spatrick /// Add the current register live set to the instruction.
7709467b48Spatrick void addLiveOutSetToMI(MachineFunction &MF, MachineInstr &MI);
7809467b48Spatrick
7909467b48Spatrick /// Create a register mask and initialize it with the registers from
8009467b48Spatrick /// the register live set.
8109467b48Spatrick uint32_t *createRegisterMask(MachineFunction &MF) const;
8209467b48Spatrick };
8309467b48Spatrick } // namespace
8409467b48Spatrick
8509467b48Spatrick char StackMapLiveness::ID = 0;
8609467b48Spatrick char &llvm::StackMapLivenessID = StackMapLiveness::ID;
8709467b48Spatrick INITIALIZE_PASS(StackMapLiveness, "stackmap-liveness",
8809467b48Spatrick "StackMap Liveness Analysis", false, false)
8909467b48Spatrick
9009467b48Spatrick /// Default construct and initialize the pass.
StackMapLiveness()9109467b48Spatrick StackMapLiveness::StackMapLiveness() : MachineFunctionPass(ID) {
9209467b48Spatrick initializeStackMapLivenessPass(*PassRegistry::getPassRegistry());
9309467b48Spatrick }
9409467b48Spatrick
9509467b48Spatrick /// Tell the pass manager which passes we depend on and what information we
9609467b48Spatrick /// preserve.
getAnalysisUsage(AnalysisUsage & AU) const9709467b48Spatrick void StackMapLiveness::getAnalysisUsage(AnalysisUsage &AU) const {
9809467b48Spatrick // We preserve all information.
9909467b48Spatrick AU.setPreservesAll();
10009467b48Spatrick AU.setPreservesCFG();
10109467b48Spatrick MachineFunctionPass::getAnalysisUsage(AU);
10209467b48Spatrick }
10309467b48Spatrick
10409467b48Spatrick /// Calculate the liveness information for the given machine function.
runOnMachineFunction(MachineFunction & MF)10509467b48Spatrick bool StackMapLiveness::runOnMachineFunction(MachineFunction &MF) {
10609467b48Spatrick if (!EnablePatchPointLiveness)
10709467b48Spatrick return false;
10809467b48Spatrick
10909467b48Spatrick LLVM_DEBUG(dbgs() << "********** COMPUTING STACKMAP LIVENESS: "
11009467b48Spatrick << MF.getName() << " **********\n");
11109467b48Spatrick TRI = MF.getSubtarget().getRegisterInfo();
11209467b48Spatrick ++NumStackMapFuncVisited;
11309467b48Spatrick
11409467b48Spatrick // Skip this function if there are no patchpoints to process.
11509467b48Spatrick if (!MF.getFrameInfo().hasPatchPoint()) {
11609467b48Spatrick ++NumStackMapFuncSkipped;
11709467b48Spatrick return false;
11809467b48Spatrick }
11909467b48Spatrick return calculateLiveness(MF);
12009467b48Spatrick }
12109467b48Spatrick
12209467b48Spatrick /// Performs the actual liveness calculation for the function.
calculateLiveness(MachineFunction & MF)12309467b48Spatrick bool StackMapLiveness::calculateLiveness(MachineFunction &MF) {
12409467b48Spatrick bool HasChanged = false;
12509467b48Spatrick // For all basic blocks in the function.
12609467b48Spatrick for (auto &MBB : MF) {
12709467b48Spatrick LLVM_DEBUG(dbgs() << "****** BB " << MBB.getName() << " ******\n");
12809467b48Spatrick LiveRegs.init(*TRI);
12909467b48Spatrick // FIXME: This should probably be addLiveOuts().
13009467b48Spatrick LiveRegs.addLiveOutsNoPristines(MBB);
13109467b48Spatrick bool HasStackMap = false;
13209467b48Spatrick // Reverse iterate over all instructions and add the current live register
13309467b48Spatrick // set to an instruction if we encounter a patchpoint instruction.
134*d415bd75Srobert for (MachineInstr &MI : llvm::reverse(MBB)) {
135*d415bd75Srobert if (MI.getOpcode() == TargetOpcode::PATCHPOINT) {
136*d415bd75Srobert addLiveOutSetToMI(MF, MI);
13709467b48Spatrick HasChanged = true;
13809467b48Spatrick HasStackMap = true;
13909467b48Spatrick ++NumStackMaps;
14009467b48Spatrick }
141*d415bd75Srobert LLVM_DEBUG(dbgs() << " " << LiveRegs << " " << MI);
142*d415bd75Srobert LiveRegs.stepBackward(MI);
14309467b48Spatrick }
14409467b48Spatrick ++NumBBsVisited;
14509467b48Spatrick if (!HasStackMap)
14609467b48Spatrick ++NumBBsHaveNoStackmap;
14709467b48Spatrick }
14809467b48Spatrick return HasChanged;
14909467b48Spatrick }
15009467b48Spatrick
15109467b48Spatrick /// Add the current register live set to the instruction.
addLiveOutSetToMI(MachineFunction & MF,MachineInstr & MI)15209467b48Spatrick void StackMapLiveness::addLiveOutSetToMI(MachineFunction &MF,
15309467b48Spatrick MachineInstr &MI) {
15409467b48Spatrick uint32_t *Mask = createRegisterMask(MF);
15509467b48Spatrick MachineOperand MO = MachineOperand::CreateRegLiveOut(Mask);
15609467b48Spatrick MI.addOperand(MF, MO);
15709467b48Spatrick }
15809467b48Spatrick
15909467b48Spatrick /// Create a register mask and initialize it with the registers from the
16009467b48Spatrick /// register live set.
createRegisterMask(MachineFunction & MF) const16109467b48Spatrick uint32_t *StackMapLiveness::createRegisterMask(MachineFunction &MF) const {
16209467b48Spatrick // The mask is owned and cleaned up by the Machine Function.
16309467b48Spatrick uint32_t *Mask = MF.allocateRegMask();
16409467b48Spatrick for (auto Reg : LiveRegs)
16509467b48Spatrick Mask[Reg / 32] |= 1U << (Reg % 32);
16609467b48Spatrick
16709467b48Spatrick // Give the target a chance to adjust the mask.
16809467b48Spatrick TRI->adjustStackMapLiveOutMask(Mask);
16909467b48Spatrick
17009467b48Spatrick return Mask;
17109467b48Spatrick }
172