comparison gcc/tree-ssa-math-opts.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 /* Global, SSA-based optimizations using mathematical identities. 1 /* Global, SSA-based optimizations using mathematical identities.
2 Copyright (C) 2005-2018 Free Software Foundation, Inc. 2 Copyright (C) 2005-2020 Free Software Foundation, Inc.
3 3
4 This file is part of GCC. 4 This file is part of GCC.
5 5
6 GCC is free software; you can redistribute it and/or modify it 6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the 7 under the terms of the GNU General Public License as published by the
107 #include "stor-layout.h" 107 #include "stor-layout.h"
108 #include "tree-cfg.h" 108 #include "tree-cfg.h"
109 #include "tree-dfa.h" 109 #include "tree-dfa.h"
110 #include "tree-ssa.h" 110 #include "tree-ssa.h"
111 #include "builtins.h" 111 #include "builtins.h"
112 #include "params.h"
113 #include "internal-fn.h" 112 #include "internal-fn.h"
114 #include "case-cfn-macros.h" 113 #include "case-cfn-macros.h"
115 #include "optabs-libfuncs.h" 114 #include "optabs-libfuncs.h"
116 #include "tree-eh.h" 115 #include "tree-eh.h"
117 #include "targhooks.h" 116 #include "targhooks.h"
332 && gimple_assign_rhs_code (use_stmt) == RDIV_EXPR 331 && gimple_assign_rhs_code (use_stmt) == RDIV_EXPR
333 && gimple_assign_rhs2 (use_stmt) == def 332 && gimple_assign_rhs2 (use_stmt) == def
334 /* Do not recognize x / x as valid division, as we are getting 333 /* Do not recognize x / x as valid division, as we are getting
335 confused later by replacing all immediate uses x in such 334 confused later by replacing all immediate uses x in such
336 a stmt. */ 335 a stmt. */
337 && gimple_assign_rhs1 (use_stmt) != def; 336 && gimple_assign_rhs1 (use_stmt) != def
337 && !stmt_can_throw_internal (cfun, use_stmt);
338 } 338 }
339 339
340 /* Return TRUE if USE_STMT is a multiplication of DEF by A. */ 340 /* Return TRUE if USE_STMT is a multiplication of DEF by A. */
341 static inline bool 341 static inline bool
342 is_mult_by (gimple *use_stmt, tree def, tree a) 342 is_mult_by (gimple *use_stmt, tree def, tree a)
365 static inline bool 365 static inline bool
366 is_division_by_square (gimple *use_stmt, tree def) 366 is_division_by_square (gimple *use_stmt, tree def)
367 { 367 {
368 if (gimple_code (use_stmt) == GIMPLE_ASSIGN 368 if (gimple_code (use_stmt) == GIMPLE_ASSIGN
369 && gimple_assign_rhs_code (use_stmt) == RDIV_EXPR 369 && gimple_assign_rhs_code (use_stmt) == RDIV_EXPR
370 && gimple_assign_rhs1 (use_stmt) != gimple_assign_rhs2 (use_stmt)) 370 && gimple_assign_rhs1 (use_stmt) != gimple_assign_rhs2 (use_stmt)
371 && !stmt_can_throw_internal (cfun, use_stmt))
371 { 372 {
372 tree denominator = gimple_assign_rhs2 (use_stmt); 373 tree denominator = gimple_assign_rhs2 (use_stmt);
373 if (TREE_CODE (denominator) == SSA_NAME) 374 if (TREE_CODE (denominator) == SSA_NAME)
374 { 375 return is_square_of (SSA_NAME_DEF_STMT (denominator), def);
375 return is_square_of (SSA_NAME_DEF_STMT (denominator), def);
376 }
377 } 376 }
378 return 0; 377 return 0;
379 } 378 }
380 379
381 /* Walk the subset of the dominator tree rooted at OCC, setting the 380 /* Walk the subset of the dominator tree rooted at OCC, setting the
650 { 649 {
651 fprintf (dump_file, "Replacing original division\n"); 650 fprintf (dump_file, "Replacing original division\n");
652 print_gimple_stmt (dump_file, stmt, 0, TDF_NONE); 651 print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
653 fprintf (dump_file, "with new division\n"); 652 fprintf (dump_file, "with new division\n");
654 } 653 }
655 gimple_assign_set_lhs (stmt, sqr_ssa_name); 654 stmt
656 gimple_assign_set_rhs2 (stmt, a); 655 = gimple_build_assign (sqr_ssa_name, gimple_assign_rhs_code (stmt),
656 gimple_assign_rhs1 (stmt), a);
657 gsi_insert_before (def_gsi, stmt, GSI_SAME_STMT);
658 gsi_remove (def_gsi, true);
659 *def_gsi = gsi_for_stmt (stmt);
657 fold_stmt_inplace (def_gsi); 660 fold_stmt_inplace (def_gsi);
658 update_stmt (stmt); 661 update_stmt (stmt);
659 662
660 if (dump_file) 663 if (dump_file)
661 print_gimple_stmt (dump_file, stmt, 0, TDF_NONE); 664 print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
702 gcc_assert (orig_sqrt_ssa_name); 705 gcc_assert (orig_sqrt_ssa_name);
703 gcc_assert (sqr_ssa_name); 706 gcc_assert (sqr_ssa_name);
704 707
705 gimple *new_stmt 708 gimple *new_stmt
706 = gimple_build_assign (x, MULT_EXPR, 709 = gimple_build_assign (x, MULT_EXPR,
707 orig_sqrt_ssa_name, sqr_ssa_name); 710 orig_sqrt_ssa_name, sqr_ssa_name);
708 gsi_insert_after (def_gsi, new_stmt, GSI_NEW_STMT); 711 gsi_insert_after (def_gsi, new_stmt, GSI_NEW_STMT);
709 update_stmt (stmt); 712 update_stmt (stmt);
710 } 713 }
711 else if (delete_div) 714 else if (delete_div)
712 { 715 {
713 /* Remove the original division. */ 716 /* Remove the original division. */
714 gimple_stmt_iterator gsi2 = gsi_for_stmt (stmt); 717 gimple_stmt_iterator gsi2 = gsi_for_stmt (stmt);
715 gsi_remove (&gsi2, true); 718 gsi_remove (&gsi2, true);
716 release_defs (stmt); 719 release_defs (stmt);
717 } 720 }
721 else
722 release_ssa_name (x);
718 } 723 }
719 724
720 /* Look for floating-point divisions among DEF's uses, and try to 725 /* Look for floating-point divisions among DEF's uses, and try to
721 replace them by multiplications with the reciprocal. Add 726 replace them by multiplications with the reciprocal. Add
722 as many statements computing the reciprocal as needed. 727 as many statements computing the reciprocal as needed.
791 /* Square reciprocals were counted twice above. */ 796 /* Square reciprocals were counted twice above. */
792 square_recip_count /= 2; 797 square_recip_count /= 2;
793 798
794 /* If it is more profitable to optimize 1 / x, don't optimize 1 / (x * x). */ 799 /* If it is more profitable to optimize 1 / x, don't optimize 1 / (x * x). */
795 if (sqrt_recip_count > square_recip_count) 800 if (sqrt_recip_count > square_recip_count)
796 return; 801 goto out;
797 802
798 /* Do the expensive part only if we can hope to optimize something. */ 803 /* Do the expensive part only if we can hope to optimize something. */
799 if (count + square_recip_count >= threshold && count >= 1) 804 if (count + square_recip_count >= threshold && count >= 1)
800 { 805 {
801 gimple *use_stmt; 806 gimple *use_stmt;
834 } 839 }
835 } 840 }
836 } 841 }
837 } 842 }
838 843
844 out:
839 for (occ = occ_head; occ; ) 845 for (occ = occ_head; occ; )
840 occ = free_bb (occ); 846 occ = free_bb (occ);
841 847
842 occ_head = NULL; 848 occ_head = NULL;
843 } 849 }
949 { 955 {
950 execute_cse_reciprocals_1 (&gsi, def); 956 execute_cse_reciprocals_1 (&gsi, def);
951 stmt = gsi_stmt (gsi); 957 stmt = gsi_stmt (gsi);
952 if (flag_unsafe_math_optimizations 958 if (flag_unsafe_math_optimizations
953 && is_gimple_assign (stmt) 959 && is_gimple_assign (stmt)
960 && gimple_assign_lhs (stmt) == def
954 && !stmt_can_throw_internal (cfun, stmt) 961 && !stmt_can_throw_internal (cfun, stmt)
955 && gimple_assign_rhs_code (stmt) == RDIV_EXPR) 962 && gimple_assign_rhs_code (stmt) == RDIV_EXPR)
956 optimize_recip_sqrt (&gsi, def); 963 optimize_recip_sqrt (&gsi, def);
957 } 964 }
958 } 965 }
1030 if (ifn == IFN_LAST) 1037 if (ifn == IFN_LAST)
1031 stmt2 = gimple_build_call_vec (fndecl, args); 1038 stmt2 = gimple_build_call_vec (fndecl, args);
1032 else 1039 else
1033 stmt2 = gimple_build_call_internal_vec (ifn, args); 1040 stmt2 = gimple_build_call_internal_vec (ifn, args);
1034 gimple_call_set_lhs (stmt2, arg1); 1041 gimple_call_set_lhs (stmt2, arg1);
1035 if (gimple_vdef (call)) 1042 gimple_move_vops (stmt2, call);
1036 {
1037 gimple_set_vdef (stmt2, gimple_vdef (call));
1038 SSA_NAME_DEF_STMT (gimple_vdef (stmt2)) = stmt2;
1039 }
1040 gimple_call_set_nothrow (stmt2, 1043 gimple_call_set_nothrow (stmt2,
1041 gimple_call_nothrow_p (call)); 1044 gimple_call_nothrow_p (call));
1042 gimple_set_vuse (stmt2, gimple_vuse (call));
1043 gimple_stmt_iterator gsi2 = gsi_for_stmt (call); 1045 gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
1044 gsi_replace (&gsi2, stmt2, true); 1046 gsi_replace (&gsi2, stmt2, true);
1045 } 1047 }
1046 else 1048 else
1047 { 1049 {
1970 && hw_sqrt_exists 1972 && hw_sqrt_exists
1971 && (speed_p || real_equal (&c, &dconst1_4)) 1973 && (speed_p || real_equal (&c, &dconst1_4))
1972 && !HONOR_SIGNED_ZEROS (mode)) 1974 && !HONOR_SIGNED_ZEROS (mode))
1973 { 1975 {
1974 unsigned int max_depth = speed_p 1976 unsigned int max_depth = speed_p
1975 ? PARAM_VALUE (PARAM_MAX_POW_SQRT_DEPTH) 1977 ? param_max_pow_sqrt_depth
1976 : 2; 1978 : 2;
1977 1979
1978 tree expand_with_sqrts 1980 tree expand_with_sqrts
1979 = expand_pow_as_sqrts (gsi, loc, arg0, arg1, max_depth); 1981 = expand_pow_as_sqrts (gsi, loc, arg0, arg1, max_depth);
1980 1982
2907 gimple_call_set_nothrow (fma_stmt, !stmt_can_throw_internal (cfun, 2909 gimple_call_set_nothrow (fma_stmt, !stmt_can_throw_internal (cfun,
2908 use_stmt)); 2910 use_stmt));
2909 gsi_replace (&gsi, fma_stmt, true); 2911 gsi_replace (&gsi, fma_stmt, true);
2910 /* Follow all SSA edges so that we generate FMS, FNMA and FNMS 2912 /* Follow all SSA edges so that we generate FMS, FNMA and FNMS
2911 regardless of where the negation occurs. */ 2913 regardless of where the negation occurs. */
2914 gimple *orig_stmt = gsi_stmt (gsi);
2912 if (fold_stmt (&gsi, follow_all_ssa_edges)) 2915 if (fold_stmt (&gsi, follow_all_ssa_edges))
2913 update_stmt (gsi_stmt (gsi)); 2916 {
2917 if (maybe_clean_or_replace_eh_stmt (orig_stmt, gsi_stmt (gsi)))
2918 gcc_unreachable ();
2919 update_stmt (gsi_stmt (gsi));
2920 }
2914 2921
2915 if (dump_file && (dump_flags & TDF_DETAILS)) 2922 if (dump_file && (dump_flags & TDF_DETAILS))
2916 { 2923 {
2917 fprintf (dump_file, "Generated FMA "); 2924 fprintf (dump_file, "Generated FMA ");
2918 print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, TDF_NONE); 2925 print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, TDF_NONE);
3029 } 3036 }
3030 3037
3031 /* Combine the multiplication at MUL_STMT with operands MULOP1 and MULOP2 3038 /* Combine the multiplication at MUL_STMT with operands MULOP1 and MULOP2
3032 with uses in additions and subtractions to form fused multiply-add 3039 with uses in additions and subtractions to form fused multiply-add
3033 operations. Returns true if successful and MUL_STMT should be removed. 3040 operations. Returns true if successful and MUL_STMT should be removed.
3041 If MUL_COND is nonnull, the multiplication in MUL_STMT is conditional
3042 on MUL_COND, otherwise it is unconditional.
3034 3043
3035 If STATE indicates that we are deferring FMA transformation, that means 3044 If STATE indicates that we are deferring FMA transformation, that means
3036 that we do not produce FMAs for basic blocks which look like: 3045 that we do not produce FMAs for basic blocks which look like:
3037 3046
3038 <bb 6> 3047 <bb 6>
3045 and if we later discover an FMA candidate that is not part of such a chain, 3054 and if we later discover an FMA candidate that is not part of such a chain,
3046 we go back and perform all deferred past candidates. */ 3055 we go back and perform all deferred past candidates. */
3047 3056
3048 static bool 3057 static bool
3049 convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2, 3058 convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2,
3050 fma_deferring_state *state) 3059 fma_deferring_state *state, tree mul_cond = NULL_TREE)
3051 { 3060 {
3052 tree mul_result = gimple_get_lhs (mul_stmt); 3061 tree mul_result = gimple_get_lhs (mul_stmt);
3053 tree type = TREE_TYPE (mul_result); 3062 tree type = TREE_TYPE (mul_result);
3054 gimple *use_stmt, *neguse_stmt; 3063 gimple *use_stmt, *neguse_stmt;
3055 use_operand_p use_p; 3064 use_operand_p use_p;
3077 return false; 3086 return false;
3078 3087
3079 bool check_defer 3088 bool check_defer
3080 = (state->m_deferring_p 3089 = (state->m_deferring_p
3081 && (tree_to_shwi (TYPE_SIZE (type)) 3090 && (tree_to_shwi (TYPE_SIZE (type))
3082 <= PARAM_VALUE (PARAM_AVOID_FMA_MAX_BITS))); 3091 <= param_avoid_fma_max_bits));
3083 bool defer = check_defer; 3092 bool defer = check_defer;
3093 bool seen_negate_p = false;
3084 /* Make sure that the multiplication statement becomes dead after 3094 /* Make sure that the multiplication statement becomes dead after
3085 the transformation, thus that all uses are transformed to FMAs. 3095 the transformation, thus that all uses are transformed to FMAs.
3086 This means we assume that an FMA operation has the same cost 3096 This means we assume that an FMA operation has the same cost
3087 as an addition. */ 3097 as an addition. */
3088 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, mul_result) 3098 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, mul_result)
3112 && gimple_assign_rhs_code (use_stmt) == NEGATE_EXPR) 3122 && gimple_assign_rhs_code (use_stmt) == NEGATE_EXPR)
3113 { 3123 {
3114 ssa_op_iter iter; 3124 ssa_op_iter iter;
3115 use_operand_p usep; 3125 use_operand_p usep;
3116 3126
3127 /* If (due to earlier missed optimizations) we have two
3128 negates of the same value, treat them as equivalent
3129 to a single negate with multiple uses. */
3130 if (seen_negate_p)
3131 return false;
3132
3117 result = gimple_assign_lhs (use_stmt); 3133 result = gimple_assign_lhs (use_stmt);
3118 3134
3119 /* Make sure the negate statement becomes dead with this 3135 /* Make sure the negate statement becomes dead with this
3120 single transformation. */ 3136 single transformation. */
3121 if (!single_imm_use (gimple_assign_lhs (use_stmt), 3137 if (!single_imm_use (gimple_assign_lhs (use_stmt),
3130 /* Re-validate. */ 3146 /* Re-validate. */
3131 use_stmt = neguse_stmt; 3147 use_stmt = neguse_stmt;
3132 if (gimple_bb (use_stmt) != gimple_bb (mul_stmt)) 3148 if (gimple_bb (use_stmt) != gimple_bb (mul_stmt))
3133 return false; 3149 return false;
3134 3150
3135 negate_p = true; 3151 negate_p = seen_negate_p = true;
3136 } 3152 }
3137 3153
3138 tree cond, else_value, ops[3]; 3154 tree cond, else_value, ops[3];
3139 tree_code code; 3155 tree_code code;
3140 if (!can_interpret_as_conditional_op_p (use_stmt, &cond, &code, ops, 3156 if (!can_interpret_as_conditional_op_p (use_stmt, &cond, &code, ops,
3151 break; 3167 break;
3152 default: 3168 default:
3153 /* FMA can only be formed from PLUS and MINUS. */ 3169 /* FMA can only be formed from PLUS and MINUS. */
3154 return false; 3170 return false;
3155 } 3171 }
3172
3173 if (mul_cond && cond != mul_cond)
3174 return false;
3156 3175
3157 if (cond) 3176 if (cond)
3158 { 3177 {
3159 if (cond == result || else_value == result) 3178 if (cond == result || else_value == result)
3160 return false; 3179 return false;
3722 void 3741 void
3723 math_opts_dom_walker::after_dom_children (basic_block bb) 3742 math_opts_dom_walker::after_dom_children (basic_block bb)
3724 { 3743 {
3725 gimple_stmt_iterator gsi; 3744 gimple_stmt_iterator gsi;
3726 3745
3727 fma_deferring_state fma_state (PARAM_VALUE (PARAM_AVOID_FMA_MAX_BITS) > 0); 3746 fma_deferring_state fma_state (param_avoid_fma_max_bits > 0);
3728 3747
3729 for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);) 3748 for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
3730 { 3749 {
3731 gimple *stmt = gsi_stmt (gsi); 3750 gimple *stmt = gsi_stmt (gsi);
3732 enum tree_code code; 3751 enum tree_code code;
3763 default:; 3782 default:;
3764 } 3783 }
3765 } 3784 }
3766 else if (is_gimple_call (stmt)) 3785 else if (is_gimple_call (stmt))
3767 { 3786 {
3768 tree fndecl = gimple_call_fndecl (stmt); 3787 switch (gimple_call_combined_fn (stmt))
3769 if (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
3770 { 3788 {
3771 switch (DECL_FUNCTION_CODE (fndecl)) 3789 CASE_CFN_POW:
3790 if (gimple_call_lhs (stmt)
3791 && TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST
3792 && real_equal (&TREE_REAL_CST (gimple_call_arg (stmt, 1)),
3793 &dconst2)
3794 && convert_mult_to_fma (stmt,
3795 gimple_call_arg (stmt, 0),
3796 gimple_call_arg (stmt, 0),
3797 &fma_state))
3772 { 3798 {
3773 case BUILT_IN_POWF: 3799 unlink_stmt_vdef (stmt);
3774 case BUILT_IN_POW: 3800 if (gsi_remove (&gsi, true)
3775 case BUILT_IN_POWL: 3801 && gimple_purge_dead_eh_edges (bb))
3776 if (gimple_call_lhs (stmt) 3802 *m_cfg_changed_p = true;
3777 && TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST 3803 release_defs (stmt);
3778 && real_equal 3804 continue;
3779 (&TREE_REAL_CST (gimple_call_arg (stmt, 1)),
3780 &dconst2)
3781 && convert_mult_to_fma (stmt,
3782 gimple_call_arg (stmt, 0),
3783 gimple_call_arg (stmt, 0),
3784 &fma_state))
3785 {
3786 unlink_stmt_vdef (stmt);
3787 if (gsi_remove (&gsi, true)
3788 && gimple_purge_dead_eh_edges (bb))
3789 *m_cfg_changed_p = true;
3790 release_defs (stmt);
3791 continue;
3792 }
3793 break;
3794
3795 default:;
3796 } 3805 }
3806 break;
3807
3808 case CFN_COND_MUL:
3809 if (convert_mult_to_fma (stmt,
3810 gimple_call_arg (stmt, 1),
3811 gimple_call_arg (stmt, 2),
3812 &fma_state,
3813 gimple_call_arg (stmt, 0)))
3814
3815 {
3816 gsi_remove (&gsi, true);
3817 release_defs (stmt);
3818 continue;
3819 }
3820 break;
3821
3822 case CFN_LAST:
3823 cancel_fma_deferring (&fma_state);
3824 break;
3825
3826 default:
3827 break;
3797 } 3828 }
3798 else
3799 cancel_fma_deferring (&fma_state);
3800 } 3829 }
3801 gsi_next (&gsi); 3830 gsi_next (&gsi);
3802 } 3831 }
3803 if (fma_state.m_deferring_p 3832 if (fma_state.m_deferring_p
3804 && fma_state.m_initial_phi) 3833 && fma_state.m_initial_phi)
3818 { 3847 {
3819 bool cfg_changed = false; 3848 bool cfg_changed = false;
3820 3849
3821 memset (&widen_mul_stats, 0, sizeof (widen_mul_stats)); 3850 memset (&widen_mul_stats, 0, sizeof (widen_mul_stats));
3822 calculate_dominance_info (CDI_DOMINATORS); 3851 calculate_dominance_info (CDI_DOMINATORS);
3823 renumber_gimple_stmt_uids (); 3852 renumber_gimple_stmt_uids (cfun);
3824 3853
3825 math_opts_dom_walker (&cfg_changed).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun)); 3854 math_opts_dom_walker (&cfg_changed).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
3826 3855
3827 statistics_counter_event (fun, "widening multiplications inserted", 3856 statistics_counter_event (fun, "widening multiplications inserted",
3828 widen_mul_stats.widen_mults_inserted); 3857 widen_mul_stats.widen_mults_inserted);