mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 05:40:09 +00:00
[AST] Don't merge memory locations in AliasSetTracker (#65731)
This changes the AliasSetTracker to track memory locations instead of pointers in its alias sets. The motivation for this is outlined in an RFC posted on LLVM discourse: https://discourse.llvm.org/t/rfc-dont-merge-memory-locations-in-aliassettracker/73336 In the data structures of the AST implementation, I made the choice to replace the linked list of `PointerRec` entries (that had to go anyway) with a simple flat vector of `MemoryLocation` objects, but for the `AliasSet` objects referenced from a lookup table, I retained the mechanism of a linked list, reference counting, forwarding, etc. The data structures could be revised in a follow-up change.
This commit is contained in:
parent
8fb685fb7e
commit
656bf13004
@ -7,7 +7,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// This file defines two classes: AliasSetTracker and AliasSet. These interfaces
|
// This file defines two classes: AliasSetTracker and AliasSet. These interfaces
|
||||||
// are used to classify a collection of pointer references into a maximal number
|
// are used to classify a collection of memory locations into a maximal number
|
||||||
// of disjoint sets. Each AliasSet object constructed by the AliasSetTracker
|
// of disjoint sets. Each AliasSet object constructed by the AliasSetTracker
|
||||||
// object refers to memory disjoint from the other sets.
|
// object refers to memory disjoint from the other sets.
|
||||||
//
|
//
|
||||||
@ -19,7 +19,7 @@
|
|||||||
#define LLVM_ANALYSIS_ALIASSETTRACKER_H
|
#define LLVM_ANALYSIS_ALIASSETTRACKER_H
|
||||||
|
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/DenseMapInfo.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/ilist.h"
|
#include "llvm/ADT/ilist.h"
|
||||||
#include "llvm/ADT/ilist_node.h"
|
#include "llvm/ADT/ilist_node.h"
|
||||||
#include "llvm/Analysis/MemoryLocation.h"
|
#include "llvm/Analysis/MemoryLocation.h"
|
||||||
@ -27,8 +27,6 @@
|
|||||||
#include "llvm/IR/PassManager.h"
|
#include "llvm/IR/PassManager.h"
|
||||||
#include "llvm/IR/ValueHandle.h"
|
#include "llvm/IR/ValueHandle.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstddef>
|
|
||||||
#include <iterator>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -49,99 +47,12 @@ class Value;
|
|||||||
class AliasSet : public ilist_node<AliasSet> {
|
class AliasSet : public ilist_node<AliasSet> {
|
||||||
friend class AliasSetTracker;
|
friend class AliasSetTracker;
|
||||||
|
|
||||||
class PointerRec {
|
|
||||||
Value *Val; // The pointer this record corresponds to.
|
|
||||||
PointerRec **PrevInList = nullptr;
|
|
||||||
PointerRec *NextInList = nullptr;
|
|
||||||
AliasSet *AS = nullptr;
|
|
||||||
LocationSize Size = LocationSize::mapEmpty();
|
|
||||||
AAMDNodes AAInfo;
|
|
||||||
|
|
||||||
// Whether the size for this record has been set at all. This makes no
|
|
||||||
// guarantees about the size being known.
|
|
||||||
bool isSizeSet() const { return Size != LocationSize::mapEmpty(); }
|
|
||||||
|
|
||||||
public:
|
|
||||||
PointerRec(Value *V)
|
|
||||||
: Val(V), AAInfo(DenseMapInfo<AAMDNodes>::getEmptyKey()) {}
|
|
||||||
|
|
||||||
Value *getValue() const { return Val; }
|
|
||||||
|
|
||||||
PointerRec *getNext() const { return NextInList; }
|
|
||||||
bool hasAliasSet() const { return AS != nullptr; }
|
|
||||||
|
|
||||||
PointerRec** setPrevInList(PointerRec **PIL) {
|
|
||||||
PrevInList = PIL;
|
|
||||||
return &NextInList;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool updateSizeAndAAInfo(LocationSize NewSize, const AAMDNodes &NewAAInfo) {
|
|
||||||
bool SizeChanged = false;
|
|
||||||
if (NewSize != Size) {
|
|
||||||
LocationSize OldSize = Size;
|
|
||||||
Size = isSizeSet() ? Size.unionWith(NewSize) : NewSize;
|
|
||||||
SizeChanged = OldSize != Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AAInfo == DenseMapInfo<AAMDNodes>::getEmptyKey())
|
|
||||||
// We don't have a AAInfo yet. Set it to NewAAInfo.
|
|
||||||
AAInfo = NewAAInfo;
|
|
||||||
else {
|
|
||||||
AAMDNodes Intersection(AAInfo.intersect(NewAAInfo));
|
|
||||||
SizeChanged |= Intersection != AAInfo;
|
|
||||||
AAInfo = Intersection;
|
|
||||||
}
|
|
||||||
return SizeChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
LocationSize getSize() const {
|
|
||||||
assert(isSizeSet() && "Getting an unset size!");
|
|
||||||
return Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the AAInfo, or null if there is no information or conflicting
|
|
||||||
/// information.
|
|
||||||
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) {
|
|
||||||
assert(AS && "No AliasSet yet!");
|
|
||||||
if (AS->Forward) {
|
|
||||||
AliasSet *OldAS = AS;
|
|
||||||
AS = OldAS->getForwardedTarget(AST);
|
|
||||||
AS->addRef();
|
|
||||||
OldAS->dropRef(AST);
|
|
||||||
}
|
|
||||||
return AS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAliasSet(AliasSet *as) {
|
|
||||||
assert(!AS && "Already have an alias set!");
|
|
||||||
AS = as;
|
|
||||||
}
|
|
||||||
|
|
||||||
void eraseFromList() {
|
|
||||||
if (NextInList) NextInList->PrevInList = PrevInList;
|
|
||||||
*PrevInList = NextInList;
|
|
||||||
if (AS->PtrListEnd == &NextInList) {
|
|
||||||
AS->PtrListEnd = PrevInList;
|
|
||||||
assert(*AS->PtrListEnd == nullptr && "List not terminated right!");
|
|
||||||
}
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Doubly linked list of nodes.
|
|
||||||
PointerRec *PtrList = nullptr;
|
|
||||||
PointerRec **PtrListEnd;
|
|
||||||
// Forwarding pointer.
|
// Forwarding pointer.
|
||||||
AliasSet *Forward = nullptr;
|
AliasSet *Forward = nullptr;
|
||||||
|
|
||||||
|
/// Memory locations in this alias set.
|
||||||
|
SmallVector<MemoryLocation, 0> MemoryLocs;
|
||||||
|
|
||||||
/// All instructions without a specific address in this alias set.
|
/// All instructions without a specific address in this alias set.
|
||||||
std::vector<AssertingVH<Instruction>> UnknownInsts;
|
std::vector<AssertingVH<Instruction>> UnknownInsts;
|
||||||
|
|
||||||
@ -178,8 +89,6 @@ class AliasSet : public ilist_node<AliasSet> {
|
|||||||
};
|
};
|
||||||
unsigned Alias : 1;
|
unsigned Alias : 1;
|
||||||
|
|
||||||
unsigned SetSize = 0;
|
|
||||||
|
|
||||||
void addRef() { ++RefCount; }
|
void addRef() { ++RefCount; }
|
||||||
|
|
||||||
void dropRef(AliasSetTracker &AST) {
|
void dropRef(AliasSetTracker &AST) {
|
||||||
@ -205,95 +114,40 @@ public:
|
|||||||
/// Merge the specified alias set into this alias set.
|
/// Merge the specified alias set into this alias set.
|
||||||
void mergeSetIn(AliasSet &AS, AliasSetTracker &AST, BatchAAResults &BatchAA);
|
void mergeSetIn(AliasSet &AS, AliasSetTracker &AST, BatchAAResults &BatchAA);
|
||||||
|
|
||||||
// Alias Set iteration - Allow access to all of the pointers which are part of
|
// Alias Set iteration - Allow access to all of the memory locations which are
|
||||||
// this alias set.
|
// part of this alias set.
|
||||||
class iterator;
|
using iterator = SmallVectorImpl<MemoryLocation>::const_iterator;
|
||||||
iterator begin() const { return iterator(PtrList); }
|
iterator begin() const { return MemoryLocs.begin(); }
|
||||||
iterator end() const { return iterator(); }
|
iterator end() const { return MemoryLocs.end(); }
|
||||||
bool empty() const { return PtrList == nullptr; }
|
|
||||||
|
|
||||||
// Unfortunately, ilist::size() is linear, so we have to add code to keep
|
unsigned size() { return MemoryLocs.size(); }
|
||||||
// track of the list's exact size.
|
|
||||||
unsigned size() { return SetSize; }
|
/// Retrieve the pointer values for the memory locations in this alias set.
|
||||||
|
/// The order matches that of the memory locations, but duplicate pointer
|
||||||
|
/// values are omitted.
|
||||||
|
using PointerVector = SmallVector<const Value *, 8>;
|
||||||
|
PointerVector getPointers() const;
|
||||||
|
|
||||||
void print(raw_ostream &OS) const;
|
void print(raw_ostream &OS) const;
|
||||||
void dump() const;
|
void dump() const;
|
||||||
|
|
||||||
/// Define an iterator for alias sets... this is just a forward iterator.
|
|
||||||
class iterator {
|
|
||||||
PointerRec *CurNode;
|
|
||||||
|
|
||||||
public:
|
|
||||||
using iterator_category = std::forward_iterator_tag;
|
|
||||||
using value_type = PointerRec;
|
|
||||||
using difference_type = std::ptrdiff_t;
|
|
||||||
using pointer = value_type *;
|
|
||||||
using reference = value_type &;
|
|
||||||
|
|
||||||
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); }
|
|
||||||
|
|
||||||
value_type &operator*() const {
|
|
||||||
assert(CurNode && "Dereferencing AliasSet.end()!");
|
|
||||||
return *CurNode;
|
|
||||||
}
|
|
||||||
value_type *operator->() const { return &operator*(); }
|
|
||||||
|
|
||||||
Value *getPointer() const { return CurNode->getValue(); }
|
|
||||||
LocationSize getSize() const { return CurNode->getSize(); }
|
|
||||||
AAMDNodes getAAInfo() const { return CurNode->getAAInfo(); }
|
|
||||||
|
|
||||||
iterator& operator++() { // Preincrement
|
|
||||||
assert(CurNode && "Advancing past AliasSet.end()!");
|
|
||||||
CurNode = CurNode->getNext();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
iterator operator++(int) { // Postincrement
|
|
||||||
iterator tmp = *this; ++*this; return tmp;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Can only be created by AliasSetTracker.
|
// Can only be created by AliasSetTracker.
|
||||||
AliasSet()
|
AliasSet()
|
||||||
: PtrListEnd(&PtrList), RefCount(0), AliasAny(false), Access(NoAccess),
|
: RefCount(0), AliasAny(false), Access(NoAccess), Alias(SetMustAlias) {}
|
||||||
Alias(SetMustAlias) {}
|
|
||||||
|
|
||||||
PointerRec *getSomePointer() const {
|
|
||||||
return PtrList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the real alias set this represents. If this has been merged with
|
|
||||||
/// another set and is forwarding, return the ultimate destination set. This
|
|
||||||
/// also implements the union-find collapsing as well.
|
|
||||||
AliasSet *getForwardedTarget(AliasSetTracker &AST) {
|
|
||||||
if (!Forward) return this;
|
|
||||||
|
|
||||||
AliasSet *Dest = Forward->getForwardedTarget(AST);
|
|
||||||
if (Dest != Forward) {
|
|
||||||
Dest->addRef();
|
|
||||||
Forward->dropRef(AST);
|
|
||||||
Forward = Dest;
|
|
||||||
}
|
|
||||||
return Dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeFromTracker(AliasSetTracker &AST);
|
void removeFromTracker(AliasSetTracker &AST);
|
||||||
|
|
||||||
void addPointer(AliasSetTracker &AST, PointerRec &Entry, LocationSize Size,
|
void addMemoryLocation(AliasSetTracker &AST, const MemoryLocation &MemLoc,
|
||||||
const AAMDNodes &AAInfo, bool KnownMustAlias = false,
|
bool KnownMustAlias = false);
|
||||||
bool SkipSizeUpdate = false);
|
|
||||||
void addUnknownInst(Instruction *I, BatchAAResults &AA);
|
void addUnknownInst(Instruction *I, BatchAAResults &AA);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// If the specified pointer "may" (or must) alias one of the members in the
|
/// If the specified memory location "may" (or must) alias one of the members
|
||||||
/// set return the appropriate AliasResult. Otherwise return NoAlias.
|
/// in the set return the appropriate AliasResult. Otherwise return NoAlias.
|
||||||
AliasResult aliasesPointer(const Value *Ptr, LocationSize Size,
|
AliasResult aliasesMemoryLocation(const MemoryLocation &MemLoc,
|
||||||
const AAMDNodes &AAInfo, BatchAAResults &AA) const;
|
BatchAAResults &AA) const;
|
||||||
|
|
||||||
ModRefInfo aliasesUnknownInst(const Instruction *Inst,
|
ModRefInfo aliasesUnknownInst(const Instruction *Inst,
|
||||||
BatchAAResults &AA) const;
|
BatchAAResults &AA) const;
|
||||||
};
|
};
|
||||||
@ -307,9 +161,10 @@ class AliasSetTracker {
|
|||||||
BatchAAResults &AA;
|
BatchAAResults &AA;
|
||||||
ilist<AliasSet> AliasSets;
|
ilist<AliasSet> AliasSets;
|
||||||
|
|
||||||
using PointerMapType = DenseMap<AssertingVH<Value>, AliasSet::PointerRec *>;
|
using PointerMapType = DenseMap<AssertingVH<const Value>, AliasSet *>;
|
||||||
|
|
||||||
// Map from pointers to their node
|
// Map from pointer values to the alias set holding one or more memory
|
||||||
|
// locations with that pointer value.
|
||||||
PointerMapType PointerMap;
|
PointerMapType PointerMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -327,9 +182,6 @@ public:
|
|||||||
/// 3. If the instruction aliases multiple sets, merge the sets, and add
|
/// 3. If the instruction aliases multiple sets, merge the sets, and add
|
||||||
/// the instruction to the result.
|
/// the instruction to the result.
|
||||||
///
|
///
|
||||||
/// 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).
|
|
||||||
///
|
|
||||||
void add(const MemoryLocation &Loc);
|
void add(const MemoryLocation &Loc);
|
||||||
void add(LoadInst *LI);
|
void add(LoadInst *LI);
|
||||||
void add(StoreInst *SI);
|
void add(StoreInst *SI);
|
||||||
@ -370,31 +222,39 @@ public:
|
|||||||
private:
|
private:
|
||||||
friend class AliasSet;
|
friend class AliasSet;
|
||||||
|
|
||||||
// The total number of pointers contained in all "may" alias sets.
|
// The total number of memory locations contained in all alias sets.
|
||||||
unsigned TotalMayAliasSetSize = 0;
|
unsigned TotalAliasSetSize = 0;
|
||||||
|
|
||||||
// A non-null value signifies this AST is saturated. A saturated AST lumps
|
// A non-null value signifies this AST is saturated. A saturated AST lumps
|
||||||
// all pointers into a single "May" set.
|
// all elements into a single "May" set.
|
||||||
AliasSet *AliasAnyAS = nullptr;
|
AliasSet *AliasAnyAS = nullptr;
|
||||||
|
|
||||||
void removeAliasSet(AliasSet *AS);
|
void removeAliasSet(AliasSet *AS);
|
||||||
|
|
||||||
/// Just like operator[] on the map, except that it creates an entry for the
|
// Update an alias set field to point to its real destination. If the field is
|
||||||
/// pointer if it doesn't already exist.
|
// pointing to a set that has been merged with another set and is forwarding,
|
||||||
AliasSet::PointerRec &getEntryFor(Value *V) {
|
// the field is updated to point to the set obtained by following the
|
||||||
AliasSet::PointerRec *&Entry = PointerMap[V];
|
// forwarding links. The Forward fields of intermediate alias sets are
|
||||||
if (!Entry)
|
// collapsed as well, and alias set reference counts are updated to reflect
|
||||||
Entry = new AliasSet::PointerRec(V);
|
// the new situation.
|
||||||
return *Entry;
|
void collapseForwardingIn(AliasSet *&AS) {
|
||||||
|
if (AS->Forward) {
|
||||||
|
collapseForwardingIn(AS->Forward);
|
||||||
|
// Swap out AS for AS->Forward, while updating reference counts.
|
||||||
|
AliasSet *NewAS = AS->Forward;
|
||||||
|
NewAS->addRef();
|
||||||
|
AS->dropRef(*this);
|
||||||
|
AS = NewAS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AliasSet &addPointer(MemoryLocation Loc, AliasSet::AccessLattice E);
|
AliasSet &addMemoryLocation(MemoryLocation Loc, AliasSet::AccessLattice E);
|
||||||
AliasSet *mergeAliasSetsForPointer(const Value *Ptr, LocationSize Size,
|
AliasSet *mergeAliasSetsForMemoryLocation(const MemoryLocation &MemLoc,
|
||||||
const AAMDNodes &AAInfo,
|
AliasSet *PtrAS,
|
||||||
bool &MustAliasAll);
|
bool &MustAliasAll);
|
||||||
|
|
||||||
/// Merge all alias sets into a single set that is considered to alias any
|
/// Merge all alias sets into a single set that is considered to alias
|
||||||
/// pointer.
|
/// any memory location or instruction.
|
||||||
AliasSet &mergeAllAliasSets();
|
AliasSet &mergeAllAliasSets();
|
||||||
|
|
||||||
AliasSet *findAliasSetForUnknownInst(Instruction *Inst);
|
AliasSet *findAliasSetForUnknownInst(Instruction *Inst);
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/Analysis/AliasSetTracker.h"
|
#include "llvm/Analysis/AliasSetTracker.h"
|
||||||
|
#include "llvm/ADT/SetVector.h"
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/Analysis/AliasAnalysis.h"
|
#include "llvm/Analysis/AliasAnalysis.h"
|
||||||
#include "llvm/Analysis/GuardUtils.h"
|
#include "llvm/Analysis/GuardUtils.h"
|
||||||
@ -34,11 +35,10 @@
|
|||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
static cl::opt<unsigned>
|
static cl::opt<unsigned> SaturationThreshold(
|
||||||
SaturationThreshold("alias-set-saturation-threshold", cl::Hidden,
|
"alias-set-saturation-threshold", cl::Hidden, cl::init(250),
|
||||||
cl::init(250),
|
cl::desc("The maximum total number of memory locations alias "
|
||||||
cl::desc("The maximum number of pointers may-alias "
|
"sets may contain before degradation"));
|
||||||
"sets may contain before degradation"));
|
|
||||||
|
|
||||||
/// mergeSetIn - Merge the specified alias set into this alias set.
|
/// mergeSetIn - Merge the specified alias set into this alias set.
|
||||||
void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST,
|
void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST,
|
||||||
@ -46,30 +46,27 @@ void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST,
|
|||||||
assert(!AS.Forward && "Alias set is already forwarding!");
|
assert(!AS.Forward && "Alias set is already forwarding!");
|
||||||
assert(!Forward && "This set is a forwarding set!!");
|
assert(!Forward && "This set is a forwarding set!!");
|
||||||
|
|
||||||
bool WasMustAlias = (Alias == SetMustAlias);
|
|
||||||
// Update the alias and access types of this set...
|
// Update the alias and access types of this set...
|
||||||
Access |= AS.Access;
|
Access |= AS.Access;
|
||||||
Alias |= AS.Alias;
|
Alias |= AS.Alias;
|
||||||
|
|
||||||
if (Alias == SetMustAlias) {
|
if (Alias == SetMustAlias) {
|
||||||
// Check that these two merged sets really are must aliases. Since both
|
// Check that these two merged sets really are must aliases. If we cannot
|
||||||
// used to be must-alias sets, we can just check any pointer from each set
|
// find a must-alias pair between them, this set becomes a may alias.
|
||||||
// for aliasing.
|
if (!any_of(MemoryLocs, [&](const MemoryLocation &MemLoc) {
|
||||||
PointerRec *L = getSomePointer();
|
return any_of(AS.MemoryLocs, [&](const MemoryLocation &ASMemLoc) {
|
||||||
PointerRec *R = AS.getSomePointer();
|
return BatchAA.isMustAlias(MemLoc, ASMemLoc);
|
||||||
|
});
|
||||||
// If the pointers are not a must-alias pair, this set becomes a may alias.
|
}))
|
||||||
if (!BatchAA.isMustAlias(
|
|
||||||
MemoryLocation(L->getValue(), L->getSize(), L->getAAInfo()),
|
|
||||||
MemoryLocation(R->getValue(), R->getSize(), R->getAAInfo())))
|
|
||||||
Alias = SetMayAlias;
|
Alias = SetMayAlias;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Alias == SetMayAlias) {
|
// Merge the list of constituent memory locations...
|
||||||
if (WasMustAlias)
|
if (MemoryLocs.empty()) {
|
||||||
AST.TotalMayAliasSetSize += size();
|
std::swap(MemoryLocs, AS.MemoryLocs);
|
||||||
if (AS.Alias == SetMustAlias)
|
} else {
|
||||||
AST.TotalMayAliasSetSize += AS.size();
|
append_range(MemoryLocs, AS.MemoryLocs);
|
||||||
|
AS.MemoryLocs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASHadUnknownInsts = !AS.UnknownInsts.empty();
|
bool ASHadUnknownInsts = !AS.UnknownInsts.empty();
|
||||||
@ -86,18 +83,6 @@ void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST,
|
|||||||
AS.Forward = this; // Forward across AS now...
|
AS.Forward = this; // Forward across AS now...
|
||||||
addRef(); // AS is now pointing to us...
|
addRef(); // AS is now pointing to us...
|
||||||
|
|
||||||
// Merge the list of constituent pointers...
|
|
||||||
if (AS.PtrList) {
|
|
||||||
SetSize += AS.size();
|
|
||||||
AS.SetSize = 0;
|
|
||||||
*PtrListEnd = AS.PtrList;
|
|
||||||
AS.PtrList->setPrevInList(PtrListEnd);
|
|
||||||
PtrListEnd = AS.PtrListEnd;
|
|
||||||
|
|
||||||
AS.PtrList = nullptr;
|
|
||||||
AS.PtrListEnd = &AS.PtrList;
|
|
||||||
assert(*AS.PtrListEnd == nullptr && "End of list is not null?");
|
|
||||||
}
|
|
||||||
if (ASHadUnknownInsts)
|
if (ASHadUnknownInsts)
|
||||||
AS.dropRef(AST);
|
AS.dropRef(AST);
|
||||||
}
|
}
|
||||||
@ -106,9 +91,8 @@ void AliasSetTracker::removeAliasSet(AliasSet *AS) {
|
|||||||
if (AliasSet *Fwd = AS->Forward) {
|
if (AliasSet *Fwd = AS->Forward) {
|
||||||
Fwd->dropRef(*this);
|
Fwd->dropRef(*this);
|
||||||
AS->Forward = nullptr;
|
AS->Forward = nullptr;
|
||||||
} else // Update TotalMayAliasSetSize only if not forwarding.
|
} else // Update TotalAliasSetSize only if not forwarding.
|
||||||
if (AS->Alias == AliasSet::SetMayAlias)
|
TotalAliasSetSize -= AS->size();
|
||||||
TotalMayAliasSetSize -= AS->size();
|
|
||||||
|
|
||||||
AliasSets.erase(AS);
|
AliasSets.erase(AS);
|
||||||
// If we've removed the saturated alias set, set saturated marker back to
|
// If we've removed the saturated alias set, set saturated marker back to
|
||||||
@ -124,42 +108,22 @@ void AliasSet::removeFromTracker(AliasSetTracker &AST) {
|
|||||||
AST.removeAliasSet(this);
|
AST.removeAliasSet(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry,
|
void AliasSet::addMemoryLocation(AliasSetTracker &AST,
|
||||||
LocationSize Size, const AAMDNodes &AAInfo,
|
const MemoryLocation &MemLoc,
|
||||||
bool KnownMustAlias, bool SkipSizeUpdate) {
|
bool KnownMustAlias) {
|
||||||
assert(!Entry.hasAliasSet() && "Entry already in set!");
|
if (isMustAlias() && !KnownMustAlias) {
|
||||||
|
// If we cannot find a must-alias with any of the existing MemoryLocs, we
|
||||||
// Check to see if we have to downgrade to _may_ alias.
|
// must downgrade to may-alias.
|
||||||
if (isMustAlias())
|
if (!any_of(MemoryLocs, [&](const MemoryLocation &ASMemLoc) {
|
||||||
if (PointerRec *P = getSomePointer()) {
|
return AST.getAliasAnalysis().isMustAlias(MemLoc, ASMemLoc);
|
||||||
if (!KnownMustAlias) {
|
}))
|
||||||
BatchAAResults &AA = AST.getAliasAnalysis();
|
Alias = SetMayAlias;
|
||||||
AliasResult Result = AA.alias(
|
}
|
||||||
MemoryLocation(P->getValue(), P->getSize(), P->getAAInfo()),
|
|
||||||
MemoryLocation(Entry.getValue(), Size, AAInfo));
|
|
||||||
if (Result != AliasResult::MustAlias) {
|
|
||||||
Alias = SetMayAlias;
|
|
||||||
AST.TotalMayAliasSetSize += size();
|
|
||||||
}
|
|
||||||
assert(Result != AliasResult::NoAlias && "Cannot be part of must set!");
|
|
||||||
} else if (!SkipSizeUpdate)
|
|
||||||
P->updateSizeAndAAInfo(Size, AAInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
Entry.setAliasSet(this);
|
|
||||||
Entry.updateSizeAndAAInfo(Size, AAInfo);
|
|
||||||
|
|
||||||
// Add it to the end of the list...
|
// Add it to the end of the list...
|
||||||
++SetSize;
|
MemoryLocs.push_back(MemLoc);
|
||||||
assert(*PtrListEnd == nullptr && "End of list is not null?");
|
|
||||||
*PtrListEnd = &Entry;
|
|
||||||
PtrListEnd = Entry.setPrevInList(PtrListEnd);
|
|
||||||
assert(*PtrListEnd == nullptr && "End of list is not null?");
|
|
||||||
// Entry points to alias set.
|
|
||||||
addRef();
|
|
||||||
|
|
||||||
if (Alias == SetMayAlias)
|
AST.TotalAliasSetSize++;
|
||||||
AST.TotalMayAliasSetSize++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AliasSet::addUnknownInst(Instruction *I, BatchAAResults &AA) {
|
void AliasSet::addUnknownInst(Instruction *I, BatchAAResults &AA) {
|
||||||
@ -183,45 +147,26 @@ void AliasSet::addUnknownInst(Instruction *I, BatchAAResults &AA) {
|
|||||||
Access = ModRefAccess;
|
Access = ModRefAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// aliasesPointer - If the specified pointer "may" (or must) alias one of the
|
/// aliasesMemoryLocation - If the specified memory location "may" (or must)
|
||||||
/// members in the set return the appropriate AliasResult. Otherwise return
|
/// alias one of the members in the set return the appropriate AliasResult.
|
||||||
/// NoAlias.
|
/// Otherwise return NoAlias.
|
||||||
///
|
///
|
||||||
AliasResult AliasSet::aliasesPointer(const Value *Ptr, LocationSize Size,
|
AliasResult AliasSet::aliasesMemoryLocation(const MemoryLocation &MemLoc,
|
||||||
const AAMDNodes &AAInfo,
|
BatchAAResults &AA) const {
|
||||||
BatchAAResults &AA) const {
|
|
||||||
if (AliasAny)
|
if (AliasAny)
|
||||||
return AliasResult::MayAlias;
|
return AliasResult::MayAlias;
|
||||||
|
|
||||||
if (Alias == SetMustAlias) {
|
// Check all of the memory locations in the set...
|
||||||
assert(UnknownInsts.empty() && "Illegal must alias set!");
|
for (const auto &ASMemLoc : MemoryLocs) {
|
||||||
|
AliasResult AR = AA.alias(MemLoc, ASMemLoc);
|
||||||
// If this is a set of MustAliases, only check to see if the pointer aliases
|
|
||||||
// SOME value in the set.
|
|
||||||
PointerRec *SomePtr = getSomePointer();
|
|
||||||
assert(SomePtr && "Empty must-alias set??");
|
|
||||||
return AA.alias(MemoryLocation(SomePtr->getValue(), SomePtr->getSize(),
|
|
||||||
SomePtr->getAAInfo()),
|
|
||||||
MemoryLocation(Ptr, Size, AAInfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this is a may-alias set, we have to check all of the pointers in the set
|
|
||||||
// to be sure it doesn't alias the set...
|
|
||||||
for (iterator I = begin(), E = end(); I != E; ++I) {
|
|
||||||
AliasResult AR =
|
|
||||||
AA.alias(MemoryLocation(Ptr, Size, AAInfo),
|
|
||||||
MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()));
|
|
||||||
if (AR != AliasResult::NoAlias)
|
if (AR != AliasResult::NoAlias)
|
||||||
return AR;
|
return AR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the unknown instructions...
|
// Check the unknown instructions...
|
||||||
if (!UnknownInsts.empty()) {
|
for (Instruction *Inst : UnknownInsts)
|
||||||
for (Instruction *Inst : UnknownInsts)
|
if (isModOrRefSet(AA.getModRefInfo(Inst, MemLoc)))
|
||||||
if (isModOrRefSet(
|
return AliasResult::MayAlias;
|
||||||
AA.getModRefInfo(Inst, MemoryLocation(Ptr, Size, AAInfo))))
|
|
||||||
return AliasResult::MayAlias;
|
|
||||||
}
|
|
||||||
|
|
||||||
return AliasResult::NoAlias;
|
return AliasResult::NoAlias;
|
||||||
}
|
}
|
||||||
@ -246,9 +191,8 @@ ModRefInfo AliasSet::aliasesUnknownInst(const Instruction *Inst,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ModRefInfo MR = ModRefInfo::NoModRef;
|
ModRefInfo MR = ModRefInfo::NoModRef;
|
||||||
for (iterator I = begin(), E = end(); I != E; ++I) {
|
for (const auto &ASMemLoc : MemoryLocs) {
|
||||||
MR |= AA.getModRefInfo(
|
MR |= AA.getModRefInfo(Inst, ASMemLoc);
|
||||||
Inst, MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()));
|
|
||||||
if (isModAndRefSet(MR))
|
if (isModAndRefSet(MR))
|
||||||
return MR;
|
return MR;
|
||||||
}
|
}
|
||||||
@ -256,37 +200,46 @@ ModRefInfo AliasSet::aliasesUnknownInst(const Instruction *Inst,
|
|||||||
return MR;
|
return MR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AliasSet::PointerVector AliasSet::getPointers() const {
|
||||||
|
SmallSetVector<const Value *, 8> Pointers;
|
||||||
|
for (const MemoryLocation &MemLoc : MemoryLocs)
|
||||||
|
Pointers.insert(MemLoc.Ptr);
|
||||||
|
return Pointers.takeVector();
|
||||||
|
}
|
||||||
|
|
||||||
void AliasSetTracker::clear() {
|
void AliasSetTracker::clear() {
|
||||||
// Delete all the PointerRec entries.
|
|
||||||
for (auto &I : PointerMap)
|
|
||||||
I.second->eraseFromList();
|
|
||||||
|
|
||||||
PointerMap.clear();
|
PointerMap.clear();
|
||||||
|
|
||||||
// The alias sets should all be clear now.
|
|
||||||
AliasSets.clear();
|
AliasSets.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// mergeAliasSetsForPointer - Given a pointer, merge all alias sets that may
|
/// mergeAliasSetsForMemoryLocation - Given a memory location, merge all alias
|
||||||
/// alias the pointer. Return the unified set, or nullptr if no set that aliases
|
/// sets that may alias it. Return the unified set, or nullptr if no aliasing
|
||||||
/// the pointer was found. MustAliasAll is updated to true/false if the pointer
|
/// set was found. A known existing alias set for the pointer value of the
|
||||||
/// is found to MustAlias all the sets it merged.
|
/// memory location can be passed in (or nullptr if not available). MustAliasAll
|
||||||
AliasSet *AliasSetTracker::mergeAliasSetsForPointer(const Value *Ptr,
|
/// is updated to true/false if the memory location is found to MustAlias all
|
||||||
LocationSize Size,
|
/// the sets it merged.
|
||||||
const AAMDNodes &AAInfo,
|
AliasSet *AliasSetTracker::mergeAliasSetsForMemoryLocation(
|
||||||
bool &MustAliasAll) {
|
const MemoryLocation &MemLoc, AliasSet *PtrAS, bool &MustAliasAll) {
|
||||||
AliasSet *FoundSet = nullptr;
|
AliasSet *FoundSet = nullptr;
|
||||||
MustAliasAll = true;
|
MustAliasAll = true;
|
||||||
for (AliasSet &AS : llvm::make_early_inc_range(*this)) {
|
for (AliasSet &AS : llvm::make_early_inc_range(*this)) {
|
||||||
if (AS.Forward)
|
if (AS.Forward)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
AliasResult AR = AS.aliasesPointer(Ptr, Size, AAInfo, AA);
|
// An alias set that already contains a memory location with the same
|
||||||
if (AR == AliasResult::NoAlias)
|
// pointer value is directly assumed to MustAlias; we bypass the AA query in
|
||||||
continue;
|
// this case.
|
||||||
|
// Note: it is not guaranteed that AA would always provide the same result;
|
||||||
|
// a known exception are undef pointer values, where alias(undef, undef) is
|
||||||
|
// NoAlias, while we treat it as MustAlias.
|
||||||
|
if (&AS != PtrAS) {
|
||||||
|
AliasResult AR = AS.aliasesMemoryLocation(MemLoc, AA);
|
||||||
|
if (AR == AliasResult::NoAlias)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (AR != AliasResult::MustAlias)
|
if (AR != AliasResult::MustAlias)
|
||||||
MustAliasAll = false;
|
MustAliasAll = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!FoundSet) {
|
if (!FoundSet) {
|
||||||
// If this is the first alias set ptr can go into, remember it.
|
// If this is the first alias set ptr can go into, remember it.
|
||||||
@ -317,91 +270,77 @@ AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction *Inst) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AliasSet &AliasSetTracker::getAliasSetFor(const MemoryLocation &MemLoc) {
|
AliasSet &AliasSetTracker::getAliasSetFor(const MemoryLocation &MemLoc) {
|
||||||
|
// The alias sets are indexed with a map from the memory locations' pointer
|
||||||
|
// values. If the memory location is already registered, we can find it in the
|
||||||
|
// alias set associated with its pointer.
|
||||||
|
AliasSet *&MapEntry = PointerMap[MemLoc.Ptr];
|
||||||
|
if (MapEntry) {
|
||||||
|
collapseForwardingIn(MapEntry);
|
||||||
|
if (is_contained(MapEntry->MemoryLocs, MemLoc))
|
||||||
|
return *MapEntry;
|
||||||
|
}
|
||||||
|
|
||||||
Value * const Pointer = const_cast<Value*>(MemLoc.Ptr);
|
AliasSet *AS;
|
||||||
const LocationSize Size = MemLoc.Size;
|
bool MustAliasAll = false;
|
||||||
const AAMDNodes &AAInfo = MemLoc.AATags;
|
|
||||||
|
|
||||||
AliasSet::PointerRec &Entry = getEntryFor(Pointer);
|
|
||||||
|
|
||||||
if (AliasAnyAS) {
|
if (AliasAnyAS) {
|
||||||
// At this point, the AST is saturated, so we only have one active alias
|
// At this point, the AST is saturated, so we only have one active alias
|
||||||
// set. That means we already know which alias set we want to return, and
|
// set. That means we already know which alias set we want to return, and
|
||||||
// just need to add the pointer to that set to keep the data structure
|
// just need to add the memory location to that set to keep the data
|
||||||
// consistent.
|
// structure consistent.
|
||||||
// This, of course, means that we will never need a merge here.
|
// This, of course, means that we will never need a merge here.
|
||||||
if (Entry.hasAliasSet()) {
|
AS = AliasAnyAS;
|
||||||
Entry.updateSizeAndAAInfo(Size, AAInfo);
|
} else if (AliasSet *AliasAS = mergeAliasSetsForMemoryLocation(
|
||||||
assert(Entry.getAliasSet(*this) == AliasAnyAS &&
|
MemLoc, MapEntry, MustAliasAll)) {
|
||||||
"Entry in saturated AST must belong to only alias set");
|
|
||||||
} else {
|
|
||||||
AliasAnyAS->addPointer(*this, Entry, Size, AAInfo);
|
|
||||||
}
|
|
||||||
return *AliasAnyAS;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MustAliasAll = false;
|
|
||||||
// Check to see if the pointer is already known.
|
|
||||||
if (Entry.hasAliasSet()) {
|
|
||||||
// If the size changed, we may need to merge several alias sets.
|
|
||||||
// Note that we can *not* return the result of mergeAliasSetsForPointer
|
|
||||||
// due to a quirk of alias analysis behavior. Since alias(undef, undef)
|
|
||||||
// is NoAlias, mergeAliasSetsForPointer(undef, ...) will not find the
|
|
||||||
// the right set for undef, even if it exists.
|
|
||||||
if (Entry.updateSizeAndAAInfo(Size, AAInfo)) {
|
|
||||||
mergeAliasSetsForPointer(Pointer, Size, AAInfo, MustAliasAll);
|
|
||||||
|
|
||||||
// For MustAlias sets, also update Size/AAInfo of the representative
|
|
||||||
// pointer.
|
|
||||||
AliasSet &AS = *Entry.getAliasSet(*this);
|
|
||||||
if (AS.isMustAlias())
|
|
||||||
if (AliasSet::PointerRec *P = AS.getSomePointer())
|
|
||||||
P->updateSizeAndAAInfo(Size, AAInfo);
|
|
||||||
}
|
|
||||||
// Return the set!
|
|
||||||
return *Entry.getAliasSet(*this)->getForwardedTarget(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AliasSet *AS =
|
|
||||||
mergeAliasSetsForPointer(Pointer, Size, AAInfo, MustAliasAll)) {
|
|
||||||
// Add it to the alias set it aliases.
|
// Add it to the alias set it aliases.
|
||||||
AS->addPointer(*this, Entry, Size, AAInfo, MustAliasAll);
|
AS = AliasAS;
|
||||||
return *AS;
|
} else {
|
||||||
|
// Otherwise create a new alias set to hold the new memory location.
|
||||||
|
AliasSets.push_back(AS = new AliasSet());
|
||||||
|
MustAliasAll = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise create a new alias set to hold the loaded pointer.
|
// Register memory location in selected alias set.
|
||||||
AliasSets.push_back(new AliasSet());
|
AS->addMemoryLocation(*this, MemLoc, MustAliasAll);
|
||||||
AliasSets.back().addPointer(*this, Entry, Size, AAInfo, true);
|
// Register selected alias set in pointer map (or ensure it is consistent with
|
||||||
return AliasSets.back();
|
// earlier map entry after taking into account new merging).
|
||||||
|
if (MapEntry) {
|
||||||
|
collapseForwardingIn(MapEntry);
|
||||||
|
assert(MapEntry == AS && "Memory locations with same pointer value cannot "
|
||||||
|
"be in different alias sets");
|
||||||
|
} else {
|
||||||
|
AS->addRef();
|
||||||
|
MapEntry = AS;
|
||||||
|
}
|
||||||
|
return *AS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AliasSetTracker::add(const MemoryLocation &Loc) {
|
void AliasSetTracker::add(const MemoryLocation &Loc) {
|
||||||
addPointer(Loc, AliasSet::NoAccess);
|
addMemoryLocation(Loc, AliasSet::NoAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AliasSetTracker::add(LoadInst *LI) {
|
void AliasSetTracker::add(LoadInst *LI) {
|
||||||
if (isStrongerThanMonotonic(LI->getOrdering()))
|
if (isStrongerThanMonotonic(LI->getOrdering()))
|
||||||
return addUnknown(LI);
|
return addUnknown(LI);
|
||||||
addPointer(MemoryLocation::get(LI), AliasSet::RefAccess);
|
addMemoryLocation(MemoryLocation::get(LI), AliasSet::RefAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AliasSetTracker::add(StoreInst *SI) {
|
void AliasSetTracker::add(StoreInst *SI) {
|
||||||
if (isStrongerThanMonotonic(SI->getOrdering()))
|
if (isStrongerThanMonotonic(SI->getOrdering()))
|
||||||
return addUnknown(SI);
|
return addUnknown(SI);
|
||||||
addPointer(MemoryLocation::get(SI), AliasSet::ModAccess);
|
addMemoryLocation(MemoryLocation::get(SI), AliasSet::ModAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AliasSetTracker::add(VAArgInst *VAAI) {
|
void AliasSetTracker::add(VAArgInst *VAAI) {
|
||||||
addPointer(MemoryLocation::get(VAAI), AliasSet::ModRefAccess);
|
addMemoryLocation(MemoryLocation::get(VAAI), AliasSet::ModRefAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AliasSetTracker::add(AnyMemSetInst *MSI) {
|
void AliasSetTracker::add(AnyMemSetInst *MSI) {
|
||||||
addPointer(MemoryLocation::getForDest(MSI), AliasSet::ModAccess);
|
addMemoryLocation(MemoryLocation::getForDest(MSI), AliasSet::ModAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AliasSetTracker::add(AnyMemTransferInst *MTI) {
|
void AliasSetTracker::add(AnyMemTransferInst *MTI) {
|
||||||
addPointer(MemoryLocation::getForDest(MTI), AliasSet::ModAccess);
|
addMemoryLocation(MemoryLocation::getForDest(MTI), AliasSet::ModAccess);
|
||||||
addPointer(MemoryLocation::getForSource(MTI), AliasSet::RefAccess);
|
addMemoryLocation(MemoryLocation::getForSource(MTI), AliasSet::RefAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AliasSetTracker::addUnknown(Instruction *Inst) {
|
void AliasSetTracker::addUnknown(Instruction *Inst) {
|
||||||
@ -480,7 +419,7 @@ void AliasSetTracker::add(Instruction *I) {
|
|||||||
ModRefInfo ArgMask = AA.getArgModRefInfo(Call, ArgIdx);
|
ModRefInfo ArgMask = AA.getArgModRefInfo(Call, ArgIdx);
|
||||||
ArgMask &= CallMask;
|
ArgMask &= CallMask;
|
||||||
if (!isNoModRef(ArgMask))
|
if (!isNoModRef(ArgMask))
|
||||||
addPointer(ArgLoc, getAccessFromModRef(ArgMask));
|
addMemoryLocation(ArgLoc, getAccessFromModRef(ArgMask));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -497,7 +436,7 @@ void AliasSetTracker::add(const AliasSetTracker &AST) {
|
|||||||
assert(&AA == &AST.AA &&
|
assert(&AA == &AST.AA &&
|
||||||
"Merging AliasSetTracker objects with different Alias Analyses!");
|
"Merging AliasSetTracker objects with different Alias Analyses!");
|
||||||
|
|
||||||
// Loop over all of the alias sets in AST, adding the pointers contained
|
// Loop over all of the alias sets in AST, adding the members contained
|
||||||
// therein into the current alias sets. This can cause alias sets to be
|
// therein into the current alias sets. This can cause alias sets to be
|
||||||
// merged together in the current AST.
|
// merged together in the current AST.
|
||||||
for (const AliasSet &AS : AST) {
|
for (const AliasSet &AS : AST) {
|
||||||
@ -508,16 +447,14 @@ void AliasSetTracker::add(const AliasSetTracker &AST) {
|
|||||||
for (Instruction *Inst : AS.UnknownInsts)
|
for (Instruction *Inst : AS.UnknownInsts)
|
||||||
add(Inst);
|
add(Inst);
|
||||||
|
|
||||||
// Loop over all of the pointers in this alias set.
|
// Loop over all of the memory locations in this alias set.
|
||||||
for (AliasSet::iterator ASI = AS.begin(), E = AS.end(); ASI != E; ++ASI)
|
for (const MemoryLocation &ASMemLoc : AS.MemoryLocs)
|
||||||
addPointer(
|
addMemoryLocation(ASMemLoc, (AliasSet::AccessLattice)AS.Access);
|
||||||
MemoryLocation(ASI.getPointer(), ASI.getSize(), ASI.getAAInfo()),
|
|
||||||
(AliasSet::AccessLattice)AS.Access);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AliasSet &AliasSetTracker::mergeAllAliasSets() {
|
AliasSet &AliasSetTracker::mergeAllAliasSets() {
|
||||||
assert(!AliasAnyAS && (TotalMayAliasSetSize > SaturationThreshold) &&
|
assert(!AliasAnyAS && (TotalAliasSetSize > SaturationThreshold) &&
|
||||||
"Full merge should happen once, when the saturation threshold is "
|
"Full merge should happen once, when the saturation threshold is "
|
||||||
"reached");
|
"reached");
|
||||||
|
|
||||||
@ -528,8 +465,8 @@ AliasSet &AliasSetTracker::mergeAllAliasSets() {
|
|||||||
for (AliasSet &AS : *this)
|
for (AliasSet &AS : *this)
|
||||||
ASVector.push_back(&AS);
|
ASVector.push_back(&AS);
|
||||||
|
|
||||||
// Copy all instructions and pointers into a new set, and forward all other
|
// Copy all instructions and memory locations into a new set, and forward all
|
||||||
// sets to it.
|
// other sets to it.
|
||||||
AliasSets.push_back(new AliasSet());
|
AliasSets.push_back(new AliasSet());
|
||||||
AliasAnyAS = &AliasSets.back();
|
AliasAnyAS = &AliasSets.back();
|
||||||
AliasAnyAS->Alias = AliasSet::SetMayAlias;
|
AliasAnyAS->Alias = AliasSet::SetMayAlias;
|
||||||
@ -553,14 +490,14 @@ AliasSet &AliasSetTracker::mergeAllAliasSets() {
|
|||||||
return *AliasAnyAS;
|
return *AliasAnyAS;
|
||||||
}
|
}
|
||||||
|
|
||||||
AliasSet &AliasSetTracker::addPointer(MemoryLocation Loc,
|
AliasSet &AliasSetTracker::addMemoryLocation(MemoryLocation Loc,
|
||||||
AliasSet::AccessLattice E) {
|
AliasSet::AccessLattice E) {
|
||||||
AliasSet &AS = getAliasSetFor(Loc);
|
AliasSet &AS = getAliasSetFor(Loc);
|
||||||
AS.Access |= E;
|
AS.Access |= E;
|
||||||
|
|
||||||
if (!AliasAnyAS && (TotalMayAliasSetSize > SaturationThreshold)) {
|
if (!AliasAnyAS && (TotalAliasSetSize > SaturationThreshold)) {
|
||||||
// The AST is now saturated. From here on, we conservatively consider all
|
// The AST is now saturated. From here on, we conservatively consider all
|
||||||
// pointers to alias each-other.
|
// elements to alias each-other.
|
||||||
return mergeAllAliasSets();
|
return mergeAllAliasSets();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -584,17 +521,18 @@ void AliasSet::print(raw_ostream &OS) const {
|
|||||||
if (Forward)
|
if (Forward)
|
||||||
OS << " forwarding to " << (void*)Forward;
|
OS << " forwarding to " << (void*)Forward;
|
||||||
|
|
||||||
if (!empty()) {
|
if (!MemoryLocs.empty()) {
|
||||||
OS << "Pointers: ";
|
ListSeparator LS;
|
||||||
for (iterator I = begin(), E = end(); I != E; ++I) {
|
OS << "Memory locations: ";
|
||||||
if (I != begin()) OS << ", ";
|
for (const MemoryLocation &MemLoc : MemoryLocs) {
|
||||||
I.getPointer()->printAsOperand(OS << "(");
|
OS << LS;
|
||||||
if (I.getSize() == LocationSize::afterPointer())
|
MemLoc.Ptr->printAsOperand(OS << "(");
|
||||||
|
if (MemLoc.Size == LocationSize::afterPointer())
|
||||||
OS << ", unknown after)";
|
OS << ", unknown after)";
|
||||||
else if (I.getSize() == LocationSize::beforeOrAfterPointer())
|
else if (MemLoc.Size == LocationSize::beforeOrAfterPointer())
|
||||||
OS << ", unknown before-or-after)";
|
OS << ", unknown before-or-after)";
|
||||||
else
|
else
|
||||||
OS << ", " << I.getSize() << ")";
|
OS << ", " << MemLoc.Size << ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!UnknownInsts.empty()) {
|
if (!UnknownInsts.empty()) {
|
||||||
|
@ -1115,6 +1115,7 @@ bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck,
|
|||||||
int NumWritePtrChecks = 0;
|
int NumWritePtrChecks = 0;
|
||||||
bool CanDoAliasSetRT = true;
|
bool CanDoAliasSetRT = true;
|
||||||
++ASId;
|
++ASId;
|
||||||
|
auto ASPointers = AS.getPointers();
|
||||||
|
|
||||||
// We assign consecutive id to access from different dependence sets.
|
// We assign consecutive id to access from different dependence sets.
|
||||||
// Accesses within the same set don't need a runtime check.
|
// Accesses within the same set don't need a runtime check.
|
||||||
@ -1126,8 +1127,8 @@ bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck,
|
|||||||
// First, count how many write and read accesses are in the alias set. Also
|
// First, count how many write and read accesses are in the alias set. Also
|
||||||
// collect MemAccessInfos for later.
|
// collect MemAccessInfos for later.
|
||||||
SmallVector<MemAccessInfo, 4> AccessInfos;
|
SmallVector<MemAccessInfo, 4> AccessInfos;
|
||||||
for (const auto &A : AS) {
|
for (const Value *Ptr_ : ASPointers) {
|
||||||
Value *Ptr = A.getValue();
|
Value *Ptr = const_cast<Value *>(Ptr_);
|
||||||
bool IsWrite = Accesses.count(MemAccessInfo(Ptr, true));
|
bool IsWrite = Accesses.count(MemAccessInfo(Ptr, true));
|
||||||
if (IsWrite)
|
if (IsWrite)
|
||||||
++NumWritePtrChecks;
|
++NumWritePtrChecks;
|
||||||
@ -1140,10 +1141,11 @@ bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck,
|
|||||||
// or a single write and no reads.
|
// or a single write and no reads.
|
||||||
if (NumWritePtrChecks == 0 ||
|
if (NumWritePtrChecks == 0 ||
|
||||||
(NumWritePtrChecks == 1 && NumReadPtrChecks == 0)) {
|
(NumWritePtrChecks == 1 && NumReadPtrChecks == 0)) {
|
||||||
assert((AS.size() <= 1 ||
|
assert((ASPointers.size() <= 1 ||
|
||||||
all_of(AS,
|
all_of(ASPointers,
|
||||||
[this](auto AC) {
|
[this](const Value *Ptr) {
|
||||||
MemAccessInfo AccessWrite(AC.getValue(), true);
|
MemAccessInfo AccessWrite(const_cast<Value *>(Ptr),
|
||||||
|
true);
|
||||||
return DepCands.findValue(AccessWrite) == DepCands.end();
|
return DepCands.findValue(AccessWrite) == DepCands.end();
|
||||||
})) &&
|
})) &&
|
||||||
"Can only skip updating CanDoRT below, if all entries in AS "
|
"Can only skip updating CanDoRT below, if all entries in AS "
|
||||||
@ -1271,8 +1273,9 @@ void AccessAnalysis::processMemAccesses() {
|
|||||||
// set.
|
// set.
|
||||||
for (const auto &AS : AST) {
|
for (const auto &AS : AST) {
|
||||||
// Note that both the alias-set tracker and the alias sets themselves used
|
// Note that both the alias-set tracker and the alias sets themselves used
|
||||||
// linked lists internally and so the iteration order here is deterministic
|
// ordered collections internally and so the iteration order here is
|
||||||
// (matching the original instruction order within each set).
|
// deterministic.
|
||||||
|
auto ASPointers = AS.getPointers();
|
||||||
|
|
||||||
bool SetHasWrite = false;
|
bool SetHasWrite = false;
|
||||||
|
|
||||||
@ -1289,8 +1292,8 @@ void AccessAnalysis::processMemAccesses() {
|
|||||||
bool UseDeferred = SetIteration > 0;
|
bool UseDeferred = SetIteration > 0;
|
||||||
PtrAccessMap &S = UseDeferred ? DeferredAccesses : Accesses;
|
PtrAccessMap &S = UseDeferred ? DeferredAccesses : Accesses;
|
||||||
|
|
||||||
for (const auto &AV : AS) {
|
for (const Value *Ptr_ : ASPointers) {
|
||||||
Value *Ptr = AV.getValue();
|
Value *Ptr = const_cast<Value *>(Ptr_);
|
||||||
|
|
||||||
// For a single memory access in AliasSetTracker, Accesses may contain
|
// For a single memory access in AliasSetTracker, Accesses may contain
|
||||||
// both read and write, and they both need to be handled for CheckDeps.
|
// both read and write, and they both need to be handled for CheckDeps.
|
||||||
|
@ -2323,8 +2323,8 @@ collectPromotionCandidates(MemorySSA *MSSA, AliasAnalysis *AA, Loop *L) {
|
|||||||
SmallVector<std::pair<SmallSetVector<Value *, 8>, bool>, 0> Result;
|
SmallVector<std::pair<SmallSetVector<Value *, 8>, bool>, 0> Result;
|
||||||
for (auto [Set, HasReadsOutsideSet] : Sets) {
|
for (auto [Set, HasReadsOutsideSet] : Sets) {
|
||||||
SmallSetVector<Value *, 8> PointerMustAliases;
|
SmallSetVector<Value *, 8> PointerMustAliases;
|
||||||
for (const auto &ASI : *Set)
|
for (const auto &MemLoc : *Set)
|
||||||
PointerMustAliases.insert(ASI.getValue());
|
PointerMustAliases.insert(const_cast<Value *>(MemLoc.Ptr));
|
||||||
Result.emplace_back(std::move(PointerMustAliases), HasReadsOutsideSet);
|
Result.emplace_back(std::move(PointerMustAliases), HasReadsOutsideSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,13 +258,13 @@ bool LoopVersioningLICM::legalLoopMemoryAccesses() {
|
|||||||
// With MustAlias its not worth adding runtime bound check.
|
// With MustAlias its not worth adding runtime bound check.
|
||||||
if (AS.isMustAlias())
|
if (AS.isMustAlias())
|
||||||
return false;
|
return false;
|
||||||
Value *SomePtr = AS.begin()->getValue();
|
const Value *SomePtr = AS.begin()->Ptr;
|
||||||
bool TypeCheck = true;
|
bool TypeCheck = true;
|
||||||
// Check for Mod & MayAlias
|
// Check for Mod & MayAlias
|
||||||
HasMayAlias |= AS.isMayAlias();
|
HasMayAlias |= AS.isMayAlias();
|
||||||
HasMod |= AS.isMod();
|
HasMod |= AS.isMod();
|
||||||
for (const auto &A : AS) {
|
for (const auto &MemLoc : AS) {
|
||||||
Value *Ptr = A.getValue();
|
const Value *Ptr = MemLoc.Ptr;
|
||||||
// Alias tracker should have pointers of same data type.
|
// Alias tracker should have pointers of same data type.
|
||||||
//
|
//
|
||||||
// FIXME: check no longer effective since opaque pointers?
|
// FIXME: check no longer effective since opaque pointers?
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test_alloca_argmemonly':
|
; CHECK: Alias sets for function 'test_alloca_argmemonly':
|
||||||
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 3 pointer values.
|
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 3 pointer values.
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %d, unknown before-or-after), (ptr %s, unknown before-or-after)
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %d, unknown before-or-after), (ptr %s, unknown before-or-after)
|
||||||
define void @test_alloca_argmemonly(ptr %s, ptr %d) {
|
define void @test_alloca_argmemonly(ptr %s, ptr %d) {
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8, align 1
|
%a = alloca i8, align 1
|
||||||
@ -17,8 +17,8 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test_readonly_arg'
|
; CHECK: Alias sets for function 'test_readonly_arg'
|
||||||
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %d, unknown before-or-after)
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %d, unknown before-or-after)
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Pointers: (ptr %s, unknown before-or-after)
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Memory locations: (ptr %s, unknown before-or-after), (ptr %s, LocationSize::precise(1))
|
||||||
define i8 @test_readonly_arg(ptr noalias %s, ptr noalias %d) {
|
define i8 @test_readonly_arg(ptr noalias %s, ptr noalias %d) {
|
||||||
entry:
|
entry:
|
||||||
call void @my_memcpy(ptr %d, ptr %s, i64 1)
|
call void @my_memcpy(ptr %d, ptr %s, i64 1)
|
||||||
@ -28,8 +28,8 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test_noalias_argmemonly':
|
; CHECK: Alias sets for function 'test_noalias_argmemonly':
|
||||||
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 3 pointer values.
|
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 3 pointer values.
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %d, unknown before-or-after), (ptr %s, unknown before-or-after)
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %d, unknown before-or-after), (ptr %s, unknown before-or-after)
|
||||||
define void @test_noalias_argmemonly(ptr noalias %a, ptr %s, ptr %d) {
|
define void @test_noalias_argmemonly(ptr noalias %a, ptr %s, ptr %d) {
|
||||||
entry:
|
entry:
|
||||||
store i8 1, ptr %a, align 1
|
store i8 1, ptr %a, align 1
|
||||||
@ -39,8 +39,8 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test5':
|
; CHECK: Alias sets for function 'test5':
|
||||||
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, unknown before-or-after)
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1)), (ptr %a, unknown before-or-after)
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, unknown before-or-after)
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, unknown before-or-after), (ptr %b, LocationSize::precise(1))
|
||||||
define void @test5(ptr noalias %a, ptr noalias %b) {
|
define void @test5(ptr noalias %a, ptr noalias %b) {
|
||||||
entry:
|
entry:
|
||||||
store i8 1, ptr %a, align 1
|
store i8 1, ptr %a, align 1
|
||||||
@ -51,8 +51,8 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test_argcollapse':
|
; CHECK: Alias sets for function 'test_argcollapse':
|
||||||
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, unknown before-or-after)
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1)), (ptr %a, unknown before-or-after)
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %b, unknown before-or-after)
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %b, unknown before-or-after), (ptr %b, LocationSize::precise(1))
|
||||||
define void @test_argcollapse(ptr noalias %a, ptr noalias %b) {
|
define void @test_argcollapse(ptr noalias %a, ptr noalias %b) {
|
||||||
entry:
|
entry:
|
||||||
store i8 1, ptr %a, align 1
|
store i8 1, ptr %a, align 1
|
||||||
@ -63,8 +63,8 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test_memcpy1':
|
; CHECK: Alias sets for function 'test_memcpy1':
|
||||||
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %b, unknown before-or-after)
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %b, unknown before-or-after)
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, unknown before-or-after)
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, unknown before-or-after)
|
||||||
define void @test_memcpy1(ptr noalias %a, ptr noalias %b) {
|
define void @test_memcpy1(ptr noalias %a, ptr noalias %b) {
|
||||||
entry:
|
entry:
|
||||||
call void @my_memcpy(ptr %b, ptr %a, i64 1)
|
call void @my_memcpy(ptr %b, ptr %a, i64 1)
|
||||||
@ -74,7 +74,7 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test_memset1':
|
; CHECK: Alias sets for function 'test_memset1':
|
||||||
; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 1 pointer values.
|
; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 1 pointer values.
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, unknown before-or-after)
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, unknown before-or-after)
|
||||||
define void @test_memset1() {
|
define void @test_memset1() {
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8, align 1
|
%a = alloca i8, align 1
|
||||||
@ -84,7 +84,7 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test_memset2':
|
; CHECK: Alias sets for function 'test_memset2':
|
||||||
; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 1 pointer values.
|
; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 1 pointer values.
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, unknown before-or-after)
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, unknown before-or-after)
|
||||||
define void @test_memset2(ptr %a) {
|
define void @test_memset2(ptr %a) {
|
||||||
entry:
|
entry:
|
||||||
call void @my_memset(ptr %a, i8 0, i64 1)
|
call void @my_memset(ptr %a, i8 0, i64 1)
|
||||||
@ -93,7 +93,7 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test_memset3':
|
; CHECK: Alias sets for function 'test_memset3':
|
||||||
; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 2 pointer values.
|
; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 2 pointer values.
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod Pointers: (ptr %a, unknown before-or-after), (ptr %b, unknown before-or-after)
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod Memory locations: (ptr %a, unknown before-or-after), (ptr %b, unknown before-or-after)
|
||||||
define void @test_memset3(ptr %a, ptr %b) {
|
define void @test_memset3(ptr %a, ptr %b) {
|
||||||
entry:
|
entry:
|
||||||
call void @my_memset(ptr %a, i8 0, i64 1)
|
call void @my_memset(ptr %a, i8 0, i64 1)
|
||||||
@ -105,8 +105,8 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test_memset4':
|
; CHECK: Alias sets for function 'test_memset4':
|
||||||
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, unknown before-or-after)
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, unknown before-or-after)
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, unknown before-or-after)
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, unknown before-or-after)
|
||||||
define void @test_memset4(ptr noalias %a, ptr noalias %b) {
|
define void @test_memset4(ptr noalias %a, ptr noalias %b) {
|
||||||
entry:
|
entry:
|
||||||
call void @my_memset(ptr %a, i8 0, i64 1)
|
call void @my_memset(ptr %a, i8 0, i64 1)
|
||||||
@ -121,7 +121,7 @@ declare void @my_memmove(ptr nocapture, ptr nocapture readonly, i64) argmemonly
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test_attribute_intersect':
|
; CHECK: Alias sets for function 'test_attribute_intersect':
|
||||||
; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 1 pointer values.
|
; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 1 pointer values.
|
||||||
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
define i8 @test_attribute_intersect(ptr noalias %a) {
|
define i8 @test_attribute_intersect(ptr noalias %a) {
|
||||||
entry:
|
entry:
|
||||||
;; This call is effectively readnone since the argument is readonly
|
;; This call is effectively readnone since the argument is readonly
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test1':
|
; CHECK: Alias sets for function 'test1':
|
||||||
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK-NOT: 1 Unknown instruction
|
; CHECK-NOT: 1 Unknown instruction
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
|
||||||
define void @test1(i32 %c) {
|
define void @test1(i32 %c) {
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8, align 1
|
%a = alloca i8, align 1
|
||||||
@ -18,10 +18,10 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test2':
|
; CHECK: Alias sets for function 'test2':
|
||||||
; CHECK: Alias Set Tracker: 3 alias sets for 2 pointer values.
|
; CHECK: Alias Set Tracker: 3 alias sets for 2 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] may alias, Ref
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] may alias, Ref
|
||||||
; CHECK: 1 Unknown instructions: call void (i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]
|
; CHECK: 1 Unknown instructions: call void (i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
|
||||||
define void @test2(i32 %c) {
|
define void @test2(i32 %c) {
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8, align 1
|
%a = alloca i8, align 1
|
||||||
@ -35,7 +35,7 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test3':
|
; CHECK: Alias sets for function 'test3':
|
||||||
; CHECK: Alias Set Tracker: 1 alias sets for 2 pointer values.
|
; CHECK: Alias Set Tracker: 1 alias sets for 2 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 3] may alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(1)), (ptr %b, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 3] may alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1)), (ptr %b, LocationSize::precise(1))
|
||||||
; CHECK: 1 Unknown instructions: call void (i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]
|
; CHECK: 1 Unknown instructions: call void (i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]
|
||||||
define void @test3(i32 %c, ptr %a, ptr %b) {
|
define void @test3(i32 %c, ptr %a, ptr %b) {
|
||||||
entry:
|
entry:
|
||||||
@ -48,9 +48,9 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test4':
|
; CHECK: Alias sets for function 'test4':
|
||||||
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK: 1 Unknown instructions: call void (i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]
|
; CHECK: 1 Unknown instructions: call void (i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
|
||||||
define void @test4(i32 %c, ptr %a) {
|
define void @test4(i32 %c, ptr %a) {
|
||||||
entry:
|
entry:
|
||||||
%b = alloca i8, align 1
|
%b = alloca i8, align 1
|
||||||
@ -63,9 +63,9 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test5':
|
; CHECK: Alias sets for function 'test5':
|
||||||
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK-NOT: 1 Unknown instruction
|
; CHECK-NOT: 1 Unknown instruction
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
|
||||||
define void @test5() {
|
define void @test5() {
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8, align 1
|
%a = alloca i8, align 1
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
; RUN: opt -S < %s -passes=print-alias-sets 2>&1 | FileCheck %s
|
; RUN: opt -S < %s -passes=print-alias-sets 2>&1 | FileCheck %s
|
||||||
|
|
||||||
; CHECK-LABEL: Alias sets for function 'sn'
|
; CHECK-LABEL: Alias sets for function 'sn'
|
||||||
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %p, unknown after)
|
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %p, LocationSize::precise(vscale x 16)), (ptr %p, LocationSize::precise(8))
|
||||||
define void @sn(ptr %p) {;
|
define void @sn(ptr %p) {;
|
||||||
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
|
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
|
||||||
store i64 0, ptr %p, align 2
|
store i64 0, ptr %p, align 2
|
||||||
@ -10,7 +10,7 @@ define void @sn(ptr %p) {;
|
|||||||
}
|
}
|
||||||
|
|
||||||
; CHECK-LABEL: Alias sets for function 'ns'
|
; CHECK-LABEL: Alias sets for function 'ns'
|
||||||
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %p, unknown after)
|
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %p, LocationSize::precise(8)), (ptr %p, LocationSize::precise(vscale x 16))
|
||||||
define void @ns(ptr %p) {
|
define void @ns(ptr %p) {
|
||||||
store i64 0, ptr %p, align 2
|
store i64 0, ptr %p, align 2
|
||||||
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
|
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
|
||||||
@ -18,7 +18,7 @@ define void @ns(ptr %p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
; CHECK-LABEL: Alias sets for function 'ss':
|
; CHECK-LABEL: Alias sets for function 'ss':
|
||||||
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %p, LocationSize::precise(vscale x 16))
|
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %p, LocationSize::precise(vscale x 16))
|
||||||
define void @ss(ptr %p) {
|
define void @ss(ptr %p) {
|
||||||
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
|
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
|
||||||
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
|
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
|
||||||
@ -26,7 +26,7 @@ define void @ss(ptr %p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
; CHECK-LABEL: Alias sets for function 'ss2':
|
; CHECK-LABEL: Alias sets for function 'ss2':
|
||||||
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %p, unknown after)
|
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %p, LocationSize::precise(vscale x 16)), (ptr %p, LocationSize::precise(vscale x 32))
|
||||||
define void @ss2(ptr %p) {
|
define void @ss2(ptr %p) {
|
||||||
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
|
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
|
||||||
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
|
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
|
||||||
@ -34,7 +34,7 @@ define void @ss2(ptr %p) {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: Alias sets for function 'son':
|
; CHECK-LABEL: Alias sets for function 'son':
|
||||||
; CHECK: AliasSet[{{.*}}, 2] may alias, Mod Pointers: (ptr %g, LocationSize::precise(vscale x 16)), (ptr %p, LocationSize::precise(8))
|
; CHECK: AliasSet[{{.*}}, 2] may alias, Mod Memory locations: (ptr %g, LocationSize::precise(vscale x 16)), (ptr %p, LocationSize::precise(8))
|
||||||
define void @son(ptr %p) {
|
define void @son(ptr %p) {
|
||||||
%g = getelementptr i8, ptr %p, i64 8
|
%g = getelementptr i8, ptr %p, i64 8
|
||||||
store <vscale x 2 x i64> zeroinitializer, ptr %g, align 2
|
store <vscale x 2 x i64> zeroinitializer, ptr %g, align 2
|
||||||
@ -43,7 +43,7 @@ define void @son(ptr %p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
; CHECK-LABEL: Alias sets for function 'sno':
|
; CHECK-LABEL: Alias sets for function 'sno':
|
||||||
; CHECK: AliasSet[{{.*}}, 2] may alias, Mod Pointers: (ptr %p, LocationSize::precise(vscale x 16)), (ptr %g, LocationSize::precise(8))
|
; CHECK: AliasSet[{{.*}}, 2] may alias, Mod Memory locations: (ptr %p, LocationSize::precise(vscale x 16)), (ptr %g, LocationSize::precise(8))
|
||||||
define void @sno(ptr %p) {
|
define void @sno(ptr %p) {
|
||||||
%g = getelementptr i8, ptr %p, i64 8
|
%g = getelementptr i8, ptr %p, i64 8
|
||||||
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
|
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test_known_size':
|
; CHECK: Alias sets for function 'test_known_size':
|
||||||
; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values.
|
; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %d, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %d, LocationSize::precise(1))
|
||||||
define void @test_known_size(ptr noalias %d) {
|
define void @test_known_size(ptr noalias %d) {
|
||||||
entry:
|
entry:
|
||||||
call void @llvm.memset.p0.i64(ptr align 1 %d, i8 0, i64 1, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %d, i8 0, i64 1, i1 false)
|
||||||
@ -14,7 +14,7 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test_unknown_size':
|
; CHECK: Alias sets for function 'test_unknown_size':
|
||||||
; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values.
|
; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %d, unknown after)
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %d, unknown after)
|
||||||
define void @test_unknown_size(ptr noalias %d, i64 %len) {
|
define void @test_unknown_size(ptr noalias %d, i64 %len) {
|
||||||
entry:
|
entry:
|
||||||
call void @llvm.memset.p0.i64(ptr align 1 %d, i8 0, i64 %len, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %d, i8 0, i64 %len, i1 false)
|
||||||
@ -24,7 +24,7 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test_atomic_known_size':
|
; CHECK: Alias sets for function 'test_atomic_known_size':
|
||||||
; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values.
|
; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %d, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %d, LocationSize::precise(1))
|
||||||
define void @test_atomic_known_size(ptr noalias %d) {
|
define void @test_atomic_known_size(ptr noalias %d) {
|
||||||
entry:
|
entry:
|
||||||
call void @llvm.memset.element.unordered.atomic.p0.i32(ptr align 1 %d, i8 0, i64 1, i32 1)
|
call void @llvm.memset.element.unordered.atomic.p0.i32(ptr align 1 %d, i8 0, i64 1, i32 1)
|
||||||
@ -33,7 +33,7 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test_atomic_unknown_size':
|
; CHECK: Alias sets for function 'test_atomic_unknown_size':
|
||||||
; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values.
|
; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %d, unknown after)
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %d, unknown after)
|
||||||
define void @test_atomic_unknown_size(ptr noalias %d, i64 %len) {
|
define void @test_atomic_unknown_size(ptr noalias %d, i64 %len) {
|
||||||
entry:
|
entry:
|
||||||
call void @llvm.memset.element.unordered.atomic.p0.i32(ptr align 1 %d, i8 0, i64 %len, i32 1)
|
call void @llvm.memset.element.unordered.atomic.p0.i32(ptr align 1 %d, i8 0, i64 %len, i32 1)
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test_known_size':
|
; CHECK: Alias sets for function 'test_known_size':
|
||||||
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %d, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %d, LocationSize::precise(1))
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Pointers: (ptr %s, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Memory locations: (ptr %s, LocationSize::precise(1))
|
||||||
define void @test_known_size(ptr noalias %s, ptr noalias %d) {
|
define void @test_known_size(ptr noalias %s, ptr noalias %d) {
|
||||||
entry:
|
entry:
|
||||||
call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 1, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 1, i1 false)
|
||||||
@ -16,8 +16,8 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test_unknown_size':
|
; CHECK: Alias sets for function 'test_unknown_size':
|
||||||
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %d, unknown after)
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %d, unknown after)
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Pointers: (ptr %s, unknown after)
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Memory locations: (ptr %s, unknown after)
|
||||||
define void @test_unknown_size(ptr noalias %s, ptr noalias %d, i64 %len) {
|
define void @test_unknown_size(ptr noalias %s, ptr noalias %d, i64 %len) {
|
||||||
entry:
|
entry:
|
||||||
call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 %len, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 %len, i1 false)
|
||||||
@ -27,10 +27,10 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test1':
|
; CHECK: Alias sets for function 'test1':
|
||||||
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
|
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK-NOT: 1 Unknown instructions
|
; CHECK-NOT: 1 Unknown instructions
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
|
||||||
define void @test1(ptr %s, ptr %d) {
|
define void @test1(ptr %s, ptr %d) {
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8, align 1
|
%a = alloca i8, align 1
|
||||||
@ -43,10 +43,10 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test1_atomic':
|
; CHECK: Alias sets for function 'test1_atomic':
|
||||||
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
|
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK-NOT: 1 Unknown instructions
|
; CHECK-NOT: 1 Unknown instructions
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
|
||||||
define void @test1_atomic(ptr %s, ptr %d) {
|
define void @test1_atomic(ptr %s, ptr %d) {
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8, align 1
|
%a = alloca i8, align 1
|
||||||
@ -59,10 +59,10 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test2':
|
; CHECK: Alias sets for function 'test2':
|
||||||
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
|
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK-NOT: 1 Unknown instructions
|
; CHECK-NOT: 1 Unknown instructions
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
|
||||||
define void @test2(ptr %s, ptr %d) {
|
define void @test2(ptr %s, ptr %d) {
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8, align 1
|
%a = alloca i8, align 1
|
||||||
@ -75,10 +75,10 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test3':
|
; CHECK: Alias sets for function 'test3':
|
||||||
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
|
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK-NOT: 1 Unknown instructions
|
; CHECK-NOT: 1 Unknown instructions
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
|
||||||
define void @test3(ptr %s, ptr %d) {
|
define void @test3(ptr %s, ptr %d) {
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8, align 1
|
%a = alloca i8, align 1
|
||||||
@ -91,10 +91,10 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test3_atomic':
|
; CHECK: Alias sets for function 'test3_atomic':
|
||||||
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
|
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK-NOT: 1 Unknown instructions
|
; CHECK-NOT: 1 Unknown instructions
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
|
||||||
define void @test3_atomic(ptr %s, ptr %d) {
|
define void @test3_atomic(ptr %s, ptr %d) {
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8, align 1
|
%a = alloca i8, align 1
|
||||||
@ -107,10 +107,10 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test4':
|
; CHECK: Alias sets for function 'test4':
|
||||||
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
|
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK-NOT: 1 Unknown instructions
|
; CHECK-NOT: 1 Unknown instructions
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
|
||||||
define void @test4(ptr %s, ptr %d) {
|
define void @test4(ptr %s, ptr %d) {
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8, align 1
|
%a = alloca i8, align 1
|
||||||
@ -123,8 +123,8 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test5':
|
; CHECK: Alias sets for function 'test5':
|
||||||
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
|
||||||
define void @test5() {
|
define void @test5() {
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8, align 1
|
%a = alloca i8, align 1
|
||||||
@ -137,8 +137,8 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test5_atomic':
|
; CHECK: Alias sets for function 'test5_atomic':
|
||||||
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
|
||||||
define void @test5_atomic() {
|
define void @test5_atomic() {
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8, align 1
|
%a = alloca i8, align 1
|
||||||
@ -151,8 +151,8 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test6':
|
; CHECK: Alias sets for function 'test6':
|
||||||
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
|
||||||
define void @test6() {
|
define void @test6() {
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8, align 1
|
%a = alloca i8, align 1
|
||||||
@ -165,8 +165,8 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test6_atomic':
|
; CHECK: Alias sets for function 'test6_atomic':
|
||||||
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
|
||||||
define void @test6_atomic() {
|
define void @test6_atomic() {
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8, align 1
|
%a = alloca i8, align 1
|
||||||
@ -179,8 +179,8 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test7':
|
; CHECK: Alias sets for function 'test7':
|
||||||
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %b, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %b, LocationSize::precise(1))
|
||||||
define void @test7() {
|
define void @test7() {
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8, align 1
|
%a = alloca i8, align 1
|
||||||
@ -194,8 +194,8 @@ entry:
|
|||||||
|
|
||||||
; CHECK: Alias sets for function 'test7_atomic':
|
; CHECK: Alias sets for function 'test7_atomic':
|
||||||
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1))
|
||||||
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %b, LocationSize::precise(1))
|
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %b, LocationSize::precise(1))
|
||||||
define void @test7_atomic() {
|
define void @test7_atomic() {
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8, align 1
|
%a = alloca i8, align 1
|
||||||
|
@ -1,47 +1,45 @@
|
|||||||
; RUN: opt -passes=print-alias-sets -alias-set-saturation-threshold=2 -S -o - < %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=NOSAT
|
; RUN: opt -passes=print-alias-sets -alias-set-saturation-threshold=4 -S -o - < %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=NOSAT
|
||||||
; RUN: opt -passes=print-alias-sets -alias-set-saturation-threshold=1 -S -o - < %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=SAT
|
; RUN: opt -passes=print-alias-sets -alias-set-saturation-threshold=3 -S -o - < %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=SAT
|
||||||
|
|
||||||
; CHECK-LABEL: 'allmust'
|
; CHECK-LABEL: 'nomerge'
|
||||||
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(4))
|
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(4))
|
||||||
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(4))
|
; CHECK: AliasSet[{{.*}}, 2] may alias, Mod Memory locations: (ptr %b, LocationSize::precise(4)), (ptr %b1, LocationSize::precise(4))
|
||||||
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %c, LocationSize::precise(4))
|
define void @nomerge(i32 %k) {
|
||||||
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %d, LocationSize::precise(4))
|
|
||||||
define void @allmust() {
|
|
||||||
%a = alloca i32
|
%a = alloca i32
|
||||||
%b = alloca i32
|
%b = alloca [10 x i32]
|
||||||
%c = alloca i32
|
|
||||||
%d = alloca i32
|
|
||||||
store i32 1, ptr %a
|
store i32 1, ptr %a
|
||||||
store i32 2, ptr %b
|
store i32 2, ptr %b
|
||||||
store i32 3, ptr %c
|
%b1 = getelementptr i32, ptr %b, i32 %k
|
||||||
store i32 4, ptr %d
|
store i32 3, ptr %b1
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK-LABEL: 'mergemay'
|
; CHECK-LABEL: 'mergemay'
|
||||||
; NOSAT: AliasSet[{{.*}}, 2] may alias, Mod Pointers: (ptr %a, LocationSize::precise(4)), (ptr %a1, LocationSize::precise(4))
|
; NOSAT: AliasSet[{{.*}}, 3] may alias, Mod Memory locations: (ptr %a, LocationSize::precise(4)), (ptr %a1, LocationSize::precise(4)), (ptr %a2, LocationSize::precise(4))
|
||||||
; NOSAT: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(4))
|
; NOSAT: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(4))
|
||||||
; SAT: AliasSet[{{.*}}, 2] may alias, Mod forwarding to 0x[[FWD:[0-9a-f]*]]
|
; SAT: AliasSet[{{.*}}, 3] may alias, Mod forwarding to 0x[[FWD:[0-9a-f]*]]
|
||||||
; SAT: AliasSet[{{.*}}, 1] must alias, Mod forwarding to 0x[[FWD]]
|
; SAT: AliasSet[{{.*}}, 1] must alias, Mod forwarding to 0x[[FWD]]
|
||||||
; SAT: AliasSet[0x[[FWD]], 2] may alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(4)), (ptr %a1, LocationSize::precise(4)), (ptr %b, LocationSize::precise(4))
|
; SAT: AliasSet[0x[[FWD]], 2] may alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(4)), (ptr %a1, LocationSize::precise(4)), (ptr %a2, LocationSize::precise(4)), (ptr %b, LocationSize::precise(4))
|
||||||
define void @mergemay(i32 %k) {
|
define void @mergemay(i32 %k, i32 %l) {
|
||||||
%a = alloca i32
|
%a = alloca i32
|
||||||
%b = alloca i32
|
%b = alloca i32
|
||||||
store i32 1, ptr %a
|
store i32 1, ptr %a
|
||||||
store i32 2, ptr %b
|
store i32 2, ptr %b
|
||||||
%a1 = getelementptr i32, ptr %a, i32 %k
|
%a1 = getelementptr i32, ptr %a, i32 %k
|
||||||
store i32 2, ptr %a1
|
store i32 2, ptr %a1
|
||||||
|
%a2 = getelementptr i32, ptr %a, i32 %l
|
||||||
|
store i32 2, ptr %a2
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK-LABEL: 'mergemust'
|
; CHECK-LABEL: 'mergemust'
|
||||||
; NOSAT: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(4))
|
; NOSAT: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(4))
|
||||||
; NOSAT: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(4))
|
; NOSAT: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(4))
|
||||||
; NOSAT: AliasSet[{{.*}}, 2] may alias, Mod Pointers: (ptr %c, LocationSize::precise(4)), (ptr %d, LocationSize::precise(4))
|
; NOSAT: AliasSet[{{.*}}, 2] may alias, Mod Memory locations: (ptr %c, LocationSize::precise(4)), (ptr %d, LocationSize::precise(4))
|
||||||
; SAT: AliasSet[{{.*}}, 1] must alias, Mod forwarding to 0x[[FWD:[0-9a-f]*]]
|
; SAT: AliasSet[{{.*}}, 1] must alias, Mod forwarding to 0x[[FWD:[0-9a-f]*]]
|
||||||
; SAT: AliasSet[{{.*}}, 1] must alias, Mod forwarding to 0x[[FWD]]
|
; SAT: AliasSet[{{.*}}, 1] must alias, Mod forwarding to 0x[[FWD]]
|
||||||
; SAT: AliasSet[{{.*}}, 2] may alias, Mod forwarding to 0x[[FWD]]
|
; SAT: AliasSet[{{.*}}, 2] may alias, Mod forwarding to 0x[[FWD]]
|
||||||
; SAT: AliasSet[0x[[FWD]], 3] may alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(4)), (ptr %b, LocationSize::precise(4)), (ptr %c, LocationSize::precise(4)), (ptr %d, LocationSize::precise(4))
|
; SAT: AliasSet[0x[[FWD]], 3] may alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(4)), (ptr %b, LocationSize::precise(4)), (ptr %c, LocationSize::precise(4)), (ptr %d, LocationSize::precise(4))
|
||||||
define void @mergemust(ptr %c, ptr %d) {
|
define void @mergemust(ptr %c, ptr %d) {
|
||||||
%a = alloca i32
|
%a = alloca i32
|
||||||
%b = alloca i32
|
%b = alloca i32
|
||||||
|
@ -9,15 +9,17 @@ define void @_Z4testP1S(ptr %s) {
|
|||||||
; CHECK-LABEL: define void @_Z4testP1S(
|
; CHECK-LABEL: define void @_Z4testP1S(
|
||||||
; CHECK-SAME: ptr [[S:%.*]]) {
|
; CHECK-SAME: ptr [[S:%.*]]) {
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
|
; CHECK-NEXT: [[S_PROMOTED:%.*]] = load ptr, ptr [[S]], align 4, !tbaa [[TBAA0:![0-9]+]]
|
||||||
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
|
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
|
||||||
; CHECK: for.cond.cleanup:
|
; CHECK: for.cond.cleanup:
|
||||||
|
; CHECK-NEXT: [[ADD_PTR_I_LCSSA:%.*]] = phi ptr [ [[ADD_PTR_I:%.*]], [[FOR_BODY]] ]
|
||||||
|
; CHECK-NEXT: store ptr [[ADD_PTR_I_LCSSA]], ptr [[S]], align 4, !tbaa [[TBAA0]]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: for.body:
|
; CHECK: for.body:
|
||||||
; CHECK-NEXT: [[I_05:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
|
; CHECK-NEXT: [[ADD_PTR_I1:%.*]] = phi ptr [ [[S_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD_PTR_I]], [[FOR_BODY]] ]
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S]], align 4, !tbaa [[TBAA0:![0-9]+]]
|
; CHECK-NEXT: [[I_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
|
||||||
; CHECK-NEXT: store i32 [[I_05]], ptr [[TMP0]], align 4, !tbaa [[TBAA5:![0-9]+]]
|
; CHECK-NEXT: store i32 [[I_05]], ptr [[ADD_PTR_I1]], align 4, !tbaa [[TBAA4:![0-9]+]]
|
||||||
; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i32, ptr [[TMP0]], i32 1
|
; CHECK-NEXT: [[ADD_PTR_I]] = getelementptr inbounds i32, ptr [[ADD_PTR_I1]], i32 1
|
||||||
; CHECK-NEXT: store ptr [[ADD_PTR_I]], ptr [[S]], align 4, !tbaa [[TBAA7:![0-9]+]]
|
|
||||||
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_05]], 1
|
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_05]], 1
|
||||||
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], 100
|
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], 100
|
||||||
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
|
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
|
||||||
@ -48,12 +50,10 @@ for.body: ; preds = %entry, %for.body
|
|||||||
!6 = !{!"int", !3, i64 0}
|
!6 = !{!"int", !3, i64 0}
|
||||||
!7 = !{!2, !2, i64 0}
|
!7 = !{!2, !2, i64 0}
|
||||||
;.
|
;.
|
||||||
; CHECK: [[TBAA0]] = !{[[META1:![0-9]+]], [[META2:![0-9]+]], i64 0}
|
; CHECK: [[TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
|
||||||
; CHECK: [[META1]] = !{!"_ZTS1S", [[META2]], i64 0}
|
; CHECK: [[META1]] = !{!"any pointer", [[META2:![0-9]+]], i64 0}
|
||||||
; CHECK: [[META2]] = !{!"any pointer", [[META3:![0-9]+]], i64 0}
|
; CHECK: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0}
|
||||||
; CHECK: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0}
|
; CHECK: [[META3]] = !{!"Simple C++ TBAA"}
|
||||||
; CHECK: [[META4]] = !{!"Simple C++ TBAA"}
|
; CHECK: [[TBAA4]] = !{[[META5:![0-9]+]], [[META5]], i64 0}
|
||||||
; CHECK: [[TBAA5]] = !{[[META6:![0-9]+]], [[META6]], i64 0}
|
; CHECK: [[META5]] = !{!"int", [[META2]], i64 0}
|
||||||
; CHECK: [[META6]] = !{!"int", [[META3]], i64 0}
|
|
||||||
; CHECK: [[TBAA7]] = !{[[META2]], [[META2]], i64 0}
|
|
||||||
;.
|
;.
|
||||||
|
@ -3255,8 +3255,8 @@ ScopBuilder::buildAliasGroupsForAccesses() {
|
|||||||
if (AS.isMustAlias() || AS.isForwardingAliasSet())
|
if (AS.isMustAlias() || AS.isForwardingAliasSet())
|
||||||
continue;
|
continue;
|
||||||
AliasGroupTy AG;
|
AliasGroupTy AG;
|
||||||
for (auto &PR : AS)
|
for (const Value *Ptr : AS.getPointers())
|
||||||
AG.push_back(PtrToAcc[PR.getValue()]);
|
AG.push_back(PtrToAcc[const_cast<Value *>(Ptr)]);
|
||||||
if (AG.size() < 2)
|
if (AG.size() < 2)
|
||||||
continue;
|
continue;
|
||||||
AliasGroups.push_back(std::move(AG));
|
AliasGroups.push_back(std::move(AG));
|
||||||
|
@ -1149,6 +1149,8 @@ bool ScopDetection::isValidAccess(Instruction *Inst, const SCEV *AF,
|
|||||||
// sure the base pointer is not an instruction defined inside the scop.
|
// sure the base pointer is not an instruction defined inside the scop.
|
||||||
// However, we can ignore loads that will be hoisted.
|
// However, we can ignore loads that will be hoisted.
|
||||||
|
|
||||||
|
auto ASPointers = AS.getPointers();
|
||||||
|
|
||||||
InvariantLoadsSetTy VariantLS, InvariantLS;
|
InvariantLoadsSetTy VariantLS, InvariantLS;
|
||||||
// In order to detect loads which are dependent on other invariant loads
|
// In order to detect loads which are dependent on other invariant loads
|
||||||
// as invariant, we use fixed-point iteration method here i.e we iterate
|
// as invariant, we use fixed-point iteration method here i.e we iterate
|
||||||
@ -1158,8 +1160,8 @@ bool ScopDetection::isValidAccess(Instruction *Inst, const SCEV *AF,
|
|||||||
const unsigned int VariantSize = VariantLS.size(),
|
const unsigned int VariantSize = VariantLS.size(),
|
||||||
InvariantSize = InvariantLS.size();
|
InvariantSize = InvariantLS.size();
|
||||||
|
|
||||||
for (const auto &Ptr : AS) {
|
for (const Value *Ptr : ASPointers) {
|
||||||
Instruction *Inst = dyn_cast<Instruction>(Ptr.getValue());
|
Instruction *Inst = dyn_cast<Instruction>(const_cast<Value *>(Ptr));
|
||||||
if (Inst && Context.CurRegion.contains(Inst)) {
|
if (Inst && Context.CurRegion.contains(Inst)) {
|
||||||
auto *Load = dyn_cast<LoadInst>(Inst);
|
auto *Load = dyn_cast<LoadInst>(Inst);
|
||||||
if (Load && InvariantLS.count(Load))
|
if (Load && InvariantLS.count(Load))
|
||||||
|
@ -638,8 +638,7 @@ bool ReportNonSimpleMemoryAccess::classof(const RejectReason *RR) {
|
|||||||
|
|
||||||
ReportAlias::ReportAlias(Instruction *Inst, AliasSet &AS)
|
ReportAlias::ReportAlias(Instruction *Inst, AliasSet &AS)
|
||||||
: RejectReason(RejectReasonKind::Alias), Inst(Inst) {
|
: RejectReason(RejectReasonKind::Alias), Inst(Inst) {
|
||||||
for (const auto &I : AS)
|
append_range(Pointers, AS.getPointers());
|
||||||
Pointers.push_back(I.getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ReportAlias::formatInvalidAlias(std::string Prefix,
|
std::string ReportAlias::formatInvalidAlias(std::string Prefix,
|
||||||
|
Loading…
Reference in New Issue
Block a user