From 76a8f7fb5a325ab635f55f811803eb3ca034f8fa Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 30 Aug 2002 20:19:49 +0000 Subject: [PATCH] - Pass now has AnalysisImpls class to implement getAnalysis() so that it is correct even when called back by another passes run method. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3531 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Pass.h | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index 0f4b56fdbcc..6f5f8d63b46 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -47,6 +47,12 @@ class Pass { friend class AnalysisResolver; AnalysisResolver *Resolver; // AnalysisResolver this pass is owned by... const PassInfo *PassInfoCache; + + // AnalysisImpls - This keeps track of which passes implement the interfaces + // that are required by the current pass (to implement getAnalysis()). + // + std::vector > AnalysisImpls; + void operator=(const Pass&); // DO NOT IMPLEMENT Pass(const Pass &); // DO NOT IMPLEMENT public: @@ -129,26 +135,38 @@ protected: AnalysisType &getAnalysis() const { assert(Resolver && "Pass has not been inserted into a PassManager object!"); const PassInfo *PI = getClassPassInfo(); + return getAnalysisID(PI); + } + + template + AnalysisType &getAnalysisID(const PassInfo *PI) const { + assert(Resolver && "Pass has not been inserted into a PassManager object!"); assert(PI && "getAnalysis for unregistered pass!"); + // PI *must* appear in AnalysisImpls. Because the number of passes used + // should be a small number, we just do a linear search over a (dense) + // vector. + Pass *ResultPass = 0; + for (unsigned i = 0; ; ++i) { + assert(i != AnalysisImpls.size() && + "getAnalysis*() called on an analysis that we not " + "'required' by pass!"); + if (AnalysisImpls[i].first == PI) { + ResultPass = AnalysisImpls[i].second; + break; + } + } + // Because the AnalysisType may not be a subclass of pass (for // AnalysisGroups), we must use dynamic_cast here to potentially adjust the // return pointer (because the class may multiply inherit, once from pass, // once from AnalysisType). // - AnalysisType *Result = - dynamic_cast(Resolver->getAnalysis(PI)); + AnalysisType *Result = dynamic_cast(ResultPass); assert(Result && "Pass does not implement interface required!"); return *Result; } - template - AnalysisType &getAnalysisID(const PassInfo *PI) const { - assert(Resolver && "Pass has not been inserted into a PassManager object!"); - assert(PI && "getAnalysis for unregistered pass!"); - return *dynamic_cast(Resolver->getAnalysis(PI)); - } - /// getAnalysisToUpdate() - This function is used by subclasses /// to get to the analysis information that might be around that needs to be /// updated. This is different than getAnalysis in that it can fail (ie the -- 2.34.1