xref: /openbsd-src/gnu/llvm/llvm/lib/CodeGen/StackMapLivenessAnalysis.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
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