[llvm] r227299 - [LPM] A targeted but somewhat horrible fix to the legacy pass manager's

Chandler Carruth chandlerc at gmail.com
Wed Jan 28 02:01:03 PST 2015


Hans, here is the second patch I'd liked pulled into 3.6 to potentially
address some compile time problems.

On Wed, Jan 28, 2015 at 1:47 AM, Chandler Carruth <chandlerc at gmail.com>
wrote:

> Author: chandlerc
> Date: Wed Jan 28 03:47:21 2015
> New Revision: 227299
>
> URL: http://llvm.org/viewvc/llvm-project?rev=227299&view=rev
> Log:
> [LPM] A targeted but somewhat horrible fix to the legacy pass manager's
> querying of the pass registry.
>
> The pass manager relies on the static registry of PassInfo objects to
> perform all manner of its functionality. I don't understand why it does
> much of this. My very vague understanding is that this registry is
> touched both during static initialization *and* while each pass is being
> constructed. As a consequence it is hard to make accessing it not
> require a acquiring some lock. This lock ends up in the hot path of
> setting up, tearing down, and invaliditing analyses in the legacy pass
> manager.
>
> On most systems you can observe this as a non-trivial % of the time
> spent in 'ninja check-llvm'. However, I haven't really seen it be more
> than 1% in extreme cases of compiling more real-world software,
> including LTO.
>
> Unfortunately, some of the GPU JITs are seeing this taking essentially
> all of their time because they have very small IR running through
> a small pass pipeline very many times (at least, this is the vague
> understanding I have of it).
>
> This patch tries to minimize the cost of looking up PassInfo objects by
> leveraging the fact that the objects themselves are immutable and they
> are allocated separately on the heap and so don't have their address
> change. It also requires a change I made the last time I tried to debug
> this problem which removed the ability to de-register a pass from the
> registry. This patch creates a single access path to these objects
> inside the PMTopLevelManager which memoizes the result of querying the
> registry. This is somewhat gross as I don't really know if
> PMTopLevelManager is the *right* place to put it, and I dislike using
> a mutable member to memoize things, but it seems to work.
>
> For long-lived pass managers this should completely eliminate
> the cost of acquiring locks to look into the pass registry once the
> memoized cache is warm. For 'ninja check' I measured about 1.5%
> reduction in CPU time and in total time on a machine with 32 hardware
> threads. For normal compilation, I don't know how much this will help,
> sadly. We will still pay the cost while we populate the memoized cache.
> I don't think it will hurt though, and for LTO or compiles with many
> small functions it should still be a win. However, for tight loops
> around a pass manager with many passes and small modules, this will help
> tremendously. On the AArch64 backend I saw nearly 50% reductions in time
> to complete 2000 cycles of spinning up and tearing down the pipeline.
> Measurements from Owen of an actual long-lived pass manager show more
> along the lines of 10% improvements.
>
> Differential Revision: http://reviews.llvm.org/D7213
>
> Modified:
>     llvm/trunk/include/llvm/IR/LegacyPassManagers.h
>     llvm/trunk/lib/IR/LegacyPassManager.cpp
>
> Modified: llvm/trunk/include/llvm/IR/LegacyPassManagers.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/LegacyPassManagers.h?rev=227299&r1=227298&r2=227299&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/LegacyPassManagers.h (original)
> +++ llvm/trunk/include/llvm/IR/LegacyPassManagers.h Wed Jan 28 03:47:21
> 2015
> @@ -195,6 +195,9 @@ public:
>    /// then return NULL.
>    Pass *findAnalysisPass(AnalysisID AID);
>
> +  /// Retrieve the PassInfo for an analysis.
> +  const PassInfo *findAnalysisPassInfo(AnalysisID AID) const;
> +
>    /// Find analysis usage information for the pass P.
>    AnalysisUsage *findAnalysisUsage(Pass *P);
>
> @@ -251,6 +254,12 @@ private:
>    SmallVector<ImmutablePass *, 16> ImmutablePasses;
>
>    DenseMap<Pass *, AnalysisUsage *> AnUsageMap;
> +
> +  /// Collection of PassInfo objects found via analysis IDs and in this
> top
> +  /// level manager. This is used to memoize queries to the pass registry.
> +  /// FIXME: This is an egregious hack because querying the pass registry
> is
> +  /// either slow or racy.
> +  mutable DenseMap<AnalysisID, const PassInfo *> AnalysisPassInfos;
>  };
>
>
>
> Modified: llvm/trunk/lib/IR/LegacyPassManager.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LegacyPassManager.cpp?rev=227299&r1=227298&r2=227299&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/IR/LegacyPassManager.cpp (original)
> +++ llvm/trunk/lib/IR/LegacyPassManager.cpp Wed Jan 28 03:47:21 2015
> @@ -600,8 +600,7 @@ void PMTopLevelManager::schedulePass(Pas
>    // If P is an analysis pass and it is available then do not
>    // generate the analysis again. Stale analysis info should not be
>    // available at this point.
> -  const PassInfo *PI =
> -    PassRegistry::getPassRegistry()->getPassInfo(P->getPassID());
> +  const PassInfo *PI = findAnalysisPassInfo(P->getPassID());
>    if (PI && PI->isAnalysis() && findAnalysisPass(P->getPassID())) {
>      delete P;
>      return;
> @@ -619,7 +618,7 @@ void PMTopLevelManager::schedulePass(Pas
>
>        Pass *AnalysisPass = findAnalysisPass(*I);
>        if (!AnalysisPass) {
> -        const PassInfo *PI =
> PassRegistry::getPassRegistry()->getPassInfo(*I);
> +        const PassInfo *PI = findAnalysisPassInfo(*I);
>
>          if (!PI) {
>            // Pass P is not in the global PassRegistry
> @@ -716,8 +715,7 @@ Pass *PMTopLevelManager::findAnalysisPas
>        return *I;
>
>      // If Pass not found then check the interfaces implemented by
> Immutable Pass
> -    const PassInfo *PassInf =
> -      PassRegistry::getPassRegistry()->getPassInfo(PI);
> +    const PassInfo *PassInf = findAnalysisPassInfo(PI);
>      assert(PassInf && "Expected all immutable passes to be initialized");
>      const std::vector<const PassInfo*> &ImmPI =
>        PassInf->getInterfacesImplemented();
> @@ -731,6 +729,17 @@ Pass *PMTopLevelManager::findAnalysisPas
>    return nullptr;
>  }
>
> +const PassInfo *PMTopLevelManager::findAnalysisPassInfo(AnalysisID AID)
> const {
> +  const PassInfo *&PI = AnalysisPassInfos[AID];
> +  if (!PI)
> +    PI = PassRegistry::getPassRegistry()->getPassInfo(AID);
> +  else
> +    assert(PI == PassRegistry::getPassRegistry()->getPassInfo(AID) &&
> +           "The pass info pointer changed for an analysis ID!");
> +
> +  return PI;
> +}
> +
>  // Print passes managed by this top level manager.
>  void PMTopLevelManager::dumpPasses() const {
>
> @@ -759,8 +768,7 @@ void PMTopLevelManager::dumpArguments()
>    dbgs() << "Pass Arguments: ";
>    for (SmallVectorImpl<ImmutablePass *>::const_iterator I =
>         ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I)
> -    if (const PassInfo *PI =
> -        PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID())) {
> +    if (const PassInfo *PI = findAnalysisPassInfo((*I)->getPassID())) {
>        assert(PI && "Expected all immutable passes to be initialized");
>        if (!PI->isAnalysisGroup())
>          dbgs() << " -" << PI->getPassArgument();
> @@ -824,7 +832,7 @@ void PMDataManager::recordAvailableAnaly
>
>    // This pass is the current implementation of all of the interfaces it
>    // implements as well.
> -  const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(PI);
> +  const PassInfo *PInf = TPM->findAnalysisPassInfo(PI);
>    if (!PInf) return;
>    const std::vector<const PassInfo*> &II =
> PInf->getInterfacesImplemented();
>    for (unsigned i = 0, e = II.size(); i != e; ++i)
> @@ -957,7 +965,7 @@ void PMDataManager::freePass(Pass *P, St
>    }
>
>    AnalysisID PI = P->getPassID();
> -  if (const PassInfo *PInf =
> PassRegistry::getPassRegistry()->getPassInfo(PI)) {
> +  if (const PassInfo *PInf = TPM->findAnalysisPassInfo(PI)) {
>      // Remove the pass itself (if it is not already removed).
>      AvailableAnalysis.erase(PI);
>
> @@ -1037,7 +1045,7 @@ void PMDataManager::add(Pass *P, bool Pr
>    for (SmallVectorImpl<AnalysisID>::iterator
>           I = ReqAnalysisNotAvailable.begin(),
>           E = ReqAnalysisNotAvailable.end() ;I != E; ++I) {
> -    const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I);
> +    const PassInfo *PI = TPM->findAnalysisPassInfo(*I);
>      Pass *AnalysisPass = PI->createPass();
>      this->addLowerLevelRequiredPass(P, AnalysisPass);
>    }
> @@ -1142,7 +1150,7 @@ void PMDataManager::dumpPassArguments()
>        PMD->dumpPassArguments();
>      else
>        if (const PassInfo *PI =
> -
> PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID()))
> +            TPM->findAnalysisPassInfo((*I)->getPassID()))
>          if (!PI->isAnalysisGroup())
>            dbgs() << " -" << PI->getPassArgument();
>    }
> @@ -1218,7 +1226,7 @@ void PMDataManager::dumpAnalysisUsage(St
>    dbgs() << (const void*)P << std::string(getDepth()*2+3, ' ') << Msg <<
> " Analyses:";
>    for (unsigned i = 0; i != Set.size(); ++i) {
>      if (i) dbgs() << ',';
> -    const PassInfo *PInf =
> PassRegistry::getPassRegistry()->getPassInfo(Set[i]);
> +    const PassInfo *PInf = TPM->findAnalysisPassInfo(Set[i]);
>      if (!PInf) {
>        // Some preserved passes, such as AliasAnalysis, may not be
> initialized by
>        // all drivers.
> @@ -1658,8 +1666,8 @@ void MPPassManager::addLowerLevelRequire
>
>      OnTheFlyManagers[P] = FPP;
>    }
> -  const PassInfo * RequiredPassPI =
> -
> PassRegistry::getPassRegistry()->getPassInfo(RequiredPass->getPassID());
> +  const PassInfo *RequiredPassPI =
> +      TPM->findAnalysisPassInfo(RequiredPass->getPassID());
>
>    Pass *FoundPass = nullptr;
>    if (RequiredPassPI && RequiredPassPI->isAnalysis()) {
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150128/ed542abb/attachment.html>


More information about the llvm-commits mailing list