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