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 *