Branch data Line data Source code
1 : : /* IPA predicates.
2 : : Copyright (C) 2003-2025 Free Software Foundation, Inc.
3 : : Contributed by Jan Hubicka
4 : :
5 : : This file is part of GCC.
6 : :
7 : : GCC is free software; you can redistribute it and/or modify it under
8 : : the terms of the GNU General Public License as published by the Free
9 : : Software Foundation; either version 3, or (at your option) any later
10 : : version.
11 : :
12 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : : for more details.
16 : :
17 : : You should have received a copy of the GNU General Public License
18 : : along with GCC; see the file COPYING3. If not see
19 : : <http://www.gnu.org/licenses/>. */
20 : :
21 : : #include "config.h"
22 : : #include "system.h"
23 : : #include "coretypes.h"
24 : : #include "backend.h"
25 : : #include "tree.h"
26 : : #include "cgraph.h"
27 : : #include "tree-vrp.h"
28 : : #include "alloc-pool.h"
29 : : #include "symbol-summary.h"
30 : : #include "sreal.h"
31 : : #include "ipa-cp.h"
32 : : #include "ipa-prop.h"
33 : : #include "ipa-fnsummary.h"
34 : : #include "real.h"
35 : : #include "fold-const.h"
36 : : #include "tree-pretty-print.h"
37 : : #include "gimple.h"
38 : : #include "gimplify.h"
39 : : #include "data-streamer.h"
40 : :
41 : :
42 : : /* Check whether two set of operations have same effects. */
43 : : static bool
44 : 14126799 : expr_eval_ops_equal_p (expr_eval_ops ops1, expr_eval_ops ops2)
45 : : {
46 : 14126799 : if (ops1)
47 : : {
48 : 1121093 : if (!ops2 || ops1->length () != ops2->length ())
49 : : return false;
50 : :
51 : 1567852 : for (unsigned i = 0; i < ops1->length (); i++)
52 : : {
53 : 1086790 : expr_eval_op &op1 = (*ops1)[i];
54 : 1086790 : expr_eval_op &op2 = (*ops2)[i];
55 : :
56 : 1086790 : if (op1.code != op2.code
57 : 957126 : || op1.index != op2.index
58 : 957126 : || !vrp_operand_equal_p (op1.val[0], op2.val[0])
59 : 692356 : || !vrp_operand_equal_p (op1.val[1], op2.val[1])
60 : 1779146 : || !types_compatible_p (op1.type, op2.type))
61 : 395589 : return false;
62 : : }
63 : : return true;
64 : : }
65 : 13005706 : return !ops2;
66 : : }
67 : :
68 : : /* Add clause CLAUSE into the predicate P.
69 : : When CONDITIONS is NULL do not perform checking whether NEW_CLAUSE
70 : : is obviously true. This is useful only when NEW_CLAUSE is known to be
71 : : sane. */
72 : :
73 : : void
74 : 49818757 : ipa_predicate::add_clause (conditions conditions, clause_t new_clause)
75 : : {
76 : 49818757 : int i;
77 : 49818757 : int i2;
78 : 49818757 : int insert_here = -1;
79 : 49818757 : int c1, c2;
80 : :
81 : : /* True clause. */
82 : 49818757 : if (!new_clause)
83 : : return;
84 : :
85 : : /* False clause makes the whole predicate false. Kill the other variants. */
86 : 49818757 : if (new_clause == (1 << ipa_predicate::false_condition))
87 : : {
88 : 0 : *this = false;
89 : 0 : return;
90 : : }
91 : 49818757 : if (*this == false)
92 : : return;
93 : :
94 : : /* No one should be silly enough to add false into nontrivial clauses. */
95 : 49818757 : gcc_checking_assert (!(new_clause & (1 << ipa_predicate::false_condition)));
96 : :
97 : : /* Look where to insert the new_clause. At the same time prune out
98 : : new_clauses of P that are implied by the new new_clause and thus
99 : : redundant. */
100 : 135802990 : for (i = 0, i2 = 0; i <= max_clauses; i++)
101 : : {
102 : 135802990 : m_clause[i2] = m_clause[i];
103 : :
104 : 135802990 : if (!m_clause[i])
105 : : break;
106 : :
107 : : /* If m_clause[i] implies new_clause, there is nothing to add. */
108 : 98182020 : if ((m_clause[i] & new_clause) == m_clause[i])
109 : : {
110 : : /* We had nothing to add, none of clauses should've become
111 : : redundant. */
112 : 12197787 : gcc_checking_assert (i == i2);
113 : : return;
114 : : }
115 : :
116 : 85984233 : if (m_clause[i] < new_clause && insert_here < 0)
117 : 85984233 : insert_here = i2;
118 : :
119 : : /* If new_clause implies clause[i], then clause[i] becomes redundant.
120 : : Otherwise the clause[i] has to stay. */
121 : 85984233 : if ((m_clause[i] & new_clause) != new_clause)
122 : 82559631 : i2++;
123 : : }
124 : :
125 : : /* Look for clauses that are obviously true. I.e.
126 : : op0 == 5 || op0 != 5. */
127 : 37620970 : if (conditions)
128 : 299721013 : for (c1 = ipa_predicate::first_dynamic_condition;
129 : 311057393 : c1 < num_conditions; c1++)
130 : : {
131 : 301161829 : condition *cc1;
132 : 301161829 : if (!(new_clause & (1 << c1)))
133 : 268599967 : continue;
134 : 32561862 : cc1 = &(*conditions)[c1 - ipa_predicate::first_dynamic_condition];
135 : : /* We have no way to represent !changed and !is_not_constant
136 : : and thus there is no point for looking for them. */
137 : 32561862 : if (cc1->code == changed || cc1->code == is_not_constant || cc1->code == not_sra_candidate)
138 : 6618479 : continue;
139 : 566891887 : for (c2 = c1 + 1; c2 < num_conditions; c2++)
140 : 542389320 : if (new_clause & (1 << c2))
141 : : {
142 : 52898225 : condition *cc2 =
143 : 52898225 : &(*conditions)[c2 - ipa_predicate::first_dynamic_condition];
144 : 52898225 : if (cc1->operand_num == cc2->operand_num
145 : 46919141 : && vrp_operand_equal_p (cc1->val, cc2->val)
146 : 2898200 : && cc2->code != is_not_constant
147 : 2898200 : && cc2->code != not_sra_candidate
148 : 2898200 : && cc2->code != changed
149 : 2898200 : && expr_eval_ops_equal_p (cc1->param_ops, cc2->param_ops)
150 : 2113953 : && cc2->agg_contents == cc1->agg_contents
151 : 1951501 : && cc2->by_ref == cc1->by_ref
152 : 1949721 : && types_compatible_p (cc2->type, cc1->type)
153 : 54774451 : && cc1->code == invert_tree_comparison (cc2->code,
154 : 1876226 : HONOR_NANS (cc1->val)))
155 : : return;
156 : : }
157 : : }
158 : :
159 : :
160 : : /* We run out of variants. Be conservative in positive direction. */
161 : 36180154 : if (i2 == max_clauses)
162 : : return;
163 : : /* Keep clauses in decreasing order. This makes equivalence testing easy. */
164 : 35790878 : m_clause[i2 + 1] = 0;
165 : 35790878 : if (insert_here >= 0)
166 : 43652427 : for (; i2 > insert_here; i2--)
167 : 25535669 : m_clause[i2] = m_clause[i2 - 1];
168 : : else
169 : : insert_here = i2;
170 : 35790878 : m_clause[insert_here] = new_clause;
171 : : }
172 : :
173 : :
174 : : /* Do THIS &= P. */
175 : :
176 : : ipa_predicate &
177 : 440444865 : ipa_predicate::operator &= (const ipa_predicate &p)
178 : : {
179 : : /* Avoid busy work. */
180 : 440444865 : if (p == false || *this == true)
181 : : {
182 : 342397583 : *this = p;
183 : 342397583 : return *this;
184 : : }
185 : 98047282 : if (*this == false || p == true || this == &p)
186 : : return *this;
187 : :
188 : : int i;
189 : :
190 : : /* See how far ipa_predicates match. */
191 : 69358425 : for (i = 0; m_clause[i] && m_clause[i] == p.m_clause[i]; i++)
192 : : {
193 : 27013515 : gcc_checking_assert (i < max_clauses);
194 : : }
195 : :
196 : : /* Combine the ipa_predicates rest. */
197 : 74704881 : for (; p.m_clause[i]; i++)
198 : : {
199 : 32359971 : gcc_checking_assert (i < max_clauses);
200 : 32359971 : add_clause (NULL, p.m_clause[i]);
201 : : }
202 : : return *this;
203 : : }
204 : :
205 : :
206 : :
207 : : /* Return THIS | P2. */
208 : :
209 : : ipa_predicate
210 : 120677481 : ipa_predicate::or_with (conditions conditions,
211 : : const ipa_predicate &p) const
212 : : {
213 : : /* Avoid busy work. */
214 : 120677481 : if (p == false || *this == true || *this == p)
215 : 15027345 : return *this;
216 : 105650136 : if (*this == false || p == true)
217 : 100971705 : return p;
218 : :
219 : : /* OK, combine the predicates. */
220 : 4678431 : ipa_predicate out = true;
221 : :
222 : 12104010 : for (int i = 0; m_clause[i]; i++)
223 : 24657833 : for (int j = 0; p.m_clause[j]; j++)
224 : : {
225 : 17232254 : gcc_checking_assert (i < max_clauses && j < max_clauses);
226 : 17232254 : out.add_clause (conditions, m_clause[i] | p.m_clause[j]);
227 : : }
228 : 4678431 : return out;
229 : : }
230 : :
231 : :
232 : : /* Having partial truth assignment in POSSIBLE_TRUTHS, return false
233 : : if predicate P is known to be false. */
234 : :
235 : : bool
236 : 255493304 : ipa_predicate::evaluate (clause_t possible_truths) const
237 : : {
238 : 255493304 : int i;
239 : :
240 : : /* True remains true. */
241 : 255493304 : if (*this == true)
242 : : return true;
243 : :
244 : 195765554 : gcc_assert (!(possible_truths & (1 << ipa_predicate::false_condition)));
245 : :
246 : : /* See if we can find clause we can disprove. */
247 : 444090380 : for (i = 0; m_clause[i]; i++)
248 : : {
249 : 308904166 : gcc_checking_assert (i < max_clauses);
250 : 308904166 : if (!(m_clause[i] & possible_truths))
251 : : return false;
252 : : }
253 : : return true;
254 : : }
255 : :
256 : : /* Return the probability in range 0...REG_BR_PROB_BASE that the predicated
257 : : instruction will be recomputed per invocation of the inlined call. */
258 : :
259 : : int
260 : 29713038 : ipa_predicate::probability (conditions conds,
261 : : clause_t possible_truths,
262 : : vec<inline_param_summary> inline_param_summary) const
263 : : {
264 : 29713038 : int i;
265 : 29713038 : int combined_prob = REG_BR_PROB_BASE;
266 : :
267 : : /* True remains true. */
268 : 29713038 : if (*this == true)
269 : : return REG_BR_PROB_BASE;
270 : :
271 : 19582377 : if (*this == false)
272 : : return 0;
273 : :
274 : 19582377 : gcc_assert (!(possible_truths & (1 << ipa_predicate::false_condition)));
275 : :
276 : : /* See if we can find clause we can disprove. */
277 : 47452549 : for (i = 0; m_clause[i]; i++)
278 : : {
279 : 31738010 : gcc_checking_assert (i < max_clauses);
280 : 31738010 : if (!(m_clause[i] & possible_truths))
281 : : return 0;
282 : : else
283 : : {
284 : 31738010 : int this_prob = 0;
285 : 31738010 : int i2;
286 : 31738010 : if (!inline_param_summary.exists ())
287 : : return REG_BR_PROB_BASE;
288 : 1047346377 : for (i2 = 0; i2 < num_conditions; i2++)
289 : 1015608608 : if ((m_clause[i] & possible_truths) & (1 << i2))
290 : : {
291 : 38856795 : if (i2 >= ipa_predicate::first_dynamic_condition)
292 : : {
293 : 38856795 : condition *c =
294 : 38856795 : &(*conds)[i2 - ipa_predicate::first_dynamic_condition];
295 : 38856795 : if (c->code == ipa_predicate::changed
296 : 38856795 : && (c->operand_num <
297 : 16253719 : (int) inline_param_summary.length ()))
298 : : {
299 : 16253672 : int iprob =
300 : 16253672 : inline_param_summary[c->operand_num].change_prob;
301 : 1015608608 : this_prob = MAX (this_prob, iprob);
302 : : }
303 : : else
304 : : this_prob = REG_BR_PROB_BASE;
305 : : }
306 : : else
307 : : this_prob = REG_BR_PROB_BASE;
308 : : }
309 : 31737769 : combined_prob = MIN (this_prob, combined_prob);
310 : 31737769 : if (!combined_prob)
311 : : return 0;
312 : : }
313 : : }
314 : : return combined_prob;
315 : : }
316 : :
317 : :
318 : : /* Dump conditional COND. */
319 : :
320 : : void
321 : 14068 : dump_condition (FILE *f, conditions conditions, int cond)
322 : : {
323 : 14068 : condition *c;
324 : 14068 : if (cond == ipa_predicate::false_condition)
325 : 2551 : fprintf (f, "false");
326 : 11517 : else if (cond == ipa_predicate::not_inlined_condition)
327 : 3289 : fprintf (f, "not inlined");
328 : : else
329 : : {
330 : 8228 : c = &(*conditions)[cond - ipa_predicate::first_dynamic_condition];
331 : 8228 : fprintf (f, "op%i", c->operand_num);
332 : 8228 : if (c->agg_contents)
333 : 1535 : fprintf (f, "[%soffset: " HOST_WIDE_INT_PRINT_DEC "]",
334 : 1535 : c->by_ref ? "ref " : "", c->offset);
335 : :
336 : 9252 : for (unsigned i = 0; i < vec_safe_length (c->param_ops); i++)
337 : : {
338 : 1024 : expr_eval_op &op = (*(c->param_ops))[i];
339 : 1024 : const char *op_name = op_symbol_code (op.code);
340 : :
341 : 1024 : if (op_name == op_symbol_code (ERROR_MARK))
342 : 288 : op_name = get_tree_code_name (op.code);
343 : :
344 : 1024 : fprintf (f, ",(");
345 : :
346 : 1024 : if (!op.val[0])
347 : : {
348 : 288 : switch (op.code)
349 : : {
350 : 288 : case FLOAT_EXPR:
351 : 288 : case FIX_TRUNC_EXPR:
352 : 288 : case FIXED_CONVERT_EXPR:
353 : 288 : case VIEW_CONVERT_EXPR:
354 : 288 : CASE_CONVERT:
355 : 288 : if (op.code == VIEW_CONVERT_EXPR)
356 : 0 : fprintf (f, "VCE");
357 : 288 : fprintf (f, "(");
358 : 288 : print_generic_expr (f, op.type);
359 : 288 : fprintf (f, ")" );
360 : 288 : break;
361 : :
362 : 0 : default:
363 : 0 : fprintf (f, "%s", op_name);
364 : : }
365 : 288 : fprintf (f, " #");
366 : : }
367 : 736 : else if (!op.val[1])
368 : : {
369 : 736 : if (op.index)
370 : : {
371 : 48 : print_generic_expr (f, op.val[0]);
372 : 48 : fprintf (f, " %s #", op_name);
373 : : }
374 : : else
375 : : {
376 : 688 : fprintf (f, "# %s ", op_name);
377 : 688 : print_generic_expr (f, op.val[0]);
378 : : }
379 : : }
380 : : else
381 : : {
382 : 0 : fprintf (f, "%s ", op_name);
383 : 0 : switch (op.index)
384 : : {
385 : 0 : case 0:
386 : 0 : fprintf (f, "#, ");
387 : 0 : print_generic_expr (f, op.val[0]);
388 : 0 : fprintf (f, ", ");
389 : 0 : print_generic_expr (f, op.val[1]);
390 : 0 : break;
391 : :
392 : 0 : case 1:
393 : 0 : print_generic_expr (f, op.val[0]);
394 : 0 : fprintf (f, ", #, ");
395 : 0 : print_generic_expr (f, op.val[1]);
396 : 0 : break;
397 : :
398 : 0 : case 2:
399 : 0 : print_generic_expr (f, op.val[0]);
400 : 0 : fprintf (f, ", ");
401 : 0 : print_generic_expr (f, op.val[1]);
402 : 0 : fprintf (f, ", #");
403 : 0 : break;
404 : :
405 : 0 : default:
406 : 0 : fprintf (f, "*, *, *");
407 : : }
408 : : }
409 : 1024 : fprintf (f, ")");
410 : : }
411 : :
412 : 8228 : if (c->code == ipa_predicate::is_not_constant)
413 : : {
414 : 18 : fprintf (f, " not constant");
415 : 18 : return;
416 : : }
417 : 8210 : if (c->code == ipa_predicate::changed)
418 : : {
419 : 1778 : fprintf (f, " changed");
420 : 1778 : return;
421 : : }
422 : 6432 : if (c->code == ipa_predicate::not_sra_candidate)
423 : : {
424 : 1704 : fprintf (f, " not sra candidate");
425 : 1704 : return;
426 : : }
427 : 4728 : fprintf (f, " %s ", op_symbol_code (c->code));
428 : 4728 : print_generic_expr (f, c->val);
429 : : }
430 : : }
431 : :
432 : :
433 : : /* Dump clause CLAUSE. */
434 : :
435 : : static void
436 : 15691 : dump_clause (FILE *f, conditions conds, clause_t clause)
437 : : {
438 : 15691 : int i;
439 : 15691 : bool found = false;
440 : 15691 : fprintf (f, "(");
441 : 15691 : if (!clause)
442 : 3442 : fprintf (f, "true");
443 : 517803 : for (i = 0; i < ipa_predicate::num_conditions; i++)
444 : 502112 : if (clause & (1 << i))
445 : : {
446 : 12681 : if (found)
447 : 432 : fprintf (f, " || ");
448 : 12681 : found = true;
449 : 12681 : dump_condition (f, conds, i);
450 : : }
451 : 15691 : fprintf (f, ")");
452 : 15691 : }
453 : :
454 : :
455 : : /* Dump THIS to F. CONDS a vector of conditions used when evaluating
456 : : ipa_predicates. When NL is true new line is output at the end of dump. */
457 : :
458 : : void
459 : 12462 : ipa_predicate::dump (FILE *f, conditions conds, bool nl) const
460 : : {
461 : 12462 : int i;
462 : 12462 : if (*this == true)
463 : 3442 : dump_clause (f, conds, 0);
464 : : else
465 : 21269 : for (i = 0; m_clause[i]; i++)
466 : : {
467 : 12249 : if (i)
468 : 3229 : fprintf (f, " && ");
469 : 12249 : dump_clause (f, conds, m_clause[i]);
470 : : }
471 : 12462 : if (nl)
472 : 4908 : fprintf (f, "\n");
473 : 12462 : }
474 : :
475 : :
476 : : void
477 : 0 : ipa_predicate::debug (conditions conds) const
478 : : {
479 : 0 : dump (stderr, conds);
480 : 0 : }
481 : :
482 : :
483 : : /* Remap predicate THIS of former function to be predicate of duplicated function.
484 : : POSSIBLE_TRUTHS is clause of possible truths in the duplicated node,
485 : : INFO is inline summary of the duplicated node. */
486 : :
487 : : ipa_predicate
488 : 176320 : ipa_predicate::remap_after_duplication (clause_t possible_truths)
489 : : {
490 : 176320 : int j;
491 : 176320 : ipa_predicate out = true;
492 : 402852 : for (j = 0; m_clause[j]; j++)
493 : 245100 : if (!(possible_truths & m_clause[j]))
494 : 18568 : return false;
495 : : else
496 : 226532 : out.add_clause (NULL, possible_truths & m_clause[j]);
497 : 157752 : return out;
498 : : }
499 : :
500 : :
501 : : /* Translate all conditions from callee representation into caller
502 : : representation and symbolically evaluate predicate THIS into new predicate.
503 : :
504 : : INFO is ipa_fn_summary of function we are adding predicate into, CALLEE_INFO
505 : : is summary of function predicate P is from. OPERAND_MAP is array giving
506 : : callee formal IDs the caller formal IDs. POSSSIBLE_TRUTHS is clause of all
507 : : callee conditions that may be true in caller context. TOPLEV_PREDICATE is
508 : : predicate under which callee is executed. OFFSET_MAP is an array of
509 : : offsets that need to be added to conditions, negative offset means that
510 : : conditions relying on values passed by reference have to be discarded
511 : : because they might not be preserved (and should be considered offset zero
512 : : for other purposes). */
513 : :
514 : : ipa_predicate
515 : 36556756 : ipa_predicate::remap_after_inlining (class ipa_fn_summary *info,
516 : : class ipa_node_params *params_summary,
517 : : class ipa_fn_summary *callee_info,
518 : : const vec<int> &operand_map,
519 : : const vec<HOST_WIDE_INT> &offset_map,
520 : : clause_t possible_truths,
521 : : const ipa_predicate &toplev_predicate)
522 : : {
523 : 36556756 : int i;
524 : 36556756 : ipa_predicate out = true;
525 : :
526 : : /* True ipa_predicate is easy. */
527 : 36556756 : if (*this == true)
528 : 9438827 : return toplev_predicate;
529 : 70026852 : for (i = 0; m_clause[i]; i++)
530 : : {
531 : 42908923 : clause_t clause = m_clause[i];
532 : 42908923 : int cond;
533 : 42908923 : ipa_predicate clause_predicate = false;
534 : :
535 : 42908923 : gcc_assert (i < max_clauses);
536 : :
537 : 1415994459 : for (cond = 0; cond < num_conditions; cond++)
538 : : /* Do we have condition we can't disprove? */
539 : 1373085536 : if (clause & possible_truths & (1 << cond))
540 : : {
541 : 24421701 : ipa_predicate cond_predicate;
542 : : /* Work out if the condition can translate to predicate in the
543 : : inlined function. */
544 : 24421701 : if (cond >= ipa_predicate::first_dynamic_condition)
545 : : {
546 : 24421701 : struct condition *c;
547 : :
548 : 24421701 : int index = cond - ipa_predicate::first_dynamic_condition;
549 : 24421701 : c = &(*callee_info->conds)[index];
550 : : /* See if we can remap condition operand to caller's operand.
551 : : Otherwise give up. */
552 : 24421701 : if (!operand_map.exists ()
553 : 24421701 : || (int) operand_map.length () <= c->operand_num
554 : 10942313 : || operand_map[c->operand_num] == -1
555 : : /* TODO: For non-aggregate conditions, adding an offset is
556 : : basically an arithmetic jump function processing which
557 : : we should support in future. */
558 : 3631941 : || ((!c->agg_contents || !c->by_ref)
559 : 1918918 : && offset_map[c->operand_num] > 0)
560 : 27948623 : || (c->agg_contents && c->by_ref
561 : 1713023 : && offset_map[c->operand_num] < 0))
562 : 21757069 : cond_predicate = true;
563 : : else
564 : : {
565 : 2664632 : struct agg_position_info ap;
566 : 2664632 : HOST_WIDE_INT offset_delta = offset_map[c->operand_num];
567 : 2664632 : if (offset_delta < 0)
568 : : {
569 : 1249363 : gcc_checking_assert (!c->agg_contents || !c->by_ref);
570 : : offset_delta = 0;
571 : : }
572 : 2664632 : gcc_assert (!c->agg_contents
573 : : || c->by_ref || offset_delta == 0);
574 : 2664632 : ap.offset = c->offset + offset_delta;
575 : 2664632 : ap.agg_contents = c->agg_contents;
576 : 2664632 : ap.by_ref = c->by_ref;
577 : 5329264 : cond_predicate = add_condition (info, params_summary,
578 : 2664632 : operand_map[c->operand_num],
579 : 2664632 : c->type, &ap, c->code,
580 : : c->val, c->param_ops);
581 : : }
582 : : }
583 : : /* Fixed conditions remains same, construct single
584 : : condition predicate. */
585 : : else
586 : 0 : cond_predicate = ipa_predicate::predicate_testing_cond (cond);
587 : 24421701 : clause_predicate = clause_predicate.or_with (info->conds,
588 : : cond_predicate);
589 : : }
590 : 42908923 : out &= clause_predicate;
591 : : }
592 : 27117929 : out &= toplev_predicate;
593 : 27117929 : return out;
594 : : }
595 : :
596 : :
597 : : /* Read predicate from IB. */
598 : :
599 : : void
600 : 818121 : ipa_predicate::stream_in (class lto_input_block *ib)
601 : : {
602 : 818121 : clause_t clause;
603 : 818121 : int k = 0;
604 : :
605 : 1166901 : do
606 : : {
607 : 1166901 : gcc_assert (k <= max_clauses);
608 : 1166901 : clause = m_clause[k++] = streamer_read_uhwi (ib);
609 : : }
610 : 1166901 : while (clause);
611 : :
612 : : /* Zero-initialize the remaining clauses in OUT. */
613 : 7014309 : while (k <= max_clauses)
614 : 6196188 : m_clause[k++] = 0;
615 : 818121 : }
616 : :
617 : :
618 : : /* Write predicate P to OB. */
619 : :
620 : : void
621 : 580646 : ipa_predicate::stream_out (struct output_block *ob)
622 : : {
623 : 580646 : int j;
624 : 1008142 : for (j = 0; m_clause[j]; j++)
625 : : {
626 : 427496 : gcc_assert (j < max_clauses);
627 : 427496 : streamer_write_uhwi (ob, m_clause[j]);
628 : : }
629 : 580646 : streamer_write_uhwi (ob, 0);
630 : 580646 : }
631 : :
632 : :
633 : : /* Add condition to condition list SUMMARY. OPERAND_NUM, TYPE, CODE, VAL and
634 : : PARAM_OPS correspond to fields of condition structure. AGGPOS describes
635 : : whether the used operand is loaded from an aggregate and where in the
636 : : aggregate it is. It can be NULL, which means this not a load from an
637 : : aggregate. */
638 : :
639 : : ipa_predicate
640 : 21028334 : add_condition (class ipa_fn_summary *summary,
641 : : class ipa_node_params *params_summary,
642 : : int operand_num,
643 : : tree type, struct agg_position_info *aggpos,
644 : : enum tree_code code, tree val, expr_eval_ops param_ops)
645 : : {
646 : 21028334 : int i, j;
647 : 21028334 : struct condition *c;
648 : 21028334 : struct condition new_cond;
649 : 21028334 : HOST_WIDE_INT offset;
650 : 21028334 : bool agg_contents, by_ref;
651 : 21028334 : expr_eval_op *op;
652 : :
653 : 21028334 : if (params_summary)
654 : 7697289 : ipa_set_param_used_by_ipa_predicates (params_summary, operand_num, true);
655 : :
656 : 21028334 : if (aggpos)
657 : : {
658 : 8396084 : offset = aggpos->offset;
659 : 8396084 : agg_contents = aggpos->agg_contents;
660 : 8396084 : by_ref = aggpos->by_ref;
661 : : }
662 : : else
663 : : {
664 : : offset = 0;
665 : : agg_contents = false;
666 : : by_ref = false;
667 : : }
668 : :
669 : 21028334 : gcc_checking_assert (operand_num >= 0);
670 : 97331978 : for (i = 0; vec_safe_iterate (summary->conds, i, &c); i++)
671 : : {
672 : 85608707 : if (c->operand_num == operand_num
673 : 43312759 : && c->code == code
674 : 16701831 : && types_compatible_p (c->type, type)
675 : 14909963 : && vrp_operand_equal_p (c->val, val)
676 : 11637005 : && c->agg_contents == agg_contents
677 : 11228599 : && expr_eval_ops_equal_p (c->param_ops, param_ops)
678 : 96681012 : && (!agg_contents || (c->offset == offset && c->by_ref == by_ref)))
679 : 9305063 : return ipa_predicate::predicate_testing_cond (i);
680 : : }
681 : : /* Too many conditions. Give up and return constant true. */
682 : 11723271 : if (i == ipa_predicate::num_conditions - ipa_predicate::first_dynamic_condition)
683 : 280391 : return true;
684 : :
685 : 11442880 : new_cond.operand_num = operand_num;
686 : 11442880 : new_cond.code = code;
687 : 11442880 : new_cond.type = unshare_expr_without_location (type);
688 : 11442880 : new_cond.val = val ? unshare_expr_without_location (val) : val;
689 : 11442880 : new_cond.agg_contents = agg_contents;
690 : 11442880 : new_cond.by_ref = by_ref;
691 : 11442880 : new_cond.offset = offset;
692 : 11442880 : new_cond.param_ops = vec_safe_copy (param_ops);
693 : :
694 : 11977193 : for (j = 0; vec_safe_iterate (new_cond.param_ops, j, &op); j++)
695 : : {
696 : 534313 : if (op->val[0])
697 : 301735 : op->val[0] = unshare_expr_without_location (op->val[0]);
698 : 534313 : if (op->val[1])
699 : 24 : op->val[1] = unshare_expr_without_location (op->val[1]);
700 : : }
701 : :
702 : 11442880 : vec_safe_push (summary->conds, new_cond);
703 : :
704 : 11442880 : return ipa_predicate::predicate_testing_cond (i);
705 : : }
|