Line data Source code
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 0 : AliasAttrs getAttrNone() { return AttrNone; }
30 :
31 77 : AliasAttrs getAttrUnknown() { return AttrUnknown; }
32 0 : bool hasUnknownAttr(AliasAttrs Attr) { return Attr.test(AttrUnknownIndex); }
33 :
34 222 : AliasAttrs getAttrCaller() { return AttrCaller; }
35 0 : bool hasCallerAttr(AliasAttrs Attr) { return Attr.test(AttrCaller); }
36 4268 : bool hasUnknownOrCallerAttr(AliasAttrs Attr) {
37 4268 : return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex);
38 : }
39 :
40 46 : AliasAttrs getAttrEscaped() { return AttrEscaped; }
41 0 : bool hasEscapedAttr(AliasAttrs Attr) { return Attr.test(AttrEscapedIndex); }
42 :
43 : static AliasAttr argNumberToAttr(unsigned ArgNum) {
44 217 : 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 209 : return AliasAttr(1ULL << (ArgNum + AttrFirstArgIndex));
49 : }
50 :
51 252 : AliasAttrs getGlobalOrArgAttrFromValue(const Value &Val) {
52 : if (isa<GlobalValue>(Val))
53 30 : 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 222 : if (!Arg->hasNoAliasAttr() && Arg->getType()->isPointerTy())
60 426 : return argNumberToAttr(Arg->getArgNo());
61 5 : return AttrNone;
62 : }
63 :
64 2517 : bool isGlobalOrArgAttr(AliasAttrs Attr) {
65 : return Attr.reset(AttrEscapedIndex)
66 : .reset(AttrUnknownIndex)
67 : .reset(AttrCallerIndex)
68 2517 : .any();
69 : }
70 :
71 486 : AliasAttrs getExternallyVisibleAttrs(AliasAttrs Attr) {
72 486 : return Attr & AliasAttrs(ExternalAttrMask);
73 : }
74 :
75 116 : Optional<InstantiatedValue> instantiateInterfaceValue(InterfaceValue IValue,
76 : CallSite CS) {
77 116 : auto Index = IValue.Index;
78 116 : auto Value = (Index == 0) ? CS.getInstruction() : CS.getArgument(Index - 1);
79 232 : if (Value->getType()->isPointerTy())
80 116 : return InstantiatedValue{Value, IValue.DerefLevel};
81 : return None;
82 : }
83 :
84 : Optional<InstantiatedRelation>
85 28 : instantiateExternalRelation(ExternalRelation ERelation, CallSite CS) {
86 28 : auto From = instantiateInterfaceValue(ERelation.From, CS);
87 28 : if (!From)
88 : return None;
89 28 : auto To = instantiateInterfaceValue(ERelation.To, CS);
90 28 : if (!To)
91 : return None;
92 28 : return InstantiatedRelation{*From, *To, ERelation.Offset};
93 : }
94 :
95 60 : Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute EAttr,
96 : CallSite CS) {
97 60 : auto Value = instantiateInterfaceValue(EAttr.IValue, CS);
98 60 : if (!Value)
99 : return None;
100 60 : return InstantiatedAttr{*Value, EAttr.Attr};
101 : }
102 : }
103 : }
|