|  | #include "AliasAnalysisSummary.h" | 
|  | #include "llvm/IR/Argument.h" | 
|  | #include "llvm/IR/Type.h" | 
|  | #include "llvm/Support/Compiler.h" | 
|  |  | 
|  | namespace llvm { | 
|  | namespace cflaa { | 
|  |  | 
|  | namespace { | 
|  | const unsigned AttrEscapedIndex = 0; | 
|  | const unsigned AttrUnknownIndex = 1; | 
|  | const unsigned AttrGlobalIndex = 2; | 
|  | const unsigned AttrCallerIndex = 3; | 
|  | const unsigned AttrFirstArgIndex = 4; | 
|  | const unsigned AttrLastArgIndex = NumAliasAttrs; | 
|  | const unsigned AttrMaxNumArgs = AttrLastArgIndex - AttrFirstArgIndex; | 
|  |  | 
|  | // It would be *slightly* prettier if we changed these to AliasAttrs, but it | 
|  | // seems that both GCC and MSVC emit dynamic initializers for const bitsets. | 
|  | using AliasAttr = unsigned; | 
|  | const AliasAttr AttrNone = 0; | 
|  | const AliasAttr AttrEscaped = 1 << AttrEscapedIndex; | 
|  | const AliasAttr AttrUnknown = 1 << AttrUnknownIndex; | 
|  | const AliasAttr AttrGlobal = 1 << AttrGlobalIndex; | 
|  | const AliasAttr AttrCaller = 1 << AttrCallerIndex; | 
|  | const AliasAttr ExternalAttrMask = AttrEscaped | AttrUnknown | AttrGlobal; | 
|  | } | 
|  |  | 
|  | AliasAttrs getAttrNone() { return AttrNone; } | 
|  |  | 
|  | AliasAttrs getAttrUnknown() { return AttrUnknown; } | 
|  | bool hasUnknownAttr(AliasAttrs Attr) { return Attr.test(AttrUnknownIndex); } | 
|  |  | 
|  | AliasAttrs getAttrCaller() { return AttrCaller; } | 
|  | bool hasCallerAttr(AliasAttrs Attr) { return Attr.test(AttrCaller); } | 
|  | bool hasUnknownOrCallerAttr(AliasAttrs Attr) { | 
|  | return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex); | 
|  | } | 
|  |  | 
|  | AliasAttrs getAttrEscaped() { return AttrEscaped; } | 
|  | bool hasEscapedAttr(AliasAttrs Attr) { return Attr.test(AttrEscapedIndex); } | 
|  |  | 
|  | static AliasAttr argNumberToAttr(unsigned ArgNum) { | 
|  | if (ArgNum >= AttrMaxNumArgs) | 
|  | return AttrUnknown; | 
|  | // N.B. MSVC complains if we use `1U` here, since AliasAttr' ctor takes | 
|  | // an unsigned long long. | 
|  | return AliasAttr(1ULL << (ArgNum + AttrFirstArgIndex)); | 
|  | } | 
|  |  | 
|  | AliasAttrs getGlobalOrArgAttrFromValue(const Value &Val) { | 
|  | if (isa<GlobalValue>(Val)) | 
|  | return AttrGlobal; | 
|  |  | 
|  | if (auto *Arg = dyn_cast<Argument>(&Val)) | 
|  | // Only pointer arguments should have the argument attribute, | 
|  | // because things can't escape through scalars without us seeing a | 
|  | // cast, and thus, interaction with them doesn't matter. | 
|  | if (!Arg->hasNoAliasAttr() && Arg->getType()->isPointerTy()) | 
|  | return argNumberToAttr(Arg->getArgNo()); | 
|  | return AttrNone; | 
|  | } | 
|  |  | 
|  | bool isGlobalOrArgAttr(AliasAttrs Attr) { | 
|  | return Attr.reset(AttrEscapedIndex) | 
|  | .reset(AttrUnknownIndex) | 
|  | .reset(AttrCallerIndex) | 
|  | .any(); | 
|  | } | 
|  |  | 
|  | AliasAttrs getExternallyVisibleAttrs(AliasAttrs Attr) { | 
|  | return Attr & AliasAttrs(ExternalAttrMask); | 
|  | } | 
|  |  | 
|  | Optional<InstantiatedValue> instantiateInterfaceValue(InterfaceValue IValue, | 
|  | CallBase &Call) { | 
|  | auto Index = IValue.Index; | 
|  | auto *V = (Index == 0) ? &Call : Call.getArgOperand(Index - 1); | 
|  | if (V->getType()->isPointerTy()) | 
|  | return InstantiatedValue{V, IValue.DerefLevel}; | 
|  | return None; | 
|  | } | 
|  |  | 
|  | Optional<InstantiatedRelation> | 
|  | instantiateExternalRelation(ExternalRelation ERelation, CallBase &Call) { | 
|  | auto From = instantiateInterfaceValue(ERelation.From, Call); | 
|  | if (!From) | 
|  | return None; | 
|  | auto To = instantiateInterfaceValue(ERelation.To, Call); | 
|  | if (!To) | 
|  | return None; | 
|  | return InstantiatedRelation{*From, *To, ERelation.Offset}; | 
|  | } | 
|  |  | 
|  | Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute EAttr, | 
|  | CallBase &Call) { | 
|  | auto Value = instantiateInterfaceValue(EAttr.IValue, Call); | 
|  | if (!Value) | 
|  | return None; | 
|  | return InstantiatedAttr{*Value, EAttr.Attr}; | 
|  | } | 
|  | } | 
|  | } |