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 { |
| 10 | LLVM_CONSTEXPR unsigned AttrEscapedIndex = 0; |
| 11 | LLVM_CONSTEXPR unsigned AttrUnknownIndex = 1; |
| 12 | LLVM_CONSTEXPR unsigned AttrGlobalIndex = 2; |
| 13 | LLVM_CONSTEXPR unsigned AttrCallerIndex = 3; |
| 14 | LLVM_CONSTEXPR unsigned AttrFirstArgIndex = 4; |
| 15 | LLVM_CONSTEXPR unsigned AttrLastArgIndex = NumAliasAttrs; |
| 16 | LLVM_CONSTEXPR unsigned AttrMaxNumArgs = AttrLastArgIndex - AttrFirstArgIndex; |
| 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; |
| 22 | LLVM_CONSTEXPR AliasAttr AttrNone = 0; |
| 23 | LLVM_CONSTEXPR AliasAttr AttrEscaped = 1 << AttrEscapedIndex; |
| 24 | LLVM_CONSTEXPR AliasAttr AttrUnknown = 1 << AttrUnknownIndex; |
| 25 | LLVM_CONSTEXPR AliasAttr AttrGlobal = 1 << AttrGlobalIndex; |
| 26 | LLVM_CONSTEXPR AliasAttr AttrCaller = 1 << AttrCallerIndex; |
| 27 | LLVM_CONSTEXPR AliasAttr ExternalAttrMask = |
| 28 | AttrEscaped | AttrUnknown | AttrGlobal; |
| 29 | } |
| 30 | |
| 31 | AliasAttrs getAttrNone() { return AttrNone; } |
| 32 | |
| 33 | AliasAttrs getAttrUnknown() { return AttrUnknown; } |
| 34 | bool hasUnknownAttr(AliasAttrs Attr) { return Attr.test(AttrUnknownIndex); } |
| 35 | |
| 36 | AliasAttrs getAttrCaller() { return AttrCaller; } |
| 37 | bool hasCallerAttr(AliasAttrs Attr) { return Attr.test(AttrCaller); } |
| 38 | bool hasUnknownOrCallerAttr(AliasAttrs Attr) { |
| 39 | return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex); |
| 40 | } |
| 41 | |
| 42 | AliasAttrs getAttrEscaped() { return AttrEscaped; } |
| 43 | bool hasEscapedAttr(AliasAttrs Attr) { return Attr.test(AttrEscapedIndex); } |
| 44 | |
| 45 | static AliasAttr argNumberToAttr(unsigned ArgNum) { |
| 46 | if (ArgNum >= AttrMaxNumArgs) |
| 47 | return AttrUnknown; |
| 48 | // N.B. MSVC complains if we use `1U` here, since AliasAttr' ctor takes |
| 49 | // an unsigned long long. |
| 50 | return AliasAttr(1ULL << (ArgNum + AttrFirstArgIndex)); |
| 51 | } |
| 52 | |
| 53 | AliasAttrs getGlobalOrArgAttrFromValue(const Value &Val) { |
| 54 | if (isa<GlobalValue>(Val)) |
| 55 | return AttrGlobal; |
| 56 | |
| 57 | if (auto *Arg = dyn_cast<Argument>(&Val)) |
| 58 | // Only pointer arguments should have the argument attribute, |
| 59 | // because things can't escape through scalars without us seeing a |
| 60 | // cast, and thus, interaction with them doesn't matter. |
| 61 | if (!Arg->hasNoAliasAttr() && Arg->getType()->isPointerTy()) |
| 62 | return argNumberToAttr(Arg->getArgNo()); |
| 63 | return AttrNone; |
| 64 | } |
| 65 | |
| 66 | bool isGlobalOrArgAttr(AliasAttrs Attr) { |
| 67 | return Attr.reset(AttrEscapedIndex) |
| 68 | .reset(AttrUnknownIndex) |
| 69 | .reset(AttrCallerIndex) |
| 70 | .any(); |
| 71 | } |
| 72 | |
| 73 | AliasAttrs getExternallyVisibleAttrs(AliasAttrs Attr) { |
| 74 | return Attr & AliasAttrs(ExternalAttrMask); |
| 75 | } |
| 76 | |
| 77 | Optional<InstantiatedValue> instantiateInterfaceValue(InterfaceValue IValue, |
| 78 | CallSite CS) { |
| 79 | auto Index = IValue.Index; |
| 80 | auto Value = (Index == 0) ? CS.getInstruction() : CS.getArgument(Index - 1); |
| 81 | if (Value->getType()->isPointerTy()) |
| 82 | return InstantiatedValue{Value, IValue.DerefLevel}; |
| 83 | return None; |
| 84 | } |
| 85 | |
| 86 | Optional<InstantiatedRelation> |
| 87 | instantiateExternalRelation(ExternalRelation ERelation, CallSite CS) { |
| 88 | auto From = instantiateInterfaceValue(ERelation.From, CS); |
| 89 | if (!From) |
| 90 | return None; |
| 91 | auto To = instantiateInterfaceValue(ERelation.To, CS); |
| 92 | if (!To) |
| 93 | return None; |
George Burgess IV | 4ec1753 | 2016-07-22 22:30:48 +0000 | [diff] [blame] | 94 | return InstantiatedRelation{*From, *To, ERelation.Offset}; |
George Burgess IV | e191996 | 2016-07-06 00:47:21 +0000 | [diff] [blame] | 95 | } |
| 96 | |
| 97 | Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute EAttr, |
| 98 | CallSite CS) { |
| 99 | auto Value = instantiateInterfaceValue(EAttr.IValue, CS); |
| 100 | if (!Value) |
| 101 | return None; |
| 102 | return InstantiatedAttr{*Value, EAttr.Attr}; |
| 103 | } |
| 104 | } |
| 105 | } |