AliasAnalysisSummary.cpp revision 304240
1#include "AliasAnalysisSummary.h"
2#include "llvm/IR/Argument.h"
3#include "llvm/IR/Type.h"
4#include "llvm/Support/Compiler.h"
5
6namespace llvm {
7namespace cflaa {
8
9namespace {
10LLVM_CONSTEXPR unsigned AttrEscapedIndex = 0;
11LLVM_CONSTEXPR unsigned AttrUnknownIndex = 1;
12LLVM_CONSTEXPR unsigned AttrGlobalIndex = 2;
13LLVM_CONSTEXPR unsigned AttrCallerIndex = 3;
14LLVM_CONSTEXPR unsigned AttrFirstArgIndex = 4;
15LLVM_CONSTEXPR unsigned AttrLastArgIndex = NumAliasAttrs;
16LLVM_CONSTEXPR unsigned AttrMaxNumArgs = AttrLastArgIndex - AttrFirstArgIndex;
17
18// NOTE: These aren't AliasAttrs because bitsets don't have a constexpr
19// ctor for some versions of MSVC that we support. We could maybe refactor,
20// but...
21using AliasAttr = unsigned;
22LLVM_CONSTEXPR AliasAttr AttrNone = 0;
23LLVM_CONSTEXPR AliasAttr AttrEscaped = 1 << AttrEscapedIndex;
24LLVM_CONSTEXPR AliasAttr AttrUnknown = 1 << AttrUnknownIndex;
25LLVM_CONSTEXPR AliasAttr AttrGlobal = 1 << AttrGlobalIndex;
26LLVM_CONSTEXPR AliasAttr AttrCaller = 1 << AttrCallerIndex;
27LLVM_CONSTEXPR AliasAttr ExternalAttrMask =
28    AttrEscaped | AttrUnknown | AttrGlobal;
29}
30
31AliasAttrs getAttrNone() { return AttrNone; }
32
33AliasAttrs getAttrUnknown() { return AttrUnknown; }
34bool hasUnknownAttr(AliasAttrs Attr) { return Attr.test(AttrUnknownIndex); }
35
36AliasAttrs getAttrCaller() { return AttrCaller; }
37bool hasCallerAttr(AliasAttrs Attr) { return Attr.test(AttrCaller); }
38bool hasUnknownOrCallerAttr(AliasAttrs Attr) {
39  return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex);
40}
41
42AliasAttrs getAttrEscaped() { return AttrEscaped; }
43bool hasEscapedAttr(AliasAttrs Attr) { return Attr.test(AttrEscapedIndex); }
44
45static AliasAttr argNumberToAttr(unsigned ArgNum) {
46  if (ArgNum >= AttrMaxNumArgs)
47    return AttrUnknown;
48  // N.B. MSVC complains if we use `1U` here, since AliasAttr' ctor takes
49  // an unsigned long long.
50  return AliasAttr(1ULL << (ArgNum + AttrFirstArgIndex));
51}
52
53AliasAttrs getGlobalOrArgAttrFromValue(const Value &Val) {
54  if (isa<GlobalValue>(Val))
55    return AttrGlobal;
56
57  if (auto *Arg = dyn_cast<Argument>(&Val))
58    // Only pointer arguments should have the argument attribute,
59    // because things can't escape through scalars without us seeing a
60    // cast, and thus, interaction with them doesn't matter.
61    if (!Arg->hasNoAliasAttr() && Arg->getType()->isPointerTy())
62      return argNumberToAttr(Arg->getArgNo());
63  return AttrNone;
64}
65
66bool isGlobalOrArgAttr(AliasAttrs Attr) {
67  return Attr.reset(AttrEscapedIndex)
68      .reset(AttrUnknownIndex)
69      .reset(AttrCallerIndex)
70      .any();
71}
72
73AliasAttrs getExternallyVisibleAttrs(AliasAttrs Attr) {
74  return Attr & AliasAttrs(ExternalAttrMask);
75}
76
77Optional<InstantiatedValue> instantiateInterfaceValue(InterfaceValue IValue,
78                                                      CallSite CS) {
79  auto Index = IValue.Index;
80  auto Value = (Index == 0) ? CS.getInstruction() : CS.getArgument(Index - 1);
81  if (Value->getType()->isPointerTy())
82    return InstantiatedValue{Value, IValue.DerefLevel};
83  return None;
84}
85
86Optional<InstantiatedRelation>
87instantiateExternalRelation(ExternalRelation ERelation, CallSite CS) {
88  auto From = instantiateInterfaceValue(ERelation.From, CS);
89  if (!From)
90    return None;
91  auto To = instantiateInterfaceValue(ERelation.To, CS);
92  if (!To)
93    return None;
94  return InstantiatedRelation{*From, *To};
95}
96
97Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute EAttr,
98                                                        CallSite CS) {
99  auto Value = instantiateInterfaceValue(EAttr.IValue, CS);
100  if (!Value)
101    return None;
102  return InstantiatedAttr{*Value, EAttr.Attr};
103}
104}
105}
106