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
//===- llvm/Analysis/AssumptionCache.h - Track @llvm.assume -----*- 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
//
9
// This file contains a pass that keeps track of @llvm.assume intrinsics in
10
// the functions of a module (allowing assumptions within any function to be
11
// found cheaply by other parts of the optimizer).
12
//
13
//===----------------------------------------------------------------------===//
14
 
15
#ifndef LLVM_ANALYSIS_ASSUMPTIONCACHE_H
16
#define LLVM_ANALYSIS_ASSUMPTIONCACHE_H
17
 
18
#include "llvm/ADT/ArrayRef.h"
19
#include "llvm/ADT/DenseMap.h"
20
#include "llvm/ADT/DenseMapInfo.h"
21
#include "llvm/ADT/SmallVector.h"
22
#include "llvm/IR/PassManager.h"
23
#include "llvm/IR/ValueHandle.h"
24
#include "llvm/Pass.h"
25
#include <memory>
26
 
27
namespace llvm {
28
 
29
class CondGuardInst;
30
class Function;
31
class raw_ostream;
32
class TargetTransformInfo;
33
class Value;
34
 
35
/// A cache of \@llvm.assume calls within a function.
36
///
37
/// This cache provides fast lookup of assumptions within a function by caching
38
/// them and amortizing the cost of scanning for them across all queries. Passes
39
/// that create new assumptions are required to call registerAssumption() to
40
/// register any new \@llvm.assume calls that they create. Deletions of
41
/// \@llvm.assume calls do not require special handling.
42
class AssumptionCache {
43
public:
44
  /// Value of ResultElem::Index indicating that the argument to the call of the
45
  /// llvm.assume.
46
  enum : unsigned { ExprResultIdx = std::numeric_limits<unsigned>::max() };
47
 
48
  struct ResultElem {
49
    WeakVH Assume;
50
 
51
    /// contains either ExprResultIdx or the index of the operand bundle
52
    /// containing the knowledge.
53
    unsigned Index;
54
    operator Value *() const { return Assume; }
55
  };
56
 
57
private:
58
  /// The function for which this cache is handling assumptions.
59
  ///
60
  /// We track this to lazily populate our assumptions.
61
  Function &F;
62
 
63
  TargetTransformInfo *TTI;
64
 
65
  /// Vector of weak value handles to calls of the \@llvm.assume
66
  /// intrinsic.
67
  SmallVector<ResultElem, 4> AssumeHandles;
68
 
69
  class AffectedValueCallbackVH final : public CallbackVH {
70
    AssumptionCache *AC;
71
 
72
    void deleted() override;
73
    void allUsesReplacedWith(Value *) override;
74
 
75
  public:
76
    using DMI = DenseMapInfo<Value *>;
77
 
78
    AffectedValueCallbackVH(Value *V, AssumptionCache *AC = nullptr)
79
        : CallbackVH(V), AC(AC) {}
80
  };
81
 
82
  friend AffectedValueCallbackVH;
83
 
84
  /// A map of values about which an assumption might be providing
85
  /// information to the relevant set of assumptions.
86
  using AffectedValuesMap =
87
      DenseMap<AffectedValueCallbackVH, SmallVector<ResultElem, 1>,
88
               AffectedValueCallbackVH::DMI>;
89
  AffectedValuesMap AffectedValues;
90
 
91
  /// Get the vector of assumptions which affect a value from the cache.
92
  SmallVector<ResultElem, 1> &getOrInsertAffectedValues(Value *V);
93
 
94
  /// Move affected values in the cache for OV to be affected values for NV.
95
  void transferAffectedValuesInCache(Value *OV, Value *NV);
96
 
97
  /// Flag tracking whether we have scanned the function yet.
98
  ///
99
  /// We want to be as lazy about this as possible, and so we scan the function
100
  /// at the last moment.
101
  bool Scanned = false;
102
 
103
  /// Scan the function for assumptions and add them to the cache.
104
  void scanFunction();
105
 
106
public:
107
  /// Construct an AssumptionCache from a function by scanning all of
108
  /// its instructions.
109
  AssumptionCache(Function &F, TargetTransformInfo *TTI = nullptr)
110
      : F(F), TTI(TTI) {}
111
 
112
  /// This cache is designed to be self-updating and so it should never be
113
  /// invalidated.
114
  bool invalidate(Function &, const PreservedAnalyses &,
115
                  FunctionAnalysisManager::Invalidator &) {
116
    return false;
117
  }
118
 
119
  /// Add an \@llvm.assume intrinsic to this function's cache.
120
  ///
121
  /// The call passed in must be an instruction within this function and must
122
  /// not already be in the cache.
123
  void registerAssumption(CondGuardInst *CI);
124
 
125
  /// Remove an \@llvm.assume intrinsic from this function's cache if it has
126
  /// been added to the cache earlier.
127
  void unregisterAssumption(CondGuardInst *CI);
128
 
129
  /// Update the cache of values being affected by this assumption (i.e.
130
  /// the values about which this assumption provides information).
131
  void updateAffectedValues(CondGuardInst *CI);
132
 
133
  /// Clear the cache of \@llvm.assume intrinsics for a function.
134
  ///
135
  /// It will be re-scanned the next time it is requested.
136
  void clear() {
137
    AssumeHandles.clear();
138
    AffectedValues.clear();
139
    Scanned = false;
140
  }
141
 
142
  /// Access the list of assumption handles currently tracked for this
143
  /// function.
144
  ///
145
  /// Note that these produce weak handles that may be null. The caller must
146
  /// handle that case.
147
  /// FIXME: We should replace this with pointee_iterator<filter_iterator<...>>
148
  /// when we can write that to filter out the null values. Then caller code
149
  /// will become simpler.
150
  MutableArrayRef<ResultElem> assumptions() {
151
    if (!Scanned)
152
      scanFunction();
153
    return AssumeHandles;
154
  }
155
 
156
  /// Access the list of assumptions which affect this value.
157
  MutableArrayRef<ResultElem> assumptionsFor(const Value *V) {
158
    if (!Scanned)
159
      scanFunction();
160
 
161
    auto AVI = AffectedValues.find_as(const_cast<Value *>(V));
162
    if (AVI == AffectedValues.end())
163
      return MutableArrayRef<ResultElem>();
164
 
165
    return AVI->second;
166
  }
167
};
168
 
169
/// A function analysis which provides an \c AssumptionCache.
170
///
171
/// This analysis is intended for use with the new pass manager and will vend
172
/// assumption caches for a given function.
173
class AssumptionAnalysis : public AnalysisInfoMixin<AssumptionAnalysis> {
174
  friend AnalysisInfoMixin<AssumptionAnalysis>;
175
 
176
  static AnalysisKey Key;
177
 
178
public:
179
  using Result = AssumptionCache;
180
 
181
  AssumptionCache run(Function &F, FunctionAnalysisManager &);
182
};
183
 
184
/// Printer pass for the \c AssumptionAnalysis results.
185
class AssumptionPrinterPass : public PassInfoMixin<AssumptionPrinterPass> {
186
  raw_ostream &OS;
187
 
188
public:
189
  explicit AssumptionPrinterPass(raw_ostream &OS) : OS(OS) {}
190
 
191
  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
192
};
193
 
194
/// An immutable pass that tracks lazily created \c AssumptionCache
195
/// objects.
196
///
197
/// This is essentially a workaround for the legacy pass manager's weaknesses
198
/// which associates each assumption cache with Function and clears it if the
199
/// function is deleted. The nature of the AssumptionCache is that it is not
200
/// invalidated by any changes to the function body and so this is sufficient
201
/// to be conservatively correct.
202
class AssumptionCacheTracker : public ImmutablePass {
203
  /// A callback value handle applied to function objects, which we use to
204
  /// delete our cache of intrinsics for a function when it is deleted.
205
  class FunctionCallbackVH final : public CallbackVH {
206
    AssumptionCacheTracker *ACT;
207
 
208
    void deleted() override;
209
 
210
  public:
211
    using DMI = DenseMapInfo<Value *>;
212
 
213
    FunctionCallbackVH(Value *V, AssumptionCacheTracker *ACT = nullptr)
214
        : CallbackVH(V), ACT(ACT) {}
215
  };
216
 
217
  friend FunctionCallbackVH;
218
 
219
  using FunctionCallsMap =
220
      DenseMap<FunctionCallbackVH, std::unique_ptr<AssumptionCache>,
221
               FunctionCallbackVH::DMI>;
222
 
223
  FunctionCallsMap AssumptionCaches;
224
 
225
public:
226
  /// Get the cached assumptions for a function.
227
  ///
228
  /// If no assumptions are cached, this will scan the function. Otherwise, the
229
  /// existing cache will be returned.
230
  AssumptionCache &getAssumptionCache(Function &F);
231
 
232
  /// Return the cached assumptions for a function if it has already been
233
  /// scanned. Otherwise return nullptr.
234
  AssumptionCache *lookupAssumptionCache(Function &F);
235
 
236
  AssumptionCacheTracker();
237
  ~AssumptionCacheTracker() override;
238
 
239
  void releaseMemory() override {
240
    verifyAnalysis();
241
    AssumptionCaches.shrink_and_clear();
242
  }
243
 
244
  void verifyAnalysis() const override;
245
 
246
  bool doFinalization(Module &) override {
247
    verifyAnalysis();
248
    return false;
249
  }
250
 
251
  static char ID; // Pass identification, replacement for typeid
252
};
253
 
254
template<> struct simplify_type<AssumptionCache::ResultElem> {
255
  using SimpleType = Value *;
256
 
257
  static SimpleType getSimplifiedValue(AssumptionCache::ResultElem &Val) {
258
    return Val;
259
  }
260
};
261
template<> struct simplify_type<const AssumptionCache::ResultElem> {
262
  using SimpleType = /*const*/ Value *;
263
 
264
  static SimpleType getSimplifiedValue(const AssumptionCache::ResultElem &Val) {
265
    return Val;
266
  }
267
};
268
 
269
} // end namespace llvm
270
 
271
#endif // LLVM_ANALYSIS_ASSUMPTIONCACHE_H