#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
-#include "llvm/Support/CallSite.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/ValueHandle.h"
#include <vector>
namespace llvm {
PointerRec **PrevInList, *NextInList;
AliasSet *AS;
uint64_t Size;
- const MDNode *TBAAInfo;
+ AAMDNodes AAInfo;
public:
PointerRec(Value *V)
- : Val(V), PrevInList(0), NextInList(0), AS(0), Size(0),
- TBAAInfo(DenseMapInfo<const MDNode *>::getEmptyKey()) {}
+ : Val(V), PrevInList(nullptr), NextInList(nullptr), AS(nullptr), Size(0),
+ AAInfo(DenseMapInfo<AAMDNodes>::getEmptyKey()) {}
Value *getValue() const { return Val; }
PointerRec *getNext() const { return NextInList; }
- bool hasAliasSet() const { return AS != 0; }
+ bool hasAliasSet() const { return AS != nullptr; }
PointerRec** setPrevInList(PointerRec **PIL) {
PrevInList = PIL;
return &NextInList;
}
- void updateSizeAndTBAAInfo(uint64_t NewSize, const MDNode *NewTBAAInfo) {
+ void updateSizeAndAAInfo(uint64_t NewSize, const AAMDNodes &NewAAInfo) {
if (NewSize > Size) Size = NewSize;
- if (TBAAInfo == DenseMapInfo<const MDNode *>::getEmptyKey())
- // We don't have a TBAAInfo yet. Set it to NewTBAAInfo.
- TBAAInfo = NewTBAAInfo;
- else if (TBAAInfo != NewTBAAInfo)
- // NewTBAAInfo conflicts with TBAAInfo.
- TBAAInfo = DenseMapInfo<const MDNode *>::getTombstoneKey();
+ if (AAInfo == DenseMapInfo<AAMDNodes>::getEmptyKey())
+ // We don't have a AAInfo yet. Set it to NewAAInfo.
+ AAInfo = NewAAInfo;
+ else if (AAInfo != NewAAInfo)
+ // NewAAInfo conflicts with AAInfo.
+ AAInfo = DenseMapInfo<AAMDNodes>::getTombstoneKey();
}
uint64_t getSize() const { return Size; }
- /// getTBAAInfo - Return the TBAAInfo, or null if there is no
+ /// getAAInfo - Return the AAInfo, or null if there is no
/// information or conflicting information.
- const MDNode *getTBAAInfo() const {
- // If we have missing or conflicting TBAAInfo, return null.
- if (TBAAInfo == DenseMapInfo<const MDNode *>::getEmptyKey() ||
- TBAAInfo == DenseMapInfo<const MDNode *>::getTombstoneKey())
- return 0;
- return TBAAInfo;
+ AAMDNodes getAAInfo() const {
+ // If we have missing or conflicting AAInfo, return null.
+ if (AAInfo == DenseMapInfo<AAMDNodes>::getEmptyKey() ||
+ AAInfo == DenseMapInfo<AAMDNodes>::getTombstoneKey())
+ return AAMDNodes();
+ return AAInfo;
}
AliasSet *getAliasSet(AliasSetTracker &AST) {
}
void setAliasSet(AliasSet *as) {
- assert(AS == 0 && "Already have an alias set!");
+ assert(!AS && "Already have an alias set!");
AS = as;
}
*PrevInList = NextInList;
if (AS->PtrListEnd == &NextInList) {
AS->PtrListEnd = PrevInList;
- assert(*AS->PtrListEnd == 0 && "List not terminated right!");
+ assert(*AS->PtrListEnd == nullptr && "List not terminated right!");
}
delete this;
}
// AliasSets forwarding to it.
unsigned RefCount : 28;
- /// AccessType - Keep track of whether this alias set merely refers to the
- /// locations of memory, whether it modifies the memory, or whether it does
- /// both. The lattice goes from "NoModRef" to either Refs or Mods, then to
- /// ModRef as necessary.
+ /// The kinds of access this alias set models.
///
- enum AccessType {
- NoModRef = 0, Refs = 1, // Ref = bit 1
- Mods = 2, ModRef = 3 // Mod = bit 2
+ /// We keep track of whether this alias set merely refers to the locations of
+ /// memory (and not any particular access), whether it modifies or references
+ /// the memory, or whether it does both. The lattice goes from "NoAccess" to
+ /// either RefAccess or ModAccess, then to ModRefAccess as necessary.
+ enum AccessLattice {
+ NoAccess = 0,
+ RefAccess = 1,
+ ModAccess = 2,
+ ModRefAccess = RefAccess | ModAccess
};
- unsigned AccessTy : 2;
+ unsigned Access : 2;
- /// AliasType - Keep track the relationships between the pointers in the set.
- /// Lattice goes from MustAlias to MayAlias.
+ /// The kind of alias relationship between pointers of the set.
///
- enum AliasType {
- MustAlias = 0, MayAlias = 1
+ /// These represent conservatively correct alias results between any members
+ /// of the set. We represent these independently of the values of alias
+ /// results in order to pack it into a single bit. Lattice goes from
+ /// MustAlias to MayAlias.
+ enum AliasLattice {
+ SetMustAlias = 0, SetMayAlias = 1
};
- unsigned AliasTy : 1;
+ unsigned Alias : 1;
// Volatile - True if this alias set contains volatile loads or stores.
bool Volatile : 1;
public:
/// Accessors...
- bool isRef() const { return AccessTy & Refs; }
- bool isMod() const { return AccessTy & Mods; }
- bool isMustAlias() const { return AliasTy == MustAlias; }
- bool isMayAlias() const { return AliasTy == MayAlias; }
+ bool isRef() const { return Access & RefAccess; }
+ bool isMod() const { return Access & ModAccess; }
+ bool isMustAlias() const { return Alias == SetMustAlias; }
+ bool isMayAlias() const { return Alias == SetMayAlias; }
// isVolatile - Return true if this alias set contains volatile loads or
// stores.
class iterator;
iterator begin() const { return iterator(PtrList); }
iterator end() const { return iterator(); }
- bool empty() const { return PtrList == 0; }
+ bool empty() const { return PtrList == nullptr; }
void print(raw_ostream &OS) const;
void dump() const;
PointerRec, ptrdiff_t> {
PointerRec *CurNode;
public:
- explicit iterator(PointerRec *CN = 0) : CurNode(CN) {}
+ explicit iterator(PointerRec *CN = nullptr) : CurNode(CN) {}
bool operator==(const iterator& x) const {
return CurNode == x.CurNode;
}
bool operator!=(const iterator& x) const { return !operator==(x); }
- const iterator &operator=(const iterator &I) {
- CurNode = I.CurNode;
- return *this;
- }
-
value_type &operator*() const {
assert(CurNode && "Dereferencing AliasSet.end()!");
return *CurNode;
Value *getPointer() const { return CurNode->getValue(); }
uint64_t getSize() const { return CurNode->getSize(); }
- const MDNode *getTBAAInfo() const { return CurNode->getTBAAInfo(); }
+ AAMDNodes getAAInfo() const { return CurNode->getAAInfo(); }
iterator& operator++() { // Preincrement
assert(CurNode && "Advancing past AliasSet.end()!");
// Can only be created by AliasSetTracker. Also, ilist creates one
// to serve as a sentinel.
friend struct ilist_sentinel_traits<AliasSet>;
- AliasSet() : PtrList(0), PtrListEnd(&PtrList), Forward(0), RefCount(0),
- AccessTy(NoModRef), AliasTy(MustAlias), Volatile(false) {
+ AliasSet()
+ : PtrList(nullptr), PtrListEnd(&PtrList), Forward(nullptr), RefCount(0),
+ Access(NoAccess), Alias(SetMustAlias), Volatile(false) {
}
- AliasSet(const AliasSet &AS) LLVM_DELETED_FUNCTION;
- void operator=(const AliasSet &AS) LLVM_DELETED_FUNCTION;
+ AliasSet(const AliasSet &AS) = delete;
+ void operator=(const AliasSet &AS) = delete;
PointerRec *getSomePointer() const {
return PtrList;
void removeFromTracker(AliasSetTracker &AST);
void addPointer(AliasSetTracker &AST, PointerRec &Entry, uint64_t Size,
- const MDNode *TBAAInfo,
+ const AAMDNodes &AAInfo,
bool KnownMustAlias = false);
void addUnknownInst(Instruction *I, AliasAnalysis &AA);
- void removeUnknownInst(Instruction *I) {
+ void removeUnknownInst(AliasSetTracker &AST, Instruction *I) {
+ bool WasEmpty = UnknownInsts.empty();
for (size_t i = 0, e = UnknownInsts.size(); i != e; ++i)
if (UnknownInsts[i] == I) {
UnknownInsts[i] = UnknownInsts.back();
UnknownInsts.pop_back();
--i; --e; // Revisit the moved entry.
}
+ if (!WasEmpty && UnknownInsts.empty())
+ dropRef(AST);
}
void setVolatile() { Volatile = true; }
/// aliasesPointer - Return true if the specified pointer "may" (or must)
/// alias one of the members in the set.
///
- bool aliasesPointer(const Value *Ptr, uint64_t Size, const MDNode *TBAAInfo,
+ bool aliasesPointer(const Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo,
AliasAnalysis &AA) const;
- bool aliasesUnknownInst(Instruction *Inst, AliasAnalysis &AA) const;
+ bool aliasesUnknownInst(const Instruction *Inst, AliasAnalysis &AA) const;
};
inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {
class AliasSetTracker {
/// CallbackVH - A CallbackVH to arrange for AliasSetTracker to be
/// notified whenever a Value is deleted.
- class ASTCallbackVH : public CallbackVH {
+ class ASTCallbackVH final : public CallbackVH {
AliasSetTracker *AST;
- virtual void deleted();
- virtual void allUsesReplacedWith(Value *);
+ void deleted() override;
+ void allUsesReplacedWith(Value *) override;
public:
- ASTCallbackVH(Value *V, AliasSetTracker *AST = 0);
+ ASTCallbackVH(Value *V, AliasSetTracker *AST = nullptr);
ASTCallbackVH &operator=(Value *V);
};
/// ASTCallbackVHDenseMapInfo - Traits to tell DenseMap that tell us how to
/// These methods return true if inserting the instruction resulted in the
/// addition of a new alias set (i.e., the pointer did not alias anything).
///
- bool add(Value *Ptr, uint64_t Size, const MDNode *TBAAInfo); // Add a location
+ bool add(Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo); // Add a loc.
bool add(LoadInst *LI);
bool add(StoreInst *SI);
bool add(VAArgInst *VAAI);
/// be aliased by the specified instruction. These methods return true if any
/// alias sets were eliminated.
// Remove a location
- bool remove(Value *Ptr, uint64_t Size, const MDNode *TBAAInfo);
+ bool remove(Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo);
bool remove(LoadInst *LI);
bool remove(StoreInst *SI);
bool remove(VAArgInst *VAAI);
/// true if a new alias set is created to contain the pointer (because the
/// pointer didn't alias anything).
AliasSet &getAliasSetForPointer(Value *P, uint64_t Size,
- const MDNode *TBAAInfo,
- bool *New = 0);
+ const AAMDNodes &AAInfo,
+ bool *New = nullptr);
/// getAliasSetForPointerIfExists - Return the alias set containing the
/// location specified if one exists, otherwise return null.
- AliasSet *getAliasSetForPointerIfExists(Value *P, uint64_t Size,
- const MDNode *TBAAInfo) {
- return findAliasSetForPointer(P, Size, TBAAInfo);
+ AliasSet *getAliasSetForPointerIfExists(const Value *P, uint64_t Size,
+ const AAMDNodes &AAInfo) {
+ return findAliasSetForPointer(P, Size, AAInfo);
}
/// containsPointer - Return true if the specified location is represented by
/// this alias set, false otherwise. This does not modify the AST object or
/// alias sets.
- bool containsPointer(Value *P, uint64_t Size, const MDNode *TBAAInfo) const;
+ bool containsPointer(const Value *P, uint64_t Size,
+ const AAMDNodes &AAInfo) const;
+
+ /// Return true if the specified instruction "may" (or must) alias one of the
+ /// members in any of the sets.
+ bool containsUnknown(const Instruction *I) const;
/// getAliasAnalysis - Return the underlying alias analysis object used by
/// this tracker.
// entry for the pointer if it doesn't already exist.
AliasSet::PointerRec &getEntryFor(Value *V) {
AliasSet::PointerRec *&Entry = PointerMap[ASTCallbackVH(V, this)];
- if (Entry == 0)
+ if (!Entry)
Entry = new AliasSet::PointerRec(V);
return *Entry;
}
- AliasSet &addPointer(Value *P, uint64_t Size, const MDNode *TBAAInfo,
- AliasSet::AccessType E,
+ AliasSet &addPointer(Value *P, uint64_t Size, const AAMDNodes &AAInfo,
+ AliasSet::AccessLattice E,
bool &NewSet) {
NewSet = false;
- AliasSet &AS = getAliasSetForPointer(P, Size, TBAAInfo, &NewSet);
- AS.AccessTy |= E;
+ AliasSet &AS = getAliasSetForPointer(P, Size, AAInfo, &NewSet);
+ AS.Access |= E;
return AS;
}
AliasSet *findAliasSetForPointer(const Value *Ptr, uint64_t Size,
- const MDNode *TBAAInfo);
+ const AAMDNodes &AAInfo);
AliasSet *findAliasSetForUnknownInst(Instruction *Inst);
};