xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/MachinePassManager.cpp (revision 152382e6613d7998fe6f5233767df54d3fdec329)
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>(F)
113           .getManager();
114   PassInstrumentation PI = FAM.getResult<PassInstrumentationAnalysis>(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>(F).getMF();
122 
123   if (!PI.runBeforePass<MachineFunction>(*Pass, MF))
124     return PreservedAnalyses::all();
125   PreservedAnalyses PassPA = Pass->run(MF, MFAM);
126   MFAM.invalidate(MF, PassPA);
127   PI.runAfterPass(*Pass, MF, PassPA);
128   PA.intersect(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>(MF);
145   PreservedAnalyses PA = PreservedAnalyses::all();
146   for (auto &Pass : Passes) {
147     if (!PI.runBeforePass<MachineFunction>(*Pass, MF))
148       continue;
149 
150     PreservedAnalyses PassPA = Pass->run(MF, MFAM);
151     MFAM.invalidate(MF, PassPA);
152     PI.runAfterPass(*Pass, MF, PassPA);
153     PA.intersect(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