LLVM 22.0.0git
PassManager.h
Go to the documentation of this file.
1//===- PassManager.h - Pass management infrastructure -----------*- C++ -*-===//
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/// \file
9///
10/// This header defines various interfaces for pass management in LLVM. There
11/// is no "pass" interface in LLVM per se. Instead, an instance of any class
12/// which supports a method to 'run' it over a unit of IR can be used as
13/// a pass. A pass manager is generally a tool to collect a sequence of passes
14/// which run over a particular IR construct, and run each of them in sequence
15/// over each such construct in the containing IR construct. As there is no
16/// containing IR construct for a Module, a manager for passes over modules
17/// forms the base case which runs its managed passes in sequence over the
18/// single module provided.
19///
20/// The core IR library provides managers for running passes over
21/// modules and functions.
22///
23/// * FunctionPassManager can run over a Module, runs each pass over
24/// a Function.
25/// * ModulePassManager must be directly run, runs each pass over the Module.
26///
27/// Note that the implementations of the pass managers use concept-based
28/// polymorphism as outlined in the "Value Semantics and Concept-based
29/// Polymorphism" talk (or its abbreviated sibling "Inheritance Is The Base
30/// Class of Evil") by Sean Parent:
31/// * https://sean-parent.stlab.cc/papers-and-presentations
32/// * http://www.youtube.com/watch?v=_BpMYeUFXv8
33/// * https://learn.microsoft.com/en-us/shows/goingnative-2013/inheritance-base-class-of-evil
34///
35//===----------------------------------------------------------------------===//
36
37#ifndef LLVM_IR_PASSMANAGER_H
38#define LLVM_IR_PASSMANAGER_H
39
40#include "llvm/ADT/DenseMap.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/StringRef.h"
44#include "llvm/IR/Analysis.h"
48#include <cassert>
49#include <cstring>
50#include <list>
51#include <memory>
52#include <tuple>
53#include <type_traits>
54#include <utility>
55#include <vector>
56
57namespace llvm {
58
59class Function;
60class Module;
61
62// Forward declare the analysis manager template.
63template <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager;
64
65/// A CRTP mix-in to automatically provide informational APIs needed for
66/// passes.
67///
68/// This provides some boilerplate for types that are passes.
69template <typename DerivedT> struct PassInfoMixin {
70 /// Gets the name of the pass we are mixed into.
71 static StringRef name() {
72 static_assert(std::is_base_of<PassInfoMixin, DerivedT>::value,
73 "Must pass the derived type as the template argument!");
75 Name.consume_front("llvm::");
76 return Name;
77 }
78
80 function_ref<StringRef(StringRef)> MapClassName2PassName) {
81 StringRef ClassName = DerivedT::name();
82 auto PassName = MapClassName2PassName(ClassName);
83 OS << PassName;
84 }
85};
86
87/// A CRTP mix-in that provides informational APIs needed for analysis passes.
88///
89/// This provides some boilerplate for types that are analysis passes. It
90/// automatically mixes in \c PassInfoMixin.
91template <typename DerivedT>
92struct AnalysisInfoMixin : PassInfoMixin<DerivedT> {
93 /// Returns an opaque, unique ID for this analysis type.
94 ///
95 /// This ID is a pointer type that is guaranteed to be 8-byte aligned and thus
96 /// suitable for use in sets, maps, and other data structures that use the low
97 /// bits of pointers.
98 ///
99 /// Note that this requires the derived type provide a static \c AnalysisKey
100 /// member called \c Key.
101 ///
102 /// FIXME: The only reason the mixin type itself can't declare the Key value
103 /// is that some compilers cannot correctly unique a templated static variable
104 /// so it has the same addresses in each instantiation. The only currently
105 /// known platform with this limitation is Windows DLL builds, specifically
106 /// building each part of LLVM as a DLL. If we ever remove that build
107 /// configuration, this mixin can provide the static key as well.
108 static AnalysisKey *ID() {
109 static_assert(std::is_base_of<AnalysisInfoMixin, DerivedT>::value,
110 "Must pass the derived type as the template argument!");
111 return &DerivedT::Key;
112 }
113};
114
115namespace detail {
116
117/// Actual unpacker of extra arguments in getAnalysisResult,
118/// passes only those tuple arguments that are mentioned in index_sequence.
119template <typename PassT, typename IRUnitT, typename AnalysisManagerT,
120 typename... ArgTs, size_t... Ns>
121typename PassT::Result
122getAnalysisResultUnpackTuple(AnalysisManagerT &AM, IRUnitT &IR,
123 std::tuple<ArgTs...> Args,
124 std::index_sequence<Ns...>) {
125 (void)Args;
126 return AM.template getResult<PassT>(IR, std::get<Ns>(Args)...);
127}
128
129/// Helper for *partial* unpacking of extra arguments in getAnalysisResult.
130///
131/// Arguments passed in tuple come from PassManager, so they might have extra
132/// arguments after those AnalysisManager's ExtraArgTs ones that we need to
133/// pass to getResult.
134template <typename PassT, typename IRUnitT, typename... AnalysisArgTs,
135 typename... MainArgTs>
136typename PassT::Result
138 std::tuple<MainArgTs...> Args) {
140 PassT, IRUnitT>)(AM, IR, Args,
141 std::index_sequence_for<AnalysisArgTs...>{});
142}
143
144} // namespace detail
145
146/// Manages a sequence of passes over a particular unit of IR.
147///
148/// A pass manager contains a sequence of passes to run over a particular unit
149/// of IR (e.g. Functions, Modules). It is itself a valid pass over that unit of
150/// IR, and when run over some given IR will run each of its contained passes in
151/// sequence. Pass managers are the primary and most basic building block of a
152/// pass pipeline.
153///
154/// When you run a pass manager, you provide an \c AnalysisManager<IRUnitT>
155/// argument. The pass manager will propagate that analysis manager to each
156/// pass it runs, and will call the analysis manager's invalidation routine with
157/// the PreservedAnalyses of each pass it runs.
158template <typename IRUnitT,
159 typename AnalysisManagerT = AnalysisManager<IRUnitT>,
160 typename... ExtraArgTs>
162 PassManager<IRUnitT, AnalysisManagerT, ExtraArgTs...>> {
163public:
164 /// Construct a pass manager.
165 explicit PassManager() = default;
166
167 // FIXME: These are equivalent to the default move constructor/move
168 // assignment. However, using = default triggers linker errors due to the
169 // explicit instantiations below. Find away to use the default and remove the
170 // duplicated code here.
172
174 Passes = std::move(RHS.Passes);
175 return *this;
176 }
177
179 function_ref<StringRef(StringRef)> MapClassName2PassName) {
180 for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
181 auto *P = Passes[Idx].get();
182 P->printPipeline(OS, MapClassName2PassName);
183 if (Idx + 1 < Size)
184 OS << ',';
185 }
186 }
187
188 /// Run all of the passes in this manager over the given unit of IR.
189 /// ExtraArgs are passed to each pass.
190 PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM,
191 ExtraArgTs... ExtraArgs);
192
193 template <typename PassT>
194 LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v<PassT, PassManager>>
195 addPass(PassT &&Pass) {
196 using PassModelT =
197 detail::PassModel<IRUnitT, PassT, AnalysisManagerT, ExtraArgTs...>;
198 // Do not use make_unique or emplace_back, they cause too many template
199 // instantiations, causing terrible compile times.
200 Passes.push_back(std::unique_ptr<PassConceptT>(
201 new PassModelT(std::forward<PassT>(Pass))));
202 }
203
204 /// When adding a pass manager pass that has the same type as this pass
205 /// manager, simply move the passes over. This is because we don't have
206 /// use cases rely on executing nested pass managers. Doing this could
207 /// reduce implementation complexity and avoid potential invalidation
208 /// issues that may happen with nested pass managers of the same type.
209 template <typename PassT>
210 LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<std::is_same_v<PassT, PassManager>>
211 addPass(PassT &&Pass) {
212 for (auto &P : Pass.Passes)
213 Passes.push_back(std::move(P));
214 }
215
216 /// Returns if the pass manager contains any passes.
217 bool isEmpty() const { return Passes.empty(); }
218
219 static bool isRequired() { return true; }
220
221protected:
223 detail::PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...>;
224
225 std::vector<std::unique_ptr<PassConceptT>> Passes;
226};
227
228template <typename IRUnitT>
230
231template <>
233 const Module &IR);
234
235extern template class LLVM_TEMPLATE_ABI PassManager<Module>;
236
237/// Convenience typedef for a pass manager over modules.
239
240template <>
242 const Function &IR);
243
244extern template class LLVM_TEMPLATE_ABI PassManager<Function>;
245
246/// Convenience typedef for a pass manager over functions.
248
249/// A container for analyses that lazily runs them and caches their
250/// results.
251///
252/// This class can manage analyses for any IR unit where the address of the IR
253/// unit sufficies as its identity.
254template <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager {
255public:
256 class Invalidator;
257
258private:
259 // Now that we've defined our invalidator, we can define the concept types.
261 using PassConceptT =
262 detail::AnalysisPassConcept<IRUnitT, Invalidator, ExtraArgTs...>;
263
264 /// List of analysis pass IDs and associated concept pointers.
265 ///
266 /// Requires iterators to be valid across appending new entries and arbitrary
267 /// erases. Provides the analysis ID to enable finding iterators to a given
268 /// entry in maps below, and provides the storage for the actual result
269 /// concept.
270 using AnalysisResultListT =
271 std::list<std::pair<AnalysisKey *, std::unique_ptr<ResultConceptT>>>;
272
273 /// Map type from IRUnitT pointer to our custom list type.
274 using AnalysisResultListMapT = DenseMap<IRUnitT *, AnalysisResultListT>;
275
276 /// Map type from a pair of analysis ID and IRUnitT pointer to an
277 /// iterator into a particular result list (which is where the actual analysis
278 /// result is stored).
279 using AnalysisResultMapT =
281 typename AnalysisResultListT::iterator>;
282
283public:
284 /// API to communicate dependencies between analyses during invalidation.
285 ///
286 /// When an analysis result embeds handles to other analysis results, it
287 /// needs to be invalidated both when its own information isn't preserved and
288 /// when any of its embedded analysis results end up invalidated. We pass an
289 /// \c Invalidator object as an argument to \c invalidate() in order to let
290 /// the analysis results themselves define the dependency graph on the fly.
291 /// This lets us avoid building an explicit representation of the
292 /// dependencies between analysis results.
293 class Invalidator {
294 public:
295 /// Trigger the invalidation of some other analysis pass if not already
296 /// handled and return whether it was in fact invalidated.
297 ///
298 /// This is expected to be called from within a given analysis result's \c
299 /// invalidate method to trigger a depth-first walk of all inter-analysis
300 /// dependencies. The same \p IR unit and \p PA passed to that result's \c
301 /// invalidate method should in turn be provided to this routine.
302 ///
303 /// The first time this is called for a given analysis pass, it will call
304 /// the corresponding result's \c invalidate method. Subsequent calls will
305 /// use a cache of the results of that initial call. It is an error to form
306 /// cyclic dependencies between analysis results.
307 ///
308 /// This returns true if the given analysis's result is invalid. Any
309 /// dependecies on it will become invalid as a result.
310 template <typename PassT>
311 bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA) {
312 using ResultModelT =
313 detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
314 Invalidator>;
315
316 return invalidateImpl<ResultModelT>(PassT::ID(), IR, PA);
317 }
318
319 /// A type-erased variant of the above invalidate method with the same core
320 /// API other than passing an analysis ID rather than an analysis type
321 /// parameter.
322 ///
323 /// This is sadly less efficient than the above routine, which leverages
324 /// the type parameter to avoid the type erasure overhead.
325 bool invalidate(AnalysisKey *ID, IRUnitT &IR, const PreservedAnalyses &PA) {
326 return invalidateImpl<>(ID, IR, PA);
327 }
328
329 private:
330 friend class AnalysisManager;
331
332 template <typename ResultT = ResultConceptT>
333 bool invalidateImpl(AnalysisKey *ID, IRUnitT &IR,
334 const PreservedAnalyses &PA) {
335 // If we've already visited this pass, return true if it was invalidated
336 // and false otherwise.
337 auto IMapI = IsResultInvalidated.find(ID);
338 if (IMapI != IsResultInvalidated.end())
339 return IMapI->second;
340
341 // Otherwise look up the result object.
342 auto RI = Results.find({ID, &IR});
343 assert(RI != Results.end() &&
344 "Trying to invalidate a dependent result that isn't in the "
345 "manager's cache is always an error, likely due to a stale result "
346 "handle!");
347
348 auto &Result = static_cast<ResultT &>(*RI->second->second);
349
350 // Insert into the map whether the result should be invalidated and return
351 // that. Note that we cannot reuse IMapI and must do a fresh insert here,
352 // as calling invalidate could (recursively) insert things into the map,
353 // making any iterator or reference invalid.
354 bool Inserted;
355 std::tie(IMapI, Inserted) =
356 IsResultInvalidated.insert({ID, Result.invalidate(IR, PA, *this)});
357 (void)Inserted;
358 assert(Inserted && "Should not have already inserted this ID, likely "
359 "indicates a dependency cycle!");
360 return IMapI->second;
361 }
362
363 Invalidator(SmallDenseMap<AnalysisKey *, bool, 8> &IsResultInvalidated,
364 const AnalysisResultMapT &Results)
365 : IsResultInvalidated(IsResultInvalidated), Results(Results) {}
366
367 SmallDenseMap<AnalysisKey *, bool, 8> &IsResultInvalidated;
368 const AnalysisResultMapT &Results;
369 };
370
371 /// Construct an empty analysis manager.
375
376 /// Returns true if the analysis manager has an empty results cache.
377 bool empty() const {
378 assert(AnalysisResults.empty() == AnalysisResultLists.empty() &&
379 "The storage and index of analysis results disagree on how many "
380 "there are!");
381 return AnalysisResults.empty();
382 }
383
384 /// Clear any cached analysis results for a single unit of IR.
385 ///
386 /// This doesn't invalidate, but instead simply deletes, the relevant results.
387 /// It is useful when the IR is being removed and we want to clear out all the
388 /// memory pinned for it.
389 void clear(IRUnitT &IR, llvm::StringRef Name);
390
391 /// Clear all analysis results cached by this AnalysisManager.
392 ///
393 /// Like \c clear(IRUnitT&), this doesn't invalidate the results; it simply
394 /// deletes them. This lets you clean up the AnalysisManager when the set of
395 /// IR units itself has potentially changed, and thus we can't even look up a
396 /// a result and invalidate/clear it directly.
397 void clear() {
398 AnalysisResults.clear();
399 AnalysisResultLists.clear();
400 }
401
402 /// Returns true if the specified analysis pass is registered.
403 template <typename PassT> bool isPassRegistered() const {
404 return AnalysisPasses.count(PassT::ID());
405 }
406
407 /// Get the result of an analysis pass for a given IR unit.
408 ///
409 /// Runs the analysis if a cached result is not available.
410 template <typename PassT>
411 typename PassT::Result &getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs) {
412 assert(AnalysisPasses.count(PassT::ID()) &&
413 "This analysis pass was not registered prior to being queried");
414 ResultConceptT &ResultConcept =
415 getResultImpl(PassT::ID(), IR, ExtraArgs...);
416
417 using ResultModelT =
418 detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
419 Invalidator>;
420
421 return static_cast<ResultModelT &>(ResultConcept).Result;
422 }
423
424 /// Get the cached result of an analysis pass for a given IR unit.
425 ///
426 /// This method never runs the analysis.
427 ///
428 /// \returns null if there is no cached result.
429 template <typename PassT>
430 typename PassT::Result *getCachedResult(IRUnitT &IR) const {
431 assert(AnalysisPasses.count(PassT::ID()) &&
432 "This analysis pass was not registered prior to being queried");
433
434 ResultConceptT *ResultConcept = getCachedResultImpl(PassT::ID(), IR);
435 if (!ResultConcept)
436 return nullptr;
437
438 using ResultModelT =
439 detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
440 Invalidator>;
441
442 return &static_cast<ResultModelT *>(ResultConcept)->Result;
443 }
444
445 /// Verify that the given Result cannot be invalidated, assert otherwise.
446 template <typename PassT>
447 void verifyNotInvalidated(IRUnitT &IR, typename PassT::Result *Result) const {
449 SmallDenseMap<AnalysisKey *, bool, 8> IsResultInvalidated;
450 Invalidator Inv(IsResultInvalidated, AnalysisResults);
451 assert(!Result->invalidate(IR, PA, Inv) &&
452 "Cached result cannot be invalidated");
453 }
454
455 /// Register an analysis pass with the manager.
456 ///
457 /// The parameter is a callable whose result is an analysis pass. This allows
458 /// passing in a lambda to construct the analysis.
459 ///
460 /// The analysis type to register is the type returned by calling the \c
461 /// PassBuilder argument. If that type has already been registered, then the
462 /// argument will not be called and this function will return false.
463 /// Otherwise, we register the analysis returned by calling \c PassBuilder(),
464 /// and this function returns true.
465 ///
466 /// (Note: Although the return value of this function indicates whether or not
467 /// an analysis was previously registered, you should just register all the
468 /// analyses you might want and let this class run them lazily. This idiom
469 /// lets us minimize the number of times we have to look up analyses in our
470 /// hashtable.)
471 template <typename PassBuilderT>
472 bool registerPass(PassBuilderT &&PassBuilder) {
473 using PassT = decltype(PassBuilder());
474 using PassModelT =
475 detail::AnalysisPassModel<IRUnitT, PassT, Invalidator, ExtraArgTs...>;
476
477 auto &PassPtr = AnalysisPasses[PassT::ID()];
478 if (PassPtr)
479 // Already registered this pass type!
480 return false;
481
482 // Construct a new model around the instance returned by the builder.
483 PassPtr.reset(new PassModelT(PassBuilder()));
484 return true;
485 }
486
487 /// Invalidate cached analyses for an IR unit.
488 ///
489 /// Walk through all of the analyses pertaining to this unit of IR and
490 /// invalidate them, unless they are preserved by the PreservedAnalyses set.
491 void invalidate(IRUnitT &IR, const PreservedAnalyses &PA);
492
493 /// Directly clear a cached analysis for an IR unit.
494 ///
495 /// Using invalidate() over this is preferred unless you are really
496 /// sure you want to *only* clear this analysis without asking if it is
497 /// invalid.
498 template <typename AnalysisT> void clearAnalysis(IRUnitT &IR) {
499 AnalysisResultListT &ResultsList = AnalysisResultLists[&IR];
500 AnalysisKey *ID = AnalysisT::ID();
501
502 auto I =
503 llvm::find_if(ResultsList, [&ID](auto &E) { return E.first == ID; });
504 assert(I != ResultsList.end() && "Analysis must be available");
505 ResultsList.erase(I);
506 AnalysisResults.erase({ID, &IR});
507 }
508
509private:
510 /// Look up a registered analysis pass.
511 PassConceptT &lookUpPass(AnalysisKey *ID) {
512 typename AnalysisPassMapT::iterator PI = AnalysisPasses.find(ID);
513 assert(PI != AnalysisPasses.end() &&
514 "Analysis passes must be registered prior to being queried!");
515 return *PI->second;
516 }
517
518 /// Look up a registered analysis pass.
519 const PassConceptT &lookUpPass(AnalysisKey *ID) const {
520 typename AnalysisPassMapT::const_iterator PI = AnalysisPasses.find(ID);
521 assert(PI != AnalysisPasses.end() &&
522 "Analysis passes must be registered prior to being queried!");
523 return *PI->second;
524 }
525
526 /// Get an analysis result, running the pass if necessary.
527 ResultConceptT &getResultImpl(AnalysisKey *ID, IRUnitT &IR,
528 ExtraArgTs... ExtraArgs);
529
530 /// Get a cached analysis result or return null.
531 ResultConceptT *getCachedResultImpl(AnalysisKey *ID, IRUnitT &IR) const {
532 typename AnalysisResultMapT::const_iterator RI =
533 AnalysisResults.find({ID, &IR});
534 return RI == AnalysisResults.end() ? nullptr : &*RI->second->second;
535 }
536
537 /// Map type from analysis pass ID to pass concept pointer.
538 using AnalysisPassMapT =
539 DenseMap<AnalysisKey *, std::unique_ptr<PassConceptT>>;
540
541 /// Collection of analysis passes, indexed by ID.
542 AnalysisPassMapT AnalysisPasses;
543
544 /// Map from IR unit to a list of analysis results.
545 ///
546 /// Provides linear time removal of all analysis results for a IR unit and
547 /// the ultimate storage for a particular cached analysis result.
548 AnalysisResultListMapT AnalysisResultLists;
549
550 /// Map from an analysis ID and IR unit to a particular cached
551 /// analysis result.
552 AnalysisResultMapT AnalysisResults;
553};
554
555extern template class LLVM_TEMPLATE_ABI AnalysisManager<Module>;
556
557/// Convenience typedef for the Module analysis manager.
559
560extern template class LLVM_TEMPLATE_ABI AnalysisManager<Function>;
561
562/// Convenience typedef for the Function analysis manager.
564
565/// An analysis over an "outer" IR unit that provides access to an
566/// analysis manager over an "inner" IR unit. The inner unit must be contained
567/// in the outer unit.
568///
569/// For example, InnerAnalysisManagerProxy<FunctionAnalysisManager, Module> is
570/// an analysis over Modules (the "outer" unit) that provides access to a
571/// Function analysis manager. The FunctionAnalysisManager is the "inner"
572/// manager being proxied, and Functions are the "inner" unit. The inner/outer
573/// relationship is valid because each Function is contained in one Module.
574///
575/// If you're (transitively) within a pass manager for an IR unit U that
576/// contains IR unit V, you should never use an analysis manager over V, except
577/// via one of these proxies.
578///
579/// Note that the proxy's result is a move-only RAII object. The validity of
580/// the analyses in the inner analysis manager is tied to its lifetime.
581template <typename AnalysisManagerT, typename IRUnitT, typename... ExtraArgTs>
583 : public AnalysisInfoMixin<
584 InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>> {
585public:
586 class Result {
587 public:
588 explicit Result(AnalysisManagerT &InnerAM) : InnerAM(&InnerAM) {}
589
590 Result(Result &&Arg) : InnerAM(std::move(Arg.InnerAM)) {
591 // We have to null out the analysis manager in the moved-from state
592 // because we are taking ownership of the responsibilty to clear the
593 // analysis state.
594 Arg.InnerAM = nullptr;
595 }
596
598 // InnerAM is cleared in a moved from state where there is nothing to do.
599 if (!InnerAM)
600 return;
601
602 // Clear out the analysis manager if we're being destroyed -- it means we
603 // didn't even see an invalidate call when we got invalidated.
604 InnerAM->clear();
605 }
606
608 InnerAM = RHS.InnerAM;
609 // We have to null out the analysis manager in the moved-from state
610 // because we are taking ownership of the responsibilty to clear the
611 // analysis state.
612 RHS.InnerAM = nullptr;
613 return *this;
614 }
615
616 /// Accessor for the analysis manager.
617 AnalysisManagerT &getManager() { return *InnerAM; }
618
619 /// Handler for invalidation of the outer IR unit, \c IRUnitT.
620 ///
621 /// If the proxy analysis itself is not preserved, we assume that the set of
622 /// inner IR objects contained in IRUnit may have changed. In this case,
623 /// we have to call \c clear() on the inner analysis manager, as it may now
624 /// have stale pointers to its inner IR objects.
625 ///
626 /// Regardless of whether the proxy analysis is marked as preserved, all of
627 /// the analyses in the inner analysis manager are potentially invalidated
628 /// based on the set of preserved analyses.
630 IRUnitT &IR, const PreservedAnalyses &PA,
632
633 private:
634 AnalysisManagerT *InnerAM;
635 };
636
637 explicit InnerAnalysisManagerProxy(AnalysisManagerT &InnerAM)
638 : InnerAM(&InnerAM) {}
639
640 /// Run the analysis pass and create our proxy result object.
641 ///
642 /// This doesn't do any interesting work; it is primarily used to insert our
643 /// proxy result object into the outer analysis cache so that we can proxy
644 /// invalidation to the inner analysis manager.
646 ExtraArgTs...) {
647 return Result(*InnerAM);
648 }
649
650private:
651 friend AnalysisInfoMixin<
653
654 static AnalysisKey Key;
655
656 AnalysisManagerT *InnerAM;
657};
658
659// NOTE: The LLVM_ABI annotation cannot be used here because MSVC disallows
660// storage-class specifiers on class members outside of the class declaration
661// (C2720). LLVM_ATTRIBUTE_VISIBILITY_DEFAULT only applies to non-Windows
662// targets so it is used instead. Without this annotation, compiling LLVM as a
663// shared library with -fvisibility=hidden using GCC fails to export the symbol
664// even though InnerAnalysisManagerProxy is already annotated with LLVM_ABI.
665template <typename AnalysisManagerT, typename IRUnitT, typename... ExtraArgTs>
667 InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>::Key;
668
669/// Provide the \c FunctionAnalysisManager to \c Module proxy.
672
673/// Specialization of the invalidate method for the \c
674/// FunctionAnalysisManagerModuleProxy's result.
675template <>
676LLVM_ABI bool FunctionAnalysisManagerModuleProxy::Result::invalidate(
677 Module &M, const PreservedAnalyses &PA,
678 ModuleAnalysisManager::Invalidator &Inv);
679
680// Ensure the \c FunctionAnalysisManagerModuleProxy is provided as an extern
681// template.
683 Module>;
684
685/// An analysis over an "inner" IR unit that provides access to an
686/// analysis manager over a "outer" IR unit. The inner unit must be contained
687/// in the outer unit.
688///
689/// For example OuterAnalysisManagerProxy<ModuleAnalysisManager, Function> is an
690/// analysis over Functions (the "inner" unit) which provides access to a Module
691/// analysis manager. The ModuleAnalysisManager is the "outer" manager being
692/// proxied, and Modules are the "outer" IR unit. The inner/outer relationship
693/// is valid because each Function is contained in one Module.
694///
695/// This proxy only exposes the const interface of the outer analysis manager,
696/// to indicate that you cannot cause an outer analysis to run from within an
697/// inner pass. Instead, you must rely on the \c getCachedResult API. This is
698/// due to keeping potential future concurrency in mind. To give an example,
699/// running a module analysis before any function passes may give a different
700/// result than running it in a function pass. Both may be valid, but it would
701/// produce non-deterministic results. GlobalsAA is a good analysis example,
702/// because the cached information has the mod/ref info for all memory for each
703/// function at the time the analysis was computed. The information is still
704/// valid after a function transformation, but it may be *different* if
705/// recomputed after that transform. GlobalsAA is never invalidated.
706
707///
708/// This proxy doesn't manage invalidation in any way -- that is handled by the
709/// recursive return path of each layer of the pass manager. A consequence of
710/// this is the outer analyses may be stale. We invalidate the outer analyses
711/// only when we're done running passes over the inner IR units.
712template <typename AnalysisManagerT, typename IRUnitT, typename... ExtraArgTs>
714 : public AnalysisInfoMixin<
715 OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>> {
716public:
717 /// Result proxy object for \c OuterAnalysisManagerProxy.
718 class Result {
719 public:
720 explicit Result(const AnalysisManagerT &OuterAM) : OuterAM(&OuterAM) {}
721
722 /// Get a cached analysis. If the analysis can be invalidated, this will
723 /// assert.
724 template <typename PassT, typename IRUnitTParam>
725 typename PassT::Result *getCachedResult(IRUnitTParam &IR) const {
726 typename PassT::Result *Res =
727 OuterAM->template getCachedResult<PassT>(IR);
728 if (Res)
729 OuterAM->template verifyNotInvalidated<PassT>(IR, Res);
730 return Res;
731 }
732
733 /// Method provided for unit testing, not intended for general use.
734 template <typename PassT, typename IRUnitTParam>
735 bool cachedResultExists(IRUnitTParam &IR) const {
736 typename PassT::Result *Res =
737 OuterAM->template getCachedResult<PassT>(IR);
738 return Res != nullptr;
739 }
740
741 /// When invalidation occurs, remove any registered invalidation events.
743 IRUnitT &IRUnit, const PreservedAnalyses &PA,
745 // Loop over the set of registered outer invalidation mappings and if any
746 // of them map to an analysis that is now invalid, clear it out.
748 for (auto &KeyValuePair : OuterAnalysisInvalidationMap) {
749 AnalysisKey *OuterID = KeyValuePair.first;
750 auto &InnerIDs = KeyValuePair.second;
751 llvm::erase_if(InnerIDs, [&](AnalysisKey *InnerID) {
752 return Inv.invalidate(InnerID, IRUnit, PA);
753 });
754 if (InnerIDs.empty())
755 DeadKeys.push_back(OuterID);
756 }
757
758 for (auto *OuterID : DeadKeys)
759 OuterAnalysisInvalidationMap.erase(OuterID);
760
761 // The proxy itself remains valid regardless of anything else.
762 return false;
763 }
764
765 /// Register a deferred invalidation event for when the outer analysis
766 /// manager processes its invalidations.
767 template <typename OuterAnalysisT, typename InvalidatedAnalysisT>
769 AnalysisKey *OuterID = OuterAnalysisT::ID();
770 AnalysisKey *InvalidatedID = InvalidatedAnalysisT::ID();
771
772 auto &InvalidatedIDList = OuterAnalysisInvalidationMap[OuterID];
773 // Note, this is a linear scan. If we end up with large numbers of
774 // analyses that all trigger invalidation on the same outer analysis,
775 // this entire system should be changed to some other deterministic
776 // data structure such as a `SetVector` of a pair of pointers.
777 if (!llvm::is_contained(InvalidatedIDList, InvalidatedID))
778 InvalidatedIDList.push_back(InvalidatedID);
779 }
780
781 /// Access the map from outer analyses to deferred invalidation requiring
782 /// analyses.
785 return OuterAnalysisInvalidationMap;
786 }
787
788 private:
789 const AnalysisManagerT *OuterAM;
790
791 /// A map from an outer analysis ID to the set of this IR-unit's analyses
792 /// which need to be invalidated.
794 OuterAnalysisInvalidationMap;
795 };
796
797 OuterAnalysisManagerProxy(const AnalysisManagerT &OuterAM)
798 : OuterAM(&OuterAM) {}
799
800 /// Run the analysis pass and create our proxy result object.
801 /// Nothing to see here, it just forwards the \c OuterAM reference into the
802 /// result.
804 ExtraArgTs...) {
805 return Result(*OuterAM);
806 }
807
808private:
809 friend AnalysisInfoMixin<
810 OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>>;
811
812 static AnalysisKey Key;
813
814 const AnalysisManagerT *OuterAM;
815};
816
817template <typename AnalysisManagerT, typename IRUnitT, typename... ExtraArgTs>
818AnalysisKey
819 OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>::Key;
820
821extern template class LLVM_TEMPLATE_ABI
823/// Provide the \c ModuleAnalysisManager to \c Function proxy.
826
827/// Trivial adaptor that maps from a module to its functions.
828///
829/// Designed to allow composition of a FunctionPass(Manager) and
830/// a ModulePassManager, by running the FunctionPass(Manager) over every
831/// function in the module.
832///
833/// Function passes run within this adaptor can rely on having exclusive access
834/// to the function they are run over. They should not read or modify any other
835/// functions! Other threads or systems may be manipulating other functions in
836/// the module, and so their state should never be relied on.
837/// FIXME: Make the above true for all of LLVM's actual passes, some still
838/// violate this principle.
839///
840/// Function passes can also read the module containing the function, but they
841/// should not modify that module outside of the use lists of various globals.
842/// For example, a function pass is not permitted to add functions to the
843/// module.
844/// FIXME: Make the above true for all of LLVM's actual passes, some still
845/// violate this principle.
846///
847/// Note that although function passes can access module analyses, module
848/// analyses are not invalidated while the function passes are running, so they
849/// may be stale. Function analyses will not be stale.
852public:
854
855 explicit ModuleToFunctionPassAdaptor(std::unique_ptr<PassConceptT> Pass,
856 bool EagerlyInvalidate)
857 : Pass(std::move(Pass)), EagerlyInvalidate(EagerlyInvalidate) {}
858
859 /// Runs the function pass across every function in the module.
861 LLVM_ABI void
862 printPipeline(raw_ostream &OS,
863 function_ref<StringRef(StringRef)> MapClassName2PassName);
864
865 static bool isRequired() { return true; }
866
867private:
868 std::unique_ptr<PassConceptT> Pass;
869 bool EagerlyInvalidate;
870};
871
872/// A function to deduce a function pass type and wrap it in the
873/// templated adaptor.
874template <typename FunctionPassT>
875ModuleToFunctionPassAdaptor
877 bool EagerlyInvalidate = false) {
878 using PassModelT =
880 // Do not use make_unique, it causes too many template instantiations,
881 // causing terrible compile times.
883 std::unique_ptr<ModuleToFunctionPassAdaptor::PassConceptT>(
884 new PassModelT(std::forward<FunctionPassT>(Pass))),
885 EagerlyInvalidate);
886}
887
888/// A utility pass template to force an analysis result to be available.
889///
890/// If there are extra arguments at the pass's run level there may also be
891/// extra arguments to the analysis manager's \c getResult routine. We can't
892/// guess how to effectively map the arguments from one to the other, and so
893/// this specialization just ignores them.
894///
895/// Specific patterns of run-method extra arguments and analysis manager extra
896/// arguments will have to be defined as appropriate specializations.
897template <typename AnalysisT, typename IRUnitT,
898 typename AnalysisManagerT = AnalysisManager<IRUnitT>,
899 typename... ExtraArgTs>
901 : PassInfoMixin<RequireAnalysisPass<AnalysisT, IRUnitT, AnalysisManagerT,
902 ExtraArgTs...>> {
903 /// Run this pass over some unit of IR.
904 ///
905 /// This pass can be run over any unit of IR and use any analysis manager
906 /// provided they satisfy the basic API requirements. When this pass is
907 /// created, these methods can be instantiated to satisfy whatever the
908 /// context requires.
909 PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT &AM,
910 ExtraArgTs &&... Args) {
911 (void)AM.template getResult<AnalysisT>(Arg,
912 std::forward<ExtraArgTs>(Args)...);
913
914 return PreservedAnalyses::all();
915 }
917 function_ref<StringRef(StringRef)> MapClassName2PassName) {
918 auto ClassName = AnalysisT::name();
919 auto PassName = MapClassName2PassName(ClassName);
920 OS << "require<" << PassName << '>';
921 }
922 static bool isRequired() { return true; }
923};
924
925/// A no-op pass template which simply forces a specific analysis result
926/// to be invalidated.
927template <typename AnalysisT>
929 : PassInfoMixin<InvalidateAnalysisPass<AnalysisT>> {
930 /// Run this pass over some unit of IR.
931 ///
932 /// This pass can be run over any unit of IR and use any analysis manager,
933 /// provided they satisfy the basic API requirements. When this pass is
934 /// created, these methods can be instantiated to satisfy whatever the
935 /// context requires.
936 template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
937 PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT &AM, ExtraArgTs &&...) {
938 auto PA = PreservedAnalyses::all();
939 PA.abandon<AnalysisT>();
940 return PA;
941 }
943 function_ref<StringRef(StringRef)> MapClassName2PassName) {
944 auto ClassName = AnalysisT::name();
945 auto PassName = MapClassName2PassName(ClassName);
946 OS << "invalidate<" << PassName << '>';
947 }
948};
949
950/// A utility pass that does nothing, but preserves no analyses.
951///
952/// Because this preserves no analyses, any analysis passes queried after this
953/// pass runs will recompute fresh results.
954struct InvalidateAllAnalysesPass : PassInfoMixin<InvalidateAllAnalysesPass> {
955 /// Run this pass over some unit of IR.
956 template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
957 PreservedAnalyses run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...) {
959 }
960};
961
962} // end namespace llvm
963
964#endif // LLVM_IR_PASSMANAGER_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Function Alias Analysis Results
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_ABI
Definition Compiler.h:213
#define LLVM_TEMPLATE_ABI
Definition Compiler.h:214
#define LLVM_ATTRIBUTE_MINSIZE
Definition Compiler.h:328
#define LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
Definition Compiler.h:126
This file defines the DenseMap class.
Legalize the Machine IR a function s Machine IR
Definition Legalizer.cpp:80
#define I(x, y, z)
Definition MD5.cpp:57
#define P(N)
This header provides internal APIs and implementation details used by the pass management interfaces ...
This file contains some templates that are useful if you are working with the STL at all.
static const char PassName[]
Value * RHS
API to communicate dependencies between analyses during invalidation.
bool invalidate(AnalysisKey *ID, IRUnitT &IR, const PreservedAnalyses &PA)
A type-erased variant of the above invalidate method with the same core API other than passing an ana...
bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA)
Trigger the invalidation of some other analysis pass if not already handled and return whether it was...
A container for analyses that lazily runs them and caches their results.
bool isPassRegistered() const
Returns true if the specified analysis pass is registered.
AnalysisManager()
Construct an empty analysis manager.
void clear()
Clear all analysis results cached by this AnalysisManager.
AnalysisManager(AnalysisManager &&)
void verifyNotInvalidated(IRUnitT &IR, typename PassT::Result *Result) const
Verify that the given Result cannot be invalidated, assert otherwise.
AnalysisManager & operator=(AnalysisManager &&)
void clear(IRUnitT &IR, llvm::StringRef Name)
Clear any cached analysis results for a single unit of IR.
void invalidate(IRUnitT &IR, const PreservedAnalyses &PA)
Invalidate cached analyses for an IR unit.
void clearAnalysis(IRUnitT &IR)
Directly clear a cached analysis for an IR unit.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
bool empty() const
Returns true if the analysis manager has an empty results cache.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA, typename AnalysisManager< IRUnitT, ExtraArgTs... >::Invalidator &Inv)
Handler for invalidation of the outer IR unit, IRUnitT.
Result(AnalysisManagerT &InnerAM)
AnalysisManagerT & getManager()
Accessor for the analysis manager.
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Result run(IRUnitT &IR, AnalysisManager< IRUnitT, ExtraArgTs... > &AM, ExtraArgTs...)
Run the analysis pass and create our proxy result object.
InnerAnalysisManagerProxy(AnalysisManagerT &InnerAM)
Trivial adaptor that maps from a module to its functions.
detail::PassConcept< Function, FunctionAnalysisManager > PassConceptT
ModuleToFunctionPassAdaptor(std::unique_ptr< PassConceptT > Pass, bool EagerlyInvalidate)
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
Result(const AnalysisManagerT &OuterAM)
PassT::Result * getCachedResult(IRUnitTParam &IR) const
Get a cached analysis.
bool invalidate(IRUnitT &IRUnit, const PreservedAnalyses &PA, typename AnalysisManager< IRUnitT, ExtraArgTs... >::Invalidator &Inv)
When invalidation occurs, remove any registered invalidation events.
bool cachedResultExists(IRUnitTParam &IR) const
Method provided for unit testing, not intended for general use.
const SmallDenseMap< AnalysisKey *, TinyPtrVector< AnalysisKey * >, 2 > & getOuterInvalidations() const
Access the map from outer analyses to deferred invalidation requiring analyses.
void registerOuterAnalysisInvalidation()
Register a deferred invalidation event for when the outer analysis manager processes its invalidation...
An analysis over an "inner" IR unit that provides access to an analysis manager over a "outer" IR uni...
Result run(IRUnitT &, AnalysisManager< IRUnitT, ExtraArgTs... > &, ExtraArgTs...)
Run the analysis pass and create our proxy result object.
OuterAnalysisManagerProxy(const AnalysisManagerT &OuterAM)
This class provides access to building LLVM's passes.
Manages a sequence of passes over a particular unit of IR.
PassManager(PassManager &&Arg)
PassManager & operator=(PassManager &&RHS)
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
PassManager()=default
Construct a pass manager.
detail::PassConcept< LazyCallGraph::SCC, CGSCCAnalysisManager, ExtraArgTs... > PassConceptT
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t< std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
When adding a pass manager pass that has the same type as this pass manager, simply move the passes o...
static bool isRequired()
PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs)
Run all of the passes in this manager over the given unit of IR.
bool isEmpty() const
Returns if the pass manager contains any passes.
Pass interface - Implemented by all 'passes'.
Definition Pass.h:99
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
Definition Analysis.h:171
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
Pass manager infrastructure for declaring and invalidating analyses.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
PassT::Result getAnalysisResultUnpackTuple(AnalysisManagerT &AM, IRUnitT &IR, std::tuple< ArgTs... > Args, std::index_sequence< Ns... >)
Actual unpacker of extra arguments in getAnalysisResult, passes only those tuple arguments that are m...
PassT::Result getAnalysisResult(AnalysisManager< IRUnitT, AnalysisArgTs... > &AM, IRUnitT &IR, std::tuple< MainArgTs... > Args)
Helper for partial unpacking of extra arguments in getAnalysisResult.
This is an optimization pass for GlobalISel generic memory operations.
ModuleToFunctionPassAdaptor createModuleToFunctionPassAdaptor(FunctionPassT &&Pass, bool EagerlyInvalidate=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_GET_TYPE_NAME_CONSTEXPR StringRef getTypeName()
We provide a function which tries to compute the (demangled) name of a type statically.
Definition TypeName.h:40
LLVM_ABI void printIRUnitNameForStackTrace< Function >(raw_ostream &OS, const Function &IR)
void printIRUnitNameForStackTrace(raw_ostream &OS, const IRUnitT &IR)
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
LLVM_ABI void printIRUnitNameForStackTrace< Module >(raw_ostream &OS, const Module &IR)
PassManager< Module > ModulePassManager
Convenience typedef for a pass manager over modules.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
PassManager< Function > FunctionPassManager
Convenience typedef for a pass manager over functions.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1867
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1758
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition STLExtras.h:2120
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1897
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:867
A CRTP mix-in that provides informational APIs needed for analysis passes.
Definition PassManager.h:92
static AnalysisKey * ID()
Returns an opaque, unique ID for this analysis type.
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29
A utility pass that does nothing, but preserves no analyses.
PreservedAnalyses run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...)
Run this pass over some unit of IR.
A no-op pass template which simply forces a specific analysis result to be invalidated.
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT &AM, ExtraArgTs &&...)
Run this pass over some unit of IR.
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition PassManager.h:69
static StringRef name()
Gets the name of the pass we are mixed into.
Definition PassManager.h:71
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
Definition PassManager.h:79
A utility pass template to force an analysis result to be available.
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT &AM, ExtraArgTs &&... Args)
Run this pass over some unit of IR.
Abstract concept of an analysis pass.
Wrapper to model the analysis pass concept.
Abstract concept of an analysis result.
Wrapper to model the analysis result concept.
Template for the abstract base class used to dispatch polymorphically over pass objects.
A template wrapper used to implement the polymorphic API.