xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/MachinePassManager.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
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>(F)
116           .getManager();
117   PassInstrumentation PI = FAM.getResult<PassInstrumentationAnalysis>(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>(F).getMF();
125 
126   if (!PI.runBeforePass<MachineFunction>(*Pass, MF))
127     return PreservedAnalyses::all();
128   PreservedAnalyses PassPA = Pass->run(MF, MFAM);
129   MFAM.invalidate(MF, PassPA);
130   PI.runAfterPass(*Pass, MF, PassPA);
131   PA.intersect(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>(MF);
148   PreservedAnalyses PA = PreservedAnalyses::all();
149   for (auto &Pass : Passes) {
150     if (!PI.runBeforePass<MachineFunction>(*Pass, MF))
151       continue;
152 
153     PreservedAnalyses PassPA = Pass->run(MF, MFAM);
154     MFAM.invalidate(MF, PassPA);
155     PI.runAfterPass(*Pass, MF, PassPA);
156     PA.intersect(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