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