diff options
Diffstat (limited to 'lib/Analysis/AliasAnalysisSummary.cpp')
-rw-r--r-- | lib/Analysis/AliasAnalysisSummary.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/lib/Analysis/AliasAnalysisSummary.cpp b/lib/Analysis/AliasAnalysisSummary.cpp new file mode 100644 index 000000000000..f3f13df283db --- /dev/null +++ b/lib/Analysis/AliasAnalysisSummary.cpp @@ -0,0 +1,105 @@ +#include "AliasAnalysisSummary.h" +#include "llvm/IR/Argument.h" +#include "llvm/IR/Type.h" +#include "llvm/Support/Compiler.h" + +namespace llvm { +namespace cflaa { + +namespace { +LLVM_CONSTEXPR unsigned AttrEscapedIndex = 0; +LLVM_CONSTEXPR unsigned AttrUnknownIndex = 1; +LLVM_CONSTEXPR unsigned AttrGlobalIndex = 2; +LLVM_CONSTEXPR unsigned AttrCallerIndex = 3; +LLVM_CONSTEXPR unsigned AttrFirstArgIndex = 4; +LLVM_CONSTEXPR unsigned AttrLastArgIndex = NumAliasAttrs; +LLVM_CONSTEXPR unsigned AttrMaxNumArgs = AttrLastArgIndex - AttrFirstArgIndex; + +// NOTE: These aren't AliasAttrs because bitsets don't have a constexpr +// ctor for some versions of MSVC that we support. We could maybe refactor, +// but... +using AliasAttr = unsigned; +LLVM_CONSTEXPR AliasAttr AttrNone = 0; +LLVM_CONSTEXPR AliasAttr AttrEscaped = 1 << AttrEscapedIndex; +LLVM_CONSTEXPR AliasAttr AttrUnknown = 1 << AttrUnknownIndex; +LLVM_CONSTEXPR AliasAttr AttrGlobal = 1 << AttrGlobalIndex; +LLVM_CONSTEXPR AliasAttr AttrCaller = 1 << AttrCallerIndex; +LLVM_CONSTEXPR AliasAttr ExternalAttrMask = + AttrEscaped | AttrUnknown | AttrGlobal; +} + +AliasAttrs getAttrNone() { return AttrNone; } + +AliasAttrs getAttrUnknown() { return AttrUnknown; } +bool hasUnknownAttr(AliasAttrs Attr) { return Attr.test(AttrUnknownIndex); } + +AliasAttrs getAttrCaller() { return AttrCaller; } +bool hasCallerAttr(AliasAttrs Attr) { return Attr.test(AttrCaller); } +bool hasUnknownOrCallerAttr(AliasAttrs Attr) { + return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex); +} + +AliasAttrs getAttrEscaped() { return AttrEscaped; } +bool hasEscapedAttr(AliasAttrs Attr) { return Attr.test(AttrEscapedIndex); } + +static AliasAttr argNumberToAttr(unsigned ArgNum) { + if (ArgNum >= AttrMaxNumArgs) + return AttrUnknown; + // N.B. MSVC complains if we use `1U` here, since AliasAttr' ctor takes + // an unsigned long long. + return AliasAttr(1ULL << (ArgNum + AttrFirstArgIndex)); +} + +AliasAttrs getGlobalOrArgAttrFromValue(const Value &Val) { + if (isa<GlobalValue>(Val)) + return AttrGlobal; + + if (auto *Arg = dyn_cast<Argument>(&Val)) + // Only pointer arguments should have the argument attribute, + // because things can't escape through scalars without us seeing a + // cast, and thus, interaction with them doesn't matter. + if (!Arg->hasNoAliasAttr() && Arg->getType()->isPointerTy()) + return argNumberToAttr(Arg->getArgNo()); + return AttrNone; +} + +bool isGlobalOrArgAttr(AliasAttrs Attr) { + return Attr.reset(AttrEscapedIndex) + .reset(AttrUnknownIndex) + .reset(AttrCallerIndex) + .any(); +} + +AliasAttrs getExternallyVisibleAttrs(AliasAttrs Attr) { + return Attr & AliasAttrs(ExternalAttrMask); +} + +Optional<InstantiatedValue> instantiateInterfaceValue(InterfaceValue IValue, + CallSite CS) { + auto Index = IValue.Index; + auto Value = (Index == 0) ? CS.getInstruction() : CS.getArgument(Index - 1); + if (Value->getType()->isPointerTy()) + return InstantiatedValue{Value, IValue.DerefLevel}; + return None; +} + +Optional<InstantiatedRelation> +instantiateExternalRelation(ExternalRelation ERelation, CallSite CS) { + auto From = instantiateInterfaceValue(ERelation.From, CS); + if (!From) + return None; + auto To = instantiateInterfaceValue(ERelation.To, CS); + if (!To) + return None; + return InstantiatedRelation{*From, *To}; +} + +Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute EAttr, + CallSite CS) { + auto Value = instantiateInterfaceValue(EAttr.IValue, CS); + if (!Value) + return None; + return InstantiatedAttr{*Value, EAttr.Attr}; +} +} +} |