diff --git a/include/llvm/Analysis/TargetLibraryInfo.h b/include/llvm/Analysis/TargetLibraryInfo.h index 7e563c1e386..ef7b7b4a388 100644 --- a/include/llvm/Analysis/TargetLibraryInfo.h +++ b/include/llvm/Analysis/TargetLibraryInfo.h @@ -11,10 +11,14 @@ #define LLVM_ANALYSIS_TARGETLIBRARYINFO_H #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/Triple.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Module.h" #include "llvm/Pass.h" namespace llvm { - class Triple; +class PreservedAnalyses; namespace LibFunc { enum Func { @@ -718,7 +722,12 @@ class TargetLibraryInfo { public: TargetLibraryInfo(); explicit TargetLibraryInfo(const Triple &T); - explicit TargetLibraryInfo(const TargetLibraryInfo &TLI); + + // Provide value semantics. + TargetLibraryInfo(const TargetLibraryInfo &TLI); + TargetLibraryInfo(TargetLibraryInfo &&TLI); + TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI); + TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI); /// \brief Searches for a particular function name. /// @@ -799,6 +808,66 @@ public: /// /// This can be used for options like -fno-builtin. void disableAllFunctions(); + + /// \brief Handle invalidation from the pass manager. + /// + /// If we try to invalidate this info, just return false. It cannot become + /// invalid even if the module changes. + bool invalidate(Module &, const PreservedAnalyses &) { return false; } +}; + +/// \brief Analysis pass providing the \c TargetLibraryInfo. +/// +/// Note that this pass's result cannot be invalidated, it is immutable for the +/// life of the module. +class TargetLibraryAnalysis { +public: + typedef TargetLibraryInfo Result; + + /// \brief Opaque, unique identifier for this analysis pass. + static void *ID() { return (void *)&PassID; } + + /// \brief Default construct the library analysis. + /// + /// This will use the module's triple to construct the library info for that + /// module. + TargetLibraryAnalysis() {} + + /// \brief Construct a library analysis with preset info. + /// + /// This will directly copy the preset info into the result without + /// consulting the module's triple. + TargetLibraryAnalysis(TargetLibraryInfo PresetInfo) + : PresetInfo(std::move(PresetInfo)) {} + + // Value semantics. We spell out the constructors for MSVC. + TargetLibraryAnalysis(const TargetLibraryAnalysis &Arg) + : PresetInfo(Arg.PresetInfo) {} + TargetLibraryAnalysis(TargetLibraryAnalysis &&Arg) + : PresetInfo(std::move(Arg.PresetInfo)) {} + TargetLibraryAnalysis &operator=(const TargetLibraryAnalysis &RHS) { + PresetInfo = RHS.PresetInfo; + return *this; + } + TargetLibraryAnalysis &operator=(TargetLibraryAnalysis &&RHS) { + PresetInfo = std::move(RHS.PresetInfo); + return *this; + } + + TargetLibraryInfo run(Module &M) { + if (PresetInfo) + return *PresetInfo; + + return TargetLibraryInfo(Triple(M.getTargetTriple())); + } + + /// \brief Provide access to a name for this pass for debugging purposes. + static StringRef name() { return "TargetLibraryAnalysis"; } + +private: + static char PassID; + + Optional PresetInfo; }; class TargetLibraryInfoWrapperPass : public ImmutablePass { diff --git a/lib/Analysis/TargetLibraryInfo.cpp b/lib/Analysis/TargetLibraryInfo.cpp index 1b6ebfa0906..417f570bb6f 100644 --- a/lib/Analysis/TargetLibraryInfo.cpp +++ b/lib/Analysis/TargetLibraryInfo.cpp @@ -690,9 +690,28 @@ TargetLibraryInfo::TargetLibraryInfo(const Triple &T) { initialize(*this, T, StandardNames); } -TargetLibraryInfo::TargetLibraryInfo(const TargetLibraryInfo &TLI) { +TargetLibraryInfo::TargetLibraryInfo(const TargetLibraryInfo &TLI) + : CustomNames(TLI.CustomNames) { memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); +} + +TargetLibraryInfo::TargetLibraryInfo(TargetLibraryInfo &&TLI) + : CustomNames(std::move(TLI.CustomNames)) { + std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), + AvailableArray); +} + +TargetLibraryInfo &TargetLibraryInfo::operator=(const TargetLibraryInfo &TLI) { CustomNames = TLI.CustomNames; + memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); + return *this; +} + +TargetLibraryInfo &TargetLibraryInfo::operator=(TargetLibraryInfo &&TLI) { + CustomNames = std::move(TLI.CustomNames); + std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), + AvailableArray); + return *this; } namespace { @@ -756,6 +775,8 @@ TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass( initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); } +char TargetLibraryAnalysis::PassID; + // Register the basic pass. INITIALIZE_PASS(TargetLibraryInfoWrapperPass, "targetlibinfo", "Target Library Information", false, true) diff --git a/test/Other/new-pass-manager.ll b/test/Other/new-pass-manager.ll index 6454ffc1fb0..2cb54ba49a8 100644 --- a/test/Other/new-pass-manager.ll +++ b/test/Other/new-pass-manager.ll @@ -266,6 +266,18 @@ ; CHECK-INVALIDATE-ALL-CG-NOT: Running analysis: NoOpModuleAnalysis ; CHECK-INVALIDATE-ALL-CG: Finished pass manager +; RUN: opt -disable-output -disable-verify -debug-pass-manager %s 2>&1 \ +; RUN: -passes='require,invalidate,require' \ +; RUN: | FileCheck %s --check-prefix=CHECK-TLI +; CHECK-TLI: Starting pass manager +; CHECK-TLI: Running pass: RequireAnalysisPass +; CHECK-TLI: Running analysis: TargetLibraryAnalysis +; CHECK-TLI: Running pass: InvalidateAllAnalysesPass +; CHECK-TLI-NOT: Invalidating analysis: TargetLibraryAnalysis +; CHECK-TLI: Running pass: RequireAnalysisPass +; CHECK-TLI-NOT: Running analysis: TargetLibraryAnalysis +; CHECK-TLI: Finished pass manager + define void @foo() { ret void } diff --git a/tools/opt/PassRegistry.def b/tools/opt/PassRegistry.def index c98de60b570..411ca0f02d8 100644 --- a/tools/opt/PassRegistry.def +++ b/tools/opt/PassRegistry.def @@ -21,6 +21,7 @@ #endif MODULE_ANALYSIS("lcg", LazyCallGraphAnalysis()) MODULE_ANALYSIS("no-op-module", NoOpModuleAnalysis()) +MODULE_ANALYSIS("targetlibinfo", TargetLibraryAnalysis()) #undef MODULE_ANALYSIS #ifndef MODULE_PASS diff --git a/tools/opt/Passes.cpp b/tools/opt/Passes.cpp index 518112a1c88..1af4d52b870 100644 --- a/tools/opt/Passes.cpp +++ b/tools/opt/Passes.cpp @@ -17,6 +17,7 @@ #include "Passes.h" #include "llvm/Analysis/CGSCCPassManager.h" #include "llvm/Analysis/LazyCallGraph.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/PassManager.h"