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