1 | //===---------- MachinePassManager.cpp ------------------------------------===// |
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 contains the pass management machinery for machine functions. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "llvm/CodeGen/MachinePassManager.h" |
14 | #include "llvm/CodeGen/MachineFunction.h" |
15 | #include "llvm/CodeGen/MachineFunctionAnalysis.h" |
16 | #include "llvm/CodeGen/MachineModuleInfo.h" |
17 | #include "llvm/IR/PassManagerImpl.h" |
18 | |
19 | using namespace llvm; |
20 | |
21 | AnalysisKey FunctionAnalysisManagerMachineFunctionProxy::Key; |
22 | |
23 | namespace llvm { |
24 | template class AnalysisManager<MachineFunction>; |
25 | template class PassManager<MachineFunction>; |
26 | template class InnerAnalysisManagerProxy<MachineFunctionAnalysisManager, |
27 | Module>; |
28 | template class InnerAnalysisManagerProxy<MachineFunctionAnalysisManager, |
29 | Function>; |
30 | template class OuterAnalysisManagerProxy<ModuleAnalysisManager, |
31 | MachineFunction>; |
32 | } // namespace llvm |
33 | |
34 | bool FunctionAnalysisManagerMachineFunctionProxy::Result::invalidate( |
35 | MachineFunction &IR, const PreservedAnalyses &PA, |
36 | MachineFunctionAnalysisManager::Invalidator &Inv) { |
37 | // MachineFunction passes should not invalidate Function analyses. |
38 | // TODO: verify that PA doesn't invalidate Function analyses. |
39 | return false; |
40 | } |
41 | |
42 | template <> |
43 | bool MachineFunctionAnalysisManagerModuleProxy::Result::invalidate( |
44 | Module &M, const PreservedAnalyses &PA, |
45 | ModuleAnalysisManager::Invalidator &Inv) { |
46 | // If literally everything is preserved, we're done. |
47 | if (PA.areAllPreserved()) |
48 | return false; // This is still a valid proxy. |
49 | |
50 | // If this proxy isn't marked as preserved, then even if the result remains |
51 | // valid, the key itself may no longer be valid, so we clear everything. |
52 | // |
53 | // Note that in order to preserve this proxy, a module pass must ensure that |
54 | // the MFAM has been completely updated to handle the deletion of functions. |
55 | // Specifically, any MFAM-cached results for those functions need to have been |
56 | // forcibly cleared. When preserved, this proxy will only invalidate results |
57 | // cached on functions *still in the module* at the end of the module pass. |
58 | auto PAC = PA.getChecker<MachineFunctionAnalysisManagerModuleProxy>(); |
59 | if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Module>>()) { |
60 | InnerAM->clear(); |
61 | return true; |
62 | } |
63 | |
64 | // FIXME: be more precise, see |
65 | // FunctionAnalysisManagerModuleProxy::Result::invalidate. |
66 | if (!PA.allAnalysesInSetPreserved<AllAnalysesOn<MachineFunction>>()) { |
67 | InnerAM->clear(); |
68 | return true; |
69 | } |
70 | |
71 | // Return false to indicate that this result is still a valid proxy. |
72 | return false; |
73 | } |
74 | |
75 | template <> |
76 | bool MachineFunctionAnalysisManagerFunctionProxy::Result::invalidate( |
77 | Function &F, const PreservedAnalyses &PA, |
78 | FunctionAnalysisManager::Invalidator &Inv) { |
79 | // If literally everything is preserved, we're done. |
80 | if (PA.areAllPreserved()) |
81 | return false; // This is still a valid proxy. |
82 | |
83 | // If this proxy isn't marked as preserved, then even if the result remains |
84 | // valid, the key itself may no longer be valid, so we clear everything. |
85 | // |
86 | // Note that in order to preserve this proxy, a module pass must ensure that |
87 | // the MFAM has been completely updated to handle the deletion of functions. |
88 | // Specifically, any MFAM-cached results for those functions need to have been |
89 | // forcibly cleared. When preserved, this proxy will only invalidate results |
90 | // cached on functions *still in the module* at the end of the module pass. |
91 | auto PAC = PA.getChecker<MachineFunctionAnalysisManagerFunctionProxy>(); |
92 | if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Function>>()) { |
93 | InnerAM->clear(); |
94 | return true; |
95 | } |
96 | |
97 | // FIXME: be more precise, see |
98 | // FunctionAnalysisManagerModuleProxy::Result::invalidate. |
99 | if (!PA.allAnalysesInSetPreserved<AllAnalysesOn<MachineFunction>>()) { |
100 | InnerAM->clear(); |
101 | return true; |
102 | } |
103 | |
104 | // Return false to indicate that this result is still a valid proxy. |
105 | return false; |
106 | } |
107 | |
108 | PreservedAnalyses |
109 | FunctionToMachineFunctionPassAdaptor::run(Function &F, |
110 | FunctionAnalysisManager &FAM) { |
111 | MachineFunctionAnalysisManager &MFAM = |
112 | FAM.getResult<MachineFunctionAnalysisManagerFunctionProxy>(IR&: F) |
113 | .getManager(); |
114 | PassInstrumentation PI = FAM.getResult<PassInstrumentationAnalysis>(IR&: F); |
115 | PreservedAnalyses PA = PreservedAnalyses::all(); |
116 | // Do not codegen any 'available_externally' functions at all, they have |
117 | // definitions outside the translation unit. |
118 | if (F.isDeclaration() || F.hasAvailableExternallyLinkage()) |
119 | return PreservedAnalyses::all(); |
120 | |
121 | MachineFunction &MF = FAM.getResult<MachineFunctionAnalysis>(IR&: F).getMF(); |
122 | |
123 | if (!PI.runBeforePass<MachineFunction>(Pass: *Pass, IR: MF)) |
124 | return PreservedAnalyses::all(); |
125 | PreservedAnalyses PassPA = Pass->run(IR&: MF, AM&: MFAM); |
126 | MFAM.invalidate(IR&: MF, PA: PassPA); |
127 | PI.runAfterPass(Pass: *Pass, IR: MF, PA: PassPA); |
128 | PA.intersect(Arg: std::move(PassPA)); |
129 | |
130 | return PA; |
131 | } |
132 | |
133 | void FunctionToMachineFunctionPassAdaptor::printPipeline( |
134 | raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) { |
135 | OS << "machine-function(" ; |
136 | Pass->printPipeline(OS, MapClassName2PassName); |
137 | OS << ')'; |
138 | } |
139 | |
140 | template <> |
141 | PreservedAnalyses |
142 | PassManager<MachineFunction>::run(MachineFunction &MF, |
143 | AnalysisManager<MachineFunction> &MFAM) { |
144 | PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(IR&: MF); |
145 | PreservedAnalyses PA = PreservedAnalyses::all(); |
146 | for (auto &Pass : Passes) { |
147 | if (!PI.runBeforePass<MachineFunction>(Pass: *Pass, IR: MF)) |
148 | continue; |
149 | |
150 | PreservedAnalyses PassPA = Pass->run(IR&: MF, AM&: MFAM); |
151 | MFAM.invalidate(IR&: MF, PA: PassPA); |
152 | PI.runAfterPass(Pass: *Pass, IR: MF, PA: PassPA); |
153 | PA.intersect(Arg: std::move(PassPA)); |
154 | } |
155 | return PA; |
156 | } |
157 | |
158 | PreservedAnalyses llvm::getMachineFunctionPassPreservedAnalyses() { |
159 | PreservedAnalyses PA; |
160 | // Machine function passes are not allowed to modify the LLVM |
161 | // representation, therefore we should preserve all IR analyses. |
162 | PA.template preserveSet<AllAnalysesOn<Module>>(); |
163 | PA.template preserveSet<AllAnalysesOn<Function>>(); |
164 | return PA; |
165 | } |
166 | |