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().set( |
66 | MachineFunctionProperties::Property::NoVRegs); |
67 | } |
68 | |
69 | /// Calculate the liveness information for the given machine function. |
70 | bool runOnMachineFunction(MachineFunction &MF) override; |
71 | |
72 | private: |
73 | /// Performs the actual liveness calculation for the function. |
74 | bool calculateLiveness(MachineFunction &MF); |
75 | |
76 | /// Add the current register live set to the instruction. |
77 | void addLiveOutSetToMI(MachineFunction &MF, MachineInstr &MI); |
78 | |
79 | /// Create a register mask and initialize it with the registers from |
80 | /// the register live set. |
81 | uint32_t *createRegisterMask(MachineFunction &MF) const; |
82 | }; |
83 | } // namespace |
84 | |
85 | char StackMapLiveness::ID = 0; |
86 | char &llvm::StackMapLivenessID = StackMapLiveness::ID; |
87 | INITIALIZE_PASS(StackMapLiveness, "stackmap-liveness" , |
88 | "StackMap Liveness Analysis" , false, false) |
89 | |
90 | /// Default construct and initialize the pass. |
91 | StackMapLiveness::StackMapLiveness() : MachineFunctionPass(ID) { |
92 | initializeStackMapLivenessPass(Registry&: *PassRegistry::getPassRegistry()); |
93 | } |
94 | |
95 | /// Tell the pass manager which passes we depend on and what information we |
96 | /// preserve. |
97 | void StackMapLiveness::getAnalysisUsage(AnalysisUsage &AU) const { |
98 | // We preserve all information. |
99 | AU.setPreservesAll(); |
100 | AU.setPreservesCFG(); |
101 | MachineFunctionPass::getAnalysisUsage(AU); |
102 | } |
103 | |
104 | /// Calculate the liveness information for the given machine function. |
105 | bool StackMapLiveness::runOnMachineFunction(MachineFunction &MF) { |
106 | if (!EnablePatchPointLiveness) |
107 | return false; |
108 | |
109 | LLVM_DEBUG(dbgs() << "********** COMPUTING STACKMAP LIVENESS: " |
110 | << MF.getName() << " **********\n" ); |
111 | TRI = MF.getSubtarget().getRegisterInfo(); |
112 | ++NumStackMapFuncVisited; |
113 | |
114 | // Skip this function if there are no patchpoints to process. |
115 | if (!MF.getFrameInfo().hasPatchPoint()) { |
116 | ++NumStackMapFuncSkipped; |
117 | return false; |
118 | } |
119 | return calculateLiveness(MF); |
120 | } |
121 | |
122 | /// Performs the actual liveness calculation for the function. |
123 | bool StackMapLiveness::calculateLiveness(MachineFunction &MF) { |
124 | bool HasChanged = false; |
125 | // For all basic blocks in the function. |
126 | for (auto &MBB : MF) { |
127 | LLVM_DEBUG(dbgs() << "****** BB " << MBB.getName() << " ******\n" ); |
128 | LiveRegs.init(TRI: *TRI); |
129 | LiveRegs.addLiveOuts(MBB); |
130 | bool HasStackMap = false; |
131 | // Reverse iterate over all instructions and add the current live register |
132 | // set to an instruction if we encounter a patchpoint instruction. |
133 | for (MachineInstr &MI : llvm::reverse(C&: MBB)) { |
134 | if (MI.getOpcode() == TargetOpcode::PATCHPOINT) { |
135 | addLiveOutSetToMI(MF, MI); |
136 | HasChanged = true; |
137 | HasStackMap = true; |
138 | ++NumStackMaps; |
139 | } |
140 | LLVM_DEBUG(dbgs() << " " << LiveRegs << " " << MI); |
141 | LiveRegs.stepBackward(MI); |
142 | } |
143 | ++NumBBsVisited; |
144 | if (!HasStackMap) |
145 | ++NumBBsHaveNoStackmap; |
146 | } |
147 | return HasChanged; |
148 | } |
149 | |
150 | /// Add the current register live set to the instruction. |
151 | void StackMapLiveness::addLiveOutSetToMI(MachineFunction &MF, |
152 | MachineInstr &MI) { |
153 | uint32_t *Mask = createRegisterMask(MF); |
154 | MachineOperand MO = MachineOperand::CreateRegLiveOut(Mask); |
155 | MI.addOperand(MF, Op: MO); |
156 | } |
157 | |
158 | /// Create a register mask and initialize it with the registers from the |
159 | /// register live set. |
160 | uint32_t *StackMapLiveness::createRegisterMask(MachineFunction &MF) const { |
161 | // The mask is owned and cleaned up by the Machine Function. |
162 | uint32_t *Mask = MF.allocateRegMask(); |
163 | for (auto Reg : LiveRegs) |
164 | Mask[Reg / 32] |= 1U << (Reg % 32); |
165 | |
166 | // Give the target a chance to adjust the mask. |
167 | TRI->adjustStackMapLiveOutMask(Mask); |
168 | |
169 | return Mask; |
170 | } |
171 | |