public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Remove fully propagated stmts during substitute_and_fold
@ 2014-06-16 13:26 Richard Biener
  0 siblings, 0 replies; only message in thread
From: Richard Biener @ 2014-06-16 13:26 UTC (permalink / raw)
  To: gcc-patches


This adjusts substitute_and_fold similar to how the FRE/PRE propagation 
stage works which means we properly cleanup after ourselves with
respect to DCE (if we are allowed to).  The patch removes the
poor-mans DCE code (checking for has_zero_uses) as that doesn't
really belong here and as it doesn't work reliably anymore with
doing this in a DOM walk (which is to make debug stmt generation
happy).

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2014-06-16  Richard Biener  <rguenther@suse.de>

	* tree-ssa-propagate.c: Include domwalk.h.
	(substitute_and_fold): Outline main worker into a domwalker ...
	(substitute_and_fold_dom_walker::before_dom_children): ... here.
	Schedule stmts we can fully propagate for removal.  Remove
	poor-mans DCE.
	(substitute_and_fold): Apply a dominator walk to perform
	substitution.  Process stmts scheduled for removal here.

	* gcc.dg/tree-ssa/20041122-1.c: Adjust.
	* gcc.dg/tree-ssa/forwprop-21.c: Likewise.
	* gcc.dg/tree-ssa/vrp35.c: Revert previous adjustments.
	* gcc.dg/tree-ssa/vrp36.c: Likewise.
	* gcc.dg/vect/nodump-forwprop-22.c: Adjust.

Index: gcc/tree-ssa-propagate.c
===================================================================
*** gcc/tree-ssa-propagate.c.orig	2014-06-16 14:16:21.325565287 +0200
--- gcc/tree-ssa-propagate.c	2014-06-16 14:26:20.748524017 +0200
***************
*** 49,54 ****
--- 49,55 ----
  #include "tree-ssa-propagate.h"
  #include "langhooks.h"
  #include "value-prof.h"
+ #include "domwalk.h"
  
  /* This file implements a generic value propagation engine based on
     the same propagation used by the SSA-CCP algorithm [1].
*************** replace_phi_args_in (gimple phi, ssa_pro
*** 1017,1241 ****
  }
  
  
! /* Perform final substitution and folding of propagated values.
! 
!    PROP_VALUE[I] contains the single value that should be substituted
!    at every use of SSA name N_I.  If PROP_VALUE is NULL, no values are
!    substituted.
! 
!    If FOLD_FN is non-NULL the function will be invoked on all statements
!    before propagating values for pass specific simplification.
  
!    DO_DCE is true if trivially dead stmts can be removed.
  
!    If DO_DCE is true, the statements within a BB are walked from
!    last to first element.  Otherwise we scan from first to last element.
! 
!    Return TRUE when something changed.  */
  
! bool
! substitute_and_fold (ssa_prop_get_value_fn get_value_fn,
! 		     ssa_prop_fold_stmt_fn fold_fn,
! 		     bool do_dce)
  {
!   basic_block bb;
!   bool something_changed = false;
!   unsigned i;
  
!   if (!get_value_fn && !fold_fn)
!     return false;
  
!   if (dump_file && (dump_flags & TDF_DETAILS))
!     fprintf (dump_file, "\nSubstituting values and folding statements\n\n");
  
!   memset (&prop_stats, 0, sizeof (prop_stats));
  
!   /* Substitute lattice values at definition sites.  */
!   if (get_value_fn)
!     for (i = 1; i < num_ssa_names; ++i)
!       {
! 	tree name = ssa_name (i);
! 	tree val;
! 	gimple def_stmt;
! 	gimple_stmt_iterator gsi;
! 
! 	if (!name
! 	    || virtual_operand_p (name))
! 	  continue;
! 
! 	def_stmt = SSA_NAME_DEF_STMT (name);
! 	if (gimple_nop_p (def_stmt)
! 	    /* Do not substitute ASSERT_EXPR rhs, this will confuse VRP.  */
! 	    || (gimple_assign_single_p (def_stmt)
! 		&& gimple_assign_rhs_code (def_stmt) == ASSERT_EXPR)
! 	    || !(val = (*get_value_fn) (name))
! 	    || !may_propagate_copy (name, val))
! 	  continue;
! 
! 	gsi = gsi_for_stmt (def_stmt);
! 	if (is_gimple_assign (def_stmt))
! 	  {
! 	    gimple_assign_set_rhs_with_ops (&gsi, TREE_CODE (val),
! 					    val, NULL_TREE);
! 	    gcc_assert (gsi_stmt (gsi) == def_stmt);
! 	    if (maybe_clean_eh_stmt (def_stmt))
! 	      gimple_purge_dead_eh_edges (gimple_bb (def_stmt));
! 	    update_stmt (def_stmt);
! 	  }
! 	else if (is_gimple_call (def_stmt))
! 	  {
! 	    int flags = gimple_call_flags (def_stmt);
! 
! 	    /* Don't optimize away calls that have side-effects.  */
! 	    if ((flags & (ECF_CONST|ECF_PURE)) == 0
! 		|| (flags & ECF_LOOPING_CONST_OR_PURE))
! 	      continue;
! 	    if (update_call_from_tree (&gsi, val)
! 		&& maybe_clean_or_replace_eh_stmt (def_stmt, gsi_stmt (gsi)))
! 	      gimple_purge_dead_eh_edges (gimple_bb (gsi_stmt (gsi)));
! 	  }
! 	else if (gimple_code (def_stmt) == GIMPLE_PHI)
! 	  {
! 	    gimple new_stmt = gimple_build_assign (name, val);
! 	    gimple_stmt_iterator gsi2;
! 	    gsi2 = gsi_after_labels (gimple_bb (def_stmt));
! 	    gsi_insert_before (&gsi2, new_stmt, GSI_SAME_STMT);
! 	    remove_phi_node (&gsi, false);
! 	  }
! 
! 	something_changed = true;
!       }
! 
!   /* Propagate into all uses and fold.  */
!   FOR_EACH_BB_FN (bb, cfun)
!     {
!       gimple_stmt_iterator i;
! 
!       /* Propagate known values into PHI nodes.  */
!       if (get_value_fn)
! 	for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i))
! 	  replace_phi_args_in (gsi_stmt (i), get_value_fn);
! 
!       /* Propagate known values into stmts.  Do a backward walk if
!          do_dce is true. In some case it exposes
! 	 more trivially deletable stmts to walk backward.  */
!       for (i = (do_dce ? gsi_last_bb (bb) : gsi_start_bb (bb)); !gsi_end_p (i);)
  	{
!           bool did_replace;
! 	  gimple stmt = gsi_stmt (i);
! 	  gimple old_stmt;
! 	  enum gimple_code code = gimple_code (stmt);
! 	  gimple_stmt_iterator oldi;
! 
! 	  oldi = i;
! 	  if (do_dce)
! 	    gsi_prev (&i);
! 	  else
! 	    gsi_next (&i);
! 
! 	  /* Ignore ASSERT_EXPRs.  They are used by VRP to generate
! 	     range information for names and they are discarded
! 	     afterwards.  */
! 
! 	  if (code == GIMPLE_ASSIGN
! 	      && TREE_CODE (gimple_assign_rhs1 (stmt)) == ASSERT_EXPR)
! 	    continue;
! 
! 	  /* No point propagating into a stmt whose result is not used,
! 	     but instead we might be able to remove a trivially dead stmt.
! 	     Don't do this when called from VRP, since the SSA_NAME which
! 	     is going to be released could be still referenced in VRP
! 	     ranges.  */
! 	  if (do_dce
! 	      && gimple_get_lhs (stmt)
! 	      && TREE_CODE (gimple_get_lhs (stmt)) == SSA_NAME
! 	      && has_zero_uses (gimple_get_lhs (stmt))
  	      && !stmt_could_throw_p (stmt)
  	      && !gimple_has_side_effects (stmt))
  	    {
! 	      gimple_stmt_iterator i2;
! 
! 	      if (dump_file && dump_flags & TDF_DETAILS)
! 		{
! 		  fprintf (dump_file, "Removing dead stmt ");
! 		  print_gimple_stmt (dump_file, stmt, 0, 0);
! 		  fprintf (dump_file, "\n");
! 		}
! 	      prop_stats.num_dce++;
! 	      i2 = gsi_for_stmt (stmt);
! 	      gsi_remove (&i2, true);
! 	      release_defs (stmt);
  	      continue;
  	    }
  
! 	  /* Replace the statement with its folded version and mark it
! 	     folded.  */
! 	  did_replace = false;
! 	  if (dump_file && (dump_flags & TDF_DETAILS))
  	    {
! 	      fprintf (dump_file, "Folding statement: ");
! 	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
  	    }
  
! 	  old_stmt = stmt;
  
! 	  /* Some statements may be simplified using propagator
! 	     specific information.  Do this before propagating
! 	     into the stmt to not disturb pass specific information.  */
! 	  if (fold_fn
! 	      && (*fold_fn)(&oldi))
  	    {
! 	      did_replace = true;
! 	      prop_stats.num_stmts_folded++;
! 	      stmt = gsi_stmt (oldi);
! 	      update_stmt (stmt);
  	    }
  
- 	  /* Replace real uses in the statement.  */
- 	  if (get_value_fn)
- 	    did_replace |= replace_uses_in (stmt, get_value_fn);
  
- 	  /* If we made a replacement, fold the statement.  */
- 	  if (did_replace)
- 	    fold_stmt (&oldi);
  
! 	  /* Now cleanup.  */
! 	  if (did_replace)
! 	    {
! 	      stmt = gsi_stmt (oldi);
  
!               /* If we cleaned up EH information from the statement,
!                  remove EH edges.  */
! 	      if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
! 		gimple_purge_dead_eh_edges (bb);
! 
!               if (is_gimple_assign (stmt)
!                   && (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
!                       == GIMPLE_SINGLE_RHS))
!               {
!                 tree rhs = gimple_assign_rhs1 (stmt);
  
!                 if (TREE_CODE (rhs) == ADDR_EXPR)
!                   recompute_tree_invariant_for_addr_expr (rhs);
!               }
  
! 	      /* Determine what needs to be done to update the SSA form.  */
! 	      update_stmt (stmt);
! 	      if (!is_gimple_debug (stmt))
! 		something_changed = true;
! 	    }
  
! 	  if (dump_file && (dump_flags & TDF_DETAILS))
! 	    {
! 	      if (did_replace)
! 		{
! 		  fprintf (dump_file, "Folded into: ");
! 		  print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
! 		  fprintf (dump_file, "\n");
! 		}
! 	      else
! 		fprintf (dump_file, "Not folded\n");
! 	    }
  	}
      }
  
--- 1018,1235 ----
  }
  
  
! class substitute_and_fold_dom_walker : public dom_walker
! {
! public:
!     substitute_and_fold_dom_walker (cdi_direction direction,
! 				    ssa_prop_get_value_fn get_value_fn_,
! 				    ssa_prop_fold_stmt_fn fold_fn_,
! 				    bool do_dce_)
! 	: dom_walker (direction), get_value_fn (get_value_fn_),
!       fold_fn (fold_fn_), do_dce (do_dce_), something_changed (false)
!     {
!       stmts_to_remove.create (0);
!     }
!     ~substitute_and_fold_dom_walker () { stmts_to_remove.release (); }
  
!     virtual void before_dom_children (basic_block);
!     virtual void after_dom_children (basic_block) {}
  
!     ssa_prop_get_value_fn get_value_fn;
!     ssa_prop_fold_stmt_fn fold_fn;
!     bool do_dce;
!     bool something_changed;
!     vec<gimple> stmts_to_remove;
! };
  
! void
! substitute_and_fold_dom_walker::before_dom_children (basic_block bb)
  {
!   gimple_stmt_iterator i;
  
!   /* Propagate known values into PHI nodes.  */
!   for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i))
!     {
!       gimple phi = gsi_stmt (i);
!       tree res = gimple_phi_result (phi);
!       if (virtual_operand_p (res))
! 	continue;
!       if (do_dce
! 	  && res && TREE_CODE (res) == SSA_NAME)
! 	{
! 	  tree sprime = get_value_fn (res);
! 	  if (sprime
! 	      && sprime != res
! 	      && may_propagate_copy (res, sprime))
! 	    {
! 	      stmts_to_remove.safe_push (phi);
! 	      continue;
! 	    }
! 	}
!       replace_phi_args_in (phi, get_value_fn);
!     }
  
!   /* Propagate known values into stmts.  In some case it exposes
!      more trivially deletable stmts to walk backward.  */
!   for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
!     {
!       bool did_replace;
!       gimple stmt = gsi_stmt (i);
!       gimple old_stmt;
!       enum gimple_code code = gimple_code (stmt);
! 
!       /* Ignore ASSERT_EXPRs.  They are used by VRP to generate
! 	 range information for names and they are discarded
! 	 afterwards.  */
  
!       if (code == GIMPLE_ASSIGN
! 	  && TREE_CODE (gimple_assign_rhs1 (stmt)) == ASSERT_EXPR)
! 	continue;
  
!       /* No point propagating into a stmt we have a value for we
!          can propagate into all uses.  Mark it for removal instead.  */
!       tree lhs = gimple_get_lhs (stmt);
!       if (do_dce
! 	  && lhs && TREE_CODE (lhs) == SSA_NAME)
  	{
! 	  tree sprime = get_value_fn (lhs);
! 	  if (sprime
! 	      && sprime != lhs
! 	      && may_propagate_copy (lhs, sprime)
  	      && !stmt_could_throw_p (stmt)
  	      && !gimple_has_side_effects (stmt))
  	    {
! 	      stmts_to_remove.safe_push (stmt);
  	      continue;
  	    }
+ 	}
+ 
+       /* Replace the statement with its folded version and mark it
+ 	 folded.  */
+       did_replace = false;
+       if (dump_file && (dump_flags & TDF_DETAILS))
+ 	{
+ 	  fprintf (dump_file, "Folding statement: ");
+ 	  print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
+ 	}
+ 
+       old_stmt = stmt;
+ 
+       /* Some statements may be simplified using propagator
+ 	 specific information.  Do this before propagating
+ 	 into the stmt to not disturb pass specific information.  */
+       if (fold_fn
+ 	  && (*fold_fn)(&i))
+ 	{
+ 	  did_replace = true;
+ 	  prop_stats.num_stmts_folded++;
+ 	  stmt = gsi_stmt (i);
+ 	  update_stmt (stmt);
+ 	}
+ 
+       /* Replace real uses in the statement.  */
+       did_replace |= replace_uses_in (stmt, get_value_fn);
+ 
+       /* If we made a replacement, fold the statement.  */
+       if (did_replace)
+ 	fold_stmt (&i);
  
!       /* Now cleanup.  */
!       if (did_replace)
! 	{
! 	  stmt = gsi_stmt (i);
! 
! 	  /* If we cleaned up EH information from the statement,
! 	     remove EH edges.  */
! 	  if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
! 	    gimple_purge_dead_eh_edges (bb);
! 
! 	  if (is_gimple_assign (stmt)
! 	      && (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
! 		  == GIMPLE_SINGLE_RHS))
  	    {
! 	      tree rhs = gimple_assign_rhs1 (stmt);
! 
! 	      if (TREE_CODE (rhs) == ADDR_EXPR)
! 		recompute_tree_invariant_for_addr_expr (rhs);
  	    }
  
! 	  /* Determine what needs to be done to update the SSA form.  */
! 	  update_stmt (stmt);
! 	  if (!is_gimple_debug (stmt))
! 	    something_changed = true;
! 	}
  
!       if (dump_file && (dump_flags & TDF_DETAILS))
! 	{
! 	  if (did_replace)
  	    {
! 	      fprintf (dump_file, "Folded into: ");
! 	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
! 	      fprintf (dump_file, "\n");
  	    }
+ 	  else
+ 	    fprintf (dump_file, "Not folded\n");
+ 	}
+     }
+ }
  
  
  
! /* Perform final substitution and folding of propagated values.
  
!    PROP_VALUE[I] contains the single value that should be substituted
!    at every use of SSA name N_I.  If PROP_VALUE is NULL, no values are
!    substituted.
  
!    If FOLD_FN is non-NULL the function will be invoked on all statements
!    before propagating values for pass specific simplification.
  
!    DO_DCE is true if trivially dead stmts can be removed.
  
!    If DO_DCE is true, the statements within a BB are walked from
!    last to first element.  Otherwise we scan from first to last element.
! 
!    Return TRUE when something changed.  */
! 
! bool
! substitute_and_fold (ssa_prop_get_value_fn get_value_fn,
! 		     ssa_prop_fold_stmt_fn fold_fn,
! 		     bool do_dce)
! {
!   gcc_assert (get_value_fn);
! 
!   if (dump_file && (dump_flags & TDF_DETAILS))
!     fprintf (dump_file, "\nSubstituting values and folding statements\n\n");
! 
!   memset (&prop_stats, 0, sizeof (prop_stats));
! 
!   calculate_dominance_info (CDI_DOMINATORS);
!   substitute_and_fold_dom_walker walker(CDI_DOMINATORS,
! 					get_value_fn, fold_fn, do_dce);
!   walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
! 
!   /* We cannot remove stmts during the BB walk, especially not release
!      SSA names there as that destroys the lattice of our callers.
!      Remove stmts in reverse order to make debug stmt creation possible.  */
!   while (!walker.stmts_to_remove.is_empty ())
!     {
!       gimple stmt = walker.stmts_to_remove.pop ();
!       if (dump_file && dump_flags & TDF_DETAILS)
! 	{
! 	  fprintf (dump_file, "Removing dead stmt ");
! 	  print_gimple_stmt (dump_file, stmt, 0, 0);
! 	  fprintf (dump_file, "\n");
! 	}
!       prop_stats.num_dce++;
!       gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
!       if (gimple_code (stmt) == GIMPLE_PHI)
! 	remove_phi_node (&gsi, true);
!       else
! 	{
! 	  unlink_stmt_vdef (stmt);
! 	  gsi_remove (&gsi, true);
! 	  release_defs (stmt);
  	}
      }
  
*************** substitute_and_fold (ssa_prop_get_value_
*** 1247,1253 ****
  			    prop_stats.num_stmts_folded);
    statistics_counter_event (cfun, "Statements deleted",
  			    prop_stats.num_dce);
!   return something_changed;
  }
  
  
--- 1241,1248 ----
  			    prop_stats.num_stmts_folded);
    statistics_counter_event (cfun, "Statements deleted",
  			    prop_stats.num_dce);
! 
!   return walker.something_changed;
  }
  
  
Index: gcc/testsuite/gcc.dg/tree-ssa/20041122-1.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/20041122-1.c.orig	2014-06-16 14:16:21.325565287 +0200
--- gcc/testsuite/gcc.dg/tree-ssa/20041122-1.c	2014-06-16 14:21:06.239545671 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fstrict-aliasing -fdump-tree-fre1" } */
  
  __extension__ typedef __SIZE_TYPE__ size_t;
  extern void *xmalloc (size_t) __attribute__ ((__malloc__));
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fstrict-aliasing -fdump-tree-cddce1" } */
  
  __extension__ typedef __SIZE_TYPE__ size_t;
  extern void *xmalloc (size_t) __attribute__ ((__malloc__));
*************** find_unreachable_blocks (void)
*** 34,38 ****
     able to determine that modifying e->dest->flags does not
     modify e or e->dest if we can assert strict-aliasing rules.
     The net result is that we only need one load of e->dest.  */
! /* { dg-final { scan-tree-dump-times "->dest" 1 "fre1" } } */
! /* { dg-final { cleanup-tree-dump "fre1" } } */
--- 34,38 ----
     able to determine that modifying e->dest->flags does not
     modify e or e->dest if we can assert strict-aliasing rules.
     The net result is that we only need one load of e->dest.  */
! /* { dg-final { scan-tree-dump-times "->dest" 1 "cddce1" } } */
! /* { dg-final { cleanup-tree-dump "cddce1" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/forwprop-21.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/forwprop-21.c.orig	2014-06-16 14:16:21.325565287 +0200
--- gcc/testsuite/gcc.dg/tree-ssa/forwprop-21.c	2014-06-16 14:21:06.240545671 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O -fdump-tree-copyprop1" } */
  typedef int v4si __attribute__ ((vector_size (4 * sizeof(int))));
  
  int
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O -fdump-tree-cddce1 -fno-tree-fre" } */
  typedef int v4si __attribute__ ((vector_size (4 * sizeof(int))));
  
  int
*************** test (v4si *x, v4si *y)
*** 10,16 ****
    return z[2];
  }
  
! /* Optimization in forwprop1, cleanup in copyprop1.  */
  
! /* { dg-final { scan-tree-dump-not "VEC_PERM_EXPR" "copyprop1" } } */
! /* { dg-final { cleanup-tree-dump "copyprop1" } } */
--- 10,16 ----
    return z[2];
  }
  
! /* Optimization in forwprop1, cleanup in cddce1.  */
  
! /* { dg-final { scan-tree-dump-not "VEC_PERM_EXPR" "cddce1" } } */
! /* { dg-final { cleanup-tree-dump "cddce1" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/vrp35.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/vrp35.c.orig	2014-06-16 14:16:21.325565287 +0200
--- gcc/testsuite/gcc.dg/tree-ssa/vrp35.c	2014-06-16 14:21:06.240545671 +0200
*************** int test1(int i, int k)
*** 11,15 ****
    return 1;
  }
  
! /* { dg-final { scan-tree-dump-not "j_.* == 10" "vrp1" } } */
  /* { dg-final { cleanup-tree-dump "vrp1" } } */
--- 11,15 ----
    return 1;
  }
  
! /* { dg-final { scan-tree-dump "Folding predicate j_.* == 10 to 0" "vrp1" } } */
  /* { dg-final { cleanup-tree-dump "vrp1" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/vrp36.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/vrp36.c.orig	2014-06-16 14:16:21.325565287 +0200
--- gcc/testsuite/gcc.dg/tree-ssa/vrp36.c	2014-06-16 14:21:06.240545671 +0200
*************** int foo(int i)
*** 8,12 ****
    return 1;
  }
  
! /* { dg-final { scan-tree-dump-not "i_.* == 1" "vrp1" } } */
  /* { dg-final { cleanup-tree-dump "vrp1" } } */
--- 8,12 ----
    return 1;
  }
  
! /* { dg-final { scan-tree-dump "Folding predicate i_.* == 1 to 0" "vrp1" } } */
  /* { dg-final { cleanup-tree-dump "vrp1" } } */
Index: gcc/testsuite/gcc.dg/vect/nodump-forwprop-22.c
===================================================================
*** gcc/testsuite/gcc.dg/vect/nodump-forwprop-22.c.orig	2014-06-16 14:16:21.325565287 +0200
--- gcc/testsuite/gcc.dg/vect/nodump-forwprop-22.c	2014-06-16 14:21:06.241545671 +0200
***************
*** 1,7 ****
  /* { dg-do compile } */
  /* { dg-require-effective-target vect_double } */
  /* { dg-require-effective-target vect_perm } */
! /* { dg-additional-options "-fdump-tree-copyprop1" } */
  
  typedef double vec __attribute__((vector_size (2 * sizeof (double))));
  void f (vec *px, vec *y, vec *z)
--- 1,7 ----
  /* { dg-do compile } */
  /* { dg-require-effective-target vect_double } */
  /* { dg-require-effective-target vect_perm } */
! /* { dg-additional-options "-fdump-tree-cddce1 -fno-tree-fre" } */
  
  typedef double vec __attribute__((vector_size (2 * sizeof (double))));
  void f (vec *px, vec *y, vec *z)
*************** void f (vec *px, vec *y, vec *z)
*** 13,20 ****
    *z = t2;
  }
  
! /* Optimization in forwprop1, cleanup in copyprop1.  */
  
! /* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 1 "copyprop1" } } */
! /* { dg-final { scan-tree-dump-not "BIT_FIELD_REF" "copyprop1" } } */
! /* { dg-final { cleanup-tree-dump "copyprop1" } } */
--- 13,20 ----
    *z = t2;
  }
  
! /* Optimization in forwprop1, cleanup in cddce1.  */
  
! /* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 1 "cddce1" } } */
! /* { dg-final { scan-tree-dump-not "BIT_FIELD_REF" "cddce1" } } */
! /* { dg-final { cleanup-tree-dump "cddce1" } } */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2014-06-16 13:26 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-16 13:26 [PATCH] Remove fully propagated stmts during substitute_and_fold Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).