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-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file implements the StackMap Liveness analysis pass. The pass calculates |
10 | // the liveness for each basic block in a function and attaches the register |
11 | // 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 | |
27 | using namespace llvm; |
28 | |
29 | #define DEBUG_TYPE "stackmaps" |
30 | |
31 | static cl::opt<bool> EnablePatchPointLiveness( |
32 | "enable-patchpoint-liveness" , cl::Hidden, cl::init(Val: true), |
33 | cl::desc("Enable PatchPoint Liveness Analysis Pass" )); |
34 | |
35 | STATISTIC(NumStackMapFuncVisited, "Number of functions visited" ); |
36 | STATISTIC(NumStackMapFuncSkipped, "Number of functions skipped" ); |
37 | STATISTIC(NumBBsVisited, "Number of basic blocks visited" ); |
38 | STATISTIC(NumBBsHaveNoStackmap, "Number of basic blocks with no stackmap" ); |
39 | STATISTIC(NumStackMaps, "Number of StackMaps visited" ); |
40 | |
41 | namespace { |
42 | /// This pass calculates the liveness information for each basic block in |
43 | /// a function and attaches the register live-out information to a patchpoint |
44 | /// 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. The |
48 | /// information provided by this pass is optional and not required by the |
49 | /// aformentioned intrinsic to function. |
50 | class StackMapLiveness : public MachineFunctionPass { |
51 | const TargetRegisterInfo *TRI = nullptr; |
52 | LivePhysRegs LiveRegs; |
53 | |
54 | public: |
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 what |
61 | /// 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 | |
71 | private: |
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 from |
79 | /// the register live set. |
80 | uint32_t *createRegisterMask(MachineFunction &MF) const; |
81 | }; |
82 | } // namespace |
83 | |
84 | char StackMapLiveness::ID = 0; |
85 | char &llvm::StackMapLivenessID = StackMapLiveness::ID; |
86 | INITIALIZE_PASS(StackMapLiveness, "stackmap-liveness" , |
87 | "StackMap Liveness Analysis" , false, false) |
88 | |
89 | /// Default construct and initialize the pass. |
90 | StackMapLiveness::StackMapLiveness() : MachineFunctionPass(ID) { |
91 | initializeStackMapLivenessPass(Registry&: *PassRegistry::getPassRegistry()); |
92 | } |
93 | |
94 | /// Tell the pass manager which passes we depend on and what information we |
95 | /// preserve. |
96 | void 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. |
104 | bool 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. |
120 | bool 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: *TRI); |
128 | LiveRegs.addLiveOuts(MBB); |
129 | bool HasStackMap = false; |
130 | // Reverse iterate over all instructions and add the current live register |
131 | // set to an instruction if we encounter a patchpoint instruction. |
132 | for (MachineInstr &MI : llvm::reverse(C&: 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. |
150 | void StackMapLiveness::addLiveOutSetToMI(MachineFunction &MF, |
151 | MachineInstr &MI) { |
152 | uint32_t *Mask = createRegisterMask(MF); |
153 | MachineOperand MO = MachineOperand::CreateRegLiveOut(Mask); |
154 | MI.addOperand(MF, Op: MO); |
155 | } |
156 | |
157 | /// Create a register mask and initialize it with the registers from the |
158 | /// register live set. |
159 | uint32_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 | |