George Burgess IV | e191996 | 2016-07-06 00:47:21 +0000 | [diff] [blame] | 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 { |
George Burgess IV | 381fc0e | 2016-08-25 01:05:08 +0000 | [diff] [blame] | 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; |
George Burgess IV | e191996 | 2016-07-06 00:47:21 +0000 | [diff] [blame] | 17 | |
| 18 | // NOTE: These aren't AliasAttrs because bitsets don't have a constexpr |
| 19 | // ctor for some versions of MSVC that we support. We could maybe refactor, |
| 20 | // but... |
| 21 | using AliasAttr = unsigned; |
George Burgess IV | 381fc0e | 2016-08-25 01:05:08 +0000 | [diff] [blame] | 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; |
George Burgess IV | e191996 | 2016-07-06 00:47:21 +0000 | [diff] [blame] | 28 | } |
| 29 | |
| 30 | AliasAttrs getAttrNone() { return AttrNone; } |
| 31 | |
| 32 | AliasAttrs getAttrUnknown() { return AttrUnknown; } |
| 33 | bool hasUnknownAttr(AliasAttrs Attr) { return Attr.test(AttrUnknownIndex); } |
| 34 | |
| 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); |
| 39 | } |
| 40 | |
| 41 | AliasAttrs getAttrEscaped() { return AttrEscaped; } |
| 42 | bool hasEscapedAttr(AliasAttrs Attr) { return Attr.test(AttrEscapedIndex); } |
| 43 | |
| 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 | |
| 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 | |
| 65 | bool isGlobalOrArgAttr(AliasAttrs Attr) { |
| 66 | return Attr.reset(AttrEscapedIndex) |
| 67 | .reset(AttrUnknownIndex) |
| 68 | .reset(AttrCallerIndex) |
| 69 | .any(); |
| 70 | } |
| 71 | |
| 72 | AliasAttrs getExternallyVisibleAttrs(AliasAttrs Attr) { |
| 73 | return Attr & AliasAttrs(ExternalAttrMask); |
| 74 | } |
| 75 | |
| 76 | Optional<InstantiatedValue> instantiateInterfaceValue(InterfaceValue IValue, |
| 77 | CallSite CS) { |
| 78 | auto Index = IValue.Index; |
| 79 | auto Value = (Index == 0) ? CS.getInstruction() : CS.getArgument(Index - 1); |
| 80 | if (Value->getType()->isPointerTy()) |
| 81 | return InstantiatedValue{Value, IValue.DerefLevel}; |
| 82 | return None; |
| 83 | } |
| 84 | |
| 85 | Optional<InstantiatedRelation> |
| 86 | instantiateExternalRelation(ExternalRelation ERelation, CallSite CS) { |
| 87 | auto From = instantiateInterfaceValue(ERelation.From, CS); |
| 88 | if (!From) |
| 89 | return None; |
| 90 | auto To = instantiateInterfaceValue(ERelation.To, CS); |
| 91 | if (!To) |
| 92 | return None; |
George Burgess IV | 4ec1753 | 2016-07-22 22:30:48 +0000 | [diff] [blame] | 93 | return InstantiatedRelation{*From, *To, ERelation.Offset}; |
George Burgess IV | e191996 | 2016-07-06 00:47:21 +0000 | [diff] [blame] | 94 | } |
| 95 | |
| 96 | Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute EAttr, |
| 97 | CallSite CS) { |
| 98 | auto Value = instantiateInterfaceValue(EAttr.IValue, CS); |
| 99 | if (!Value) |
| 100 | return None; |
| 101 | return InstantiatedAttr{*Value, EAttr.Attr}; |
| 102 | } |
| 103 | } |
| 104 | } |