1 #include "AliasAnalysisSummary.h"
2 #include "llvm/IR/Argument.h"
3 #include "llvm/IR/Type.h"
4 #include "llvm/Support/Compiler.h"
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
;
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
;
29 AliasAttrs
getAttrNone() { return AttrNone
; }
31 AliasAttrs
getAttrUnknown() { return AttrUnknown
; }
32 bool hasUnknownAttr(AliasAttrs Attr
) { return Attr
.test(AttrUnknownIndex
); }
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
);
40 AliasAttrs
getAttrEscaped() { return AttrEscaped
; }
41 bool hasEscapedAttr(AliasAttrs Attr
) { return Attr
.test(AttrEscapedIndex
); }
43 static AliasAttr
argNumberToAttr(unsigned ArgNum
) {
44 if (ArgNum
>= AttrMaxNumArgs
)
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
));
51 AliasAttrs
getGlobalOrArgAttrFromValue(const Value
&Val
) {
52 if (isa
<GlobalValue
>(Val
))
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());
64 bool isGlobalOrArgAttr(AliasAttrs Attr
) {
65 return Attr
.reset(AttrEscapedIndex
)
66 .reset(AttrUnknownIndex
)
67 .reset(AttrCallerIndex
)
71 AliasAttrs
getExternallyVisibleAttrs(AliasAttrs Attr
) {
72 return Attr
& AliasAttrs(ExternalAttrMask
);
75 Optional
<InstantiatedValue
> instantiateInterfaceValue(InterfaceValue IValue
,
77 auto Index
= IValue
.Index
;
78 auto *V
= (Index
== 0) ? &Call
: Call
.getArgOperand(Index
- 1);
79 if (V
->getType()->isPointerTy())
80 return InstantiatedValue
{V
, IValue
.DerefLevel
};
84 Optional
<InstantiatedRelation
>
85 instantiateExternalRelation(ExternalRelation ERelation
, CallBase
&Call
) {
86 auto From
= instantiateInterfaceValue(ERelation
.From
, Call
);
89 auto To
= instantiateInterfaceValue(ERelation
.To
, Call
);
92 return InstantiatedRelation
{*From
, *To
, ERelation
.Offset
};
95 Optional
<InstantiatedAttr
> instantiateExternalAttribute(ExternalAttribute EAttr
,
97 auto Value
= instantiateInterfaceValue(EAttr
.IValue
, Call
);
100 return InstantiatedAttr
{*Value
, EAttr
.Attr
};