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 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; 17 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. 20 using AliasAttr = unsigned; 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; 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; 92 return InstantiatedRelation{*From, *To, ERelation.Offset}; 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 } 104