[NFC] Update memcpy tests
[llvm-complete.git] / lib / Analysis / AliasAnalysisSummary.cpp
blob2f3396a44117a256619ca5518f9a9e7e3f7339b8
1 #include "AliasAnalysisSummary.h"
2 #include "llvm/IR/Argument.h"
3 #include "llvm/IR/Type.h"
4 #include "llvm/Support/Compiler.h"
6 namespace llvm {
7 namespace cflaa {
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;
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;
29 AliasAttrs getAttrNone() { return AttrNone; }
31 AliasAttrs getAttrUnknown() { return AttrUnknown; }
32 bool hasUnknownAttr(AliasAttrs Attr) { return Attr.test(AttrUnknownIndex); }
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);
40 AliasAttrs getAttrEscaped() { return AttrEscaped; }
41 bool hasEscapedAttr(AliasAttrs Attr) { return Attr.test(AttrEscapedIndex); }
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));
51 AliasAttrs getGlobalOrArgAttrFromValue(const Value &Val) {
52 if (isa<GlobalValue>(Val))
53 return AttrGlobal;
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;
64 bool isGlobalOrArgAttr(AliasAttrs Attr) {
65 return Attr.reset(AttrEscapedIndex)
66 .reset(AttrUnknownIndex)
67 .reset(AttrCallerIndex)
68 .any();
71 AliasAttrs getExternallyVisibleAttrs(AliasAttrs Attr) {
72 return Attr & AliasAttrs(ExternalAttrMask);
75 Optional<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;
84 Optional<InstantiatedRelation>
85 instantiateExternalRelation(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};
95 Optional<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};