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