1*9880d681SAndroid Build Coastguard Worker //=====- CFLSummary.h - Abstract stratified sets implementation. --------=====// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker /// \file 10*9880d681SAndroid Build Coastguard Worker /// This file defines various utility types and functions useful to 11*9880d681SAndroid Build Coastguard Worker /// summary-based alias analysis. 12*9880d681SAndroid Build Coastguard Worker /// 13*9880d681SAndroid Build Coastguard Worker /// Summary-based analysis, also known as bottom-up analysis, is a style of 14*9880d681SAndroid Build Coastguard Worker /// interprocedrual static analysis that tries to analyze the callees before the 15*9880d681SAndroid Build Coastguard Worker /// callers get analyzed. The key idea of summary-based analysis is to first 16*9880d681SAndroid Build Coastguard Worker /// process each function indepedently, outline its behavior in a condensed 17*9880d681SAndroid Build Coastguard Worker /// summary, and then instantiate the summary at the callsite when the said 18*9880d681SAndroid Build Coastguard Worker /// function is called elsewhere. This is often in contrast to another style 19*9880d681SAndroid Build Coastguard Worker /// called top-down analysis, in which callers are always analyzed first before 20*9880d681SAndroid Build Coastguard Worker /// the callees. 21*9880d681SAndroid Build Coastguard Worker /// 22*9880d681SAndroid Build Coastguard Worker /// In a summary-based analysis, functions must be examined independently and 23*9880d681SAndroid Build Coastguard Worker /// out-of-context. We have no information on the state of the memory, the 24*9880d681SAndroid Build Coastguard Worker /// arguments, the global values, and anything else external to the function. To 25*9880d681SAndroid Build Coastguard Worker /// carry out the analysis conservative assumptions have to be made about those 26*9880d681SAndroid Build Coastguard Worker /// external states. In exchange for the potential loss of precision, the 27*9880d681SAndroid Build Coastguard Worker /// summary we obtain this way is highly reusable, which makes the analysis 28*9880d681SAndroid Build Coastguard Worker /// easier to scale to large programs even if carried out context-sensitively. 29*9880d681SAndroid Build Coastguard Worker /// 30*9880d681SAndroid Build Coastguard Worker /// Currently, all CFL-based alias analyses adopt the summary-based approach 31*9880d681SAndroid Build Coastguard Worker /// and therefore heavily rely on this header. 32*9880d681SAndroid Build Coastguard Worker /// 33*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_ANALYSIS_ALIASANALYSISSUMMARY_H 36*9880d681SAndroid Build Coastguard Worker #define LLVM_ANALYSIS_ALIASANALYSISSUMMARY_H 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/DenseMapInfo.h" 39*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Optional.h" 40*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h" 41*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/CallSite.h" 42*9880d681SAndroid Build Coastguard Worker #include <bitset> 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Worker namespace llvm { 45*9880d681SAndroid Build Coastguard Worker namespace cflaa { 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 48*9880d681SAndroid Build Coastguard Worker // AliasAttr related stuffs 49*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Worker /// The number of attributes that AliasAttr should contain. Attributes are 52*9880d681SAndroid Build Coastguard Worker /// described below, and 32 was an arbitrary choice because it fits nicely in 32 53*9880d681SAndroid Build Coastguard Worker /// bits (because we use a bitset for AliasAttr). 54*9880d681SAndroid Build Coastguard Worker static const unsigned NumAliasAttrs = 32; 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Worker /// These are attributes that an alias analysis can use to mark certain special 57*9880d681SAndroid Build Coastguard Worker /// properties of a given pointer. Refer to the related functions below to see 58*9880d681SAndroid Build Coastguard Worker /// what kinds of attributes are currently defined. 59*9880d681SAndroid Build Coastguard Worker typedef std::bitset<NumAliasAttrs> AliasAttrs; 60*9880d681SAndroid Build Coastguard Worker 61*9880d681SAndroid Build Coastguard Worker /// Attr represent whether the said pointer comes from an unknown source 62*9880d681SAndroid Build Coastguard Worker /// (such as opaque memory or an integer cast). 63*9880d681SAndroid Build Coastguard Worker AliasAttrs getAttrNone(); 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Worker /// AttrUnknown represent whether the said pointer comes from a source not known 66*9880d681SAndroid Build Coastguard Worker /// to alias analyses (such as opaque memory or an integer cast). 67*9880d681SAndroid Build Coastguard Worker AliasAttrs getAttrUnknown(); 68*9880d681SAndroid Build Coastguard Worker bool hasUnknownAttr(AliasAttrs); 69*9880d681SAndroid Build Coastguard Worker 70*9880d681SAndroid Build Coastguard Worker /// AttrCaller represent whether the said pointer comes from a source not known 71*9880d681SAndroid Build Coastguard Worker /// to the current function but known to the caller. Values pointed to by the 72*9880d681SAndroid Build Coastguard Worker /// arguments of the current function have this attribute set 73*9880d681SAndroid Build Coastguard Worker AliasAttrs getAttrCaller(); 74*9880d681SAndroid Build Coastguard Worker bool hasCallerAttr(AliasAttrs); 75*9880d681SAndroid Build Coastguard Worker bool hasUnknownOrCallerAttr(AliasAttrs); 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker /// AttrEscaped represent whether the said pointer comes from a known source but 78*9880d681SAndroid Build Coastguard Worker /// escapes to the unknown world (e.g. casted to an integer, or passed as an 79*9880d681SAndroid Build Coastguard Worker /// argument to opaque function). Unlike non-escaped pointers, escaped ones may 80*9880d681SAndroid Build Coastguard Worker /// alias pointers coming from unknown sources. 81*9880d681SAndroid Build Coastguard Worker AliasAttrs getAttrEscaped(); 82*9880d681SAndroid Build Coastguard Worker bool hasEscapedAttr(AliasAttrs); 83*9880d681SAndroid Build Coastguard Worker 84*9880d681SAndroid Build Coastguard Worker /// AttrGlobal represent whether the said pointer is a global value. 85*9880d681SAndroid Build Coastguard Worker /// AttrArg represent whether the said pointer is an argument, and if so, what 86*9880d681SAndroid Build Coastguard Worker /// index the argument has. 87*9880d681SAndroid Build Coastguard Worker AliasAttrs getGlobalOrArgAttrFromValue(const Value &); 88*9880d681SAndroid Build Coastguard Worker bool isGlobalOrArgAttr(AliasAttrs); 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker /// Given an AliasAttrs, return a new AliasAttrs that only contains attributes 91*9880d681SAndroid Build Coastguard Worker /// meaningful to the caller. This function is primarily used for 92*9880d681SAndroid Build Coastguard Worker /// interprocedural analysis 93*9880d681SAndroid Build Coastguard Worker /// Currently, externally visible AliasAttrs include AttrUnknown, AttrGlobal, 94*9880d681SAndroid Build Coastguard Worker /// and AttrEscaped 95*9880d681SAndroid Build Coastguard Worker AliasAttrs getExternallyVisibleAttrs(AliasAttrs); 96*9880d681SAndroid Build Coastguard Worker 97*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 98*9880d681SAndroid Build Coastguard Worker // Function summary related stuffs 99*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 100*9880d681SAndroid Build Coastguard Worker 101*9880d681SAndroid Build Coastguard Worker /// The maximum number of arguments we can put into a summary. 102*9880d681SAndroid Build Coastguard Worker LLVM_CONSTEXPR static unsigned MaxSupportedArgsInSummary = 50; 103*9880d681SAndroid Build Coastguard Worker 104*9880d681SAndroid Build Coastguard Worker /// We use InterfaceValue to describe parameters/return value, as well as 105*9880d681SAndroid Build Coastguard Worker /// potential memory locations that are pointed to by parameters/return value, 106*9880d681SAndroid Build Coastguard Worker /// of a function. 107*9880d681SAndroid Build Coastguard Worker /// Index is an integer which represents a single parameter or a return value. 108*9880d681SAndroid Build Coastguard Worker /// When the index is 0, it refers to the return value. Non-zero index i refers 109*9880d681SAndroid Build Coastguard Worker /// to the i-th parameter. 110*9880d681SAndroid Build Coastguard Worker /// DerefLevel indicates the number of dereferences one must perform on the 111*9880d681SAndroid Build Coastguard Worker /// parameter/return value to get this InterfaceValue. 112*9880d681SAndroid Build Coastguard Worker struct InterfaceValue { 113*9880d681SAndroid Build Coastguard Worker unsigned Index; 114*9880d681SAndroid Build Coastguard Worker unsigned DerefLevel; 115*9880d681SAndroid Build Coastguard Worker }; 116*9880d681SAndroid Build Coastguard Worker 117*9880d681SAndroid Build Coastguard Worker inline bool operator==(InterfaceValue lhs, InterfaceValue rhs) { 118*9880d681SAndroid Build Coastguard Worker return lhs.Index == rhs.Index && lhs.DerefLevel == rhs.DerefLevel; 119*9880d681SAndroid Build Coastguard Worker } 120*9880d681SAndroid Build Coastguard Worker inline bool operator!=(InterfaceValue lhs, InterfaceValue rhs) { 121*9880d681SAndroid Build Coastguard Worker return !(lhs == rhs); 122*9880d681SAndroid Build Coastguard Worker } 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Worker /// We use ExternalRelation to describe an externally visible aliasing relations 125*9880d681SAndroid Build Coastguard Worker /// between parameters/return value of a function. 126*9880d681SAndroid Build Coastguard Worker struct ExternalRelation { 127*9880d681SAndroid Build Coastguard Worker InterfaceValue From, To; 128*9880d681SAndroid Build Coastguard Worker }; 129*9880d681SAndroid Build Coastguard Worker 130*9880d681SAndroid Build Coastguard Worker /// We use ExternalAttribute to describe an externally visible AliasAttrs 131*9880d681SAndroid Build Coastguard Worker /// for parameters/return value. 132*9880d681SAndroid Build Coastguard Worker struct ExternalAttribute { 133*9880d681SAndroid Build Coastguard Worker InterfaceValue IValue; 134*9880d681SAndroid Build Coastguard Worker AliasAttrs Attr; 135*9880d681SAndroid Build Coastguard Worker }; 136*9880d681SAndroid Build Coastguard Worker 137*9880d681SAndroid Build Coastguard Worker /// AliasSummary is just a collection of ExternalRelation and ExternalAttribute 138*9880d681SAndroid Build Coastguard Worker struct AliasSummary { 139*9880d681SAndroid Build Coastguard Worker // RetParamRelations is a collection of ExternalRelations. 140*9880d681SAndroid Build Coastguard Worker SmallVector<ExternalRelation, 8> RetParamRelations; 141*9880d681SAndroid Build Coastguard Worker 142*9880d681SAndroid Build Coastguard Worker // RetParamAttributes is a collection of ExternalAttributes. 143*9880d681SAndroid Build Coastguard Worker SmallVector<ExternalAttribute, 8> RetParamAttributes; 144*9880d681SAndroid Build Coastguard Worker }; 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker /// This is the result of instantiating InterfaceValue at a particular callsite 147*9880d681SAndroid Build Coastguard Worker struct InstantiatedValue { 148*9880d681SAndroid Build Coastguard Worker Value *Val; 149*9880d681SAndroid Build Coastguard Worker unsigned DerefLevel; 150*9880d681SAndroid Build Coastguard Worker }; 151*9880d681SAndroid Build Coastguard Worker Optional<InstantiatedValue> instantiateInterfaceValue(InterfaceValue, CallSite); 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Worker /// This is the result of instantiating ExternalRelation at a particular 154*9880d681SAndroid Build Coastguard Worker /// callsite 155*9880d681SAndroid Build Coastguard Worker struct InstantiatedRelation { 156*9880d681SAndroid Build Coastguard Worker InstantiatedValue From, To; 157*9880d681SAndroid Build Coastguard Worker }; 158*9880d681SAndroid Build Coastguard Worker Optional<InstantiatedRelation> instantiateExternalRelation(ExternalRelation, 159*9880d681SAndroid Build Coastguard Worker CallSite); 160*9880d681SAndroid Build Coastguard Worker 161*9880d681SAndroid Build Coastguard Worker /// This is the result of instantiating ExternalAttribute at a particular 162*9880d681SAndroid Build Coastguard Worker /// callsite 163*9880d681SAndroid Build Coastguard Worker struct InstantiatedAttr { 164*9880d681SAndroid Build Coastguard Worker InstantiatedValue IValue; 165*9880d681SAndroid Build Coastguard Worker AliasAttrs Attr; 166*9880d681SAndroid Build Coastguard Worker }; 167*9880d681SAndroid Build Coastguard Worker Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute, 168*9880d681SAndroid Build Coastguard Worker CallSite); 169*9880d681SAndroid Build Coastguard Worker } 170*9880d681SAndroid Build Coastguard Worker 171*9880d681SAndroid Build Coastguard Worker template <> struct DenseMapInfo<cflaa::InstantiatedValue> { 172*9880d681SAndroid Build Coastguard Worker static inline cflaa::InstantiatedValue getEmptyKey() { 173*9880d681SAndroid Build Coastguard Worker return cflaa::InstantiatedValue{DenseMapInfo<Value *>::getEmptyKey(), 174*9880d681SAndroid Build Coastguard Worker DenseMapInfo<unsigned>::getEmptyKey()}; 175*9880d681SAndroid Build Coastguard Worker } 176*9880d681SAndroid Build Coastguard Worker static inline cflaa::InstantiatedValue getTombstoneKey() { 177*9880d681SAndroid Build Coastguard Worker return cflaa::InstantiatedValue{DenseMapInfo<Value *>::getTombstoneKey(), 178*9880d681SAndroid Build Coastguard Worker DenseMapInfo<unsigned>::getTombstoneKey()}; 179*9880d681SAndroid Build Coastguard Worker } 180*9880d681SAndroid Build Coastguard Worker static unsigned getHashValue(const cflaa::InstantiatedValue &IV) { 181*9880d681SAndroid Build Coastguard Worker return DenseMapInfo<std::pair<Value *, unsigned>>::getHashValue( 182*9880d681SAndroid Build Coastguard Worker std::make_pair(IV.Val, IV.DerefLevel)); 183*9880d681SAndroid Build Coastguard Worker } 184*9880d681SAndroid Build Coastguard Worker static bool isEqual(const cflaa::InstantiatedValue &LHS, 185*9880d681SAndroid Build Coastguard Worker const cflaa::InstantiatedValue &RHS) { 186*9880d681SAndroid Build Coastguard Worker return LHS.Val == RHS.Val && LHS.DerefLevel == RHS.DerefLevel; 187*9880d681SAndroid Build Coastguard Worker } 188*9880d681SAndroid Build Coastguard Worker }; 189*9880d681SAndroid Build Coastguard Worker } 190*9880d681SAndroid Build Coastguard Worker 191*9880d681SAndroid Build Coastguard Worker #endif 192