xref: /freebsd/contrib/llvm-project/llvm/lib/IR/PassManager.cpp (revision 5e801ac66d24704442eba426ed13c3effb8a34e7)
1 //===- PassManager.cpp - Infrastructure for managing & running IR passes --===//
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 #include "llvm/IR/PassManager.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/IR/LLVMContext.h"
12 #include "llvm/IR/PassManagerImpl.h"
13 #include "llvm/Support/CommandLine.h"
14 
15 using namespace llvm;
16 
17 namespace llvm {
18 // Explicit template instantiations and specialization defininitions for core
19 // template typedefs.
20 template class AllAnalysesOn<Module>;
21 template class AllAnalysesOn<Function>;
22 template class PassManager<Module>;
23 template class PassManager<Function>;
24 template class AnalysisManager<Module>;
25 template class AnalysisManager<Function>;
26 template class InnerAnalysisManagerProxy<FunctionAnalysisManager, Module>;
27 template class OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>;
28 
29 template <>
30 bool FunctionAnalysisManagerModuleProxy::Result::invalidate(
31     Module &M, const PreservedAnalyses &PA,
32     ModuleAnalysisManager::Invalidator &Inv) {
33   // If literally everything is preserved, we're done.
34   if (PA.areAllPreserved())
35     return false; // This is still a valid proxy.
36 
37   // If this proxy isn't marked as preserved, then even if the result remains
38   // valid, the key itself may no longer be valid, so we clear everything.
39   //
40   // Note that in order to preserve this proxy, a module pass must ensure that
41   // the FAM has been completely updated to handle the deletion of functions.
42   // Specifically, any FAM-cached results for those functions need to have been
43   // forcibly cleared. When preserved, this proxy will only invalidate results
44   // cached on functions *still in the module* at the end of the module pass.
45   auto PAC = PA.getChecker<FunctionAnalysisManagerModuleProxy>();
46   if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Module>>()) {
47     InnerAM->clear();
48     return true;
49   }
50 
51   // Directly check if the relevant set is preserved.
52   bool AreFunctionAnalysesPreserved =
53       PA.allAnalysesInSetPreserved<AllAnalysesOn<Function>>();
54 
55   // Now walk all the functions to see if any inner analysis invalidation is
56   // necessary.
57   for (Function &F : M) {
58     Optional<PreservedAnalyses> FunctionPA;
59 
60     // Check to see whether the preserved set needs to be pruned based on
61     // module-level analysis invalidation that triggers deferred invalidation
62     // registered with the outer analysis manager proxy for this function.
63     if (auto *OuterProxy =
64             InnerAM->getCachedResult<ModuleAnalysisManagerFunctionProxy>(F))
65       for (const auto &OuterInvalidationPair :
66            OuterProxy->getOuterInvalidations()) {
67         AnalysisKey *OuterAnalysisID = OuterInvalidationPair.first;
68         const auto &InnerAnalysisIDs = OuterInvalidationPair.second;
69         if (Inv.invalidate(OuterAnalysisID, M, PA)) {
70           if (!FunctionPA)
71             FunctionPA = PA;
72           for (AnalysisKey *InnerAnalysisID : InnerAnalysisIDs)
73             FunctionPA->abandon(InnerAnalysisID);
74         }
75       }
76 
77     // Check if we needed a custom PA set, and if so we'll need to run the
78     // inner invalidation.
79     if (FunctionPA) {
80       InnerAM->invalidate(F, *FunctionPA);
81       continue;
82     }
83 
84     // Otherwise we only need to do invalidation if the original PA set didn't
85     // preserve all function analyses.
86     if (!AreFunctionAnalysesPreserved)
87       InnerAM->invalidate(F, PA);
88   }
89 
90   // Return false to indicate that this result is still a valid proxy.
91   return false;
92 }
93 } // namespace llvm
94 
95 void ModuleToFunctionPassAdaptor::printPipeline(
96     raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
97   OS << "function";
98   if (EagerlyInvalidate)
99     OS << "<eager-inv>";
100   OS << "(";
101   Pass->printPipeline(OS, MapClassName2PassName);
102   OS << ")";
103 }
104 
105 PreservedAnalyses ModuleToFunctionPassAdaptor::run(Module &M,
106                                                    ModuleAnalysisManager &AM) {
107   FunctionAnalysisManager &FAM =
108       AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
109 
110   // Request PassInstrumentation from analysis manager, will use it to run
111   // instrumenting callbacks for the passes later.
112   PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(M);
113 
114   PreservedAnalyses PA = PreservedAnalyses::all();
115   for (Function &F : M) {
116     if (F.isDeclaration())
117       continue;
118 
119     // Check the PassInstrumentation's BeforePass callbacks before running the
120     // pass, skip its execution completely if asked to (callback returns
121     // false).
122     if (!PI.runBeforePass<Function>(*Pass, F))
123       continue;
124 
125     PreservedAnalyses PassPA;
126     {
127       TimeTraceScope TimeScope(Pass->name(), F.getName());
128       PassPA = Pass->run(F, FAM);
129     }
130 
131     PI.runAfterPass(*Pass, F, PassPA);
132 
133     // We know that the function pass couldn't have invalidated any other
134     // function's analyses (that's the contract of a function pass), so
135     // directly handle the function analysis manager's invalidation here.
136     FAM.invalidate(F, EagerlyInvalidate ? PreservedAnalyses::none() : PassPA);
137 
138     // Then intersect the preserved set so that invalidation of module
139     // analyses will eventually occur when the module pass completes.
140     PA.intersect(std::move(PassPA));
141   }
142 
143   // The FunctionAnalysisManagerModuleProxy is preserved because (we assume)
144   // the function passes we ran didn't add or remove any functions.
145   //
146   // We also preserve all analyses on Functions, because we did all the
147   // invalidation we needed to do above.
148   PA.preserveSet<AllAnalysesOn<Function>>();
149   PA.preserve<FunctionAnalysisManagerModuleProxy>();
150   return PA;
151 }
152 
153 AnalysisSetKey CFGAnalyses::SetKey;
154 
155 AnalysisSetKey PreservedAnalyses::AllAnalysesKey;
156