File indexing completed on 2026-05-10 08:43:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_ANALYSIS_ASSUMPTIONCACHE_H
0016 #define LLVM_ANALYSIS_ASSUMPTIONCACHE_H
0017
0018 #include "llvm/ADT/ArrayRef.h"
0019 #include "llvm/ADT/DenseMap.h"
0020 #include "llvm/ADT/DenseMapInfo.h"
0021 #include "llvm/ADT/SmallVector.h"
0022 #include "llvm/IR/PassManager.h"
0023 #include "llvm/IR/ValueHandle.h"
0024 #include "llvm/Pass.h"
0025 #include <memory>
0026
0027 namespace llvm {
0028
0029 class AssumeInst;
0030 class Function;
0031 class raw_ostream;
0032 class TargetTransformInfo;
0033 class Value;
0034
0035
0036
0037
0038
0039
0040
0041
0042 class AssumptionCache {
0043 public:
0044
0045
0046 enum : unsigned { ExprResultIdx = std::numeric_limits<unsigned>::max() };
0047
0048 struct ResultElem {
0049 WeakVH Assume;
0050
0051
0052
0053 unsigned Index;
0054 operator Value *() const { return Assume; }
0055 };
0056
0057 private:
0058
0059
0060
0061 Function &F;
0062
0063 TargetTransformInfo *TTI;
0064
0065
0066
0067 SmallVector<ResultElem, 4> AssumeHandles;
0068
0069 class AffectedValueCallbackVH final : public CallbackVH {
0070 AssumptionCache *AC;
0071
0072 void deleted() override;
0073 void allUsesReplacedWith(Value *) override;
0074
0075 public:
0076 using DMI = DenseMapInfo<Value *>;
0077
0078 AffectedValueCallbackVH(Value *V, AssumptionCache *AC = nullptr)
0079 : CallbackVH(V), AC(AC) {}
0080 };
0081
0082 friend AffectedValueCallbackVH;
0083
0084
0085
0086 using AffectedValuesMap =
0087 DenseMap<AffectedValueCallbackVH, SmallVector<ResultElem, 1>,
0088 AffectedValueCallbackVH::DMI>;
0089 AffectedValuesMap AffectedValues;
0090
0091
0092 SmallVector<ResultElem, 1> &getOrInsertAffectedValues(Value *V);
0093
0094
0095 void transferAffectedValuesInCache(Value *OV, Value *NV);
0096
0097
0098
0099
0100
0101 bool Scanned = false;
0102
0103
0104 void scanFunction();
0105
0106 public:
0107
0108
0109 AssumptionCache(Function &F, TargetTransformInfo *TTI = nullptr)
0110 : F(F), TTI(TTI) {}
0111
0112
0113
0114 bool invalidate(Function &, const PreservedAnalyses &,
0115 FunctionAnalysisManager::Invalidator &) {
0116 return false;
0117 }
0118
0119
0120
0121
0122
0123 void registerAssumption(AssumeInst *CI);
0124
0125
0126
0127 void unregisterAssumption(AssumeInst *CI);
0128
0129
0130
0131 void updateAffectedValues(AssumeInst *CI);
0132
0133
0134
0135
0136 void clear() {
0137 AssumeHandles.clear();
0138 AffectedValues.clear();
0139 Scanned = false;
0140 }
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 MutableArrayRef<ResultElem> assumptions() {
0151 if (!Scanned)
0152 scanFunction();
0153 return AssumeHandles;
0154 }
0155
0156
0157 MutableArrayRef<ResultElem> assumptionsFor(const Value *V) {
0158 if (!Scanned)
0159 scanFunction();
0160
0161 auto AVI = AffectedValues.find_as(const_cast<Value *>(V));
0162 if (AVI == AffectedValues.end())
0163 return MutableArrayRef<ResultElem>();
0164
0165 return AVI->second;
0166 }
0167 };
0168
0169
0170
0171
0172
0173 class AssumptionAnalysis : public AnalysisInfoMixin<AssumptionAnalysis> {
0174 friend AnalysisInfoMixin<AssumptionAnalysis>;
0175
0176 static AnalysisKey Key;
0177
0178 public:
0179 using Result = AssumptionCache;
0180
0181 AssumptionCache run(Function &F, FunctionAnalysisManager &);
0182 };
0183
0184
0185 class AssumptionPrinterPass : public PassInfoMixin<AssumptionPrinterPass> {
0186 raw_ostream &OS;
0187
0188 public:
0189 explicit AssumptionPrinterPass(raw_ostream &OS) : OS(OS) {}
0190
0191 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
0192
0193 static bool isRequired() { return true; }
0194 };
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204 class AssumptionCacheTracker : public ImmutablePass {
0205
0206
0207 class FunctionCallbackVH final : public CallbackVH {
0208 AssumptionCacheTracker *ACT;
0209
0210 void deleted() override;
0211
0212 public:
0213 using DMI = DenseMapInfo<Value *>;
0214
0215 FunctionCallbackVH(Value *V, AssumptionCacheTracker *ACT = nullptr)
0216 : CallbackVH(V), ACT(ACT) {}
0217 };
0218
0219 friend FunctionCallbackVH;
0220
0221 using FunctionCallsMap =
0222 DenseMap<FunctionCallbackVH, std::unique_ptr<AssumptionCache>,
0223 FunctionCallbackVH::DMI>;
0224
0225 FunctionCallsMap AssumptionCaches;
0226
0227 public:
0228
0229
0230
0231
0232 AssumptionCache &getAssumptionCache(Function &F);
0233
0234
0235
0236 AssumptionCache *lookupAssumptionCache(Function &F);
0237
0238 AssumptionCacheTracker();
0239 ~AssumptionCacheTracker() override;
0240
0241 void releaseMemory() override {
0242 verifyAnalysis();
0243 AssumptionCaches.shrink_and_clear();
0244 }
0245
0246 void verifyAnalysis() const override;
0247
0248 bool doFinalization(Module &) override {
0249 verifyAnalysis();
0250 return false;
0251 }
0252
0253 static char ID;
0254 };
0255
0256 template<> struct simplify_type<AssumptionCache::ResultElem> {
0257 using SimpleType = Value *;
0258
0259 static SimpleType getSimplifiedValue(AssumptionCache::ResultElem &Val) {
0260 return Val;
0261 }
0262 };
0263 template<> struct simplify_type<const AssumptionCache::ResultElem> {
0264 using SimpleType = Value *;
0265
0266 static SimpleType getSimplifiedValue(const AssumptionCache::ResultElem &Val) {
0267 return Val;
0268 }
0269 };
0270
0271 }
0272
0273 #endif