AliasAnalysisSummary.cpp revision 355940
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 { 10const unsigned AttrEscapedIndex = 0; 11const unsigned AttrUnknownIndex = 1; 12const unsigned AttrGlobalIndex = 2; 13const unsigned AttrCallerIndex = 3; 14const unsigned AttrFirstArgIndex = 4; 15const unsigned AttrLastArgIndex = NumAliasAttrs; 16const 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. 20using AliasAttr = unsigned; 21const AliasAttr AttrNone = 0; 22const AliasAttr AttrEscaped = 1 << AttrEscapedIndex; 23const AliasAttr AttrUnknown = 1 << AttrUnknownIndex; 24const AliasAttr AttrGlobal = 1 << AttrGlobalIndex; 25const AliasAttr AttrCaller = 1 << AttrCallerIndex; 26const AliasAttr ExternalAttrMask = AttrEscaped | AttrUnknown | AttrGlobal; 27} 28 29AliasAttrs getAttrNone() { return AttrNone; } 30 31AliasAttrs getAttrUnknown() { return AttrUnknown; } 32bool hasUnknownAttr(AliasAttrs Attr) { return Attr.test(AttrUnknownIndex); } 33 34AliasAttrs getAttrCaller() { return AttrCaller; } 35bool hasCallerAttr(AliasAttrs Attr) { return Attr.test(AttrCaller); } 36bool hasUnknownOrCallerAttr(AliasAttrs Attr) { 37 return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex); 38} 39 40AliasAttrs getAttrEscaped() { return AttrEscaped; } 41bool hasEscapedAttr(AliasAttrs Attr) { return Attr.test(AttrEscapedIndex); } 42 43static 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 51AliasAttrs 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 64bool isGlobalOrArgAttr(AliasAttrs Attr) { 65 return Attr.reset(AttrEscapedIndex) 66 .reset(AttrUnknownIndex) 67 .reset(AttrCallerIndex) 68 .any(); 69} 70 71AliasAttrs getExternallyVisibleAttrs(AliasAttrs Attr) { 72 return Attr & AliasAttrs(ExternalAttrMask); 73} 74 75Optional<InstantiatedValue> instantiateInterfaceValue(InterfaceValue IValue, 76 CallBase &Call) { 77 auto Index = IValue.Index; 78 auto *V = (Index == 0) ? &Call : Call.getArgOperand(Index - 1); 79 if (V->getType()->isPointerTy()) 80 return InstantiatedValue{V, IValue.DerefLevel}; 81 return None; 82} 83 84Optional<InstantiatedRelation> 85instantiateExternalRelation(ExternalRelation ERelation, CallBase &Call) { 86 auto From = instantiateInterfaceValue(ERelation.From, Call); 87 if (!From) 88 return None; 89 auto To = instantiateInterfaceValue(ERelation.To, Call); 90 if (!To) 91 return None; 92 return InstantiatedRelation{*From, *To, ERelation.Offset}; 93} 94 95Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute EAttr, 96 CallBase &Call) { 97 auto Value = instantiateInterfaceValue(EAttr.IValue, Call); 98 if (!Value) 99 return None; 100 return InstantiatedAttr{*Value, EAttr.Attr}; 101} 102} 103} 104