#ifndef LLVM_ANALYSIS_ALIASANALYSISSUMMARY_H
#define LLVM_ANALYSIS_ALIASANALYSISSUMMARY_H
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include <bitset>
namespace llvm {
class CallBase;
class Value;
namespace cflaa {
static const unsigned NumAliasAttrs = 32;
typedef std::bitset<NumAliasAttrs> AliasAttrs;
AliasAttrs getAttrNone();
AliasAttrs getAttrUnknown();
bool hasUnknownAttr(AliasAttrs);
AliasAttrs getAttrCaller();
bool hasCallerAttr(AliasAttrs);
bool hasUnknownOrCallerAttr(AliasAttrs);
AliasAttrs getAttrEscaped();
bool hasEscapedAttr(AliasAttrs);
AliasAttrs getGlobalOrArgAttrFromValue(const Value &);
bool isGlobalOrArgAttr(AliasAttrs);
AliasAttrs getExternallyVisibleAttrs(AliasAttrs);
static const unsigned MaxSupportedArgsInSummary = 50;
struct InterfaceValue {
unsigned Index;
unsigned DerefLevel;
};
inline bool operator==(InterfaceValue LHS, InterfaceValue RHS) {
return LHS.Index == RHS.Index && LHS.DerefLevel == RHS.DerefLevel;
}
inline bool operator!=(InterfaceValue LHS, InterfaceValue RHS) {
return !(LHS == RHS);
}
inline bool operator<(InterfaceValue LHS, InterfaceValue RHS) {
return LHS.Index < RHS.Index ||
(LHS.Index == RHS.Index && LHS.DerefLevel < RHS.DerefLevel);
}
inline bool operator>(InterfaceValue LHS, InterfaceValue RHS) {
return RHS < LHS;
}
inline bool operator<=(InterfaceValue LHS, InterfaceValue RHS) {
return !(RHS < LHS);
}
inline bool operator>=(InterfaceValue LHS, InterfaceValue RHS) {
return !(LHS < RHS);
}
static const int64_t UnknownOffset = INT64_MAX;
inline int64_t addOffset(int64_t LHS, int64_t RHS) {
if (LHS == UnknownOffset || RHS == UnknownOffset)
return UnknownOffset;
return LHS + RHS;
}
struct ExternalRelation {
InterfaceValue From, To;
int64_t Offset;
};
inline bool operator==(ExternalRelation LHS, ExternalRelation RHS) {
return LHS.From == RHS.From && LHS.To == RHS.To && LHS.Offset == RHS.Offset;
}
inline bool operator!=(ExternalRelation LHS, ExternalRelation RHS) {
return !(LHS == RHS);
}
inline bool operator<(ExternalRelation LHS, ExternalRelation RHS) {
if (LHS.From < RHS.From)
return true;
if (LHS.From > RHS.From)
return false;
if (LHS.To < RHS.To)
return true;
if (LHS.To > RHS.To)
return false;
return LHS.Offset < RHS.Offset;
}
inline bool operator>(ExternalRelation LHS, ExternalRelation RHS) {
return RHS < LHS;
}
inline bool operator<=(ExternalRelation LHS, ExternalRelation RHS) {
return !(RHS < LHS);
}
inline bool operator>=(ExternalRelation LHS, ExternalRelation RHS) {
return !(LHS < RHS);
}
struct ExternalAttribute {
InterfaceValue IValue;
AliasAttrs Attr;
};
struct AliasSummary {
SmallVector<ExternalRelation, 8> RetParamRelations;
SmallVector<ExternalAttribute, 8> RetParamAttributes;
};
struct InstantiatedValue {
Value *Val;
unsigned DerefLevel;
};
Optional<InstantiatedValue> instantiateInterfaceValue(InterfaceValue IValue,
CallBase &Call);
inline bool operator==(InstantiatedValue LHS, InstantiatedValue RHS) {
return LHS.Val == RHS.Val && LHS.DerefLevel == RHS.DerefLevel;
}
inline bool operator!=(InstantiatedValue LHS, InstantiatedValue RHS) {
return !(LHS == RHS);
}
inline bool operator<(InstantiatedValue LHS, InstantiatedValue RHS) {
return std::less<Value *>()(LHS.Val, RHS.Val) ||
(LHS.Val == RHS.Val && LHS.DerefLevel < RHS.DerefLevel);
}
inline bool operator>(InstantiatedValue LHS, InstantiatedValue RHS) {
return RHS < LHS;
}
inline bool operator<=(InstantiatedValue LHS, InstantiatedValue RHS) {
return !(RHS < LHS);
}
inline bool operator>=(InstantiatedValue LHS, InstantiatedValue RHS) {
return !(LHS < RHS);
}
struct InstantiatedRelation {
InstantiatedValue From, To;
int64_t Offset;
};
Optional<InstantiatedRelation>
instantiateExternalRelation(ExternalRelation ERelation, CallBase &Call);
struct InstantiatedAttr {
InstantiatedValue IValue;
AliasAttrs Attr;
};
Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute EAttr,
CallBase &Call);
}
template <> struct DenseMapInfo<cflaa::InstantiatedValue> {
static inline cflaa::InstantiatedValue getEmptyKey() {
return cflaa::InstantiatedValue{DenseMapInfo<Value *>::getEmptyKey(),
DenseMapInfo<unsigned>::getEmptyKey()};
}
static inline cflaa::InstantiatedValue getTombstoneKey() {
return cflaa::InstantiatedValue{DenseMapInfo<Value *>::getTombstoneKey(),
DenseMapInfo<unsigned>::getTombstoneKey()};
}
static unsigned getHashValue(const cflaa::InstantiatedValue &IV) {
return DenseMapInfo<std::pair<Value *, unsigned>>::getHashValue(
std::make_pair(IV.Val, IV.DerefLevel));
}
static bool isEqual(const cflaa::InstantiatedValue &LHS,
const cflaa::InstantiatedValue &RHS) {
return LHS.Val == RHS.Val && LHS.DerefLevel == RHS.DerefLevel;
}
};
}
#endif