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 : 1989 : ipa_argagg_value_list (const vec<ipa_argagg_value, va_gc> *values)
231 : 3920 : : m_elts (values)
232 : : {}
233 : 3095 : ipa_argagg_value_list (const vec<ipa_argagg_value> *values)
234 : 6190 : : 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 : 103608 : bool value_for_index_p (int index) const
269 : : {
270 : 103608 : 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 : 820015 : bool known_p () const { return m_storage != NULL; }
308 : 6354651 : tree type () const { return m_type; }
309 : : void get_vrange (Value_Range &) const;
310 : : bool equal_p (const vrange &) const;
311 : : const vrange_storage *storage () const { return m_storage; }
312 : : void streamer_read (lto_input_block *, class data_in *);
313 : : void streamer_write (output_block *) const;
314 : : void dump (FILE *) const;
315 : :
316 : : private:
317 : : friend void gt_pch_nx (struct ipa_vr &);
318 : : friend void gt_ggc_mx (struct ipa_vr &);
319 : : friend void gt_pch_nx (struct ipa_vr *, gt_pointer_operator, void *);
320 : : friend void gt_ggc_mx_ipa_vr (void *);
321 : : friend void gt_pch_nx_ipa_vr (void*);
322 : : friend void gt_pch_p_6ipa_vr(void*, void*, gt_pointer_operator, void*);
323 : :
324 : : vrange_storage *m_storage;
325 : : tree m_type;
326 : : };
327 : :
328 : : /* A jump function for a callsite represents the values passed as actual
329 : : arguments of the callsite. See enum jump_func_type for the various
330 : : types of jump functions supported. */
331 : : struct GTY (()) ipa_jump_func
332 : : {
333 : : /* Aggregate jump function description. See struct ipa_agg_jump_function
334 : : and its description. */
335 : : struct ipa_agg_jump_function agg;
336 : :
337 : : /* Information about value range, containing valid data only when vr_known is
338 : : true. The pointed to structure is shared betweed different jump
339 : : functions. Use ipa_set_jfunc_vr to set this field. */
340 : : ipa_vr *m_vr;
341 : :
342 : : enum jump_func_type type;
343 : : /* Represents a value of a jump function. pass_through is used only in jump
344 : : function context. constant represents the actual constant in constant jump
345 : : functions and member_cst holds constant c++ member functions. */
346 : : union jump_func_value
347 : : {
348 : : struct ipa_constant_data GTY ((tag ("IPA_JF_CONST"))) constant;
349 : : struct ipa_pass_through_data GTY ((tag ("IPA_JF_PASS_THROUGH"))) pass_through;
350 : : struct ipa_ancestor_jf_data GTY ((tag ("IPA_JF_ANCESTOR"))) ancestor;
351 : : } GTY ((desc ("%1.type"))) value;
352 : : };
353 : :
354 : :
355 : : /* Return the constant stored in a constant jump functin JFUNC. */
356 : :
357 : : inline tree
358 : 4735080 : ipa_get_jf_constant (struct ipa_jump_func *jfunc)
359 : : {
360 : 4735080 : gcc_checking_assert (jfunc->type == IPA_JF_CONST);
361 : 4735080 : return jfunc->value.constant.value;
362 : : }
363 : :
364 : : inline struct ipa_cst_ref_desc *
365 : 1281841 : ipa_get_jf_constant_rdesc (struct ipa_jump_func *jfunc)
366 : : {
367 : 1281841 : gcc_checking_assert (jfunc->type == IPA_JF_CONST);
368 : 1281841 : return jfunc->value.constant.rdesc;
369 : : }
370 : :
371 : : /* Make JFUNC not participate in any further reference counting. */
372 : :
373 : : inline void
374 : 348 : ipa_zap_jf_refdesc (ipa_jump_func *jfunc)
375 : : {
376 : 348 : gcc_checking_assert (jfunc->type == IPA_JF_CONST);
377 : 348 : jfunc->value.constant.rdesc = NULL;
378 : 348 : }
379 : :
380 : : /* Return the operand of a pass through jmp function JFUNC. */
381 : :
382 : : inline tree
383 : 86209 : ipa_get_jf_pass_through_operand (struct ipa_jump_func *jfunc)
384 : : {
385 : 86209 : gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
386 : 86209 : return jfunc->value.pass_through.operand;
387 : : }
388 : :
389 : : /* Return the number of the caller's formal parameter that a pass through jump
390 : : function JFUNC refers to. */
391 : :
392 : : inline int
393 : 5189786 : ipa_get_jf_pass_through_formal_id (struct ipa_jump_func *jfunc)
394 : : {
395 : 5189786 : gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
396 : 5189786 : return jfunc->value.pass_through.formal_id;
397 : : }
398 : :
399 : : /* Return operation of a pass through jump function JFUNC. */
400 : :
401 : : inline enum tree_code
402 : 2065550 : ipa_get_jf_pass_through_operation (struct ipa_jump_func *jfunc)
403 : : {
404 : 2065550 : gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
405 : 2065550 : return jfunc->value.pass_through.operation;
406 : : }
407 : :
408 : : /* Return the agg_preserved flag of a pass through jump function JFUNC. */
409 : :
410 : : inline bool
411 : 1936449 : ipa_get_jf_pass_through_agg_preserved (struct ipa_jump_func *jfunc)
412 : : {
413 : 1936449 : gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
414 : 1936449 : return jfunc->value.pass_through.agg_preserved;
415 : : }
416 : :
417 : : /* Return the refdesc_decremented flag of a pass through jump function
418 : : JFUNC. */
419 : :
420 : : inline bool
421 : 371049 : ipa_get_jf_pass_through_refdesc_decremented (struct ipa_jump_func *jfunc)
422 : : {
423 : 371049 : gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
424 : 371049 : return jfunc->value.pass_through.refdesc_decremented;
425 : : }
426 : :
427 : : /* Set the refdesc_decremented flag of a pass through jump function JFUNC to
428 : : VALUE. */
429 : :
430 : : inline void
431 : 16 : ipa_set_jf_pass_through_refdesc_decremented (ipa_jump_func *jfunc, bool value)
432 : : {
433 : 16 : gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
434 : 16 : jfunc->value.pass_through.refdesc_decremented = value;
435 : 16 : }
436 : :
437 : : /* Return true if pass through jump function JFUNC preserves type
438 : : information. */
439 : :
440 : : inline bool
441 : 252668 : ipa_get_jf_pass_through_type_preserved (struct ipa_jump_func *jfunc)
442 : : {
443 : 252668 : gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
444 : 252668 : return jfunc->value.pass_through.agg_preserved;
445 : : }
446 : :
447 : : /* Return the offset of an ancestor jump function JFUNC. */
448 : :
449 : : inline HOST_WIDE_INT
450 : 197145 : ipa_get_jf_ancestor_offset (struct ipa_jump_func *jfunc)
451 : : {
452 : 197145 : gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
453 : 197145 : return jfunc->value.ancestor.offset;
454 : : }
455 : :
456 : : /* Return the number of the caller's formal parameter that an ancestor jump
457 : : function JFUNC refers to. */
458 : :
459 : : inline int
460 : 957850 : ipa_get_jf_ancestor_formal_id (struct ipa_jump_func *jfunc)
461 : : {
462 : 957850 : gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
463 : 957850 : return jfunc->value.ancestor.formal_id;
464 : : }
465 : :
466 : : /* Return the agg_preserved flag of an ancestor jump function JFUNC. */
467 : :
468 : : inline bool
469 : 229875 : ipa_get_jf_ancestor_agg_preserved (struct ipa_jump_func *jfunc)
470 : : {
471 : 229875 : gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
472 : 229875 : return jfunc->value.ancestor.agg_preserved;
473 : : }
474 : :
475 : : /* Return true if ancestor jump function JFUNC presrves type information. */
476 : :
477 : : inline bool
478 : 46824 : ipa_get_jf_ancestor_type_preserved (struct ipa_jump_func *jfunc)
479 : : {
480 : 46824 : gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
481 : 46824 : return jfunc->value.ancestor.agg_preserved;
482 : : }
483 : :
484 : : /* Return if jfunc represents an operation whether we first check the formal
485 : : parameter for non-NULLness unless it does not matter because the offset is
486 : : zero anyway. */
487 : :
488 : : inline bool
489 : 23009 : ipa_get_jf_ancestor_keep_null (struct ipa_jump_func *jfunc)
490 : : {
491 : 23009 : gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
492 : 23009 : return jfunc->value.ancestor.keep_null;
493 : : }
494 : :
495 : : /* Class for allocating a bundle of various potentially known properties about
496 : : actual arguments of a particular call on stack for the usual case and on
497 : : heap only if there are unusually many arguments. The data is deallocated
498 : : when the instance of this class goes out of scope or is otherwise
499 : : destructed. */
500 : :
501 : 19742395 : class ipa_auto_call_arg_values
502 : : {
503 : : public:
504 : : /* If m_known_vals (vector of known "scalar" values) is sufficiantly long,
505 : : return its element at INDEX, otherwise return NULL. */
506 : 41879827 : tree safe_sval_at (int index)
507 : : {
508 : 83759654 : if ((unsigned) index < m_known_vals.length ())
509 : 25790626 : return m_known_vals[index];
510 : : return NULL;
511 : : }
512 : :
513 : : /* Vector describing known values of parameters. */
514 : : auto_vec<tree, 32> m_known_vals;
515 : :
516 : : /* Vector describing known polymorphic call contexts. */
517 : : auto_vec<ipa_polymorphic_call_context, 32> m_known_contexts;
518 : :
519 : : /* Vector describing known aggregate values. */
520 : : auto_vec<ipa_argagg_value, 32> m_known_aggs;
521 : :
522 : : /* Vector describing known value ranges of arguments. */
523 : : auto_vec<Value_Range, 32> m_known_value_ranges;
524 : : };
525 : :
526 : : inline
527 : 19161117 : ipa_argagg_value_list
528 : 19161117 : ::ipa_argagg_value_list (const ipa_auto_call_arg_values *aavals)
529 : 38322234 : : m_elts (aavals->m_known_aggs)
530 : : {}
531 : :
532 : : /* Class bundling the various potentially known properties about actual
533 : : arguments of a particular call. This variant does not deallocate the
534 : : bundled data in any way as the vectors can either be pointing to vectors in
535 : : ipa_auto_call_arg_values or be allocated independently. */
536 : :
537 : : class ipa_call_arg_values
538 : : {
539 : : public:
540 : : /* Default constructor, setting the vectors to empty ones. */
541 : 998605 : ipa_call_arg_values ()
542 : 0 : {}
543 : :
544 : : /* Construct this general variant of the bundle from the variant which uses
545 : : auto_vecs to hold the vectors. This means that vectors of objects
546 : : constructed with this constructor should not be changed because if they
547 : : get reallocated, the member vectors and the underlying auto_vecs would get
548 : : out of sync. */
549 : 15971039 : ipa_call_arg_values (ipa_auto_call_arg_values *aavals)
550 : 15971039 : : m_known_vals (aavals->m_known_vals.to_vec_legacy ()),
551 : 15971039 : m_known_contexts (aavals->m_known_contexts.to_vec_legacy ()),
552 : 15971039 : m_known_aggs (aavals->m_known_aggs.to_vec_legacy ()),
553 : 15971039 : m_known_value_ranges (aavals->m_known_value_ranges.to_vec_legacy ())
554 : : {}
555 : :
556 : : /* If m_known_vals (vector of known "scalar" values) is sufficiantly long,
557 : : return its element at INDEX, otherwise return NULL. */
558 : 123602 : tree safe_sval_at (int index)
559 : : {
560 : 247204 : if ((unsigned) index < m_known_vals.length ())
561 : 80086 : return m_known_vals[index];
562 : : return NULL;
563 : : }
564 : :
565 : : /* Vector describing known values of parameters. */
566 : : vec<tree> m_known_vals = vNULL;
567 : :
568 : : /* Vector describing known polymorphic call contexts. */
569 : : vec<ipa_polymorphic_call_context> m_known_contexts = vNULL;
570 : :
571 : : /* Vector describing known aggregate values. */
572 : : vec<ipa_argagg_value> m_known_aggs = vNULL;
573 : :
574 : : /* Vector describing known value ranges of arguments. */
575 : : vec<Value_Range> m_known_value_ranges = vNULL;
576 : : };
577 : :
578 : : inline
579 : 2070706 : ipa_argagg_value_list
580 : 2070706 : ::ipa_argagg_value_list (const ipa_call_arg_values *gavals)
581 : 2501025 : : m_elts (gavals->m_known_aggs)
582 : : {}
583 : :
584 : : /* Summary describing a single formal parameter. */
585 : :
586 : : struct GTY(()) ipa_param_descriptor
587 : : {
588 : : /* In analysis and modification phase, this is the PARAM_DECL of this
589 : : parameter, in IPA LTO phase, this is the type of the described
590 : : parameter or NULL if not known. Do not read this field directly but
591 : : through ipa_get_param and ipa_get_type as appropriate. */
592 : : tree decl_or_type;
593 : : /* If all uses of the parameter are described by ipa-prop structures, this
594 : : says how many there are. If any use could not be described by means of
595 : : ipa-prop structures (which include flag dereferenced below), this is
596 : : IPA_UNDESCRIBED_USE. */
597 : : int controlled_uses;
598 : : unsigned int move_cost : 27;
599 : : /* The parameter is used. */
600 : : unsigned used : 1;
601 : : unsigned used_by_ipa_predicates : 1;
602 : : unsigned used_by_indirect_call : 1;
603 : : unsigned used_by_polymorphic_call : 1;
604 : : /* Set to true when in addition to being used in call statements, the
605 : : parameter has also been used for loads (but not for writes, does not
606 : : escape, etc.). This allows us to identify parameters p which are only
607 : : used as *p, and so when we propagate a constant to them, we can generate a
608 : : LOAD and not ADDR reference to them. */
609 : : unsigned load_dereferenced : 1;
610 : : };
611 : :
612 : : /* ipa_node_params stores information related to formal parameters of functions
613 : : and some other information for interprocedural passes that operate on
614 : : parameters (such as ipa-cp). */
615 : :
616 : : class GTY((for_user)) ipa_node_params
617 : : {
618 : : public:
619 : : /* Default constructor. */
620 : : ipa_node_params ();
621 : :
622 : : /* Default destructor. */
623 : : ~ipa_node_params ();
624 : :
625 : : /* Information about individual formal parameters that are gathered when
626 : : summaries are generated. */
627 : : vec<ipa_param_descriptor, va_gc> *descriptors;
628 : : /* Pointer to an array of structures describing individual formal
629 : : parameters. */
630 : : vec<ipcp_param_lattices> GTY((skip)) lattices;
631 : : /* Only for versioned nodes this field would not be NULL,
632 : : it points to the node that IPA cp cloned from. */
633 : : struct cgraph_node * GTY((skip)) ipcp_orig_node;
634 : : /* If this node is an ipa-cp clone, these are the known constants that
635 : : describe what it has been specialized for. */
636 : : vec<tree> GTY((skip)) known_csts;
637 : : /* If this node is an ipa-cp clone, these are the known polymorphic contexts
638 : : that describe what it has been specialized for. */
639 : : vec<ipa_polymorphic_call_context> GTY((skip)) known_contexts;
640 : : /* Whether the param uses analysis and jump function computation has already
641 : : been performed. */
642 : : unsigned analysis_done : 1;
643 : : /* Whether the function is enqueued in ipa-cp propagation stack. */
644 : : unsigned node_enqueued : 1;
645 : : /* Whether we should create a specialized version based on values that are
646 : : known to be constant in all contexts. */
647 : : unsigned do_clone_for_all_contexts : 1;
648 : : /* Set if this is an IPA-CP clone for all contexts. */
649 : : unsigned is_all_contexts_clone : 1;
650 : : /* Node has been completely replaced by clones and will be removed after
651 : : ipa-cp is finished. */
652 : : unsigned node_dead : 1;
653 : : /* Node is involved in a recursion, potentionally indirect. */
654 : : unsigned node_within_scc : 1;
655 : : /* Node contains only direct recursion. */
656 : : unsigned node_is_self_scc : 1;
657 : : /* Node is calling a private function called only once. */
658 : : unsigned node_calling_single_call : 1;
659 : : /* False when there is something makes versioning impossible. */
660 : : unsigned versionable : 1;
661 : : };
662 : :
663 : : inline
664 : 6358515 : ipa_node_params::ipa_node_params ()
665 : 6358515 : : descriptors (NULL), lattices (vNULL), ipcp_orig_node (NULL),
666 : 6358515 : known_csts (vNULL), known_contexts (vNULL), analysis_done (0),
667 : 6358515 : node_enqueued (0), do_clone_for_all_contexts (0), is_all_contexts_clone (0),
668 : 6358515 : node_dead (0), node_within_scc (0), node_is_self_scc (0),
669 : 6358515 : node_calling_single_call (0), versionable (0)
670 : : {
671 : : }
672 : :
673 : : inline
674 : 6358514 : ipa_node_params::~ipa_node_params ()
675 : : {
676 : 6358514 : vec_free (descriptors);
677 : 6358514 : lattices.release ();
678 : 6358514 : known_csts.release ();
679 : 6358514 : known_contexts.release ();
680 : 6358514 : }
681 : :
682 : : /* Intermediate information that we get from alias analysis about a particular
683 : : parameter in a particular basic_block. When a parameter or the memory it
684 : : references is marked modified, we use that information in all dominated
685 : : blocks without consulting alias analysis oracle. */
686 : :
687 : : struct ipa_param_aa_status
688 : : {
689 : : /* Set when this structure contains meaningful information. If not, the
690 : : structure describing a dominating BB should be used instead. */
691 : : bool valid;
692 : :
693 : : /* Whether we have seen something which might have modified the data in
694 : : question. PARM is for the parameter itself, REF is for data it points to
695 : : but using the alias type of individual accesses and PT is the same thing
696 : : but for computing aggregate pass-through functions using a very inclusive
697 : : ao_ref. */
698 : : bool parm_modified, ref_modified, pt_modified;
699 : : };
700 : :
701 : : /* Information related to a given BB that used only when looking at function
702 : : body. */
703 : :
704 : : struct ipa_bb_info
705 : : {
706 : : /* Call graph edges going out of this BB. */
707 : : vec<cgraph_edge *> cg_edges;
708 : : /* Alias analysis statuses of each formal parameter at this bb. */
709 : : vec<ipa_param_aa_status> param_aa_statuses;
710 : : };
711 : :
712 : : /* Structure with global information that is only used when looking at function
713 : : body. */
714 : :
715 : : struct ipa_func_body_info
716 : : {
717 : : /* The node that is being analyzed. */
718 : : cgraph_node *node;
719 : :
720 : : /* Its info. */
721 : : class ipa_node_params *info;
722 : :
723 : : /* Information about individual BBs. */
724 : : vec<ipa_bb_info> bb_infos;
725 : :
726 : : /* Number of parameters. */
727 : : int param_count;
728 : :
729 : : /* Number of statements we are still allowed to walked by when analyzing this
730 : : function. */
731 : : unsigned int aa_walk_budget;
732 : : };
733 : :
734 : : /* ipa_node_params access functions. Please use these to access fields that
735 : : are or will be shared among various passes. */
736 : :
737 : : /* Return the number of formal parameters. */
738 : :
739 : : inline int
740 : 68328751 : ipa_get_param_count (class ipa_node_params *info)
741 : : {
742 : 132089810 : return vec_safe_length (info->descriptors);
743 : : }
744 : :
745 : : /* Return the parameter declaration in DESCRIPTORS at index I and assert it is
746 : : indeed a PARM_DECL. */
747 : :
748 : : inline tree
749 : 2250511 : ipa_get_param (const vec<ipa_param_descriptor, va_gc> &descriptors, int i)
750 : : {
751 : 2250511 : tree t = descriptors[i].decl_or_type;
752 : 2250511 : gcc_checking_assert (TREE_CODE (t) == PARM_DECL);
753 : 2250511 : return t;
754 : : }
755 : :
756 : : /* Return the declaration of Ith formal parameter of the function corresponding
757 : : to INFO. Note there is no setter function as this array is built just once
758 : : using ipa_initialize_node_params. This function should not be called in
759 : : WPA. */
760 : :
761 : : inline tree
762 : 2250511 : ipa_get_param (class ipa_node_params *info, int i)
763 : : {
764 : 2250511 : gcc_checking_assert (info->descriptors);
765 : 2250511 : return ipa_get_param (*info->descriptors, i);
766 : : }
767 : :
768 : : /* Return the type of Ith formal parameter of the function corresponding
769 : : to INFO if it is known or NULL if not. */
770 : :
771 : : inline tree
772 : 20790580 : ipa_get_type (class ipa_node_params *info, int i)
773 : : {
774 : 41580842 : if (vec_safe_length (info->descriptors) <= (unsigned) i)
775 : : return NULL;
776 : 20556735 : tree t = (*info->descriptors)[i].decl_or_type;
777 : 20556735 : if (!t)
778 : : return NULL;
779 : 20556735 : if (TYPE_P (t))
780 : : return t;
781 : 19215774 : gcc_checking_assert (TREE_CODE (t) == PARM_DECL);
782 : 19215774 : return TREE_TYPE (t);
783 : : }
784 : :
785 : : /* Return the move cost of Ith formal parameter of the function corresponding
786 : : to INFO. */
787 : :
788 : : inline int
789 : 289076 : ipa_get_param_move_cost (class ipa_node_params *info, int i)
790 : : {
791 : 289076 : gcc_checking_assert (info->descriptors);
792 : 289076 : return (*info->descriptors)[i].move_cost;
793 : : }
794 : :
795 : : /* Set the used flag corresponding to the Ith formal parameter of the function
796 : : associated with INFO to VAL. */
797 : :
798 : : inline void
799 : 2278183 : ipa_set_param_used (class ipa_node_params *info, int i, bool val)
800 : : {
801 : 2278183 : gcc_checking_assert (info->descriptors);
802 : 2278183 : (*info->descriptors)[i].used = val;
803 : 2278183 : }
804 : :
805 : : /* Set the used_by_ipa_predicates flag corresponding to the Ith formal
806 : : parameter of the function associated with INFO to VAL. */
807 : :
808 : : inline void
809 : 6309310 : ipa_set_param_used_by_ipa_predicates (class ipa_node_params *info, int i, bool val)
810 : : {
811 : 6309310 : gcc_checking_assert (info->descriptors);
812 : 6309310 : (*info->descriptors)[i].used_by_ipa_predicates = val;
813 : 6309310 : }
814 : :
815 : : /* Set the used_by_indirect_call flag corresponding to the Ith formal
816 : : parameter of the function associated with INFO to VAL. */
817 : :
818 : : inline void
819 : 21141 : ipa_set_param_used_by_indirect_call (class ipa_node_params *info, int i, bool val)
820 : : {
821 : 21141 : gcc_checking_assert (info->descriptors);
822 : 21141 : (*info->descriptors)[i].used_by_indirect_call = val;
823 : 21141 : }
824 : :
825 : : /* Set the .used_by_polymorphic_call flag corresponding to the Ith formal
826 : : parameter of the function associated with INFO to VAL. */
827 : :
828 : : inline void
829 : 13174 : ipa_set_param_used_by_polymorphic_call (class ipa_node_params *info, int i, bool val)
830 : : {
831 : 13174 : gcc_checking_assert (info->descriptors);
832 : 13174 : (*info->descriptors)[i].used_by_polymorphic_call = val;
833 : 13174 : }
834 : :
835 : : /* Return how many uses described by ipa-prop a parameter has or
836 : : IPA_UNDESCRIBED_USE if there is a use that is not described by these
837 : : structures. */
838 : : inline int
839 : 955452 : ipa_get_controlled_uses (class ipa_node_params *info, int i)
840 : : {
841 : : /* FIXME: introducing speculation causes out of bounds access here. */
842 : 1910895 : if (vec_safe_length (info->descriptors) > (unsigned)i)
843 : 955443 : return (*info->descriptors)[i].controlled_uses;
844 : : return IPA_UNDESCRIBED_USE;
845 : : }
846 : :
847 : : /* Set the controlled counter of a given parameter. */
848 : :
849 : : inline void
850 : 2593506 : ipa_set_controlled_uses (class ipa_node_params *info, int i, int val)
851 : : {
852 : 2593506 : gcc_checking_assert (info->descriptors);
853 : 2593506 : (*info->descriptors)[i].controlled_uses = val;
854 : 2593506 : }
855 : :
856 : : /* Assuming a parameter does not have IPA_UNDESCRIBED_USE controlled uses,
857 : : return flag which indicates it has been dereferenced but only in a load. */
858 : : inline int
859 : 177384 : ipa_get_param_load_dereferenced (class ipa_node_params *info, int i)
860 : : {
861 : 177384 : gcc_assert (ipa_get_controlled_uses (info, i) != IPA_UNDESCRIBED_USE);
862 : 177384 : return (*info->descriptors)[i].load_dereferenced;
863 : : }
864 : :
865 : : /* Set the load_dereferenced flag of a given parameter. */
866 : :
867 : : inline void
868 : 2408532 : ipa_set_param_load_dereferenced (class ipa_node_params *info, int i, bool val)
869 : : {
870 : 2408532 : gcc_checking_assert (info->descriptors);
871 : 2408532 : (*info->descriptors)[i].load_dereferenced = val;
872 : 2408532 : }
873 : :
874 : : /* Return the used flag corresponding to the Ith formal parameter of the
875 : : function associated with INFO. */
876 : :
877 : : inline bool
878 : 8530664 : ipa_is_param_used (class ipa_node_params *info, int i)
879 : : {
880 : 8530664 : gcc_checking_assert (info->descriptors);
881 : 8530664 : return (*info->descriptors)[i].used;
882 : : }
883 : :
884 : : /* Return the used_by_ipa_predicates flag corresponding to the Ith formal
885 : : parameter of the function associated with INFO. */
886 : :
887 : : inline bool
888 : 37524250 : ipa_is_param_used_by_ipa_predicates (class ipa_node_params *info, int i)
889 : : {
890 : 37524250 : gcc_checking_assert (info->descriptors);
891 : 37524250 : return (*info->descriptors)[i].used_by_ipa_predicates;
892 : : }
893 : :
894 : : /* Return the used_by_indirect_call flag corresponding to the Ith formal
895 : : parameter of the function associated with INFO. */
896 : :
897 : : inline bool
898 : 39324549 : ipa_is_param_used_by_indirect_call (class ipa_node_params *info, int i)
899 : : {
900 : 39324549 : gcc_checking_assert (info->descriptors);
901 : 39324549 : return (*info->descriptors)[i].used_by_indirect_call;
902 : : }
903 : :
904 : : /* Return the used_by_polymorphic_call flag corresponding to the Ith formal
905 : : parameter of the function associated with INFO. */
906 : :
907 : : inline bool
908 : 31227157 : ipa_is_param_used_by_polymorphic_call (class ipa_node_params *info, int i)
909 : : {
910 : 31227157 : gcc_checking_assert (info->descriptors);
911 : 31227157 : return (*info->descriptors)[i].used_by_polymorphic_call;
912 : : }
913 : :
914 : : /* GTY-marked structure used to map DECL_UIDs of APRAMs to their indices in
915 : : their DECL_ARGUMENTs chain. */
916 : : struct GTY(()) ipa_uid_to_idx_map_elt
917 : : {
918 : : /* DECL_UID of the PARAM. */
919 : : unsigned uid;
920 : : /* Its index in the DECL_ARGUMETs chain. */
921 : : unsigned index;
922 : : };
923 : :
924 : : /* Structure holding information for the transformation phase of IPA-CP. */
925 : :
926 : : struct GTY(()) ipcp_transformation
927 : : {
928 : : /* Default constructor. */
929 : 118686 : ipcp_transformation ()
930 : 118686 : : m_agg_values (nullptr), m_vr (nullptr), m_uid_to_idx (nullptr)
931 : : { }
932 : :
933 : : /* Default destructor. */
934 : 118666 : ~ipcp_transformation ()
935 : : {
936 : 118666 : vec_free (m_agg_values);
937 : 118666 : vec_free (m_vr);
938 : 118666 : }
939 : :
940 : : /* Given PARAM which must be a parameter of function FNDECL described by
941 : : THIS, return its index in the DECL_ARGUMENTS chain, using a pre-computed
942 : : DECL_UID-sorted vector if available (which is pre-computed only if there
943 : : are many parameters). Can return -1 if param is static chain not
944 : : represented among DECL_ARGUMENTS. */
945 : :
946 : : int get_param_index (const_tree fndecl, const_tree param) const;
947 : :
948 : : /* Assuming THIS describes FNDECL and it has sufficiently many parameters to
949 : : justify the overhead, create a DECL_UID-sorted vector to speed up mapping
950 : : from parameters to their indices in DECL_ARGUMENTS chain. */
951 : :
952 : : void maybe_create_parm_idx_map (tree fndecl);
953 : :
954 : : /* Remove all elements in m_agg_values on which PREDICATE returns true. */
955 : :
956 : : template<typename pred_function>
957 : 7658 : void remove_argaggs_if (pred_function &&predicate)
958 : : {
959 : 7658 : unsigned ts_len = vec_safe_length (m_agg_values);
960 : 3261 : if (ts_len == 0)
961 : : return;
962 : :
963 : : bool removed_item = false;
964 : : unsigned dst_index = 0;
965 : :
966 : 15809 : for (unsigned i = 0; i < ts_len; i++)
967 : : {
968 : 12548 : ipa_argagg_value *v = &(*m_agg_values)[i];
969 : 12548 : if (!predicate (*v))
970 : : {
971 : 12403 : if (removed_item)
972 : 86 : (*m_agg_values)[dst_index] = *v;
973 : 12403 : dst_index++;
974 : : }
975 : : else
976 : : removed_item = true;
977 : : }
978 : 3261 : if (dst_index == 0)
979 : : {
980 : 40 : ggc_free (m_agg_values);
981 : 40 : m_agg_values = NULL;
982 : : }
983 : 3221 : else if (removed_item)
984 : 22 : m_agg_values->truncate (dst_index);
985 : : }
986 : :
987 : : /* Known aggregate values. */
988 : : vec<ipa_argagg_value, va_gc> *m_agg_values;
989 : : /* Value range information. */
990 : : vec<ipa_vr, va_gc> *m_vr;
991 : : /* If there are many parameters, this is a vector sorted by their DECL_UIDs
992 : : to map them to their indices in the DECL_ARGUMENT chain. */
993 : : vec<ipa_uid_to_idx_map_elt, va_gc> *m_uid_to_idx;
994 : : };
995 : :
996 : : inline
997 : 47526 : ipa_argagg_value_list::ipa_argagg_value_list (const ipcp_transformation *tinfo)
998 : 95052 : : m_elts (tinfo->m_agg_values)
999 : : {}
1000 : :
1001 : : void ipa_set_node_agg_value_chain (struct cgraph_node *node,
1002 : : vec<ipa_argagg_value, va_gc> *aggs);
1003 : : void ipcp_transformation_initialize (void);
1004 : : void ipcp_free_transformation_sum (void);
1005 : :
1006 : : /* ipa_edge_args stores information related to a callsite and particularly its
1007 : : arguments. It can be accessed by the IPA_EDGE_REF macro. */
1008 : :
1009 : : class GTY((for_user)) ipa_edge_args
1010 : : {
1011 : : public:
1012 : :
1013 : : /* Default constructor. */
1014 : 3713714 : ipa_edge_args () : jump_functions (NULL), polymorphic_call_contexts (NULL)
1015 : : {}
1016 : :
1017 : : /* Destructor. */
1018 : 3713714 : ~ipa_edge_args ()
1019 : : {
1020 : 3713714 : unsigned int i;
1021 : 3713714 : ipa_jump_func *jf;
1022 : 11770081 : FOR_EACH_VEC_SAFE_ELT (jump_functions, i, jf)
1023 : 8394894 : vec_free (jf->agg.items);
1024 : 3713714 : vec_free (jump_functions);
1025 : 3713714 : vec_free (polymorphic_call_contexts);
1026 : 3713714 : }
1027 : :
1028 : : /* Vectors of the callsite's jump function and polymorphic context
1029 : : information of each parameter. */
1030 : : vec<ipa_jump_func, va_gc> *jump_functions;
1031 : : vec<ipa_polymorphic_call_context, va_gc> *polymorphic_call_contexts;
1032 : : };
1033 : :
1034 : : /* ipa_edge_args access functions. Please use these to access fields that
1035 : : are or will be shared among various passes. */
1036 : :
1037 : : /* Return the number of actual arguments. */
1038 : :
1039 : : inline int
1040 : 19898821 : ipa_get_cs_argument_count (class ipa_edge_args *args)
1041 : : {
1042 : 38665130 : return vec_safe_length (args->jump_functions);
1043 : : }
1044 : :
1045 : : /* Returns a pointer to the jump function for the ith argument. Please note
1046 : : there is no setter function as jump functions are all set up in
1047 : : ipa_compute_jump_functions. */
1048 : :
1049 : : inline struct ipa_jump_func *
1050 : 42532965 : ipa_get_ith_jump_func (class ipa_edge_args *args, int i)
1051 : : {
1052 : 40537647 : return &(*args->jump_functions)[i];
1053 : : }
1054 : :
1055 : : /* Returns a pointer to the polymorphic call context for the ith argument.
1056 : : NULL if contexts are not computed. */
1057 : : inline class ipa_polymorphic_call_context *
1058 : 6606226 : ipa_get_ith_polymorhic_call_context (class ipa_edge_args *args, int i)
1059 : : {
1060 : 6603673 : if (!args->polymorphic_call_contexts)
1061 : : return NULL;
1062 : 3353683 : return &(*args->polymorphic_call_contexts)[i];
1063 : : }
1064 : :
1065 : : /* Function summary for ipa_node_params. */
1066 : : class GTY((user)) ipa_node_params_t: public function_summary <ipa_node_params *>
1067 : : {
1068 : : public:
1069 : 4637220 : ipa_node_params_t (symbol_table *table, bool ggc):
1070 : 4637220 : function_summary<ipa_node_params *> (table, ggc)
1071 : : {
1072 : 4637220 : disable_insertion_hook ();
1073 : 4637220 : }
1074 : :
1075 : : /* Hook that is called by summary when a node is duplicated. */
1076 : : void duplicate (cgraph_node *node,
1077 : : cgraph_node *node2,
1078 : : ipa_node_params *data,
1079 : : ipa_node_params *data2) final override;
1080 : : };
1081 : :
1082 : : /* Summary to manange ipa_edge_args structures. */
1083 : :
1084 : : class GTY((user)) ipa_edge_args_sum_t : public call_summary <ipa_edge_args *>
1085 : : {
1086 : : public:
1087 : 243108 : ipa_edge_args_sum_t (symbol_table *table, bool ggc)
1088 : 243108 : : call_summary<ipa_edge_args *> (table, ggc) { }
1089 : :
1090 : 738941 : void remove (cgraph_edge *edge)
1091 : : {
1092 : 738941 : call_summary <ipa_edge_args *>::remove (edge);
1093 : 738941 : }
1094 : :
1095 : : /* Hook that is called by summary when an edge is removed. */
1096 : : void remove (cgraph_edge *cs, ipa_edge_args *args) final override;
1097 : : /* Hook that is called by summary when an edge is duplicated. */
1098 : : void duplicate (cgraph_edge *src,
1099 : : cgraph_edge *dst,
1100 : : ipa_edge_args *old_args,
1101 : : ipa_edge_args *new_args) final override;
1102 : : };
1103 : :
1104 : : /* Function summary where the parameter infos are actually stored. */
1105 : : extern GTY(()) ipa_node_params_t * ipa_node_params_sum;
1106 : : /* Call summary to store information about edges such as jump functions. */
1107 : : extern GTY(()) ipa_edge_args_sum_t *ipa_edge_args_sum;
1108 : :
1109 : : /* Function summary for IPA-CP transformation. */
1110 : : class ipcp_transformation_t
1111 : : : public function_summary<ipcp_transformation *>
1112 : : {
1113 : : public:
1114 : 17983 : ipcp_transformation_t (symbol_table *table, bool ggc):
1115 : 35966 : function_summary<ipcp_transformation *> (table, ggc) {}
1116 : :
1117 : 17974 : ~ipcp_transformation_t () {}
1118 : :
1119 : 17983 : static ipcp_transformation_t *create_ggc (symbol_table *symtab)
1120 : : {
1121 : 17983 : ipcp_transformation_t *summary
1122 : 17983 : = new (ggc_alloc_no_dtor <ipcp_transformation_t> ())
1123 : 17983 : ipcp_transformation_t (symtab, true);
1124 : 17983 : return summary;
1125 : : }
1126 : : /* Hook that is called by summary when a node is duplicated. */
1127 : : void duplicate (cgraph_node *node,
1128 : : cgraph_node *node2,
1129 : : ipcp_transformation *data,
1130 : : ipcp_transformation *data2) final override;
1131 : : };
1132 : :
1133 : : /* Function summary where the IPA CP transformations are actually stored. */
1134 : : extern GTY(()) function_summary <ipcp_transformation *> *ipcp_transformation_sum;
1135 : :
1136 : : /* Creating and freeing ipa_node_params and ipa_edge_args. */
1137 : : void ipa_create_all_node_params (void);
1138 : : void ipa_create_all_edge_args (void);
1139 : : void ipa_check_create_edge_args (void);
1140 : : void ipa_free_all_node_params (void);
1141 : : void ipa_free_all_edge_args (void);
1142 : : void ipa_free_all_structures_after_ipa_cp (void);
1143 : : void ipa_free_all_structures_after_iinln (void);
1144 : :
1145 : : void ipa_register_cgraph_hooks (void);
1146 : : int count_formal_params (tree fndecl);
1147 : :
1148 : : /* This function ensures the array of node param infos is big enough to
1149 : : accommodate a structure for all nodes and reallocates it if not. */
1150 : :
1151 : : inline void
1152 : 7361206 : ipa_check_create_node_params (void)
1153 : : {
1154 : 7361206 : if (!ipa_node_params_sum)
1155 : 4637220 : ipa_node_params_sum
1156 : 9274440 : = (new (ggc_alloc_no_dtor <ipa_node_params_t> ())
1157 : 4637220 : ipa_node_params_t (symtab, true));
1158 : 7361206 : }
1159 : :
1160 : : /* Returns true if edge summary contains a record for EDGE. The main purpose
1161 : : of this function is that debug dumping function can check info availability
1162 : : without causing allocations. */
1163 : :
1164 : : inline bool
1165 : 1288 : ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
1166 : : {
1167 : 1288 : return ipa_edge_args_sum->exists (edge);
1168 : : }
1169 : :
1170 : : inline ipcp_transformation *
1171 : 14989943 : ipcp_get_transformation_summary (cgraph_node *node)
1172 : : {
1173 : 14989943 : if (ipcp_transformation_sum == NULL)
1174 : : return NULL;
1175 : :
1176 : 4340829 : return ipcp_transformation_sum->get (node);
1177 : : }
1178 : :
1179 : : /* Function formal parameters related computations. */
1180 : : void ipa_initialize_node_params (struct cgraph_node *node);
1181 : : bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
1182 : : vec<cgraph_edge *> *new_edges);
1183 : :
1184 : : /* Indirect edge processing and target discovery. */
1185 : : tree ipa_get_indirect_edge_target (struct cgraph_edge *ie,
1186 : : ipa_call_arg_values *avals,
1187 : : bool *speculative);
1188 : : struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree,
1189 : : bool speculative = false);
1190 : : tree ipa_impossible_devirt_target (struct cgraph_edge *, tree);
1191 : :
1192 : :
1193 : : /* Functions related to both. */
1194 : : void ipa_analyze_node (struct cgraph_node *);
1195 : :
1196 : : /* Aggregate jump function related functions. */
1197 : : tree ipa_find_agg_cst_from_init (tree scalar, HOST_WIDE_INT offset,
1198 : : bool by_ref);
1199 : : bool ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
1200 : : vec<ipa_param_descriptor, va_gc> *descriptors,
1201 : : gimple *stmt, tree op, int *index_p,
1202 : : HOST_WIDE_INT *offset_p, poly_int64 *size_p,
1203 : : bool *by_ref, bool *guaranteed_unmodified = NULL);
1204 : :
1205 : : /* Debugging interface. */
1206 : : void ipa_print_node_params (FILE *, struct cgraph_node *node);
1207 : : void ipa_print_all_params (FILE *);
1208 : : void ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node);
1209 : : void ipa_print_all_jump_functions (FILE * f);
1210 : : void ipcp_verify_propagated_values (void);
1211 : :
1212 : : template <typename value>
1213 : : class ipcp_value;
1214 : :
1215 : : extern object_allocator<ipcp_value<tree> > ipcp_cst_values_pool;
1216 : : extern object_allocator<ipcp_value<ipa_polymorphic_call_context> >
1217 : : ipcp_poly_ctx_values_pool;
1218 : :
1219 : : template <typename valtype>
1220 : : struct ipcp_value_source;
1221 : :
1222 : : extern object_allocator<ipcp_value_source<tree> > ipcp_sources_pool;
1223 : :
1224 : : struct ipcp_agg_lattice;
1225 : :
1226 : : extern object_allocator<ipcp_agg_lattice> ipcp_agg_lattice_pool;
1227 : :
1228 : : void ipa_prop_write_jump_functions (void);
1229 : : void ipa_prop_read_jump_functions (void);
1230 : : void ipcp_write_transformation_summaries (void);
1231 : : void ipcp_read_transformation_summaries (void);
1232 : : int ipa_get_param_decl_index (class ipa_node_params *, tree);
1233 : : tree ipa_value_from_jfunc (class ipa_node_params *info,
1234 : : struct ipa_jump_func *jfunc, tree type);
1235 : : tree ipa_agg_value_from_jfunc (ipa_node_params *info, cgraph_node *node,
1236 : : const ipa_agg_jf_item *item);
1237 : : unsigned int ipcp_transform_function (struct cgraph_node *node);
1238 : : ipa_polymorphic_call_context ipa_context_from_jfunc (ipa_node_params *,
1239 : : cgraph_edge *,
1240 : : int,
1241 : : ipa_jump_func *);
1242 : : void ipa_value_range_from_jfunc (vrange &, ipa_node_params *, cgraph_edge *,
1243 : : ipa_jump_func *, tree);
1244 : : void ipa_push_agg_values_from_jfunc (ipa_node_params *info, cgraph_node *node,
1245 : : ipa_agg_jump_function *agg_jfunc,
1246 : : unsigned dst_index,
1247 : : vec<ipa_argagg_value> *res);
1248 : : void ipa_dump_param (FILE *, class ipa_node_params *info, int i);
1249 : : void ipa_release_body_info (struct ipa_func_body_info *);
1250 : : tree ipa_get_callee_param_type (struct cgraph_edge *e, int i);
1251 : : bool ipcp_get_parm_bits (tree, tree *, widest_int *);
1252 : : tree ipcp_get_aggregate_const (struct function *func, tree parm, bool by_ref,
1253 : : HOST_WIDE_INT bit_offset,
1254 : : HOST_WIDE_INT bit_size);
1255 : : bool unadjusted_ptr_and_unit_offset (tree op, tree *ret,
1256 : : poly_int64 *offset_ret);
1257 : :
1258 : : void ipa_prop_cc_finalize (void);
1259 : :
1260 : : /* From tree-sra.cc: */
1261 : : tree build_ref_for_offset (location_t, tree, poly_int64, bool, tree,
1262 : : gimple_stmt_iterator *, bool);
1263 : :
1264 : : /* In ipa-cp.cc */
1265 : : void ipa_cp_cc_finalize (void);
1266 : :
1267 : : /* Set R to the range of [VAL, VAL] while normalizing addresses to
1268 : : non-zero. */
1269 : :
1270 : : inline void
1271 : 877046 : ipa_range_set_and_normalize (vrange &r, tree val)
1272 : : {
1273 : 877046 : if (TREE_CODE (val) == ADDR_EXPR)
1274 : 751 : r.set_nonzero (TREE_TYPE (val));
1275 : : else
1276 : 876295 : r.set (val, val);
1277 : 877046 : }
1278 : :
1279 : : bool ipa_return_value_range (Value_Range &range, tree decl);
1280 : : void ipa_record_return_value_range (Value_Range val);
1281 : :
1282 : : #endif /* IPA_PROP_H */
|