|
|
|||
File indexing completed on 2026-05-10 08:43:14
0001 //===- llvm/Analysis/MemoryDependenceAnalysis.h - Memory Deps ---*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 // 0009 // This file defines the MemoryDependenceAnalysis analysis pass. 0010 // 0011 //===----------------------------------------------------------------------===// 0012 0013 #ifndef LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H 0014 #define LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H 0015 0016 #include "llvm/ADT/DenseMap.h" 0017 #include "llvm/ADT/PointerEmbeddedInt.h" 0018 #include "llvm/ADT/PointerIntPair.h" 0019 #include "llvm/ADT/PointerSumType.h" 0020 #include "llvm/ADT/SmallPtrSet.h" 0021 #include "llvm/Analysis/AliasAnalysis.h" 0022 #include "llvm/Analysis/MemoryLocation.h" 0023 #include "llvm/IR/PassManager.h" 0024 #include "llvm/IR/PredIteratorCache.h" 0025 #include "llvm/IR/ValueHandle.h" 0026 #include "llvm/Pass.h" 0027 #include <optional> 0028 0029 namespace llvm { 0030 0031 class AssumptionCache; 0032 class DominatorTree; 0033 class PHITransAddr; 0034 0035 /// A memory dependence query can return one of three different answers. 0036 class MemDepResult { 0037 enum DepType { 0038 /// Clients of MemDep never see this. 0039 /// 0040 /// Entries with this marker occur in a LocalDeps map or NonLocalDeps map 0041 /// when the instruction they previously referenced was removed from 0042 /// MemDep. In either case, the entry may include an instruction pointer. 0043 /// If so, the pointer is an instruction in the block where scanning can 0044 /// start from, saving some work. 0045 /// 0046 /// In a default-constructed MemDepResult object, the type will be Invalid 0047 /// and the instruction pointer will be null. 0048 Invalid = 0, 0049 0050 /// This is a dependence on the specified instruction which clobbers the 0051 /// desired value. The pointer member of the MemDepResult pair holds the 0052 /// instruction that clobbers the memory. For example, this occurs when we 0053 /// see a may-aliased store to the memory location we care about. 0054 /// 0055 /// There are several cases that may be interesting here: 0056 /// 1. Loads are clobbered by may-alias stores. 0057 /// 2. Loads are considered clobbered by partially-aliased loads. The 0058 /// client may choose to analyze deeper into these cases. 0059 Clobber, 0060 0061 /// This is a dependence on the specified instruction which defines or 0062 /// produces the desired memory location. The pointer member of the 0063 /// MemDepResult pair holds the instruction that defines the memory. 0064 /// 0065 /// Cases of interest: 0066 /// 1. This could be a load or store for dependence queries on 0067 /// load/store. The value loaded or stored is the produced value. 0068 /// Note that the pointer operand may be different than that of the 0069 /// queried pointer due to must aliases and phi translation. Note 0070 /// that the def may not be the same type as the query, the pointers 0071 /// may just be must aliases. 0072 /// 2. For loads and stores, this could be an allocation instruction. In 0073 /// this case, the load is loading an undef value or a store is the 0074 /// first store to (that part of) the allocation. 0075 /// 3. Dependence queries on calls return Def only when they are readonly 0076 /// calls or memory use intrinsics with identical callees and no 0077 /// intervening clobbers. No validation is done that the operands to 0078 /// the calls are the same. 0079 /// 4. For loads and stores, this could be a select instruction that 0080 /// defines pointer to this memory location. In this case, users can 0081 /// find non-clobbered Defs for both select values that are reaching 0082 // the desired memory location (there is still a guarantee that there 0083 // are no clobbers between analyzed memory location and select). 0084 Def, 0085 0086 /// This marker indicates that the query has no known dependency in the 0087 /// specified block. 0088 /// 0089 /// More detailed state info is encoded in the upper part of the pair (i.e. 0090 /// the Instruction*) 0091 Other 0092 }; 0093 0094 /// If DepType is "Other", the upper part of the sum type is an encoding of 0095 /// the following more detailed type information. 0096 enum OtherType { 0097 /// This marker indicates that the query has no dependency in the specified 0098 /// block. 0099 /// 0100 /// To find out more, the client should query other predecessor blocks. 0101 NonLocal = 1, 0102 /// This marker indicates that the query has no dependency in the specified 0103 /// function. 0104 NonFuncLocal, 0105 /// This marker indicates that the query dependency is unknown. 0106 Unknown 0107 }; 0108 0109 using ValueTy = PointerSumType< 0110 DepType, PointerSumTypeMember<Invalid, Instruction *>, 0111 PointerSumTypeMember<Clobber, Instruction *>, 0112 PointerSumTypeMember<Def, Instruction *>, 0113 PointerSumTypeMember<Other, PointerEmbeddedInt<OtherType, 3>>>; 0114 ValueTy Value; 0115 0116 explicit MemDepResult(ValueTy V) : Value(V) {} 0117 0118 public: 0119 MemDepResult() = default; 0120 0121 /// get methods: These are static ctor methods for creating various 0122 /// MemDepResult kinds. 0123 static MemDepResult getDef(Instruction *Inst) { 0124 assert(Inst && "Def requires inst"); 0125 return MemDepResult(ValueTy::create<Def>(Inst)); 0126 } 0127 static MemDepResult getClobber(Instruction *Inst) { 0128 assert(Inst && "Clobber requires inst"); 0129 return MemDepResult(ValueTy::create<Clobber>(Inst)); 0130 } 0131 static MemDepResult getNonLocal() { 0132 return MemDepResult(ValueTy::create<Other>(NonLocal)); 0133 } 0134 static MemDepResult getNonFuncLocal() { 0135 return MemDepResult(ValueTy::create<Other>(NonFuncLocal)); 0136 } 0137 static MemDepResult getUnknown() { 0138 return MemDepResult(ValueTy::create<Other>(Unknown)); 0139 } 0140 0141 /// Tests if this MemDepResult represents a query that is an instruction 0142 /// clobber dependency. 0143 bool isClobber() const { return Value.is<Clobber>(); } 0144 0145 /// Tests if this MemDepResult represents a query that is an instruction 0146 /// definition dependency. 0147 bool isDef() const { return Value.is<Def>(); } 0148 0149 /// Tests if this MemDepResult represents a valid local query (Clobber/Def). 0150 bool isLocal() const { return isClobber() || isDef(); } 0151 0152 /// Tests if this MemDepResult represents a query that is transparent to the 0153 /// start of the block, but where a non-local hasn't been done. 0154 bool isNonLocal() const { 0155 return Value.is<Other>() && Value.cast<Other>() == NonLocal; 0156 } 0157 0158 /// Tests if this MemDepResult represents a query that is transparent to the 0159 /// start of the function. 0160 bool isNonFuncLocal() const { 0161 return Value.is<Other>() && Value.cast<Other>() == NonFuncLocal; 0162 } 0163 0164 /// Tests if this MemDepResult represents a query which cannot and/or will 0165 /// not be computed. 0166 bool isUnknown() const { 0167 return Value.is<Other>() && Value.cast<Other>() == Unknown; 0168 } 0169 0170 /// If this is a normal dependency, returns the instruction that is depended 0171 /// on. Otherwise, returns null. 0172 Instruction *getInst() const { 0173 switch (Value.getTag()) { 0174 case Invalid: 0175 return Value.cast<Invalid>(); 0176 case Clobber: 0177 return Value.cast<Clobber>(); 0178 case Def: 0179 return Value.cast<Def>(); 0180 case Other: 0181 return nullptr; 0182 } 0183 llvm_unreachable("Unknown discriminant!"); 0184 } 0185 0186 bool operator==(const MemDepResult &M) const { return Value == M.Value; } 0187 bool operator!=(const MemDepResult &M) const { return Value != M.Value; } 0188 bool operator<(const MemDepResult &M) const { return Value < M.Value; } 0189 bool operator>(const MemDepResult &M) const { return Value > M.Value; } 0190 0191 private: 0192 friend class MemoryDependenceResults; 0193 0194 /// Tests if this is a MemDepResult in its dirty/invalid. state. 0195 bool isDirty() const { return Value.is<Invalid>(); } 0196 0197 static MemDepResult getDirty(Instruction *Inst) { 0198 return MemDepResult(ValueTy::create<Invalid>(Inst)); 0199 } 0200 }; 0201 0202 /// This is an entry in the NonLocalDepInfo cache. 0203 /// 0204 /// For each BasicBlock (the BB entry) it keeps a MemDepResult. 0205 class NonLocalDepEntry { 0206 BasicBlock *BB; 0207 MemDepResult Result; 0208 0209 public: 0210 NonLocalDepEntry(BasicBlock *BB, MemDepResult Result) 0211 : BB(BB), Result(Result) {} 0212 0213 // This is used for searches. 0214 NonLocalDepEntry(BasicBlock *BB) : BB(BB) {} 0215 0216 // BB is the sort key, it can't be changed. 0217 BasicBlock *getBB() const { return BB; } 0218 0219 void setResult(const MemDepResult &R) { Result = R; } 0220 0221 const MemDepResult &getResult() const { return Result; } 0222 0223 bool operator<(const NonLocalDepEntry &RHS) const { return BB < RHS.BB; } 0224 }; 0225 0226 /// This is a result from a NonLocal dependence query. 0227 /// 0228 /// For each BasicBlock (the BB entry) it keeps a MemDepResult and the 0229 /// (potentially phi translated) address that was live in the block. 0230 class NonLocalDepResult { 0231 NonLocalDepEntry Entry; 0232 Value *Address; 0233 0234 public: 0235 NonLocalDepResult(BasicBlock *BB, MemDepResult Result, Value *Address) 0236 : Entry(BB, Result), Address(Address) {} 0237 0238 // BB is the sort key, it can't be changed. 0239 BasicBlock *getBB() const { return Entry.getBB(); } 0240 0241 void setResult(const MemDepResult &R, Value *Addr) { 0242 Entry.setResult(R); 0243 Address = Addr; 0244 } 0245 0246 const MemDepResult &getResult() const { return Entry.getResult(); } 0247 0248 /// Returns the address of this pointer in this block. 0249 /// 0250 /// This can be different than the address queried for the non-local result 0251 /// because of phi translation. This returns null if the address was not 0252 /// available in a block (i.e. because phi translation failed) or if this is 0253 /// a cached result and that address was deleted. 0254 /// 0255 /// The address is always null for a non-local 'call' dependence. 0256 Value *getAddress() const { return Address; } 0257 }; 0258 0259 /// Provides a lazy, caching interface for making common memory aliasing 0260 /// information queries, backed by LLVM's alias analysis passes. 0261 /// 0262 /// The dependency information returned is somewhat unusual, but is pragmatic. 0263 /// If queried about a store or call that might modify memory, the analysis 0264 /// will return the instruction[s] that may either load from that memory or 0265 /// store to it. If queried with a load or call that can never modify memory, 0266 /// the analysis will return calls and stores that might modify the pointer, 0267 /// but generally does not return loads unless a) they are volatile, or 0268 /// b) they load from *must-aliased* pointers. Returning a dependence on 0269 /// must-alias'd pointers instead of all pointers interacts well with the 0270 /// internal caching mechanism. 0271 class MemoryDependenceResults { 0272 // A map from instructions to their dependency. 0273 using LocalDepMapType = DenseMap<Instruction *, MemDepResult>; 0274 LocalDepMapType LocalDeps; 0275 0276 public: 0277 using NonLocalDepInfo = std::vector<NonLocalDepEntry>; 0278 0279 private: 0280 /// A pair<Value*, bool> where the bool is true if the dependence is a read 0281 /// only dependence, false if read/write. 0282 using ValueIsLoadPair = PointerIntPair<const Value *, 1, bool>; 0283 0284 /// This pair is used when caching information for a block. 0285 /// 0286 /// If the pointer is null, the cache value is not a full query that starts 0287 /// at the specified block. If non-null, the bool indicates whether or not 0288 /// the contents of the block was skipped. 0289 using BBSkipFirstBlockPair = PointerIntPair<BasicBlock *, 1, bool>; 0290 0291 /// This record is the information kept for each (value, is load) pair. 0292 struct NonLocalPointerInfo { 0293 /// The pair of the block and the skip-first-block flag. 0294 BBSkipFirstBlockPair Pair; 0295 /// The results of the query for each relevant block. 0296 NonLocalDepInfo NonLocalDeps; 0297 /// The maximum size of the dereferences of the pointer. 0298 /// 0299 /// May be UnknownSize if the sizes are unknown. 0300 LocationSize Size = LocationSize::afterPointer(); 0301 /// The AA tags associated with dereferences of the pointer. 0302 /// 0303 /// The members may be null if there are no tags or conflicting tags. 0304 AAMDNodes AATags; 0305 0306 NonLocalPointerInfo() = default; 0307 }; 0308 0309 /// Cache storing single nonlocal def for the instruction. 0310 /// It is set when nonlocal def would be found in function returning only 0311 /// local dependencies. 0312 DenseMap<AssertingVH<const Value>, NonLocalDepResult> NonLocalDefsCache; 0313 using ReverseNonLocalDefsCacheTy = 0314 DenseMap<Instruction *, SmallPtrSet<const Value*, 4>>; 0315 ReverseNonLocalDefsCacheTy ReverseNonLocalDefsCache; 0316 0317 /// This map stores the cached results of doing a pointer lookup at the 0318 /// bottom of a block. 0319 /// 0320 /// The key of this map is the pointer+isload bit, the value is a list of 0321 /// <bb->result> mappings. 0322 using CachedNonLocalPointerInfo = 0323 DenseMap<ValueIsLoadPair, NonLocalPointerInfo>; 0324 CachedNonLocalPointerInfo NonLocalPointerDeps; 0325 0326 // A map from instructions to their non-local pointer dependencies. 0327 using ReverseNonLocalPtrDepTy = 0328 DenseMap<Instruction *, SmallPtrSet<ValueIsLoadPair, 4>>; 0329 ReverseNonLocalPtrDepTy ReverseNonLocalPtrDeps; 0330 0331 /// This is the instruction we keep for each cached access that we have for 0332 /// an instruction. 0333 /// 0334 /// The pointer is an owning pointer and the bool indicates whether we have 0335 /// any dirty bits in the set. 0336 using PerInstNLInfo = std::pair<NonLocalDepInfo, bool>; 0337 0338 // A map from instructions to their non-local dependencies. 0339 using NonLocalDepMapType = DenseMap<Instruction *, PerInstNLInfo>; 0340 0341 NonLocalDepMapType NonLocalDepsMap; 0342 0343 // A reverse mapping from dependencies to the dependees. This is 0344 // used when removing instructions to keep the cache coherent. 0345 using ReverseDepMapType = 0346 DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>>; 0347 ReverseDepMapType ReverseLocalDeps; 0348 0349 // A reverse mapping from dependencies to the non-local dependees. 0350 ReverseDepMapType ReverseNonLocalDeps; 0351 0352 /// Current AA implementation, just a cache. 0353 AAResults &AA; 0354 AssumptionCache &AC; 0355 const TargetLibraryInfo &TLI; 0356 DominatorTree &DT; 0357 PredIteratorCache PredCache; 0358 EarliestEscapeAnalysis EEA; 0359 0360 unsigned DefaultBlockScanLimit; 0361 0362 /// Offsets to dependant clobber loads. 0363 using ClobberOffsetsMapType = DenseMap<LoadInst *, int32_t>; 0364 ClobberOffsetsMapType ClobberOffsets; 0365 0366 public: 0367 MemoryDependenceResults(AAResults &AA, AssumptionCache &AC, 0368 const TargetLibraryInfo &TLI, DominatorTree &DT, 0369 unsigned DefaultBlockScanLimit) 0370 : AA(AA), AC(AC), TLI(TLI), DT(DT), EEA(DT), 0371 DefaultBlockScanLimit(DefaultBlockScanLimit) {} 0372 0373 /// Handle invalidation in the new PM. 0374 bool invalidate(Function &F, const PreservedAnalyses &PA, 0375 FunctionAnalysisManager::Invalidator &Inv); 0376 0377 /// Some methods limit the number of instructions they will examine. 0378 /// The return value of this method is the default limit that will be 0379 /// used if no limit is explicitly passed in. 0380 unsigned getDefaultBlockScanLimit() const; 0381 0382 /// Returns the instruction on which a memory operation depends. 0383 /// 0384 /// See the class comment for more details. It is illegal to call this on 0385 /// non-memory instructions. 0386 MemDepResult getDependency(Instruction *QueryInst); 0387 0388 /// Perform a full dependency query for the specified call, returning the set 0389 /// of blocks that the value is potentially live across. 0390 /// 0391 /// The returned set of results will include a "NonLocal" result for all 0392 /// blocks where the value is live across. 0393 /// 0394 /// This method assumes the instruction returns a "NonLocal" dependency 0395 /// within its own block. 0396 /// 0397 /// This returns a reference to an internal data structure that may be 0398 /// invalidated on the next non-local query or when an instruction is 0399 /// removed. Clients must copy this data if they want it around longer than 0400 /// that. 0401 const NonLocalDepInfo &getNonLocalCallDependency(CallBase *QueryCall); 0402 0403 /// Perform a full dependency query for an access to the QueryInst's 0404 /// specified memory location, returning the set of instructions that either 0405 /// define or clobber the value. 0406 /// 0407 /// Warning: For a volatile query instruction, the dependencies will be 0408 /// accurate, and thus usable for reordering, but it is never legal to 0409 /// remove the query instruction. 0410 /// 0411 /// This method assumes the pointer has a "NonLocal" dependency within 0412 /// QueryInst's parent basic block. 0413 void getNonLocalPointerDependency(Instruction *QueryInst, 0414 SmallVectorImpl<NonLocalDepResult> &Result); 0415 0416 /// Removes an instruction from the dependence analysis, updating the 0417 /// dependence of instructions that previously depended on it. 0418 void removeInstruction(Instruction *InstToRemove); 0419 0420 /// Invalidates cached information about the specified pointer, because it 0421 /// may be too conservative in memdep. 0422 /// 0423 /// This is an optional call that can be used when the client detects an 0424 /// equivalence between the pointer and some other value and replaces the 0425 /// other value with ptr. This can make Ptr available in more places that 0426 /// cached info does not necessarily keep. 0427 void invalidateCachedPointerInfo(Value *Ptr); 0428 0429 /// Clears the PredIteratorCache info. 0430 /// 0431 /// This needs to be done when the CFG changes, e.g., due to splitting 0432 /// critical edges. 0433 void invalidateCachedPredecessors(); 0434 0435 /// Returns the instruction on which a memory location depends. 0436 /// 0437 /// If isLoad is true, this routine ignores may-aliases with read-only 0438 /// operations. If isLoad is false, this routine ignores may-aliases 0439 /// with reads from read-only locations. If possible, pass the query 0440 /// instruction as well; this function may take advantage of the metadata 0441 /// annotated to the query instruction to refine the result. \p Limit 0442 /// can be used to set the maximum number of instructions that will be 0443 /// examined to find the pointer dependency. On return, it will be set to 0444 /// the number of instructions left to examine. If a null pointer is passed 0445 /// in, the limit will default to the value of -memdep-block-scan-limit. 0446 /// 0447 /// Note that this is an uncached query, and thus may be inefficient. 0448 MemDepResult getPointerDependencyFrom(const MemoryLocation &Loc, bool isLoad, 0449 BasicBlock::iterator ScanIt, 0450 BasicBlock *BB, 0451 Instruction *QueryInst = nullptr, 0452 unsigned *Limit = nullptr); 0453 0454 MemDepResult getPointerDependencyFrom(const MemoryLocation &Loc, bool isLoad, 0455 BasicBlock::iterator ScanIt, 0456 BasicBlock *BB, 0457 Instruction *QueryInst, 0458 unsigned *Limit, 0459 BatchAAResults &BatchAA); 0460 0461 MemDepResult 0462 getSimplePointerDependencyFrom(const MemoryLocation &MemLoc, bool isLoad, 0463 BasicBlock::iterator ScanIt, BasicBlock *BB, 0464 Instruction *QueryInst, unsigned *Limit, 0465 BatchAAResults &BatchAA); 0466 0467 /// This analysis looks for other loads and stores with invariant.group 0468 /// metadata and the same pointer operand. Returns Unknown if it does not 0469 /// find anything, and Def if it can be assumed that 2 instructions load or 0470 /// store the same value and NonLocal which indicate that non-local Def was 0471 /// found, which can be retrieved by calling getNonLocalPointerDependency 0472 /// with the same queried instruction. 0473 MemDepResult getInvariantGroupPointerDependency(LoadInst *LI, BasicBlock *BB); 0474 0475 /// Release memory in caches. 0476 void releaseMemory(); 0477 0478 /// Return the clobber offset to dependent instruction. 0479 std::optional<int32_t> getClobberOffset(LoadInst *DepInst) const { 0480 const auto Off = ClobberOffsets.find(DepInst); 0481 if (Off != ClobberOffsets.end()) 0482 return Off->getSecond(); 0483 return std::nullopt; 0484 } 0485 0486 private: 0487 MemDepResult getCallDependencyFrom(CallBase *Call, bool isReadOnlyCall, 0488 BasicBlock::iterator ScanIt, 0489 BasicBlock *BB); 0490 bool getNonLocalPointerDepFromBB(Instruction *QueryInst, 0491 const PHITransAddr &Pointer, 0492 const MemoryLocation &Loc, bool isLoad, 0493 BasicBlock *BB, 0494 SmallVectorImpl<NonLocalDepResult> &Result, 0495 SmallDenseMap<BasicBlock *, Value *, 16> &Visited, 0496 bool SkipFirstBlock = false, 0497 bool IsIncomplete = false); 0498 MemDepResult getNonLocalInfoForBlock(Instruction *QueryInst, 0499 const MemoryLocation &Loc, bool isLoad, 0500 BasicBlock *BB, NonLocalDepInfo *Cache, 0501 unsigned NumSortedEntries, 0502 BatchAAResults &BatchAA); 0503 0504 void removeCachedNonLocalPointerDependencies(ValueIsLoadPair P); 0505 0506 void verifyRemoved(Instruction *Inst) const; 0507 }; 0508 0509 /// An analysis that produces \c MemoryDependenceResults for a function. 0510 /// 0511 /// This is essentially a no-op because the results are computed entirely 0512 /// lazily. 0513 class MemoryDependenceAnalysis 0514 : public AnalysisInfoMixin<MemoryDependenceAnalysis> { 0515 friend AnalysisInfoMixin<MemoryDependenceAnalysis>; 0516 0517 static AnalysisKey Key; 0518 0519 unsigned DefaultBlockScanLimit; 0520 0521 public: 0522 using Result = MemoryDependenceResults; 0523 0524 MemoryDependenceAnalysis(); 0525 MemoryDependenceAnalysis(unsigned DefaultBlockScanLimit) : DefaultBlockScanLimit(DefaultBlockScanLimit) { } 0526 0527 MemoryDependenceResults run(Function &F, FunctionAnalysisManager &AM); 0528 }; 0529 0530 /// A wrapper analysis pass for the legacy pass manager that exposes a \c 0531 /// MemoryDepnedenceResults instance. 0532 class MemoryDependenceWrapperPass : public FunctionPass { 0533 std::optional<MemoryDependenceResults> MemDep; 0534 0535 public: 0536 static char ID; 0537 0538 MemoryDependenceWrapperPass(); 0539 ~MemoryDependenceWrapperPass() override; 0540 0541 /// Pass Implementation stuff. This doesn't do any analysis eagerly. 0542 bool runOnFunction(Function &) override; 0543 0544 /// Clean up memory in between runs 0545 void releaseMemory() override; 0546 0547 /// Does not modify anything. It uses Value Numbering and Alias Analysis. 0548 void getAnalysisUsage(AnalysisUsage &AU) const override; 0549 0550 MemoryDependenceResults &getMemDep() { return *MemDep; } 0551 }; 0552 0553 } // end namespace llvm 0554 0555 #endif // LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|