aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/AliasAnalysisSummary.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/AliasAnalysisSummary.cpp')
-rw-r--r--lib/Analysis/AliasAnalysisSummary.cpp105
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};
+}
+}
+}