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