]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/pointer-query.h
libcpp: __VA_OPT__ tweak
[thirdparty/gcc.git] / gcc / pointer-query.h
CommitLineData
2a837de2
MS
1/* Definitions of the pointer_query and related classes.
2
3 Copyright (C) 2020-2021 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21#ifndef GCC_POINTER_QUERY_H
22#define GCC_POINTER_QUERY_H
23
24/* Describes recursion limits used by functions that follow use-def
25 chains of SSA_NAMEs. */
26
27class ssa_name_limit_t
28{
29 bitmap visited; /* Bitmap of visited SSA_NAMEs. */
30 unsigned ssa_def_max; /* Longest chain of SSA_NAMEs to follow. */
31
32 /* Not copyable or assignable. */
33 DISABLE_COPY_AND_ASSIGN (ssa_name_limit_t);
34
35public:
36
37 ssa_name_limit_t ()
38 : visited (),
39 ssa_def_max (param_ssa_name_def_chain_limit) { }
40
41 /* Set a bit for the PHI in VISITED and return true if it wasn't
42 already set. */
43 bool visit_phi (tree);
44 /* Clear a bit for the PHI in VISITED. */
45 void leave_phi (tree);
46 /* Return false if the SSA_NAME chain length counter has reached
47 the limit, otherwise increment the counter and return true. */
48 bool next ();
49
50 /* If the SSA_NAME has already been "seen" return a positive value.
51 Otherwise add it to VISITED. If the SSA_NAME limit has been
52 reached, return a negative value. Otherwise return zero. */
53 int next_phi (tree);
54
55 ~ssa_name_limit_t ();
56};
57
58class pointer_query;
59
60/* Describes a reference to an object used in an access. */
61struct access_ref
62{
63 /* Set the bounds of the reference to at most as many bytes
64 as the first argument or unknown when null, and at least
65 one when the second argument is true unless the first one
66 is a constant zero. */
67 access_ref (tree = NULL_TREE, bool = false);
68
69 /* Return the PHI node REF refers to or null if it doesn't. */
70 gphi *phi () const;
71
72 /* Return the object to which REF refers. */
73 tree get_ref (vec<access_ref> *, access_ref * = NULL, int = 1,
74 ssa_name_limit_t * = NULL, pointer_query * = NULL) const;
75
76 /* Return true if OFFRNG is the constant zero. */
77 bool offset_zero () const
78 {
79 return offrng[0] == 0 && offrng[1] == 0;
80 }
81
82 /* Return true if OFFRNG is bounded to a subrange of offset values
83 valid for the largest possible object. */
84 bool offset_bounded () const;
85
86 /* Return the maximum amount of space remaining and if non-null, set
87 argument to the minimum. */
88 offset_int size_remaining (offset_int * = NULL) const;
89
90/* Return true if the offset and object size are in range for SIZE. */
91 bool offset_in_range (const offset_int &) const;
92
93 /* Return true if *THIS is an access to a declared object. */
94 bool ref_declared () const
95 {
96 return DECL_P (ref) && base0 && deref < 1;
97 }
98
99 /* Set the size range to the maximum. */
100 void set_max_size_range ()
101 {
102 sizrng[0] = 0;
103 sizrng[1] = wi::to_offset (max_object_size ());
104 }
105
106 /* Add OFF to the offset range. */
107 void add_offset (const offset_int &off)
108 {
109 add_offset (off, off);
110 }
111
112 /* Add the range [MIN, MAX] to the offset range. */
113 void add_offset (const offset_int &, const offset_int &);
114
115 /* Add the maximum representable offset to the offset range. */
116 void add_max_offset ()
117 {
118 offset_int maxoff = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node));
119 add_offset (-maxoff - 1, maxoff);
120 }
121
122 /* Issue an informational message describing the target of an access
123 with the given mode. */
124 void inform_access (access_mode) const;
125
126 /* Reference to the accessed object(s). */
127 tree ref;
128
129 /* Range of byte offsets into and sizes of the object(s). */
130 offset_int offrng[2];
131 offset_int sizrng[2];
132 /* The minimum and maximum offset computed. */
133 offset_int offmax[2];
134 /* Range of the bound of the access: denotes that the access
135 is at least BNDRNG[0] bytes but no more than BNDRNG[1].
136 For string functions the size of the actual access is
137 further constrained by the length of the string. */
138 offset_int bndrng[2];
139
140 /* Used to fold integer expressions when called from front ends. */
141 tree (*eval)(tree);
142 /* Positive when REF is dereferenced, negative when its address is
143 taken. */
144 int deref;
145 /* Set if trailing one-element arrays should be treated as flexible
146 array members. */
147 bool trail1special;
148 /* Set if valid offsets must start at zero (for declared and allocated
149 objects but not for others referenced by pointers). */
150 bool base0;
151 /* Set if REF refers to a function array parameter not declared
152 static. */
153 bool parmarray;
154};
155
156class range_query;
157
158/* Queries and caches compute_objsize results. */
159class pointer_query
160{
161 DISABLE_COPY_AND_ASSIGN (pointer_query);
162
163public:
164 /* Type of the two-level cache object defined by clients of the class
165 to have pointer SSA_NAMEs cached for speedy access. */
166 struct cache_type
167 {
168 /* 1-based indices into cache. */
169 vec<unsigned> indices;
170 /* The cache itself. */
171 vec<access_ref> access_refs;
172 };
173
174 /* Construct an object with the given Ranger instance and cache. */
175 explicit pointer_query (range_query * = NULL, cache_type * = NULL);
176
177 /* Retrieve the access_ref for a variable from cache if it's there. */
178 const access_ref* get_ref (tree, int = 1) const;
179
180 /* Retrieve the access_ref for a variable from cache or compute it. */
181 bool get_ref (tree, access_ref*, int = 1);
182
183 /* Add an access_ref for the SSA_NAME to the cache. */
184 void put_ref (tree, const access_ref&, int = 1);
185
186 /* Flush the cache. */
187 void flush_cache ();
188
189 /* A Ranger instance. May be null to use global ranges. */
190 range_query *rvals;
191 /* Cache of SSA_NAMEs. May be null to disable caching. */
192 cache_type *var_cache;
193
194 /* Cache performance counters. */
195 mutable unsigned hits;
196 mutable unsigned misses;
197 mutable unsigned failures;
198 mutable unsigned depth;
199 mutable unsigned max_depth;
200};
201
202/* Describes a pair of references used in an access by built-in
203 functions like memcpy. */
204struct access_data
205{
81d6cdd3
MS
206 /* Set the access to at most MAXWRITE and MAXREAD bytes, and
207 at least 1 when MINWRITE or MINREAD, respectively, is set. */
208 access_data (gimple *stmt, access_mode mode,
209 tree maxwrite = NULL_TREE, bool minwrite = false,
210 tree maxread = NULL_TREE, bool minread = false)
211 : stmt (stmt), call (),
212 dst (maxwrite, minwrite), src (maxread, minread), mode (mode) { }
213
2a837de2
MS
214 /* Set the access to at most MAXWRITE and MAXREAD bytes, and
215 at least 1 when MINWRITE or MINREAD, respectively, is set. */
216 access_data (tree expr, access_mode mode,
217 tree maxwrite = NULL_TREE, bool minwrite = false,
218 tree maxread = NULL_TREE, bool minread = false)
81d6cdd3 219 : stmt (), call (expr),
2a837de2
MS
220 dst (maxwrite, minwrite), src (maxread, minread), mode (mode) { }
221
81d6cdd3
MS
222 /* Access statement. */
223 gimple *stmt;
2a837de2
MS
224 /* Built-in function call. */
225 tree call;
226 /* Destination and source of the access. */
227 access_ref dst, src;
228 /* Read-only for functions like memcmp or strlen, write-only
229 for memset, read-write for memcpy or strcat. */
230 access_mode mode;
231};
232
b48d4e68
MS
233enum size_range_flags
234 {
235 /* Set to consider zero a valid range. */
236 SR_ALLOW_ZERO = 1,
237 /* Set to use the largest subrange of a set of ranges as opposed
238 to the smallest. */
239 SR_USE_LARGEST = 2
240 };
241extern bool get_size_range (tree, tree[2], int = 0);
242extern bool get_size_range (range_query *, tree, gimple *, tree[2], int = 0);
243
2a837de2
MS
244class range_query;
245extern tree gimple_call_alloc_size (gimple *, wide_int[2] = NULL,
246 range_query * = NULL);
247extern tree gimple_parm_array_size (tree, wide_int[2], bool * = NULL);
248
249extern tree compute_objsize (tree, int, access_ref *, range_query * = NULL);
250/* Legacy/transitional API. Should not be used in new code. */
251extern tree compute_objsize (tree, int, access_ref *, pointer_query *);
252extern tree compute_objsize (tree, int, tree * = NULL, tree * = NULL,
253 range_query * = NULL);
254
255#endif // GCC_POINTER_QUERY_H