Branch data Line data Source code
1 : : /* Interprocedural analyses.
2 : : Copyright (C) 2005-2024 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
6 : : GCC is free software; you can redistribute it and/or modify it under
7 : : the terms of the GNU General Public License as published by the Free
8 : : Software Foundation; either version 3, or (at your option) any later
9 : : version.
10 : :
11 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : : for more details.
15 : :
16 : : You should have received a copy of the GNU General Public License
17 : : along with GCC; see the file COPYING3. If not see
18 : : <http://www.gnu.org/licenses/>. */
19 : :
20 : : #ifndef IPA_PROP_H
21 : : #define IPA_PROP_H
22 : :
23 : : /* The following definitions and interfaces are used by
24 : : interprocedural analyses or parameters. */
25 : :
26 : : #define IPA_UNDESCRIBED_USE -1
27 : :
28 : : /* Index identifying an actualargument or a formal parameter may have only this
29 : : many bits. */
30 : :
31 : : #define IPA_PROP_ARG_INDEX_LIMIT_BITS 16
32 : :
33 : : /* ipa-prop.cc stuff (ipa-cp, indirect inlining): */
34 : :
35 : : /* A jump function for a callsite represents the values passed as actual
36 : : arguments of the callsite. They were originally proposed in a paper called
37 : : "Interprocedural Constant Propagation", by David Callahan, Keith D Cooper,
38 : : Ken Kennedy, Linda Torczon in Comp86, pg 152-161. There are three main
39 : : types of values :
40 : :
41 : : Pass-through - the caller's formal parameter is passed as an actual
42 : : argument, possibly one simple operation performed on it.
43 : : Constant - a constant (is_gimple_ip_invariant)is passed as an actual
44 : : argument.
45 : : Unknown - neither of the above.
46 : :
47 : : IPA_JF_LOAD_AGG is a compound pass-through jump function, in which primary
48 : : operation on formal parameter is memory dereference that loads a value from
49 : : a part of an aggregate, which is represented or pointed to by the formal
50 : : parameter. Moreover, an additional unary/binary operation can be applied on
51 : : the loaded value, and final result is passed as actual argument of callee
52 : : (e.g. *(param_1(D) + 4) op 24 ). It is meant to describe usage of aggregate
53 : : parameter or by-reference parameter referenced in argument passing, commonly
54 : : found in C++ and Fortran.
55 : :
56 : : IPA_JF_ANCESTOR is a special pass-through jump function, which means that
57 : : the result is an address of a part of the object pointed to by the formal
58 : : parameter to which the function refers. It is mainly intended to represent
59 : : getting addresses of ancestor fields in C++
60 : : (e.g. &this_1(D)->D.1766.D.1756). Note that if the original pointer is
61 : : NULL, ancestor jump function must behave like a simple pass-through.
62 : :
63 : : Other pass-through functions can either simply pass on an unchanged formal
64 : : parameter or can apply one simple binary operation to it (such jump
65 : : functions are called polynomial).
66 : :
67 : : Jump functions are computed in ipa-prop.cc by function
68 : : update_call_notes_after_inlining. Some information can be lost and jump
69 : : functions degraded accordingly when inlining, see
70 : : update_call_notes_after_inlining in the same file. */
71 : :
72 : : enum jump_func_type
73 : : {
74 : : IPA_JF_UNKNOWN = 0, /* newly allocated and zeroed jump functions default */
75 : : IPA_JF_CONST, /* represented by field costant */
76 : : IPA_JF_PASS_THROUGH, /* represented by field pass_through */
77 : : IPA_JF_LOAD_AGG, /* represented by field load_agg */
78 : : IPA_JF_ANCESTOR /* represented by field ancestor */
79 : : };
80 : :
81 : : struct ipa_cst_ref_desc;
82 : :
83 : : /* Structure holding data required to describe a constant jump function. */
84 : : struct GTY(()) ipa_constant_data
85 : : {
86 : : /* The value of the constant. */
87 : : tree value;
88 : : /* Pointer to the structure that describes the reference. */
89 : : struct ipa_cst_ref_desc GTY((skip)) *rdesc;
90 : : };
91 : :
92 : : /* Structure holding data required to describe a pass-through jump function. */
93 : :
94 : : struct GTY(()) ipa_pass_through_data
95 : : {
96 : : /* If an operation is to be performed on the original parameter, this is the
97 : : second (constant) operand. */
98 : : tree operand;
99 : : /* Number of the caller's formal parameter being passed. */
100 : : int formal_id;
101 : : /* Operation that is performed on the argument before it is passed on.
102 : : Special values which have other meaning than in normal contexts:
103 : : - NOP_EXPR means no operation, not even type conversion.
104 : : - ASSERT_EXPR means that only the value in operand is allowed to pass
105 : : through (without any change), for all other values the result is
106 : : unknown.
107 : : Otherwise operation must be a simple binary or unary arithmetic operation
108 : : where the caller's parameter is the first operand and (for binary
109 : : operations) the operand field from this structure is the second one. */
110 : : enum tree_code operation;
111 : : /* When the passed value is a pointer, it is set to true only when we are
112 : : certain that no write to the object it points to has occurred since the
113 : : caller functions started execution, except for changes noted in the
114 : : aggregate part of the jump function (see description of
115 : : ipa_agg_jump_function). The flag is used only when the operation is
116 : : NOP_EXPR. */
117 : : unsigned agg_preserved : 1;
118 : : /* Set when the edge has already been used to decrement an appropriate
119 : : reference description counter and should not be decremented again. */
120 : : unsigned refdesc_decremented : 1;
121 : : };
122 : :
123 : : /* Structure holding data required to describe a load-value-from-aggregate
124 : : jump function. */
125 : :
126 : : struct GTY(()) ipa_load_agg_data
127 : : {
128 : : /* Inherit from pass through jump function, describing unary/binary
129 : : operation on the value loaded from aggregate that is represented or
130 : : pointed to by the formal parameter, specified by formal_id in this
131 : : pass_through jump function data structure. */
132 : : struct ipa_pass_through_data pass_through;
133 : : /* Type of the value loaded from the aggregate. */
134 : : tree type;
135 : : /* Offset at which the value is located within the aggregate. */
136 : : HOST_WIDE_INT offset;
137 : : /* True if loaded by reference (the aggregate is pointed to by the formal
138 : : parameter) or false if loaded by value (the aggregate is represented
139 : : by the formal parameter). */
140 : : bool by_ref;
141 : : };
142 : :
143 : : /* Structure holding data required to describe an ancestor pass-through
144 : : jump function. */
145 : :
146 : : struct GTY(()) ipa_ancestor_jf_data
147 : : {
148 : : /* Offset of the field representing the ancestor. */
149 : : HOST_WIDE_INT offset;
150 : : /* Number of the caller's formal parameter being passed. */
151 : : int formal_id;
152 : : /* Flag with the same meaning like agg_preserve in ipa_pass_through_data. */
153 : : unsigned agg_preserved : 1;
154 : : /* When set, the operation should not have any effect on NULL pointers. */
155 : : unsigned keep_null : 1;
156 : : };
157 : :
158 : : /* A jump function for an aggregate part at a given offset, which describes how
159 : : it content value is generated. All unlisted positions are assumed to have a
160 : : value defined in an unknown way. */
161 : :
162 : : struct GTY(()) ipa_agg_jf_item
163 : : {
164 : : /* The offset for the aggregate part. */
165 : : HOST_WIDE_INT offset;
166 : :
167 : : /* Data type of the aggregate part. */
168 : : tree type;
169 : :
170 : : /* Jump function type. */
171 : : enum jump_func_type jftype;
172 : :
173 : : /* Represents a value of jump function. constant represents the actual constant
174 : : in constant jump function content. pass_through is used only in simple pass
175 : : through jump function context. load_agg is for load-value-from-aggregate
176 : : jump function context. */
177 : : union jump_func_agg_value
178 : : {
179 : : tree GTY ((tag ("IPA_JF_CONST"))) constant;
180 : : struct ipa_pass_through_data GTY ((tag ("IPA_JF_PASS_THROUGH"))) pass_through;
181 : : struct ipa_load_agg_data GTY ((tag ("IPA_JF_LOAD_AGG"))) load_agg;
182 : : } GTY ((desc ("%1.jftype"))) value;
183 : : };
184 : :
185 : : /* Jump functions describing a set of aggregate contents. */
186 : :
187 : : struct GTY(()) ipa_agg_jump_function
188 : : {
189 : : /* Description of the individual jump function item. */
190 : : vec<ipa_agg_jf_item, va_gc> *items;
191 : : /* True if the data was passed by reference (as opposed to by value). */
192 : : bool by_ref;
193 : : };
194 : :
195 : : class ipcp_transformation;
196 : : class ipa_auto_call_arg_values;
197 : : class ipa_call_arg_values;
198 : :
199 : : /* Element of a vector describing aggregate values for a number of arguments in
200 : : a particular context, be it a call or the aggregate constants that a node is
201 : : specialized for. */
202 : :
203 : : struct GTY(()) ipa_argagg_value
204 : : {
205 : : /* The constant value. In the contexts where the list of known values is
206 : : being pruned, NULL means a variable value. */
207 : : tree value;
208 : : /* Unit offset within the aggregate. */
209 : : unsigned unit_offset;
210 : : /* Index of the parameter, as it was in the original function (i.e. needs
211 : : remapping after parameter modification is carried out as part of clone
212 : : materialization). */
213 : : unsigned index : IPA_PROP_ARG_INDEX_LIMIT_BITS;
214 : : /* Whether the value was passed by reference. */
215 : : unsigned by_ref : 1;
216 : : /* Set if the value should not be used after materialization in
217 : : value_numbering. It is kept around just so that clone materialization can
218 : : distinguish a combined IPA-CP and IPA-SRA from a deleted argument. */
219 : : unsigned killed : 1;
220 : : };
221 : :
222 : : /* A view into a sorted list of aggregate values in a particular context, be it
223 : : a call or the aggregate constants that a node is specialized for. The
224 : : actual data is stored in the vector this has been constructed from. */
225 : :
226 : : class ipa_argagg_value_list
227 : : {
228 : : public:
229 : : ipa_argagg_value_list () = delete;
230 : 1996 : ipa_argagg_value_list (const vec<ipa_argagg_value, va_gc> *values)
231 : 3935 : : m_elts (values)
232 : : {}
233 : 3331 : ipa_argagg_value_list (const vec<ipa_argagg_value> *values)
234 : 6662 : : m_elts (*values)
235 : : {}
236 : : ipa_argagg_value_list (const ipa_auto_call_arg_values *aavals);
237 : : ipa_argagg_value_list (const ipa_call_arg_values *gavals);
238 : : ipa_argagg_value_list (const ipcp_transformation *tinfo);
239 : :
240 : : /* Return the aggregate constant stored for INDEX at UNIT_OFFSET, if it is
241 : : passed by reference or not according to BY_REF, or NULL_TREE
242 : : otherwise. */
243 : :
244 : : tree get_value (int index, unsigned unit_offset, bool by_ref) const;
245 : :
246 : : /* Return the aggregate constant stored for INDEX at UNIT_OFFSET, not
247 : : performing any check of whether value is passed by reference. Return
248 : : NULL_TREE if there is no such constant. */
249 : :
250 : : tree get_value (int index, unsigned unit_offset) const;
251 : :
252 : : /* Return the item describing a constant stored for INDEX at UNIT_OFFSET or
253 : : NULL if there is no such constant. */
254 : :
255 : : const ipa_argagg_value *get_elt (int index, unsigned unit_offset) const;
256 : :
257 : :
258 : : /* Return the first item describing a constant stored for parameter with
259 : : INDEX, regardless of offset or reference, or NULL if there is no such
260 : : constant. */
261 : :
262 : : const ipa_argagg_value *get_elt_for_index (int index) const;
263 : :
264 : : /* Return true if there is an aggregate constant referring to a value passed
265 : : in or by parameter with INDEX (at any offset, whether by reference or
266 : : not). */
267 : :
268 : 119647 : bool value_for_index_p (int index) const
269 : : {
270 : 119647 : return !!get_elt_for_index (index);
271 : : }
272 : :
273 : : /* Return true if all elements present in OTHER are also present in this
274 : : list. */
275 : :
276 : : bool superset_of_p (const ipa_argagg_value_list &other) const;
277 : :
278 : : /* Push all items in this list that describe parameter SRC_INDEX into RES as
279 : : ones describing DST_INDEX while subtracting UNIT_DELTA from their unit
280 : : offsets but skip those which would end up with a negative offset. */
281 : :
282 : : void push_adjusted_values (unsigned src_index, unsigned dest_index,
283 : : unsigned unit_delta,
284 : : vec<ipa_argagg_value> *res) const;
285 : :
286 : : /* Dump aggregate constants to FILE. */
287 : :
288 : : void dump (FILE *f);
289 : :
290 : : /* Dump aggregate constants to stderr. */
291 : :
292 : : void DEBUG_FUNCTION debug ();
293 : :
294 : : /* Array slice pointing to the actual storage. */
295 : :
296 : : array_slice<const ipa_argagg_value> m_elts;
297 : : };
298 : :
299 : : /* Info about value ranges. */
300 : :
301 : : class GTY(()) ipa_vr
302 : : {
303 : : public:
304 : : ipa_vr ();
305 : : ipa_vr (const vrange &);
306 : : void set_unknown ();
307 : 7159072 : bool known_p () const { return m_storage != NULL; }
308 : 6686228 : tree type () const { return m_type; }
309 : : void get_vrange (value_range &) const;
310 : : bool equal_p (const vrange &) const;
311 : : bool equal_p (const ipa_vr &) const;
312 : : const vrange_storage *storage () const { return m_storage; }
313 : : void streamer_read (lto_input_block *, class data_in *);
314 : : void streamer_write (output_block *) const;
315 : : void dump (FILE *) const;
316 : :
317 : : private:
318 : : friend void gt_pch_nx (struct ipa_vr &);
319 : : friend void gt_ggc_mx (struct ipa_vr &);
320 : : friend void gt_pch_nx (struct ipa_vr *, gt_pointer_operator, void *);
321 : : friend void gt_ggc_mx_ipa_vr (void *);
322 : : friend void gt_pch_nx_ipa_vr (void*);
323 : : friend void gt_pch_p_6ipa_vr(void*, void*, gt_pointer_operator, void*);
324 : :
325 : : vrange_storage *m_storage;
326 : : tree m_type;
327 : : };
328 : :
329 : : /* A jump function for a callsite represents the values passed as actual
330 : : arguments of the callsite. See enum jump_func_type for the various
331 : : types of jump functions supported. */
332 : : struct GTY (()) ipa_jump_func
333 : : {
334 : : /* Aggregate jump function description. See struct ipa_agg_jump_function
335 : : and its description. */
336 : : struct ipa_agg_jump_function agg;
337 : :
338 : : /* Information about value range, containing valid data only when vr_known is
339 : : true. The pointed to structure is shared betweed different jump
340 : : functions. Use ipa_set_jfunc_vr to set this field. */
341 : : ipa_vr *m_vr;
342 : :
343 : : enum jump_func_type type;
344 : : /* Represents a value of a jump function. pass_through is used only in jump
345 : : function context. constant represents the actual constant in constant jump
346 : : functions and member_cst holds constant c++ member functions. */
347 : : union jump_func_value
348 : : {
349 : : struct ipa_constant_data GTY ((tag ("IPA_JF_CONST"))) constant;
350 : : struct ipa_pass_through_data GTY ((tag ("IPA_JF_PASS_THROUGH"))) pass_through;
351 : : struct ipa_ancestor_jf_data GTY ((tag ("IPA_JF_ANCESTOR"))) ancestor;
352 : : } GTY ((desc ("%1.type"))) value;
353 : : };
354 : :
355 : :
356 : : /* Return the constant stored in a constant jump functin JFUNC. */
357 : :
358 : : inline tree
359 : 4386704 : ipa_get_jf_constant (struct ipa_jump_func *jfunc)
360 : : {
361 : 4386704 : gcc_checking_assert (jfunc->type == IPA_JF_CONST);
362 : 4386704 : return jfunc->value.constant.value;
363 : : }
364 : :
365 : : inline struct ipa_cst_ref_desc *
366 : 1351717 : ipa_get_jf_constant_rdesc (struct ipa_jump_func *jfunc)
367 : : {
368 : 1351717 : gcc_checking_assert (jfunc->type == IPA_JF_CONST);
369 : 1351717 : return jfunc->value.constant.rdesc;
370 : : }
371 : :
372 : : /* Make JFUNC not participate in any further reference counting. */
373 : :
374 : : inline void
375 : 352 : ipa_zap_jf_refdesc (ipa_jump_func *jfunc)
376 : : {
377 : 352 : gcc_checking_assert (jfunc->type == IPA_JF_CONST);
378 : 352 : jfunc->value.constant.rdesc = NULL;
379 : 352 : }
380 : :
381 : : /* Return the operand of a pass through jmp function JFUNC. */
382 : :
383 : : inline tree
384 : 86437 : ipa_get_jf_pass_through_operand (struct ipa_jump_func *jfunc)
385 : : {
386 : 86437 : gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
387 : 86437 : return jfunc->value.pass_through.operand;
388 : : }
389 : :
390 : : /* Return the number of the caller's formal parameter that a pass through jump
391 : : function JFUNC refers to. */
392 : :
393 : : inline int
394 : 5312830 : ipa_get_jf_pass_through_formal_id (struct ipa_jump_func *jfunc)
395 : : {
396 : 5312830 : gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
397 : 5312830 : return jfunc->value.pass_through.formal_id;
398 : : }
399 : :
400 : : /* Return operation of a pass through jump function JFUNC. */
401 : :
402 : : inline enum tree_code
403 : 2065983 : ipa_get_jf_pass_through_operation (struct ipa_jump_func *jfunc)
404 : : {
405 : 2065983 : gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
406 : 2065983 : return jfunc->value.pass_through.operation;
407 : : }
408 : :
409 : : /* Return the agg_preserved flag of a pass through jump function JFUNC. */
410 : :
411 : : inline bool
412 : 1934358 : ipa_get_jf_pass_through_agg_preserved (struct ipa_jump_func *jfunc)
413 : : {
414 : 1934358 : gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
415 : 1934358 : return jfunc->value.pass_through.agg_preserved;
416 : : }
417 : :
418 : : /* Return the refdesc_decremented flag of a pass through jump function
419 : : JFUNC. */
420 : :
421 : : inline bool
422 : 381404 : ipa_get_jf_pass_through_refdesc_decremented (struct ipa_jump_func *jfunc)
423 : : {
424 : 381404 : gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
425 : 381404 : return jfunc->value.pass_through.refdesc_decremented;
426 : : }
427 : :
428 : : /* Set the refdesc_decremented flag of a pass through jump function JFUNC to
429 : : VALUE. */
430 : :
431 : : inline void
432 : 16 : ipa_set_jf_pass_through_refdesc_decremented (ipa_jump_func *jfunc, bool value)
433 : : {
434 : 16 : gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
435 : 16 : jfunc->value.pass_through.refdesc_decremented = value;
436 : 16 : }
437 : :
438 : : /* Return true if pass through jump function JFUNC preserves type
439 : : information. */
440 : :
441 : : inline bool
442 : 240617 : ipa_get_jf_pass_through_type_preserved (struct ipa_jump_func *jfunc)
443 : : {
444 : 240617 : gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
445 : 240617 : return jfunc->value.pass_through.agg_preserved;
446 : : }
447 : :
448 : : /* Return the offset of an ancestor jump function JFUNC. */
449 : :
450 : : inline HOST_WIDE_INT
451 : 194670 : ipa_get_jf_ancestor_offset (struct ipa_jump_func *jfunc)
452 : : {
453 : 194670 : gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
454 : 194670 : return jfunc->value.ancestor.offset;
455 : : }
456 : :
457 : : /* Return the number of the caller's formal parameter that an ancestor jump
458 : : function JFUNC refers to. */
459 : :
460 : : inline int
461 : 948977 : ipa_get_jf_ancestor_formal_id (struct ipa_jump_func *jfunc)
462 : : {
463 : 948977 : gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
464 : 948977 : return jfunc->value.ancestor.formal_id;
465 : : }
466 : :
467 : : /* Return the agg_preserved flag of an ancestor jump function JFUNC. */
468 : :
469 : : inline bool
470 : 229331 : ipa_get_jf_ancestor_agg_preserved (struct ipa_jump_func *jfunc)
471 : : {
472 : 229331 : gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
473 : 229331 : return jfunc->value.ancestor.agg_preserved;
474 : : }
475 : :
476 : : /* Return true if ancestor jump function JFUNC presrves type information. */
477 : :
478 : : inline bool
479 : 46541 : ipa_get_jf_ancestor_type_preserved (struct ipa_jump_func *jfunc)
480 : : {
481 : 46541 : gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
482 : 46541 : return jfunc->value.ancestor.agg_preserved;
483 : : }
484 : :
485 : : /* Return if jfunc represents an operation whether we first check the formal
486 : : parameter for non-NULLness unless it does not matter because the offset is
487 : : zero anyway. */
488 : :
489 : : inline bool
490 : 20838 : ipa_get_jf_ancestor_keep_null (struct ipa_jump_func *jfunc)
491 : : {
492 : 20838 : gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
493 : 20838 : return jfunc->value.ancestor.keep_null;
494 : : }
495 : :
496 : : /* Class for allocating a bundle of various potentially known properties about
497 : : actual arguments of a particular call on stack for the usual case and on
498 : : heap only if there are unusually many arguments. The data is deallocated
499 : : when the instance of this class goes out of scope or is otherwise
500 : : destructed. */
501 : :
502 : 19989219 : class ipa_auto_call_arg_values
503 : : {
504 : : public:
505 : : /* If m_known_vals (vector of known "scalar" values) is sufficiantly long,
506 : : return its element at INDEX, otherwise return NULL. */
507 : 44153060 : tree safe_sval_at (int index)
508 : : {
509 : 44153060 : if ((unsigned) index < m_known_vals.length ())
510 : 27269429 : return m_known_vals[index];
511 : : return NULL;
512 : : }
513 : :
514 : : /* Vector describing known values of parameters. */
515 : : auto_vec<tree, 32> m_known_vals;
516 : :
517 : : /* Vector describing known polymorphic call contexts. */
518 : : auto_vec<ipa_polymorphic_call_context, 32> m_known_contexts;
519 : :
520 : : /* Vector describing known aggregate values. */
521 : : auto_vec<ipa_argagg_value, 32> m_known_aggs;
522 : :
523 : : /* Vector describing known value ranges of arguments. */
524 : : auto_vec<value_range, 32> m_known_value_ranges;
525 : : };
526 : :
527 : : inline
528 : 21080387 : ipa_argagg_value_list
529 : 21080387 : ::ipa_argagg_value_list (const ipa_auto_call_arg_values *aavals)
530 : 42160774 : : m_elts (aavals->m_known_aggs)
531 : : {}
532 : :
533 : : /* Class bundling the various potentially known properties about actual
534 : : arguments of a particular call. This variant does not deallocate the
535 : : bundled data in any way as the vectors can either be pointing to vectors in
536 : : ipa_auto_call_arg_values or be allocated independently. */
537 : :
538 : : class ipa_call_arg_values
539 : : {
540 : : public:
541 : : /* Default constructor, setting the vectors to empty ones. */
542 : 1010853 : ipa_call_arg_values ()
543 : 0 : {}
544 : :
545 : : /* Construct this general variant of the bundle from the variant which uses
546 : : auto_vecs to hold the vectors. This means that vectors of objects
547 : : constructed with this constructor should not be changed because if they
548 : : get reallocated, the member vectors and the underlying auto_vecs would get
549 : : out of sync. */
550 : 16116957 : ipa_call_arg_values (ipa_auto_call_arg_values *aavals)
551 : 16116957 : : m_known_vals (aavals->m_known_vals.to_vec_legacy ()),
552 : 16116957 : m_known_contexts (aavals->m_known_contexts.to_vec_legacy ()),
553 : 16116957 : m_known_aggs (aavals->m_known_aggs.to_vec_legacy ()),
554 : 16116957 : m_known_value_ranges (aavals->m_known_value_ranges.to_vec_legacy ())
555 : : {}
556 : :
557 : : /* If m_known_vals (vector of known "scalar" values) is sufficiantly long,
558 : : return its element at INDEX, otherwise return NULL. */
559 : 138631 : tree safe_sval_at (int index)
560 : : {
561 : 138631 : if ((unsigned) index < m_known_vals.length ())
562 : 91684 : return m_known_vals[index];
563 : : return NULL;
564 : : }
565 : :
566 : : /* Vector describing known values of parameters. */
567 : : vec<tree> m_known_vals = vNULL;
568 : :
569 : : /* Vector describing known polymorphic call contexts. */
570 : : vec<ipa_polymorphic_call_context> m_known_contexts = vNULL;
571 : :
572 : : /* Vector describing known aggregate values. */
573 : : vec<ipa_argagg_value> m_known_aggs = vNULL;
574 : :
575 : : /* Vector describing known value ranges of arguments. */
576 : : vec<value_range> m_known_value_ranges = vNULL;
577 : : };
578 : :
579 : : inline
580 : 2201872 : ipa_argagg_value_list
581 : 2201872 : ::ipa_argagg_value_list (const ipa_call_arg_values *gavals)
582 : 2779742 : : m_elts (gavals->m_known_aggs)
583 : : {}
584 : :
585 : : /* Summary describing a single formal parameter. */
586 : :
587 : : struct GTY(()) ipa_param_descriptor
588 : : {
589 : : /* In analysis and modification phase, this is the PARAM_DECL of this
590 : : parameter, in IPA LTO phase, this is the type of the described
591 : : parameter or NULL if not known. Do not read this field directly but
592 : : through ipa_get_param and ipa_get_type as appropriate. */
593 : : tree decl_or_type;
594 : : /* If all uses of the parameter are described by ipa-prop structures, this
595 : : says how many there are. If any use could not be described by means of
596 : : ipa-prop structures (which include flag dereferenced below), this is
597 : : IPA_UNDESCRIBED_USE. */
598 : : int controlled_uses;
599 : : unsigned int move_cost : 27;
600 : : /* The parameter is used. */
601 : : unsigned used : 1;
602 : : unsigned used_by_ipa_predicates : 1;
603 : : unsigned used_by_indirect_call : 1;
604 : : unsigned used_by_polymorphic_call : 1;
605 : : /* Set to true when in addition to being used in call statements, the
606 : : parameter has also been used for loads (but not for writes, does not
607 : : escape, etc.). This allows us to identify parameters p which are only
608 : : used as *p, and so when we propagate a constant to them, we can generate a
609 : : LOAD and not ADDR reference to them. */
610 : : unsigned load_dereferenced : 1;
611 : : };
612 : :
613 : : /* ipa_node_params stores information related to formal parameters of functions
614 : : and some other information for interprocedural passes that operate on
615 : : parameters (such as ipa-cp). */
616 : :
617 : : class GTY((for_user)) ipa_node_params
618 : : {
619 : : public:
620 : : /* Default constructor. */
621 : : ipa_node_params ();
622 : :
623 : : /* Default destructor. */
624 : : ~ipa_node_params ();
625 : :
626 : : /* Information about individual formal parameters that are gathered when
627 : : summaries are generated. */
628 : : vec<ipa_param_descriptor, va_gc> *descriptors;
629 : : /* Pointer to an array of structures describing individual formal
630 : : parameters. */
631 : : vec<ipcp_param_lattices> GTY((skip)) lattices;
632 : : /* Only for versioned nodes this field would not be NULL,
633 : : it points to the node that IPA cp cloned from. */
634 : : struct cgraph_node * GTY((skip)) ipcp_orig_node;
635 : : /* If this node is an ipa-cp clone, these are the known constants that
636 : : describe what it has been specialized for. */
637 : : vec<tree> GTY((skip)) known_csts;
638 : : /* If this node is an ipa-cp clone, these are the known polymorphic contexts
639 : : that describe what it has been specialized for. */
640 : : vec<ipa_polymorphic_call_context> GTY((skip)) known_contexts;
641 : : /* Whether the param uses analysis and jump function computation has already
642 : : been performed. */
643 : : unsigned analysis_done : 1;
644 : : /* Whether the function is enqueued in ipa-cp propagation stack. */
645 : : unsigned node_enqueued : 1;
646 : : /* Whether we should create a specialized version based on values that are
647 : : known to be constant in all contexts. */
648 : : unsigned do_clone_for_all_contexts : 1;
649 : : /* Set if this is an IPA-CP clone for all contexts. */
650 : : unsigned is_all_contexts_clone : 1;
651 : : /* Node has been completely replaced by clones and will be removed after
652 : : ipa-cp is finished. */
653 : : unsigned node_dead : 1;
654 : : /* Node is involved in a recursion, potentionally indirect. */
655 : : unsigned node_within_scc : 1;
656 : : /* Node contains only direct recursion. */
657 : : unsigned node_is_self_scc : 1;
658 : : /* Node is calling a private function called only once. */
659 : : unsigned node_calling_single_call : 1;
660 : : /* False when there is something makes versioning impossible. */
661 : : unsigned versionable : 1;
662 : : };
663 : :
664 : : inline
665 : 6623906 : ipa_node_params::ipa_node_params ()
666 : 6623906 : : descriptors (NULL), lattices (vNULL), ipcp_orig_node (NULL),
667 : 6623906 : known_csts (vNULL), known_contexts (vNULL), analysis_done (0),
668 : 6623906 : node_enqueued (0), do_clone_for_all_contexts (0), is_all_contexts_clone (0),
669 : 6623906 : node_dead (0), node_within_scc (0), node_is_self_scc (0),
670 : 6623906 : node_calling_single_call (0), versionable (0)
671 : : {
672 : : }
673 : :
674 : : inline
675 : 6623905 : ipa_node_params::~ipa_node_params ()
676 : : {
677 : 6623905 : vec_free (descriptors);
678 : 6623905 : lattices.release ();
679 : 6623905 : known_csts.release ();
680 : 6623905 : known_contexts.release ();
681 : 6623905 : }
682 : :
683 : : /* Intermediate information that we get from alias analysis about a particular
684 : : parameter in a particular basic_block. When a parameter or the memory it
685 : : references is marked modified, we use that information in all dominated
686 : : blocks without consulting alias analysis oracle. */
687 : :
688 : : struct ipa_param_aa_status
689 : : {
690 : : /* Set when this structure contains meaningful information. If not, the
691 : : structure describing a dominating BB should be used instead. */
692 : : bool valid;
693 : :
694 : : /* Whether we have seen something which might have modified the data in
695 : : question. PARM is for the parameter itself, REF is for data it points to
696 : : but using the alias type of individual accesses and PT is the same thing
697 : : but for computing aggregate pass-through functions using a very inclusive
698 : : ao_ref. */
699 : : bool parm_modified, ref_modified, pt_modified;
700 : : };
701 : :
702 : : /* Information related to a given BB that used only when looking at function
703 : : body. */
704 : :
705 : : struct ipa_bb_info
706 : : {
707 : : /* Call graph edges going out of this BB. */
708 : : vec<cgraph_edge *> cg_edges;
709 : : /* Alias analysis statuses of each formal parameter at this bb. */
710 : : vec<ipa_param_aa_status> param_aa_statuses;
711 : : };
712 : :
713 : : /* Structure with global information that is only used when looking at function
714 : : body. */
715 : :
716 : : struct ipa_func_body_info
717 : : {
718 : : /* The node that is being analyzed. */
719 : : cgraph_node *node;
720 : :
721 : : /* Its info. */
722 : : class ipa_node_params *info;
723 : :
724 : : /* Information about individual BBs. */
725 : : vec<ipa_bb_info> bb_infos;
726 : :
727 : : /* Number of parameters. */
728 : : int param_count;
729 : :
730 : : /* Number of statements we are still allowed to walked by when analyzing this
731 : : function. */
732 : : unsigned int aa_walk_budget;
733 : : };
734 : :
735 : : /* ipa_node_params access functions. Please use these to access fields that
736 : : are or will be shared among various passes. */
737 : :
738 : : /* Return the number of formal parameters. */
739 : :
740 : : inline int
741 : 69750694 : ipa_get_param_count (class ipa_node_params *info)
742 : : {
743 : 134336698 : return vec_safe_length (info->descriptors);
744 : : }
745 : :
746 : : /* Return the parameter declaration in DESCRIPTORS at index I and assert it is
747 : : indeed a PARM_DECL. */
748 : :
749 : : inline tree
750 : 2300751 : ipa_get_param (const vec<ipa_param_descriptor, va_gc> &descriptors, int i)
751 : : {
752 : 2300751 : tree t = descriptors[i].decl_or_type;
753 : 2300751 : gcc_checking_assert (TREE_CODE (t) == PARM_DECL);
754 : 2300751 : return t;
755 : : }
756 : :
757 : : /* Return the declaration of Ith formal parameter of the function corresponding
758 : : to INFO. Note there is no setter function as this array is built just once
759 : : using ipa_initialize_node_params. This function should not be called in
760 : : WPA. */
761 : :
762 : : inline tree
763 : 2300751 : ipa_get_param (class ipa_node_params *info, int i)
764 : : {
765 : 2300751 : gcc_checking_assert (info->descriptors);
766 : 2300751 : return ipa_get_param (*info->descriptors, i);
767 : : }
768 : :
769 : : /* Return the type of Ith formal parameter of the function corresponding
770 : : to INFO if it is known or NULL if not. */
771 : :
772 : : inline tree
773 : 21018840 : ipa_get_type (class ipa_node_params *info, int i)
774 : : {
775 : 21018840 : if (vec_safe_length (info->descriptors) <= (unsigned) i)
776 : : return NULL;
777 : 20782293 : tree t = (*info->descriptors)[i].decl_or_type;
778 : 20782293 : if (!t)
779 : : return NULL;
780 : 20782293 : if (TYPE_P (t))
781 : : return t;
782 : 19439672 : gcc_checking_assert (TREE_CODE (t) == PARM_DECL);
783 : 19439672 : return TREE_TYPE (t);
784 : : }
785 : :
786 : : /* Return the move cost of Ith formal parameter of the function corresponding
787 : : to INFO. */
788 : :
789 : : inline int
790 : 296774 : ipa_get_param_move_cost (class ipa_node_params *info, int i)
791 : : {
792 : 296774 : gcc_checking_assert (info->descriptors);
793 : 296774 : return (*info->descriptors)[i].move_cost;
794 : : }
795 : :
796 : : /* Set the used flag corresponding to the Ith formal parameter of the function
797 : : associated with INFO to VAL. */
798 : :
799 : : inline void
800 : 2331908 : ipa_set_param_used (class ipa_node_params *info, int i, bool val)
801 : : {
802 : 2331908 : gcc_checking_assert (info->descriptors);
803 : 2331908 : (*info->descriptors)[i].used = val;
804 : 2331908 : }
805 : :
806 : : /* Set the used_by_ipa_predicates flag corresponding to the Ith formal
807 : : parameter of the function associated with INFO to VAL. */
808 : :
809 : : inline void
810 : 6640435 : ipa_set_param_used_by_ipa_predicates (class ipa_node_params *info, int i, bool val)
811 : : {
812 : 6640435 : gcc_checking_assert (info->descriptors);
813 : 6640435 : (*info->descriptors)[i].used_by_ipa_predicates = val;
814 : 6640435 : }
815 : :
816 : : /* Set the used_by_indirect_call flag corresponding to the Ith formal
817 : : parameter of the function associated with INFO to VAL. */
818 : :
819 : : inline void
820 : 20800 : ipa_set_param_used_by_indirect_call (class ipa_node_params *info, int i, bool val)
821 : : {
822 : 20800 : gcc_checking_assert (info->descriptors);
823 : 20800 : (*info->descriptors)[i].used_by_indirect_call = val;
824 : 20800 : }
825 : :
826 : : /* Set the .used_by_polymorphic_call flag corresponding to the Ith formal
827 : : parameter of the function associated with INFO to VAL. */
828 : :
829 : : inline void
830 : 13000 : ipa_set_param_used_by_polymorphic_call (class ipa_node_params *info, int i, bool val)
831 : : {
832 : 13000 : gcc_checking_assert (info->descriptors);
833 : 13000 : (*info->descriptors)[i].used_by_polymorphic_call = val;
834 : 13000 : }
835 : :
836 : : /* Return how many uses described by ipa-prop a parameter has or
837 : : IPA_UNDESCRIBED_USE if there is a use that is not described by these
838 : : structures. */
839 : : inline int
840 : 979555 : ipa_get_controlled_uses (class ipa_node_params *info, int i)
841 : : {
842 : : /* FIXME: introducing speculation causes out of bounds access here. */
843 : 979555 : if (vec_safe_length (info->descriptors) > (unsigned)i)
844 : 979546 : return (*info->descriptors)[i].controlled_uses;
845 : : return IPA_UNDESCRIBED_USE;
846 : : }
847 : :
848 : : /* Set the controlled counter of a given parameter. */
849 : :
850 : : inline void
851 : 2654485 : ipa_set_controlled_uses (class ipa_node_params *info, int i, int val)
852 : : {
853 : 2654485 : gcc_checking_assert (info->descriptors);
854 : 2654485 : (*info->descriptors)[i].controlled_uses = val;
855 : 2654485 : }
856 : :
857 : : /* Assuming a parameter does not have IPA_UNDESCRIBED_USE controlled uses,
858 : : return flag which indicates it has been dereferenced but only in a load. */
859 : : inline int
860 : 179555 : ipa_get_param_load_dereferenced (class ipa_node_params *info, int i)
861 : : {
862 : 179555 : gcc_assert (ipa_get_controlled_uses (info, i) != IPA_UNDESCRIBED_USE);
863 : 179555 : return (*info->descriptors)[i].load_dereferenced;
864 : : }
865 : :
866 : : /* Set the load_dereferenced flag of a given parameter. */
867 : :
868 : : inline void
869 : 2459953 : ipa_set_param_load_dereferenced (class ipa_node_params *info, int i, bool val)
870 : : {
871 : 2459953 : gcc_checking_assert (info->descriptors);
872 : 2459953 : (*info->descriptors)[i].load_dereferenced = val;
873 : 2459953 : }
874 : :
875 : : /* Return the used flag corresponding to the Ith formal parameter of the
876 : : function associated with INFO. */
877 : :
878 : : inline bool
879 : 8705084 : ipa_is_param_used (class ipa_node_params *info, int i)
880 : : {
881 : 8705084 : gcc_checking_assert (info->descriptors);
882 : 8705084 : return (*info->descriptors)[i].used;
883 : : }
884 : :
885 : : /* Return the used_by_ipa_predicates flag corresponding to the Ith formal
886 : : parameter of the function associated with INFO. */
887 : :
888 : : inline bool
889 : 37891187 : ipa_is_param_used_by_ipa_predicates (class ipa_node_params *info, int i)
890 : : {
891 : 37891187 : gcc_checking_assert (info->descriptors);
892 : 37891187 : return (*info->descriptors)[i].used_by_ipa_predicates;
893 : : }
894 : :
895 : : /* Return the used_by_indirect_call flag corresponding to the Ith formal
896 : : parameter of the function associated with INFO. */
897 : :
898 : : inline bool
899 : 39808508 : ipa_is_param_used_by_indirect_call (class ipa_node_params *info, int i)
900 : : {
901 : 39808508 : gcc_checking_assert (info->descriptors);
902 : 39808508 : return (*info->descriptors)[i].used_by_indirect_call;
903 : : }
904 : :
905 : : /* Return the used_by_polymorphic_call flag corresponding to the Ith formal
906 : : parameter of the function associated with INFO. */
907 : :
908 : : inline bool
909 : 31623535 : ipa_is_param_used_by_polymorphic_call (class ipa_node_params *info, int i)
910 : : {
911 : 31623535 : gcc_checking_assert (info->descriptors);
912 : 31623535 : return (*info->descriptors)[i].used_by_polymorphic_call;
913 : : }
914 : :
915 : : /* GTY-marked structure used to map DECL_UIDs of APRAMs to their indices in
916 : : their DECL_ARGUMENTs chain. */
917 : : struct GTY(()) ipa_uid_to_idx_map_elt
918 : : {
919 : : /* DECL_UID of the PARAM. */
920 : : unsigned uid;
921 : : /* Its index in the DECL_ARGUMETs chain. */
922 : : unsigned index;
923 : : };
924 : :
925 : : /* Structure holding information for the transformation phase of IPA-CP. */
926 : :
927 : : struct GTY(()) ipcp_transformation
928 : : {
929 : : /* Default constructor. */
930 : 118218 : ipcp_transformation ()
931 : 118218 : : m_agg_values (nullptr), m_vr (nullptr), m_uid_to_idx (nullptr)
932 : : { }
933 : :
934 : : /* Default destructor. */
935 : 118198 : ~ipcp_transformation ()
936 : : {
937 : 118198 : vec_free (m_agg_values);
938 : 118198 : vec_free (m_vr);
939 : 118198 : }
940 : :
941 : : /* Given PARAM which must be a parameter of function FNDECL described by
942 : : THIS, return its index in the DECL_ARGUMENTS chain, using a pre-computed
943 : : DECL_UID-sorted vector if available (which is pre-computed only if there
944 : : are many parameters). Can return -1 if param is static chain not
945 : : represented among DECL_ARGUMENTS. */
946 : :
947 : : int get_param_index (const_tree fndecl, const_tree param) const;
948 : :
949 : : /* Assuming THIS describes FNDECL and it has sufficiently many parameters to
950 : : justify the overhead, create a DECL_UID-sorted vector to speed up mapping
951 : : from parameters to their indices in DECL_ARGUMENTS chain. */
952 : :
953 : : void maybe_create_parm_idx_map (tree fndecl);
954 : :
955 : : /* Remove all elements in m_agg_values on which PREDICATE returns true. */
956 : :
957 : : template<typename pred_function>
958 : 7905 : void remove_argaggs_if (pred_function &&predicate)
959 : : {
960 : 7905 : unsigned ts_len = vec_safe_length (m_agg_values);
961 : 3260 : if (ts_len == 0)
962 : : return;
963 : :
964 : : bool removed_item = false;
965 : : unsigned dst_index = 0;
966 : :
967 : 16603 : for (unsigned i = 0; i < ts_len; i++)
968 : : {
969 : 13343 : ipa_argagg_value *v = &(*m_agg_values)[i];
970 : 13343 : if (!predicate (*v))
971 : : {
972 : 13198 : if (removed_item)
973 : 22 : (*m_agg_values)[dst_index] = *v;
974 : 13198 : dst_index++;
975 : : }
976 : : else
977 : : removed_item = true;
978 : : }
979 : 3260 : if (dst_index == 0)
980 : : {
981 : 39 : ggc_free (m_agg_values);
982 : 39 : m_agg_values = NULL;
983 : : }
984 : 3221 : else if (removed_item)
985 : 22 : m_agg_values->truncate (dst_index);
986 : : }
987 : :
988 : : /* Known aggregate values. */
989 : : vec<ipa_argagg_value, va_gc> *m_agg_values;
990 : : /* Value range information. */
991 : : vec<ipa_vr, va_gc> *m_vr;
992 : : /* If there are many parameters, this is a vector sorted by their DECL_UIDs
993 : : to map them to their indices in the DECL_ARGUMENT chain. */
994 : : vec<ipa_uid_to_idx_map_elt, va_gc> *m_uid_to_idx;
995 : : };
996 : :
997 : : inline
998 : 48284 : ipa_argagg_value_list::ipa_argagg_value_list (const ipcp_transformation *tinfo)
999 : 96568 : : m_elts (tinfo->m_agg_values)
1000 : : {}
1001 : :
1002 : : void ipa_set_node_agg_value_chain (struct cgraph_node *node,
1003 : : vec<ipa_argagg_value, va_gc> *aggs);
1004 : : void ipcp_transformation_initialize (void);
1005 : : void ipcp_free_transformation_sum (void);
1006 : :
1007 : : /* ipa_edge_args stores information related to a callsite and particularly its
1008 : : arguments. It can be accessed by the IPA_EDGE_REF macro. */
1009 : :
1010 : : class GTY((for_user)) ipa_edge_args
1011 : : {
1012 : : public:
1013 : :
1014 : : /* Default constructor. */
1015 : 4050554 : ipa_edge_args () : jump_functions (NULL), polymorphic_call_contexts (NULL)
1016 : : {}
1017 : :
1018 : : /* Destructor. */
1019 : 4050554 : ~ipa_edge_args ()
1020 : : {
1021 : 4050554 : unsigned int i;
1022 : 4050554 : ipa_jump_func *jf;
1023 : 12640130 : FOR_EACH_VEC_SAFE_ELT (jump_functions, i, jf)
1024 : 8950256 : vec_free (jf->agg.items);
1025 : 4050554 : vec_free (jump_functions);
1026 : 4050554 : vec_free (polymorphic_call_contexts);
1027 : 4050554 : }
1028 : :
1029 : : /* Vectors of the callsite's jump function and polymorphic context
1030 : : information of each parameter. */
1031 : : vec<ipa_jump_func, va_gc> *jump_functions;
1032 : : vec<ipa_polymorphic_call_context, va_gc> *polymorphic_call_contexts;
1033 : : };
1034 : :
1035 : : /* ipa_edge_args access functions. Please use these to access fields that
1036 : : are or will be shared among various passes. */
1037 : :
1038 : : /* Return the number of actual arguments. */
1039 : :
1040 : : inline int
1041 : 20847828 : ipa_get_cs_argument_count (class ipa_edge_args *args)
1042 : : {
1043 : 40353143 : return vec_safe_length (args->jump_functions);
1044 : : }
1045 : :
1046 : : /* Returns a pointer to the jump function for the ith argument. Please note
1047 : : there is no setter function as jump functions are all set up in
1048 : : ipa_compute_jump_functions. */
1049 : :
1050 : : inline struct ipa_jump_func *
1051 : 44592354 : ipa_get_ith_jump_func (class ipa_edge_args *args, int i)
1052 : : {
1053 : 42292586 : return &(*args->jump_functions)[i];
1054 : : }
1055 : :
1056 : : /* Returns a pointer to the polymorphic call context for the ith argument.
1057 : : NULL if contexts are not computed. */
1058 : : inline class ipa_polymorphic_call_context *
1059 : 7013407 : ipa_get_ith_polymorhic_call_context (class ipa_edge_args *args, int i)
1060 : : {
1061 : 7010799 : if (!args->polymorphic_call_contexts)
1062 : : return NULL;
1063 : 3522570 : return &(*args->polymorphic_call_contexts)[i];
1064 : : }
1065 : :
1066 : : /* Function summary for ipa_node_params. */
1067 : : class GTY((user)) ipa_node_params_t: public function_summary <ipa_node_params *>
1068 : : {
1069 : : public:
1070 : 4819206 : ipa_node_params_t (symbol_table *table, bool ggc):
1071 : 4819206 : function_summary<ipa_node_params *> (table, ggc)
1072 : : {
1073 : 4819206 : disable_insertion_hook ();
1074 : 4819206 : }
1075 : :
1076 : : /* Hook that is called by summary when a node is duplicated. */
1077 : : void duplicate (cgraph_node *node,
1078 : : cgraph_node *node2,
1079 : : ipa_node_params *data,
1080 : : ipa_node_params *data2) final override;
1081 : : };
1082 : :
1083 : : /* Summary to manange ipa_edge_args structures. */
1084 : :
1085 : : class GTY((user)) ipa_edge_args_sum_t : public call_summary <ipa_edge_args *>
1086 : : {
1087 : : public:
1088 : 239255 : ipa_edge_args_sum_t (symbol_table *table, bool ggc)
1089 : 239255 : : call_summary<ipa_edge_args *> (table, ggc) { }
1090 : :
1091 : 734379 : void remove (cgraph_edge *edge)
1092 : : {
1093 : 734379 : call_summary <ipa_edge_args *>::remove (edge);
1094 : 734379 : }
1095 : :
1096 : : /* Hook that is called by summary when an edge is removed. */
1097 : : void remove (cgraph_edge *cs, ipa_edge_args *args) final override;
1098 : : /* Hook that is called by summary when an edge is duplicated. */
1099 : : void duplicate (cgraph_edge *src,
1100 : : cgraph_edge *dst,
1101 : : ipa_edge_args *old_args,
1102 : : ipa_edge_args *new_args) final override;
1103 : : };
1104 : :
1105 : : /* Function summary where the parameter infos are actually stored. */
1106 : : extern GTY(()) ipa_node_params_t * ipa_node_params_sum;
1107 : : /* Call summary to store information about edges such as jump functions. */
1108 : : extern GTY(()) ipa_edge_args_sum_t *ipa_edge_args_sum;
1109 : :
1110 : : /* Function summary for IPA-CP transformation. */
1111 : : class ipcp_transformation_t
1112 : : : public function_summary<ipcp_transformation *>
1113 : : {
1114 : : public:
1115 : 18065 : ipcp_transformation_t (symbol_table *table, bool ggc):
1116 : 36130 : function_summary<ipcp_transformation *> (table, ggc) {}
1117 : :
1118 : 18056 : ~ipcp_transformation_t () {}
1119 : :
1120 : 18065 : static ipcp_transformation_t *create_ggc (symbol_table *symtab)
1121 : : {
1122 : 18065 : ipcp_transformation_t *summary
1123 : 18065 : = new (ggc_alloc_no_dtor <ipcp_transformation_t> ())
1124 : 18065 : ipcp_transformation_t (symtab, true);
1125 : 18065 : return summary;
1126 : : }
1127 : : /* Hook that is called by summary when a node is duplicated. */
1128 : : void duplicate (cgraph_node *node,
1129 : : cgraph_node *node2,
1130 : : ipcp_transformation *data,
1131 : : ipcp_transformation *data2) final override;
1132 : : };
1133 : :
1134 : : /* Function summary where the IPA CP transformations are actually stored. */
1135 : : extern GTY(()) function_summary <ipcp_transformation *> *ipcp_transformation_sum;
1136 : :
1137 : : /* Creating and freeing ipa_node_params and ipa_edge_args. */
1138 : : void ipa_create_all_node_params (void);
1139 : : void ipa_create_all_edge_args (void);
1140 : : void ipa_check_create_edge_args (void);
1141 : : void ipa_free_all_node_params (void);
1142 : : void ipa_free_all_edge_args (void);
1143 : : void ipa_free_all_structures_after_ipa_cp (void);
1144 : : void ipa_free_all_structures_after_iinln (void);
1145 : :
1146 : : void ipa_register_cgraph_hooks (void);
1147 : : int count_formal_params (tree fndecl);
1148 : :
1149 : : /* This function ensures the array of node param infos is big enough to
1150 : : accommodate a structure for all nodes and reallocates it if not. */
1151 : :
1152 : : inline void
1153 : 7683027 : ipa_check_create_node_params (void)
1154 : : {
1155 : 7683027 : if (!ipa_node_params_sum)
1156 : 4819206 : ipa_node_params_sum
1157 : 9638412 : = (new (ggc_alloc_no_dtor <ipa_node_params_t> ())
1158 : 4819206 : ipa_node_params_t (symtab, true));
1159 : 7683027 : }
1160 : :
1161 : : /* Returns true if edge summary contains a record for EDGE. The main purpose
1162 : : of this function is that debug dumping function can check info availability
1163 : : without causing allocations. */
1164 : :
1165 : : inline bool
1166 : 1145 : ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
1167 : : {
1168 : 1145 : return ipa_edge_args_sum->exists (edge);
1169 : : }
1170 : :
1171 : : inline ipcp_transformation *
1172 : 15555726 : ipcp_get_transformation_summary (cgraph_node *node)
1173 : : {
1174 : 15555726 : if (ipcp_transformation_sum == NULL)
1175 : : return NULL;
1176 : :
1177 : 4399160 : return ipcp_transformation_sum->get (node);
1178 : : }
1179 : :
1180 : : /* Function formal parameters related computations. */
1181 : : void ipa_initialize_node_params (struct cgraph_node *node);
1182 : : void ipa_print_constant_value (FILE *f, tree val);
1183 : : bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
1184 : : vec<cgraph_edge *> *new_edges);
1185 : :
1186 : : /* Indirect edge processing and target discovery. */
1187 : : tree ipa_get_indirect_edge_target (struct cgraph_edge *ie,
1188 : : ipa_call_arg_values *avals,
1189 : : bool *speculative);
1190 : : struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree,
1191 : : bool speculative = false);
1192 : : tree ipa_impossible_devirt_target (struct cgraph_edge *, tree);
1193 : :
1194 : :
1195 : : /* Functions related to both. */
1196 : : void ipa_analyze_node (struct cgraph_node *);
1197 : :
1198 : : /* Aggregate jump function related functions. */
1199 : : tree ipa_find_agg_cst_from_init (tree scalar, HOST_WIDE_INT offset,
1200 : : bool by_ref);
1201 : : bool ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
1202 : : vec<ipa_param_descriptor, va_gc> *descriptors,
1203 : : gimple *stmt, tree op, int *index_p,
1204 : : HOST_WIDE_INT *offset_p, poly_int64 *size_p,
1205 : : bool *by_ref, bool *guaranteed_unmodified = NULL);
1206 : :
1207 : : /* Debugging interface. */
1208 : : void ipa_print_node_params (FILE *, struct cgraph_node *node);
1209 : : void ipa_print_all_params (FILE *);
1210 : : void ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node);
1211 : : void ipa_print_all_jump_functions (FILE * f);
1212 : : void ipcp_verify_propagated_values (void);
1213 : :
1214 : : template <typename value>
1215 : : class ipcp_value;
1216 : :
1217 : : extern object_allocator<ipcp_value<tree> > ipcp_cst_values_pool;
1218 : : extern object_allocator<ipcp_value<ipa_polymorphic_call_context> >
1219 : : ipcp_poly_ctx_values_pool;
1220 : :
1221 : : template <typename valtype>
1222 : : struct ipcp_value_source;
1223 : :
1224 : : extern object_allocator<ipcp_value_source<tree> > ipcp_sources_pool;
1225 : :
1226 : : struct ipcp_agg_lattice;
1227 : :
1228 : : extern object_allocator<ipcp_agg_lattice> ipcp_agg_lattice_pool;
1229 : :
1230 : : void ipa_prop_write_jump_functions (void);
1231 : : void ipa_prop_read_jump_functions (void);
1232 : : void ipcp_write_transformation_summaries (void);
1233 : : void ipcp_read_transformation_summaries (void);
1234 : : int ipa_get_param_decl_index (class ipa_node_params *, tree);
1235 : : tree ipa_value_from_jfunc (class ipa_node_params *info,
1236 : : struct ipa_jump_func *jfunc, tree type);
1237 : : tree ipa_agg_value_from_jfunc (ipa_node_params *info, cgraph_node *node,
1238 : : const ipa_agg_jf_item *item);
1239 : : unsigned int ipcp_transform_function (struct cgraph_node *node);
1240 : : ipa_polymorphic_call_context ipa_context_from_jfunc (ipa_node_params *,
1241 : : cgraph_edge *,
1242 : : int,
1243 : : ipa_jump_func *);
1244 : : void ipa_value_range_from_jfunc (vrange &, ipa_node_params *, cgraph_edge *,
1245 : : ipa_jump_func *, tree);
1246 : : void ipa_push_agg_values_from_jfunc (ipa_node_params *info, cgraph_node *node,
1247 : : ipa_agg_jump_function *agg_jfunc,
1248 : : unsigned dst_index,
1249 : : vec<ipa_argagg_value> *res);
1250 : : void ipa_dump_param (FILE *, class ipa_node_params *info, int i);
1251 : : void ipa_dump_jump_function (FILE *f, ipa_jump_func *jfunc,
1252 : : class ipa_polymorphic_call_context *ctx = NULL);
1253 : : void ipa_release_body_info (struct ipa_func_body_info *);
1254 : : tree ipa_get_callee_param_type (struct cgraph_edge *e, int i);
1255 : : bool ipcp_get_parm_bits (tree, tree *, widest_int *);
1256 : : tree ipcp_get_aggregate_const (struct function *func, tree parm, bool by_ref,
1257 : : HOST_WIDE_INT bit_offset,
1258 : : HOST_WIDE_INT bit_size);
1259 : : bool unadjusted_ptr_and_unit_offset (tree op, tree *ret,
1260 : : poly_int64 *offset_ret);
1261 : :
1262 : : void ipa_prop_cc_finalize (void);
1263 : :
1264 : : /* From tree-sra.cc: */
1265 : : tree build_ref_for_offset (location_t, tree, poly_int64, bool, tree,
1266 : : gimple_stmt_iterator *, bool);
1267 : :
1268 : : /* In ipa-cp.cc */
1269 : : void ipa_cp_cc_finalize (void);
1270 : :
1271 : : /* Set R to the range of [VAL, VAL] while normalizing addresses to
1272 : : non-zero. */
1273 : :
1274 : : inline void
1275 : 979459 : ipa_range_set_and_normalize (vrange &r, tree val)
1276 : : {
1277 : 979459 : if (TREE_CODE (val) == ADDR_EXPR)
1278 : 767 : r.set_nonzero (TREE_TYPE (val));
1279 : : else
1280 : 978692 : r.set (val, val);
1281 : 979459 : }
1282 : :
1283 : : bool ipa_return_value_range (value_range &range, tree decl);
1284 : : void ipa_record_return_value_range (value_range val);
1285 : : bool ipa_jump_functions_equivalent_p (ipa_jump_func *jf1, ipa_jump_func *jf2);
1286 : :
1287 : :
1288 : : #endif /* IPA_PROP_H */
|