1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[PM] Implement the final conclusion as to how the analysis IDs should

work in the face of the limitations of DLLs and templated static
variables.

This requires passes that use the AnalysisBase mixin provide a static
variable themselves. So as to keep their APIs clean, I've made these
private and befriended the CRTP base class (which is the common
practice).

I've added documentation to AnalysisBase for why this is necessary and
at what point we can go back to the much simpler system.

This is clearly a better pattern than the extern template as it caught
*numerous* places where the template magic hadn't been applied and
things were "just working" but would eventually have broken
mysteriously.

llvm-svn: 263216
This commit is contained in:
Chandler Carruth 2016-03-11 10:22:49 +00:00
parent af02270708
commit 0bb4ed7ba7
47 changed files with 182 additions and 81 deletions

View File

@ -874,6 +874,9 @@ public:
} }
private: private:
friend AnalysisBase<AAManager>;
static char PassID;
SmallVector<void (*)(Function &F, AnalysisManager<Function> &AM, SmallVector<void (*)(Function &F, AnalysisManager<Function> &AM,
AAResults &AAResults), AAResults &AAResults),
4> ResultGetters; 4> ResultGetters;
@ -895,8 +898,6 @@ private:
} }
}; };
extern template class AnalysisBase<AAManager>;
/// A wrapper pass to provide the legacy pass manager access to a suitably /// A wrapper pass to provide the legacy pass manager access to a suitably
/// prepared AAResults object. /// prepared AAResults object.
class AAResultsWrapperPass : public FunctionPass { class AAResultsWrapperPass : public FunctionPass {

View File

@ -93,7 +93,11 @@ public:
/// ///
/// This analysis is intended for use with the new pass manager and will vend /// This analysis is intended for use with the new pass manager and will vend
/// assumption caches for a given function. /// assumption caches for a given function.
struct AssumptionAnalysis : AnalysisBase<AssumptionAnalysis> { class AssumptionAnalysis : public AnalysisBase<AssumptionAnalysis> {
friend AnalysisBase<AssumptionAnalysis>;
static char PassID;
public:
typedef AssumptionCache Result; typedef AssumptionCache Result;
AssumptionAnalysis() {} AssumptionAnalysis() {}
@ -105,8 +109,6 @@ struct AssumptionAnalysis : AnalysisBase<AssumptionAnalysis> {
AssumptionCache run(Function &F) { return AssumptionCache(F); } AssumptionCache run(Function &F) { return AssumptionCache(F); }
}; };
extern template class AnalysisBase<AssumptionAnalysis>;
/// \brief Printer pass for the \c AssumptionAnalysis results. /// \brief Printer pass for the \c AssumptionAnalysis results.
class AssumptionPrinterPass : public PassBase<AssumptionPrinterPass> { class AssumptionPrinterPass : public PassBase<AssumptionPrinterPass> {
raw_ostream &OS; raw_ostream &OS;

View File

@ -180,7 +180,11 @@ private:
}; };
/// Analysis pass providing a never-invalidated alias analysis result. /// Analysis pass providing a never-invalidated alias analysis result.
struct BasicAA : AnalysisBase<BasicAA> { class BasicAA : public AnalysisBase<BasicAA> {
friend AnalysisBase<BasicAA>;
static char PassID;
public:
typedef BasicAAResult Result; typedef BasicAAResult Result;
BasicAAResult run(Function &F, AnalysisManager<Function> *AM); BasicAAResult run(Function &F, AnalysisManager<Function> *AM);

View File

@ -109,7 +109,11 @@ private:
/// ///
/// FIXME: We really should refactor CFL to use the analysis more heavily, and /// FIXME: We really should refactor CFL to use the analysis more heavily, and
/// in particular to leverage invalidation to trigger re-computation of sets. /// in particular to leverage invalidation to trigger re-computation of sets.
struct CFLAA : AnalysisBase<CFLAA> { class CFLAA : public AnalysisBase<CFLAA> {
friend AnalysisBase<CFLAA>;
static char PassID;
public:
typedef CFLAAResult Result; typedef CFLAAResult Result;
CFLAAResult run(Function &F, AnalysisManager<Function> *AM); CFLAAResult run(Function &F, AnalysisManager<Function> *AM);

View File

@ -48,16 +48,12 @@ extern template class InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>;
typedef InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module> typedef InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>
CGSCCAnalysisManagerModuleProxy; CGSCCAnalysisManagerModuleProxy;
extern template class AnalysisBase<CGSCCAnalysisManagerModuleProxy>;
extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager, extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
LazyCallGraph::SCC>; LazyCallGraph::SCC>;
/// A proxy from a \c ModuleAnalysisManager to an \c SCC. /// A proxy from a \c ModuleAnalysisManager to an \c SCC.
typedef OuterAnalysisManagerProxy<ModuleAnalysisManager, LazyCallGraph::SCC> typedef OuterAnalysisManagerProxy<ModuleAnalysisManager, LazyCallGraph::SCC>
ModuleAnalysisManagerCGSCCProxy; ModuleAnalysisManagerCGSCCProxy;
extern template class AnalysisBase<ModuleAnalysisManagerCGSCCProxy>;
/// \brief The core module pass which does a post-order walk of the SCCs and /// \brief The core module pass which does a post-order walk of the SCCs and
/// runs a CGSCC pass over each one. /// runs a CGSCC pass over each one.
/// ///
@ -148,8 +144,6 @@ extern template class InnerAnalysisManagerProxy<FunctionAnalysisManager,
typedef InnerAnalysisManagerProxy<FunctionAnalysisManager, LazyCallGraph::SCC> typedef InnerAnalysisManagerProxy<FunctionAnalysisManager, LazyCallGraph::SCC>
FunctionAnalysisManagerCGSCCProxy; FunctionAnalysisManagerCGSCCProxy;
extern template class AnalysisBase<FunctionAnalysisManagerCGSCCProxy>;
extern template class OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>; extern template class OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>;
/// A proxy from a \c CGSCCAnalysisManager to a \c Function. /// A proxy from a \c CGSCCAnalysisManager to a \c Function.
typedef OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function> typedef OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>

View File

@ -295,7 +295,10 @@ private:
/// This class implements the concept of an analysis pass used by the \c /// This class implements the concept of an analysis pass used by the \c
/// ModuleAnalysisManager to run an analysis over a module and cache the /// ModuleAnalysisManager to run an analysis over a module and cache the
/// resulting data. /// resulting data.
struct CallGraphAnalysis : AnalysisBase<CallGraphAnalysis> { class CallGraphAnalysis : public AnalysisBase<CallGraphAnalysis> {
friend AnalysisBase<CallGraphAnalysis>;
static char PassID;
public: public:
/// \brief A formulaic typedef to inform clients of the result type. /// \brief A formulaic typedef to inform clients of the result type.
typedef CallGraph Result; typedef CallGraph Result;
@ -306,9 +309,6 @@ public:
CallGraph run(Module &M) { return CallGraph(M); } CallGraph run(Module &M) { return CallGraph(M); }
}; };
/// Instantiated in CallGraph.cpp
extern template class llvm::AnalysisBase<CallGraphAnalysis>;
/// \brief Printer pass for the \c CallGraphAnalysis results. /// \brief Printer pass for the \c CallGraphAnalysis results.
class CallGraphPrinterPass : public PassBase<CallGraphPrinterPass> { class CallGraphPrinterPass : public PassBase<CallGraphPrinterPass> {
raw_ostream &OS; raw_ostream &OS;

View File

@ -168,7 +168,12 @@ extern template class DominanceFrontierBase<BasicBlock>;
extern template class ForwardDominanceFrontierBase<BasicBlock>; extern template class ForwardDominanceFrontierBase<BasicBlock>;
/// \brief Analysis pass which computes a \c DominanceFrontier. /// \brief Analysis pass which computes a \c DominanceFrontier.
struct DominanceFrontierAnalysis : AnalysisBase<DominanceFrontierAnalysis> { class DominanceFrontierAnalysis
: public AnalysisBase<DominanceFrontierAnalysis> {
friend AnalysisBase<DominanceFrontierAnalysis>;
static char PassID;
public:
/// \brief Provide the result typedef for this analysis pass. /// \brief Provide the result typedef for this analysis pass.
typedef DominanceFrontier Result; typedef DominanceFrontier Result;
@ -176,8 +181,6 @@ struct DominanceFrontierAnalysis : AnalysisBase<DominanceFrontierAnalysis> {
DominanceFrontier run(Function &F, AnalysisManager<Function> *AM); DominanceFrontier run(Function &F, AnalysisManager<Function> *AM);
}; };
extern template class AnalysisBase<DominanceFrontierAnalysis>;
/// \brief Printer pass for the \c DominanceFrontier. /// \brief Printer pass for the \c DominanceFrontier.
class DominanceFrontierPrinterPass class DominanceFrontierPrinterPass
: public PassBase<DominanceFrontierPrinterPass> { : public PassBase<DominanceFrontierPrinterPass> {

View File

@ -118,7 +118,11 @@ private:
}; };
/// Analysis pass providing a never-invalidated alias analysis result. /// Analysis pass providing a never-invalidated alias analysis result.
struct GlobalsAA : AnalysisBase<GlobalsAA> { class GlobalsAA : public AnalysisBase<GlobalsAA> {
friend AnalysisBase<GlobalsAA>;
static char PassID;
public:
typedef GlobalsAAResult Result; typedef GlobalsAAResult Result;
GlobalsAAResult run(Module &M, AnalysisManager<Module> *AM); GlobalsAAResult run(Module &M, AnalysisManager<Module> *AM);

View File

@ -895,7 +895,11 @@ template <> struct GraphTraits<LazyCallGraph *> {
}; };
/// An analysis pass which computes the call graph for a module. /// An analysis pass which computes the call graph for a module.
struct LazyCallGraphAnalysis : AnalysisBase<LazyCallGraphAnalysis> { class LazyCallGraphAnalysis : public AnalysisBase<LazyCallGraphAnalysis> {
friend AnalysisBase<LazyCallGraphAnalysis>;
static char PassID;
public:
/// Inform generic clients of the result type. /// Inform generic clients of the result type.
typedef LazyCallGraph Result; typedef LazyCallGraph Result;
@ -906,8 +910,6 @@ struct LazyCallGraphAnalysis : AnalysisBase<LazyCallGraphAnalysis> {
LazyCallGraph run(Module &M) { return LazyCallGraph(M); } LazyCallGraph run(Module &M) { return LazyCallGraph(M); }
}; };
extern template class AnalysisBase<LazyCallGraphAnalysis>;
/// A pass which prints the call graph to a \c raw_ostream. /// A pass which prints the call graph to a \c raw_ostream.
/// ///
/// This is primarily useful for testing the analysis. /// This is primarily useful for testing the analysis.

View File

@ -787,14 +787,16 @@ template <> struct GraphTraits<Loop*> {
}; };
/// \brief Analysis pass that exposes the \c LoopInfo for a function. /// \brief Analysis pass that exposes the \c LoopInfo for a function.
struct LoopAnalysis : AnalysisBase<LoopAnalysis> { class LoopAnalysis : public AnalysisBase<LoopAnalysis> {
friend AnalysisBase<LoopAnalysis>;
static char PassID;
public:
typedef LoopInfo Result; typedef LoopInfo Result;
LoopInfo run(Function &F, AnalysisManager<Function> *AM); LoopInfo run(Function &F, AnalysisManager<Function> *AM);
}; };
extern template class AnalysisBase<LoopAnalysis>;
/// \brief Printer pass for the \c LoopAnalysis results. /// \brief Printer pass for the \c LoopAnalysis results.
class LoopPrinterPass : public PassBase<LoopPrinterPass> { class LoopPrinterPass : public PassBase<LoopPrinterPass> {
raw_ostream &OS; raw_ostream &OS;

View File

@ -43,8 +43,6 @@ extern template class InnerAnalysisManagerProxy<LoopAnalysisManager, Function>;
typedef InnerAnalysisManagerProxy<LoopAnalysisManager, Function> typedef InnerAnalysisManagerProxy<LoopAnalysisManager, Function>
LoopAnalysisManagerFunctionProxy; LoopAnalysisManagerFunctionProxy;
extern template class AnalysisBase<LoopAnalysisManagerFunctionProxy>;
extern template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>; extern template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>;
/// A proxy from a \c FunctionAnalysisManager to a \c Loop. /// A proxy from a \c FunctionAnalysisManager to a \c Loop.
typedef OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop> typedef OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>

View File

@ -471,7 +471,11 @@ private:
/// ///
/// This is essentially a no-op because the results are computed entirely /// This is essentially a no-op because the results are computed entirely
/// lazily. /// lazily.
struct MemoryDependenceAnalysis : AnalysisBase<MemoryDependenceAnalysis> { class MemoryDependenceAnalysis : public AnalysisBase<MemoryDependenceAnalysis> {
friend AnalysisBase<MemoryDependenceAnalysis>;
static char PassID;
public:
typedef MemoryDependenceResults Result; typedef MemoryDependenceResults Result;
MemoryDependenceResults run(Function &F, AnalysisManager<Function> *AM); MemoryDependenceResults run(Function &F, AnalysisManager<Function> *AM);

View File

@ -61,7 +61,11 @@ public:
}; };
/// Analysis pass providing a never-invalidated alias analysis result. /// Analysis pass providing a never-invalidated alias analysis result.
struct ObjCARCAA : AnalysisBase<ObjCARCAA> { class ObjCARCAA : public AnalysisBase<ObjCARCAA> {
friend AnalysisBase<ObjCARCAA>;
static char PassID;
public:
typedef ObjCARCAAResult Result; typedef ObjCARCAAResult Result;
ObjCARCAAResult run(Function &F, AnalysisManager<Function> *AM); ObjCARCAAResult run(Function &F, AnalysisManager<Function> *AM);

View File

@ -37,7 +37,12 @@ struct PostDominatorTree : public DominatorTreeBase<BasicBlock> {
}; };
/// \brief Analysis pass which computes a \c PostDominatorTree. /// \brief Analysis pass which computes a \c PostDominatorTree.
struct PostDominatorTreeAnalysis : AnalysisBase<PostDominatorTreeAnalysis> { class PostDominatorTreeAnalysis
: public AnalysisBase<PostDominatorTreeAnalysis> {
friend AnalysisBase<PostDominatorTreeAnalysis>;
static char PassID;
public:
/// \brief Provide the result typedef for this analysis pass. /// \brief Provide the result typedef for this analysis pass.
typedef PostDominatorTree Result; typedef PostDominatorTree Result;
@ -46,8 +51,6 @@ struct PostDominatorTreeAnalysis : AnalysisBase<PostDominatorTreeAnalysis> {
PostDominatorTree run(Function &F); PostDominatorTree run(Function &F);
}; };
extern template class AnalysisBase<PostDominatorTreeAnalysis>;
/// \brief Printer pass for the \c PostDominatorTree. /// \brief Printer pass for the \c PostDominatorTree.
class PostDominatorTreePrinterPass class PostDominatorTreePrinterPass
: public PassBase<PostDominatorTreePrinterPass> { : public PassBase<PostDominatorTreePrinterPass> {

View File

@ -923,14 +923,16 @@ public:
}; };
/// \brief Analysis pass that exposes the \c RegionInfo for a function. /// \brief Analysis pass that exposes the \c RegionInfo for a function.
struct RegionInfoAnalysis : AnalysisBase<RegionInfoAnalysis> { class RegionInfoAnalysis : public AnalysisBase<RegionInfoAnalysis> {
friend AnalysisBase<RegionInfoAnalysis>;
static char PassID;
public:
typedef RegionInfo Result; typedef RegionInfo Result;
RegionInfo run(Function &F, AnalysisManager<Function> *AM); RegionInfo run(Function &F, AnalysisManager<Function> *AM);
}; };
extern template class AnalysisBase<RegionInfoAnalysis>;
/// \brief Printer pass for the \c RegionInfo. /// \brief Printer pass for the \c RegionInfo.
class RegionInfoPrinterPass : public PassBase<RegionInfoPrinterPass> { class RegionInfoPrinterPass : public PassBase<RegionInfoPrinterPass> {
raw_ostream &OS; raw_ostream &OS;

View File

@ -1430,14 +1430,16 @@ namespace llvm {
}; };
/// \brief Analysis pass that exposes the \c ScalarEvolution for a function. /// \brief Analysis pass that exposes the \c ScalarEvolution for a function.
struct ScalarEvolutionAnalysis : AnalysisBase<ScalarEvolutionAnalysis> { class ScalarEvolutionAnalysis : public AnalysisBase<ScalarEvolutionAnalysis> {
friend AnalysisBase<ScalarEvolutionAnalysis>;
static char PassID;
public:
typedef ScalarEvolution Result; typedef ScalarEvolution Result;
ScalarEvolution run(Function &F, AnalysisManager<Function> *AM); ScalarEvolution run(Function &F, AnalysisManager<Function> *AM);
}; };
extern template class AnalysisBase<ScalarEvolutionAnalysis>;
/// \brief Printer pass for the \c ScalarEvolutionAnalysis results. /// \brief Printer pass for the \c ScalarEvolutionAnalysis results.
class ScalarEvolutionPrinterPass class ScalarEvolutionPrinterPass
: public PassBase<ScalarEvolutionPrinterPass> { : public PassBase<ScalarEvolutionPrinterPass> {

View File

@ -38,7 +38,11 @@ private:
}; };
/// Analysis pass providing a never-invalidated alias analysis result. /// Analysis pass providing a never-invalidated alias analysis result.
struct SCEVAA : AnalysisBase<SCEVAA> { class SCEVAA : public AnalysisBase<SCEVAA> {
friend AnalysisBase<SCEVAA>;
static char PassID;
public:
typedef SCEVAAResult Result; typedef SCEVAAResult Result;
SCEVAAResult run(Function &F, AnalysisManager<Function> *AM); SCEVAAResult run(Function &F, AnalysisManager<Function> *AM);

View File

@ -47,7 +47,11 @@ private:
}; };
/// Analysis pass providing a never-invalidated alias analysis result. /// Analysis pass providing a never-invalidated alias analysis result.
struct ScopedNoAliasAA : AnalysisBase<ScopedNoAliasAA> { class ScopedNoAliasAA : public AnalysisBase<ScopedNoAliasAA> {
friend AnalysisBase<ScopedNoAliasAA>;
static char PassID;
public:
typedef ScopedNoAliasAAResult Result; typedef ScopedNoAliasAAResult Result;
ScopedNoAliasAAResult run(Function &F, AnalysisManager<Function> *AM); ScopedNoAliasAAResult run(Function &F, AnalysisManager<Function> *AM);

View File

@ -292,6 +292,9 @@ public:
TargetLibraryInfo run(Function &F); TargetLibraryInfo run(Function &F);
private: private:
friend AnalysisBase<TargetLibraryAnalysis>;
static char PassID;
Optional<TargetLibraryInfoImpl> PresetInfoImpl; Optional<TargetLibraryInfoImpl> PresetInfoImpl;
StringMap<std::unique_ptr<TargetLibraryInfoImpl>> Impls; StringMap<std::unique_ptr<TargetLibraryInfoImpl>> Impls;
@ -299,8 +302,6 @@ private:
TargetLibraryInfoImpl &lookupInfoImpl(Triple T); TargetLibraryInfoImpl &lookupInfoImpl(Triple T);
}; };
extern template class AnalysisBase<TargetLibraryAnalysis>;
class TargetLibraryInfoWrapperPass : public ImmutablePass { class TargetLibraryInfoWrapperPass : public ImmutablePass {
TargetLibraryInfoImpl TLIImpl; TargetLibraryInfoImpl TLIImpl;
TargetLibraryInfo TLI; TargetLibraryInfo TLI;

View File

@ -922,6 +922,9 @@ public:
Result run(const Function &F); Result run(const Function &F);
private: private:
friend AnalysisBase<TargetIRAnalysis>;
static char PassID;
/// \brief The callback used to produce a result. /// \brief The callback used to produce a result.
/// ///
/// We use a completely opaque callback so that targets can provide whatever /// We use a completely opaque callback so that targets can provide whatever
@ -938,8 +941,6 @@ private:
static Result getDefaultTTI(const Function &F); static Result getDefaultTTI(const Function &F);
}; };
extern template class AnalysisBase<TargetIRAnalysis>;
/// \brief Wrapper pass for TargetTransformInfo. /// \brief Wrapper pass for TargetTransformInfo.
/// ///
/// This pass can be constructed from a TTI object which it stores internally /// This pass can be constructed from a TTI object which it stores internally

View File

@ -48,7 +48,11 @@ private:
}; };
/// Analysis pass providing a never-invalidated alias analysis result. /// Analysis pass providing a never-invalidated alias analysis result.
struct TypeBasedAA : AnalysisBase<TypeBasedAA> { class TypeBasedAA : public AnalysisBase<TypeBasedAA> {
friend AnalysisBase<TypeBasedAA>;
static char PassID;
public:
typedef TypeBasedAAResult Result; typedef TypeBasedAAResult Result;
TypeBasedAAResult run(Function &F, AnalysisManager<Function> *AM); TypeBasedAAResult run(Function &F, AnalysisManager<Function> *AM);

View File

@ -182,7 +182,11 @@ template <> struct GraphTraits<DominatorTree*>
}; };
/// \brief Analysis pass which computes a \c DominatorTree. /// \brief Analysis pass which computes a \c DominatorTree.
struct DominatorTreeAnalysis : AnalysisBase<DominatorTreeAnalysis> { class DominatorTreeAnalysis : public AnalysisBase<DominatorTreeAnalysis> {
friend AnalysisBase<DominatorTreeAnalysis>;
static char PassID;
public:
/// \brief Provide the result typedef for this analysis pass. /// \brief Provide the result typedef for this analysis pass.
typedef DominatorTree Result; typedef DominatorTree Result;
@ -190,8 +194,6 @@ struct DominatorTreeAnalysis : AnalysisBase<DominatorTreeAnalysis> {
DominatorTree run(Function &F); DominatorTree run(Function &F);
}; };
extern template class AnalysisBase<DominatorTreeAnalysis>;
/// \brief Printer pass for the \c DominatorTree. /// \brief Printer pass for the \c DominatorTree.
class DominatorTreePrinterPass : public PassBase<DominatorTreePrinterPass> { class DominatorTreePrinterPass : public PassBase<DominatorTreePrinterPass> {
raw_ostream &OS; raw_ostream &OS;

View File

@ -183,17 +183,23 @@ template <typename DerivedT> struct PassBase {
/// A CRTP mix-in base class to help define types that are valid analyses. /// A CRTP mix-in base class to help define types that are valid analyses.
/// ///
/// This provides some boiler plate for types that are analysis passes. /// This provides some boiler plate for types that are analysis passes.
template <typename DerivedT> class AnalysisBase : public PassBase<DerivedT> { template <typename DerivedT> struct AnalysisBase : PassBase<DerivedT> {
static char PassID;
public:
/// Returns an opaque, unique ID for this pass type. /// Returns an opaque, unique ID for this pass type.
static void *ID() { return (void *)&PassID; } ///
/// Note that this requires the derived type provide a static member whose
/// address can be converted to a void pointer.
///
/// FIXME: The only reason the derived type needs to provide this rather than
/// this mixin providing it is due to broken implementations which cannot
/// correctly unique a templated static so that they have the same addresses
/// for each instantiation and are definitively emitted once for each
/// instantiation. The only currently known platform with this limitation are
/// Windows DLL builds, specifically building each part of LLVM as a DLL. If
/// we ever remove that build configuration, this mixin can provide the
/// static PassID as well.
static void *ID() { return (void *)&DerivedT::PassID; }
}; };
/// Private static data to provide unique ID.
template <typename DerivedT> char AnalysisBase<DerivedT>::PassID;
/// \brief Manages a sequence of passes over units of IR. /// \brief Manages a sequence of passes over units of IR.
/// ///
/// A pass manager contains a sequence of passes to run over units of IR. It is /// A pass manager contains a sequence of passes to run over units of IR. It is
@ -740,17 +746,21 @@ public:
Result run(IRUnitT &IR) { return Result(*AM); } Result run(IRUnitT &IR) { return Result(*AM); }
private: private:
friend AnalysisBase<InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>>;
static char PassID;
AnalysisManagerT *AM; AnalysisManagerT *AM;
}; };
template <typename AnalysisManagerT, typename IRUnitT>
char InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>::PassID;
extern template class InnerAnalysisManagerProxy<FunctionAnalysisManager, extern template class InnerAnalysisManagerProxy<FunctionAnalysisManager,
Module>; Module>;
/// Provide the \c FunctionAnalysisManager to \c Module proxy. /// Provide the \c FunctionAnalysisManager to \c Module proxy.
typedef InnerAnalysisManagerProxy<FunctionAnalysisManager, Module> typedef InnerAnalysisManagerProxy<FunctionAnalysisManager, Module>
FunctionAnalysisManagerModuleProxy; FunctionAnalysisManagerModuleProxy;
extern template class AnalysisBase<FunctionAnalysisManagerModuleProxy>;
/// \brief A function analysis which acts as a proxy for a module analysis /// \brief A function analysis which acts as a proxy for a module analysis
/// manager. /// manager.
/// ///
@ -808,9 +818,15 @@ public:
Result run(IRUnitT &) { return Result(*AM); } Result run(IRUnitT &) { return Result(*AM); }
private: private:
friend AnalysisBase<OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT>>;
static char PassID;
const AnalysisManagerT *AM; const AnalysisManagerT *AM;
}; };
template <typename AnalysisManagerT, typename IRUnitT>
char OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT>::PassID;
extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager, extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
Function>; Function>;
/// Provide the \c ModuleAnalysisManager to \c Fucntion proxy. /// Provide the \c ModuleAnalysisManager to \c Fucntion proxy.

View File

@ -504,7 +504,7 @@ bool AAResults::canInstructionRangeModRef(const Instruction &I1,
AAResults::Concept::~Concept() {} AAResults::Concept::~Concept() {}
// Provide a definition for the static object used to identify passes. // Provide a definition for the static object used to identify passes.
template class llvm::AnalysisBase<AAManager>; char AAManager::PassID;
namespace { namespace {
/// A wrapper pass for external alias analyses. This just squirrels away the /// A wrapper pass for external alias analyses. This just squirrels away the

View File

@ -74,7 +74,7 @@ void AssumptionCache::registerAssumption(CallInst *CI) {
#endif #endif
} }
template class llvm::AnalysisBase<AssumptionAnalysis>; char AssumptionAnalysis::PassID;
PreservedAnalyses AssumptionPrinterPass::run(Function &F, PreservedAnalyses AssumptionPrinterPass::run(Function &F,
AnalysisManager<Function> *AM) { AnalysisManager<Function> *AM) {

View File

@ -1606,6 +1606,8 @@ bool BasicAAResult::constantOffsetHeuristic(
// BasicAliasAnalysis Pass // BasicAliasAnalysis Pass
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
char BasicAA::PassID;
BasicAAResult BasicAA::run(Function &F, AnalysisManager<Function> *AM) { BasicAAResult BasicAA::run(Function &F, AnalysisManager<Function> *AM) {
return BasicAAResult(F.getParent()->getDataLayout(), return BasicAAResult(F.getParent()->getDataLayout(),
AM->getResult<TargetLibraryAnalysis>(F), AM->getResult<TargetLibraryAnalysis>(F),

View File

@ -1088,6 +1088,8 @@ AliasResult CFLAAResult::query(const MemoryLocation &LocA,
return NoAlias; return NoAlias;
} }
char CFLAA::PassID;
CFLAAResult CFLAA::run(Function &F, AnalysisManager<Function> *AM) { CFLAAResult CFLAA::run(Function &F, AnalysisManager<Function> *AM) {
return CFLAAResult(); return CFLAAResult();
} }

View File

@ -18,12 +18,9 @@ namespace llvm {
template class PassManager<LazyCallGraph::SCC>; template class PassManager<LazyCallGraph::SCC>;
template class AnalysisManager<LazyCallGraph::SCC>; template class AnalysisManager<LazyCallGraph::SCC>;
template class InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>; template class InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>;
template class AnalysisBase<CGSCCAnalysisManagerModuleProxy>;
template class OuterAnalysisManagerProxy<ModuleAnalysisManager, template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
LazyCallGraph::SCC>; LazyCallGraph::SCC>;
template class AnalysisBase<ModuleAnalysisManagerCGSCCProxy>;
template class InnerAnalysisManagerProxy<FunctionAnalysisManager, template class InnerAnalysisManagerProxy<FunctionAnalysisManager,
LazyCallGraph::SCC>; LazyCallGraph::SCC>;
template class AnalysisBase<FunctionAnalysisManagerCGSCCProxy>;
template class OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>; template class OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>;
} }

View File

@ -260,7 +260,7 @@ void CallGraphNode::replaceCallEdge(CallSite CS,
} }
// Provide an explicit template instantiation for the static ID. // Provide an explicit template instantiation for the static ID.
template class llvm::AnalysisBase<CallGraphAnalysis>; char CallGraphAnalysis::PassID;
PreservedAnalyses CallGraphPrinterPass::run(Module &M, PreservedAnalyses CallGraphPrinterPass::run(Module &M,
AnalysisManager<Module> *AM) { AnalysisManager<Module> *AM) {

View File

@ -56,7 +56,7 @@ LLVM_DUMP_METHOD void DominanceFrontierWrapperPass::dump() const {
} }
#endif #endif
template class llvm::AnalysisBase<DominanceFrontierAnalysis>; char DominanceFrontierAnalysis::PassID;
DominanceFrontier DominanceFrontierAnalysis::run(Function &F, DominanceFrontier DominanceFrontierAnalysis::run(Function &F,
FunctionAnalysisManager *AM) { FunctionAnalysisManager *AM) {

View File

@ -936,6 +936,8 @@ GlobalsAAResult::analyzeModule(Module &M, const TargetLibraryInfo &TLI,
return Result; return Result;
} }
char GlobalsAA::PassID;
GlobalsAAResult GlobalsAA::run(Module &M, AnalysisManager<Module> *AM) { GlobalsAAResult GlobalsAA::run(Module &M, AnalysisManager<Module> *AM) {
return GlobalsAAResult::analyzeModule(M, return GlobalsAAResult::analyzeModule(M,
AM->getResult<TargetLibraryAnalysis>(M), AM->getResult<TargetLibraryAnalysis>(M),

View File

@ -1499,7 +1499,7 @@ LazyCallGraph::RefSCC *LazyCallGraph::getNextRefSCCInPostOrder() {
} }
} }
template class llvm::AnalysisBase<LazyCallGraphAnalysis>; char LazyCallGraphAnalysis::PassID;
LazyCallGraphPrinterPass::LazyCallGraphPrinterPass(raw_ostream &OS) : OS(OS) {} LazyCallGraphPrinterPass::LazyCallGraphPrinterPass(raw_ostream &OS) : OS(OS) {}

View File

@ -641,7 +641,7 @@ void LoopInfo::markAsRemoved(Loop *Unloop) {
} }
} }
template class llvm::AnalysisBase<LoopAnalysis>; char LoopAnalysis::PassID;
LoopInfo LoopAnalysis::run(Function &F, AnalysisManager<Function> *AM) { LoopInfo LoopAnalysis::run(Function &F, AnalysisManager<Function> *AM) {
// FIXME: Currently we create a LoopInfo from scratch for every function. // FIXME: Currently we create a LoopInfo from scratch for every function.

View File

@ -16,6 +16,5 @@ namespace llvm {
template class PassManager<Loop>; template class PassManager<Loop>;
template class AnalysisManager<Loop>; template class AnalysisManager<Loop>;
template class InnerAnalysisManagerProxy<LoopAnalysisManager, Function>; template class InnerAnalysisManagerProxy<LoopAnalysisManager, Function>;
template class AnalysisBase<LoopAnalysisManagerFunctionProxy>;
template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>; template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>;
} }

View File

@ -1659,6 +1659,8 @@ void MemoryDependenceResults::verifyRemoved(Instruction *D) const {
#endif #endif
} }
char MemoryDependenceAnalysis::PassID;
MemoryDependenceResults MemoryDependenceResults
MemoryDependenceAnalysis::run(Function &F, AnalysisManager<Function> *AM) { MemoryDependenceAnalysis::run(Function &F, AnalysisManager<Function> *AM) {
auto &AA = AM->getResult<AAManager>(F); auto &AA = AM->getResult<AAManager>(F);

View File

@ -44,7 +44,7 @@ FunctionPass* llvm::createPostDomTree() {
return new PostDominatorTreeWrapperPass(); return new PostDominatorTreeWrapperPass();
} }
template class llvm::AnalysisBase<PostDominatorTreeAnalysis>; char PostDominatorTreeAnalysis::PassID;
PostDominatorTree PostDominatorTreeAnalysis::run(Function &F) { PostDominatorTree PostDominatorTreeAnalysis::run(Function &F) {
PostDominatorTree PDT; PostDominatorTree PDT;

View File

@ -185,7 +185,7 @@ namespace llvm {
// RegionInfoAnalysis implementation // RegionInfoAnalysis implementation
// //
template class llvm::AnalysisBase<RegionInfoAnalysis>; char RegionInfoAnalysis::PassID;
RegionInfo RegionInfoAnalysis::run(Function &F, AnalysisManager<Function> *AM) { RegionInfo RegionInfoAnalysis::run(Function &F, AnalysisManager<Function> *AM) {
RegionInfo RI; RegionInfo RI;

View File

@ -9730,7 +9730,7 @@ void ScalarEvolution::verify() const {
// TODO: Verify more things. // TODO: Verify more things.
} }
template class llvm::AnalysisBase<ScalarEvolutionAnalysis>; char ScalarEvolutionAnalysis::PassID;
ScalarEvolution ScalarEvolutionAnalysis::run(Function &F, ScalarEvolution ScalarEvolutionAnalysis::run(Function &F,
AnalysisManager<Function> *AM) { AnalysisManager<Function> *AM) {

View File

@ -110,6 +110,8 @@ Value *SCEVAAResult::GetBaseValue(const SCEV *S) {
return nullptr; return nullptr;
} }
char SCEVAA::PassID;
SCEVAAResult SCEVAA::run(Function &F, AnalysisManager<Function> *AM) { SCEVAAResult SCEVAA::run(Function &F, AnalysisManager<Function> *AM) {
return SCEVAAResult(AM->getResult<ScalarEvolutionAnalysis>(F)); return SCEVAAResult(AM->getResult<ScalarEvolutionAnalysis>(F));
} }

View File

@ -172,6 +172,8 @@ bool ScopedNoAliasAAResult::mayAliasInScopes(const MDNode *Scopes,
return true; return true;
} }
char ScopedNoAliasAA::PassID;
ScopedNoAliasAAResult ScopedNoAliasAA::run(Function &F, ScopedNoAliasAAResult ScopedNoAliasAA::run(Function &F,
AnalysisManager<Function> *AM) { AnalysisManager<Function> *AM) {
return ScopedNoAliasAAResult(); return ScopedNoAliasAAResult();

View File

@ -636,7 +636,7 @@ TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass(
initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry());
} }
template class llvm::AnalysisBase<TargetLibraryAnalysis>; char TargetLibraryAnalysis::PassID;
// Register the basic pass. // Register the basic pass.
INITIALIZE_PASS(TargetLibraryInfoWrapperPass, "targetlibinfo", INITIALIZE_PASS(TargetLibraryInfoWrapperPass, "targetlibinfo",

View File

@ -377,7 +377,7 @@ TargetIRAnalysis::Result TargetIRAnalysis::run(const Function &F) {
return TTICallback(F); return TTICallback(F);
} }
template class llvm::AnalysisBase<TargetIRAnalysis>; char TargetIRAnalysis::PassID;
TargetIRAnalysis::Result TargetIRAnalysis::getDefaultTTI(const Function &F) { TargetIRAnalysis::Result TargetIRAnalysis::getDefaultTTI(const Function &F) {
return Result(F.getParent()->getDataLayout()); return Result(F.getParent()->getDataLayout());

View File

@ -583,6 +583,8 @@ bool TypeBasedAAResult::PathAliases(const MDNode *A, const MDNode *B) const {
return false; return false;
} }
char TypeBasedAA::PassID;
TypeBasedAAResult TypeBasedAA::run(Function &F, AnalysisManager<Function> *AM) { TypeBasedAAResult TypeBasedAA::run(Function &F, AnalysisManager<Function> *AM) {
return TypeBasedAAResult(); return TypeBasedAAResult();
} }

View File

@ -308,7 +308,7 @@ DominatorTree DominatorTreeAnalysis::run(Function &F) {
return DT; return DT;
} }
template class llvm::AnalysisBase<DominatorTreeAnalysis>; char DominatorTreeAnalysis::PassID;
DominatorTreePrinterPass::DominatorTreePrinterPass(raw_ostream &OS) : OS(OS) {} DominatorTreePrinterPass::DominatorTreePrinterPass(raw_ostream &OS) : OS(OS) {}

View File

@ -20,6 +20,5 @@ template class PassManager<Function>;
template class AnalysisManager<Module>; template class AnalysisManager<Module>;
template class AnalysisManager<Function>; template class AnalysisManager<Function>;
template class InnerAnalysisManagerProxy<FunctionAnalysisManager, Module>; template class InnerAnalysisManagerProxy<FunctionAnalysisManager, Module>;
template class AnalysisBase<FunctionAnalysisManagerModuleProxy>;
template class OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>; template class OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>;
} }

View File

@ -70,7 +70,11 @@ struct NoOpModulePass {
}; };
/// \brief No-op module analysis. /// \brief No-op module analysis.
struct NoOpModuleAnalysis : AnalysisBase<NoOpModuleAnalysis> { class NoOpModuleAnalysis : public AnalysisBase<NoOpModuleAnalysis> {
friend AnalysisBase<NoOpModuleAnalysis>;
static char PassID;
public:
struct Result {}; struct Result {};
Result run(Module &) { return Result(); } Result run(Module &) { return Result(); }
static StringRef name() { return "NoOpModuleAnalysis"; } static StringRef name() { return "NoOpModuleAnalysis"; }
@ -85,7 +89,11 @@ struct NoOpCGSCCPass {
}; };
/// \brief No-op CGSCC analysis. /// \brief No-op CGSCC analysis.
struct NoOpCGSCCAnalysis : AnalysisBase<NoOpCGSCCAnalysis> { class NoOpCGSCCAnalysis : public AnalysisBase<NoOpCGSCCAnalysis> {
friend AnalysisBase<NoOpCGSCCAnalysis>;
static char PassID;
public:
struct Result {}; struct Result {};
Result run(LazyCallGraph::SCC &) { return Result(); } Result run(LazyCallGraph::SCC &) { return Result(); }
static StringRef name() { return "NoOpCGSCCAnalysis"; } static StringRef name() { return "NoOpCGSCCAnalysis"; }
@ -98,7 +106,11 @@ struct NoOpFunctionPass {
}; };
/// \brief No-op function analysis. /// \brief No-op function analysis.
struct NoOpFunctionAnalysis : AnalysisBase<NoOpFunctionAnalysis> { class NoOpFunctionAnalysis : public AnalysisBase<NoOpFunctionAnalysis> {
friend AnalysisBase<NoOpFunctionAnalysis>;
static char PassID;
public:
struct Result {}; struct Result {};
Result run(Function &) { return Result(); } Result run(Function &) { return Result(); }
static StringRef name() { return "NoOpFunctionAnalysis"; } static StringRef name() { return "NoOpFunctionAnalysis"; }
@ -111,12 +123,21 @@ struct NoOpLoopPass {
}; };
/// \brief No-op loop analysis. /// \brief No-op loop analysis.
struct NoOpLoopAnalysis : AnalysisBase<NoOpLoopAnalysis> { class NoOpLoopAnalysis : public AnalysisBase<NoOpLoopAnalysis> {
friend AnalysisBase<NoOpLoopAnalysis>;
static char PassID;
public:
struct Result {}; struct Result {};
Result run(Loop &) { return Result(); } Result run(Loop &) { return Result(); }
static StringRef name() { return "NoOpLoopAnalysis"; } static StringRef name() { return "NoOpLoopAnalysis"; }
}; };
char NoOpModuleAnalysis::PassID;
char NoOpCGSCCAnalysis::PassID;
char NoOpFunctionAnalysis::PassID;
char NoOpLoopAnalysis::PassID;
} // End anonymous namespace. } // End anonymous namespace.
void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) { void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) {

View File

@ -40,9 +40,14 @@ public:
} }
private: private:
friend AnalysisBase<TestFunctionAnalysis>;
static char PassID;
int &Runs; int &Runs;
}; };
char TestFunctionAnalysis::PassID;
class TestModuleAnalysis : public AnalysisBase<TestModuleAnalysis> { class TestModuleAnalysis : public AnalysisBase<TestModuleAnalysis> {
public: public:
struct Result { struct Result {
@ -61,9 +66,14 @@ public:
} }
private: private:
friend AnalysisBase<TestModuleAnalysis>;
static char PassID;
int &Runs; int &Runs;
}; };
char TestModuleAnalysis::PassID;
struct TestModulePass : PassBase<TestModulePass> { struct TestModulePass : PassBase<TestModulePass> {
TestModulePass(int &RunCount) : RunCount(RunCount) {} TestModulePass(int &RunCount) : RunCount(RunCount) {}