Mercurial > hg > CbC > CbC_gcc
comparison gcc/ipa-predicate.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 /* IPA predicates. | 1 /* IPA predicates. |
2 Copyright (C) 2003-2018 Free Software Foundation, Inc. | 2 Copyright (C) 2003-2020 Free Software Foundation, Inc. |
3 Contributed by Jan Hubicka | 3 Contributed by Jan Hubicka |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it under | 7 GCC is free software; you can redistribute it and/or modify it under |
23 #include "coretypes.h" | 23 #include "coretypes.h" |
24 #include "backend.h" | 24 #include "backend.h" |
25 #include "tree.h" | 25 #include "tree.h" |
26 #include "cgraph.h" | 26 #include "cgraph.h" |
27 #include "tree-vrp.h" | 27 #include "tree-vrp.h" |
28 #include "alloc-pool.h" | |
28 #include "symbol-summary.h" | 29 #include "symbol-summary.h" |
29 #include "alloc-pool.h" | |
30 #include "ipa-prop.h" | 30 #include "ipa-prop.h" |
31 #include "ipa-fnsummary.h" | 31 #include "ipa-fnsummary.h" |
32 #include "real.h" | 32 #include "real.h" |
33 #include "fold-const.h" | 33 #include "fold-const.h" |
34 #include "tree-pretty-print.h" | 34 #include "tree-pretty-print.h" |
35 #include "gimple.h" | 35 #include "gimple.h" |
36 #include "gimplify.h" | |
36 #include "data-streamer.h" | 37 #include "data-streamer.h" |
37 | 38 |
39 | |
40 /* Check whether two set of operations have same effects. */ | |
41 static bool | |
42 expr_eval_ops_equal_p (expr_eval_ops ops1, expr_eval_ops ops2) | |
43 { | |
44 if (ops1) | |
45 { | |
46 if (!ops2 || ops1->length () != ops2->length ()) | |
47 return false; | |
48 | |
49 for (unsigned i = 0; i < ops1->length (); i++) | |
50 { | |
51 expr_eval_op &op1 = (*ops1)[i]; | |
52 expr_eval_op &op2 = (*ops2)[i]; | |
53 | |
54 if (op1.code != op2.code | |
55 || op1.index != op2.index | |
56 || !vrp_operand_equal_p (op1.val[0], op2.val[0]) | |
57 || !vrp_operand_equal_p (op1.val[1], op2.val[1]) | |
58 || !types_compatible_p (op1.type, op2.type)) | |
59 return false; | |
60 } | |
61 return true; | |
62 } | |
63 return !ops2; | |
64 } | |
38 | 65 |
39 /* Add clause CLAUSE into the predicate P. | 66 /* Add clause CLAUSE into the predicate P. |
40 When CONDITIONS is NULL do not perform checking whether NEW_CLAUSE | 67 When CONDITIONS is NULL do not perform checking whether NEW_CLAUSE |
41 is obviously true. This is useful only when NEW_CLAUSE is known to be | 68 is obviously true. This is useful only when NEW_CLAUSE is known to be |
42 sane. */ | 69 sane. */ |
108 if (cc1->code == changed || cc1->code == is_not_constant) | 135 if (cc1->code == changed || cc1->code == is_not_constant) |
109 continue; | 136 continue; |
110 for (c2 = c1 + 1; c2 < num_conditions; c2++) | 137 for (c2 = c1 + 1; c2 < num_conditions; c2++) |
111 if (new_clause & (1 << c2)) | 138 if (new_clause & (1 << c2)) |
112 { | 139 { |
113 condition *cc1 = | |
114 &(*conditions)[c1 - predicate::first_dynamic_condition]; | |
115 condition *cc2 = | 140 condition *cc2 = |
116 &(*conditions)[c2 - predicate::first_dynamic_condition]; | 141 &(*conditions)[c2 - predicate::first_dynamic_condition]; |
117 if (cc1->operand_num == cc2->operand_num | 142 if (cc1->operand_num == cc2->operand_num |
118 && cc1->val == cc2->val | 143 && vrp_operand_equal_p (cc1->val, cc2->val) |
119 && cc2->code != is_not_constant | 144 && cc2->code != is_not_constant |
120 && cc2->code != predicate::changed | 145 && cc2->code != changed |
146 && expr_eval_ops_equal_p (cc1->param_ops, cc2->param_ops) | |
147 && cc2->agg_contents == cc1->agg_contents | |
148 && cc2->by_ref == cc1->by_ref | |
149 && types_compatible_p (cc2->type, cc1->type) | |
121 && cc1->code == invert_tree_comparison (cc2->code, | 150 && cc1->code == invert_tree_comparison (cc2->code, |
122 HONOR_NANS (cc1->val))) | 151 HONOR_NANS (cc1->val))) |
123 return; | 152 return; |
124 } | 153 } |
125 } | 154 } |
298 c = &(*conditions)[cond - predicate::first_dynamic_condition]; | 327 c = &(*conditions)[cond - predicate::first_dynamic_condition]; |
299 fprintf (f, "op%i", c->operand_num); | 328 fprintf (f, "op%i", c->operand_num); |
300 if (c->agg_contents) | 329 if (c->agg_contents) |
301 fprintf (f, "[%soffset: " HOST_WIDE_INT_PRINT_DEC "]", | 330 fprintf (f, "[%soffset: " HOST_WIDE_INT_PRINT_DEC "]", |
302 c->by_ref ? "ref " : "", c->offset); | 331 c->by_ref ? "ref " : "", c->offset); |
332 | |
333 for (unsigned i = 0; i < vec_safe_length (c->param_ops); i++) | |
334 { | |
335 expr_eval_op &op = (*(c->param_ops))[i]; | |
336 const char *op_name = op_symbol_code (op.code); | |
337 | |
338 if (op_name == op_symbol_code (ERROR_MARK)) | |
339 op_name = get_tree_code_name (op.code); | |
340 | |
341 fprintf (f, ",("); | |
342 | |
343 if (!op.val[0]) | |
344 { | |
345 switch (op.code) | |
346 { | |
347 case FLOAT_EXPR: | |
348 case FIX_TRUNC_EXPR: | |
349 case FIXED_CONVERT_EXPR: | |
350 case VIEW_CONVERT_EXPR: | |
351 CASE_CONVERT: | |
352 if (op.code == VIEW_CONVERT_EXPR) | |
353 fprintf (f, "VCE"); | |
354 fprintf (f, "("); | |
355 print_generic_expr (f, op.type); | |
356 fprintf (f, ")" ); | |
357 break; | |
358 | |
359 default: | |
360 fprintf (f, "%s", op_name); | |
361 } | |
362 fprintf (f, " #"); | |
363 } | |
364 else if (!op.val[1]) | |
365 { | |
366 if (op.index) | |
367 { | |
368 print_generic_expr (f, op.val[0]); | |
369 fprintf (f, " %s #", op_name); | |
370 } | |
371 else | |
372 { | |
373 fprintf (f, "# %s ", op_name); | |
374 print_generic_expr (f, op.val[0]); | |
375 } | |
376 } | |
377 else | |
378 { | |
379 fprintf (f, "%s ", op_name); | |
380 switch (op.index) | |
381 { | |
382 case 0: | |
383 fprintf (f, "#, "); | |
384 print_generic_expr (f, op.val[0]); | |
385 fprintf (f, ", "); | |
386 print_generic_expr (f, op.val[1]); | |
387 break; | |
388 | |
389 case 1: | |
390 print_generic_expr (f, op.val[0]); | |
391 fprintf (f, ", #, "); | |
392 print_generic_expr (f, op.val[1]); | |
393 break; | |
394 | |
395 case 2: | |
396 print_generic_expr (f, op.val[0]); | |
397 fprintf (f, ", "); | |
398 print_generic_expr (f, op.val[1]); | |
399 fprintf (f, ", #"); | |
400 break; | |
401 | |
402 default: | |
403 fprintf (f, "*, *, *"); | |
404 } | |
405 } | |
406 fprintf (f, ")"); | |
407 } | |
408 | |
303 if (c->code == predicate::is_not_constant) | 409 if (c->code == predicate::is_not_constant) |
304 { | 410 { |
305 fprintf (f, " not constant"); | 411 fprintf (f, " not constant"); |
306 return; | 412 return; |
307 } | 413 } |
336 } | 442 } |
337 fprintf (f, ")"); | 443 fprintf (f, ")"); |
338 } | 444 } |
339 | 445 |
340 | 446 |
341 /* Dump THIS to F. CONDS a vector of conditions used when evauating | 447 /* Dump THIS to F. CONDS a vector of conditions used when evaluating |
342 predicats. When NL is true new line is output at the end of dump. */ | 448 predicates. When NL is true new line is output at the end of dump. */ |
343 | 449 |
344 void | 450 void |
345 predicate::dump (FILE *f, conditions conds, bool nl) const | 451 predicate::dump (FILE *f, conditions conds, bool nl) const |
346 { | 452 { |
347 int i; | 453 int i; |
387 /* Translate all conditions from callee representation into caller | 493 /* Translate all conditions from callee representation into caller |
388 representation and symbolically evaluate predicate THIS into new predicate. | 494 representation and symbolically evaluate predicate THIS into new predicate. |
389 | 495 |
390 INFO is ipa_fn_summary of function we are adding predicate into, CALLEE_INFO | 496 INFO is ipa_fn_summary of function we are adding predicate into, CALLEE_INFO |
391 is summary of function predicate P is from. OPERAND_MAP is array giving | 497 is summary of function predicate P is from. OPERAND_MAP is array giving |
392 callee formal IDs the caller formal IDs. POSSSIBLE_TRUTHS is clausule of all | 498 callee formal IDs the caller formal IDs. POSSSIBLE_TRUTHS is clause of all |
393 callee conditions that may be true in caller context. TOPLEV_PREDICATE is | 499 callee conditions that may be true in caller context. TOPLEV_PREDICATE is |
394 predicate under which callee is executed. OFFSET_MAP is an array of of | 500 predicate under which callee is executed. OFFSET_MAP is an array of of |
395 offsets that need to be added to conditions, negative offset means that | 501 offsets that need to be added to conditions, negative offset means that |
396 conditions relying on values passed by reference have to be discarded | 502 conditions relying on values passed by reference have to be discarded |
397 because they might not be preserved (and should be considered offset zero | 503 because they might not be preserved (and should be considered offset zero |
398 for other purposes). */ | 504 for other purposes). */ |
399 | 505 |
400 predicate | 506 predicate |
401 predicate::remap_after_inlining (struct ipa_fn_summary *info, | 507 predicate::remap_after_inlining (class ipa_fn_summary *info, |
402 struct ipa_fn_summary *callee_info, | 508 class ipa_node_params *params_summary, |
509 class ipa_fn_summary *callee_info, | |
403 vec<int> operand_map, | 510 vec<int> operand_map, |
404 vec<int> offset_map, | 511 vec<int> offset_map, |
405 clause_t possible_truths, | 512 clause_t possible_truths, |
406 const predicate &toplev_predicate) | 513 const predicate &toplev_predicate) |
407 { | 514 { |
458 gcc_assert (!c->agg_contents | 565 gcc_assert (!c->agg_contents |
459 || c->by_ref || offset_delta == 0); | 566 || c->by_ref || offset_delta == 0); |
460 ap.offset = c->offset + offset_delta; | 567 ap.offset = c->offset + offset_delta; |
461 ap.agg_contents = c->agg_contents; | 568 ap.agg_contents = c->agg_contents; |
462 ap.by_ref = c->by_ref; | 569 ap.by_ref = c->by_ref; |
463 cond_predicate = add_condition (info, | 570 cond_predicate = add_condition (info, params_summary, |
464 operand_map[c->operand_num], | 571 operand_map[c->operand_num], |
465 c->size, &ap, c->code, | 572 c->type, &ap, c->code, |
466 c->val); | 573 c->val, c->param_ops); |
467 } | 574 } |
468 } | 575 } |
469 /* Fixed conditions remains same, construct single | 576 /* Fixed conditions remains same, construct single |
470 condition predicate. */ | 577 condition predicate. */ |
471 else | 578 else |
481 | 588 |
482 | 589 |
483 /* Read predicate from IB. */ | 590 /* Read predicate from IB. */ |
484 | 591 |
485 void | 592 void |
486 predicate::stream_in (struct lto_input_block *ib) | 593 predicate::stream_in (class lto_input_block *ib) |
487 { | 594 { |
488 clause_t clause; | 595 clause_t clause; |
489 int k = 0; | 596 int k = 0; |
490 | 597 |
491 do | 598 do |
514 } | 621 } |
515 streamer_write_uhwi (ob, 0); | 622 streamer_write_uhwi (ob, 0); |
516 } | 623 } |
517 | 624 |
518 | 625 |
519 /* Add condition to condition list SUMMARY. OPERAND_NUM, SIZE, CODE and VAL | 626 /* Add condition to condition list SUMMARY. OPERAND_NUM, TYPE, CODE, VAL and |
520 correspond to fields of condition structure. AGGPOS describes whether the | 627 PARAM_OPS correspond to fields of condition structure. AGGPOS describes |
521 used operand is loaded from an aggregate and where in the aggregate it is. | 628 whether the used operand is loaded from an aggregate and where in the |
522 It can be NULL, which means this not a load from an aggregate. */ | 629 aggregate it is. It can be NULL, which means this not a load from an |
630 aggregate. */ | |
523 | 631 |
524 predicate | 632 predicate |
525 add_condition (struct ipa_fn_summary *summary, int operand_num, | 633 add_condition (class ipa_fn_summary *summary, |
526 HOST_WIDE_INT size, struct agg_position_info *aggpos, | 634 class ipa_node_params *params_summary, |
527 enum tree_code code, tree val) | 635 int operand_num, |
528 { | 636 tree type, struct agg_position_info *aggpos, |
529 int i; | 637 enum tree_code code, tree val, expr_eval_ops param_ops) |
638 { | |
639 int i, j; | |
530 struct condition *c; | 640 struct condition *c; |
531 struct condition new_cond; | 641 struct condition new_cond; |
532 HOST_WIDE_INT offset; | 642 HOST_WIDE_INT offset; |
533 bool agg_contents, by_ref; | 643 bool agg_contents, by_ref; |
644 expr_eval_op *op; | |
645 | |
646 if (params_summary) | |
647 ipa_set_param_used_by_ipa_predicates (params_summary, operand_num, true); | |
534 | 648 |
535 if (aggpos) | 649 if (aggpos) |
536 { | 650 { |
537 offset = aggpos->offset; | 651 offset = aggpos->offset; |
538 agg_contents = aggpos->agg_contents; | 652 agg_contents = aggpos->agg_contents; |
547 | 661 |
548 gcc_checking_assert (operand_num >= 0); | 662 gcc_checking_assert (operand_num >= 0); |
549 for (i = 0; vec_safe_iterate (summary->conds, i, &c); i++) | 663 for (i = 0; vec_safe_iterate (summary->conds, i, &c); i++) |
550 { | 664 { |
551 if (c->operand_num == operand_num | 665 if (c->operand_num == operand_num |
552 && c->size == size | |
553 && c->code == code | 666 && c->code == code |
554 && c->val == val | 667 && types_compatible_p (c->type, type) |
668 && vrp_operand_equal_p (c->val, val) | |
555 && c->agg_contents == agg_contents | 669 && c->agg_contents == agg_contents |
670 && expr_eval_ops_equal_p (c->param_ops, param_ops) | |
556 && (!agg_contents || (c->offset == offset && c->by_ref == by_ref))) | 671 && (!agg_contents || (c->offset == offset && c->by_ref == by_ref))) |
557 return predicate::predicate_testing_cond (i); | 672 return predicate::predicate_testing_cond (i); |
558 } | 673 } |
559 /* Too many conditions. Give up and return constant true. */ | 674 /* Too many conditions. Give up and return constant true. */ |
560 if (i == predicate::num_conditions - predicate::first_dynamic_condition) | 675 if (i == predicate::num_conditions - predicate::first_dynamic_condition) |
561 return true; | 676 return true; |
562 | 677 |
563 new_cond.operand_num = operand_num; | 678 new_cond.operand_num = operand_num; |
564 new_cond.code = code; | 679 new_cond.code = code; |
565 new_cond.val = val; | 680 new_cond.type = unshare_expr_without_location (type); |
681 new_cond.val = val ? unshare_expr_without_location (val) : val; | |
566 new_cond.agg_contents = agg_contents; | 682 new_cond.agg_contents = agg_contents; |
567 new_cond.by_ref = by_ref; | 683 new_cond.by_ref = by_ref; |
568 new_cond.offset = offset; | 684 new_cond.offset = offset; |
569 new_cond.size = size; | 685 new_cond.param_ops = vec_safe_copy (param_ops); |
686 | |
687 for (j = 0; vec_safe_iterate (new_cond.param_ops, j, &op); j++) | |
688 { | |
689 if (op->val[0]) | |
690 op->val[0] = unshare_expr_without_location (op->val[0]); | |
691 if (op->val[1]) | |
692 op->val[1] = unshare_expr_without_location (op->val[1]); | |
693 } | |
694 | |
570 vec_safe_push (summary->conds, new_cond); | 695 vec_safe_push (summary->conds, new_cond); |
571 | 696 |
572 return predicate::predicate_testing_cond (i); | 697 return predicate::predicate_testing_cond (i); |
573 } | 698 } |