Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- PassManagerImpl.h - Pass management infrastructure -------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. /// \file
  9. /// Provides implementations for PassManager and AnalysisManager template
  10. /// methods. These classes should be explicitly instantiated for any IR unit,
  11. /// and files doing the explicit instantiation should include this header.
  12. ///
  13. //===----------------------------------------------------------------------===//
  14.  
  15. #ifndef LLVM_IR_PASSMANAGERIMPL_H
  16. #define LLVM_IR_PASSMANAGERIMPL_H
  17.  
  18. #include "llvm/IR/PassManager.h"
  19.  
  20. namespace llvm {
  21.  
  22. template <typename IRUnitT, typename... ExtraArgTs>
  23. inline AnalysisManager<IRUnitT, ExtraArgTs...>::AnalysisManager() = default;
  24.  
  25. template <typename IRUnitT, typename... ExtraArgTs>
  26. inline AnalysisManager<IRUnitT, ExtraArgTs...>::AnalysisManager(
  27.     AnalysisManager &&) = default;
  28.  
  29. template <typename IRUnitT, typename... ExtraArgTs>
  30. inline AnalysisManager<IRUnitT, ExtraArgTs...> &
  31. AnalysisManager<IRUnitT, ExtraArgTs...>::operator=(AnalysisManager &&) =
  32.     default;
  33.  
  34. template <typename IRUnitT, typename... ExtraArgTs>
  35. inline void
  36. AnalysisManager<IRUnitT, ExtraArgTs...>::clear(IRUnitT &IR,
  37.                                                llvm::StringRef Name) {
  38.   if (auto *PI = getCachedResult<PassInstrumentationAnalysis>(IR))
  39.     PI->runAnalysesCleared(Name);
  40.  
  41.   auto ResultsListI = AnalysisResultLists.find(&IR);
  42.   if (ResultsListI == AnalysisResultLists.end())
  43.     return;
  44.   // Delete the map entries that point into the results list.
  45.   for (auto &IDAndResult : ResultsListI->second)
  46.     AnalysisResults.erase({IDAndResult.first, &IR});
  47.  
  48.   // And actually destroy and erase the results associated with this IR.
  49.   AnalysisResultLists.erase(ResultsListI);
  50. }
  51.  
  52. template <typename IRUnitT, typename... ExtraArgTs>
  53. inline typename AnalysisManager<IRUnitT, ExtraArgTs...>::ResultConceptT &
  54. AnalysisManager<IRUnitT, ExtraArgTs...>::getResultImpl(
  55.     AnalysisKey *ID, IRUnitT &IR, ExtraArgTs... ExtraArgs) {
  56.   typename AnalysisResultMapT::iterator RI;
  57.   bool Inserted;
  58.   std::tie(RI, Inserted) = AnalysisResults.insert(std::make_pair(
  59.       std::make_pair(ID, &IR), typename AnalysisResultListT::iterator()));
  60.  
  61.   // If we don't have a cached result for this function, look up the pass and
  62.   // run it to produce a result, which we then add to the cache.
  63.   if (Inserted) {
  64.     auto &P = this->lookUpPass(ID);
  65.  
  66.     PassInstrumentation PI;
  67.     if (ID != PassInstrumentationAnalysis::ID()) {
  68.       PI = getResult<PassInstrumentationAnalysis>(IR, ExtraArgs...);
  69.       PI.runBeforeAnalysis(P, IR);
  70.     }
  71.  
  72.     AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
  73.     ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...));
  74.  
  75.     PI.runAfterAnalysis(P, IR);
  76.  
  77.     // P.run may have inserted elements into AnalysisResults and invalidated
  78.     // RI.
  79.     RI = AnalysisResults.find({ID, &IR});
  80.     assert(RI != AnalysisResults.end() && "we just inserted it!");
  81.  
  82.     RI->second = std::prev(ResultList.end());
  83.   }
  84.  
  85.   return *RI->second->second;
  86. }
  87.  
  88. template <typename IRUnitT, typename... ExtraArgTs>
  89. inline void AnalysisManager<IRUnitT, ExtraArgTs...>::invalidate(
  90.     IRUnitT &IR, const PreservedAnalyses &PA) {
  91.   // We're done if all analyses on this IR unit are preserved.
  92.   if (PA.allAnalysesInSetPreserved<AllAnalysesOn<IRUnitT>>())
  93.     return;
  94.  
  95.   // Track whether each analysis's result is invalidated in
  96.   // IsResultInvalidated.
  97.   SmallDenseMap<AnalysisKey *, bool, 8> IsResultInvalidated;
  98.   Invalidator Inv(IsResultInvalidated, AnalysisResults);
  99.   AnalysisResultListT &ResultsList = AnalysisResultLists[&IR];
  100.   for (auto &AnalysisResultPair : ResultsList) {
  101.     // This is basically the same thing as Invalidator::invalidate, but we
  102.     // can't call it here because we're operating on the type-erased result.
  103.     // Moreover if we instead called invalidate() directly, it would do an
  104.     // unnecessary look up in ResultsList.
  105.     AnalysisKey *ID = AnalysisResultPair.first;
  106.     auto &Result = *AnalysisResultPair.second;
  107.  
  108.     auto IMapI = IsResultInvalidated.find(ID);
  109.     if (IMapI != IsResultInvalidated.end())
  110.       // This result was already handled via the Invalidator.
  111.       continue;
  112.  
  113.     // Try to invalidate the result, giving it the Invalidator so it can
  114.     // recursively query for any dependencies it has and record the result.
  115.     // Note that we cannot reuse 'IMapI' here or pre-insert the ID, as
  116.     // Result.invalidate may insert things into the map, invalidating our
  117.     // iterator.
  118.     bool Inserted =
  119.         IsResultInvalidated.insert({ID, Result.invalidate(IR, PA, Inv)}).second;
  120.     (void)Inserted;
  121.     assert(Inserted && "Should never have already inserted this ID, likely "
  122.                        "indicates a cycle!");
  123.   }
  124.  
  125.   // Now erase the results that were marked above as invalidated.
  126.   if (!IsResultInvalidated.empty()) {
  127.     for (auto I = ResultsList.begin(), E = ResultsList.end(); I != E;) {
  128.       AnalysisKey *ID = I->first;
  129.       if (!IsResultInvalidated.lookup(ID)) {
  130.         ++I;
  131.         continue;
  132.       }
  133.  
  134.       if (auto *PI = getCachedResult<PassInstrumentationAnalysis>(IR))
  135.         PI->runAnalysisInvalidated(this->lookUpPass(ID), IR);
  136.  
  137.       I = ResultsList.erase(I);
  138.       AnalysisResults.erase({ID, &IR});
  139.     }
  140.   }
  141.  
  142.   if (ResultsList.empty())
  143.     AnalysisResultLists.erase(&IR);
  144. }
  145. } // end namespace llvm
  146.  
  147. #endif // LLVM_IR_PASSMANAGERIMPL_H
  148.