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