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"
6 
7 namespace llvm {
8 namespace cflaa {
9 
10 namespace {
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;
18 
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;
28 }
29 
getAttrNone()30 AliasAttrs getAttrNone() { return AttrNone; }
31 
getAttrUnknown()32 AliasAttrs getAttrUnknown() { return AttrUnknown; }
hasUnknownAttr(AliasAttrs Attr)33 bool hasUnknownAttr(AliasAttrs Attr) { return Attr.test(AttrUnknownIndex); }
34 
getAttrCaller()35 AliasAttrs getAttrCaller() { return AttrCaller; }
hasCallerAttr(AliasAttrs Attr)36 bool hasCallerAttr(AliasAttrs Attr) { return Attr.test(AttrCaller); }
hasUnknownOrCallerAttr(AliasAttrs Attr)37 bool hasUnknownOrCallerAttr(AliasAttrs Attr) {
38   return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex);
39 }
40 
getAttrEscaped()41 AliasAttrs getAttrEscaped() { return AttrEscaped; }
hasEscapedAttr(AliasAttrs Attr)42 bool hasEscapedAttr(AliasAttrs Attr) { return Attr.test(AttrEscapedIndex); }
43 
argNumberToAttr(unsigned ArgNum)44 static AliasAttr argNumberToAttr(unsigned ArgNum) {
45   if (ArgNum >= AttrMaxNumArgs)
46     return AttrUnknown;
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));
50 }
51 
getGlobalOrArgAttrFromValue(const Value & Val)52 AliasAttrs getGlobalOrArgAttrFromValue(const Value &Val) {
53   if (isa<GlobalValue>(Val))
54     return AttrGlobal;
55 
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());
62   return AttrNone;
63 }
64 
isGlobalOrArgAttr(AliasAttrs Attr)65 bool isGlobalOrArgAttr(AliasAttrs Attr) {
66   return Attr.reset(AttrEscapedIndex)
67       .reset(AttrUnknownIndex)
68       .reset(AttrCallerIndex)
69       .any();
70 }
71 
getExternallyVisibleAttrs(AliasAttrs Attr)72 AliasAttrs getExternallyVisibleAttrs(AliasAttrs Attr) {
73   return Attr & AliasAttrs(ExternalAttrMask);
74 }
75 
instantiateInterfaceValue(InterfaceValue IValue,CallBase & Call)76 Optional<InstantiatedValue> instantiateInterfaceValue(InterfaceValue IValue,
77                                                       CallBase &Call) {
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};
82   return None;
83 }
84 
85 Optional<InstantiatedRelation>
instantiateExternalRelation(ExternalRelation ERelation,CallBase & Call)86 instantiateExternalRelation(ExternalRelation ERelation, CallBase &Call) {
87   auto From = instantiateInterfaceValue(ERelation.From, Call);
88   if (!From)
89     return None;
90   auto To = instantiateInterfaceValue(ERelation.To, Call);
91   if (!To)
92     return None;
93   return InstantiatedRelation{*From, *To, ERelation.Offset};
94 }
95 
instantiateExternalAttribute(ExternalAttribute EAttr,CallBase & Call)96 Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute EAttr,
97                                                         CallBase &Call) {
98   auto Value = instantiateInterfaceValue(EAttr.IValue, Call);
99   if (!Value)
100     return None;
101   return InstantiatedAttr{*Value, EAttr.Attr};
102 }
103 }
104 }
105