Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-if-conv.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 /* If-conversion for vectorizer. | 1 /* If-conversion for vectorizer. |
2 Copyright (C) 2004-2018 Free Software Foundation, Inc. | 2 Copyright (C) 2004-2020 Free Software Foundation, Inc. |
3 Contributed by Devang Patel <dpatel@apple.com> | 3 Contributed by Devang Patel <dpatel@apple.com> |
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 |
112 #include "tree-ssa-address.h" | 112 #include "tree-ssa-address.h" |
113 #include "dbgcnt.h" | 113 #include "dbgcnt.h" |
114 #include "tree-hash-traits.h" | 114 #include "tree-hash-traits.h" |
115 #include "varasm.h" | 115 #include "varasm.h" |
116 #include "builtins.h" | 116 #include "builtins.h" |
117 #include "params.h" | |
118 #include "cfganal.h" | 117 #include "cfganal.h" |
119 #include "internal-fn.h" | 118 #include "internal-fn.h" |
120 #include "fold-const.h" | 119 #include "fold-const.h" |
120 #include "tree-ssa-sccvn.h" | |
121 #include "tree-cfgcleanup.h" | |
122 #include "tree-ssa-dse.h" | |
121 | 123 |
122 /* Only handle PHIs with no more arguments unless we are asked to by | 124 /* Only handle PHIs with no more arguments unless we are asked to by |
123 simd pragma. */ | 125 simd pragma. */ |
124 #define MAX_PHI_ARG_NUM \ | 126 #define MAX_PHI_ARG_NUM \ |
125 ((unsigned) PARAM_VALUE (PARAM_MAX_TREE_IF_CONVERSION_PHI_ARGS)) | 127 ((unsigned) param_max_tree_if_conversion_phi_args) |
126 | 128 |
127 /* True if we've converted a statement that was only executed when some | 129 /* True if we've converted a statement that was only executed when some |
128 condition C was true, and if for correctness we need to predicate the | 130 condition C was true, and if for correctness we need to predicate the |
129 statement to ensure that it is a no-op when C is false. See | 131 statement to ensure that it is a no-op when C is false. See |
130 predicate_statements for the kinds of predication we support. */ | 132 predicate_statements for the kinds of predication we support. */ |
432 enum tree_code code1 = parse_predicate (c1, &op1a, &op1b); | 434 enum tree_code code1 = parse_predicate (c1, &op1a, &op1b); |
433 enum tree_code code2 = parse_predicate (c2, &op2a, &op2b); | 435 enum tree_code code2 = parse_predicate (c2, &op2a, &op2b); |
434 | 436 |
435 if (code1 != ERROR_MARK && code2 != ERROR_MARK) | 437 if (code1 != ERROR_MARK && code2 != ERROR_MARK) |
436 { | 438 { |
437 tree t = maybe_fold_or_comparisons (code1, op1a, op1b, | 439 tree t = maybe_fold_or_comparisons (boolean_type_node, code1, op1a, op1b, |
438 code2, op2a, op2b); | 440 code2, op2a, op2b); |
439 if (t) | 441 if (t) |
440 return t; | 442 return t; |
441 } | 443 } |
442 | 444 |
498 the loop to be if-converted. Use predicate of cd-equivalent block | 500 the loop to be if-converted. Use predicate of cd-equivalent block |
499 for join bb if it exists: we call basic blocks bb1 and bb2 | 501 for join bb if it exists: we call basic blocks bb1 and bb2 |
500 cd-equivalent if they are executed under the same condition. */ | 502 cd-equivalent if they are executed under the same condition. */ |
501 | 503 |
502 static inline void | 504 static inline void |
503 add_to_predicate_list (struct loop *loop, basic_block bb, tree nc) | 505 add_to_predicate_list (class loop *loop, basic_block bb, tree nc) |
504 { | 506 { |
505 tree bc, *tp; | 507 tree bc, *tp; |
506 basic_block dom_bb; | 508 basic_block dom_bb; |
507 | 509 |
508 if (is_true_predicate (nc)) | 510 if (is_true_predicate (nc)) |
563 /* Add the condition COND to the previous condition PREV_COND, and add | 565 /* Add the condition COND to the previous condition PREV_COND, and add |
564 this to the predicate list of the destination of edge E. LOOP is | 566 this to the predicate list of the destination of edge E. LOOP is |
565 the loop to be if-converted. */ | 567 the loop to be if-converted. */ |
566 | 568 |
567 static void | 569 static void |
568 add_to_dst_predicate_list (struct loop *loop, edge e, | 570 add_to_dst_predicate_list (class loop *loop, edge e, |
569 tree prev_cond, tree cond) | 571 tree prev_cond, tree cond) |
570 { | 572 { |
571 if (!flow_bb_inside_loop_p (loop, e->dest)) | 573 if (!flow_bb_inside_loop_p (loop, e->dest)) |
572 return; | 574 return; |
573 | 575 |
580 } | 582 } |
581 | 583 |
582 /* Return true if one of the successor edges of BB exits LOOP. */ | 584 /* Return true if one of the successor edges of BB exits LOOP. */ |
583 | 585 |
584 static bool | 586 static bool |
585 bb_with_exit_edge_p (struct loop *loop, basic_block bb) | 587 bb_with_exit_edge_p (class loop *loop, basic_block bb) |
586 { | 588 { |
587 edge e; | 589 edge e; |
588 edge_iterator ei; | 590 edge_iterator ei; |
589 | 591 |
590 FOR_EACH_EDGE (e, ei, bb->succs) | 592 FOR_EACH_EDGE (e, ei, bb->succs) |
657 and it belongs to basic block BB. Note at this point, it is sure | 659 and it belongs to basic block BB. Note at this point, it is sure |
658 that PHI is if-convertible. This function updates global variable | 660 that PHI is if-convertible. This function updates global variable |
659 ANY_COMPLICATED_PHI if PHI is complicated. */ | 661 ANY_COMPLICATED_PHI if PHI is complicated. */ |
660 | 662 |
661 static bool | 663 static bool |
662 if_convertible_phi_p (struct loop *loop, basic_block bb, gphi *phi) | 664 if_convertible_phi_p (class loop *loop, basic_block bb, gphi *phi) |
663 { | 665 { |
664 if (dump_file && (dump_flags & TDF_DETAILS)) | 666 if (dump_file && (dump_flags & TDF_DETAILS)) |
665 { | 667 { |
666 fprintf (dump_file, "-------------------------\n"); | 668 fprintf (dump_file, "-------------------------\n"); |
667 print_gimple_stmt (dump_file, phi, 0, TDF_SLIM); | 669 print_gimple_stmt (dump_file, phi, 0, TDF_SLIM); |
752 { | 754 { |
753 wi::overflow_type overflow; | 755 wi::overflow_type overflow; |
754 widest_int niter, valid_niter, delta, wi_step; | 756 widest_int niter, valid_niter, delta, wi_step; |
755 tree ev, init, step; | 757 tree ev, init, step; |
756 tree low, high; | 758 tree low, high; |
757 struct loop *loop = (struct loop*) dta; | 759 class loop *loop = (class loop*) dta; |
758 | 760 |
759 /* Only support within-bound access for array references. */ | 761 /* Only support within-bound access for array references. */ |
760 if (TREE_CODE (ref) != ARRAY_REF) | 762 if (TREE_CODE (ref) != ARRAY_REF) |
761 return false; | 763 return false; |
762 | 764 |
818 /* Return TRUE if ref is a within bound array reference. */ | 820 /* Return TRUE if ref is a within bound array reference. */ |
819 | 821 |
820 static bool | 822 static bool |
821 ref_within_array_bound (gimple *stmt, tree ref) | 823 ref_within_array_bound (gimple *stmt, tree ref) |
822 { | 824 { |
823 struct loop *loop = loop_containing_stmt (stmt); | 825 class loop *loop = loop_containing_stmt (stmt); |
824 | 826 |
825 gcc_assert (loop != NULL); | 827 gcc_assert (loop != NULL); |
826 return for_each_index (&ref, idx_within_array_bound, loop); | 828 return for_each_index (&ref, idx_within_array_bound, loop); |
827 } | 829 } |
828 | 830 |
909 | 911 |
910 /* an unconditionaly write won't trap if the base is written | 912 /* an unconditionaly write won't trap if the base is written |
911 to unconditionally. */ | 913 to unconditionally. */ |
912 if (base_master_dr | 914 if (base_master_dr |
913 && DR_BASE_W_UNCONDITIONALLY (*base_master_dr)) | 915 && DR_BASE_W_UNCONDITIONALLY (*base_master_dr)) |
914 return PARAM_VALUE (PARAM_ALLOW_STORE_DATA_RACES); | 916 return flag_store_data_races; |
915 /* or the base is known to be not readonly. */ | 917 /* or the base is known to be not readonly. */ |
916 else if (base_object_writable (DR_REF (a))) | 918 else if (base_object_writable (DR_REF (a))) |
917 return PARAM_VALUE (PARAM_ALLOW_STORE_DATA_RACES); | 919 return flag_store_data_races; |
918 } | 920 } |
919 | 921 |
920 return false; | 922 return false; |
921 } | 923 } |
922 | 924 |
1124 | 1126 |
1125 EXIT_BB is the basic block containing the exit of the LOOP. BB is | 1127 EXIT_BB is the basic block containing the exit of the LOOP. BB is |
1126 inside LOOP. */ | 1128 inside LOOP. */ |
1127 | 1129 |
1128 static bool | 1130 static bool |
1129 if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb) | 1131 if_convertible_bb_p (class loop *loop, basic_block bb, basic_block exit_bb) |
1130 { | 1132 { |
1131 edge e; | 1133 edge e; |
1132 edge_iterator ei; | 1134 edge_iterator ei; |
1133 | 1135 |
1134 if (dump_file && (dump_flags & TDF_DETAILS)) | 1136 if (dump_file && (dump_flags & TDF_DETAILS)) |
1193 If-conversion suitable order is, breadth first sort (BFS) order | 1195 If-conversion suitable order is, breadth first sort (BFS) order |
1194 with an additional constraint: select a block only if all its | 1196 with an additional constraint: select a block only if all its |
1195 predecessors are already selected. */ | 1197 predecessors are already selected. */ |
1196 | 1198 |
1197 static basic_block * | 1199 static basic_block * |
1198 get_loop_body_in_if_conv_order (const struct loop *loop) | 1200 get_loop_body_in_if_conv_order (const class loop *loop) |
1199 { | 1201 { |
1200 basic_block *blocks, *blocks_in_bfs_order; | 1202 basic_block *blocks, *blocks_in_bfs_order; |
1201 basic_block bb; | 1203 basic_block bb; |
1202 bitmap visited; | 1204 bitmap visited; |
1203 unsigned int index = 0; | 1205 unsigned int index = 0; |
1340 } | 1342 } |
1341 | 1343 |
1342 /* Build region by adding loop pre-header and post-header blocks. */ | 1344 /* Build region by adding loop pre-header and post-header blocks. */ |
1343 | 1345 |
1344 static vec<basic_block> | 1346 static vec<basic_block> |
1345 build_region (struct loop *loop) | 1347 build_region (class loop *loop) |
1346 { | 1348 { |
1347 vec<basic_block> region = vNULL; | 1349 vec<basic_block> region = vNULL; |
1348 basic_block exit_bb = NULL; | 1350 basic_block exit_bb = NULL; |
1349 | 1351 |
1350 gcc_assert (ifc_bbs); | 1352 gcc_assert (ifc_bbs); |
1374 /* Return true when LOOP is if-convertible. This is a helper function | 1376 /* Return true when LOOP is if-convertible. This is a helper function |
1375 for if_convertible_loop_p. REFS and DDRS are initialized and freed | 1377 for if_convertible_loop_p. REFS and DDRS are initialized and freed |
1376 in if_convertible_loop_p. */ | 1378 in if_convertible_loop_p. */ |
1377 | 1379 |
1378 static bool | 1380 static bool |
1379 if_convertible_loop_p_1 (struct loop *loop, vec<data_reference_p> *refs) | 1381 if_convertible_loop_p_1 (class loop *loop, vec<data_reference_p> *refs) |
1380 { | 1382 { |
1381 unsigned int i; | 1383 unsigned int i; |
1382 basic_block exit_bb = NULL; | 1384 basic_block exit_bb = NULL; |
1383 vec<basic_block> region; | 1385 vec<basic_block> region; |
1384 | 1386 |
1514 - it has only one exit, | 1516 - it has only one exit, |
1515 - loop header is not the exit edge, | 1517 - loop header is not the exit edge, |
1516 - if its basic blocks and phi nodes are if convertible. */ | 1518 - if its basic blocks and phi nodes are if convertible. */ |
1517 | 1519 |
1518 static bool | 1520 static bool |
1519 if_convertible_loop_p (struct loop *loop) | 1521 if_convertible_loop_p (class loop *loop) |
1520 { | 1522 { |
1521 edge e; | 1523 edge e; |
1522 edge_iterator ei; | 1524 edge_iterator ei; |
1523 bool res = false; | 1525 bool res = false; |
1524 vec<data_reference_p> refs; | 1526 vec<data_reference_p> refs; |
1593 tree lhs, r_op1, r_op2; | 1595 tree lhs, r_op1, r_op2; |
1594 gimple *stmt; | 1596 gimple *stmt; |
1595 gimple *header_phi = NULL; | 1597 gimple *header_phi = NULL; |
1596 enum tree_code reduction_op; | 1598 enum tree_code reduction_op; |
1597 basic_block bb = gimple_bb (phi); | 1599 basic_block bb = gimple_bb (phi); |
1598 struct loop *loop = bb->loop_father; | 1600 class loop *loop = bb->loop_father; |
1599 edge latch_e = loop_latch_edge (loop); | 1601 edge latch_e = loop_latch_edge (loop); |
1600 imm_use_iterator imm_iter; | 1602 imm_use_iterator imm_iter; |
1601 use_operand_p use_p; | 1603 use_operand_p use_p; |
1602 edge e; | 1604 edge e; |
1603 edge_iterator ei; | 1605 edge_iterator ei; |
2000 | 2002 |
2001 /* Replaces in LOOP all the scalar phi nodes other than those in the | 2003 /* Replaces in LOOP all the scalar phi nodes other than those in the |
2002 LOOP->header block with conditional modify expressions. */ | 2004 LOOP->header block with conditional modify expressions. */ |
2003 | 2005 |
2004 static void | 2006 static void |
2005 predicate_all_scalar_phis (struct loop *loop) | 2007 predicate_all_scalar_phis (class loop *loop) |
2006 { | 2008 { |
2007 basic_block bb; | 2009 basic_block bb; |
2008 unsigned int orig_loop_num_nodes = loop->num_nodes; | 2010 unsigned int orig_loop_num_nodes = loop->num_nodes; |
2009 unsigned int i; | 2011 unsigned int i; |
2010 | 2012 |
2137 else | 2139 else |
2138 { | 2140 { |
2139 new_stmt | 2141 new_stmt |
2140 = gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr, | 2142 = gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr, |
2141 mask, rhs); | 2143 mask, rhs); |
2142 gimple_set_vuse (new_stmt, gimple_vuse (stmt)); | 2144 gimple_move_vops (new_stmt, stmt); |
2143 gimple_set_vdef (new_stmt, gimple_vdef (stmt)); | |
2144 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt; | |
2145 } | 2145 } |
2146 gimple_call_set_nothrow (new_stmt, true); | 2146 gimple_call_set_nothrow (new_stmt, true); |
2147 return new_stmt; | 2147 return new_stmt; |
2148 } | 2148 } |
2149 | 2149 |
2522 | 2522 |
2523 /* Combine all the basic blocks from LOOP into one or two super basic | 2523 /* Combine all the basic blocks from LOOP into one or two super basic |
2524 blocks. Replace PHI nodes with conditional modify expressions. */ | 2524 blocks. Replace PHI nodes with conditional modify expressions. */ |
2525 | 2525 |
2526 static void | 2526 static void |
2527 combine_blocks (struct loop *loop) | 2527 combine_blocks (class loop *loop) |
2528 { | 2528 { |
2529 basic_block bb, exit_bb, merge_target_bb; | 2529 basic_block bb, exit_bb, merge_target_bb; |
2530 unsigned int orig_loop_num_nodes = loop->num_nodes; | 2530 unsigned int orig_loop_num_nodes = loop->num_nodes; |
2531 unsigned int i; | 2531 unsigned int i; |
2532 edge e; | 2532 edge e; |
2622 out using the current VUSE. The def might be the one used | 2622 out using the current VUSE. The def might be the one used |
2623 after the loop. */ | 2623 after the loop. */ |
2624 vphi = get_virtual_phi (bb); | 2624 vphi = get_virtual_phi (bb); |
2625 if (vphi) | 2625 if (vphi) |
2626 { | 2626 { |
2627 /* When there's just loads inside the loop a stray virtual | |
2628 PHI merging the uses can appear, update last_vdef from | |
2629 it. */ | |
2630 if (!last_vdef) | |
2631 last_vdef = gimple_phi_arg_def (vphi, 0); | |
2627 imm_use_iterator iter; | 2632 imm_use_iterator iter; |
2628 use_operand_p use_p; | 2633 use_operand_p use_p; |
2629 gimple *use_stmt; | 2634 gimple *use_stmt; |
2630 FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_phi_result (vphi)) | 2635 FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_phi_result (vphi)) |
2631 { | 2636 { |
2632 FOR_EACH_IMM_USE_ON_STMT (use_p, iter) | 2637 FOR_EACH_IMM_USE_ON_STMT (use_p, iter) |
2633 SET_USE (use_p, last_vdef); | 2638 SET_USE (use_p, last_vdef); |
2634 } | 2639 } |
2640 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (vphi))) | |
2641 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (last_vdef) = 1; | |
2635 gsi = gsi_for_stmt (vphi); | 2642 gsi = gsi_for_stmt (vphi); |
2636 remove_phi_node (&gsi, true); | 2643 remove_phi_node (&gsi, true); |
2637 } | 2644 } |
2638 | 2645 |
2639 /* Make stmts member of loop->header and clear range info from all stmts | 2646 /* Make stmts member of loop->header and clear range info from all stmts |
2651 && USE_FROM_PTR (use_p) != last_vdef) | 2658 && USE_FROM_PTR (use_p) != last_vdef) |
2652 SET_USE (use_p, last_vdef); | 2659 SET_USE (use_p, last_vdef); |
2653 if (gimple_vdef (stmt)) | 2660 if (gimple_vdef (stmt)) |
2654 last_vdef = gimple_vdef (stmt); | 2661 last_vdef = gimple_vdef (stmt); |
2655 } | 2662 } |
2663 else | |
2664 /* If this is the first load we arrive at update last_vdef | |
2665 so we handle stray PHIs correctly. */ | |
2666 last_vdef = gimple_vuse (stmt); | |
2656 if (predicated[i]) | 2667 if (predicated[i]) |
2657 { | 2668 { |
2658 ssa_op_iter i; | 2669 ssa_op_iter i; |
2659 tree op; | 2670 tree op; |
2660 FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF) | 2671 FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF) |
2688 FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_phi_result (vphi)) | 2699 FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_phi_result (vphi)) |
2689 { | 2700 { |
2690 FOR_EACH_IMM_USE_ON_STMT (use_p, iter) | 2701 FOR_EACH_IMM_USE_ON_STMT (use_p, iter) |
2691 SET_USE (use_p, last_vdef); | 2702 SET_USE (use_p, last_vdef); |
2692 } | 2703 } |
2704 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (vphi))) | |
2705 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (last_vdef) = 1; | |
2693 gimple_stmt_iterator gsi = gsi_for_stmt (vphi); | 2706 gimple_stmt_iterator gsi = gsi_for_stmt (vphi); |
2694 remove_phi_node (&gsi, true); | 2707 remove_phi_node (&gsi, true); |
2695 } | 2708 } |
2696 | 2709 |
2697 if (can_merge_blocks_p (loop->header, exit_bb)) | 2710 if (can_merge_blocks_p (loop->header, exit_bb)) |
2711 | 2724 |
2712 Note that this function intentionally invalidates profile. Both edges | 2725 Note that this function intentionally invalidates profile. Both edges |
2713 out of LOOP_VECTORIZED must have 100% probability so the profile remains | 2726 out of LOOP_VECTORIZED must have 100% probability so the profile remains |
2714 consistent after the condition is folded in the vectorizer. */ | 2727 consistent after the condition is folded in the vectorizer. */ |
2715 | 2728 |
2716 static struct loop * | 2729 static class loop * |
2717 version_loop_for_if_conversion (struct loop *loop) | 2730 version_loop_for_if_conversion (class loop *loop, vec<gimple *> *preds) |
2718 { | 2731 { |
2719 basic_block cond_bb; | 2732 basic_block cond_bb; |
2720 tree cond = make_ssa_name (boolean_type_node); | 2733 tree cond = make_ssa_name (boolean_type_node); |
2721 struct loop *new_loop; | 2734 class loop *new_loop; |
2722 gimple *g; | 2735 gimple *g; |
2723 gimple_stmt_iterator gsi; | 2736 gimple_stmt_iterator gsi; |
2724 unsigned int save_length; | 2737 unsigned int save_length; |
2725 | 2738 |
2726 g = gimple_build_call_internal (IFN_LOOP_VECTORIZED, 2, | 2739 g = gimple_build_call_internal (IFN_LOOP_VECTORIZED, 2, |
2752 | 2765 |
2753 new_loop->dont_vectorize = true; | 2766 new_loop->dont_vectorize = true; |
2754 new_loop->force_vectorize = false; | 2767 new_loop->force_vectorize = false; |
2755 gsi = gsi_last_bb (cond_bb); | 2768 gsi = gsi_last_bb (cond_bb); |
2756 gimple_call_set_arg (g, 1, build_int_cst (integer_type_node, new_loop->num)); | 2769 gimple_call_set_arg (g, 1, build_int_cst (integer_type_node, new_loop->num)); |
2770 if (preds) | |
2771 preds->safe_push (g); | |
2757 gsi_insert_before (&gsi, g, GSI_SAME_STMT); | 2772 gsi_insert_before (&gsi, g, GSI_SAME_STMT); |
2758 update_ssa (TODO_update_ssa); | 2773 update_ssa (TODO_update_ssa); |
2759 return new_loop; | 2774 return new_loop; |
2760 } | 2775 } |
2761 | 2776 |
2771 predecessor. | 2786 predecessor. |
2772 - The loop exit block has a single predecessor, which is the | 2787 - The loop exit block has a single predecessor, which is the |
2773 inner loop's exit block. */ | 2788 inner loop's exit block. */ |
2774 | 2789 |
2775 static bool | 2790 static bool |
2776 versionable_outer_loop_p (struct loop *loop) | 2791 versionable_outer_loop_p (class loop *loop) |
2777 { | 2792 { |
2778 if (!loop_outer (loop) | 2793 if (!loop_outer (loop) |
2779 || loop->dont_vectorize | 2794 || loop->dont_vectorize |
2780 || !loop->inner | 2795 || !loop->inner |
2781 || loop->inner->next | 2796 || loop->inner->next |
2805 - LOOP has PHI with more than MAX_PHI_ARG_NUM arguments. | 2820 - LOOP has PHI with more than MAX_PHI_ARG_NUM arguments. |
2806 | 2821 |
2807 Last restriction is valid only if AGGRESSIVE_IF_CONV is false. */ | 2822 Last restriction is valid only if AGGRESSIVE_IF_CONV is false. */ |
2808 | 2823 |
2809 static bool | 2824 static bool |
2810 ifcvt_split_critical_edges (struct loop *loop, bool aggressive_if_conv) | 2825 ifcvt_split_critical_edges (class loop *loop, bool aggressive_if_conv) |
2811 { | 2826 { |
2812 basic_block *body; | 2827 basic_block *body; |
2813 basic_block bb; | 2828 basic_block bb; |
2814 unsigned int num = loop->num_nodes; | 2829 unsigned int num = loop->num_nodes; |
2815 unsigned int i; | 2830 unsigned int i; |
2865 | 2880 |
2866 /* Delete redundant statements produced by predication which prevents | 2881 /* Delete redundant statements produced by predication which prevents |
2867 loop vectorization. */ | 2882 loop vectorization. */ |
2868 | 2883 |
2869 static void | 2884 static void |
2870 ifcvt_local_dce (basic_block bb) | 2885 ifcvt_local_dce (class loop *loop) |
2871 { | 2886 { |
2872 gimple *stmt; | 2887 gimple *stmt; |
2873 gimple *stmt1; | 2888 gimple *stmt1; |
2874 gimple *phi; | 2889 gimple *phi; |
2875 gimple_stmt_iterator gsi; | 2890 gimple_stmt_iterator gsi; |
2882 | 2897 |
2883 FOR_EACH_VEC_ELT (redundant_ssa_names, i, name_pair) | 2898 FOR_EACH_VEC_ELT (redundant_ssa_names, i, name_pair) |
2884 replace_uses_by (name_pair->first, name_pair->second); | 2899 replace_uses_by (name_pair->first, name_pair->second); |
2885 redundant_ssa_names.release (); | 2900 redundant_ssa_names.release (); |
2886 | 2901 |
2902 /* The loop has a single BB only. */ | |
2903 basic_block bb = loop->header; | |
2904 tree latch_vdef = NULL_TREE; | |
2905 | |
2887 worklist.create (64); | 2906 worklist.create (64); |
2888 /* Consider all phi as live statements. */ | 2907 /* Consider all phi as live statements. */ |
2889 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | 2908 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
2890 { | 2909 { |
2891 phi = gsi_stmt (gsi); | 2910 phi = gsi_stmt (gsi); |
2892 gimple_set_plf (phi, GF_PLF_2, true); | 2911 gimple_set_plf (phi, GF_PLF_2, true); |
2893 worklist.safe_push (phi); | 2912 worklist.safe_push (phi); |
2913 if (virtual_operand_p (gimple_phi_result (phi))) | |
2914 latch_vdef = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop)); | |
2894 } | 2915 } |
2895 /* Consider load/store statements, CALL and COND as live. */ | 2916 /* Consider load/store statements, CALL and COND as live. */ |
2896 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | 2917 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
2897 { | 2918 { |
2898 stmt = gsi_stmt (gsi); | 2919 stmt = gsi_stmt (gsi); |
2952 /* Delete dead statements. */ | 2973 /* Delete dead statements. */ |
2953 gsi = gsi_start_bb (bb); | 2974 gsi = gsi_start_bb (bb); |
2954 while (!gsi_end_p (gsi)) | 2975 while (!gsi_end_p (gsi)) |
2955 { | 2976 { |
2956 stmt = gsi_stmt (gsi); | 2977 stmt = gsi_stmt (gsi); |
2978 if (gimple_store_p (stmt)) | |
2979 { | |
2980 tree lhs = gimple_get_lhs (stmt); | |
2981 ao_ref write; | |
2982 ao_ref_init (&write, lhs); | |
2983 | |
2984 if (dse_classify_store (&write, stmt, false, NULL, NULL, latch_vdef) | |
2985 == DSE_STORE_DEAD) | |
2986 delete_dead_or_redundant_assignment (&gsi, "dead"); | |
2987 else | |
2988 gsi_next (&gsi); | |
2989 continue; | |
2990 } | |
2991 | |
2957 if (gimple_plf (stmt, GF_PLF_2)) | 2992 if (gimple_plf (stmt, GF_PLF_2)) |
2958 { | 2993 { |
2959 gsi_next (&gsi); | 2994 gsi_next (&gsi); |
2960 continue; | 2995 continue; |
2961 } | 2996 } |
2972 /* If-convert LOOP when it is legal. For the moment this pass has no | 3007 /* If-convert LOOP when it is legal. For the moment this pass has no |
2973 profitability analysis. Returns non-zero todo flags when something | 3008 profitability analysis. Returns non-zero todo flags when something |
2974 changed. */ | 3009 changed. */ |
2975 | 3010 |
2976 unsigned int | 3011 unsigned int |
2977 tree_if_conversion (struct loop *loop) | 3012 tree_if_conversion (class loop *loop, vec<gimple *> *preds) |
2978 { | 3013 { |
2979 unsigned int todo = 0; | 3014 unsigned int todo = 0; |
2980 bool aggressive_if_conv; | 3015 bool aggressive_if_conv; |
2981 struct loop *rloop; | 3016 class loop *rloop; |
3017 bitmap exit_bbs; | |
2982 | 3018 |
2983 again: | 3019 again: |
2984 rloop = NULL; | 3020 rloop = NULL; |
2985 ifc_bbs = NULL; | 3021 ifc_bbs = NULL; |
2986 need_to_predicate = false; | 3022 need_to_predicate = false; |
2990 marked with simd pragma. When that's the case, we try to if-convert | 3026 marked with simd pragma. When that's the case, we try to if-convert |
2991 loop containing PHIs with more than MAX_PHI_ARG_NUM arguments. */ | 3027 loop containing PHIs with more than MAX_PHI_ARG_NUM arguments. */ |
2992 aggressive_if_conv = loop->force_vectorize; | 3028 aggressive_if_conv = loop->force_vectorize; |
2993 if (!aggressive_if_conv) | 3029 if (!aggressive_if_conv) |
2994 { | 3030 { |
2995 struct loop *outer_loop = loop_outer (loop); | 3031 class loop *outer_loop = loop_outer (loop); |
2996 if (outer_loop && outer_loop->force_vectorize) | 3032 if (outer_loop && outer_loop->force_vectorize) |
2997 aggressive_if_conv = true; | 3033 aggressive_if_conv = true; |
2998 } | 3034 } |
2999 | 3035 |
3000 if (!ifcvt_split_critical_edges (loop, aggressive_if_conv)) | 3036 if (!ifcvt_split_critical_edges (loop, aggressive_if_conv)) |
3016 still if-convert the original inner loop. */ | 3052 still if-convert the original inner loop. */ |
3017 if (need_to_predicate | 3053 if (need_to_predicate |
3018 || any_complicated_phi | 3054 || any_complicated_phi |
3019 || flag_tree_loop_if_convert != 1) | 3055 || flag_tree_loop_if_convert != 1) |
3020 { | 3056 { |
3021 struct loop *vloop | 3057 class loop *vloop |
3022 = (versionable_outer_loop_p (loop_outer (loop)) | 3058 = (versionable_outer_loop_p (loop_outer (loop)) |
3023 ? loop_outer (loop) : loop); | 3059 ? loop_outer (loop) : loop); |
3024 struct loop *nloop = version_loop_for_if_conversion (vloop); | 3060 class loop *nloop = version_loop_for_if_conversion (vloop, preds); |
3025 if (nloop == NULL) | 3061 if (nloop == NULL) |
3026 goto cleanup; | 3062 goto cleanup; |
3027 if (vloop != loop) | 3063 if (vloop != loop) |
3028 { | 3064 { |
3029 /* If versionable_outer_loop_p decided to version the | 3065 /* If versionable_outer_loop_p decided to version the |
3051 /* Now all statements are if-convertible. Combine all the basic | 3087 /* Now all statements are if-convertible. Combine all the basic |
3052 blocks into one huge basic block doing the if-conversion | 3088 blocks into one huge basic block doing the if-conversion |
3053 on-the-fly. */ | 3089 on-the-fly. */ |
3054 combine_blocks (loop); | 3090 combine_blocks (loop); |
3055 | 3091 |
3092 /* Perform local CSE, this esp. helps the vectorizer analysis if loads | |
3093 and stores are involved. CSE only the loop body, not the entry | |
3094 PHIs, those are to be kept in sync with the non-if-converted copy. | |
3095 ??? We'll still keep dead stores though. */ | |
3096 exit_bbs = BITMAP_ALLOC (NULL); | |
3097 bitmap_set_bit (exit_bbs, single_exit (loop)->dest->index); | |
3098 bitmap_set_bit (exit_bbs, loop->latch->index); | |
3099 todo |= do_rpo_vn (cfun, loop_preheader_edge (loop), exit_bbs); | |
3100 | |
3056 /* Delete dead predicate computations. */ | 3101 /* Delete dead predicate computations. */ |
3057 ifcvt_local_dce (loop->header); | 3102 ifcvt_local_dce (loop); |
3103 BITMAP_FREE (exit_bbs); | |
3058 | 3104 |
3059 todo |= TODO_cleanup_cfg; | 3105 todo |= TODO_cleanup_cfg; |
3060 | 3106 |
3061 cleanup: | 3107 cleanup: |
3062 if (ifc_bbs) | 3108 if (ifc_bbs) |
3117 } | 3163 } |
3118 | 3164 |
3119 unsigned int | 3165 unsigned int |
3120 pass_if_conversion::execute (function *fun) | 3166 pass_if_conversion::execute (function *fun) |
3121 { | 3167 { |
3122 struct loop *loop; | 3168 class loop *loop; |
3123 unsigned todo = 0; | 3169 unsigned todo = 0; |
3124 | 3170 |
3125 if (number_of_loops (fun) <= 1) | 3171 if (number_of_loops (fun) <= 1) |
3126 return 0; | 3172 return 0; |
3127 | 3173 |
3174 auto_vec<gimple *> preds; | |
3128 FOR_EACH_LOOP (loop, 0) | 3175 FOR_EACH_LOOP (loop, 0) |
3129 if (flag_tree_loop_if_convert == 1 | 3176 if (flag_tree_loop_if_convert == 1 |
3130 || ((flag_tree_loop_vectorize || loop->force_vectorize) | 3177 || ((flag_tree_loop_vectorize || loop->force_vectorize) |
3131 && !loop->dont_vectorize)) | 3178 && !loop->dont_vectorize)) |
3132 todo |= tree_if_conversion (loop); | 3179 todo |= tree_if_conversion (loop, &preds); |
3133 | 3180 |
3134 if (todo) | 3181 if (todo) |
3135 { | 3182 { |
3136 free_numbers_of_iterations_estimates (fun); | 3183 free_numbers_of_iterations_estimates (fun); |
3137 scev_reset (); | 3184 scev_reset (); |
3142 basic_block bb; | 3189 basic_block bb; |
3143 FOR_EACH_BB_FN (bb, fun) | 3190 FOR_EACH_BB_FN (bb, fun) |
3144 gcc_assert (!bb->aux); | 3191 gcc_assert (!bb->aux); |
3145 } | 3192 } |
3146 | 3193 |
3147 return todo; | 3194 /* Perform IL update now, it might elide some loops. */ |
3195 if (todo & TODO_cleanup_cfg) | |
3196 { | |
3197 cleanup_tree_cfg (); | |
3198 if (need_ssa_update_p (fun)) | |
3199 todo |= TODO_update_ssa; | |
3200 } | |
3201 if (todo & TODO_update_ssa_any) | |
3202 update_ssa (todo & TODO_update_ssa_any); | |
3203 | |
3204 /* If if-conversion elided the loop fall back to the original one. */ | |
3205 for (unsigned i = 0; i < preds.length (); ++i) | |
3206 { | |
3207 gimple *g = preds[i]; | |
3208 if (!gimple_bb (g)) | |
3209 continue; | |
3210 unsigned ifcvt_loop = tree_to_uhwi (gimple_call_arg (g, 0)); | |
3211 if (!get_loop (fun, ifcvt_loop)) | |
3212 { | |
3213 if (dump_file) | |
3214 fprintf (dump_file, "If-converted loop vanished\n"); | |
3215 fold_loop_internal_call (g, boolean_false_node); | |
3216 } | |
3217 } | |
3218 | |
3219 return 0; | |
3148 } | 3220 } |
3149 | 3221 |
3150 } // anon namespace | 3222 } // anon namespace |
3151 | 3223 |
3152 gimple_opt_pass * | 3224 gimple_opt_pass * |