Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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