]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/pointer-query.h
Move bndrng from access_ref to access_data.
[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{
9a27acc3 63 /* Set the bounds of the reference. */
f9379fcb 64 access_ref ();
2a837de2
MS
65
66 /* Return the PHI node REF refers to or null if it doesn't. */
67 gphi *phi () const;
68
69 /* Return the object to which REF refers. */
9a27acc3
MS
70 tree get_ref (vec<access_ref> *, access_ref * = nullptr, int = 1,
71 ssa_name_limit_t * = nullptr, pointer_query * = nullptr) const;
2a837de2
MS
72
73 /* Return true if OFFRNG is the constant zero. */
74 bool offset_zero () const
75 {
76 return offrng[0] == 0 && offrng[1] == 0;
77 }
78
79 /* Return true if OFFRNG is bounded to a subrange of offset values
80 valid for the largest possible object. */
81 bool offset_bounded () const;
82
83 /* Return the maximum amount of space remaining and if non-null, set
84 argument to the minimum. */
9a27acc3 85 offset_int size_remaining (offset_int * = nullptr) const;
2a837de2
MS
86
87/* Return true if the offset and object size are in range for SIZE. */
88 bool offset_in_range (const offset_int &) const;
89
90 /* Return true if *THIS is an access to a declared object. */
91 bool ref_declared () const
92 {
93 return DECL_P (ref) && base0 && deref < 1;
94 }
95
96 /* Set the size range to the maximum. */
97 void set_max_size_range ()
98 {
99 sizrng[0] = 0;
100 sizrng[1] = wi::to_offset (max_object_size ());
101 }
102
103 /* Add OFF to the offset range. */
104 void add_offset (const offset_int &off)
105 {
106 add_offset (off, off);
107 }
108
109 /* Add the range [MIN, MAX] to the offset range. */
110 void add_offset (const offset_int &, const offset_int &);
111
112 /* Add the maximum representable offset to the offset range. */
113 void add_max_offset ()
114 {
115 offset_int maxoff = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node));
116 add_offset (-maxoff - 1, maxoff);
117 }
118
119 /* Issue an informational message describing the target of an access
120 with the given mode. */
121 void inform_access (access_mode) const;
122
123 /* Reference to the accessed object(s). */
124 tree ref;
125
126 /* Range of byte offsets into and sizes of the object(s). */
127 offset_int offrng[2];
128 offset_int sizrng[2];
129 /* The minimum and maximum offset computed. */
130 offset_int offmax[2];
2a837de2
MS
131
132 /* Used to fold integer expressions when called from front ends. */
133 tree (*eval)(tree);
134 /* Positive when REF is dereferenced, negative when its address is
135 taken. */
136 int deref;
137 /* Set if trailing one-element arrays should be treated as flexible
138 array members. */
139 bool trail1special;
140 /* Set if valid offsets must start at zero (for declared and allocated
141 objects but not for others referenced by pointers). */
142 bool base0;
143 /* Set if REF refers to a function array parameter not declared
144 static. */
145 bool parmarray;
146};
147
148class range_query;
149
150/* Queries and caches compute_objsize results. */
151class pointer_query
152{
153 DISABLE_COPY_AND_ASSIGN (pointer_query);
154
155public:
156 /* Type of the two-level cache object defined by clients of the class
157 to have pointer SSA_NAMEs cached for speedy access. */
158 struct cache_type
159 {
160 /* 1-based indices into cache. */
161 vec<unsigned> indices;
162 /* The cache itself. */
163 vec<access_ref> access_refs;
164 };
165
166 /* Construct an object with the given Ranger instance and cache. */
9a27acc3 167 explicit pointer_query (range_query * = nullptr, cache_type * = nullptr);
2a837de2
MS
168
169 /* Retrieve the access_ref for a variable from cache if it's there. */
170 const access_ref* get_ref (tree, int = 1) const;
171
172 /* Retrieve the access_ref for a variable from cache or compute it. */
9a27acc3 173 bool get_ref (tree, gimple *, access_ref*, int = 1);
2a837de2
MS
174
175 /* Add an access_ref for the SSA_NAME to the cache. */
176 void put_ref (tree, const access_ref&, int = 1);
177
178 /* Flush the cache. */
179 void flush_cache ();
180
ece28da9
MS
181 /* Dump statistics and optionally cache contents to DUMP_FILE. */
182 void dump (FILE *, bool = false);
183
2a837de2
MS
184 /* A Ranger instance. May be null to use global ranges. */
185 range_query *rvals;
186 /* Cache of SSA_NAMEs. May be null to disable caching. */
187 cache_type *var_cache;
188
189 /* Cache performance counters. */
190 mutable unsigned hits;
191 mutable unsigned misses;
192 mutable unsigned failures;
193 mutable unsigned depth;
194 mutable unsigned max_depth;
195};
196
197/* Describes a pair of references used in an access by built-in
198 functions like memcpy. */
199struct access_data
200{
81d6cdd3
MS
201 /* Set the access to at most MAXWRITE and MAXREAD bytes, and
202 at least 1 when MINWRITE or MINREAD, respectively, is set. */
f9379fcb
MS
203 access_data (range_query *, gimple *, access_mode,
204 tree = NULL_TREE, bool = false,
205 tree = NULL_TREE, bool = false);
81d6cdd3 206
2a837de2
MS
207 /* Set the access to at most MAXWRITE and MAXREAD bytes, and
208 at least 1 when MINWRITE or MINREAD, respectively, is set. */
f9379fcb
MS
209 access_data (range_query *, tree, access_mode,
210 tree = NULL_TREE, bool = false,
211 tree = NULL_TREE, bool = false);
212
213 /* Constructor helper. */
214 static void set_bound (offset_int[2], tree, bool, range_query *, gimple *);
2a837de2 215
81d6cdd3
MS
216 /* Access statement. */
217 gimple *stmt;
2a837de2
MS
218 /* Built-in function call. */
219 tree call;
220 /* Destination and source of the access. */
221 access_ref dst, src;
f9379fcb
MS
222
223 /* Range of the bound of the access: denotes that the access is at
224 least XXX_BNDRNG[0] bytes but no more than XXX_BNDRNG[1]. For
225 string functions the size of the actual access is further
226 constrained by the length of the string. */
227 offset_int dst_bndrng[2];
228 offset_int src_bndrng[2];
229
2a837de2
MS
230 /* Read-only for functions like memcmp or strlen, write-only
231 for memset, read-write for memcpy or strcat. */
232 access_mode mode;
233};
234
b48d4e68
MS
235enum size_range_flags
236 {
237 /* Set to consider zero a valid range. */
238 SR_ALLOW_ZERO = 1,
239 /* Set to use the largest subrange of a set of ranges as opposed
240 to the smallest. */
241 SR_USE_LARGEST = 2
242 };
243extern bool get_size_range (tree, tree[2], int = 0);
244extern bool get_size_range (range_query *, tree, gimple *, tree[2], int = 0);
245
2a837de2 246class range_query;
9a27acc3
MS
247extern tree gimple_call_alloc_size (gimple *, wide_int[2] = nullptr,
248 range_query * = nullptr);
249
250/* Compute the size of an object referenced by the first argument in
251 a statement given by second argument, using Object Size Type given
252 by third argument. Store result in an access_ref. */
253extern tree compute_objsize (tree, gimple *, int, access_ref *,
254 range_query * = nullptr);
255extern tree compute_objsize (tree, gimple *, int, access_ref *,
256 pointer_query *);
257inline tree compute_objsize (tree ptr, int ostype, access_ref *pref)
258{
259 return compute_objsize (ptr, nullptr, ostype, pref, (range_query *)nullptr);
260}
2a837de2 261
2a837de2 262/* Legacy/transitional API. Should not be used in new code. */
9a27acc3
MS
263extern tree compute_objsize (tree, int, tree * = nullptr, tree * = nullptr,
264 range_query * = nullptr);
2a837de2 265
1ff4dbdd
MS
266/* Return the field at the constant offset. */
267extern tree field_at_offset (tree, tree, HOST_WIDE_INT,
268 HOST_WIDE_INT * = nullptr,
269 HOST_WIDE_INT * = nullptr);
270/* Return the array at the constant offset. */
271extern tree array_elt_at_offset (tree, HOST_WIDE_INT,
272 HOST_WIDE_INT * = nullptr,
273 HOST_WIDE_INT * = nullptr);
274
ea9e0d6c
MS
275/* Helper to build an array type that can be printed. */
276extern tree build_printable_array_type (tree, unsigned HOST_WIDE_INT);
277
2a837de2 278#endif // GCC_POINTER_QUERY_H