This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[3/6] Fold prev/next into gimple


Hi,

this introduces a new helper (gsi_replace_with_seq) which can replace a 
single statement with a sequence, and makes use of it in 
gimplify_and_update_call_from_tree.  This make sure that the statements 
aren't inserted into the target sequence while they still are in the 
original one.  Could also be solved by gsi_removing them just before 
inserting them, but this way seems much nicer.

The tree-ssa-forwprop.c hunk ensures that when we remove the statement 
that the iterator (in the caller) pointing to it isn't invalidated.  I 
think this was from earlier experiments of how to represent the data 
structures and might not be strictly needed anymore, but I've always 
tested with it, and it's definitely not harmful.

As per [0/6] regstrapped with the other five on x86_64-linux.  Okay for 
trunk?


Ciao,
Michael.
----------------------
2012-05-02  Michael Matz  <matz@suse.de>

	* gimple-fold.c (gimplify_and_update_call_from_tree): Use
	gsi_replace_with_seq, instead of inserting itself.
	* gimple-iterator.c (gsi_replace_with_seq): New function.
	* tree-ssa-forwprop.c (forward_propagate_comparison): Take
	iterator instead of statement, advance it.
	(ssa_forward_propagate_and_combine): Adjust call to above.

Index: gimple-fold.c
===================================================================
*** gimple-fold.c.orig	2012-05-01 22:44:02.000000000 +0200
--- gimple-fold.c	2012-05-01 22:44:06.000000000 +0200
*************** gimplify_and_update_call_from_tree (gimp
*** 551,557 ****
    gimple_stmt_iterator i;
    gimple_seq stmts = NULL;
    struct gimplify_ctx gctx;
-   gimple last;
    gimple laststore;
    tree reaching_vuse;
  
--- 551,556 ----
*************** gimplify_and_update_call_from_tree (gimp
*** 620,636 ****
  
    /* Second iterate over the statements forward, assigning virtual
       operands to their uses.  */
-   last = NULL;
    reaching_vuse = gimple_vuse (stmt);
    for (i = gsi_start (stmts); !gsi_end_p (i); gsi_next (&i))
      {
-       /* Do not insert the last stmt in this loop but remember it
-          for replacing the original statement.  */
-       if (last)
- 	{
- 	  gsi_insert_before (si_p, last, GSI_NEW_STMT);
- 	  gsi_next (si_p);
- 	}
        new_stmt = gsi_stmt (i);
        /* The replacement can expose previously unreferenced variables.  */
        if (gimple_in_ssa_p (cfun))
--- 619,627 ----
*************** gimplify_and_update_call_from_tree (gimp
*** 642,648 ****
        gimple_set_modified (new_stmt, true);
        if (gimple_vdef (new_stmt))
  	reaching_vuse = gimple_vdef (new_stmt);
-       last = new_stmt;
      }
  
    /* If the new sequence does not do a store release the virtual
--- 633,638 ----
*************** gimplify_and_update_call_from_tree (gimp
*** 659,666 ****
  	}
      }
  
!   /* Finally replace rhe original statement with the last.  */
!   gsi_replace (si_p, last, false);
  }
  
  /* Return the string length, maximum string length or maximum value of
--- 649,656 ----
  	}
      }
  
!   /* Finally replace the original statement with the sequence.  */
!   gsi_replace_with_seq (si_p, stmts, false);
  }
  
  /* Return the string length, maximum string length or maximum value of
Index: gimple-iterator.c
===================================================================
*** gimple-iterator.c.orig	2012-05-01 22:43:34.000000000 +0200
--- gimple-iterator.c	2012-05-01 22:44:06.000000000 +0200
*************** gsi_replace (gimple_stmt_iterator *gsi,
*** 433,438 ****
--- 433,456 ----
    update_modified_stmt (stmt);
  }
  
+ void
+ gsi_replace_with_seq (gimple_stmt_iterator *gsi, gimple_seq seq,
+ 		      bool update_eh_info)
+ {
+   gimple_stmt_iterator seqi;
+   gimple last;
+   if (gimple_seq_empty_p (seq))
+     {
+       gsi_remove (gsi, true);
+       return;
+     }
+   seqi = gsi_last (seq);
+   last = gsi_stmt (seqi);
+   gsi_remove (&seqi, false);
+   gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT);
+   gsi_replace (gsi, last, update_eh_info);
+ }
+ 
  
  /* Insert statement STMT before the statement pointed-to by iterator I.
     M specifies how to update iterator I after insertion (see enum
Index: tree-ssa-forwprop.c
===================================================================
*** tree-ssa-forwprop.c.orig	2012-05-01 22:39:07.000000000 +0200
--- tree-ssa-forwprop.c	2012-05-01 22:44:06.000000000 +0200
*************** forward_propagate_addr_expr (tree name,
*** 1202,1217 ****
  }
  
  
! /* Forward propagate the comparison defined in STMT like
     cond_1 = x CMP y to uses of the form
       a_1 = (T')cond_1
       a_1 = !cond_1
       a_1 = cond_1 != 0
!    Returns true if stmt is now unused.  */
  
  static bool
! forward_propagate_comparison (gimple stmt)
  {
    tree name = gimple_assign_lhs (stmt);
    gimple use_stmt;
    tree tmp = NULL_TREE;
--- 1202,1219 ----
  }
  
  
! /* Forward propagate the comparison defined in *DEFGSI like
     cond_1 = x CMP y to uses of the form
       a_1 = (T')cond_1
       a_1 = !cond_1
       a_1 = cond_1 != 0
!    Returns true if stmt is now unused.  Advance DEFGSI to the next
!    statement.  */
  
  static bool
! forward_propagate_comparison (gimple_stmt_iterator *defgsi)
  {
+   gimple stmt = gsi_stmt (*defgsi);
    tree name = gimple_assign_lhs (stmt);
    gimple use_stmt;
    tree tmp = NULL_TREE;
*************** forward_propagate_comparison (gimple stm
*** 1224,1241 ****
         && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (stmt)))
        || (TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME
          && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs2 (stmt))))
!     return false;
  
    /* Do not un-cse comparisons.  But propagate through copies.  */
    use_stmt = get_prop_dest_stmt (name, &name);
    if (!use_stmt
        || !is_gimple_assign (use_stmt))
!     return false;
  
    code = gimple_assign_rhs_code (use_stmt);
    lhs = gimple_assign_lhs (use_stmt);
    if (!INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
!     return false;
  
    /* We can propagate the condition into a statement that
       computes the logical negation of the comparison result.  */
--- 1226,1243 ----
         && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (stmt)))
        || (TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME
          && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs2 (stmt))))
!     goto bailout;
  
    /* Do not un-cse comparisons.  But propagate through copies.  */
    use_stmt = get_prop_dest_stmt (name, &name);
    if (!use_stmt
        || !is_gimple_assign (use_stmt))
!     goto bailout;
  
    code = gimple_assign_rhs_code (use_stmt);
    lhs = gimple_assign_lhs (use_stmt);
    if (!INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
!     goto bailout;
  
    /* We can propagate the condition into a statement that
       computes the logical negation of the comparison result.  */
*************** forward_propagate_comparison (gimple stm
*** 1249,1261 ****
        enum tree_code inv_code;
        inv_code = invert_tree_comparison (gimple_assign_rhs_code (stmt), nans);
        if (inv_code == ERROR_MARK)
! 	return false;
  
        tmp = build2 (inv_code, TREE_TYPE (lhs), gimple_assign_rhs1 (stmt),
  		    gimple_assign_rhs2 (stmt));
      }
    else
!     return false;
  
    gsi = gsi_for_stmt (use_stmt);
    gimple_assign_set_rhs_from_tree (&gsi, unshare_expr (tmp));
--- 1251,1263 ----
        enum tree_code inv_code;
        inv_code = invert_tree_comparison (gimple_assign_rhs_code (stmt), nans);
        if (inv_code == ERROR_MARK)
! 	goto bailout;
  
        tmp = build2 (inv_code, TREE_TYPE (lhs), gimple_assign_rhs1 (stmt),
  		    gimple_assign_rhs2 (stmt));
      }
    else
!     goto bailout;
  
    gsi = gsi_for_stmt (use_stmt);
    gimple_assign_set_rhs_from_tree (&gsi, unshare_expr (tmp));
*************** forward_propagate_comparison (gimple stm
*** 1271,1278 ****
--- 1273,1288 ----
        fprintf (dump_file, "'\n");
      }
  
+   /* When we remove stmt now the iterator defgsi goes off it's current
+      sequence, hence advance it now.  */
+   gsi_next (defgsi);
+ 
    /* Remove defining statements.  */
    return remove_prop_source_from_use (name);
+ 
+ bailout:
+   gsi_next (defgsi);
+   return false;
  }
  
  
*************** ssa_forward_propagate_and_combine (void)
*** 2682,2690 ****
  	    }
  	  else if (TREE_CODE_CLASS (code) == tcc_comparison)
  	    {
! 	      if (forward_propagate_comparison (stmt))
  	        cfg_changed = true;
- 	      gsi_next (&gsi);
  	    }
  	  else
  	    gsi_next (&gsi);
--- 2692,2699 ----
  	    }
  	  else if (TREE_CODE_CLASS (code) == tcc_comparison)
  	    {
! 	      if (forward_propagate_comparison (&gsi))
  	        cfg_changed = true;
  	    }
  	  else
  	    gsi_next (&gsi);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]