diff gcc/tree-ssa-math-opts.c @ 146:351920fa3827

merge
author anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Sun, 01 Mar 2020 16:13:28 +0900
parents 1830386684a0
children
line wrap: on
line diff
--- a/gcc/tree-ssa-math-opts.c	Sun Dec 23 21:23:56 2018 +0900
+++ b/gcc/tree-ssa-math-opts.c	Sun Mar 01 16:13:28 2020 +0900
@@ -1,5 +1,5 @@
 /* Global, SSA-based optimizations using mathematical identities.
-   Copyright (C) 2005-2018 Free Software Foundation, Inc.
+   Copyright (C) 2005-2020 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -109,7 +109,6 @@
 #include "tree-dfa.h"
 #include "tree-ssa.h"
 #include "builtins.h"
-#include "params.h"
 #include "internal-fn.h"
 #include "case-cfn-macros.h"
 #include "optabs-libfuncs.h"
@@ -334,7 +333,8 @@
 	 /* Do not recognize x / x as valid division, as we are getting
 	    confused later by replacing all immediate uses x in such
 	    a stmt.  */
-	 && gimple_assign_rhs1 (use_stmt) != def;
+	 && gimple_assign_rhs1 (use_stmt) != def
+	 && !stmt_can_throw_internal (cfun, use_stmt);
 }
 
 /* Return TRUE if USE_STMT is a multiplication of DEF by A.  */
@@ -367,13 +367,12 @@
 {
   if (gimple_code (use_stmt) == GIMPLE_ASSIGN
       && gimple_assign_rhs_code (use_stmt) == RDIV_EXPR
-      && gimple_assign_rhs1 (use_stmt) != gimple_assign_rhs2 (use_stmt))
+      && gimple_assign_rhs1 (use_stmt) != gimple_assign_rhs2 (use_stmt)
+      && !stmt_can_throw_internal (cfun, use_stmt))
     {
       tree denominator = gimple_assign_rhs2 (use_stmt);
       if (TREE_CODE (denominator) == SSA_NAME)
-	{
-	  return is_square_of (SSA_NAME_DEF_STMT (denominator), def);
-	}
+	return is_square_of (SSA_NAME_DEF_STMT (denominator), def);
     }
   return 0;
 }
@@ -652,8 +651,12 @@
 	  print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
 	  fprintf (dump_file, "with new division\n");
 	}
-      gimple_assign_set_lhs (stmt, sqr_ssa_name);
-      gimple_assign_set_rhs2 (stmt, a);
+      stmt
+	= gimple_build_assign (sqr_ssa_name, gimple_assign_rhs_code (stmt),
+			       gimple_assign_rhs1 (stmt), a);
+      gsi_insert_before (def_gsi, stmt, GSI_SAME_STMT);
+      gsi_remove (def_gsi, true);
+      *def_gsi = gsi_for_stmt (stmt);
       fold_stmt_inplace (def_gsi);
       update_stmt (stmt);
 
@@ -704,7 +707,7 @@
 
       gimple *new_stmt
 	= gimple_build_assign (x, MULT_EXPR,
-				orig_sqrt_ssa_name, sqr_ssa_name);
+			       orig_sqrt_ssa_name, sqr_ssa_name);
       gsi_insert_after (def_gsi, new_stmt, GSI_NEW_STMT);
       update_stmt (stmt);
     }
@@ -715,6 +718,8 @@
       gsi_remove (&gsi2, true);
       release_defs (stmt);
     }
+  else
+    release_ssa_name (x);
 }
 
 /* Look for floating-point divisions among DEF's uses, and try to
@@ -793,7 +798,7 @@
 
   /* If it is more profitable to optimize 1 / x, don't optimize 1 / (x * x).  */
   if (sqrt_recip_count > square_recip_count)
-    return;
+    goto out;
 
   /* Do the expensive part only if we can hope to optimize something.  */
   if (count + square_recip_count >= threshold && count >= 1)
@@ -836,6 +841,7 @@
 	}
     }
 
+out:
   for (occ = occ_head; occ; )
     occ = free_bb (occ);
 
@@ -951,6 +957,7 @@
 	      stmt = gsi_stmt (gsi);
 	      if (flag_unsafe_math_optimizations
 		  && is_gimple_assign (stmt)
+		  && gimple_assign_lhs (stmt) == def
 		  && !stmt_can_throw_internal (cfun, stmt)
 		  && gimple_assign_rhs_code (stmt) == RDIV_EXPR)
 		optimize_recip_sqrt (&gsi, def);
@@ -1032,14 +1039,9 @@
 		      else
 			stmt2 = gimple_build_call_internal_vec (ifn, args);
 		      gimple_call_set_lhs (stmt2, arg1);
-		      if (gimple_vdef (call))
-			{
-			  gimple_set_vdef (stmt2, gimple_vdef (call));
-			  SSA_NAME_DEF_STMT (gimple_vdef (stmt2)) = stmt2;
-			}
+		      gimple_move_vops (stmt2, call);
 		      gimple_call_set_nothrow (stmt2,
 					       gimple_call_nothrow_p (call));
-		      gimple_set_vuse (stmt2, gimple_vuse (call));
 		      gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
 		      gsi_replace (&gsi2, stmt2, true);
 		    }
@@ -1972,7 +1974,7 @@
       && !HONOR_SIGNED_ZEROS (mode))
     {
       unsigned int max_depth = speed_p
-				? PARAM_VALUE (PARAM_MAX_POW_SQRT_DEPTH)
+				? param_max_pow_sqrt_depth
 				: 2;
 
       tree expand_with_sqrts
@@ -2909,8 +2911,13 @@
       gsi_replace (&gsi, fma_stmt, true);
       /* Follow all SSA edges so that we generate FMS, FNMA and FNMS
 	 regardless of where the negation occurs.  */
+      gimple *orig_stmt = gsi_stmt (gsi);
       if (fold_stmt (&gsi, follow_all_ssa_edges))
-	update_stmt (gsi_stmt (gsi));
+	{
+	  if (maybe_clean_or_replace_eh_stmt (orig_stmt, gsi_stmt (gsi)))
+	    gcc_unreachable ();
+	  update_stmt (gsi_stmt (gsi));
+	}
 
       if (dump_file && (dump_flags & TDF_DETAILS))
 	{
@@ -3031,6 +3038,8 @@
 /* Combine the multiplication at MUL_STMT with operands MULOP1 and MULOP2
    with uses in additions and subtractions to form fused multiply-add
    operations.  Returns true if successful and MUL_STMT should be removed.
+   If MUL_COND is nonnull, the multiplication in MUL_STMT is conditional
+   on MUL_COND, otherwise it is unconditional.
 
    If STATE indicates that we are deferring FMA transformation, that means
    that we do not produce FMAs for basic blocks which look like:
@@ -3047,7 +3056,7 @@
 
 static bool
 convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2,
-		     fma_deferring_state *state)
+		     fma_deferring_state *state, tree mul_cond = NULL_TREE)
 {
   tree mul_result = gimple_get_lhs (mul_stmt);
   tree type = TREE_TYPE (mul_result);
@@ -3079,8 +3088,9 @@
   bool check_defer
     = (state->m_deferring_p
        && (tree_to_shwi (TYPE_SIZE (type))
-	   <= PARAM_VALUE (PARAM_AVOID_FMA_MAX_BITS)));
+	   <= param_avoid_fma_max_bits));
   bool defer = check_defer;
+  bool seen_negate_p = false;
   /* Make sure that the multiplication statement becomes dead after
      the transformation, thus that all uses are transformed to FMAs.
      This means we assume that an FMA operation has the same cost
@@ -3114,6 +3124,12 @@
 	  ssa_op_iter iter;
 	  use_operand_p usep;
 
+	  /* If (due to earlier missed optimizations) we have two
+	     negates of the same value, treat them as equivalent
+	     to a single negate with multiple uses.  */
+	  if (seen_negate_p)
+	    return false;
+
 	  result = gimple_assign_lhs (use_stmt);
 
 	  /* Make sure the negate statement becomes dead with this
@@ -3132,7 +3148,7 @@
 	  if (gimple_bb (use_stmt) != gimple_bb (mul_stmt))
 	    return false;
 
-	  negate_p = true;
+	  negate_p = seen_negate_p = true;
 	}
 
       tree cond, else_value, ops[3];
@@ -3154,6 +3170,9 @@
 	  return false;
 	}
 
+      if (mul_cond && cond != mul_cond)
+	return false;
+
       if (cond)
 	{
 	  if (cond == result || else_value == result)
@@ -3724,7 +3743,7 @@
 {
   gimple_stmt_iterator gsi;
 
-  fma_deferring_state fma_state (PARAM_VALUE (PARAM_AVOID_FMA_MAX_BITS) > 0);
+  fma_deferring_state fma_state (param_avoid_fma_max_bits > 0);
 
   for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
     {
@@ -3765,38 +3784,48 @@
 	}
       else if (is_gimple_call (stmt))
 	{
-	  tree fndecl = gimple_call_fndecl (stmt);
-	  if (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
+	  switch (gimple_call_combined_fn (stmt))
 	    {
-	      switch (DECL_FUNCTION_CODE (fndecl))
+	    CASE_CFN_POW:
+	      if (gimple_call_lhs (stmt)
+		  && TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST
+		  && real_equal (&TREE_REAL_CST (gimple_call_arg (stmt, 1)),
+				 &dconst2)
+		  && convert_mult_to_fma (stmt,
+					  gimple_call_arg (stmt, 0),
+					  gimple_call_arg (stmt, 0),
+					  &fma_state))
 		{
-		case BUILT_IN_POWF:
-		case BUILT_IN_POW:
-		case BUILT_IN_POWL:
-		  if (gimple_call_lhs (stmt)
-		      && TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST
-		      && real_equal
-		      (&TREE_REAL_CST (gimple_call_arg (stmt, 1)),
-		       &dconst2)
-		      && convert_mult_to_fma (stmt,
-					      gimple_call_arg (stmt, 0),
-					      gimple_call_arg (stmt, 0),
-					      &fma_state))
-		    {
-		      unlink_stmt_vdef (stmt);
-		      if (gsi_remove (&gsi, true)
-			  && gimple_purge_dead_eh_edges (bb))
-			*m_cfg_changed_p = true;
-		      release_defs (stmt);
-		      continue;
-		    }
-		  break;
-
-		default:;
+		  unlink_stmt_vdef (stmt);
+		  if (gsi_remove (&gsi, true)
+		      && gimple_purge_dead_eh_edges (bb))
+		    *m_cfg_changed_p = true;
+		  release_defs (stmt);
+		  continue;
 		}
+	      break;
+
+	    case CFN_COND_MUL:
+	      if (convert_mult_to_fma (stmt,
+				       gimple_call_arg (stmt, 1),
+				       gimple_call_arg (stmt, 2),
+				       &fma_state,
+				       gimple_call_arg (stmt, 0)))
+
+		{
+		  gsi_remove (&gsi, true);
+		  release_defs (stmt);
+		  continue;
+		}
+	      break;
+
+	    case CFN_LAST:
+	      cancel_fma_deferring (&fma_state);
+	      break;
+
+	    default:
+	      break;
 	    }
-	  else
-	    cancel_fma_deferring (&fma_state);
 	}
       gsi_next (&gsi);
     }
@@ -3820,7 +3849,7 @@
 
   memset (&widen_mul_stats, 0, sizeof (widen_mul_stats));
   calculate_dominance_info (CDI_DOMINATORS);
-  renumber_gimple_stmt_uids ();
+  renumber_gimple_stmt_uids (cfun);
 
   math_opts_dom_walker (&cfg_changed).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));