diff options
| author | Chris Lattner <sabre@nondot.org> | 2002-08-21 22:17:09 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2002-08-21 22:17:09 +0000 | 
| commit | 6e041bdb12441e0721d33fb90da04c5cd535c898 (patch) | |
| tree | 8c88aea49b9041bdbb78b6254f3f2e792868c3d6 /llvm | |
| parent | 38ba7d5d59865c605283cee26dc9d2e030e14516 (diff) | |
| download | bcm5719-llvm-6e041bdb12441e0721d33fb90da04c5cd535c898.tar.gz bcm5719-llvm-6e041bdb12441e0721d33fb90da04c5cd535c898.zip  | |
 - Implement the new AnalysisGroup feature, neccesary for Value#ing and pointer analysis
llvm-svn: 3426
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/VMCore/Pass.cpp | 125 | ||||
| -rw-r--r-- | llvm/lib/VMCore/PassManagerT.h | 69 | 
2 files changed, 171 insertions, 23 deletions
diff --git a/llvm/lib/VMCore/Pass.cpp b/llvm/lib/VMCore/Pass.cpp index b6f855d017e..3d09d9d7e1c 100644 --- a/llvm/lib/VMCore/Pass.cpp +++ b/llvm/lib/VMCore/Pass.cpp @@ -14,6 +14,7 @@  #include <stdio.h>  #include <sys/resource.h>  #include <sys/unistd.h> +#include <set>  //===----------------------------------------------------------------------===//  //   AnalysisID Class Implementation @@ -395,10 +396,10 @@ void RegisterPassBase::registerPass(PassInfo *PI) {        (*I)->passRegistered(PI);  } -RegisterPassBase::~RegisterPassBase() { +void RegisterPassBase::unregisterPass(PassInfo *PI) {    assert(PassInfoMap && "Pass registered but not in map!");    std::map<TypeInfo, PassInfo*>::iterator I = -    PassInfoMap->find(PIObj->getTypeInfo()); +    PassInfoMap->find(PI->getTypeInfo());    assert(I != PassInfoMap->end() && "Pass registered but not in map!");    // Remove pass from the map... @@ -412,12 +413,128 @@ RegisterPassBase::~RegisterPassBase() {    if (Listeners)      for (std::vector<PassRegistrationListener*>::iterator             I = Listeners->begin(), E = Listeners->end(); I != E; ++I) -      (*I)->passUnregistered(PIObj); +      (*I)->passUnregistered(PI);    // Delete the PassInfo object itself... -  delete PIObj; +  delete PI;  } +//===----------------------------------------------------------------------===// +//                  Analysis Group Implementation Code +//===----------------------------------------------------------------------===// + +struct AnalysisGroupInfo { +  const PassInfo *DefaultImpl; +  std::set<const PassInfo *> Implementations; +  AnalysisGroupInfo() : DefaultImpl(0) {} +}; + +static std::map<const PassInfo *, AnalysisGroupInfo> *AnalysisGroupInfoMap = 0; + +// RegisterAGBase implementation +// +RegisterAGBase::RegisterAGBase(const std::type_info &Interface, +                               const std::type_info *Pass, bool isDefault) +  : ImplementationInfo(0), isDefaultImplementation(isDefault) { + +  std::cerr << "Registering interface: " << Interface.name() << "\n"; + +  InterfaceInfo = const_cast<PassInfo*>(Pass::lookupPassInfo(Interface)); +  if (InterfaceInfo == 0) {   // First reference to Interface, add it now. +    InterfaceInfo =   // Create the new PassInfo for the interface... +      new PassInfo("", "", Interface, PassInfo::AnalysisGroup, 0, 0); +    registerPass(InterfaceInfo); +    PIObj = 0; +  } +  assert(InterfaceInfo->getPassType() == PassInfo::AnalysisGroup && +         "Trying to join an analysis group that is a normal pass!"); + +  if (Pass) { +  std::cerr << "Registering interface impl: " << Pass->name() << "\n"; + +    ImplementationInfo = Pass::lookupPassInfo(*Pass); +    assert(ImplementationInfo && +           "Must register pass before adding to AnalysisGroup!"); + +    // Lazily allocate to avoid nasty initialization order dependencies +    if (AnalysisGroupInfoMap == 0) +      AnalysisGroupInfoMap = new std::map<const PassInfo *,AnalysisGroupInfo>(); + +    AnalysisGroupInfo &AGI = (*AnalysisGroupInfoMap)[InterfaceInfo]; +    assert(AGI.Implementations.count(ImplementationInfo) == 0 && +           "Cannot add a pass to the same analysis group more than once!"); +    AGI.Implementations.insert(ImplementationInfo); +    if (isDefault) { +      assert(AGI.DefaultImpl == 0 && InterfaceInfo->getNormalCtor() == 0 && +             "Default implementation for analysis group already specified!"); +      assert(ImplementationInfo->getNormalCtor() && +           "Cannot specify pass as default if it does not have a default ctor"); +      AGI.DefaultImpl = ImplementationInfo; +      InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor()); +    } +  } +} + +void RegisterAGBase::setGroupName(const char *Name) { +  assert(InterfaceInfo->getPassName()[0] == 0 && "Interface Name already set!"); +  InterfaceInfo->setPassName(Name); +} + +RegisterAGBase::~RegisterAGBase() { +  if (ImplementationInfo) { +    assert(AnalysisGroupInfoMap && "Inserted into map, but map doesn't exist?"); +    AnalysisGroupInfo &AGI = (*AnalysisGroupInfoMap)[InterfaceInfo]; + +    assert(AGI.Implementations.count(ImplementationInfo) && +           "Pass not a member of analysis group?"); + +    if (AGI.DefaultImpl == ImplementationInfo) +      AGI.DefaultImpl = 0; +     +    AGI.Implementations.erase(ImplementationInfo); + +    // Last member of this analysis group? Unregister PassInfo, delete map entry +    if (AGI.Implementations.empty()) { +      assert(AGI.DefaultImpl == 0 && +             "Default implementation didn't unregister?"); +      AnalysisGroupInfoMap->erase(InterfaceInfo); +      if (AnalysisGroupInfoMap->empty()) {  // Delete map if empty +        delete AnalysisGroupInfoMap; +        AnalysisGroupInfoMap = 0; +      } + +      unregisterPass(InterfaceInfo); +    } +  } +} + + +// findAnalysisGroupMember - Return an iterator pointing to one of the elements +// of Map if there is a pass in Map that is a member of the analysis group for +// the specified AnalysisGroupID. +// +static std::map<const PassInfo*, Pass*>::const_iterator +findAnalysisGroupMember(const PassInfo *AnalysisGroupID, +                        const std::map<const PassInfo*, Pass*> &Map) { +  assert(AnalysisGroupID->getPassType() == PassInfo::AnalysisGroup && +         "AnalysisGroupID is not an analysis group!"); +  assert(AnalysisGroupInfoMap && AnalysisGroupInfoMap->count(AnalysisGroupID) && +         "Analysis Group does not have any registered members!"); + +  // Get the set of all known implementations of this analysis group... +  std::set<const PassInfo *> &Impls =  +    (*AnalysisGroupInfoMap)[AnalysisGroupID].Implementations; + +  // Scan over available passes, checking to see if any is a valid analysis +  for (std::map<const PassInfo*, Pass*>::const_iterator I = Map.begin(), +         E = Map.end(); I != E; ++I) +    if (Impls.count(I->first))  // This is a valid analysis, return it. +      return I; + +  return Map.end();  // Nothing of use found. +} + +  //===----------------------------------------------------------------------===// diff --git a/llvm/lib/VMCore/PassManagerT.h b/llvm/lib/VMCore/PassManagerT.h index 9f34f15cca5..4e0d6b24bf3 100644 --- a/llvm/lib/VMCore/PassManagerT.h +++ b/llvm/lib/VMCore/PassManagerT.h @@ -106,6 +106,19 @@ public:    void passEnded(Pass *P);  }; +//===----------------------------------------------------------------------===// +// Forward declarations of global functions defined in Pass.cpp.  These are +// defined to be static functions because this header is *ONLY* included by +// Pass.cpp. +// + +// findAnalysisGroupMember - Return an iterator pointing to one of the elements +// of Map if there is a pass in Map that is a member of the analysis group for +// the specified AnalysisGroupID. +// +static std::map<const PassInfo*, Pass*>::const_iterator +findAnalysisGroupMember(const PassInfo *AnalysisGroupID, +                        const std::map<const PassInfo*, Pass*> &Map);  //===----------------------------------------------------------------------===// @@ -269,24 +282,36 @@ public:      }    } -  Pass *getAnalysisOrNullDown(AnalysisID ID) const { -    std::map<AnalysisID, Pass*>::const_iterator I = CurrentAnalyses.find(ID); -    if (I == CurrentAnalyses.end()) { -      if (Batcher) -        return ((AnalysisResolver*)Batcher)->getAnalysisOrNullDown(ID); -      return 0; +  Pass *getAnalysisOrNullDown(const PassInfo *ID) const { +    std::map<const PassInfo*, Pass*>::const_iterator I; + +    if (ID->getPassType() == PassInfo::AnalysisGroup) { +      I = findAnalysisGroupMember(ID, CurrentAnalyses); +    } else { +      I = CurrentAnalyses.find(ID);      } -    return I->second; + +    if (I != CurrentAnalyses.end()) +      return I->second;  // Found it. + +    if (Batcher) +      return ((AnalysisResolver*)Batcher)->getAnalysisOrNullDown(ID); +    return 0;    } -  Pass *getAnalysisOrNullUp(AnalysisID ID) const { -    std::map<AnalysisID, Pass*>::const_iterator I = CurrentAnalyses.find(ID); -    if (I == CurrentAnalyses.end()) { -      if (Parent) -        return Parent->getAnalysisOrNullUp(ID); -      return 0; +  Pass *getAnalysisOrNullUp(const PassInfo *ID) const { +    std::map<AnalysisID, Pass*>::const_iterator I; +    if (ID->getPassType() == PassInfo::AnalysisGroup) { +      I = findAnalysisGroupMember(ID, CurrentAnalyses); +    } else { +      I = CurrentAnalyses.find(ID);      } -    return I->second; +    if (I != CurrentAnalyses.end()) +      return I->second;  // Found it. + +    if (Parent)          // Try scanning... +      return Parent->getAnalysisOrNullUp(ID); +    return 0;    }    // {start/end}Pass - Called when a pass is started, it just propogates @@ -308,8 +333,15 @@ public:    // make sure that analyses are not free'd before we have to use    // them...    // -  void markPassUsed(AnalysisID P, Pass *User) { -    std::map<AnalysisID, Pass*>::iterator I = CurrentAnalyses.find(P); +  void markPassUsed(const PassInfo *P, Pass *User) { +    std::map<const PassInfo *, Pass*>::const_iterator I; + +    if (P->getPassType() == PassInfo::AnalysisGroup) { +      I = findAnalysisGroupMember(P, CurrentAnalyses); +    } else { +      I = CurrentAnalyses.find(P); +    } +      if (I != CurrentAnalyses.end()) {        LastUseOf[I->second] = User;    // Local pass, extend the lifetime      } else { @@ -318,8 +350,7 @@ public:        // parent that we (the passmanager) are using the analysis so that it        // frees the analysis AFTER this pass manager runs.        // -      assert(Parent != 0 && "Pass available but not found! " -             "Did your analysis pass 'Provide' itself?"); +      assert(Parent != 0 && "Pass available but not found!");        Parent->markPassUsed(P, this);      }    } @@ -336,7 +367,7 @@ public:      return Passes[N];    } -  // add - Add a pass to the queue of passes to run.  This passes ownership of +  // add - Add a pass to the queue of passes to run.  This gives ownership of    // the Pass to the PassManager.  When the PassManager is destroyed, the pass    // will be destroyed as well, so there is no need to delete the pass.  This    // implies that all passes MUST be new'd.  | 

