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; 94 return InstantiatedRelation{*From, *To}; 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 } 106