123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- Inliner.h - Inliner pass and infrastructure --------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_TRANSFORMS_IPO_INLINER_H
- #define LLVM_TRANSFORMS_IPO_INLINER_H
- #include "llvm/Analysis/CGSCCPassManager.h"
- #include "llvm/Analysis/CallGraphSCCPass.h"
- #include "llvm/Analysis/InlineAdvisor.h"
- #include "llvm/Analysis/InlineCost.h"
- #include "llvm/Analysis/LazyCallGraph.h"
- #include "llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h"
- #include "llvm/IR/PassManager.h"
- namespace llvm {
- class AssumptionCacheTracker;
- class CallGraph;
- class ProfileSummaryInfo;
- /// This class contains all of the helper code which is used to perform the
- /// inlining operations that do not depend on the policy. It contains the core
- /// bottom-up inlining infrastructure that specific inliner passes use.
- struct LegacyInlinerBase : public CallGraphSCCPass {
- explicit LegacyInlinerBase(char &ID);
- explicit LegacyInlinerBase(char &ID, bool InsertLifetime);
- /// For this class, we declare that we require and preserve the call graph.
- /// If the derived class implements this method, it should always explicitly
- /// call the implementation here.
- void getAnalysisUsage(AnalysisUsage &Info) const override;
- using llvm::Pass::doInitialization;
- bool doInitialization(CallGraph &CG) override;
- /// Main run interface method, this implements the interface required by the
- /// Pass class.
- bool runOnSCC(CallGraphSCC &SCC) override;
- using llvm::Pass::doFinalization;
- /// Remove now-dead linkonce functions at the end of processing to avoid
- /// breaking the SCC traversal.
- bool doFinalization(CallGraph &CG) override;
- /// This method must be implemented by the subclass to determine the cost of
- /// inlining the specified call site. If the cost returned is greater than
- /// the current inline threshold, the call site is not inlined.
- virtual InlineCost getInlineCost(CallBase &CB) = 0;
- /// Remove dead functions.
- ///
- /// This also includes a hack in the form of the 'AlwaysInlineOnly' flag
- /// which restricts it to deleting functions with an 'AlwaysInline'
- /// attribute. This is useful for the InlineAlways pass that only wants to
- /// deal with that subset of the functions.
- bool removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly = false);
- /// This function performs the main work of the pass. The default of
- /// Inlinter::runOnSCC() calls skipSCC() before calling this method, but
- /// derived classes which cannot be skipped can override that method and call
- /// this function unconditionally.
- bool inlineCalls(CallGraphSCC &SCC);
- private:
- // Insert @llvm.lifetime intrinsics.
- bool InsertLifetime = true;
- protected:
- AssumptionCacheTracker *ACT;
- ProfileSummaryInfo *PSI;
- std::function<const TargetLibraryInfo &(Function &)> GetTLI;
- ImportedFunctionsInliningStatistics ImportedFunctionsStats;
- };
- /// The inliner pass for the new pass manager.
- ///
- /// This pass wires together the inlining utilities and the inline cost
- /// analysis into a CGSCC pass. It considers every call in every function in
- /// the SCC and tries to inline if profitable. It can be tuned with a number of
- /// parameters to control what cost model is used and what tradeoffs are made
- /// when making the decision.
- ///
- /// It should be noted that the legacy inliners do considerably more than this
- /// inliner pass does. They provide logic for manually merging allocas, and
- /// doing considerable DCE including the DCE of dead functions. This pass makes
- /// every attempt to be simpler. DCE of functions requires complex reasoning
- /// about comdat groups, etc. Instead, it is expected that other more focused
- /// passes be composed to achieve the same end result.
- class InlinerPass : public PassInfoMixin<InlinerPass> {
- public:
- InlinerPass(bool OnlyMandatory = false,
- ThinOrFullLTOPhase LTOPhase = ThinOrFullLTOPhase::None)
- : OnlyMandatory(OnlyMandatory), LTOPhase(LTOPhase) {}
- InlinerPass(InlinerPass &&Arg) = default;
- PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
- LazyCallGraph &CG, CGSCCUpdateResult &UR);
- void printPipeline(raw_ostream &OS,
- function_ref<StringRef(StringRef)> MapClassName2PassName);
- private:
- InlineAdvisor &getAdvisor(const ModuleAnalysisManagerCGSCCProxy::Result &MAM,
- FunctionAnalysisManager &FAM, Module &M);
- std::unique_ptr<InlineAdvisor> OwnedAdvisor;
- const bool OnlyMandatory;
- const ThinOrFullLTOPhase LTOPhase;
- };
- /// Module pass, wrapping the inliner pass. This works in conjunction with the
- /// InlineAdvisorAnalysis to facilitate inlining decisions taking into account
- /// module-wide state, that need to keep track of inter-inliner pass runs, for
- /// a given module. An InlineAdvisor is configured and kept alive for the
- /// duration of the ModuleInlinerWrapperPass::run.
- class ModuleInlinerWrapperPass
- : public PassInfoMixin<ModuleInlinerWrapperPass> {
- public:
- ModuleInlinerWrapperPass(
- InlineParams Params = getInlineParams(), bool MandatoryFirst = true,
- InlineContext IC = {},
- InliningAdvisorMode Mode = InliningAdvisorMode::Default,
- unsigned MaxDevirtIterations = 0);
- ModuleInlinerWrapperPass(ModuleInlinerWrapperPass &&Arg) = default;
- PreservedAnalyses run(Module &, ModuleAnalysisManager &);
- /// Allow adding more CGSCC passes, besides inlining. This should be called
- /// before run is called, as part of pass pipeline building.
- CGSCCPassManager &getPM() { return PM; }
- /// Add a module pass that runs before the CGSCC passes.
- template <class T> void addModulePass(T Pass) {
- MPM.addPass(std::move(Pass));
- }
- /// Add a module pass that runs after the CGSCC passes.
- template <class T> void addLateModulePass(T Pass) {
- AfterCGMPM.addPass(std::move(Pass));
- }
- void printPipeline(raw_ostream &OS,
- function_ref<StringRef(StringRef)> MapClassName2PassName);
- private:
- const InlineParams Params;
- const InlineContext IC;
- const InliningAdvisorMode Mode;
- const unsigned MaxDevirtIterations;
- // TODO: Clean this up so we only have one ModulePassManager.
- CGSCCPassManager PM;
- ModulePassManager MPM;
- ModulePassManager AfterCGMPM;
- };
- } // end namespace llvm
- #endif // LLVM_TRANSFORMS_IPO_INLINER_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|