blob: 09a6b8217a08e9596417bbd212cae548bff42f27 [file] [log] [blame]
George Burgess IVe1919962016-07-06 00:47:21 +00001#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 {
George Burgess IV381fc0e2016-08-25 01:05:08 +000010const unsigned AttrEscapedIndex = 0;
11const unsigned AttrUnknownIndex = 1;
12const unsigned AttrGlobalIndex = 2;
13const unsigned AttrCallerIndex = 3;
14const unsigned AttrFirstArgIndex = 4;
15const unsigned AttrLastArgIndex = NumAliasAttrs;
16const unsigned AttrMaxNumArgs = AttrLastArgIndex - AttrFirstArgIndex;
George Burgess IVe1919962016-07-06 00:47:21 +000017
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;
George Burgess IV381fc0e2016-08-25 01:05:08 +000022const AliasAttr AttrNone = 0;
23const AliasAttr AttrEscaped = 1 << AttrEscapedIndex;
24const AliasAttr AttrUnknown = 1 << AttrUnknownIndex;
25const AliasAttr AttrGlobal = 1 << AttrGlobalIndex;
26const AliasAttr AttrCaller = 1 << AttrCallerIndex;
27const AliasAttr ExternalAttrMask = AttrEscaped | AttrUnknown | AttrGlobal;
George Burgess IVe1919962016-07-06 00:47:21 +000028}
29
30AliasAttrs getAttrNone() { return AttrNone; }
31
32AliasAttrs getAttrUnknown() { return AttrUnknown; }
33bool hasUnknownAttr(AliasAttrs Attr) { return Attr.test(AttrUnknownIndex); }
34
35AliasAttrs getAttrCaller() { return AttrCaller; }
36bool hasCallerAttr(AliasAttrs Attr) { return Attr.test(AttrCaller); }
37bool hasUnknownOrCallerAttr(AliasAttrs Attr) {
38 return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex);
39}
40
41AliasAttrs getAttrEscaped() { return AttrEscaped; }
42bool hasEscapedAttr(AliasAttrs Attr) { return Attr.test(AttrEscapedIndex); }
43
44static AliasAttr argNumberToAttr(unsigned ArgNum) {
45 if (ArgNum >= AttrMaxNumArgs)
46 return AttrUnknown;
47 // N.B. MSVC complains if we use `1U` here, since AliasAttr' ctor takes
48 // an unsigned long long.
49 return AliasAttr(1ULL << (ArgNum + AttrFirstArgIndex));
50}
51
52AliasAttrs getGlobalOrArgAttrFromValue(const Value &Val) {
53 if (isa<GlobalValue>(Val))
54 return AttrGlobal;
55
56 if (auto *Arg = dyn_cast<Argument>(&Val))
57 // Only pointer arguments should have the argument attribute,
58 // because things can't escape through scalars without us seeing a
59 // cast, and thus, interaction with them doesn't matter.
60 if (!Arg->hasNoAliasAttr() && Arg->getType()->isPointerTy())
61 return argNumberToAttr(Arg->getArgNo());
62 return AttrNone;
63}
64
65bool isGlobalOrArgAttr(AliasAttrs Attr) {
66 return Attr.reset(AttrEscapedIndex)
67 .reset(AttrUnknownIndex)
68 .reset(AttrCallerIndex)
69 .any();
70}
71
72AliasAttrs getExternallyVisibleAttrs(AliasAttrs Attr) {
73 return Attr & AliasAttrs(ExternalAttrMask);
74}
75
76Optional<InstantiatedValue> instantiateInterfaceValue(InterfaceValue IValue,
77 CallSite CS) {
78 auto Index = IValue.Index;
79 auto Value = (Index == 0) ? CS.getInstruction() : CS.getArgument(Index - 1);
80 if (Value->getType()->isPointerTy())
81 return InstantiatedValue{Value, IValue.DerefLevel};
82 return None;
83}
84
85Optional<InstantiatedRelation>
86instantiateExternalRelation(ExternalRelation ERelation, CallSite CS) {
87 auto From = instantiateInterfaceValue(ERelation.From, CS);
88 if (!From)
89 return None;
90 auto To = instantiateInterfaceValue(ERelation.To, CS);
91 if (!To)
92 return None;
George Burgess IV4ec17532016-07-22 22:30:48 +000093 return InstantiatedRelation{*From, *To, ERelation.Offset};
George Burgess IVe1919962016-07-06 00:47:21 +000094}
95
96Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute EAttr,
97 CallSite CS) {
98 auto Value = instantiateInterfaceValue(EAttr.IValue, CS);
99 if (!Value)
100 return None;
101 return InstantiatedAttr{*Value, EAttr.Attr};
102}
103}
104}