1 #include "AliasAnalysisSummary.h"
2 #include "llvm/IR/Argument.h"
3 #include "llvm/IR/InstrTypes.h"
4 #include "llvm/IR/Type.h"
5 #include "llvm/Support/Compiler.h"
11 const unsigned AttrEscapedIndex
= 0;
12 const unsigned AttrUnknownIndex
= 1;
13 const unsigned AttrGlobalIndex
= 2;
14 const unsigned AttrCallerIndex
= 3;
15 const unsigned AttrFirstArgIndex
= 4;
16 const unsigned AttrLastArgIndex
= NumAliasAttrs
;
17 const unsigned AttrMaxNumArgs
= AttrLastArgIndex
- AttrFirstArgIndex
;
19 // It would be *slightly* prettier if we changed these to AliasAttrs, but it
20 // seems that both GCC and MSVC emit dynamic initializers for const bitsets.
21 using AliasAttr
= unsigned;
22 const AliasAttr AttrNone
= 0;
23 const AliasAttr AttrEscaped
= 1 << AttrEscapedIndex
;
24 const AliasAttr AttrUnknown
= 1 << AttrUnknownIndex
;
25 const AliasAttr AttrGlobal
= 1 << AttrGlobalIndex
;
26 const AliasAttr AttrCaller
= 1 << AttrCallerIndex
;
27 const AliasAttr ExternalAttrMask
= AttrEscaped
| AttrUnknown
| AttrGlobal
;
30 AliasAttrs
getAttrNone() { return AttrNone
; }
32 AliasAttrs
getAttrUnknown() { return AttrUnknown
; }
33 bool hasUnknownAttr(AliasAttrs Attr
) { return Attr
.test(AttrUnknownIndex
); }
35 AliasAttrs
getAttrCaller() { return AttrCaller
; }
36 bool hasCallerAttr(AliasAttrs Attr
) { return Attr
.test(AttrCaller
); }
37 bool hasUnknownOrCallerAttr(AliasAttrs Attr
) {
38 return Attr
.test(AttrUnknownIndex
) || Attr
.test(AttrCallerIndex
);
41 AliasAttrs
getAttrEscaped() { return AttrEscaped
; }
42 bool hasEscapedAttr(AliasAttrs Attr
) { return Attr
.test(AttrEscapedIndex
); }
44 static AliasAttr
argNumberToAttr(unsigned ArgNum
) {
45 if (ArgNum
>= AttrMaxNumArgs
)
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
));
52 AliasAttrs
getGlobalOrArgAttrFromValue(const Value
&Val
) {
53 if (isa
<GlobalValue
>(Val
))
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());
65 bool isGlobalOrArgAttr(AliasAttrs Attr
) {
66 return Attr
.reset(AttrEscapedIndex
)
67 .reset(AttrUnknownIndex
)
68 .reset(AttrCallerIndex
)
72 AliasAttrs
getExternallyVisibleAttrs(AliasAttrs Attr
) {
73 return Attr
& AliasAttrs(ExternalAttrMask
);
76 Optional
<InstantiatedValue
> instantiateInterfaceValue(InterfaceValue IValue
,
78 auto Index
= IValue
.Index
;
79 auto *V
= (Index
== 0) ? &Call
: Call
.getArgOperand(Index
- 1);
80 if (V
->getType()->isPointerTy())
81 return InstantiatedValue
{V
, IValue
.DerefLevel
};
85 Optional
<InstantiatedRelation
>
86 instantiateExternalRelation(ExternalRelation ERelation
, CallBase
&Call
) {
87 auto From
= instantiateInterfaceValue(ERelation
.From
, Call
);
90 auto To
= instantiateInterfaceValue(ERelation
.To
, Call
);
93 return InstantiatedRelation
{*From
, *To
, ERelation
.Offset
};
96 Optional
<InstantiatedAttr
> instantiateExternalAttribute(ExternalAttribute EAttr
,
98 auto Value
= instantiateInterfaceValue(EAttr
.IValue
, Call
);
101 return InstantiatedAttr
{*Value
, EAttr
.Attr
};