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
0016
0017
0018 #ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
0019 #define LLVM_ANALYSIS_ALIASSETTRACKER_H
0020
0021 #include "llvm/ADT/DenseMap.h"
0022 #include "llvm/ADT/SmallVector.h"
0023 #include "llvm/ADT/ilist.h"
0024 #include "llvm/ADT/ilist_node.h"
0025 #include "llvm/Analysis/MemoryLocation.h"
0026 #include "llvm/IR/PassManager.h"
0027 #include "llvm/IR/ValueHandle.h"
0028 #include <cassert>
0029 #include <vector>
0030
0031 namespace llvm {
0032
0033 class AliasResult;
0034 class AliasSetTracker;
0035 class AnyMemSetInst;
0036 class AnyMemTransferInst;
0037 class BasicBlock;
0038 class BatchAAResults;
0039 class Function;
0040 class Instruction;
0041 class StoreInst;
0042 class LoadInst;
0043 enum class ModRefInfo : uint8_t;
0044 class raw_ostream;
0045 class VAArgInst;
0046 class Value;
0047
0048 class AliasSet : public ilist_node<AliasSet> {
0049 friend class AliasSetTracker;
0050
0051
0052 AliasSet *Forward = nullptr;
0053
0054
0055 SmallVector<MemoryLocation, 0> MemoryLocs;
0056
0057
0058 std::vector<AssertingVH<Instruction>> UnknownInsts;
0059
0060
0061
0062 unsigned RefCount : 27;
0063
0064
0065
0066 unsigned AliasAny : 1;
0067
0068
0069
0070
0071
0072
0073
0074 enum AccessLattice {
0075 NoAccess = 0,
0076 RefAccess = 1,
0077 ModAccess = 2,
0078 ModRefAccess = RefAccess | ModAccess
0079 };
0080 unsigned Access : 2;
0081
0082
0083
0084
0085
0086
0087
0088 enum AliasLattice {
0089 SetMustAlias = 0, SetMayAlias = 1
0090 };
0091 unsigned Alias : 1;
0092
0093 void addRef() { ++RefCount; }
0094
0095 void dropRef(AliasSetTracker &AST) {
0096 assert(RefCount >= 1 && "Invalid reference count detected!");
0097 if (--RefCount == 0)
0098 removeFromTracker(AST);
0099 }
0100
0101 public:
0102 AliasSet(const AliasSet &) = delete;
0103 AliasSet &operator=(const AliasSet &) = delete;
0104
0105
0106 bool isRef() const { return Access & RefAccess; }
0107 bool isMod() const { return Access & ModAccess; }
0108 bool isMustAlias() const { return Alias == SetMustAlias; }
0109 bool isMayAlias() const { return Alias == SetMayAlias; }
0110
0111
0112
0113 bool isForwardingAliasSet() const { return Forward; }
0114
0115
0116 void mergeSetIn(AliasSet &AS, AliasSetTracker &AST, BatchAAResults &BatchAA);
0117
0118
0119
0120 using iterator = SmallVectorImpl<MemoryLocation>::const_iterator;
0121 iterator begin() const { return MemoryLocs.begin(); }
0122 iterator end() const { return MemoryLocs.end(); }
0123
0124 unsigned size() const { return MemoryLocs.size(); }
0125
0126
0127
0128
0129 using PointerVector = SmallVector<const Value *, 8>;
0130 PointerVector getPointers() const;
0131
0132 void print(raw_ostream &OS) const;
0133 void dump() const;
0134
0135 private:
0136
0137 AliasSet()
0138 : RefCount(0), AliasAny(false), Access(NoAccess), Alias(SetMustAlias) {}
0139
0140 void removeFromTracker(AliasSetTracker &AST);
0141
0142 void addMemoryLocation(AliasSetTracker &AST, const MemoryLocation &MemLoc,
0143 bool KnownMustAlias = false);
0144 void addUnknownInst(Instruction *I, BatchAAResults &AA);
0145
0146 public:
0147
0148
0149 AliasResult aliasesMemoryLocation(const MemoryLocation &MemLoc,
0150 BatchAAResults &AA) const;
0151
0152 ModRefInfo aliasesUnknownInst(const Instruction *Inst,
0153 BatchAAResults &AA) const;
0154 };
0155
0156 inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {
0157 AS.print(OS);
0158 return OS;
0159 }
0160
0161 class AliasSetTracker {
0162 BatchAAResults &AA;
0163 ilist<AliasSet> AliasSets;
0164
0165 using PointerMapType = DenseMap<AssertingVH<const Value>, AliasSet *>;
0166
0167
0168
0169 PointerMapType PointerMap;
0170
0171 public:
0172
0173
0174 explicit AliasSetTracker(BatchAAResults &AA) : AA(AA) {}
0175 ~AliasSetTracker() { clear(); }
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186 void add(const MemoryLocation &Loc);
0187 void add(LoadInst *LI);
0188 void add(StoreInst *SI);
0189 void add(VAArgInst *VAAI);
0190 void add(AnyMemSetInst *MSI);
0191 void add(AnyMemTransferInst *MTI);
0192 void add(Instruction *I);
0193 void add(BasicBlock &BB);
0194 void add(const AliasSetTracker &AST);
0195 void addUnknown(Instruction *I);
0196
0197 void clear();
0198
0199
0200 const ilist<AliasSet> &getAliasSets() const { return AliasSets; }
0201
0202
0203
0204
0205
0206 AliasSet &getAliasSetFor(const MemoryLocation &MemLoc);
0207
0208
0209 BatchAAResults &getAliasAnalysis() const { return AA; }
0210
0211 using iterator = ilist<AliasSet>::iterator;
0212 using const_iterator = ilist<AliasSet>::const_iterator;
0213
0214 const_iterator begin() const { return AliasSets.begin(); }
0215 const_iterator end() const { return AliasSets.end(); }
0216
0217 iterator begin() { return AliasSets.begin(); }
0218 iterator end() { return AliasSets.end(); }
0219
0220 void print(raw_ostream &OS) const;
0221 void dump() const;
0222
0223 private:
0224 friend class AliasSet;
0225
0226
0227 unsigned TotalAliasSetSize = 0;
0228
0229
0230
0231 AliasSet *AliasAnyAS = nullptr;
0232
0233 void removeAliasSet(AliasSet *AS);
0234
0235
0236
0237
0238
0239
0240
0241 void collapseForwardingIn(AliasSet *&AS) {
0242 if (AS->Forward) {
0243 collapseForwardingIn(AS->Forward);
0244
0245 AliasSet *NewAS = AS->Forward;
0246 NewAS->addRef();
0247 AS->dropRef(*this);
0248 AS = NewAS;
0249 }
0250 }
0251
0252 AliasSet &addMemoryLocation(MemoryLocation Loc, AliasSet::AccessLattice E);
0253 AliasSet *mergeAliasSetsForMemoryLocation(const MemoryLocation &MemLoc,
0254 AliasSet *PtrAS,
0255 bool &MustAliasAll);
0256
0257
0258
0259 AliasSet &mergeAllAliasSets();
0260
0261 AliasSet *findAliasSetForUnknownInst(Instruction *Inst);
0262 };
0263
0264 inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) {
0265 AST.print(OS);
0266 return OS;
0267 }
0268
0269 class AliasSetsPrinterPass : public PassInfoMixin<AliasSetsPrinterPass> {
0270 raw_ostream &OS;
0271
0272 public:
0273 explicit AliasSetsPrinterPass(raw_ostream &OS);
0274 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
0275 static bool isRequired() { return true; }
0276 };
0277
0278 }
0279
0280 #endif