/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/CodeGen/StackMapLivenessAnalysis.cpp
Line | Count | Source |
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/Passes.h" |
21 | | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
22 | | #include "llvm/Support/CommandLine.h" |
23 | | #include "llvm/Support/Debug.h" |
24 | | #include "llvm/Support/raw_ostream.h" |
25 | | |
26 | | using namespace llvm; |
27 | | |
28 | | #define DEBUG_TYPE "stackmaps" |
29 | | |
30 | | static cl::opt<bool> EnablePatchPointLiveness( |
31 | | "enable-patchpoint-liveness", cl::Hidden, cl::init(true), |
32 | | cl::desc("Enable PatchPoint Liveness Analysis Pass")); |
33 | | |
34 | | STATISTIC(NumStackMapFuncVisited, "Number of functions visited"); |
35 | | STATISTIC(NumStackMapFuncSkipped, "Number of functions skipped"); |
36 | | STATISTIC(NumBBsVisited, "Number of basic blocks visited"); |
37 | | STATISTIC(NumBBsHaveNoStackmap, "Number of basic blocks with no stackmap"); |
38 | | STATISTIC(NumStackMaps, "Number of StackMaps visited"); |
39 | | |
40 | | namespace { |
41 | | /// This pass calculates the liveness information for each basic block in |
42 | | /// a function and attaches the register live-out information to a patchpoint |
43 | | /// intrinsic if present. |
44 | | /// |
45 | | /// This pass can be disabled via the -enable-patchpoint-liveness=false flag. |
46 | | /// The pass skips functions that don't have any patchpoint intrinsics. The |
47 | | /// information provided by this pass is optional and not required by the |
48 | | /// aformentioned intrinsic to function. |
49 | | class StackMapLiveness : public MachineFunctionPass { |
50 | | const TargetRegisterInfo *TRI; |
51 | | LivePhysRegs LiveRegs; |
52 | | |
53 | | public: |
54 | | static char ID; |
55 | | |
56 | | /// Default construct and initialize the pass. |
57 | | StackMapLiveness(); |
58 | | |
59 | | /// Tell the pass manager which passes we depend on and what |
60 | | /// information we preserve. |
61 | | void getAnalysisUsage(AnalysisUsage &AU) const override; |
62 | | |
63 | 32.6k | MachineFunctionProperties getRequiredProperties() const override { |
64 | 32.6k | return MachineFunctionProperties().set( |
65 | 32.6k | MachineFunctionProperties::Property::NoVRegs); |
66 | 32.6k | } |
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 | 32.9k | StackMapLiveness::StackMapLiveness() : MachineFunctionPass(ID) { |
91 | 32.9k | initializeStackMapLivenessPass(*PassRegistry::getPassRegistry()); |
92 | 32.9k | } |
93 | | |
94 | | /// Tell the pass manager which passes we depend on and what information we |
95 | | /// preserve. |
96 | 32.6k | void StackMapLiveness::getAnalysisUsage(AnalysisUsage &AU) const { |
97 | 32.6k | // We preserve all information. |
98 | 32.6k | AU.setPreservesAll(); |
99 | 32.6k | AU.setPreservesCFG(); |
100 | 32.6k | MachineFunctionPass::getAnalysisUsage(AU); |
101 | 32.6k | } |
102 | | |
103 | | /// Calculate the liveness information for the given machine function. |
104 | 464k | bool StackMapLiveness::runOnMachineFunction(MachineFunction &MF) { |
105 | 464k | if (!EnablePatchPointLiveness) |
106 | 2 | return false; |
107 | 464k | |
108 | 464k | LLVM_DEBUG(dbgs() << "********** COMPUTING STACKMAP LIVENESS: " |
109 | 464k | << MF.getName() << " **********\n"); |
110 | 464k | TRI = MF.getSubtarget().getRegisterInfo(); |
111 | 464k | ++NumStackMapFuncVisited; |
112 | 464k | |
113 | 464k | // Skip this function if there are no patchpoints to process. |
114 | 464k | if (!MF.getFrameInfo().hasPatchPoint()) { |
115 | 464k | ++NumStackMapFuncSkipped; |
116 | 464k | return false; |
117 | 464k | } |
118 | 142 | return calculateLiveness(MF); |
119 | 142 | } |
120 | | |
121 | | /// Performs the actual liveness calculation for the function. |
122 | 150 | bool StackMapLiveness::calculateLiveness(MachineFunction &MF) { |
123 | 150 | bool HasChanged = false; |
124 | 150 | // For all basic blocks in the function. |
125 | 163 | for (auto &MBB : MF) { |
126 | 163 | LLVM_DEBUG(dbgs() << "****** BB " << MBB.getName() << " ******\n"); |
127 | 163 | LiveRegs.init(*TRI); |
128 | 163 | // FIXME: This should probably be addLiveOuts(). |
129 | 163 | LiveRegs.addLiveOutsNoPristines(MBB); |
130 | 163 | bool HasStackMap = false; |
131 | 163 | // Reverse iterate over all instructions and add the current live register |
132 | 163 | // set to an instruction if we encounter a patchpoint instruction. |
133 | 3.08k | for (auto I = MBB.rbegin(), E = MBB.rend(); I != E; ++I2.92k ) { |
134 | 2.92k | if (I->getOpcode() == TargetOpcode::PATCHPOINT) { |
135 | 181 | addLiveOutSetToMI(MF, *I); |
136 | 181 | HasChanged = true; |
137 | 181 | HasStackMap = true; |
138 | 181 | ++NumStackMaps; |
139 | 181 | } |
140 | 2.92k | LLVM_DEBUG(dbgs() << " " << LiveRegs << " " << *I); |
141 | 2.92k | LiveRegs.stepBackward(*I); |
142 | 2.92k | } |
143 | 163 | ++NumBBsVisited; |
144 | 163 | if (!HasStackMap) |
145 | 13 | ++NumBBsHaveNoStackmap; |
146 | 163 | } |
147 | 150 | return HasChanged; |
148 | 150 | } |
149 | | |
150 | | /// Add the current register live set to the instruction. |
151 | | void StackMapLiveness::addLiveOutSetToMI(MachineFunction &MF, |
152 | 181 | MachineInstr &MI) { |
153 | 181 | uint32_t *Mask = createRegisterMask(MF); |
154 | 181 | MachineOperand MO = MachineOperand::CreateRegLiveOut(Mask); |
155 | 181 | MI.addOperand(MF, MO); |
156 | 181 | } |
157 | | |
158 | | /// Create a register mask and initialize it with the registers from the |
159 | | /// register live set. |
160 | 181 | uint32_t *StackMapLiveness::createRegisterMask(MachineFunction &MF) const { |
161 | 181 | // The mask is owned and cleaned up by the Machine Function. |
162 | 181 | uint32_t *Mask = MF.allocateRegMask(); |
163 | 181 | for (auto Reg : LiveRegs) |
164 | 1.21k | Mask[Reg / 32] |= 1U << (Reg % 32); |
165 | 181 | |
166 | 181 | // Give the target a chance to adjust the mask. |
167 | 181 | TRI->adjustStackMapLiveOutMask(Mask); |
168 | 181 | |
169 | 181 | return Mask; |
170 | 181 | } |