George Burgess IV | cc48e0f | 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 | 3772549 | 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 | cc48e0f | 2016-07-06 00:47:21 +0000 | [diff] [blame] | 17 | |
George Burgess IV | 816e968 | 2016-08-25 01:29:55 +0000 | [diff] [blame] | 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. |
George Burgess IV | cc48e0f | 2016-07-06 00:47:21 +0000 | [diff] [blame] | 20 | using AliasAttr = unsigned; |
George Burgess IV | 3772549 | 2016-08-25 01:05:08 +0000 | [diff] [blame] | 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; |
George Burgess IV | cc48e0f | 2016-07-06 00:47:21 +0000 | [diff] [blame] | 27 | } |
| 28 | |
| 29 | AliasAttrs getAttrNone() { return AttrNone; } |
| 30 | |
| 31 | AliasAttrs getAttrUnknown() { return AttrUnknown; } |
| 32 | bool hasUnknownAttr(AliasAttrs Attr) { return Attr.test(AttrUnknownIndex); } |
| 33 | |
| 34 | AliasAttrs getAttrCaller() { return AttrCaller; } |
| 35 | bool hasCallerAttr(AliasAttrs Attr) { return Attr.test(AttrCaller); } |
| 36 | bool hasUnknownOrCallerAttr(AliasAttrs Attr) { |
| 37 | return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex); |
| 38 | } |
| 39 | |
| 40 | AliasAttrs getAttrEscaped() { return AttrEscaped; } |
| 41 | bool hasEscapedAttr(AliasAttrs Attr) { return Attr.test(AttrEscapedIndex); } |
| 42 | |
| 43 | static AliasAttr argNumberToAttr(unsigned ArgNum) { |
| 44 | 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 | return AliasAttr(1ULL << (ArgNum + AttrFirstArgIndex)); |
| 49 | } |
| 50 | |
| 51 | AliasAttrs getGlobalOrArgAttrFromValue(const Value &Val) { |
| 52 | if (isa<GlobalValue>(Val)) |
| 53 | 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 | if (!Arg->hasNoAliasAttr() && Arg->getType()->isPointerTy()) |
| 60 | return argNumberToAttr(Arg->getArgNo()); |
| 61 | return AttrNone; |
| 62 | } |
| 63 | |
| 64 | bool isGlobalOrArgAttr(AliasAttrs Attr) { |
| 65 | return Attr.reset(AttrEscapedIndex) |
| 66 | .reset(AttrUnknownIndex) |
| 67 | .reset(AttrCallerIndex) |
| 68 | .any(); |
| 69 | } |
| 70 | |
| 71 | AliasAttrs getExternallyVisibleAttrs(AliasAttrs Attr) { |
| 72 | return Attr & AliasAttrs(ExternalAttrMask); |
| 73 | } |
| 74 | |
| 75 | Optional<InstantiatedValue> instantiateInterfaceValue(InterfaceValue IValue, |
| 76 | CallSite CS) { |
| 77 | auto Index = IValue.Index; |
| 78 | auto Value = (Index == 0) ? CS.getInstruction() : CS.getArgument(Index - 1); |
| 79 | if (Value->getType()->isPointerTy()) |
| 80 | return InstantiatedValue{Value, IValue.DerefLevel}; |
| 81 | return None; |
| 82 | } |
| 83 | |
| 84 | Optional<InstantiatedRelation> |
| 85 | instantiateExternalRelation(ExternalRelation ERelation, CallSite CS) { |
| 86 | auto From = instantiateInterfaceValue(ERelation.From, CS); |
| 87 | if (!From) |
| 88 | return None; |
| 89 | auto To = instantiateInterfaceValue(ERelation.To, CS); |
| 90 | if (!To) |
| 91 | return None; |
George Burgess IV | 3dba903 | 2016-07-22 22:30:48 +0000 | [diff] [blame] | 92 | return InstantiatedRelation{*From, *To, ERelation.Offset}; |
George Burgess IV | cc48e0f | 2016-07-06 00:47:21 +0000 | [diff] [blame] | 93 | } |
| 94 | |
| 95 | Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute EAttr, |
| 96 | CallSite CS) { |
| 97 | auto Value = instantiateInterfaceValue(EAttr.IValue, CS); |
| 98 | if (!Value) |
| 99 | return None; |
| 100 | return InstantiatedAttr{*Value, EAttr.Attr}; |
| 101 | } |
| 102 | } |
| 103 | } |