1 #include "AliasAnalysisSummary.h" 2 #include "llvm/IR/Argument.h" 3 #include "llvm/IR/InstrTypes.h" 4 #include "llvm/IR/Type.h" 5 #include "llvm/Support/Compiler.h" 6 7 namespace llvm { 8 namespace cflaa { 9 10 namespace { 11 const unsigned AttrEscapedIndex = 0; 12 const unsigned AttrUnknownIndex = 1; 13 const unsigned AttrGlobalIndex = 2; 14 const unsigned AttrCallerIndex = 3; 15 const unsigned AttrFirstArgIndex = 4; 16 const unsigned AttrLastArgIndex = NumAliasAttrs; 17 const unsigned AttrMaxNumArgs = AttrLastArgIndex - AttrFirstArgIndex; 18 19 // It would be *slightly* prettier if we changed these to AliasAttrs, but it 20 // seems that both GCC and MSVC emit dynamic initializers for const bitsets. 21 using AliasAttr = unsigned; 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; 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 CallBase &Call) { 78 auto Index = IValue.Index; 79 auto *V = (Index == 0) ? &Call : Call.getArgOperand(Index - 1); 80 if (V->getType()->isPointerTy()) 81 return InstantiatedValue{V, IValue.DerefLevel}; 82 return None; 83 } 84 85 Optional<InstantiatedRelation> 86 instantiateExternalRelation(ExternalRelation ERelation, CallBase &Call) { 87 auto From = instantiateInterfaceValue(ERelation.From, Call); 88 if (!From) 89 return None; 90 auto To = instantiateInterfaceValue(ERelation.To, Call); 91 if (!To) 92 return None; 93 return InstantiatedRelation{*From, *To, ERelation.Offset}; 94 } 95 96 Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute EAttr, 97 CallBase &Call) { 98 auto Value = instantiateInterfaceValue(EAttr.IValue, Call); 99 if (!Value) 100 return None; 101 return InstantiatedAttr{*Value, EAttr.Attr}; 102 } 103 } 104 } 105