AliasAnalysisSummary.cpp revision 303231
1#include "AliasAnalysisSummary.h" 2#include "llvm/IR/Argument.h" 3#include "llvm/IR/Type.h" 4#include "llvm/Support/Compiler.h" 5 6namespace llvm { 7namespace cflaa { 8 9namespace { 10LLVM_CONSTEXPR unsigned AttrEscapedIndex = 0; 11LLVM_CONSTEXPR unsigned AttrUnknownIndex = 1; 12LLVM_CONSTEXPR unsigned AttrGlobalIndex = 2; 13LLVM_CONSTEXPR unsigned AttrCallerIndex = 3; 14LLVM_CONSTEXPR unsigned AttrFirstArgIndex = 4; 15LLVM_CONSTEXPR unsigned AttrLastArgIndex = NumAliasAttrs; 16LLVM_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... 21using AliasAttr = unsigned; 22LLVM_CONSTEXPR AliasAttr AttrNone = 0; 23LLVM_CONSTEXPR AliasAttr AttrEscaped = 1 << AttrEscapedIndex; 24LLVM_CONSTEXPR AliasAttr AttrUnknown = 1 << AttrUnknownIndex; 25LLVM_CONSTEXPR AliasAttr AttrGlobal = 1 << AttrGlobalIndex; 26LLVM_CONSTEXPR AliasAttr AttrCaller = 1 << AttrCallerIndex; 27LLVM_CONSTEXPR AliasAttr ExternalAttrMask = 28 AttrEscaped | AttrUnknown | AttrGlobal; 29} 30 31AliasAttrs getAttrNone() { return AttrNone; } 32 33AliasAttrs getAttrUnknown() { return AttrUnknown; } 34bool hasUnknownAttr(AliasAttrs Attr) { return Attr.test(AttrUnknownIndex); } 35 36AliasAttrs getAttrCaller() { return AttrCaller; } 37bool hasCallerAttr(AliasAttrs Attr) { return Attr.test(AttrCaller); } 38bool hasUnknownOrCallerAttr(AliasAttrs Attr) { 39 return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex); 40} 41 42AliasAttrs getAttrEscaped() { return AttrEscaped; } 43bool hasEscapedAttr(AliasAttrs Attr) { return Attr.test(AttrEscapedIndex); } 44 45static 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 53AliasAttrs 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 66bool isGlobalOrArgAttr(AliasAttrs Attr) { 67 return Attr.reset(AttrEscapedIndex) 68 .reset(AttrUnknownIndex) 69 .reset(AttrCallerIndex) 70 .any(); 71} 72 73AliasAttrs getExternallyVisibleAttrs(AliasAttrs Attr) { 74 return Attr & AliasAttrs(ExternalAttrMask); 75} 76 77Optional<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 86Optional<InstantiatedRelation> 87instantiateExternalRelation(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 97Optional<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