13ca95b02SDimitry Andric #include "AliasAnalysisSummary.h"
23ca95b02SDimitry Andric #include "llvm/IR/Argument.h"
33ca95b02SDimitry Andric #include "llvm/IR/Type.h"
43ca95b02SDimitry Andric #include "llvm/Support/Compiler.h"
53ca95b02SDimitry Andric 
63ca95b02SDimitry Andric namespace llvm {
73ca95b02SDimitry Andric namespace cflaa {
83ca95b02SDimitry Andric 
93ca95b02SDimitry Andric namespace {
10*d88c1a5aSDimitry Andric const unsigned AttrEscapedIndex = 0;
11*d88c1a5aSDimitry Andric const unsigned AttrUnknownIndex = 1;
12*d88c1a5aSDimitry Andric const unsigned AttrGlobalIndex = 2;
13*d88c1a5aSDimitry Andric const unsigned AttrCallerIndex = 3;
14*d88c1a5aSDimitry Andric const unsigned AttrFirstArgIndex = 4;
15*d88c1a5aSDimitry Andric const unsigned AttrLastArgIndex = NumAliasAttrs;
16*d88c1a5aSDimitry Andric const unsigned AttrMaxNumArgs = AttrLastArgIndex - AttrFirstArgIndex;
173ca95b02SDimitry Andric 
18*d88c1a5aSDimitry Andric // It would be *slightly* prettier if we changed these to AliasAttrs, but it
19*d88c1a5aSDimitry Andric // seems that both GCC and MSVC emit dynamic initializers for const bitsets.
203ca95b02SDimitry Andric using AliasAttr = unsigned;
21*d88c1a5aSDimitry Andric const AliasAttr AttrNone = 0;
22*d88c1a5aSDimitry Andric const AliasAttr AttrEscaped = 1 << AttrEscapedIndex;
23*d88c1a5aSDimitry Andric const AliasAttr AttrUnknown = 1 << AttrUnknownIndex;
24*d88c1a5aSDimitry Andric const AliasAttr AttrGlobal = 1 << AttrGlobalIndex;
25*d88c1a5aSDimitry Andric const AliasAttr AttrCaller = 1 << AttrCallerIndex;
26*d88c1a5aSDimitry Andric const AliasAttr ExternalAttrMask = AttrEscaped | AttrUnknown | AttrGlobal;
273ca95b02SDimitry Andric }
283ca95b02SDimitry Andric 
getAttrNone()293ca95b02SDimitry Andric AliasAttrs getAttrNone() { return AttrNone; }
303ca95b02SDimitry Andric 
getAttrUnknown()313ca95b02SDimitry Andric AliasAttrs getAttrUnknown() { return AttrUnknown; }
hasUnknownAttr(AliasAttrs Attr)323ca95b02SDimitry Andric bool hasUnknownAttr(AliasAttrs Attr) { return Attr.test(AttrUnknownIndex); }
333ca95b02SDimitry Andric 
getAttrCaller()343ca95b02SDimitry Andric AliasAttrs getAttrCaller() { return AttrCaller; }
hasCallerAttr(AliasAttrs Attr)353ca95b02SDimitry Andric bool hasCallerAttr(AliasAttrs Attr) { return Attr.test(AttrCaller); }
hasUnknownOrCallerAttr(AliasAttrs Attr)363ca95b02SDimitry Andric bool hasUnknownOrCallerAttr(AliasAttrs Attr) {
373ca95b02SDimitry Andric   return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex);
383ca95b02SDimitry Andric }
393ca95b02SDimitry Andric 
getAttrEscaped()403ca95b02SDimitry Andric AliasAttrs getAttrEscaped() { return AttrEscaped; }
hasEscapedAttr(AliasAttrs Attr)413ca95b02SDimitry Andric bool hasEscapedAttr(AliasAttrs Attr) { return Attr.test(AttrEscapedIndex); }
423ca95b02SDimitry Andric 
argNumberToAttr(unsigned ArgNum)433ca95b02SDimitry Andric static AliasAttr argNumberToAttr(unsigned ArgNum) {
443ca95b02SDimitry Andric   if (ArgNum >= AttrMaxNumArgs)
453ca95b02SDimitry Andric     return AttrUnknown;
463ca95b02SDimitry Andric   // N.B. MSVC complains if we use `1U` here, since AliasAttr' ctor takes
473ca95b02SDimitry Andric   // an unsigned long long.
483ca95b02SDimitry Andric   return AliasAttr(1ULL << (ArgNum + AttrFirstArgIndex));
493ca95b02SDimitry Andric }
503ca95b02SDimitry Andric 
getGlobalOrArgAttrFromValue(const Value & Val)513ca95b02SDimitry Andric AliasAttrs getGlobalOrArgAttrFromValue(const Value &Val) {
523ca95b02SDimitry Andric   if (isa<GlobalValue>(Val))
533ca95b02SDimitry Andric     return AttrGlobal;
543ca95b02SDimitry Andric 
553ca95b02SDimitry Andric   if (auto *Arg = dyn_cast<Argument>(&Val))
563ca95b02SDimitry Andric     // Only pointer arguments should have the argument attribute,
573ca95b02SDimitry Andric     // because things can't escape through scalars without us seeing a
583ca95b02SDimitry Andric     // cast, and thus, interaction with them doesn't matter.
593ca95b02SDimitry Andric     if (!Arg->hasNoAliasAttr() && Arg->getType()->isPointerTy())
603ca95b02SDimitry Andric       return argNumberToAttr(Arg->getArgNo());
613ca95b02SDimitry Andric   return AttrNone;
623ca95b02SDimitry Andric }
633ca95b02SDimitry Andric 
isGlobalOrArgAttr(AliasAttrs Attr)643ca95b02SDimitry Andric bool isGlobalOrArgAttr(AliasAttrs Attr) {
653ca95b02SDimitry Andric   return Attr.reset(AttrEscapedIndex)
663ca95b02SDimitry Andric       .reset(AttrUnknownIndex)
673ca95b02SDimitry Andric       .reset(AttrCallerIndex)
683ca95b02SDimitry Andric       .any();
693ca95b02SDimitry Andric }
703ca95b02SDimitry Andric 
getExternallyVisibleAttrs(AliasAttrs Attr)713ca95b02SDimitry Andric AliasAttrs getExternallyVisibleAttrs(AliasAttrs Attr) {
723ca95b02SDimitry Andric   return Attr & AliasAttrs(ExternalAttrMask);
733ca95b02SDimitry Andric }
743ca95b02SDimitry Andric 
instantiateInterfaceValue(InterfaceValue IValue,CallSite CS)753ca95b02SDimitry Andric Optional<InstantiatedValue> instantiateInterfaceValue(InterfaceValue IValue,
763ca95b02SDimitry Andric                                                       CallSite CS) {
773ca95b02SDimitry Andric   auto Index = IValue.Index;
783ca95b02SDimitry Andric   auto Value = (Index == 0) ? CS.getInstruction() : CS.getArgument(Index - 1);
793ca95b02SDimitry Andric   if (Value->getType()->isPointerTy())
803ca95b02SDimitry Andric     return InstantiatedValue{Value, IValue.DerefLevel};
813ca95b02SDimitry Andric   return None;
823ca95b02SDimitry Andric }
833ca95b02SDimitry Andric 
843ca95b02SDimitry Andric Optional<InstantiatedRelation>
instantiateExternalRelation(ExternalRelation ERelation,CallSite CS)853ca95b02SDimitry Andric instantiateExternalRelation(ExternalRelation ERelation, CallSite CS) {
863ca95b02SDimitry Andric   auto From = instantiateInterfaceValue(ERelation.From, CS);
873ca95b02SDimitry Andric   if (!From)
883ca95b02SDimitry Andric     return None;
893ca95b02SDimitry Andric   auto To = instantiateInterfaceValue(ERelation.To, CS);
903ca95b02SDimitry Andric   if (!To)
913ca95b02SDimitry Andric     return None;
92*d88c1a5aSDimitry Andric   return InstantiatedRelation{*From, *To, ERelation.Offset};
933ca95b02SDimitry Andric }
943ca95b02SDimitry Andric 
instantiateExternalAttribute(ExternalAttribute EAttr,CallSite CS)953ca95b02SDimitry Andric Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute EAttr,
963ca95b02SDimitry Andric                                                         CallSite CS) {
973ca95b02SDimitry Andric   auto Value = instantiateInterfaceValue(EAttr.IValue, CS);
983ca95b02SDimitry Andric   if (!Value)
993ca95b02SDimitry Andric     return None;
1003ca95b02SDimitry Andric   return InstantiatedAttr{*Value, EAttr.Attr};
1013ca95b02SDimitry Andric }
1023ca95b02SDimitry Andric }
1033ca95b02SDimitry Andric }
104