xref: /llvm-project/llvm/lib/CodeGen/MachinePassManager.cpp (revision 6ea0c0a28343b2676baf480db490b5a27fa11d7c)
1f5b5ccf2SYuanfang Chen //===---------- MachinePassManager.cpp ------------------------------------===//
2f5b5ccf2SYuanfang Chen //
3f5b5ccf2SYuanfang Chen // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f5b5ccf2SYuanfang Chen // See https://llvm.org/LICENSE.txt for license information.
5f5b5ccf2SYuanfang Chen // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f5b5ccf2SYuanfang Chen //
7f5b5ccf2SYuanfang Chen //===----------------------------------------------------------------------===//
8f5b5ccf2SYuanfang Chen //
9f5b5ccf2SYuanfang Chen // This file contains the pass management machinery for machine functions.
10f5b5ccf2SYuanfang Chen //
11f5b5ccf2SYuanfang Chen //===----------------------------------------------------------------------===//
12f5b5ccf2SYuanfang Chen 
13f5b5ccf2SYuanfang Chen #include "llvm/CodeGen/MachinePassManager.h"
14a5ed20b5SYuanfang Chen #include "llvm/CodeGen/MachineFunction.h"
15*6ea0c0a2Spaperchalice #include "llvm/CodeGen/MachineFunctionAnalysis.h"
16f5b5ccf2SYuanfang Chen #include "llvm/CodeGen/MachineModuleInfo.h"
17f5b5ccf2SYuanfang Chen #include "llvm/IR/PassManagerImpl.h"
18f5b5ccf2SYuanfang Chen 
19f5b5ccf2SYuanfang Chen using namespace llvm;
20f5b5ccf2SYuanfang Chen 
2191e9e317SArthur Eubanks AnalysisKey FunctionAnalysisManagerMachineFunctionProxy::Key;
2291e9e317SArthur Eubanks 
23*6ea0c0a2Spaperchalice namespace llvm {
24f5b5ccf2SYuanfang Chen template class AnalysisManager<MachineFunction>;
25f5b5ccf2SYuanfang Chen template class PassManager<MachineFunction>;
2691e9e317SArthur Eubanks template class InnerAnalysisManagerProxy<MachineFunctionAnalysisManager,
2791e9e317SArthur Eubanks                                          Module>;
28*6ea0c0a2Spaperchalice template class InnerAnalysisManagerProxy<MachineFunctionAnalysisManager,
29*6ea0c0a2Spaperchalice                                          Function>;
3091e9e317SArthur Eubanks template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
3191e9e317SArthur Eubanks                                          MachineFunction>;
32*6ea0c0a2Spaperchalice } // namespace llvm
33f5b5ccf2SYuanfang Chen 
invalidate(MachineFunction & IR,const PreservedAnalyses & PA,MachineFunctionAnalysisManager::Invalidator & Inv)3491e9e317SArthur Eubanks bool FunctionAnalysisManagerMachineFunctionProxy::Result::invalidate(
3591e9e317SArthur Eubanks     MachineFunction &IR, const PreservedAnalyses &PA,
3691e9e317SArthur Eubanks     MachineFunctionAnalysisManager::Invalidator &Inv) {
3791e9e317SArthur Eubanks   // MachineFunction passes should not invalidate Function analyses.
3891e9e317SArthur Eubanks   // TODO: verify that PA doesn't invalidate Function analyses.
3991e9e317SArthur Eubanks   return false;
40a5ed20b5SYuanfang Chen }
41a5ed20b5SYuanfang Chen 
4291e9e317SArthur Eubanks template <>
invalidate(Module & M,const PreservedAnalyses & PA,ModuleAnalysisManager::Invalidator & Inv)4391e9e317SArthur Eubanks bool MachineFunctionAnalysisManagerModuleProxy::Result::invalidate(
4491e9e317SArthur Eubanks     Module &M, const PreservedAnalyses &PA,
4591e9e317SArthur Eubanks     ModuleAnalysisManager::Invalidator &Inv) {
4691e9e317SArthur Eubanks   // If literally everything is preserved, we're done.
4791e9e317SArthur Eubanks   if (PA.areAllPreserved())
4891e9e317SArthur Eubanks     return false; // This is still a valid proxy.
4991e9e317SArthur Eubanks 
5091e9e317SArthur Eubanks   // If this proxy isn't marked as preserved, then even if the result remains
5191e9e317SArthur Eubanks   // valid, the key itself may no longer be valid, so we clear everything.
5291e9e317SArthur Eubanks   //
5391e9e317SArthur Eubanks   // Note that in order to preserve this proxy, a module pass must ensure that
5491e9e317SArthur Eubanks   // the MFAM has been completely updated to handle the deletion of functions.
5591e9e317SArthur Eubanks   // Specifically, any MFAM-cached results for those functions need to have been
5691e9e317SArthur Eubanks   // forcibly cleared. When preserved, this proxy will only invalidate results
5791e9e317SArthur Eubanks   // cached on functions *still in the module* at the end of the module pass.
5891e9e317SArthur Eubanks   auto PAC = PA.getChecker<MachineFunctionAnalysisManagerModuleProxy>();
5991e9e317SArthur Eubanks   if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Module>>()) {
6091e9e317SArthur Eubanks     InnerAM->clear();
6191e9e317SArthur Eubanks     return true;
62f5b5ccf2SYuanfang Chen   }
63f5b5ccf2SYuanfang Chen 
6491e9e317SArthur Eubanks   // FIXME: be more precise, see
6591e9e317SArthur Eubanks   // FunctionAnalysisManagerModuleProxy::Result::invalidate.
6691e9e317SArthur Eubanks   if (!PA.allAnalysesInSetPreserved<AllAnalysesOn<MachineFunction>>()) {
6791e9e317SArthur Eubanks     InnerAM->clear();
6891e9e317SArthur Eubanks     return true;
69f5b5ccf2SYuanfang Chen   }
70f5b5ccf2SYuanfang Chen 
7191e9e317SArthur Eubanks   // Return false to indicate that this result is still a valid proxy.
7291e9e317SArthur Eubanks   return false;
7391e9e317SArthur Eubanks }
74f5b5ccf2SYuanfang Chen 
75*6ea0c0a2Spaperchalice template <>
invalidate(Function & F,const PreservedAnalyses & PA,FunctionAnalysisManager::Invalidator & Inv)76*6ea0c0a2Spaperchalice bool MachineFunctionAnalysisManagerFunctionProxy::Result::invalidate(
77*6ea0c0a2Spaperchalice     Function &F, const PreservedAnalyses &PA,
78*6ea0c0a2Spaperchalice     FunctionAnalysisManager::Invalidator &Inv) {
79*6ea0c0a2Spaperchalice   // If literally everything is preserved, we're done.
80*6ea0c0a2Spaperchalice   if (PA.areAllPreserved())
81*6ea0c0a2Spaperchalice     return false; // This is still a valid proxy.
82*6ea0c0a2Spaperchalice 
83*6ea0c0a2Spaperchalice   // If this proxy isn't marked as preserved, then even if the result remains
84*6ea0c0a2Spaperchalice   // valid, the key itself may no longer be valid, so we clear everything.
85*6ea0c0a2Spaperchalice   //
86*6ea0c0a2Spaperchalice   // Note that in order to preserve this proxy, a module pass must ensure that
87*6ea0c0a2Spaperchalice   // the MFAM has been completely updated to handle the deletion of functions.
88*6ea0c0a2Spaperchalice   // Specifically, any MFAM-cached results for those functions need to have been
89*6ea0c0a2Spaperchalice   // forcibly cleared. When preserved, this proxy will only invalidate results
90*6ea0c0a2Spaperchalice   // cached on functions *still in the module* at the end of the module pass.
91*6ea0c0a2Spaperchalice   auto PAC = PA.getChecker<MachineFunctionAnalysisManagerFunctionProxy>();
92*6ea0c0a2Spaperchalice   if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Function>>()) {
93*6ea0c0a2Spaperchalice     InnerAM->clear();
94*6ea0c0a2Spaperchalice     return true;
95*6ea0c0a2Spaperchalice   }
96*6ea0c0a2Spaperchalice 
97*6ea0c0a2Spaperchalice   // FIXME: be more precise, see
98*6ea0c0a2Spaperchalice   // FunctionAnalysisManagerModuleProxy::Result::invalidate.
99*6ea0c0a2Spaperchalice   if (!PA.allAnalysesInSetPreserved<AllAnalysesOn<MachineFunction>>()) {
100*6ea0c0a2Spaperchalice     InnerAM->clear();
101*6ea0c0a2Spaperchalice     return true;
102*6ea0c0a2Spaperchalice   }
103*6ea0c0a2Spaperchalice 
104*6ea0c0a2Spaperchalice   // Return false to indicate that this result is still a valid proxy.
105*6ea0c0a2Spaperchalice   return false;
106*6ea0c0a2Spaperchalice }
107*6ea0c0a2Spaperchalice 
10891e9e317SArthur Eubanks PreservedAnalyses
run(Function & F,FunctionAnalysisManager & FAM)109*6ea0c0a2Spaperchalice FunctionToMachineFunctionPassAdaptor::run(Function &F,
110*6ea0c0a2Spaperchalice                                           FunctionAnalysisManager &FAM) {
11191e9e317SArthur Eubanks   MachineFunctionAnalysisManager &MFAM =
112*6ea0c0a2Spaperchalice       FAM.getResult<MachineFunctionAnalysisManagerFunctionProxy>(F)
113*6ea0c0a2Spaperchalice           .getManager();
114*6ea0c0a2Spaperchalice   PassInstrumentation PI = FAM.getResult<PassInstrumentationAnalysis>(F);
11591e9e317SArthur Eubanks   PreservedAnalyses PA = PreservedAnalyses::all();
116f5b5ccf2SYuanfang Chen   // Do not codegen any 'available_externally' functions at all, they have
117f5b5ccf2SYuanfang Chen   // definitions outside the translation unit.
118d2dff431Spaperchalice   if (F.isDeclaration() || F.hasAvailableExternallyLinkage())
119*6ea0c0a2Spaperchalice     return PreservedAnalyses::all();
120f5b5ccf2SYuanfang Chen 
121*6ea0c0a2Spaperchalice   MachineFunction &MF = FAM.getResult<MachineFunctionAnalysis>(F).getMF();
122f5b5ccf2SYuanfang Chen 
12391e9e317SArthur Eubanks   if (!PI.runBeforePass<MachineFunction>(*Pass, MF))
124*6ea0c0a2Spaperchalice     return PreservedAnalyses::all();
12591e9e317SArthur Eubanks   PreservedAnalyses PassPA = Pass->run(MF, MFAM);
12691e9e317SArthur Eubanks   MFAM.invalidate(MF, PassPA);
12791e9e317SArthur Eubanks   PI.runAfterPass(*Pass, MF, PassPA);
12891e9e317SArthur Eubanks   PA.intersect(std::move(PassPA));
129f5b5ccf2SYuanfang Chen 
13091e9e317SArthur Eubanks   return PA;
13191e9e317SArthur Eubanks }
13291e9e317SArthur Eubanks 
printPipeline(raw_ostream & OS,function_ref<StringRef (StringRef)> MapClassName2PassName)133*6ea0c0a2Spaperchalice void FunctionToMachineFunctionPassAdaptor::printPipeline(
13491e9e317SArthur Eubanks     raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
13591e9e317SArthur Eubanks   OS << "machine-function(";
13691e9e317SArthur Eubanks   Pass->printPipeline(OS, MapClassName2PassName);
13791e9e317SArthur Eubanks   OS << ')';
13891e9e317SArthur Eubanks }
13991e9e317SArthur Eubanks 
14091e9e317SArthur Eubanks template <>
14191e9e317SArthur Eubanks PreservedAnalyses
run(MachineFunction & MF,AnalysisManager<MachineFunction> & MFAM)14291e9e317SArthur Eubanks PassManager<MachineFunction>::run(MachineFunction &MF,
14391e9e317SArthur Eubanks                                   AnalysisManager<MachineFunction> &MFAM) {
14491e9e317SArthur Eubanks   PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(MF);
14591e9e317SArthur Eubanks   PreservedAnalyses PA = PreservedAnalyses::all();
14691e9e317SArthur Eubanks   for (auto &Pass : Passes) {
14791e9e317SArthur Eubanks     if (!PI.runBeforePass<MachineFunction>(*Pass, MF))
148f5b5ccf2SYuanfang Chen       continue;
149f5b5ccf2SYuanfang Chen 
15091e9e317SArthur Eubanks     PreservedAnalyses PassPA = Pass->run(MF, MFAM);
151f5b5ccf2SYuanfang Chen     MFAM.invalidate(MF, PassPA);
15291e9e317SArthur Eubanks     PI.runAfterPass(*Pass, MF, PassPA);
15391e9e317SArthur Eubanks     PA.intersect(std::move(PassPA));
154f5b5ccf2SYuanfang Chen   }
15591e9e317SArthur Eubanks   return PA;
156f5b5ccf2SYuanfang Chen }
157f5b5ccf2SYuanfang Chen 
getMachineFunctionPassPreservedAnalyses()158*6ea0c0a2Spaperchalice PreservedAnalyses llvm::getMachineFunctionPassPreservedAnalyses() {
159*6ea0c0a2Spaperchalice   PreservedAnalyses PA;
160*6ea0c0a2Spaperchalice   // Machine function passes are not allowed to modify the LLVM
161*6ea0c0a2Spaperchalice   // representation, therefore we should preserve all IR analyses.
162*6ea0c0a2Spaperchalice   PA.template preserveSet<AllAnalysesOn<Module>>();
163*6ea0c0a2Spaperchalice   PA.template preserveSet<AllAnalysesOn<Function>>();
164*6ea0c0a2Spaperchalice   return PA;
165*6ea0c0a2Spaperchalice }
166