[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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@263216 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chandler Carruth 2016-03-11 10:22:49 +00:00
parent 06d66200b3
commit e95015f4c9
47 changed files with 182 additions and 81 deletions

View File

@ -874,6 +874,9 @@ public:
}
private:
friend AnalysisBase<AAManager>;
static char PassID;
SmallVector<void (*)(Function &F, AnalysisManager<Function> &AM,
AAResults &AAResults),
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
/// prepared AAResults object.
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
/// 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;
AssumptionAnalysis() {}
@ -105,8 +109,6 @@ struct AssumptionAnalysis : AnalysisBase<AssumptionAnalysis> {
AssumptionCache run(Function &F) { return AssumptionCache(F); }
};
extern template class AnalysisBase<AssumptionAnalysis>;
/// \brief Printer pass for the \c AssumptionAnalysis results.
class AssumptionPrinterPass : public PassBase<AssumptionPrinterPass> {
raw_ostream &OS;

View File

@ -180,7 +180,11 @@ private:
};
/// 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;
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
/// 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;
CFLAAResult run(Function &F, AnalysisManager<Function> *AM);

View File

@ -48,16 +48,12 @@ extern template class InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>;
typedef InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>
CGSCCAnalysisManagerModuleProxy;
extern template class AnalysisBase<CGSCCAnalysisManagerModuleProxy>;
extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
LazyCallGraph::SCC>;
/// A proxy from a \c ModuleAnalysisManager to an \c SCC.
typedef OuterAnalysisManagerProxy<ModuleAnalysisManager, LazyCallGraph::SCC>
ModuleAnalysisManagerCGSCCProxy;
extern template class AnalysisBase<ModuleAnalysisManagerCGSCCProxy>;
/// \brief The core module pass which does a post-order walk of the SCCs and
/// runs a CGSCC pass over each one.
///
@ -148,8 +144,6 @@ extern template class InnerAnalysisManagerProxy<FunctionAnalysisManager,
typedef InnerAnalysisManagerProxy<FunctionAnalysisManager, LazyCallGraph::SCC>
FunctionAnalysisManagerCGSCCProxy;
extern template class AnalysisBase<FunctionAnalysisManagerCGSCCProxy>;
extern template class OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>;
/// A proxy from a \c CGSCCAnalysisManager to a \c 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
/// ModuleAnalysisManager to run an analysis over a module and cache the
/// resulting data.
struct CallGraphAnalysis : AnalysisBase<CallGraphAnalysis> {
class CallGraphAnalysis : public AnalysisBase<CallGraphAnalysis> {
friend AnalysisBase<CallGraphAnalysis>;
static char PassID;
public:
/// \brief A formulaic typedef to inform clients of the result type.
typedef CallGraph Result;
@ -306,9 +309,6 @@ public:
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.
class CallGraphPrinterPass : public PassBase<CallGraphPrinterPass> {
raw_ostream &OS;

View File

@ -168,7 +168,12 @@ extern template class DominanceFrontierBase<BasicBlock>;
extern template class ForwardDominanceFrontierBase<BasicBlock>;
/// \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.
typedef DominanceFrontier Result;
@ -176,8 +181,6 @@ struct DominanceFrontierAnalysis : AnalysisBase<DominanceFrontierAnalysis> {
DominanceFrontier run(Function &F, AnalysisManager<Function> *AM);
};
extern template class AnalysisBase<DominanceFrontierAnalysis>;
/// \brief Printer pass for the \c DominanceFrontier.
class DominanceFrontierPrinterPass
: public PassBase<DominanceFrontierPrinterPass> {

View File

@ -118,7 +118,11 @@ private:
};
/// 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;
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.
struct LazyCallGraphAnalysis : AnalysisBase<LazyCallGraphAnalysis> {
class LazyCallGraphAnalysis : public AnalysisBase<LazyCallGraphAnalysis> {
friend AnalysisBase<LazyCallGraphAnalysis>;
static char PassID;
public:
/// Inform generic clients of the result type.
typedef LazyCallGraph Result;
@ -906,8 +910,6 @@ struct LazyCallGraphAnalysis : AnalysisBase<LazyCallGraphAnalysis> {
LazyCallGraph run(Module &M) { return LazyCallGraph(M); }
};
extern template class AnalysisBase<LazyCallGraphAnalysis>;
/// A pass which prints the call graph to a \c raw_ostream.
///
/// 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.
struct LoopAnalysis : AnalysisBase<LoopAnalysis> {
class LoopAnalysis : public AnalysisBase<LoopAnalysis> {
friend AnalysisBase<LoopAnalysis>;
static char PassID;
public:
typedef LoopInfo Result;
LoopInfo run(Function &F, AnalysisManager<Function> *AM);
};
extern template class AnalysisBase<LoopAnalysis>;
/// \brief Printer pass for the \c LoopAnalysis results.
class LoopPrinterPass : public PassBase<LoopPrinterPass> {
raw_ostream &OS;

View File

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

View File

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

View File

@ -61,7 +61,11 @@ public:
};
/// 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;
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.
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.
typedef PostDominatorTree Result;
@ -46,8 +51,6 @@ struct PostDominatorTreeAnalysis : AnalysisBase<PostDominatorTreeAnalysis> {
PostDominatorTree run(Function &F);
};
extern template class AnalysisBase<PostDominatorTreeAnalysis>;
/// \brief Printer pass for the \c PostDominatorTree.
class PostDominatorTreePrinterPass
: public PassBase<PostDominatorTreePrinterPass> {

View File

@ -923,14 +923,16 @@ public:
};
/// \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;
RegionInfo run(Function &F, AnalysisManager<Function> *AM);
};
extern template class AnalysisBase<RegionInfoAnalysis>;
/// \brief Printer pass for the \c RegionInfo.
class RegionInfoPrinterPass : public PassBase<RegionInfoPrinterPass> {
raw_ostream &OS;

View File

@ -1430,14 +1430,16 @@ namespace llvm {
};
/// \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;
ScalarEvolution run(Function &F, AnalysisManager<Function> *AM);
};
extern template class AnalysisBase<ScalarEvolutionAnalysis>;
/// \brief Printer pass for the \c ScalarEvolutionAnalysis results.
class ScalarEvolutionPrinterPass
: public PassBase<ScalarEvolutionPrinterPass> {

View File

@ -38,7 +38,11 @@ private:
};
/// 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;
SCEVAAResult run(Function &F, AnalysisManager<Function> *AM);

View File

@ -47,7 +47,11 @@ private:
};
/// 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;
ScopedNoAliasAAResult run(Function &F, AnalysisManager<Function> *AM);

View File

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

View File

@ -922,6 +922,9 @@ public:
Result run(const Function &F);
private:
friend AnalysisBase<TargetIRAnalysis>;
static char PassID;
/// \brief The callback used to produce a result.
///
/// We use a completely opaque callback so that targets can provide whatever
@ -938,8 +941,6 @@ private:
static Result getDefaultTTI(const Function &F);
};
extern template class AnalysisBase<TargetIRAnalysis>;
/// \brief Wrapper pass for TargetTransformInfo.
///
/// 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.
struct TypeBasedAA : AnalysisBase<TypeBasedAA> {
class TypeBasedAA : public AnalysisBase<TypeBasedAA> {
friend AnalysisBase<TypeBasedAA>;
static char PassID;
public:
typedef TypeBasedAAResult Result;
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.
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.
typedef DominatorTree Result;
@ -190,8 +194,6 @@ struct DominatorTreeAnalysis : AnalysisBase<DominatorTreeAnalysis> {
DominatorTree run(Function &F);
};
extern template class AnalysisBase<DominatorTreeAnalysis>;
/// \brief Printer pass for the \c DominatorTree.
class DominatorTreePrinterPass : public PassBase<DominatorTreePrinterPass> {
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.
///
/// This provides some boiler plate for types that are analysis passes.
template <typename DerivedT> class AnalysisBase : public PassBase<DerivedT> {
static char PassID;
public:
template <typename DerivedT> struct AnalysisBase : PassBase<DerivedT> {
/// 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.
///
/// 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); }
private:
friend AnalysisBase<InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>>;
static char PassID;
AnalysisManagerT *AM;
};
template <typename AnalysisManagerT, typename IRUnitT>
char InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>::PassID;
extern template class InnerAnalysisManagerProxy<FunctionAnalysisManager,
Module>;
/// Provide the \c FunctionAnalysisManager to \c Module proxy.
typedef InnerAnalysisManagerProxy<FunctionAnalysisManager, Module>
FunctionAnalysisManagerModuleProxy;
extern template class AnalysisBase<FunctionAnalysisManagerModuleProxy>;
/// \brief A function analysis which acts as a proxy for a module analysis
/// manager.
///
@ -808,9 +818,15 @@ public:
Result run(IRUnitT &) { return Result(*AM); }
private:
friend AnalysisBase<OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT>>;
static char PassID;
const AnalysisManagerT *AM;
};
template <typename AnalysisManagerT, typename IRUnitT>
char OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT>::PassID;
extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
Function>;
/// Provide the \c ModuleAnalysisManager to \c Fucntion proxy.

View File

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

View File

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

View File

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

View File

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

View File

@ -18,12 +18,9 @@ namespace llvm {
template class PassManager<LazyCallGraph::SCC>;
template class AnalysisManager<LazyCallGraph::SCC>;
template class InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>;
template class AnalysisBase<CGSCCAnalysisManagerModuleProxy>;
template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
LazyCallGraph::SCC>;
template class AnalysisBase<ModuleAnalysisManagerCGSCCProxy>;
template class InnerAnalysisManagerProxy<FunctionAnalysisManager,
LazyCallGraph::SCC>;
template class AnalysisBase<FunctionAnalysisManagerCGSCCProxy>;
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.
template class llvm::AnalysisBase<CallGraphAnalysis>;
char CallGraphAnalysis::PassID;
PreservedAnalyses CallGraphPrinterPass::run(Module &M,
AnalysisManager<Module> *AM) {

View File

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

View File

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

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) {
// 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 AnalysisManager<Loop>;
template class InnerAnalysisManagerProxy<LoopAnalysisManager, Function>;
template class AnalysisBase<LoopAnalysisManagerFunctionProxy>;
template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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