public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [gimple-classes, committed 0/6] Use gassign in 6 tree-ssa-* files
@ 2014-11-07 15:25 David Malcolm
  2014-11-07 15:25 ` [gimple-classes, committed 1/6] tree-ssa-sink.c: Use gassign David Malcolm
                   ` (5 more replies)
  0 siblings, 6 replies; 36+ messages in thread
From: David Malcolm @ 2014-11-07 15:25 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

I've pushed the following 6 patches to the git branch
"dmalcolm/gimple-classes".

This is part of ongoing work on the branch to make all
gimple_assign_* accessors take a gassign *, rather than a gimple.

Successfully bootstrapped&regrtested the combination of the 6
patches upon the branch on x86_64-unknown-linux-gnu (Fedora 20) -
same results relative to an unpatched control bootstrap of trunk's
r216746.

David Malcolm (6):
  tree-ssa-sink.c: Use gassign
  tree-ssa-strlen.c: Use gassign
  tree-ssa-structalias.c: Use gassign
  tree-ssa-tail-merge.c: Use gassign
  tree-ssa-ter.c: Use gassign
  tree-ssa-threadedge.c: Use gassign

 gcc/ChangeLog.gimple-classes | 56 ++++++++++++++++++++++++++++++++++++++++++++
 gcc/tree-ssa-sink.c          |  9 +++----
 gcc/tree-ssa-strlen.c        | 49 ++++++++++++++++++++------------------
 gcc/tree-ssa-structalias.c   | 35 ++++++++++++++-------------
 gcc/tree-ssa-tail-merge.c    |  8 ++++---
 gcc/tree-ssa-ter.c           | 16 ++++++++-----
 gcc/tree-ssa-threadedge.c    | 33 ++++++++++++++------------
 7 files changed, 139 insertions(+), 67 deletions(-)

-- 
1.7.11.7

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [gimple-classes, committed 1/6] tree-ssa-sink.c: Use gassign
  2014-11-07 15:25 [gimple-classes, committed 0/6] Use gassign in 6 tree-ssa-* files David Malcolm
@ 2014-11-07 15:25 ` David Malcolm
  2014-11-07 15:26 ` [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: " David Malcolm
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 36+ messages in thread
From: David Malcolm @ 2014-11-07 15:25 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

gcc/ChangeLog.gimple-classes:
	* tree-ssa-sink.c (statement_sink_location): Rename param "stmt"
	to "gs", reintroducing "stmt" as a local gassign * via a dyn_cast
	for typesafety.
---
 gcc/ChangeLog.gimple-classes | 6 ++++++
 gcc/tree-ssa-sink.c          | 9 +++++----
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
index 382bd3d..2c78ce0 100644
--- a/gcc/ChangeLog.gimple-classes
+++ b/gcc/ChangeLog.gimple-classes
@@ -1,5 +1,11 @@
 2014-11-06  David Malcolm  <dmalcolm@redhat.com>
 
+	* tree-ssa-sink.c (statement_sink_location): Rename param "stmt"
+	to "gs", reintroducing "stmt" as a local gassign * via a dyn_cast
+	for typesafety.
+
+2014-11-06  David Malcolm  <dmalcolm@redhat.com>
+
 	* tree-ssa-propagate.c
 	(substitute_and_fold_dom_walker::before_dom_children): Add checked
 	cast.  Replace is_gimple_assign with a dyn_cast, introducing local
diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c
index c6d8712..968ab27 100644
--- a/gcc/tree-ssa-sink.c
+++ b/gcc/tree-ssa-sink.c
@@ -256,13 +256,13 @@ select_best_block (basic_block early_bb,
   return early_bb;
 }
 
-/* Given a statement (STMT) and the basic block it is currently in (FROMBB),
+/* Given a statement (GS) and the basic block it is currently in (FROMBB),
    determine the location to sink the statement to, if any.
    Returns true if there is such location; in that case, TOGSI points to the
-   statement before that STMT should be moved.  */
+   statement before that GS should be moved.  */
 
 static bool
-statement_sink_location (gimple stmt, basic_block frombb,
+statement_sink_location (gimple gs, basic_block frombb,
 			 gimple_stmt_iterator *togsi)
 {
   gimple use;
@@ -274,7 +274,8 @@ statement_sink_location (gimple stmt, basic_block frombb,
   imm_use_iterator imm_iter;
 
   /* We only can sink assignments.  */
-  if (!is_gimple_assign (stmt))
+  gassign *stmt = dyn_cast <gassign *> (gs);
+  if (!stmt)
     return false;
 
   /* We only can sink stmts with a single definition.  */
-- 
1.7.11.7

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [gimple-classes, committed 5/6] tree-ssa-ter.c: Use gassign
  2014-11-07 15:25 [gimple-classes, committed 0/6] Use gassign in 6 tree-ssa-* files David Malcolm
                   ` (2 preceding siblings ...)
  2014-11-07 15:26 ` [gimple-classes, committed 2/6] tree-ssa-strlen.c: " David Malcolm
@ 2014-11-07 15:26 ` David Malcolm
  2014-11-07 15:26 ` [gimple-classes, committed 6/6] tree-ssa-threadedge.c: " David Malcolm
  2014-11-07 15:26 ` [gimple-classes, committed 3/6] tree-ssa-structalias.c: " David Malcolm
  5 siblings, 0 replies; 36+ messages in thread
From: David Malcolm @ 2014-11-07 15:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

gcc/ChangeLog.gimple-classes:
	* tree-ssa-ter.c (find_replaceable_in_bb): Replace
	is_gimple_assign with a dyn_cast, introducing local "def_assign"
	and using it in place of "def_stmt" for typesafety.  Add a checked
	cast.
---
 gcc/ChangeLog.gimple-classes |  7 +++++++
 gcc/tree-ssa-ter.c           | 16 ++++++++++------
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
index 0bd0421..43c05ec 100644
--- a/gcc/ChangeLog.gimple-classes
+++ b/gcc/ChangeLog.gimple-classes
@@ -1,5 +1,12 @@
 2014-11-06  David Malcolm  <dmalcolm@redhat.com>
 
+	* tree-ssa-ter.c (find_replaceable_in_bb): Replace
+	is_gimple_assign with a dyn_cast, introducing local "def_assign"
+	and using it in place of "def_stmt" for typesafety.  Add a checked
+	cast.
+
+2014-11-06  David Malcolm  <dmalcolm@redhat.com>
+
 	* tree-ssa-tail-merge.c (same_succ_hash): Add checked cast.
 	(gimple_equal_p): Add checked casts.
 
diff --git a/gcc/tree-ssa-ter.c b/gcc/tree-ssa-ter.c
index 96b3959..adbc5f9 100644
--- a/gcc/tree-ssa-ter.c
+++ b/gcc/tree-ssa-ter.c
@@ -640,14 +640,18 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
 	      if (gimple_vdef (stmt))
 		{
 		  gimple def_stmt = SSA_NAME_DEF_STMT (use);
-		  while (is_gimple_assign (def_stmt)
-			 && gimple_assign_rhs_code (def_stmt) == SSA_NAME)
-		    def_stmt
-		      = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt));
+		  while (gassign *def_assign = dyn_cast <gassign *> (def_stmt))
+		    {
+		      if (gimple_assign_rhs_code (def_assign) != SSA_NAME)
+			break;
+		      def_stmt
+			= SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_assign));
+		    }
 		  if (gimple_vuse (def_stmt)
 		      && gimple_assign_single_p (def_stmt)
-		      && stmt_may_clobber_ref_p (stmt,
-						 gimple_assign_rhs1 (def_stmt)))
+		      && stmt_may_clobber_ref_p (
+			   stmt,
+			   gimple_assign_rhs1 (as_a <gassign *> (def_stmt))))
 		    {
 		      /* For calls, it is not a problem if USE is among
 			 call's arguments or say OBJ_TYPE_REF argument,
-- 
1.7.11.7

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [gimple-classes, committed 6/6] tree-ssa-threadedge.c: Use gassign
  2014-11-07 15:25 [gimple-classes, committed 0/6] Use gassign in 6 tree-ssa-* files David Malcolm
                   ` (3 preceding siblings ...)
  2014-11-07 15:26 ` [gimple-classes, committed 5/6] tree-ssa-ter.c: " David Malcolm
@ 2014-11-07 15:26 ` David Malcolm
  2014-11-07 15:26 ` [gimple-classes, committed 3/6] tree-ssa-structalias.c: " David Malcolm
  5 siblings, 0 replies; 36+ messages in thread
From: David Malcolm @ 2014-11-07 15:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

gcc/ChangeLog.gimple-classes:
	* tree-ssa-threadedge.c (lhs_of_dominating_assert): Capture result
	of gimple_assign_single_p as new local gassign * "use_assign",
	using it in place of "use_stmt" for typesafety.
	(fold_assignment_stmt): Strengthen param "stmt" from gimple to
	gassign *.
	(record_temporary_equivalences_from_stmts_at_dest): Replace check
	against GIMPLE_ASSIGN with a dyn_cast, introducing local gassign *
	"assign_stmt", using it in place of "stmt" for typesafety.  Later,
	use it to capture the result of gimple_assign_single_p, and use it
	in place of "stmt" for typesafety.  Add checked cast.
---
 gcc/ChangeLog.gimple-classes | 13 +++++++++++++
 gcc/tree-ssa-threadedge.c    | 33 ++++++++++++++++++---------------
 2 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
index 43c05ec..c85c138 100644
--- a/gcc/ChangeLog.gimple-classes
+++ b/gcc/ChangeLog.gimple-classes
@@ -1,5 +1,18 @@
 2014-11-06  David Malcolm  <dmalcolm@redhat.com>
 
+	* tree-ssa-threadedge.c (lhs_of_dominating_assert): Capture result
+	of gimple_assign_single_p as new local gassign * "use_assign",
+	using it in place of "use_stmt" for typesafety.
+	(fold_assignment_stmt): Strengthen param "stmt" from gimple to
+	gassign *.
+	(record_temporary_equivalences_from_stmts_at_dest): Replace check
+	against GIMPLE_ASSIGN with a dyn_cast, introducing local gassign *
+	"assign_stmt", using it in place of "stmt" for typesafety.  Later,
+	use it to capture the result of gimple_assign_single_p, and use it
+	in place of "stmt" for typesafety.  Add checked cast.
+
+2014-11-06  David Malcolm  <dmalcolm@redhat.com>
+
 	* tree-ssa-ter.c (find_replaceable_in_bb): Replace
 	is_gimple_assign with a dyn_cast, introducing local "def_assign"
 	and using it in place of "def_stmt" for typesafety.  Add a checked
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index d5b2941..c0b1c82 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -132,14 +132,15 @@ lhs_of_dominating_assert (tree op, basic_block bb, gimple stmt)
 
   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, op)
     {
+      gassign *use_assign;
       use_stmt = USE_STMT (use_p);
       if (use_stmt != stmt
-          && gimple_assign_single_p (use_stmt)
-          && TREE_CODE (gimple_assign_rhs1 (use_stmt)) == ASSERT_EXPR
-          && TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == op
-	  && dominated_by_p (CDI_DOMINATORS, bb, gimple_bb (use_stmt)))
+          && (use_assign = gimple_assign_single_p (use_stmt))
+          && TREE_CODE (gimple_assign_rhs1 (use_assign)) == ASSERT_EXPR
+          && TREE_OPERAND (gimple_assign_rhs1 (use_assign), 0) == op
+	  && dominated_by_p (CDI_DOMINATORS, bb, gimple_bb (use_assign)))
 	{
-	  return gimple_assign_lhs (use_stmt);
+	  return gimple_assign_lhs (use_assign);
 	}
     }
   return op;
@@ -243,7 +244,7 @@ record_temporary_equivalences_from_phis (edge e, vec<tree> *stack)
    May return NULL_TREE if no simplification is possible.  */
 
 static tree
-fold_assignment_stmt (gimple stmt)
+fold_assignment_stmt (gassign *stmt)
 {
   enum tree_code subcode = gimple_assign_rhs_code (stmt);
 
@@ -365,8 +366,9 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
       /* If this is not a statement that sets an SSA_NAME to a new
 	 value, then do not try to simplify this statement as it will
 	 not simplify in any way that is helpful for jump threading.  */
-      if ((gimple_code (stmt) != GIMPLE_ASSIGN
-           || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
+      gassign *assign_stmt = dyn_cast <gassign *> (stmt);
+      if ((!assign_stmt
+           || TREE_CODE (gimple_assign_lhs (assign_stmt)) != SSA_NAME)
           && (gimple_code (stmt) != GIMPLE_CALL
               || gimple_call_lhs (stmt) == NULL_TREE
               || TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME))
@@ -435,12 +437,13 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
 
 	 Handle simple copy operations as well as implied copies from
 	 ASSERT_EXPRs.  */
-      if (gimple_assign_single_p (stmt)
-          && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
-	cached_lhs = gimple_assign_rhs1 (stmt);
-      else if (gimple_assign_single_p (stmt)
-               && TREE_CODE (gimple_assign_rhs1 (stmt)) == ASSERT_EXPR)
-	cached_lhs = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
+      assign_stmt = gimple_assign_single_p (stmt);
+      if (assign_stmt
+          && TREE_CODE (gimple_assign_rhs1 (assign_stmt)) == SSA_NAME)
+	cached_lhs = gimple_assign_rhs1 (assign_stmt);
+      else if (assign_stmt
+               && TREE_CODE (gimple_assign_rhs1 (assign_stmt)) == ASSERT_EXPR)
+	cached_lhs = TREE_OPERAND (gimple_assign_rhs1 (assign_stmt), 0);
       else
 	{
 	  /* A statement that is not a trivial copy or ASSERT_EXPR.
@@ -473,7 +476,7 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
           if (is_gimple_call (stmt))
             cached_lhs = fold_call_stmt (as_a <gcall *> (stmt), false);
 	  else
-            cached_lhs = fold_assignment_stmt (stmt);
+            cached_lhs = fold_assignment_stmt (as_a <gassign *> (stmt));
 
           if (!cached_lhs
               || (TREE_CODE (cached_lhs) != SSA_NAME
-- 
1.7.11.7

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [gimple-classes, committed 2/6] tree-ssa-strlen.c: Use gassign
  2014-11-07 15:25 [gimple-classes, committed 0/6] Use gassign in 6 tree-ssa-* files David Malcolm
  2014-11-07 15:25 ` [gimple-classes, committed 1/6] tree-ssa-sink.c: Use gassign David Malcolm
  2014-11-07 15:26 ` [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: " David Malcolm
@ 2014-11-07 15:26 ` David Malcolm
  2014-11-07 15:26 ` [gimple-classes, committed 5/6] tree-ssa-ter.c: " David Malcolm
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 36+ messages in thread
From: David Malcolm @ 2014-11-07 15:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

gcc/ChangeLog.gimple-classes:
	* tree-ssa-strlen.c (find_equal_ptrs): Replace is_gimple_assign
	with a dyn_cast, strengthening local "stmt" from gimple to
	gassign *.
	(adjust_last_stmt): Likewise, introducing local "last_assign" and
	using it in place of last.stmt, and strengthening local "def_stmt"
	from gimple to gassign *.
	(handle_builtin_memcpy): Replace is_gimple_assign with a dyn_cast,
	strengthening local "def_stmt" from gimple to gassign *.
	(handle_pointer_plus): Strengthen local "stmt" from gimple to
	gassign *. Add checked cast.
	(handle_char_store): Strengthen local "stmt" from gimple to
	gassign *.
	(strlen_optimize_stmt): Replace is_gimple_assign with dyn_cast,
	introducing local gassign * "assign_stmt", using it in place of
	"stmt" for typesafety.
---
 gcc/ChangeLog.gimple-classes | 18 ++++++++++++++++
 gcc/tree-ssa-strlen.c        | 49 +++++++++++++++++++++++---------------------
 2 files changed, 44 insertions(+), 23 deletions(-)

diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
index 2c78ce0..a0e7c48 100644
--- a/gcc/ChangeLog.gimple-classes
+++ b/gcc/ChangeLog.gimple-classes
@@ -1,5 +1,23 @@
 2014-11-06  David Malcolm  <dmalcolm@redhat.com>
 
+	* tree-ssa-strlen.c (find_equal_ptrs): Replace is_gimple_assign
+	with a dyn_cast, strengthening local "stmt" from gimple to
+	gassign *.
+	(adjust_last_stmt): Likewise, introducing local "last_assign" and
+	using it in place of last.stmt, and strengthening local "def_stmt"
+	from gimple to gassign *.
+	(handle_builtin_memcpy): Replace is_gimple_assign with a dyn_cast,
+	strengthening local "def_stmt" from gimple to gassign *.
+	(handle_pointer_plus): Strengthen local "stmt" from gimple to
+	gassign *. Add checked cast.
+	(handle_char_store): Strengthen local "stmt" from gimple to
+	gassign *.
+	(strlen_optimize_stmt): Replace is_gimple_assign with dyn_cast,
+	introducing local gassign * "assign_stmt", using it in place of
+	"stmt" for typesafety.
+
+2014-11-06  David Malcolm  <dmalcolm@redhat.com>
+
 	* tree-ssa-sink.c (statement_sink_location): Rename param "stmt"
 	to "gs", reintroducing "stmt" as a local gassign * via a dyn_cast
 	for typesafety.
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 43f866f..e4e5099 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -727,8 +727,8 @@ find_equal_ptrs (tree ptr, int idx)
     return;
   while (1)
     {
-      gimple stmt = SSA_NAME_DEF_STMT (ptr);
-      if (!is_gimple_assign (stmt))
+      gassign *stmt = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (ptr));
+      if (!stmt)
 	return;
       ptr = gimple_assign_rhs1 (stmt);
       switch (gimple_assign_rhs_code (stmt))
@@ -824,17 +824,17 @@ adjust_last_stmt (strinfo si, gimple stmt, bool is_strcat)
 	return;
     }
 
-  if (is_gimple_assign (last.stmt))
+  if (gassign *last_assign = dyn_cast <gassign *> (last.stmt))
     {
       gimple_stmt_iterator gsi;
 
-      if (!integer_zerop (gimple_assign_rhs1 (last.stmt)))
+      if (!integer_zerop (gimple_assign_rhs1 (last_assign)))
 	return;
-      if (stmt_could_throw_p (last.stmt))
+      if (stmt_could_throw_p (last_assign))
 	return;
-      gsi = gsi_for_stmt (last.stmt);
-      unlink_stmt_vdef (last.stmt);
-      release_defs (last.stmt);
+      gsi = gsi_for_stmt (last_assign);
+      unlink_stmt_vdef (last_assign);
+      release_defs (last_assign);
       gsi_remove (&gsi, true);
       return;
     }
@@ -866,8 +866,8 @@ adjust_last_stmt (strinfo si, gimple stmt, bool is_strcat)
     }
   else if (TREE_CODE (len) == SSA_NAME)
     {
-      gimple def_stmt = SSA_NAME_DEF_STMT (len);
-      if (!is_gimple_assign (def_stmt)
+      gassign *def_stmt = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (len));
+      if (!def_stmt
 	  || gimple_assign_rhs_code (def_stmt) != PLUS_EXPR
 	  || gimple_assign_rhs1 (def_stmt) != last.len
 	  || !integer_onep (gimple_assign_rhs2 (def_stmt)))
@@ -1322,7 +1322,7 @@ handle_builtin_memcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi)
 
   if (idx > 0)
     {
-      gimple def_stmt;
+      gassign *def_stmt;
 
       /* Handle memcpy (x, y, l) where l is strlen (y) + 1.  */
       si = get_strinfo (idx);
@@ -1330,8 +1330,8 @@ handle_builtin_memcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi)
 	return;
       if (TREE_CODE (len) != SSA_NAME)
 	return;
-      def_stmt = SSA_NAME_DEF_STMT (len);
-      if (!is_gimple_assign (def_stmt)
+      def_stmt = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (len));
+      if (!def_stmt
 	  || gimple_assign_rhs_code (def_stmt) != PLUS_EXPR
 	  || gimple_assign_rhs1 (def_stmt) != si->length
 	  || !integer_onep (gimple_assign_rhs2 (def_stmt)))
@@ -1695,7 +1695,7 @@ handle_builtin_memset (gimple_stmt_iterator *gsi)
 static void
 handle_pointer_plus (gimple_stmt_iterator *gsi)
 {
-  gimple stmt = gsi_stmt (*gsi);
+  gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));
   tree lhs = gimple_assign_lhs (stmt), off;
   int idx = get_stridx (gimple_assign_rhs1 (stmt));
   strinfo si, zsi;
@@ -1725,7 +1725,9 @@ handle_pointer_plus (gimple_stmt_iterator *gsi)
     {
       gimple def_stmt = SSA_NAME_DEF_STMT (off);
       if (gimple_assign_single_p (def_stmt)
-	  && operand_equal_p (si->length, gimple_assign_rhs1 (def_stmt), 0))
+	  && operand_equal_p (si->length,
+			      gimple_assign_rhs1 (as_a <gassign *> (def_stmt)),
+			      0))
 	zsi = zero_length_string (lhs, si);
     }
   if (zsi != NULL
@@ -1749,7 +1751,7 @@ handle_char_store (gimple_stmt_iterator *gsi)
 {
   int idx = -1;
   strinfo si = NULL;
-  gimple stmt = gsi_stmt (*gsi);
+  gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));
   tree ssaname = NULL_TREE, lhs = gimple_assign_lhs (stmt);
 
   if (TREE_CODE (lhs) == MEM_REF
@@ -1936,20 +1938,21 @@ strlen_optimize_stmt (gimple_stmt_iterator *gsi)
 	    break;
 	  }
     }
-  else if (is_gimple_assign (stmt))
+  else if (gassign *assign_stmt = dyn_cast <gassign *> (stmt))
     {
-      tree lhs = gimple_assign_lhs (stmt);
+      tree lhs = gimple_assign_lhs (assign_stmt);
 
       if (TREE_CODE (lhs) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (lhs)))
 	{
-	  if (gimple_assign_single_p (stmt)
-	      || (gimple_assign_cast_p (stmt)
-		  && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt)))))
+	  if (gimple_assign_single_p (assign_stmt)
+	      || (gimple_assign_cast_p (assign_stmt)
+		  && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (
+						  assign_stmt)))))
 	    {
-	      int idx = get_stridx (gimple_assign_rhs1 (stmt));
+	      int idx = get_stridx (gimple_assign_rhs1 (assign_stmt));
 	      ssa_ver_to_stridx[SSA_NAME_VERSION (lhs)] = idx;
 	    }
-	  else if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
+	  else if (gimple_assign_rhs_code (assign_stmt) == POINTER_PLUS_EXPR)
 	    handle_pointer_plus (gsi);
 	}
       else if (TREE_CODE (lhs) != SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
-- 
1.7.11.7

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-07 15:25 [gimple-classes, committed 0/6] Use gassign in 6 tree-ssa-* files David Malcolm
  2014-11-07 15:25 ` [gimple-classes, committed 1/6] tree-ssa-sink.c: Use gassign David Malcolm
@ 2014-11-07 15:26 ` David Malcolm
  2014-11-07 21:01   ` Richard Biener
  2014-11-07 15:26 ` [gimple-classes, committed 2/6] tree-ssa-strlen.c: " David Malcolm
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 36+ messages in thread
From: David Malcolm @ 2014-11-07 15:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

gcc/ChangeLog.gimple-classes:
	* tree-ssa-tail-merge.c (same_succ_hash): Add checked cast.
	(gimple_equal_p): Add checked casts.
---
 gcc/ChangeLog.gimple-classes | 5 +++++
 gcc/tree-ssa-tail-merge.c    | 8 +++++---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
index f43df63..0bd0421 100644
--- a/gcc/ChangeLog.gimple-classes
+++ b/gcc/ChangeLog.gimple-classes
@@ -1,5 +1,10 @@
 2014-11-06  David Malcolm  <dmalcolm@redhat.com>
 
+	* tree-ssa-tail-merge.c (same_succ_hash): Add checked cast.
+	(gimple_equal_p): Add checked casts.
+
+2014-11-06  David Malcolm  <dmalcolm@redhat.com>
+
 	* tree-ssa-structalias.c (find_func_aliases): Replace
 	is_gimple_assign with a dyn_cast, introducing local gassign *
 	"t_assign", using it in place of "t" for typesafety.
diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
index 5678657..b822214 100644
--- a/gcc/tree-ssa-tail-merge.c
+++ b/gcc/tree-ssa-tail-merge.c
@@ -484,7 +484,7 @@ same_succ_hash (const_same_succ e)
 
       hstate.add_int (gimple_code (stmt));
       if (is_gimple_assign (stmt))
-	hstate.add_int (gimple_assign_rhs_code (stmt));
+	hstate.add_int (gimple_assign_rhs_code (as_a <gassign *> (stmt)));
       if (!is_gimple_call (stmt))
 	continue;
       if (gimple_call_internal_p (stmt))
@@ -1172,8 +1172,10 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
       if (TREE_CODE (lhs1) != SSA_NAME
 	  && TREE_CODE (lhs2) != SSA_NAME)
 	return (operand_equal_p (lhs1, lhs2, 0)
-		&& gimple_operand_equal_value_p (gimple_assign_rhs1 (s1),
-						 gimple_assign_rhs1 (s2)));
+		&& gimple_operand_equal_value_p (gimple_assign_rhs1 (
+						   as_a <gassign *> (s1)),
+						 gimple_assign_rhs1 (
+						   as_a <gassign *> (s2))));
       else if (TREE_CODE (lhs1) == SSA_NAME
 	       && TREE_CODE (lhs2) == SSA_NAME)
 	return vn_valueize (lhs1) == vn_valueize (lhs2);
-- 
1.7.11.7

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [gimple-classes, committed 3/6] tree-ssa-structalias.c: Use gassign
  2014-11-07 15:25 [gimple-classes, committed 0/6] Use gassign in 6 tree-ssa-* files David Malcolm
                   ` (4 preceding siblings ...)
  2014-11-07 15:26 ` [gimple-classes, committed 6/6] tree-ssa-threadedge.c: " David Malcolm
@ 2014-11-07 15:26 ` David Malcolm
  5 siblings, 0 replies; 36+ messages in thread
From: David Malcolm @ 2014-11-07 15:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

gcc/ChangeLog.gimple-classes:
	* tree-ssa-structalias.c (find_func_aliases): Replace
	is_gimple_assign with a dyn_cast, introducing local gassign *
	"t_assign", using it in place of "t" for typesafety.
	(find_func_clobbers): Add checked cast.
---
 gcc/ChangeLog.gimple-classes |  7 +++++++
 gcc/tree-ssa-structalias.c   | 35 +++++++++++++++++++----------------
 2 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
index a0e7c48..f43df63 100644
--- a/gcc/ChangeLog.gimple-classes
+++ b/gcc/ChangeLog.gimple-classes
@@ -1,5 +1,12 @@
 2014-11-06  David Malcolm  <dmalcolm@redhat.com>
 
+	* tree-ssa-structalias.c (find_func_aliases): Replace
+	is_gimple_assign with a dyn_cast, introducing local gassign *
+	"t_assign", using it in place of "t" for typesafety.
+	(find_func_clobbers): Add checked cast.
+
+2014-11-06  David Malcolm  <dmalcolm@redhat.com>
+
 	* tree-ssa-strlen.c (find_equal_ptrs): Replace is_gimple_assign
 	with a dyn_cast, strengthening local "stmt" from gimple to
 	gassign *.
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index e1f0e66..5d22752 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -4661,11 +4661,13 @@ find_func_aliases (struct function *fn, gimple origt)
   /* Otherwise, just a regular assignment statement.  Only care about
      operations with pointer result, others are dealt with as escape
      points if they have pointer operands.  */
-  else if (is_gimple_assign (t))
+  else if (gassign *t_assign = dyn_cast <gassign *> (t))
     {
       /* Otherwise, just a regular assignment statement.  */
-      tree lhsop = gimple_assign_lhs (t);
-      tree rhsop = (gimple_num_ops (t) == 2) ? gimple_assign_rhs1 (t) : NULL;
+      tree lhsop = gimple_assign_lhs (t_assign);
+      tree rhsop = ((gimple_num_ops (t_assign) == 2)
+		    ? gimple_assign_rhs1 (t_assign)
+		    : NULL);
 
       if (rhsop && TREE_CLOBBER_P (rhsop))
 	/* Ignore clobbers, they don't actually store anything into
@@ -4675,7 +4677,7 @@ find_func_aliases (struct function *fn, gimple origt)
 	do_structure_copy (lhsop, rhsop);
       else
 	{
-	  enum tree_code code = gimple_assign_rhs_code (t);
+	  enum tree_code code = gimple_assign_rhs_code (t_assign);
 
 	  get_constraint_for (lhsop, &lhsc);
 
@@ -4684,20 +4686,21 @@ find_func_aliases (struct function *fn, gimple origt)
 	       assume the value is not produced to transfer a pointer.  */
 	    ;
 	  else if (code == POINTER_PLUS_EXPR)
-	    get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
-					   gimple_assign_rhs2 (t), &rhsc);
+	    get_constraint_for_ptr_offset (gimple_assign_rhs1 (t_assign),
+					   gimple_assign_rhs2 (t_assign),
+					   &rhsc);
 	  else if (code == BIT_AND_EXPR
-		   && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST)
+		   && TREE_CODE (gimple_assign_rhs2 (t_assign)) == INTEGER_CST)
 	    {
 	      /* Aligning a pointer via a BIT_AND_EXPR is offsetting
 		 the pointer.  Handle it by offsetting it by UNKNOWN.  */
-	      get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
+	      get_constraint_for_ptr_offset (gimple_assign_rhs1 (t_assign),
 					     NULL_TREE, &rhsc);
 	    }
 	  else if ((CONVERT_EXPR_CODE_P (code)
-		    && !(POINTER_TYPE_P (gimple_expr_type (t))
+		    && !(POINTER_TYPE_P (gimple_expr_type (t_assign))
 			 && !POINTER_TYPE_P (TREE_TYPE (rhsop))))
-		   || gimple_assign_single_p (t))
+		   || gimple_assign_single_p (t_assign))
 	    get_constraint_for_rhs (rhsop, &rhsc);
 	  else if (code == COND_EXPR)
 	    {
@@ -4705,8 +4708,8 @@ find_func_aliases (struct function *fn, gimple origt)
 	      auto_vec<ce_s, 2> tmp;
 	      struct constraint_expr *rhsp;
 	      unsigned i;
-	      get_constraint_for_rhs (gimple_assign_rhs2 (t), &rhsc);
-	      get_constraint_for_rhs (gimple_assign_rhs3 (t), &tmp);
+	      get_constraint_for_rhs (gimple_assign_rhs2 (t_assign), &rhsc);
+	      get_constraint_for_rhs (gimple_assign_rhs3 (t_assign), &tmp);
 	      FOR_EACH_VEC_ELT (tmp, i, rhsp)
 		rhsc.safe_push (*rhsp);
 	    }
@@ -4720,10 +4723,10 @@ find_func_aliases (struct function *fn, gimple origt)
 	      auto_vec<ce_s, 4> tmp;
 	      struct constraint_expr *rhsp;
 	      unsigned i, j;
-	      get_constraint_for_rhs (gimple_assign_rhs1 (t), &rhsc);
-	      for (i = 2; i < gimple_num_ops (t); ++i)
+	      get_constraint_for_rhs (gimple_assign_rhs1 (t_assign), &rhsc);
+	      for (i = 2; i < gimple_num_ops (t_assign); ++i)
 		{
-		  get_constraint_for_rhs (gimple_op (t, i), &tmp);
+		  get_constraint_for_rhs (gimple_op (t_assign, i), &tmp);
 		  FOR_EACH_VEC_ELT (tmp, j, rhsp)
 		    rhsc.safe_push (*rhsp);
 		  tmp.truncate (0);
@@ -4898,7 +4901,7 @@ find_func_clobbers (struct function *fn, gimple origt)
 	  && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE))
     {
       tree rhs = (gimple_assign_single_p (t)
-		  ? gimple_assign_rhs1 (t)
+		  ? gimple_assign_rhs1 (as_a <gassign *> (t))
 		  : gimple_return_retval (as_a <greturn *> (t)));
       tree tem = rhs;
       while (handled_component_p (tem))
-- 
1.7.11.7

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-07 15:26 ` [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: " David Malcolm
@ 2014-11-07 21:01   ` Richard Biener
  2014-11-07 21:23     ` Jakub Jelinek
                       ` (2 more replies)
  0 siblings, 3 replies; 36+ messages in thread
From: Richard Biener @ 2014-11-07 21:01 UTC (permalink / raw)
  To: David Malcolm; +Cc: GCC Patches, GCC Development, Jeff Law

On Fri, Nov 7, 2014 at 4:21 PM, David Malcolm <dmalcolm@redhat.com> wrote:
> gcc/ChangeLog.gimple-classes:
>         * tree-ssa-tail-merge.c (same_succ_hash): Add checked cast.
>         (gimple_equal_p): Add checked casts.
> ---
>  gcc/ChangeLog.gimple-classes | 5 +++++
>  gcc/tree-ssa-tail-merge.c    | 8 +++++---
>  2 files changed, 10 insertions(+), 3 deletions(-)
>
> diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
> index f43df63..0bd0421 100644
> --- a/gcc/ChangeLog.gimple-classes
> +++ b/gcc/ChangeLog.gimple-classes
> @@ -1,5 +1,10 @@
>  2014-11-06  David Malcolm  <dmalcolm@redhat.com>
>
> +       * tree-ssa-tail-merge.c (same_succ_hash): Add checked cast.
> +       (gimple_equal_p): Add checked casts.
> +
> +2014-11-06  David Malcolm  <dmalcolm@redhat.com>
> +
>         * tree-ssa-structalias.c (find_func_aliases): Replace
>         is_gimple_assign with a dyn_cast, introducing local gassign *
>         "t_assign", using it in place of "t" for typesafety.
> diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
> index 5678657..b822214 100644
> --- a/gcc/tree-ssa-tail-merge.c
> +++ b/gcc/tree-ssa-tail-merge.c
> @@ -484,7 +484,7 @@ same_succ_hash (const_same_succ e)
>
>        hstate.add_int (gimple_code (stmt));
>        if (is_gimple_assign (stmt))
> -       hstate.add_int (gimple_assign_rhs_code (stmt));
> +       hstate.add_int (gimple_assign_rhs_code (as_a <gassign *> (stmt)));
>        if (!is_gimple_call (stmt))
>         continue;
>        if (gimple_call_internal_p (stmt))
> @@ -1172,8 +1172,10 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
>        if (TREE_CODE (lhs1) != SSA_NAME
>           && TREE_CODE (lhs2) != SSA_NAME)
>         return (operand_equal_p (lhs1, lhs2, 0)
> -               && gimple_operand_equal_value_p (gimple_assign_rhs1 (s1),
> -                                                gimple_assign_rhs1 (s2)));
> +               && gimple_operand_equal_value_p (gimple_assign_rhs1 (
> +                                                  as_a <gassign *> (s1)),
> +                                                gimple_assign_rhs1 (
> +                                                  as_a <gassign *> (s2))));

Just a comment as these patches flow by - I think this is a huge step
backwards from "enforcing" s1/s2 being a gimple_assign inside
gimple_assign_rhs1 to this as_a <gassign *> boilerplate at _each_ callsite!

Which means this step of the refactoring is totally broken and probably
requires much more manual work to avoid this kind of uglyness.

I definitely won't approve of this kind of changes.

Thanks,
Richard.

>        else if (TREE_CODE (lhs1) == SSA_NAME
>                && TREE_CODE (lhs2) == SSA_NAME)
>         return vn_valueize (lhs1) == vn_valueize (lhs2);
> --
> 1.7.11.7
>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-07 21:01   ` Richard Biener
@ 2014-11-07 21:23     ` Jakub Jelinek
  2014-11-08 10:13     ` Marek Polacek
  2014-11-08 12:07     ` Richard Biener
  2 siblings, 0 replies; 36+ messages in thread
From: Jakub Jelinek @ 2014-11-07 21:23 UTC (permalink / raw)
  To: Richard Biener; +Cc: David Malcolm, GCC Patches, GCC Development, Jeff Law

On Fri, Nov 07, 2014 at 10:01:45PM +0100, Richard Biener wrote:
> > --- a/gcc/tree-ssa-tail-merge.c
> > +++ b/gcc/tree-ssa-tail-merge.c
> > @@ -484,7 +484,7 @@ same_succ_hash (const_same_succ e)
> >
> >        hstate.add_int (gimple_code (stmt));
> >        if (is_gimple_assign (stmt))
> > -       hstate.add_int (gimple_assign_rhs_code (stmt));
> > +       hstate.add_int (gimple_assign_rhs_code (as_a <gassign *> (stmt)));
> >        if (!is_gimple_call (stmt))
> >         continue;
> >        if (gimple_call_internal_p (stmt))
> > @@ -1172,8 +1172,10 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
> >        if (TREE_CODE (lhs1) != SSA_NAME
> >           && TREE_CODE (lhs2) != SSA_NAME)
> >         return (operand_equal_p (lhs1, lhs2, 0)
> > -               && gimple_operand_equal_value_p (gimple_assign_rhs1 (s1),
> > -                                                gimple_assign_rhs1 (s2)));
> > +               && gimple_operand_equal_value_p (gimple_assign_rhs1 (
> > +                                                  as_a <gassign *> (s1)),
> > +                                                gimple_assign_rhs1 (
> > +                                                  as_a <gassign *> (s2))));
> 
> Just a comment as these patches flow by - I think this is a huge step
> backwards from "enforcing" s1/s2 being a gimple_assign inside
> gimple_assign_rhs1 to this as_a <gassign *> boilerplate at _each_ callsite!
> 
> Which means this step of the refactoring is totally broken and probably
> requires much more manual work to avoid this kind of uglyness.
> 
> I definitely won't approve of this kind of changes.

I have to agree with this, this is too ugly to live with.
I must say I don't find anything wrong with what we have right now,
unlike RTL checking, the gimple checking is inexpensive, and much better
to do it that way then enforce all all developers to write it this way.
Otherwise we'll end up with code as ugly as in LLVM :(.

	Jakub

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-07 21:01   ` Richard Biener
  2014-11-07 21:23     ` Jakub Jelinek
@ 2014-11-08 10:13     ` Marek Polacek
  2014-11-08 12:07     ` Richard Biener
  2 siblings, 0 replies; 36+ messages in thread
From: Marek Polacek @ 2014-11-08 10:13 UTC (permalink / raw)
  To: Richard Biener; +Cc: David Malcolm, GCC Patches, GCC Development, Jeff Law

On Fri, Nov 07, 2014 at 10:01:45PM +0100, Richard Biener wrote:
> Just a comment as these patches flow by - I think this is a huge step
> backwards from "enforcing" s1/s2 being a gimple_assign inside
> gimple_assign_rhs1 to this as_a <gassign *> boilerplate at _each_ callsite!

FWIW, I feel the same way.  More to type, worse readability, a lot
more of line-wrapping.

Sorry,

	Marek

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-07 21:01   ` Richard Biener
  2014-11-07 21:23     ` Jakub Jelinek
  2014-11-08 10:13     ` Marek Polacek
@ 2014-11-08 12:07     ` Richard Biener
  2014-11-08 13:56       ` Jakub Jelinek
  2014-11-08 14:04       ` David Malcolm
  2 siblings, 2 replies; 36+ messages in thread
From: Richard Biener @ 2014-11-08 12:07 UTC (permalink / raw)
  To: David Malcolm; +Cc: GCC Patches, GCC Development, Jeff Law

On Fri, Nov 7, 2014 at 10:01 PM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Fri, Nov 7, 2014 at 4:21 PM, David Malcolm <dmalcolm@redhat.com> wrote:
>> gcc/ChangeLog.gimple-classes:
>>         * tree-ssa-tail-merge.c (same_succ_hash): Add checked cast.
>>         (gimple_equal_p): Add checked casts.
>> ---
>>  gcc/ChangeLog.gimple-classes | 5 +++++
>>  gcc/tree-ssa-tail-merge.c    | 8 +++++---
>>  2 files changed, 10 insertions(+), 3 deletions(-)
>>
>> diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
>> index f43df63..0bd0421 100644
>> --- a/gcc/ChangeLog.gimple-classes
>> +++ b/gcc/ChangeLog.gimple-classes
>> @@ -1,5 +1,10 @@
>>  2014-11-06  David Malcolm  <dmalcolm@redhat.com>
>>
>> +       * tree-ssa-tail-merge.c (same_succ_hash): Add checked cast.
>> +       (gimple_equal_p): Add checked casts.
>> +
>> +2014-11-06  David Malcolm  <dmalcolm@redhat.com>
>> +
>>         * tree-ssa-structalias.c (find_func_aliases): Replace
>>         is_gimple_assign with a dyn_cast, introducing local gassign *
>>         "t_assign", using it in place of "t" for typesafety.
>> diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
>> index 5678657..b822214 100644
>> --- a/gcc/tree-ssa-tail-merge.c
>> +++ b/gcc/tree-ssa-tail-merge.c
>> @@ -484,7 +484,7 @@ same_succ_hash (const_same_succ e)
>>
>>        hstate.add_int (gimple_code (stmt));
>>        if (is_gimple_assign (stmt))
>> -       hstate.add_int (gimple_assign_rhs_code (stmt));
>> +       hstate.add_int (gimple_assign_rhs_code (as_a <gassign *> (stmt)));
>>        if (!is_gimple_call (stmt))
>>         continue;
>>        if (gimple_call_internal_p (stmt))
>> @@ -1172,8 +1172,10 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
>>        if (TREE_CODE (lhs1) != SSA_NAME
>>           && TREE_CODE (lhs2) != SSA_NAME)
>>         return (operand_equal_p (lhs1, lhs2, 0)
>> -               && gimple_operand_equal_value_p (gimple_assign_rhs1 (s1),
>> -                                                gimple_assign_rhs1 (s2)));
>> +               && gimple_operand_equal_value_p (gimple_assign_rhs1 (
>> +                                                  as_a <gassign *> (s1)),
>> +                                                gimple_assign_rhs1 (
>> +                                                  as_a <gassign *> (s2))));
>
> Just a comment as these patches flow by - I think this is a huge step
> backwards from "enforcing" s1/s2 being a gimple_assign inside
> gimple_assign_rhs1 to this as_a <gassign *> boilerplate at _each_ callsite!
>
> Which means this step of the refactoring is totally broken and probably
> requires much more manual work to avoid this kind of uglyness.
>
> I definitely won't approve of this kind of changes.

To be constructive here - the above case is from within a
GIMPLE_ASSIGN case label
and thus I'd have expected

    case GIMPLE_ASSIGN:
      {
        gassign *a1 = as_a <gassign *> (s1);
        gassign *a2 = as_a <gassign *> (s2);
      lhs1 = gimple_assign_lhs (a1);
      lhs2 = gimple_assign_lhs (a2);
      if (TREE_CODE (lhs1) != SSA_NAME
          && TREE_CODE (lhs2) != SSA_NAME)
        return (operand_equal_p (lhs1, lhs2, 0)
                && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
                                                 gimple_assign_rhs1 (a2)));
      else if (TREE_CODE (lhs1) == SSA_NAME
               && TREE_CODE (lhs2) == SSA_NAME)
        return vn_valueize (lhs1) == vn_valueize (lhs2);
      return false;
      }

instead.  That's the kind of changes I have expected and have approved of.

Thanks,
Richard.

> Thanks,
> Richard.
>
>>        else if (TREE_CODE (lhs1) == SSA_NAME
>>                && TREE_CODE (lhs2) == SSA_NAME)
>>         return vn_valueize (lhs1) == vn_valueize (lhs2);
>> --
>> 1.7.11.7
>>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-08 12:07     ` Richard Biener
@ 2014-11-08 13:56       ` Jakub Jelinek
  2014-11-10 22:37         ` David Malcolm
  2014-11-08 14:04       ` David Malcolm
  1 sibling, 1 reply; 36+ messages in thread
From: Jakub Jelinek @ 2014-11-08 13:56 UTC (permalink / raw)
  To: Richard Biener; +Cc: David Malcolm, GCC Patches, GCC Development, Jeff Law

On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
> To be constructive here - the above case is from within a
> GIMPLE_ASSIGN case label
> and thus I'd have expected
> 
>     case GIMPLE_ASSIGN:
>       {
>         gassign *a1 = as_a <gassign *> (s1);
>         gassign *a2 = as_a <gassign *> (s2);
>       lhs1 = gimple_assign_lhs (a1);
>       lhs2 = gimple_assign_lhs (a2);
>       if (TREE_CODE (lhs1) != SSA_NAME
>           && TREE_CODE (lhs2) != SSA_NAME)
>         return (operand_equal_p (lhs1, lhs2, 0)
>                 && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
>                                                  gimple_assign_rhs1 (a2)));
>       else if (TREE_CODE (lhs1) == SSA_NAME
>                && TREE_CODE (lhs2) == SSA_NAME)
>         return vn_valueize (lhs1) == vn_valueize (lhs2);
>       return false;
>       }
> 
> instead.  That's the kind of changes I have expected and have approved of.

But even that looks like just adding extra work for all developers, with no
gain.  You only have to add extra code and extra temporaries, in switches
typically also have to add {} because of the temporaries and thus extra
indentation level, and it doesn't simplify anything in the code.

	Jakub

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-08 12:07     ` Richard Biener
  2014-11-08 13:56       ` Jakub Jelinek
@ 2014-11-08 14:04       ` David Malcolm
  1 sibling, 0 replies; 36+ messages in thread
From: David Malcolm @ 2014-11-08 14:04 UTC (permalink / raw)
  To: Richard Biener; +Cc: GCC Patches, GCC Development, Jeff Law

On Sat, 2014-11-08 at 13:07 +0100, Richard Biener wrote:
> On Fri, Nov 7, 2014 at 10:01 PM, Richard Biener
> <richard.guenther@gmail.com> wrote:
> > On Fri, Nov 7, 2014 at 4:21 PM, David Malcolm <dmalcolm@redhat.com> wrote:
> >> gcc/ChangeLog.gimple-classes:
> >>         * tree-ssa-tail-merge.c (same_succ_hash): Add checked cast.
> >>         (gimple_equal_p): Add checked casts.
> >> ---
> >>  gcc/ChangeLog.gimple-classes | 5 +++++
> >>  gcc/tree-ssa-tail-merge.c    | 8 +++++---
> >>  2 files changed, 10 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
> >> index f43df63..0bd0421 100644
> >> --- a/gcc/ChangeLog.gimple-classes
> >> +++ b/gcc/ChangeLog.gimple-classes
> >> @@ -1,5 +1,10 @@
> >>  2014-11-06  David Malcolm  <dmalcolm@redhat.com>
> >>
> >> +       * tree-ssa-tail-merge.c (same_succ_hash): Add checked cast.
> >> +       (gimple_equal_p): Add checked casts.
> >> +
> >> +2014-11-06  David Malcolm  <dmalcolm@redhat.com>
> >> +
> >>         * tree-ssa-structalias.c (find_func_aliases): Replace
> >>         is_gimple_assign with a dyn_cast, introducing local gassign *
> >>         "t_assign", using it in place of "t" for typesafety.
> >> diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
> >> index 5678657..b822214 100644
> >> --- a/gcc/tree-ssa-tail-merge.c
> >> +++ b/gcc/tree-ssa-tail-merge.c
> >> @@ -484,7 +484,7 @@ same_succ_hash (const_same_succ e)
> >>
> >>        hstate.add_int (gimple_code (stmt));
> >>        if (is_gimple_assign (stmt))
> >> -       hstate.add_int (gimple_assign_rhs_code (stmt));
> >> +       hstate.add_int (gimple_assign_rhs_code (as_a <gassign *> (stmt)));
> >>        if (!is_gimple_call (stmt))
> >>         continue;
> >>        if (gimple_call_internal_p (stmt))
> >> @@ -1172,8 +1172,10 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
> >>        if (TREE_CODE (lhs1) != SSA_NAME
> >>           && TREE_CODE (lhs2) != SSA_NAME)
> >>         return (operand_equal_p (lhs1, lhs2, 0)
> >> -               && gimple_operand_equal_value_p (gimple_assign_rhs1 (s1),
> >> -                                                gimple_assign_rhs1 (s2)));
> >> +               && gimple_operand_equal_value_p (gimple_assign_rhs1 (
> >> +                                                  as_a <gassign *> (s1)),
> >> +                                                gimple_assign_rhs1 (
> >> +                                                  as_a <gassign *> (s2))));
> >
> > Just a comment as these patches flow by - I think this is a huge step
> > backwards from "enforcing" s1/s2 being a gimple_assign inside
> > gimple_assign_rhs1 to this as_a <gassign *> boilerplate at _each_ callsite!
> >
> > Which means this step of the refactoring is totally broken and probably
> > requires much more manual work to avoid this kind of uglyness.
> >
> > I definitely won't approve of this kind of changes.
> 
> To be constructive here - the above case is from within a
> GIMPLE_ASSIGN case label
> and thus I'd have expected
> 
>     case GIMPLE_ASSIGN:
>       {
>         gassign *a1 = as_a <gassign *> (s1);
>         gassign *a2 = as_a <gassign *> (s2);
>       lhs1 = gimple_assign_lhs (a1);
>       lhs2 = gimple_assign_lhs (a2);
>       if (TREE_CODE (lhs1) != SSA_NAME
>           && TREE_CODE (lhs2) != SSA_NAME)
>         return (operand_equal_p (lhs1, lhs2, 0)
>                 && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
>                                                  gimple_assign_rhs1 (a2)));
>       else if (TREE_CODE (lhs1) == SSA_NAME
>                && TREE_CODE (lhs2) == SSA_NAME)
>         return vn_valueize (lhs1) == vn_valueize (lhs2);
>       return false;
>       }
> 
> instead.  That's the kind of changes I have expected and have approved of.

I do make the above kind of change in some places within the
gimple-classes branch.

I think I didn't do it in this case because the body of the "case
GIMPLE_ASSIGN" doesn't yet have braces, so adding locals requires adding
them and re-indenting the case body.  I didn't spot the opportunity to
speed up the code as you do above by converting the two gimple_get_lhs
to gimple_assign_lhs.  Without that, I guess I decided to simply add the
two as_a<> directly in-place to avoid the reindent.   With your speedup
it's clearly better to reindent the code.


(Got to go now, sorry; I hope to write a better reply on Monday)

Thanks
Dave

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-08 13:56       ` Jakub Jelinek
@ 2014-11-10 22:37         ` David Malcolm
  2014-11-10 23:46           ` Andrew Pinski
  2014-11-11  7:35           ` Jakub Jelinek
  0 siblings, 2 replies; 36+ messages in thread
From: David Malcolm @ 2014-11-10 22:37 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Richard Biener, GCC Patches, GCC Development, Jeff Law

On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
> On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
> > To be constructive here - the above case is from within a
> > GIMPLE_ASSIGN case label
> > and thus I'd have expected
> > 
> >     case GIMPLE_ASSIGN:
> >       {
> >         gassign *a1 = as_a <gassign *> (s1);
> >         gassign *a2 = as_a <gassign *> (s2);
> >       lhs1 = gimple_assign_lhs (a1);
> >       lhs2 = gimple_assign_lhs (a2);
> >       if (TREE_CODE (lhs1) != SSA_NAME
> >           && TREE_CODE (lhs2) != SSA_NAME)
> >         return (operand_equal_p (lhs1, lhs2, 0)
> >                 && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
> >                                                  gimple_assign_rhs1 (a2)));
> >       else if (TREE_CODE (lhs1) == SSA_NAME
> >                && TREE_CODE (lhs2) == SSA_NAME)
> >         return vn_valueize (lhs1) == vn_valueize (lhs2);
> >       return false;
> >       }
> > 
> > instead.  That's the kind of changes I have expected and have approved of.
> 
> But even that looks like just adding extra work for all developers, with no
> gain.  You only have to add extra code and extra temporaries, in switches
> typically also have to add {} because of the temporaries and thus extra
> indentation level, and it doesn't simplify anything in the code.

The branch attempts to use the C++ typesystem to capture information
about the kinds of gimple statement we expect, both:
  (A) so that the compiler can detect type errors, and
  (B) as a comprehension aid to the human reader of the code

The ideal here is when function params and struct field can be
strengthened from "gimple" to a subclass ptr.  This captures the
knowledge that every use of a function or within a struct has a given
gimple code.

Examples of this for the initial patchkit were:

* the "call_stmt" field of a cgraph_edge becoming a gcall *,
  rather than a plain gimple.

* various variables in tree-into-ssa.c change from just
  vec<gimple> to being vec<gphi *>, capturing the "phi-ness" of
  the contents as a compile-time check

* tree-inline.h's struct copy_body_data, the field "debug_stmts"
  can be "concretized" from a vec<gimple> to a vec<gdebug *>.

A more recent example, from:
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=5bd16d92b9e928b5a5a7aebd571d92f72dd517f8
The fields "arr_ref_first" and "arr_ref_last" of
tree-switch-conversion.c's struct switch_conv_info can be strengthened
from gimple to gassign *: they are always GIMPLE_ASSIGN.

I applied cleanups to do my initial patchkit, which Jeff approved (with
some provisos), and which became the first 92 commits on the branch:

"[gimple-classes, committed 00/92] Initial slew of commits":
  https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html

followed by a merger from trunk into the branch:
"[gimple-classes] Merge trunk r216157-r216746 into branch":
  https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02982.html

With those commits, I was able to convert 180 accessors to taking a
concrete subclass, with 158 left taking a gimple or
const_gimple i.e. about half of them.
(My script to analyze this is gimple_typesafety.py
within https://github.com/davidmalcolm/gcc-refactoring-scripts)

I got it into my head that it was desirable to convert *all*
gimple accessors to this form, and to eliminate the GIMPLE_CHECK
macros (given that gcc development community seems to dislike
partial transitions).

I've been attempting this full conversion - convert all of the
gimple_ accessors, to require an appropriate gimple subclass
ptr, in particular focusing on the gimple_assign_ ones, but it's a *lot*
of extra work, and much more invasive than the patches
that Jeff conditionally approved.

I now suspect that it's going too far - in the initial patchkit I was
doing the clean, obvious ones, but now I'm left with the awkward ones
that would require me to uglify the code to "fix".

If it's OK to only convert some of them, then I'd rather just do that.

The type-strengthening is rarely as neat as being able to simply convert
a param or field type.  Some examples:

Functions passed a gsi
======================
Sometimes functions are passed a gsi, where it can be known that the gsi
currently references a stmt of known kind (although that isn't
necessarily obvious from reading the body of the function):

Example from tree-ssa-strlen.c:

handle_char_store (gimple_stmt_iterator *gsi)
 {
   int idx = -1;
   strinfo si = NULL;
-  gimple stmt = gsi_stmt (*gsi);
+  gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));
   tree ssaname = NULL_TREE, lhs = gimple_assign_lhs (stmt);
 
   if (TREE_CODE (lhs) == MEM_REF

from
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=78aae552f15ad5f8f5290fb825f9ae33f4a7cad9


Only acting on one kind of gimple
=================================

Some functions accept any kind of gimple, but only act on e.g. a
GIMPLE_ASSIGN, immediately returning if they got a different kind.

So I make this kind of change, where:

  void
  foo (gimple stmt, other params)
  {
    if (!is_gimple_assign (stmt))
       return;

    use_various gimple_assign_accessors (stmt);
  }

becomes:

  void
  foo (gimple gs, other params)
  {
    gassign *stmt = dyn_cast <gassign *> (gs);
    if (!stmt)
       return;

    use_various gimple_assign_accessors (stmt);
  }

renaming the param to "gs" to avoid a mass rename of "stmt".
Example tree-ssa-sink.c (statement_sink_location):
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=da19cf71e540f52a924d0985efdacd9e03684a6e


Suites where we know the type of a statement
============================================

If we have:

   if (is_gimple_assign (stmt))
     {
        /* 20 lines of logic, with numerous gimple_assign_ accessors
           on "stmt". */ 
     }

then I've been converting it to:

   if (gassign *assign_stmt = dyn_cast <gassign *> (stmt))
     {
        /* rename the "stmt" to "assign_stmt", wrapping lines as
           needed. */ 
     }

Is "assign_stmt" too long here?  It's handy to be able to distinguish
the meaning of the stmt e.g. "use_stmt", "def_stmt" can have synonyms
"use_assign" and "def_assign" for the regions where they're known to be
GIMPLE_ASSIGN).

The above is overkill for a 1-liner e.g.:

   if (gimple_get_code (stmt) == GIMPLE_ASSIGN)
     expr = gimple_get_lhs (stmt);

It could be converted to:

   if (gassign *assign_stmt = dyn_cast <gassign *> (stmt))
     expr = gimple_assign_get_lhs (assign_stmt);

or to:

   if (gimple_get_code (stmt) == GIMPLE_ASSIGN)
     expr = gimple_assign_get_lhs (as_a <gassign *> (stmt));

or left as-is if we don't want gimple_assign_get_lhs to require a
gassign *.

Casting functions
=================

Taking RTL's single_set as inspiration, I converted the predicates:
  gimple_assign_copy_p
  gimple_assign_ssa_name_copy_p
  gimple_assign_single_p
to return a gassign * rather than a bool, so that they can be used as
casting functions:
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=06a4829d92f383a0fc1e9d488f1634d3764a0171

(also burning a register, since without LTO or some attribute the
compiler can't know the invariant that if non-NULL, then the return
value == the param (albeit with a cast) - do we have a function
attribute for that?).

Example of use, from tree-ssa-pre.c

@@ -4040,6 +4041,7 @@ eliminate_dom_walker::before_dom_children (basic_block b)
       tree sprime = NULL_TREE;
       gimple stmt = gsi_stmt (gsi);
       tree lhs = gimple_get_lhs (stmt);
+      gassign *assign_stmt;
       if (lhs && TREE_CODE (lhs) == SSA_NAME
          && !gimple_has_volatile_ops (stmt)
          /* See PR43491.  Do not replace a global register variable when
@@ -4049,10 +4051,10 @@ eliminate_dom_walker::before_dom_children (basic_block b)
             ???  The fix isn't effective here.  This should instead
             be ensured by not value-numbering them the same but treating
             them like volatiles?  */
-         && !(gimple_assign_single_p (stmt)
-              && (TREE_CODE (gimple_assign_rhs1 (stmt)) == VAR_DECL
-                  && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt))
-                  && is_global_var (gimple_assign_rhs1 (stmt)))))
+         && !((assign_stmt = gimple_assign_single_p (stmt))
+              && (TREE_CODE (gimple_assign_rhs1 (assign_stmt)) == VAR_DECL
+                  && DECL_HARD_REGISTER (gimple_assign_rhs1 (assign_stmt))
+                  && is_global_var (gimple_assign_rhs1 (assign_stmt)))))

(followed by lots of renaming of "stmt" to "assign_stmt" within the
guarded scope; this is from:
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=18277e45b407ddd9f15012b48caf7403354ebaec
)

More awkward cases
==================
e.g. code that can work on both GIMPLE_CALL and GIMPLE_ASSIGN; once
we've dealt with GIMPLE_CALL, we can add:

  gassign *assign_stmt = as_a <gassign *> (stmt);

and have the rest of the code work on "assign_stmt".

etc


Current status
==============
I currently have 261 accessors converted, with 75 to go i.e.
about 75%, as compared to the 50% from the original patchkit.
I believe that the additional 50->75% work is relatively clean, but I'm
hitting a wall where the final 25% is requiring
much more invasive work, of the kind objected to earlier in this thread.
I'm having to do uglier and uglier patches.


How to proceed?
===============

I like the initial work I did, the:
  "[gimple-classes, committed 00/92] Initial slew of commits":
     https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html
work, but I agree that the work on the branch after that is ugly in
places, and the volume of the work may resemble a DoS attack on the
reviewers - sorry.  (to answer a question on IRC, those followup commits
*were* handwritten, not autogenerated).

Is it acceptable to have the partial transition of strengthening the
types of only 50% or 75% of the accessors?

I'd like to apply those first commits to trunk (applying necessary
merger work), but I know we're approaching the close of stage 1 for gcc
5.

I can try to identify a subset of patches I think are likely to be more
acceptable if this work is still viable, and maybe put them on a
different git branch.  I hope I can get close to the 75% mark without
too much ugliness and verbosity.


Thoughts?

Thanks
Dave

(fwiw, I'm getting rather sick of refactoring, and keen to focus on
user-visible work for gcc 6)

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-10 22:37         ` David Malcolm
@ 2014-11-10 23:46           ` Andrew Pinski
  2014-11-11  7:35           ` Jakub Jelinek
  1 sibling, 0 replies; 36+ messages in thread
From: Andrew Pinski @ 2014-11-10 23:46 UTC (permalink / raw)
  To: David Malcolm
  Cc: Jakub Jelinek, Richard Biener, GCC Patches, GCC Development, Jeff Law

On Mon, Nov 10, 2014 at 2:27 PM, David Malcolm <dmalcolm@redhat.com> wrote:
> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
>> On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
>> > To be constructive here - the above case is from within a
>> > GIMPLE_ASSIGN case label
>> > and thus I'd have expected
>> >
>> >     case GIMPLE_ASSIGN:
>> >       {
>> >         gassign *a1 = as_a <gassign *> (s1);
>> >         gassign *a2 = as_a <gassign *> (s2);
>> >       lhs1 = gimple_assign_lhs (a1);
>> >       lhs2 = gimple_assign_lhs (a2);
>> >       if (TREE_CODE (lhs1) != SSA_NAME
>> >           && TREE_CODE (lhs2) != SSA_NAME)
>> >         return (operand_equal_p (lhs1, lhs2, 0)
>> >                 && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
>> >                                                  gimple_assign_rhs1 (a2)));
>> >       else if (TREE_CODE (lhs1) == SSA_NAME
>> >                && TREE_CODE (lhs2) == SSA_NAME)
>> >         return vn_valueize (lhs1) == vn_valueize (lhs2);
>> >       return false;
>> >       }
>> >
>> > instead.  That's the kind of changes I have expected and have approved of.
>>
>> But even that looks like just adding extra work for all developers, with no
>> gain.  You only have to add extra code and extra temporaries, in switches
>> typically also have to add {} because of the temporaries and thus extra
>> indentation level, and it doesn't simplify anything in the code.
>
> The branch attempts to use the C++ typesystem to capture information
> about the kinds of gimple statement we expect, both:
>   (A) so that the compiler can detect type errors, and
>   (B) as a comprehension aid to the human reader of the code
>
> The ideal here is when function params and struct field can be
> strengthened from "gimple" to a subclass ptr.  This captures the
> knowledge that every use of a function or within a struct has a given
> gimple code.
>
> Examples of this for the initial patchkit were:
>
> * the "call_stmt" field of a cgraph_edge becoming a gcall *,
>   rather than a plain gimple.
>
> * various variables in tree-into-ssa.c change from just
>   vec<gimple> to being vec<gphi *>, capturing the "phi-ness" of
>   the contents as a compile-time check
>
> * tree-inline.h's struct copy_body_data, the field "debug_stmts"
>   can be "concretized" from a vec<gimple> to a vec<gdebug *>.
>
> A more recent example, from:
> https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=5bd16d92b9e928b5a5a7aebd571d92f72dd517f8
> The fields "arr_ref_first" and "arr_ref_last" of
> tree-switch-conversion.c's struct switch_conv_info can be strengthened
> from gimple to gassign *: they are always GIMPLE_ASSIGN.
>
> I applied cleanups to do my initial patchkit, which Jeff approved (with
> some provisos), and which became the first 92 commits on the branch:
>
> "[gimple-classes, committed 00/92] Initial slew of commits":
>   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html
>
> followed by a merger from trunk into the branch:
> "[gimple-classes] Merge trunk r216157-r216746 into branch":
>   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02982.html
>
> With those commits, I was able to convert 180 accessors to taking a
> concrete subclass, with 158 left taking a gimple or
> const_gimple i.e. about half of them.
> (My script to analyze this is gimple_typesafety.py
> within https://github.com/davidmalcolm/gcc-refactoring-scripts)
>
> I got it into my head that it was desirable to convert *all*
> gimple accessors to this form, and to eliminate the GIMPLE_CHECK
> macros (given that gcc development community seems to dislike
> partial transitions).
>
> I've been attempting this full conversion - convert all of the
> gimple_ accessors, to require an appropriate gimple subclass
> ptr, in particular focusing on the gimple_assign_ ones, but it's a *lot*
> of extra work, and much more invasive than the patches
> that Jeff conditionally approved.
>
> I now suspect that it's going too far - in the initial patchkit I was
> doing the clean, obvious ones, but now I'm left with the awkward ones
> that would require me to uglify the code to "fix".
>
> If it's OK to only convert some of them, then I'd rather just do that.
>
> The type-strengthening is rarely as neat as being able to simply convert
> a param or field type.  Some examples:
>
> Functions passed a gsi
> ======================
> Sometimes functions are passed a gsi, where it can be known that the gsi
> currently references a stmt of known kind (although that isn't
> necessarily obvious from reading the body of the function):
>
> Example from tree-ssa-strlen.c:
>
> handle_char_store (gimple_stmt_iterator *gsi)
>  {
>    int idx = -1;
>    strinfo si = NULL;
> -  gimple stmt = gsi_stmt (*gsi);
> +  gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));


Can we have something like:
gsi_assign (*gsi)
instead so there is less typing when we want an gassign rather than a
gimple stmt.  This should allow for easier converting also and puts
most of the as_a in one place.

Thanks,
Andrew Pinski

>    tree ssaname = NULL_TREE, lhs = gimple_assign_lhs (stmt);
>
>    if (TREE_CODE (lhs) == MEM_REF
>
> from
> https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=78aae552f15ad5f8f5290fb825f9ae33f4a7cad9
>
>
> Only acting on one kind of gimple
> =================================
>
> Some functions accept any kind of gimple, but only act on e.g. a
> GIMPLE_ASSIGN, immediately returning if they got a different kind.
>
> So I make this kind of change, where:
>
>   void
>   foo (gimple stmt, other params)
>   {
>     if (!is_gimple_assign (stmt))
>        return;
>
>     use_various gimple_assign_accessors (stmt);
>   }
>
> becomes:
>
>   void
>   foo (gimple gs, other params)
>   {
>     gassign *stmt = dyn_cast <gassign *> (gs);
>     if (!stmt)
>        return;
>
>     use_various gimple_assign_accessors (stmt);
>   }
>
> renaming the param to "gs" to avoid a mass rename of "stmt".
> Example tree-ssa-sink.c (statement_sink_location):
> https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=da19cf71e540f52a924d0985efdacd9e03684a6e
>
>
> Suites where we know the type of a statement
> ============================================
>
> If we have:
>
>    if (is_gimple_assign (stmt))
>      {
>         /* 20 lines of logic, with numerous gimple_assign_ accessors
>            on "stmt". */
>      }
>
> then I've been converting it to:
>
>    if (gassign *assign_stmt = dyn_cast <gassign *> (stmt))
>      {
>         /* rename the "stmt" to "assign_stmt", wrapping lines as
>            needed. */
>      }
>
> Is "assign_stmt" too long here?  It's handy to be able to distinguish
> the meaning of the stmt e.g. "use_stmt", "def_stmt" can have synonyms
> "use_assign" and "def_assign" for the regions where they're known to be
> GIMPLE_ASSIGN).
>
> The above is overkill for a 1-liner e.g.:
>
>    if (gimple_get_code (stmt) == GIMPLE_ASSIGN)
>      expr = gimple_get_lhs (stmt);
>
> It could be converted to:
>
>    if (gassign *assign_stmt = dyn_cast <gassign *> (stmt))
>      expr = gimple_assign_get_lhs (assign_stmt);
>
> or to:
>
>    if (gimple_get_code (stmt) == GIMPLE_ASSIGN)
>      expr = gimple_assign_get_lhs (as_a <gassign *> (stmt));
>
> or left as-is if we don't want gimple_assign_get_lhs to require a
> gassign *.
>
> Casting functions
> =================
>
> Taking RTL's single_set as inspiration, I converted the predicates:
>   gimple_assign_copy_p
>   gimple_assign_ssa_name_copy_p
>   gimple_assign_single_p
> to return a gassign * rather than a bool, so that they can be used as
> casting functions:
> https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=06a4829d92f383a0fc1e9d488f1634d3764a0171
>
> (also burning a register, since without LTO or some attribute the
> compiler can't know the invariant that if non-NULL, then the return
> value == the param (albeit with a cast) - do we have a function
> attribute for that?).
>
> Example of use, from tree-ssa-pre.c
>
> @@ -4040,6 +4041,7 @@ eliminate_dom_walker::before_dom_children (basic_block b)
>        tree sprime = NULL_TREE;
>        gimple stmt = gsi_stmt (gsi);
>        tree lhs = gimple_get_lhs (stmt);
> +      gassign *assign_stmt;
>        if (lhs && TREE_CODE (lhs) == SSA_NAME
>           && !gimple_has_volatile_ops (stmt)
>           /* See PR43491.  Do not replace a global register variable when
> @@ -4049,10 +4051,10 @@ eliminate_dom_walker::before_dom_children (basic_block b)
>              ???  The fix isn't effective here.  This should instead
>              be ensured by not value-numbering them the same but treating
>              them like volatiles?  */
> -         && !(gimple_assign_single_p (stmt)
> -              && (TREE_CODE (gimple_assign_rhs1 (stmt)) == VAR_DECL
> -                  && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt))
> -                  && is_global_var (gimple_assign_rhs1 (stmt)))))
> +         && !((assign_stmt = gimple_assign_single_p (stmt))
> +              && (TREE_CODE (gimple_assign_rhs1 (assign_stmt)) == VAR_DECL
> +                  && DECL_HARD_REGISTER (gimple_assign_rhs1 (assign_stmt))
> +                  && is_global_var (gimple_assign_rhs1 (assign_stmt)))))
>
> (followed by lots of renaming of "stmt" to "assign_stmt" within the
> guarded scope; this is from:
> https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=18277e45b407ddd9f15012b48caf7403354ebaec
> )
>
> More awkward cases
> ==================
> e.g. code that can work on both GIMPLE_CALL and GIMPLE_ASSIGN; once
> we've dealt with GIMPLE_CALL, we can add:
>
>   gassign *assign_stmt = as_a <gassign *> (stmt);
>
> and have the rest of the code work on "assign_stmt".
>
> etc
>
>
> Current status
> ==============
> I currently have 261 accessors converted, with 75 to go i.e.
> about 75%, as compared to the 50% from the original patchkit.
> I believe that the additional 50->75% work is relatively clean, but I'm
> hitting a wall where the final 25% is requiring
> much more invasive work, of the kind objected to earlier in this thread.
> I'm having to do uglier and uglier patches.
>
>
> How to proceed?
> ===============
>
> I like the initial work I did, the:
>   "[gimple-classes, committed 00/92] Initial slew of commits":
>      https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html
> work, but I agree that the work on the branch after that is ugly in
> places, and the volume of the work may resemble a DoS attack on the
> reviewers - sorry.  (to answer a question on IRC, those followup commits
> *were* handwritten, not autogenerated).
>
> Is it acceptable to have the partial transition of strengthening the
> types of only 50% or 75% of the accessors?
>
> I'd like to apply those first commits to trunk (applying necessary
> merger work), but I know we're approaching the close of stage 1 for gcc
> 5.
>
> I can try to identify a subset of patches I think are likely to be more
> acceptable if this work is still viable, and maybe put them on a
> different git branch.  I hope I can get close to the 75% mark without
> too much ugliness and verbosity.
>
>
> Thoughts?
>
> Thanks
> Dave
>
> (fwiw, I'm getting rather sick of refactoring, and keen to focus on
> user-visible work for gcc 6)
>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-10 22:37         ` David Malcolm
  2014-11-10 23:46           ` Andrew Pinski
@ 2014-11-11  7:35           ` Jakub Jelinek
  2014-11-11  8:40             ` Eric Botcazou
                               ` (2 more replies)
  1 sibling, 3 replies; 36+ messages in thread
From: Jakub Jelinek @ 2014-11-11  7:35 UTC (permalink / raw)
  To: David Malcolm; +Cc: Richard Biener, GCC Patches, GCC Development, Jeff Law

On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
> > On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
> > > To be constructive here - the above case is from within a
> > > GIMPLE_ASSIGN case label
> > > and thus I'd have expected
> > > 
> > >     case GIMPLE_ASSIGN:
> > >       {
> > >         gassign *a1 = as_a <gassign *> (s1);
> > >         gassign *a2 = as_a <gassign *> (s2);
> > >       lhs1 = gimple_assign_lhs (a1);
> > >       lhs2 = gimple_assign_lhs (a2);
> > >       if (TREE_CODE (lhs1) != SSA_NAME
> > >           && TREE_CODE (lhs2) != SSA_NAME)
> > >         return (operand_equal_p (lhs1, lhs2, 0)
> > >                 && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
> > >                                                  gimple_assign_rhs1 (a2)));
> > >       else if (TREE_CODE (lhs1) == SSA_NAME
> > >                && TREE_CODE (lhs2) == SSA_NAME)
> > >         return vn_valueize (lhs1) == vn_valueize (lhs2);
> > >       return false;
> > >       }
> > > 
> > > instead.  That's the kind of changes I have expected and have approved of.
> > 
> > But even that looks like just adding extra work for all developers, with no
> > gain.  You only have to add extra code and extra temporaries, in switches
> > typically also have to add {} because of the temporaries and thus extra
> > indentation level, and it doesn't simplify anything in the code.
> 
> The branch attempts to use the C++ typesystem to capture information
> about the kinds of gimple statement we expect, both:
>   (A) so that the compiler can detect type errors, and
>   (B) as a comprehension aid to the human reader of the code
> 
> The ideal here is when function params and struct field can be
> strengthened from "gimple" to a subclass ptr.  This captures the
> knowledge that every use of a function or within a struct has a given
> gimple code.

I just don't like all the as_a/is_a stuff enforced everywhere,
it means more typing, more temporaries, more indentation.
So, as I view it, instead of the checks being done cheaply (yes, I think
the gimple checking as we have right now is very cheap) under the
hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
put the burden on the developers, who has to check that manually through
the as_a/is_a stuff everywhere, more typing and uglier syntax.
I just don't see that as a step forward, instead a huge step backwards.
But perhaps I'm alone with this.
Can you e.g. compare the size of - lines in your patchset combined, and
size of + lines in your patchset?  As in, if your changes lead to less
typing or more.

	Jakub

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-11  7:35           ` Jakub Jelinek
@ 2014-11-11  8:40             ` Eric Botcazou
  2014-11-11 11:55               ` Bernd Schmidt
  2014-11-11 10:46             ` Richard Biener
  2014-11-13  2:23             ` David Malcolm
  2 siblings, 1 reply; 36+ messages in thread
From: Eric Botcazou @ 2014-11-11  8:40 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc, David Malcolm, Richard Biener, GCC Patches, Jeff Law

> I just don't like all the as_a/is_a stuff enforced everywhere,
> it means more typing, more temporaries, more indentation.
> So, as I view it, instead of the checks being done cheaply (yes, I think
> the gimple checking as we have right now is very cheap) under the
> hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
> put the burden on the developers, who has to check that manually through
> the as_a/is_a stuff everywhere, more typing and uglier syntax.
> I just don't see that as a step forward, instead a huge step backwards.
> But perhaps I'm alone with this.

IMO that's the sort of things some of us were afraid of when the C++ switch 
was being discussed and IIRC we were told this would not happen...

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-11  7:35           ` Jakub Jelinek
  2014-11-11  8:40             ` Eric Botcazou
@ 2014-11-11 10:46             ` Richard Biener
  2014-11-13  2:08               ` David Malcolm
  2014-11-13  2:23             ` David Malcolm
  2 siblings, 1 reply; 36+ messages in thread
From: Richard Biener @ 2014-11-11 10:46 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: David Malcolm, GCC Patches, GCC Development, Jeff Law

On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
>> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
>> > On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
>> > > To be constructive here - the above case is from within a
>> > > GIMPLE_ASSIGN case label
>> > > and thus I'd have expected
>> > >
>> > >     case GIMPLE_ASSIGN:
>> > >       {
>> > >         gassign *a1 = as_a <gassign *> (s1);
>> > >         gassign *a2 = as_a <gassign *> (s2);
>> > >       lhs1 = gimple_assign_lhs (a1);
>> > >       lhs2 = gimple_assign_lhs (a2);
>> > >       if (TREE_CODE (lhs1) != SSA_NAME
>> > >           && TREE_CODE (lhs2) != SSA_NAME)
>> > >         return (operand_equal_p (lhs1, lhs2, 0)
>> > >                 && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
>> > >                                                  gimple_assign_rhs1 (a2)));
>> > >       else if (TREE_CODE (lhs1) == SSA_NAME
>> > >                && TREE_CODE (lhs2) == SSA_NAME)
>> > >         return vn_valueize (lhs1) == vn_valueize (lhs2);
>> > >       return false;
>> > >       }
>> > >
>> > > instead.  That's the kind of changes I have expected and have approved of.
>> >
>> > But even that looks like just adding extra work for all developers, with no
>> > gain.  You only have to add extra code and extra temporaries, in switches
>> > typically also have to add {} because of the temporaries and thus extra
>> > indentation level, and it doesn't simplify anything in the code.
>>
>> The branch attempts to use the C++ typesystem to capture information
>> about the kinds of gimple statement we expect, both:
>>   (A) so that the compiler can detect type errors, and
>>   (B) as a comprehension aid to the human reader of the code
>>
>> The ideal here is when function params and struct field can be
>> strengthened from "gimple" to a subclass ptr.  This captures the
>> knowledge that every use of a function or within a struct has a given
>> gimple code.
>
> I just don't like all the as_a/is_a stuff enforced everywhere,
> it means more typing, more temporaries, more indentation.
> So, as I view it, instead of the checks being done cheaply (yes, I think
> the gimple checking as we have right now is very cheap) under the
> hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
> put the burden on the developers, who has to check that manually through
> the as_a/is_a stuff everywhere, more typing and uglier syntax.
> I just don't see that as a step forward, instead a huge step backwards.
> But perhaps I'm alone with this.
> Can you e.g. compare the size of - lines in your patchset combined, and
> size of + lines in your patchset?  As in, if your changes lead to less
> typing or more.

I see two ways out here.  One is to add overloads to all the functions
taking the special types like

tree
gimple_assign_rhs1 (gimple *);

or simply add

gassign *operator ()(gimple *g) { return as_a <gassign *> (g); }

into a gimple-compat.h header which you include in places that
are not converted "nicely".

Both avoid manually making the compiler happy (which the
explicit as_a<> stuff is!  It doesn't add any "checking" - it's
just placing the as_a<> at the callers and thus make the
runtine ICE fire there).

As much as I don't like "global" conversion operators I don't
like adding overloads to all of the accessor functions even more.

Whether you enable them generally or just for selected files
via a gimple-compat.h will be up to you (but I'd rather get
rid of them at some point).

Note this allows seamless transform of "random" functions
taking a gimple now but really only expecting a single kind.

Note that we don't absolutely have to rush this all in for GCC 5.
Being the very first for GCC 6 stage1 is another possibility.
We just should get it right.

Thanks,
Richard.


>         Jakub

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-11  8:40             ` Eric Botcazou
@ 2014-11-11 11:55               ` Bernd Schmidt
  0 siblings, 0 replies; 36+ messages in thread
From: Bernd Schmidt @ 2014-11-11 11:55 UTC (permalink / raw)
  To: Eric Botcazou, Jakub Jelinek
  Cc: gcc, David Malcolm, Richard Biener, GCC Patches, Jeff Law

On 11/11/2014 09:30 AM, Eric Botcazou wrote:
>> I just don't like all the as_a/is_a stuff enforced everywhere,
>> it means more typing, more temporaries, more indentation.
>> So, as I view it, instead of the checks being done cheaply (yes, I think
>> the gimple checking as we have right now is very cheap) under the
>> hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
>> put the burden on the developers, who has to check that manually through
>> the as_a/is_a stuff everywhere, more typing and uglier syntax.
>> I just don't see that as a step forward, instead a huge step backwards.
>> But perhaps I'm alone with this.
>
> IMO that's the sort of things some of us were afraid of when the C++ switch
> was being discussed and IIRC we were told this would not happen...

I'm with both of you on this.


Bernd


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-11 10:46             ` Richard Biener
@ 2014-11-13  2:08               ` David Malcolm
  2014-11-13 10:47                 ` Richard Biener
  0 siblings, 1 reply; 36+ messages in thread
From: David Malcolm @ 2014-11-13  2:08 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jakub Jelinek, GCC Patches, GCC Development, Jeff Law

On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
> On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> > On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
> >> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
> >> > On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
> >> > > To be constructive here - the above case is from within a
> >> > > GIMPLE_ASSIGN case label
> >> > > and thus I'd have expected
> >> > >
> >> > >     case GIMPLE_ASSIGN:
> >> > >       {
> >> > >         gassign *a1 = as_a <gassign *> (s1);
> >> > >         gassign *a2 = as_a <gassign *> (s2);
> >> > >       lhs1 = gimple_assign_lhs (a1);
> >> > >       lhs2 = gimple_assign_lhs (a2);
> >> > >       if (TREE_CODE (lhs1) != SSA_NAME
> >> > >           && TREE_CODE (lhs2) != SSA_NAME)
> >> > >         return (operand_equal_p (lhs1, lhs2, 0)
> >> > >                 && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
> >> > >                                                  gimple_assign_rhs1 (a2)));
> >> > >       else if (TREE_CODE (lhs1) == SSA_NAME
> >> > >                && TREE_CODE (lhs2) == SSA_NAME)
> >> > >         return vn_valueize (lhs1) == vn_valueize (lhs2);
> >> > >       return false;
> >> > >       }
> >> > >
> >> > > instead.  That's the kind of changes I have expected and have approved of.
> >> >
> >> > But even that looks like just adding extra work for all developers, with no
> >> > gain.  You only have to add extra code and extra temporaries, in switches
> >> > typically also have to add {} because of the temporaries and thus extra
> >> > indentation level, and it doesn't simplify anything in the code.
> >>
> >> The branch attempts to use the C++ typesystem to capture information
> >> about the kinds of gimple statement we expect, both:
> >>   (A) so that the compiler can detect type errors, and
> >>   (B) as a comprehension aid to the human reader of the code
> >>
> >> The ideal here is when function params and struct field can be
> >> strengthened from "gimple" to a subclass ptr.  This captures the
> >> knowledge that every use of a function or within a struct has a given
> >> gimple code.
> >
> > I just don't like all the as_a/is_a stuff enforced everywhere,
> > it means more typing, more temporaries, more indentation.
> > So, as I view it, instead of the checks being done cheaply (yes, I think
> > the gimple checking as we have right now is very cheap) under the
> > hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
> > put the burden on the developers, who has to check that manually through
> > the as_a/is_a stuff everywhere, more typing and uglier syntax.
> > I just don't see that as a step forward, instead a huge step backwards.
> > But perhaps I'm alone with this.
> > Can you e.g. compare the size of - lines in your patchset combined, and
> > size of + lines in your patchset?  As in, if your changes lead to less
> > typing or more.
> 
> I see two ways out here.  One is to add overloads to all the functions
> taking the special types like
> 
> tree
> gimple_assign_rhs1 (gimple *);
> 
> or simply add
> 
> gassign *operator ()(gimple *g) { return as_a <gassign *> (g); }
> 
> into a gimple-compat.h header which you include in places that
> are not converted "nicely".

Thanks for the suggestions.

Am I missing something, or is the gimple-compat.h idea above not valid C
++?

Note that "gimple" is still a typedef to
  gimple_statement_base *
(as noted before, the gimple -> gimple * change would break everyone
else's patches, so we talked about that as a followup patch for early
stage3).

Given that, if I try to create an "operator ()" outside of a class, I
get this error:

‘gassign* operator()(gimple)’ must be a nonstatic member function

which is emitted from cp/decl.c's grok_op_properties:
      /* An operator function must either be a non-static member function
	 or have at least one parameter of a class, a reference to a class,
	 an enumeration, or a reference to an enumeration.  13.4.0.6 */

I tried making it a member function of gimple_statement_base, but that
doesn't work either: we want a conversion
  from a gimple_statement_base * to a gassign *, not
  from a gimple_statement_base   to a gassign *.

Is there some syntactic trick here that I'm missing?  Sorry if I'm being
dumb (I can imagine there's a way of doing it by making "gimple" become
some kind of wrapped ptr class, but that way lies madness, surely).

> Both avoid manually making the compiler happy (which the
> explicit as_a<> stuff is!  It doesn't add any "checking" - it's
> just placing the as_a<> at the callers and thus make the
> runtine ICE fire there).
> 
> As much as I don't like "global" conversion operators I don't
> like adding overloads to all of the accessor functions even more.

(nods)

Some other options:

Option 3: only convert the "easy" accessors: the ones I already did in
the /89 patch kit, as reviewed by Jeff, and rebased by me recently,
which is this 92-patch kit:
  "[gimple-classes, committed 00/92] Initial slew of commits":
     https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html
Doing so converts about half of the gimple_foo_ accessors to taking a
gfoo *, giving a mixture of GIMPLE_CHECK vs subclass use.   I believe
the quality of those patches was higher than the later ones on the
branch: I was doing the places that didn't require the invasive/verbose
changes seen in the later patches.  Shelve the remaining ~80
increasingly ugly patches, starting a new branch to contain just the
good ones.


Option 4: don't convert any accessors, but instead focus on fields of
structs (e.g. "call_stmt" within a cgraph_edge), and on params of other
functions (e.g. phi-manipulation code).  That way we'd avoid the
inconsistency of some accessors using GIMPLE_CHECK and some using
subclasses - all would continue to consistently use GIMPLE_CHECK, but
there would be some extra type-checking and self-documentation of the
expected statement kinds in the code.



FWIW, option 3 is my preferred approach (I've already done the bulk of
the work and it's already been reviewed; it would need an update merger
from trunk, and there's the big gimple to gimple * fixup you wanted).

> Whether you enable them generally or just for selected files
> via a gimple-compat.h will be up to you (but I'd rather get
> rid of them at some point).
> 
> Note this allows seamless transform of "random" functions
> taking a gimple now but really only expecting a single kind.
> 
> Note that we don't absolutely have to rush this all in for GCC 5.
> Being the very first for GCC 6 stage1 is another possibility.
> We just should get it right.

Thanks
Dave

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-11  7:35           ` Jakub Jelinek
  2014-11-11  8:40             ` Eric Botcazou
  2014-11-11 10:46             ` Richard Biener
@ 2014-11-13  2:23             ` David Malcolm
  2 siblings, 0 replies; 36+ messages in thread
From: David Malcolm @ 2014-11-13  2:23 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Richard Biener, GCC Patches, GCC Development, Jeff Law

On Tue, 2014-11-11 at 08:26 +0100, Jakub Jelinek wrote:
> On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
> > On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
> > > On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
> > > > To be constructive here - the above case is from within a
> > > > GIMPLE_ASSIGN case label
> > > > and thus I'd have expected
> > > > 
> > > >     case GIMPLE_ASSIGN:
> > > >       {
> > > >         gassign *a1 = as_a <gassign *> (s1);
> > > >         gassign *a2 = as_a <gassign *> (s2);
> > > >       lhs1 = gimple_assign_lhs (a1);
> > > >       lhs2 = gimple_assign_lhs (a2);
> > > >       if (TREE_CODE (lhs1) != SSA_NAME
> > > >           && TREE_CODE (lhs2) != SSA_NAME)
> > > >         return (operand_equal_p (lhs1, lhs2, 0)
> > > >                 && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
> > > >                                                  gimple_assign_rhs1 (a2)));
> > > >       else if (TREE_CODE (lhs1) == SSA_NAME
> > > >                && TREE_CODE (lhs2) == SSA_NAME)
> > > >         return vn_valueize (lhs1) == vn_valueize (lhs2);
> > > >       return false;
> > > >       }
> > > > 
> > > > instead.  That's the kind of changes I have expected and have approved of.
> > > 
> > > But even that looks like just adding extra work for all developers, with no
> > > gain.  You only have to add extra code and extra temporaries, in switches
> > > typically also have to add {} because of the temporaries and thus extra
> > > indentation level, and it doesn't simplify anything in the code.
> > 
> > The branch attempts to use the C++ typesystem to capture information
> > about the kinds of gimple statement we expect, both:
> >   (A) so that the compiler can detect type errors, and
> >   (B) as a comprehension aid to the human reader of the code
> > 
> > The ideal here is when function params and struct field can be
> > strengthened from "gimple" to a subclass ptr.  This captures the
> > knowledge that every use of a function or within a struct has a given
> > gimple code.
> 
> I just don't like all the as_a/is_a stuff enforced everywhere,
> it means more typing, more temporaries, more indentation.
> So, as I view it, instead of the checks being done cheaply (yes, I think
> the gimple checking as we have right now is very cheap) under the
> hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
> put the burden on the developers, who has to check that manually through
> the as_a/is_a stuff everywhere, more typing and uglier syntax.
> I just don't see that as a step forward, instead a huge step backwards.
> But perhaps I'm alone with this.

I agree with you w.r.t. my later patches.   I like my initial set of 89
patches, but I overdid things with the attempt to convert all of the
gimple_assign_ accessors.

> Can you e.g. compare the size of - lines in your patchset combined, and
> size of + lines in your patchset?  As in, if your changes lead to less
> typing or more.

I don't know if this data matches the proposed interpretation
(autoindentation in emacs is wonderful), but here goes:

Diff of my current working copy vs last merge point, ignoring ChangeLog
additions, obtaining lines starting "-", piping into wc:

$ git diff fddbd0194b01f44c5b5f16379fd5405dcf6d71c0 $(git diff
fddbd0194b01f44c5b5f16379fd5405dcf6d71c0 | diffstat -lp1 | grep -v
ChangeLog) | grep -e "^-" | wc
   6169   31032  272916

Likewise for lines starting with "+":

$ git diff fddbd0194b01f44c5b5f16379fd5405dcf6d71c0 $(git diff
fddbd0194b01f44c5b5f16379fd5405dcf6d71c0 | diffstat -lp1 | grep -v
ChangeLog) | grep -e "^+" | wc
   7295   36566  309380

so the + lines have 13% more bytes than the - lines


Dave

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-13  2:08               ` David Malcolm
@ 2014-11-13 10:47                 ` Richard Biener
  2014-11-13 11:02                   ` Jonathan Wakely
                                     ` (3 more replies)
  0 siblings, 4 replies; 36+ messages in thread
From: Richard Biener @ 2014-11-13 10:47 UTC (permalink / raw)
  To: David Malcolm; +Cc: Jakub Jelinek, GCC Patches, GCC Development, Jeff Law

On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm <dmalcolm@redhat.com> wrote:
> On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
>> On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>> > On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
>> >> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
>> >> > On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
>> >> > > To be constructive here - the above case is from within a
>> >> > > GIMPLE_ASSIGN case label
>> >> > > and thus I'd have expected
>> >> > >
>> >> > >     case GIMPLE_ASSIGN:
>> >> > >       {
>> >> > >         gassign *a1 = as_a <gassign *> (s1);
>> >> > >         gassign *a2 = as_a <gassign *> (s2);
>> >> > >       lhs1 = gimple_assign_lhs (a1);
>> >> > >       lhs2 = gimple_assign_lhs (a2);
>> >> > >       if (TREE_CODE (lhs1) != SSA_NAME
>> >> > >           && TREE_CODE (lhs2) != SSA_NAME)
>> >> > >         return (operand_equal_p (lhs1, lhs2, 0)
>> >> > >                 && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
>> >> > >                                                  gimple_assign_rhs1 (a2)));
>> >> > >       else if (TREE_CODE (lhs1) == SSA_NAME
>> >> > >                && TREE_CODE (lhs2) == SSA_NAME)
>> >> > >         return vn_valueize (lhs1) == vn_valueize (lhs2);
>> >> > >       return false;
>> >> > >       }
>> >> > >
>> >> > > instead.  That's the kind of changes I have expected and have approved of.
>> >> >
>> >> > But even that looks like just adding extra work for all developers, with no
>> >> > gain.  You only have to add extra code and extra temporaries, in switches
>> >> > typically also have to add {} because of the temporaries and thus extra
>> >> > indentation level, and it doesn't simplify anything in the code.
>> >>
>> >> The branch attempts to use the C++ typesystem to capture information
>> >> about the kinds of gimple statement we expect, both:
>> >>   (A) so that the compiler can detect type errors, and
>> >>   (B) as a comprehension aid to the human reader of the code
>> >>
>> >> The ideal here is when function params and struct field can be
>> >> strengthened from "gimple" to a subclass ptr.  This captures the
>> >> knowledge that every use of a function or within a struct has a given
>> >> gimple code.
>> >
>> > I just don't like all the as_a/is_a stuff enforced everywhere,
>> > it means more typing, more temporaries, more indentation.
>> > So, as I view it, instead of the checks being done cheaply (yes, I think
>> > the gimple checking as we have right now is very cheap) under the
>> > hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
>> > put the burden on the developers, who has to check that manually through
>> > the as_a/is_a stuff everywhere, more typing and uglier syntax.
>> > I just don't see that as a step forward, instead a huge step backwards.
>> > But perhaps I'm alone with this.
>> > Can you e.g. compare the size of - lines in your patchset combined, and
>> > size of + lines in your patchset?  As in, if your changes lead to less
>> > typing or more.
>>
>> I see two ways out here.  One is to add overloads to all the functions
>> taking the special types like
>>
>> tree
>> gimple_assign_rhs1 (gimple *);
>>
>> or simply add
>>
>> gassign *operator ()(gimple *g) { return as_a <gassign *> (g); }
>>
>> into a gimple-compat.h header which you include in places that
>> are not converted "nicely".
>
> Thanks for the suggestions.
>
> Am I missing something, or is the gimple-compat.h idea above not valid C
> ++?
>
> Note that "gimple" is still a typedef to
>   gimple_statement_base *
> (as noted before, the gimple -> gimple * change would break everyone
> else's patches, so we talked about that as a followup patch for early
> stage3).
>
> Given that, if I try to create an "operator ()" outside of a class, I
> get this error:
>
> ‘gassign* operator()(gimple)’ must be a nonstatic member function
>
> which is emitted from cp/decl.c's grok_op_properties:
>       /* An operator function must either be a non-static member function
>          or have at least one parameter of a class, a reference to a class,
>          an enumeration, or a reference to an enumeration.  13.4.0.6 */
>
> I tried making it a member function of gimple_statement_base, but that
> doesn't work either: we want a conversion
>   from a gimple_statement_base * to a gassign *, not
>   from a gimple_statement_base   to a gassign *.
>
> Is there some syntactic trick here that I'm missing?  Sorry if I'm being
> dumb (I can imagine there's a way of doing it by making "gimple" become
> some kind of wrapped ptr class, but that way lies madness, surely).

Hmm.

struct assign;
struct base {
  operator assign *() const { return (assign *)this; }
};
struct assign : base {
};

void foo (assign *);
void bar (base *b)
{
  foo (b);
}

doesn't work, but

void bar (base &b)
{
  foo (b);
}

does.  Indeed C++ doesn't seem to provide what is necessary
for the compat trick :(

So the gimple-compat.h header would need to provide
additional overloads for the affected functions like

inline tree
gimple_assign_rhs1 (gimple *g)
{
  return gimple_assign_rhs1 (as_a <gassign *> (g));
}

that would work for me as well.

>> Both avoid manually making the compiler happy (which the
>> explicit as_a<> stuff is!  It doesn't add any "checking" - it's
>> just placing the as_a<> at the callers and thus make the
>> runtine ICE fire there).
>>
>> As much as I don't like "global" conversion operators I don't
>> like adding overloads to all of the accessor functions even more.
>
> (nods)
>
> Some other options:
>
> Option 3: only convert the "easy" accessors: the ones I already did in
> the /89 patch kit, as reviewed by Jeff, and rebased by me recently,
> which is this 92-patch kit:
>   "[gimple-classes, committed 00/92] Initial slew of commits":
>      https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html
> Doing so converts about half of the gimple_foo_ accessors to taking a
> gfoo *, giving a mixture of GIMPLE_CHECK vs subclass use.   I believe
> the quality of those patches was higher than the later ones on the
> branch: I was doing the places that didn't require the invasive/verbose
> changes seen in the later patches.  Shelve the remaining ~80
> increasingly ugly patches, starting a new branch to contain just the
> good ones.
>
>
> Option 4: don't convert any accessors, but instead focus on fields of
> structs (e.g. "call_stmt" within a cgraph_edge), and on params of other
> functions (e.g. phi-manipulation code).  That way we'd avoid the
> inconsistency of some accessors using GIMPLE_CHECK and some using
> subclasses - all would continue to consistently use GIMPLE_CHECK, but
> there would be some extra type-checking and self-documentation of the
> expected statement kinds in the code.
>
>
>
> FWIW, option 3 is my preferred approach (I've already done the bulk of
> the work and it's already been reviewed; it would need an update merger
> from trunk, and there's the big gimple to gimple * fixup you wanted).

Works for me as well.  The compat solution looks somewhat appealing
as we can then incrementally fix up things rather than requiring to
mass-convert everything.

Thanks,
Richard.

>> Whether you enable them generally or just for selected files
>> via a gimple-compat.h will be up to you (but I'd rather get
>> rid of them at some point).
>>
>> Note this allows seamless transform of "random" functions
>> taking a gimple now but really only expecting a single kind.
>>
>> Note that we don't absolutely have to rush this all in for GCC 5.
>> Being the very first for GCC 6 stage1 is another possibility.
>> We just should get it right.
>
> Thanks
> Dave
>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-13 10:47                 ` Richard Biener
@ 2014-11-13 11:02                   ` Jonathan Wakely
  2014-11-13 14:28                   ` Andrew MacLeod
                                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 36+ messages in thread
From: Jonathan Wakely @ 2014-11-13 11:02 UTC (permalink / raw)
  To: Richard Biener
  Cc: David Malcolm, Jakub Jelinek, GCC Patches, GCC Development, Jeff Law

On 13 November 2014 10:45, Richard Biener wrote:
>
> Hmm.
>
> struct assign;
> struct base {
>   operator assign *() const { return (assign *)this; }
> };
> struct assign : base {
> };
>
> void foo (assign *);
> void bar (base *b)
> {
>   foo (b);
> }
>
> doesn't work, but
>
> void bar (base &b)
> {
>   foo (b);
> }
>
> does.  Indeed C++ doesn't seem to provide what is necessary
> for the compat trick :(

Right, base* is a built-in type, you can't call a member function on it.

There is no implicit conversion between unrelated pointer types, and
no implicit conversion from base* to base& that would be necessary to
call the conversion operator of base.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-13 10:47                 ` Richard Biener
  2014-11-13 11:02                   ` Jonathan Wakely
@ 2014-11-13 14:28                   ` Andrew MacLeod
  2014-11-13 14:36                     ` Richard Biener
  2014-11-14 15:44                   ` [PATCH] Add gimple-compat.h (was Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign) David Malcolm
  2014-11-15 11:58                   ` [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign David Malcolm
  3 siblings, 1 reply; 36+ messages in thread
From: Andrew MacLeod @ 2014-11-13 14:28 UTC (permalink / raw)
  To: Richard Biener, David Malcolm
  Cc: Jakub Jelinek, GCC Patches, GCC Development, Jeff Law

On 11/13/2014 05:45 AM, Richard Biener wrote:
> On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm <dmalcolm@redhat.com> wrote:
>> On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
>>> On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>>>> On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
>>>>> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
>>>>>> On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
>>>>>>> To be constructive here - the above case is from within a
>>>>>>> GIMPLE_ASSIGN case label
>>>>>>> and thus I'd have expected
>>>>>>>
>>>>>>>      case GIMPLE_ASSIGN:
>>>>>>>        {
>>>>>>>          gassign *a1 = as_a <gassign *> (s1);
>>>>>>>          gassign *a2 = as_a <gassign *> (s2);
>>>>>>>        lhs1 = gimple_assign_lhs (a1);
>>>>>>>        lhs2 = gimple_assign_lhs (a2);
>>>>>>>        if (TREE_CODE (lhs1) != SSA_NAME
>>>>>>>            && TREE_CODE (lhs2) != SSA_NAME)
>>>>>>>          return (operand_equal_p (lhs1, lhs2, 0)
>>>>>>>                  && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
>>>>>>>                                                   gimple_assign_rhs1 (a2)));
>>>>>>>        else if (TREE_CODE (lhs1) == SSA_NAME
>>>>>>>                 && TREE_CODE (lhs2) == SSA_NAME)
>>>>>>>          return vn_valueize (lhs1) == vn_valueize (lhs2);
>>>>>>>        return false;
>>>>>>>        }
>>>>>>>
>>>>>>> instead.  That's the kind of changes I have expected and have approved of.
>>>>>> But even that looks like just adding extra work for all developers, with no
>>>>>> gain.  You only have to add extra code and extra temporaries, in switches
>>>>>> typically also have to add {} because of the temporaries and thus extra
>>>>>> indentation level, and it doesn't simplify anything in the code.
>>>>> The branch attempts to use the C++ typesystem to capture information
>>>>> about the kinds of gimple statement we expect, both:
>>>>>    (A) so that the compiler can detect type errors, and
>>>>>    (B) as a comprehension aid to the human reader of the code
>>>>>
>>>>> The ideal here is when function params and struct field can be
>>>>> strengthened from "gimple" to a subclass ptr.  This captures the
>>>>> knowledge that every use of a function or within a struct has a given
>>>>> gimple code.
>>>> I just don't like all the as_a/is_a stuff enforced everywhere,
>>>> it means more typing, more temporaries, more indentation.
>>>> So, as I view it, instead of the checks being done cheaply (yes, I think
>>>> the gimple checking as we have right now is very cheap) under the
>>>> hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
>>>> put the burden on the developers, who has to check that manually through
>>>> the as_a/is_a stuff everywhere, more typing and uglier syntax.
>>>> I just don't see that as a step forward, instead a huge step backwards.
>>>> But perhaps I'm alone with this.
>>>> Can you e.g. compare the size of - lines in your patchset combined, and
>>>> size of + lines in your patchset?  As in, if your changes lead to less
>>>> typing or more.
>>> I see two ways out here.  One is to add overloads to all the functions
>>> taking the special types like
>>>
>>> tree
>>> gimple_assign_rhs1 (gimple *);
>>>
>>> or simply add
>>>
>>> gassign *operator ()(gimple *g) { return as_a <gassign *> (g); }
>>>
>>> into a gimple-compat.h header which you include in places that
>>> are not converted "nicely".
>> Thanks for the suggestions.
>>
>> Am I missing something, or is the gimple-compat.h idea above not valid C
>> ++?
>>
>> Note that "gimple" is still a typedef to
>>    gimple_statement_base *
>> (as noted before, the gimple -> gimple * change would break everyone
>> else's patches, so we talked about that as a followup patch for early
>> stage3).
>>
>> Given that, if I try to create an "operator ()" outside of a class, I
>> get this error:
>>
>> ‘gassign* operator()(gimple)’ must be a nonstatic member function
>>
>> which is emitted from cp/decl.c's grok_op_properties:
>>        /* An operator function must either be a non-static member function
>>           or have at least one parameter of a class, a reference to a class,
>>           an enumeration, or a reference to an enumeration.  13.4.0.6 */
>>
>> I tried making it a member function of gimple_statement_base, but that
>> doesn't work either: we want a conversion
>>    from a gimple_statement_base * to a gassign *, not
>>    from a gimple_statement_base   to a gassign *.
>>
>> Is there some syntactic trick here that I'm missing?  Sorry if I'm being
>> dumb (I can imagine there's a way of doing it by making "gimple" become
>> some kind of wrapped ptr class, but that way lies madness, surely).
> Hmm.
>
> struct assign;
> struct base {
>    operator assign *() const { return (assign *)this; }
> };
> struct assign : base {
> };
>
> void foo (assign *);
> void bar (base *b)
> {
>    foo (b);
> }
>
> doesn't work, but
>
> void bar (base &b)
> {
>    foo (b);
> }
>
> does.  Indeed C++ doesn't seem to provide what is necessary
> for the compat trick :(
>
> So the gimple-compat.h header would need to provide
> additional overloads for the affected functions like
>
> inline tree
> gimple_assign_rhs1 (gimple *g)
> {
>    return gimple_assign_rhs1 (as_a <gassign *> (g));
> }
>
> that would work for me as well.
>
>
Won't that defeat the desire for checking tho?  If you dont do a 
dyn_cast<>  in gimple_assign_rhs1 (gimple *g)  anyone can call it and 
upcast any kind of gimple into a gassign without checking that it is 
really a gassign...   Actually, a gcc_assert here may be sufficient... 
and better.

It'd be pretty easy to miss someone calling it when its not a gassign.

Andrew


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-13 14:28                   ` Andrew MacLeod
@ 2014-11-13 14:36                     ` Richard Biener
  2014-11-13 15:20                       ` Andrew MacLeod
  0 siblings, 1 reply; 36+ messages in thread
From: Richard Biener @ 2014-11-13 14:36 UTC (permalink / raw)
  To: Andrew MacLeod
  Cc: David Malcolm, Jakub Jelinek, GCC Patches, GCC Development, Jeff Law

On Thu, Nov 13, 2014 at 3:24 PM, Andrew MacLeod <amacleod@redhat.com> wrote:
> On 11/13/2014 05:45 AM, Richard Biener wrote:
>>
>> On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm <dmalcolm@redhat.com>
>> wrote:
>>>
>>> On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
>>>>
>>>> On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>>>>>
>>>>> On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
>>>>>>
>>>>>> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
>>>>>>>
>>>>>>> On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
>>>>>>>>
>>>>>>>> To be constructive here - the above case is from within a
>>>>>>>> GIMPLE_ASSIGN case label
>>>>>>>> and thus I'd have expected
>>>>>>>>
>>>>>>>>      case GIMPLE_ASSIGN:
>>>>>>>>        {
>>>>>>>>          gassign *a1 = as_a <gassign *> (s1);
>>>>>>>>          gassign *a2 = as_a <gassign *> (s2);
>>>>>>>>        lhs1 = gimple_assign_lhs (a1);
>>>>>>>>        lhs2 = gimple_assign_lhs (a2);
>>>>>>>>        if (TREE_CODE (lhs1) != SSA_NAME
>>>>>>>>            && TREE_CODE (lhs2) != SSA_NAME)
>>>>>>>>          return (operand_equal_p (lhs1, lhs2, 0)
>>>>>>>>                  && gimple_operand_equal_value_p (gimple_assign_rhs1
>>>>>>>> (a1),
>>>>>>>>                                                   gimple_assign_rhs1
>>>>>>>> (a2)));
>>>>>>>>        else if (TREE_CODE (lhs1) == SSA_NAME
>>>>>>>>                 && TREE_CODE (lhs2) == SSA_NAME)
>>>>>>>>          return vn_valueize (lhs1) == vn_valueize (lhs2);
>>>>>>>>        return false;
>>>>>>>>        }
>>>>>>>>
>>>>>>>> instead.  That's the kind of changes I have expected and have
>>>>>>>> approved of.
>>>>>>>
>>>>>>> But even that looks like just adding extra work for all developers,
>>>>>>> with no
>>>>>>> gain.  You only have to add extra code and extra temporaries, in
>>>>>>> switches
>>>>>>> typically also have to add {} because of the temporaries and thus
>>>>>>> extra
>>>>>>> indentation level, and it doesn't simplify anything in the code.
>>>>>>
>>>>>> The branch attempts to use the C++ typesystem to capture information
>>>>>> about the kinds of gimple statement we expect, both:
>>>>>>    (A) so that the compiler can detect type errors, and
>>>>>>    (B) as a comprehension aid to the human reader of the code
>>>>>>
>>>>>> The ideal here is when function params and struct field can be
>>>>>> strengthened from "gimple" to a subclass ptr.  This captures the
>>>>>> knowledge that every use of a function or within a struct has a given
>>>>>> gimple code.
>>>>>
>>>>> I just don't like all the as_a/is_a stuff enforced everywhere,
>>>>> it means more typing, more temporaries, more indentation.
>>>>> So, as I view it, instead of the checks being done cheaply (yes, I
>>>>> think
>>>>> the gimple checking as we have right now is very cheap) under the
>>>>> hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
>>>>> put the burden on the developers, who has to check that manually
>>>>> through
>>>>> the as_a/is_a stuff everywhere, more typing and uglier syntax.
>>>>> I just don't see that as a step forward, instead a huge step backwards.
>>>>> But perhaps I'm alone with this.
>>>>> Can you e.g. compare the size of - lines in your patchset combined, and
>>>>> size of + lines in your patchset?  As in, if your changes lead to less
>>>>> typing or more.
>>>>
>>>> I see two ways out here.  One is to add overloads to all the functions
>>>> taking the special types like
>>>>
>>>> tree
>>>> gimple_assign_rhs1 (gimple *);
>>>>
>>>> or simply add
>>>>
>>>> gassign *operator ()(gimple *g) { return as_a <gassign *> (g); }
>>>>
>>>> into a gimple-compat.h header which you include in places that
>>>> are not converted "nicely".
>>>
>>> Thanks for the suggestions.
>>>
>>> Am I missing something, or is the gimple-compat.h idea above not valid C
>>> ++?
>>>
>>> Note that "gimple" is still a typedef to
>>>    gimple_statement_base *
>>> (as noted before, the gimple -> gimple * change would break everyone
>>> else's patches, so we talked about that as a followup patch for early
>>> stage3).
>>>
>>> Given that, if I try to create an "operator ()" outside of a class, I
>>> get this error:
>>>
>>> ‘gassign* operator()(gimple)’ must be a nonstatic member function
>>>
>>> which is emitted from cp/decl.c's grok_op_properties:
>>>        /* An operator function must either be a non-static member
>>> function
>>>           or have at least one parameter of a class, a reference to a
>>> class,
>>>           an enumeration, or a reference to an enumeration.  13.4.0.6 */
>>>
>>> I tried making it a member function of gimple_statement_base, but that
>>> doesn't work either: we want a conversion
>>>    from a gimple_statement_base * to a gassign *, not
>>>    from a gimple_statement_base   to a gassign *.
>>>
>>> Is there some syntactic trick here that I'm missing?  Sorry if I'm being
>>> dumb (I can imagine there's a way of doing it by making "gimple" become
>>> some kind of wrapped ptr class, but that way lies madness, surely).
>>
>> Hmm.
>>
>> struct assign;
>> struct base {
>>    operator assign *() const { return (assign *)this; }
>> };
>> struct assign : base {
>> };
>>
>> void foo (assign *);
>> void bar (base *b)
>> {
>>    foo (b);
>> }
>>
>> doesn't work, but
>>
>> void bar (base &b)
>> {
>>    foo (b);
>> }
>>
>> does.  Indeed C++ doesn't seem to provide what is necessary
>> for the compat trick :(
>>
>> So the gimple-compat.h header would need to provide
>> additional overloads for the affected functions like
>>
>> inline tree
>> gimple_assign_rhs1 (gimple *g)
>> {
>>    return gimple_assign_rhs1 (as_a <gassign *> (g));
>> }
>>
>> that would work for me as well.
>>
>>
> Won't that defeat the desire for checking tho?  If you dont do a dyn_cast<>
> in gimple_assign_rhs1 (gimple *g)  anyone can call it and upcast any kind of
> gimple into a gassign without checking that it is really a gassign...
> Actually, a gcc_assert here may be sufficient... and better.
>
> It'd be pretty easy to miss someone calling it when its not a gassign.

as_a performs that checking.

Richard.

> Andrew
>
>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-13 14:36                     ` Richard Biener
@ 2014-11-13 15:20                       ` Andrew MacLeod
  0 siblings, 0 replies; 36+ messages in thread
From: Andrew MacLeod @ 2014-11-13 15:20 UTC (permalink / raw)
  To: Richard Biener
  Cc: David Malcolm, Jakub Jelinek, GCC Patches, GCC Development, Jeff Law

On 11/13/2014 09:34 AM, Richard Biener wrote:
> On Thu, Nov 13, 2014 at 3:24 PM, Andrew MacLeod <amacleod@redhat.com> wrote:
>> On 11/13/2014 05:45 AM, Richard Biener wrote:
>>> On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm <dmalcolm@redhat.com>
>>> wrote:
>>>> On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
>>>>> On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>>>>>> On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
>>>>>>> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
>>>>>>>> On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
>>>>>>>>> To be constructive here - the above case is from within a
>>>>>>>>> GIMPLE_ASSIGN case label
>>>>>>>>> and thus I'd have expected
>>>>>>>>>
>>>>>>>>>       case GIMPLE_ASSIGN:
>>>>>>>>>         {
>>>>>>>>>           gassign *a1 = as_a <gassign *> (s1);
>>>>>>>>>           gassign *a2 = as_a <gassign *> (s2);
>>>>>>>>>         lhs1 = gimple_assign_lhs (a1);
>>>>>>>>>         lhs2 = gimple_assign_lhs (a2);
>>>>>>>>>         if (TREE_CODE (lhs1) != SSA_NAME
>>>>>>>>>             && TREE_CODE (lhs2) != SSA_NAME)
>>>>>>>>>           return (operand_equal_p (lhs1, lhs2, 0)
>>>>>>>>>                   && gimple_operand_equal_value_p (gimple_assign_rhs1
>>>>>>>>> (a1),
>>>>>>>>>                                                    gimple_assign_rhs1
>>>>>>>>> (a2)));
>>>>>>>>>         else if (TREE_CODE (lhs1) == SSA_NAME
>>>>>>>>>                  && TREE_CODE (lhs2) == SSA_NAME)
>>>>>>>>>           return vn_valueize (lhs1) == vn_valueize (lhs2);
>>>>>>>>>         return false;
>>>>>>>>>         }
>>>>>>>>>
>>>>>>>>> instead.  That's the kind of changes I have expected and have
>>>>>>>>> approved of.
>>>>>>>> But even that looks like just adding extra work for all developers,
>>>>>>>> with no
>>>>>>>> gain.  You only have to add extra code and extra temporaries, in
>>>>>>>> switches
>>>>>>>> typically also have to add {} because of the temporaries and thus
>>>>>>>> extra
>>>>>>>> indentation level, and it doesn't simplify anything in the code.
>>>>>>> The branch attempts to use the C++ typesystem to capture information
>>>>>>> about the kinds of gimple statement we expect, both:
>>>>>>>     (A) so that the compiler can detect type errors, and
>>>>>>>     (B) as a comprehension aid to the human reader of the code
>>>>>>>
>>>>>>> The ideal here is when function params and struct field can be
>>>>>>> strengthened from "gimple" to a subclass ptr.  This captures the
>>>>>>> knowledge that every use of a function or within a struct has a given
>>>>>>> gimple code.
>>>>>> I just don't like all the as_a/is_a stuff enforced everywhere,
>>>>>> it means more typing, more temporaries, more indentation.
>>>>>> So, as I view it, instead of the checks being done cheaply (yes, I
>>>>>> think
>>>>>> the gimple checking as we have right now is very cheap) under the
>>>>>> hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
>>>>>> put the burden on the developers, who has to check that manually
>>>>>> through
>>>>>> the as_a/is_a stuff everywhere, more typing and uglier syntax.
>>>>>> I just don't see that as a step forward, instead a huge step backwards.
>>>>>> But perhaps I'm alone with this.
>>>>>> Can you e.g. compare the size of - lines in your patchset combined, and
>>>>>> size of + lines in your patchset?  As in, if your changes lead to less
>>>>>> typing or more.
>>>>> I see two ways out here.  One is to add overloads to all the functions
>>>>> taking the special types like
>>>>>
>>>>> tree
>>>>> gimple_assign_rhs1 (gimple *);
>>>>>
>>>>> or simply add
>>>>>
>>>>> gassign *operator ()(gimple *g) { return as_a <gassign *> (g); }
>>>>>
>>>>> into a gimple-compat.h header which you include in places that
>>>>> are not converted "nicely".
>>>> Thanks for the suggestions.
>>>>
>>>> Am I missing something, or is the gimple-compat.h idea above not valid C
>>>> ++?
>>>>
>>>> Note that "gimple" is still a typedef to
>>>>     gimple_statement_base *
>>>> (as noted before, the gimple -> gimple * change would break everyone
>>>> else's patches, so we talked about that as a followup patch for early
>>>> stage3).
>>>>
>>>> Given that, if I try to create an "operator ()" outside of a class, I
>>>> get this error:
>>>>
>>>> ‘gassign* operator()(gimple)’ must be a nonstatic member function
>>>>
>>>> which is emitted from cp/decl.c's grok_op_properties:
>>>>         /* An operator function must either be a non-static member
>>>> function
>>>>            or have at least one parameter of a class, a reference to a
>>>> class,
>>>>            an enumeration, or a reference to an enumeration.  13.4.0.6 */
>>>>
>>>> I tried making it a member function of gimple_statement_base, but that
>>>> doesn't work either: we want a conversion
>>>>     from a gimple_statement_base * to a gassign *, not
>>>>     from a gimple_statement_base   to a gassign *.
>>>>
>>>> Is there some syntactic trick here that I'm missing?  Sorry if I'm being
>>>> dumb (I can imagine there's a way of doing it by making "gimple" become
>>>> some kind of wrapped ptr class, but that way lies madness, surely).
>>> Hmm.
>>>
>>> struct assign;
>>> struct base {
>>>     operator assign *() const { return (assign *)this; }
>>> };
>>> struct assign : base {
>>> };
>>>
>>> void foo (assign *);
>>> void bar (base *b)
>>> {
>>>     foo (b);
>>> }
>>>
>>> doesn't work, but
>>>
>>> void bar (base &b)
>>> {
>>>     foo (b);
>>> }
>>>
>>> does.  Indeed C++ doesn't seem to provide what is necessary
>>> for the compat trick :(
>>>
>>> So the gimple-compat.h header would need to provide
>>> additional overloads for the affected functions like
>>>
>>> inline tree
>>> gimple_assign_rhs1 (gimple *g)
>>> {
>>>     return gimple_assign_rhs1 (as_a <gassign *> (g));
>>> }
>>>
>>> that would work for me as well.
>>>
>>>
>> Won't that defeat the desire for checking tho?  If you dont do a dyn_cast<>
>> in gimple_assign_rhs1 (gimple *g)  anyone can call it and upcast any kind of
>> gimple into a gassign without checking that it is really a gassign...
>> Actually, a gcc_assert here may be sufficient... and better.
>>
>> It'd be pretty easy to miss someone calling it when its not a gassign.
> as_a performs that checking.
>
> Richard.
>
>
Ah, so it does.  Nevermind :-)

Andrew

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH] Add gimple-compat.h (was Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign)
  2014-11-13 10:47                 ` Richard Biener
  2014-11-13 11:02                   ` Jonathan Wakely
  2014-11-13 14:28                   ` Andrew MacLeod
@ 2014-11-14 15:44                   ` David Malcolm
  2014-11-17  9:54                     ` Richard Biener
  2014-11-17 19:44                     ` Jeff Law
  2014-11-15 11:58                   ` [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign David Malcolm
  3 siblings, 2 replies; 36+ messages in thread
From: David Malcolm @ 2014-11-14 15:44 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jakub Jelinek, GCC Patches, GCC Development, Jeff Law

[-- Attachment #1: Type: text/plain, Size: 9442 bytes --]

On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote:
> On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm <dmalcolm@redhat.com> wrote:
> > On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
> >> On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> >> > On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
> >> >> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
> >> >> > On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
> >> >> > > To be constructive here - the above case is from within a
> >> >> > > GIMPLE_ASSIGN case label
> >> >> > > and thus I'd have expected
> >> >> > >
> >> >> > >     case GIMPLE_ASSIGN:
> >> >> > >       {
> >> >> > >         gassign *a1 = as_a <gassign *> (s1);
> >> >> > >         gassign *a2 = as_a <gassign *> (s2);
> >> >> > >       lhs1 = gimple_assign_lhs (a1);
> >> >> > >       lhs2 = gimple_assign_lhs (a2);
> >> >> > >       if (TREE_CODE (lhs1) != SSA_NAME
> >> >> > >           && TREE_CODE (lhs2) != SSA_NAME)
> >> >> > >         return (operand_equal_p (lhs1, lhs2, 0)
> >> >> > >                 && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
> >> >> > >                                                  gimple_assign_rhs1 (a2)));
> >> >> > >       else if (TREE_CODE (lhs1) == SSA_NAME
> >> >> > >                && TREE_CODE (lhs2) == SSA_NAME)
> >> >> > >         return vn_valueize (lhs1) == vn_valueize (lhs2);
> >> >> > >       return false;
> >> >> > >       }
> >> >> > >
> >> >> > > instead.  That's the kind of changes I have expected and have approved of.
> >> >> >
> >> >> > But even that looks like just adding extra work for all developers, with no
> >> >> > gain.  You only have to add extra code and extra temporaries, in switches
> >> >> > typically also have to add {} because of the temporaries and thus extra
> >> >> > indentation level, and it doesn't simplify anything in the code.
> >> >>
> >> >> The branch attempts to use the C++ typesystem to capture information
> >> >> about the kinds of gimple statement we expect, both:
> >> >>   (A) so that the compiler can detect type errors, and
> >> >>   (B) as a comprehension aid to the human reader of the code
> >> >>
> >> >> The ideal here is when function params and struct field can be
> >> >> strengthened from "gimple" to a subclass ptr.  This captures the
> >> >> knowledge that every use of a function or within a struct has a given
> >> >> gimple code.
> >> >
> >> > I just don't like all the as_a/is_a stuff enforced everywhere,
> >> > it means more typing, more temporaries, more indentation.
> >> > So, as I view it, instead of the checks being done cheaply (yes, I think
> >> > the gimple checking as we have right now is very cheap) under the
> >> > hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
> >> > put the burden on the developers, who has to check that manually through
> >> > the as_a/is_a stuff everywhere, more typing and uglier syntax.
> >> > I just don't see that as a step forward, instead a huge step backwards.
> >> > But perhaps I'm alone with this.
> >> > Can you e.g. compare the size of - lines in your patchset combined, and
> >> > size of + lines in your patchset?  As in, if your changes lead to less
> >> > typing or more.
> >>
> >> I see two ways out here.  One is to add overloads to all the functions
> >> taking the special types like
> >>
> >> tree
> >> gimple_assign_rhs1 (gimple *);
> >>
> >> or simply add
> >>
> >> gassign *operator ()(gimple *g) { return as_a <gassign *> (g); }
> >>
> >> into a gimple-compat.h header which you include in places that
> >> are not converted "nicely".
> >
> > Thanks for the suggestions.
> >
> > Am I missing something, or is the gimple-compat.h idea above not valid C
> > ++?
> >
> > Note that "gimple" is still a typedef to
> >   gimple_statement_base *
> > (as noted before, the gimple -> gimple * change would break everyone
> > else's patches, so we talked about that as a followup patch for early
> > stage3).
> >
> > Given that, if I try to create an "operator ()" outside of a class, I
> > get this error:
> >
> > ‘gassign* operator()(gimple)’ must be a nonstatic member function
> >
> > which is emitted from cp/decl.c's grok_op_properties:
> >       /* An operator function must either be a non-static member function
> >          or have at least one parameter of a class, a reference to a class,
> >          an enumeration, or a reference to an enumeration.  13.4.0.6 */
> >
> > I tried making it a member function of gimple_statement_base, but that
> > doesn't work either: we want a conversion
> >   from a gimple_statement_base * to a gassign *, not
> >   from a gimple_statement_base   to a gassign *.
> >
> > Is there some syntactic trick here that I'm missing?  Sorry if I'm being
> > dumb (I can imagine there's a way of doing it by making "gimple" become
> > some kind of wrapped ptr class, but that way lies madness, surely).
> 
> Hmm.
> 
> struct assign;
> struct base {
>   operator assign *() const { return (assign *)this; }
> };
> struct assign : base {
> };
> 
> void foo (assign *);
> void bar (base *b)
> {
>   foo (b);
> }
> 
> doesn't work, but
> 
> void bar (base &b)
> {
>   foo (b);
> }
> 
> does.  Indeed C++ doesn't seem to provide what is necessary
> for the compat trick :(
> 
> So the gimple-compat.h header would need to provide
> additional overloads for the affected functions like
> 
> inline tree
> gimple_assign_rhs1 (gimple *g)
> {
>   return gimple_assign_rhs1 (as_a <gassign *> (g));
> }
> 
> that would work for me as well.
> 
> >> Both avoid manually making the compiler happy (which the
> >> explicit as_a<> stuff is!  It doesn't add any "checking" - it's
> >> just placing the as_a<> at the callers and thus make the
> >> runtine ICE fire there).
> >>
> >> As much as I don't like "global" conversion operators I don't
> >> like adding overloads to all of the accessor functions even more.
> >
> > (nods)
> >
> > Some other options:
> >
> > Option 3: only convert the "easy" accessors: the ones I already did in
> > the /89 patch kit, as reviewed by Jeff, and rebased by me recently,
> > which is this 92-patch kit:
> >   "[gimple-classes, committed 00/92] Initial slew of commits":
> >      https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html
> > Doing so converts about half of the gimple_foo_ accessors to taking a
> > gfoo *, giving a mixture of GIMPLE_CHECK vs subclass use.   I believe
> > the quality of those patches was higher than the later ones on the
> > branch: I was doing the places that didn't require the invasive/verbose
> > changes seen in the later patches.  Shelve the remaining ~80
> > increasingly ugly patches, starting a new branch to contain just the
> > good ones.
> >
> >
> > Option 4: don't convert any accessors, but instead focus on fields of
> > structs (e.g. "call_stmt" within a cgraph_edge), and on params of other
> > functions (e.g. phi-manipulation code).  That way we'd avoid the
> > inconsistency of some accessors using GIMPLE_CHECK and some using
> > subclasses - all would continue to consistently use GIMPLE_CHECK, but
> > there would be some extra type-checking and self-documentation of the
> > expected statement kinds in the code.
> >
> >
> >
> > FWIW, option 3 is my preferred approach (I've already done the bulk of
> > the work and it's already been reviewed; it would need an update merger
> > from trunk, and there's the big gimple to gimple * fixup you wanted).
> 
> Works for me as well.  The compat solution looks somewhat appealing
> as we can then incrementally fix up things rather than requiring to
> mass-convert everything.
> 
> Thanks,
> Richard.

I still prefer option 3 above (i.e. go with the patches Jeff reviewed,
with the fixups discussed earlier, with a merger from trunk), but I had
a go at implementing your gimple-compat.h idea.

Attached is a patch against e74b2ecd78d21fc7bcc2f50dacc92819e0e69e6b on
the gimple-classes branch (the last commit before I went overboard with
the as_a changes), which converts the remaining gimple_assign_ accessors
to take a gassign *, adding a gimple-compat.h to provide overloaded
accessors taking just a gimple for those source files that needed them.
It also strengthens some places I spotted where converting params,
locals or fields from gimple to gassign * was simple and obvious.

Successfully bootstrapped&regrtested on x86_64-unknown-linux-gnu,
comparing the branch+patch against master r216746 (2014-10-27).

This only covers gimple_assign_; it would still be a hybrid of is-a and
GIMPLE_CHECK unless I extended the patch to cover all the other
accessors.

Do you want me to continue converting things for gimple-compat.h to see
what a set of patches for that approach looks like?

If so, would it be better to split things out and have a
gimple-compat-assign.h, gimple-compat-call.h etc rather than one big
gimple-compat.h?

That said, I still prefer option 3.


> >> Whether you enable them generally or just for selected files
> >> via a gimple-compat.h will be up to you (but I'd rather get
> >> rid of them at some point).
> >>
> >> Note this allows seamless transform of "random" functions
> >> taking a gimple now but really only expecting a single kind.
> >>
> >> Note that we don't absolutely have to rush this all in for GCC 5.
> >> Being the very first for GCC 6 stage1 is another possibility.
> >> We just should get it right.
> >
> > Thanks
> > Dave
> >


[-- Attachment #2: 0001-Add-gimple-compat.h-and-port-remaining-gimple_assign.patch --]
[-- Type: text/x-patch, Size: 64151 bytes --]

From 225ca0e9a4c37f4b0d259de2325a474c905bffd9 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 13 Nov 2014 15:46:41 -0500
Subject: [PATCH] Add gimple-compat.h and port remaining gimple_assign
 accessors

gcc/ChangeLog.gimple-classes:
	* gimple-compat.h: New file.
	* gimple.h (is_a_helper <const gassign *>::test): New.
	(gimple_assign_rhs_could_trap_p): Strengthen param "s" from gimple
	to gassign *s.
	(gimple_assign_set_lhs): Likewise for param "gs".
	(gimple_assign_set_rhs1): Likewise.
	(gimple_assign_set_rhs2): Likewise.
	(gimple_assign_set_rhs3): Likewise.
	(gimple_assign_set_nontemporal_move): Likewise.
	(gimple_assign_set_rhs_code): Likewise for param "s".
	(gimple_assign_lhs): Strengthen param "gs" from const_gimple to
	const gassign *.
	(gimple_assign_lhs_ptr): Likewise.
	(gimple_assign_rhs1): Likewise.
	(gimple_assign_rhs1_ptr): Likewise.
	(gimple_assign_rhs2): Likewise.
	(gimple_assign_rhs2_ptr): Likewise.
	(gimple_assign_rhs3): Likewise.
	(gimple_assign_rhs3_ptr): Likewise.
	(gimple_assign_rhs_code): Likewise.
	(gimple_assign_rhs_class): Likewise.
	(gimple_assign_single_p): Make typesafe.
	(gimple_assign_load_p): Likewise.
	(gimple_assign_cast_p): Likewise.
	(gimple_clobber_p): Likewise.
	(gimple_expr_type): Likewise, by introducing a const gassign *
	"assign" within the GIMPLE_ASSIGN "else" clause.  Replace a
	gimple_get_lhs call with a gimple_assign_lhs.

	* asan.c: Include gimple-compat.h.
	(build_shadow_mem_access): Strengthen local "g" from gimple to
	gassign *.
	(maybe_create_ssa_name): Likewise.
	(maybe_cast_to_ptrmode): Likewise.
	(instrument_strlen_call): Likewise.
	(maybe_instrument_assignment): Likewise for local "s".
	* auto-profile.c: Include gimple-compat.h.
	* cfgexpand.c: Likewise.
	* expr.c: Likewise.
	* gimple-builder.c: Likewise.
	* gimple-fold.c: Likewise.
	* gimple-match-head.c: Likewise.
	* gimple-ssa-isolate-paths.c: Likewise.
	* gimple-ssa-strength-reduction.c: Likewise.
	* gimple-walk.c: Likewise.  Remove redundant second include of
	gimple-walk.h.
	* gimple.c: Include gimple-compat.h.
	(gimple_assign_rhs_could_trap_p): Strengthen param "s" from gimple
	to gassign *s.
	* gimplify-me.c: Include gimple-compat.h.
	* graphite-sese-to-poly.c: Likewise.
	* ipa-icf-gimple.c: Likewise.
	* ipa-inline-analysis.c: Likewise.
	* ipa-polymorphic-call.c: Likewise.
	* ipa-prop.c: Likewise.
	* ipa-split.c: Likewise.
	* omp-low.c: Likewise.
	* predict.c: Likewise.
	* sese.c: Likewise.
	* trans-mem.c: Likewise.
	(tm_log_emit_saves): Strengthen local "stmt" from gimple to
	gassign *.
	* tree-affine.c: Include gimple-compat.h.
	* tree-call-cdce.c: Likewise.
	* tree-complex.c: Likewise.
	* tree-data-ref.c: Likewise.
	* tree-eh.c: Likewise.
	* tree-emutls.c (lower_emutls_1): Strengthen local "x" from gimple
	to gassign *.
	* tree-if-conv.c: Include gimple-compat.h.
	* tree-inline.c: Likewise.
	* tree-into-ssa.c: Likewise.
	* tree-loop-distribution.c: Likewise.
	* tree-nested.c: Likewise.
	* tree-nrv.c: Likewise.
	* tree-object-size.c: Likewise.
	* tree-outof-ssa.c: Likewise.
	* tree-parloops.c: Likewise.
	* tree-predcom.c: Likewise.
	* tree-scalar-evolution.c: Likewise.
	(follow_ssa_edge_in_rhs): Strengthen param "stmt" from gimple to
	gassign *.
	(follow_ssa_edge): Add a checked cast to gassign * within
	case GIMPLE_ASSIGN.
	* tree-sra.c: Include gimple-compat.h.
	* tree-ssa-alias.c: Likewise.
	* tree-ssa-ccp.c: Likewise.
	* tree-ssa-coalesce.c: Likewise.
	* tree-ssa-copy.c: Likewise.
	* tree-ssa-copyrename.c: Likewise.
	* tree-ssa-dce.c: Likewise.
	* tree-ssa-dom.c: Likewise.
	* tree-ssa-dse.c: Likewise.
	* tree-ssa-forwprop.c: Likewise.
	* tree-ssa-ifcombine.c: Likewise.
	* tree-ssa-live.c: Likewise.
	* tree-ssa-loop-ch.c: Likewise.
	* tree-ssa-loop-im.c: Likewise.
	* tree-ssa-loop-ivcanon.c: Likewise.
	* tree-ssa-loop-ivopts.c: Likewise.
	* tree-ssa-loop-niter.c: Likewise.
	* tree-ssa-loop-prefetch.c: Likewise.
	* tree-ssa-math-opts.c: Likewise.
	* tree-ssa-phiopt.c: Likewise.
	* tree-ssa-phiprop.c: Likewise.
	* tree-ssa-pre.c: Likewise.
	* tree-ssa-propagate.c: Likewise.
	* tree-ssa-reassoc.c: Likewise.
	* tree-ssa-sccvn.c: Likewise.
	* tree-ssa-sink.c: Likewise.
	* tree-ssa-strlen.c: Likewise.
	* tree-ssa-structalias.c: Likewise.
	* tree-ssa-tail-merge.c: Likewise.
	* tree-ssa-ter.c: Likewise.
	* tree-ssa-threadedge.c: Likewise.
	* tree-ssa-uninit.c: Likewise.
	* tree-ssa.c: Likewise.
	* tree-stdarg.c: Likewise.
	* tree-switch-conversion.c (struct switch_conv_info): Strengthen
	fields "arr_ref_first" and "arr_ref_last" from gimple to
	gassign *.
	(build_one_array): Likewise for local "load".
	(build_arrays): Likewise for local "stmt".
	* tree-vect-data-refs.c: Include gimple-compat.h.
	* tree-vect-generic.c: Likewise.
	* tree-vect-loop.c: Likewise.
	* tree-vect-patterns.c: Likewise.
	* tree-vect-slp.c: Likewise.
	* tree-vect-stmts.c: Likewise.
	(vect_init_vector): Strengthen local "init_stmt" from gimple to
	gassign *.
	* tree-vrp.c: Include gimple-compat.h.
	* tsan.c: Likewise.
	* ubsan.c: Likewise.
	* value-prof.c: Likewise.
	* vtable-verify.c: Likewise.
---
 gcc/ChangeLog.gimple-classes        | 139 ++++++++++++++++++++++++++++++++++++
 gcc/asan.c                          |  11 +--
 gcc/auto-profile.c                  |   1 +
 gcc/cfgexpand.c                     |   1 +
 gcc/expr.c                          |   1 +
 gcc/gimple-builder.c                |   1 +
 gcc/gimple-compat.h                 | 123 +++++++++++++++++++++++++++++++
 gcc/gimple-fold.c                   |   1 +
 gcc/gimple-match-head.c             |   1 +
 gcc/gimple-ssa-isolate-paths.c      |   1 +
 gcc/gimple-ssa-strength-reduction.c |   1 +
 gcc/gimple-walk.c                   |   2 +-
 gcc/gimple.c                        |   4 +-
 gcc/gimple.h                        |  98 ++++++++++++-------------
 gcc/gimplify-me.c                   |   1 +
 gcc/graphite-sese-to-poly.c         |   1 +
 gcc/ipa-icf-gimple.c                |   1 +
 gcc/ipa-inline-analysis.c           |   1 +
 gcc/ipa-polymorphic-call.c          |   1 +
 gcc/ipa-prop.c                      |   1 +
 gcc/ipa-split.c                     |   1 +
 gcc/omp-low.c                       |   1 +
 gcc/predict.c                       |   1 +
 gcc/sese.c                          |   1 +
 gcc/trans-mem.c                     |   3 +-
 gcc/tree-affine.c                   |   1 +
 gcc/tree-call-cdce.c                |   2 +
 gcc/tree-complex.c                  |   1 +
 gcc/tree-data-ref.c                 |   1 +
 gcc/tree-eh.c                       |   1 +
 gcc/tree-emutls.c                   |   2 +-
 gcc/tree-if-conv.c                  |   1 +
 gcc/tree-inline.c                   |   1 +
 gcc/tree-into-ssa.c                 |   1 +
 gcc/tree-loop-distribution.c        |   1 +
 gcc/tree-nested.c                   |   1 +
 gcc/tree-nrv.c                      |   1 +
 gcc/tree-object-size.c              |   1 +
 gcc/tree-outof-ssa.c                |   1 +
 gcc/tree-parloops.c                 |   1 +
 gcc/tree-predcom.c                  |   1 +
 gcc/tree-scalar-evolution.c         |   5 +-
 gcc/tree-sra.c                      |   1 +
 gcc/tree-ssa-alias.c                |   1 +
 gcc/tree-ssa-ccp.c                  |   1 +
 gcc/tree-ssa-coalesce.c             |   1 +
 gcc/tree-ssa-copy.c                 |   1 +
 gcc/tree-ssa-copyrename.c           |   1 +
 gcc/tree-ssa-dce.c                  |   1 +
 gcc/tree-ssa-dom.c                  |   1 +
 gcc/tree-ssa-dse.c                  |   1 +
 gcc/tree-ssa-forwprop.c             |   1 +
 gcc/tree-ssa-ifcombine.c            |   1 +
 gcc/tree-ssa-live.c                 |   1 +
 gcc/tree-ssa-loop-ch.c              |   1 +
 gcc/tree-ssa-loop-im.c              |   1 +
 gcc/tree-ssa-loop-ivcanon.c         |   1 +
 gcc/tree-ssa-loop-ivopts.c          |   1 +
 gcc/tree-ssa-loop-niter.c           |   1 +
 gcc/tree-ssa-loop-prefetch.c        |   1 +
 gcc/tree-ssa-math-opts.c            |   1 +
 gcc/tree-ssa-phiopt.c               |   1 +
 gcc/tree-ssa-phiprop.c              |   1 +
 gcc/tree-ssa-pre.c                  |   1 +
 gcc/tree-ssa-propagate.c            |   1 +
 gcc/tree-ssa-reassoc.c              |   1 +
 gcc/tree-ssa-sccvn.c                |   1 +
 gcc/tree-ssa-sink.c                 |   1 +
 gcc/tree-ssa-strlen.c               |   1 +
 gcc/tree-ssa-structalias.c          |   1 +
 gcc/tree-ssa-tail-merge.c           |   1 +
 gcc/tree-ssa-ter.c                  |   1 +
 gcc/tree-ssa-threadedge.c           |   1 +
 gcc/tree-ssa-uninit.c               |   1 +
 gcc/tree-ssa.c                      |   1 +
 gcc/tree-stdarg.c                   |   1 +
 gcc/tree-switch-conversion.c        |   8 +--
 gcc/tree-vect-data-refs.c           |   1 +
 gcc/tree-vect-generic.c             |   1 +
 gcc/tree-vect-loop.c                |   1 +
 gcc/tree-vect-patterns.c            |   1 +
 gcc/tree-vect-slp.c                 |   1 +
 gcc/tree-vect-stmts.c               |   3 +-
 gcc/tree-vrp.c                      |   1 +
 gcc/tsan.c                          |   1 +
 gcc/ubsan.c                         |   1 +
 gcc/value-prof.c                    |   1 +
 gcc/vtable-verify.c                 |   1 +
 88 files changed, 406 insertions(+), 70 deletions(-)
 create mode 100644 gcc/gimple-compat.h

diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
index 133965c..e78b4b0 100644
--- a/gcc/ChangeLog.gimple-classes
+++ b/gcc/ChangeLog.gimple-classes
@@ -1,3 +1,142 @@
+2014-11-13  David Malcolm  <dmalcolm@redhat.com>
+
+	* gimple-compat.h: New file.
+	* gimple.h (is_a_helper <const gassign *>::test): New.
+	(gimple_assign_rhs_could_trap_p): Strengthen param "s" from gimple
+	to gassign *s.
+	(gimple_assign_set_lhs): Likewise for param "gs".
+	(gimple_assign_set_rhs1): Likewise.
+	(gimple_assign_set_rhs2): Likewise.
+	(gimple_assign_set_rhs3): Likewise.
+	(gimple_assign_set_nontemporal_move): Likewise.
+	(gimple_assign_set_rhs_code): Likewise for param "s".
+	(gimple_assign_lhs): Strengthen param "gs" from const_gimple to
+	const gassign *.
+	(gimple_assign_lhs_ptr): Likewise.
+	(gimple_assign_rhs1): Likewise.
+	(gimple_assign_rhs1_ptr): Likewise.
+	(gimple_assign_rhs2): Likewise.
+	(gimple_assign_rhs2_ptr): Likewise.
+	(gimple_assign_rhs3): Likewise.
+	(gimple_assign_rhs3_ptr): Likewise.
+	(gimple_assign_rhs_code): Likewise.
+	(gimple_assign_rhs_class): Likewise.
+	(gimple_assign_single_p): Make typesafe.
+	(gimple_assign_load_p): Likewise.
+	(gimple_assign_cast_p): Likewise.
+	(gimple_clobber_p): Likewise.
+	(gimple_expr_type): Likewise, by introducing a const gassign *
+	"assign" within the GIMPLE_ASSIGN "else" clause.  Replace a
+	gimple_get_lhs call with a gimple_assign_lhs.
+
+	* asan.c: Include gimple-compat.h.
+	(build_shadow_mem_access): Strengthen local "g" from gimple to
+	gassign *.
+	(maybe_create_ssa_name): Likewise.
+	(maybe_cast_to_ptrmode): Likewise.
+	(instrument_strlen_call): Likewise.
+	(maybe_instrument_assignment): Likewise for local "s".
+	* auto-profile.c: Include gimple-compat.h.
+	* cfgexpand.c: Likewise.
+	* expr.c: Likewise.
+	* gimple-builder.c: Likewise.
+	* gimple-fold.c: Likewise.
+	* gimple-match-head.c: Likewise.
+	* gimple-ssa-isolate-paths.c: Likewise.
+	* gimple-ssa-strength-reduction.c: Likewise.
+	* gimple-walk.c: Likewise.  Remove redundant second include of
+	gimple-walk.h.
+	* gimple.c: Include gimple-compat.h.
+	(gimple_assign_rhs_could_trap_p): Strengthen param "s" from gimple
+	to gassign *s.
+	* gimplify-me.c: Include gimple-compat.h.
+	* graphite-sese-to-poly.c: Likewise.
+	* ipa-icf-gimple.c: Likewise.
+	* ipa-inline-analysis.c: Likewise.
+	* ipa-polymorphic-call.c: Likewise.
+	* ipa-prop.c: Likewise.
+	* ipa-split.c: Likewise.
+	* omp-low.c: Likewise.
+	* predict.c: Likewise.
+	* sese.c: Likewise.
+	* trans-mem.c: Likewise.
+	(tm_log_emit_saves): Strengthen local "stmt" from gimple to
+	gassign *.
+	* tree-affine.c: Include gimple-compat.h.
+	* tree-call-cdce.c: Likewise.
+	* tree-complex.c: Likewise.
+	* tree-data-ref.c: Likewise.
+	* tree-eh.c: Likewise.
+	* tree-emutls.c (lower_emutls_1): Strengthen local "x" from gimple
+	to gassign *.
+	* tree-if-conv.c: Include gimple-compat.h.
+	* tree-inline.c: Likewise.
+	* tree-into-ssa.c: Likewise.
+	* tree-loop-distribution.c: Likewise.
+	* tree-nested.c: Likewise.
+	* tree-nrv.c: Likewise.
+	* tree-object-size.c: Likewise.
+	* tree-outof-ssa.c: Likewise.
+	* tree-parloops.c: Likewise.
+	* tree-predcom.c: Likewise.
+	* tree-scalar-evolution.c: Likewise.
+	(follow_ssa_edge_in_rhs): Strengthen param "stmt" from gimple to
+	gassign *.
+	(follow_ssa_edge): Add a checked cast to gassign * within
+	case GIMPLE_ASSIGN.
+	* tree-sra.c: Include gimple-compat.h.
+	* tree-ssa-alias.c: Likewise.
+	* tree-ssa-ccp.c: Likewise.
+	* tree-ssa-coalesce.c: Likewise.
+	* tree-ssa-copy.c: Likewise.
+	* tree-ssa-copyrename.c: Likewise.
+	* tree-ssa-dce.c: Likewise.
+	* tree-ssa-dom.c: Likewise.
+	* tree-ssa-dse.c: Likewise.
+	* tree-ssa-forwprop.c: Likewise.
+	* tree-ssa-ifcombine.c: Likewise.
+	* tree-ssa-live.c: Likewise.
+	* tree-ssa-loop-ch.c: Likewise.
+	* tree-ssa-loop-im.c: Likewise.
+	* tree-ssa-loop-ivcanon.c: Likewise.
+	* tree-ssa-loop-ivopts.c: Likewise.
+	* tree-ssa-loop-niter.c: Likewise.
+	* tree-ssa-loop-prefetch.c: Likewise.
+	* tree-ssa-math-opts.c: Likewise.
+	* tree-ssa-phiopt.c: Likewise.
+	* tree-ssa-phiprop.c: Likewise.
+	* tree-ssa-pre.c: Likewise.
+	* tree-ssa-propagate.c: Likewise.
+	* tree-ssa-reassoc.c: Likewise.
+	* tree-ssa-sccvn.c: Likewise.
+	* tree-ssa-sink.c: Likewise.
+	* tree-ssa-strlen.c: Likewise.
+	* tree-ssa-structalias.c: Likewise.
+	* tree-ssa-tail-merge.c: Likewise.
+	* tree-ssa-ter.c: Likewise.
+	* tree-ssa-threadedge.c: Likewise.
+	* tree-ssa-uninit.c: Likewise.
+	* tree-ssa.c: Likewise.
+	* tree-stdarg.c: Likewise.
+	* tree-switch-conversion.c (struct switch_conv_info): Strengthen
+	fields "arr_ref_first" and "arr_ref_last" from gimple to
+	gassign *.
+	(build_one_array): Likewise for local "load".
+	(build_arrays): Likewise for local "stmt".
+	* tree-vect-data-refs.c: Include gimple-compat.h.
+	* tree-vect-generic.c: Likewise.
+	* tree-vect-loop.c: Likewise.
+	* tree-vect-patterns.c: Likewise.
+	* tree-vect-slp.c: Likewise.
+	* tree-vect-stmts.c: Likewise.
+	(vect_init_vector): Strengthen local "init_stmt" from gimple to
+	gassign *.
+	* tree-vrp.c: Include gimple-compat.h.
+	* tsan.c: Likewise.
+	* ubsan.c: Likewise.
+	* value-prof.c: Likewise.
+	* vtable-verify.c: Likewise.
+
 2014-10-28  David Malcolm  <dmalcolm@redhat.com>
 
 	* auto-profile.c (autofdo::function_instance::find_icall_target_map):
diff --git a/gcc/asan.c b/gcc/asan.c
index 9a310b4..cb8d5d0 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -67,6 +67,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ubsan.h"
 #include "params.h"
 #include "builtins.h"
+#include "gimple-compat.h"
 
 /* AddressSanitizer finds out-of-bounds and use-after-free bugs
    with <2x slowdown on average.
@@ -1523,7 +1524,7 @@ build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
 {
   tree t, uintptr_type = TREE_TYPE (base_addr);
   tree shadow_type = TREE_TYPE (shadow_ptr_type);
-  gimple g;
+  gassign *g;
 
   t = build_int_cst (uintptr_type, ASAN_SHADOW_SHIFT);
   g = gimple_build_assign_with_ops (RSHIFT_EXPR,
@@ -1564,7 +1565,7 @@ maybe_create_ssa_name (location_t loc, tree base, gimple_stmt_iterator *iter,
 {
   if (TREE_CODE (base) == SSA_NAME)
     return base;
-  gimple g
+  gassign *g
     = gimple_build_assign_with_ops (TREE_CODE (base),
 				    make_ssa_name (TREE_TYPE (base), NULL),
 				    base, NULL_TREE);
@@ -1585,7 +1586,7 @@ maybe_cast_to_ptrmode (location_t loc, tree len, gimple_stmt_iterator *iter,
 {
   if (ptrofftype_p (len))
     return len;
-  gimple g
+  gassign *g
     = gimple_build_assign_with_ops (NOP_EXPR,
 				    make_ssa_name (pointer_sized_int_node, NULL),
 				    len, NULL);
@@ -1854,7 +1855,7 @@ instrument_mem_region_access (tree base, tree len,
 static bool
 instrument_strlen_call (gimple_stmt_iterator *iter)
 {
-  gimple g;
+  gassign *g;
   gcall *call = as_a <gcall *> (gsi_stmt (*iter));
   gcc_assert (is_gimple_call (call));
 
@@ -1980,7 +1981,7 @@ instrument_builtin_call (gimple_stmt_iterator *iter)
 static bool
 maybe_instrument_assignment (gimple_stmt_iterator *iter)
 {
-  gimple s = gsi_stmt (*iter);
+  gassign *s = as_a <gassign *> (gsi_stmt (*iter));
 
   gcc_assert (gimple_assign_single_p (s));
 
diff --git a/gcc/auto-profile.c b/gcc/auto-profile.c
index ba4e567..3dfe831 100644
--- a/gcc/auto-profile.c
+++ b/gcc/auto-profile.c
@@ -67,6 +67,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-inline.h"
 #include "stringpool.h"
 #include "auto-profile.h"
+#include "gimple-compat.h"
 
 /* The following routines implements AutoFDO optimization.
 
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index a2cb483..eed4354 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -85,6 +85,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "recog.h"
 #include "output.h"
 #include "builtins.h"
+#include "gimple-compat.h"
 
 /* Some systems use __main in a way incompatible with its use in gcc, in these
    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
diff --git a/gcc/expr.c b/gcc/expr.c
index a5bf13a..7929725 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -75,6 +75,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-address.h"
 #include "cfgexpand.h"
 #include "builtins.h"
+#include "gimple-compat.h"
 
 #ifndef STACK_PUSH_CODE
 #ifdef STACK_GROWS_DOWNWARD
diff --git a/gcc/gimple-builder.c b/gcc/gimple-builder.c
index a7c6c4e..aad2ce9 100644
--- a/gcc/gimple-builder.c
+++ b/gcc/gimple-builder.c
@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "is-a.h"
 #include "gimple.h"
 #include "tree-ssanames.h"
+#include "gimple-compat.h"
 
 
 /* Return the expression type to use based on the CODE and type of
diff --git a/gcc/gimple-compat.h b/gcc/gimple-compat.h
new file mode 100644
index 0000000..cbc37a0
--- /dev/null
+++ b/gcc/gimple-compat.h
@@ -0,0 +1,123 @@
+/* Compatibility for source files using gimple accessors with base class.
+
+   Copyright (C) 2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_GIMPLE_COMPAT_H
+#define GCC_GIMPLE_COMPAT_H
+
+/* Compatibility implementations of various gimple_assign_ accessors,
+   taking a gimple/const_gimple rather than a gassign *.  */
+
+static inline tree
+gimple_assign_lhs (const_gimple gs)
+{
+  return gimple_assign_lhs (as_a <const gassign *> (gs));
+}
+
+static inline tree *
+gimple_assign_lhs_ptr (const_gimple gs)
+{
+  return gimple_assign_lhs_ptr (as_a <const gassign *> (gs));
+}
+
+static inline void
+gimple_assign_set_lhs (gimple gs, tree lhs)
+{
+  gimple_assign_set_lhs (as_a <gassign *> (gs), lhs);
+}
+
+static inline enum gimple_rhs_class
+gimple_assign_rhs_class (const_gimple gs)
+{
+  return gimple_assign_rhs_class (as_a <const gassign *> (gs));
+}
+
+static inline tree
+gimple_assign_rhs1 (const_gimple gs)
+{
+  return gimple_assign_rhs1 (as_a <const gassign *> (gs));
+}
+
+static inline tree *
+gimple_assign_rhs1_ptr (const_gimple gs)
+{
+  return gimple_assign_rhs1_ptr (as_a <const gassign *> (gs));
+}
+
+static inline void
+gimple_assign_set_rhs1 (gimple gs, tree rhs)
+{
+  gimple_assign_set_rhs1 (as_a <gassign *> (gs), rhs);
+}
+
+static inline tree
+gimple_assign_rhs2 (const_gimple gs)
+{
+  return gimple_assign_rhs2 (as_a <const gassign *> (gs));
+}
+
+static inline tree *
+gimple_assign_rhs2_ptr (const_gimple gs)
+{
+  return gimple_assign_rhs2_ptr (as_a <const gassign *> (gs));
+}
+
+static inline void
+gimple_assign_set_rhs2 (gimple gs, tree rhs)
+{
+  gimple_assign_set_rhs2 (as_a <gassign *> (gs), rhs);
+}
+
+static inline tree
+gimple_assign_rhs3 (const_gimple gs)
+{
+  return gimple_assign_rhs3 (as_a <const gassign *> (gs));
+}
+
+static inline void
+gimple_assign_set_rhs3 (gimple gs, tree rhs)
+{
+  gimple_assign_set_rhs3 (as_a <gassign *> (gs), rhs);
+}
+
+static inline void
+gimple_assign_set_nontemporal_move (gimple gs, bool nontemporal)
+{
+  gimple_assign_set_nontemporal_move (as_a <gassign *> (gs), nontemporal);
+}
+
+static inline enum tree_code
+gimple_assign_rhs_code (const_gimple gs)
+{
+  return gimple_assign_rhs_code (as_a <const gassign *> (gs));
+}
+
+static inline void
+gimple_assign_set_rhs_code (gimple s, enum tree_code code)
+{
+  gimple_assign_set_rhs_code (as_a <gassign *> (s), code);
+}
+
+static inline bool
+gimple_assign_rhs_could_trap_p (gimple gs)
+{
+  return gimple_assign_rhs_could_trap_p (as_a <gassign *> (gs));
+}
+
+#endif  /* GCC_GIMPLE_COMPAT_H */
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 4b45648..9fe6b3a 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -65,6 +65,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "output.h"
 #include "tree-eh.h"
 #include "gimple-match.h"
+#include "gimple-compat.h"
 
 /* Return true when DECL can be referenced from current unit.
    FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
diff --git a/gcc/gimple-match-head.c b/gcc/gimple-match-head.c
index 9c6da59..12caa7e 100644
--- a/gcc/gimple-match-head.c
+++ b/gcc/gimple-match-head.c
@@ -50,6 +50,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ssa-iterators.h"
 #include "dumpfile.h"
 #include "gimple-match.h"
+#include "gimple-compat.h"
 
 
 /* Forward declarations of the private auto-generated matchers.
diff --git a/gcc/gimple-ssa-isolate-paths.c b/gcc/gimple-ssa-isolate-paths.c
index ea8ead0..04d7eca 100644
--- a/gcc/gimple-ssa-isolate-paths.c
+++ b/gcc/gimple-ssa-isolate-paths.c
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-cfg.h"
 #include "diagnostic-core.h"
 #include "intl.h"
+#include "gimple-compat.h"
 
 
 static bool cfg_altered;
diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
index 0831f92..bb6e7eb 100644
--- a/gcc/gimple-ssa-strength-reduction.c
+++ b/gcc/gimple-ssa-strength-reduction.c
@@ -76,6 +76,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-affine.h"
 #include "wide-int-print.h"
 #include "builtins.h"
+#include "gimple-compat.h"
 \f
 /* Information about a strength reduction candidate.  Each statement
    in the candidate table represents an expression of one of the
diff --git a/gcc/gimple-walk.c b/gcc/gimple-walk.c
index a6ea1ec..5f6abff 100644
--- a/gcc/gimple-walk.c
+++ b/gcc/gimple-walk.c
@@ -41,8 +41,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple.h"
 #include "gimple-iterator.h"
 #include "gimple-walk.h"
-#include "gimple-walk.h"
 #include "demangle.h"
+#include "gimple-compat.h"
 
 /* Walk all the statements in the sequence *PSEQ calling walk_gimple_stmt
    on each one.  WI is as in walk_gimple_stmt.
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 061a7a1..eb7f474 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "bitmap.h"
 #include "stringpool.h"
 #include "tree-ssanames.h"
+#include "gimple-compat.h"
 
 
 /* All the tuples have their operand vector (if present) at the very bottom
@@ -1947,9 +1948,8 @@ gimple_could_trap_p (gimple s)
 /* Return true if RHS of a GIMPLE_ASSIGN S can trap.  */
 
 bool
-gimple_assign_rhs_could_trap_p (gimple s)
+gimple_assign_rhs_could_trap_p (gassign *s)
 {
-  gcc_assert (is_gimple_assign (s));
   return gimple_could_trap_p_1 (s, true, false);
 }
 
diff --git a/gcc/gimple.h b/gcc/gimple.h
index ccafde5..d87709f 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1110,6 +1110,14 @@ is_a_helper <const gasm *>::test (const_gimple gs)
 template <>
 template <>
 inline bool
+is_a_helper <const gassign *>::test (const_gimple gs)
+{
+  return gs->code == GIMPLE_ASSIGN;
+}
+
+template <>
+template <>
+inline bool
 is_a_helper <const gbind *>::test (const_gimple gs)
 {
   return gs->code == GIMPLE_BIND;
@@ -1376,7 +1384,7 @@ gimple gimple_copy (gimple);
 bool gimple_has_side_effects (const_gimple);
 bool gimple_could_trap_p_1 (gimple, bool, bool);
 bool gimple_could_trap_p (gimple);
-bool gimple_assign_rhs_could_trap_p (gimple);
+bool gimple_assign_rhs_could_trap_p (gassign *);
 extern void dump_gimple_statistics (void);
 unsigned get_gimple_rhs_num_ops (enum tree_code);
 extern tree canonicalize_cond_expr_cond (tree);
@@ -2270,9 +2278,8 @@ get_gimple_rhs_class (enum tree_code code)
 /* Return the LHS of assignment statement GS.  */
 
 static inline tree
-gimple_assign_lhs (const_gimple gs)
+gimple_assign_lhs (const gassign *gs)
 {
-  GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
   return gimple_op (gs, 0);
 }
 
@@ -2280,9 +2287,8 @@ gimple_assign_lhs (const_gimple gs)
 /* Return a pointer to the LHS of assignment statement GS.  */
 
 static inline tree *
-gimple_assign_lhs_ptr (const_gimple gs)
+gimple_assign_lhs_ptr (const gassign *gs)
 {
-  GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
   return gimple_op_ptr (gs, 0);
 }
 
@@ -2290,9 +2296,8 @@ gimple_assign_lhs_ptr (const_gimple gs)
 /* Set LHS to be the LHS operand of assignment statement GS.  */
 
 static inline void
-gimple_assign_set_lhs (gimple gs, tree lhs)
+gimple_assign_set_lhs (gassign *gs, tree lhs)
 {
-  GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
   gimple_set_op (gs, 0, lhs);
 
   if (lhs && TREE_CODE (lhs) == SSA_NAME)
@@ -2303,9 +2308,8 @@ gimple_assign_set_lhs (gimple gs, tree lhs)
 /* Return the first operand on the RHS of assignment statement GS.  */
 
 static inline tree
-gimple_assign_rhs1 (const_gimple gs)
+gimple_assign_rhs1 (const gassign *gs)
 {
-  GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
   return gimple_op (gs, 1);
 }
 
@@ -2314,19 +2318,16 @@ gimple_assign_rhs1 (const_gimple gs)
    statement GS.  */
 
 static inline tree *
-gimple_assign_rhs1_ptr (const_gimple gs)
+gimple_assign_rhs1_ptr (const gassign *gs)
 {
-  GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
   return gimple_op_ptr (gs, 1);
 }
 
 /* Set RHS to be the first operand on the RHS of assignment statement GS.  */
 
 static inline void
-gimple_assign_set_rhs1 (gimple gs, tree rhs)
+gimple_assign_set_rhs1 (gassign *gs, tree rhs)
 {
-  GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
-
   gimple_set_op (gs, 1, rhs);
 }
 
@@ -2335,10 +2336,8 @@ gimple_assign_set_rhs1 (gimple gs, tree rhs)
    If GS does not have two operands, NULL is returned instead.  */
 
 static inline tree
-gimple_assign_rhs2 (const_gimple gs)
+gimple_assign_rhs2 (const gassign *gs)
 {
-  GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
-
   if (gimple_num_ops (gs) >= 3)
     return gimple_op (gs, 2);
   else
@@ -2350,9 +2349,8 @@ gimple_assign_rhs2 (const_gimple gs)
    statement GS.  */
 
 static inline tree *
-gimple_assign_rhs2_ptr (const_gimple gs)
+gimple_assign_rhs2_ptr (const gassign *gs)
 {
-  GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
   return gimple_op_ptr (gs, 2);
 }
 
@@ -2360,10 +2358,8 @@ gimple_assign_rhs2_ptr (const_gimple gs)
 /* Set RHS to be the second operand on the RHS of assignment statement GS.  */
 
 static inline void
-gimple_assign_set_rhs2 (gimple gs, tree rhs)
+gimple_assign_set_rhs2 (gassign *gs, tree rhs)
 {
-  GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
-
   gimple_set_op (gs, 2, rhs);
 }
 
@@ -2371,10 +2367,8 @@ gimple_assign_set_rhs2 (gimple gs, tree rhs)
    If GS does not have two operands, NULL is returned instead.  */
 
 static inline tree
-gimple_assign_rhs3 (const_gimple gs)
+gimple_assign_rhs3 (const gassign *gs)
 {
-  GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
-
   if (gimple_num_ops (gs) >= 4)
     return gimple_op (gs, 3);
   else
@@ -2385,9 +2379,8 @@ gimple_assign_rhs3 (const_gimple gs)
    statement GS.  */
 
 static inline tree *
-gimple_assign_rhs3_ptr (const_gimple gs)
+gimple_assign_rhs3_ptr (const gassign *gs)
 {
-  GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
   return gimple_op_ptr (gs, 3);
 }
 
@@ -2395,10 +2388,8 @@ gimple_assign_rhs3_ptr (const_gimple gs)
 /* Set RHS to be the third operand on the RHS of assignment statement GS.  */
 
 static inline void
-gimple_assign_set_rhs3 (gimple gs, tree rhs)
+gimple_assign_set_rhs3 (gassign *gs, tree rhs)
 {
-  GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
-
   gimple_set_op (gs, 3, rhs);
 }
 
@@ -2423,9 +2414,8 @@ gimple_assign_nontemporal_move_p (const gassign *gs)
 /* Sets nontemporal move flag of GS to NONTEMPORAL.  */
 
 static inline void
-gimple_assign_set_nontemporal_move (gimple gs, bool nontemporal)
+gimple_assign_set_nontemporal_move (gassign *gs, bool nontemporal)
 {
-  GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
   gs->nontemporal_move = nontemporal;
 }
 
@@ -2435,10 +2425,9 @@ gimple_assign_set_nontemporal_move (gimple gs, bool nontemporal)
    tree code of the object.  */
 
 static inline enum tree_code
-gimple_assign_rhs_code (const_gimple gs)
+gimple_assign_rhs_code (const gassign *gs)
 {
   enum tree_code code;
-  GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
 
   code = (enum tree_code) gs->subcode;
   /* While we initially set subcode to the TREE_CODE of the rhs for
@@ -2455,9 +2444,8 @@ gimple_assign_rhs_code (const_gimple gs)
    assignment S.  */
 
 static inline void
-gimple_assign_set_rhs_code (gimple s, enum tree_code code)
+gimple_assign_set_rhs_code (gassign *s, enum tree_code code)
 {
-  GIMPLE_CHECK (s, GIMPLE_ASSIGN);
   s->subcode = code;
 }
 
@@ -2467,7 +2455,7 @@ gimple_assign_set_rhs_code (gimple s, enum tree_code code)
    This will never return GIMPLE_INVALID_RHS.  */
 
 static inline enum gimple_rhs_class
-gimple_assign_rhs_class (const_gimple gs)
+gimple_assign_rhs_class (const gassign *gs)
 {
   return get_gimple_rhs_class (gimple_assign_rhs_code (gs));
 }
@@ -2481,8 +2469,9 @@ gimple_assign_rhs_class (const_gimple gs)
 static inline bool
 gimple_assign_single_p (const_gimple gs)
 {
-  return (is_gimple_assign (gs)
-          && gimple_assign_rhs_class (gs) == GIMPLE_SINGLE_RHS);
+  if (const gassign *assign = dyn_cast <const gassign *> (gs))
+    return gimple_assign_rhs_class (assign) == GIMPLE_SINGLE_RHS;
+  return false;
 }
 
 /* Return true if GS performs a store to its lhs.  */
@@ -2502,7 +2491,7 @@ gimple_assign_load_p (const_gimple gs)
   tree rhs;
   if (!gimple_assign_single_p (gs))
     return false;
-  rhs = gimple_assign_rhs1 (gs);
+  rhs = gimple_assign_rhs1 (as_a <const gassign *> (gs));
   if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
     return true;
   rhs = get_base_address (rhs);
@@ -2518,7 +2507,7 @@ gimple_assign_cast_p (const_gimple s)
 {
   if (is_gimple_assign (s))
     {
-      enum tree_code sc = gimple_assign_rhs_code (s);
+      enum tree_code sc = gimple_assign_rhs_code (as_a <const gassign *> (s));
       return CONVERT_EXPR_CODE_P (sc)
 	     || sc == VIEW_CONVERT_EXPR
 	     || sc == FIX_TRUNC_EXPR;
@@ -2533,7 +2522,7 @@ static inline bool
 gimple_clobber_p (const_gimple s)
 {
   return gimple_assign_single_p (s)
-         && TREE_CLOBBER_P (gimple_assign_rhs1 (s));
+    && TREE_CLOBBER_P (gimple_assign_rhs1 (as_a <const gassign *> (s)));
 }
 
 /* Return true if GS is a GIMPLE_CALL.  */
@@ -5626,17 +5615,20 @@ gimple_expr_type (const_gimple stmt)
 	    type = gimple_call_return_type (call_stmt);
 	}
       else
-	switch (gimple_assign_rhs_code (stmt))
-	  {
-	  case POINTER_PLUS_EXPR:
-	    type = TREE_TYPE (gimple_assign_rhs1 (stmt));
-	    break;
-
-	  default:
-	    /* As fallback use the type of the LHS.  */
-	    type = TREE_TYPE (gimple_get_lhs (stmt));
-	    break;
-	  }
+	{
+	  const gassign *assign = as_a <const gassign *> (stmt);
+	  switch (gimple_assign_rhs_code (assign))
+	    {
+	    case POINTER_PLUS_EXPR:
+	      type = TREE_TYPE (gimple_assign_rhs1 (assign));
+	      break;
+
+	    default:
+	      /* As fallback use the type of the LHS.  */
+	      type = TREE_TYPE (gimple_assign_lhs (assign));
+	      break;
+	    }
+	}
       return type;
     }
   else if (code == GIMPLE_COND)
diff --git a/gcc/gimplify-me.c b/gcc/gimplify-me.c
index 9d969de..1009b2f 100644
--- a/gcc/gimplify-me.c
+++ b/gcc/gimplify-me.c
@@ -49,6 +49,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-ssa.h"
 #include "stringpool.h"
 #include "tree-ssanames.h"
+#include "gimple-compat.h"
 
 
 /* Expand EXPR to list of gimple statements STMTS.  GIMPLE_TEST_F specifies
diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c
index 16d1bb6..1c08c3c 100644
--- a/gcc/graphite-sese-to-poly.c
+++ b/gcc/graphite-sese-to-poly.c
@@ -86,6 +86,7 @@ extern "C" {
 #include "domwalk.h"
 #include "sese.h"
 #include "tree-ssa-propagate.h"
+#include "gimple-compat.h"
 
 #ifdef HAVE_isl
 #include "expr.h"
diff --git a/gcc/ipa-icf-gimple.c b/gcc/ipa-icf-gimple.c
index 9ebef25..ddf253a 100644
--- a/gcc/ipa-icf-gimple.c
+++ b/gcc/ipa-icf-gimple.c
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "ipa-icf-gimple.h"
 #include "ipa-icf.h"
+#include "gimple-compat.h"
 
 namespace ipa_icf_gimple {
 
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index aa8a596..642e1b5 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -116,6 +116,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-utils.h"
 #include "cilk.h"
 #include "cfgexpand.h"
+#include "gimple-compat.h"
 
 /* Estimate runtime of function can easilly run into huge numbers with many
    nested loops.  Be sure we can compute time * INLINE_SIZE_SCALE * 2 in an
diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c
index 3f2d303..9a69f7e 100644
--- a/gcc/ipa-polymorphic-call.c
+++ b/gcc/ipa-polymorphic-call.c
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "data-streamer.h"
 #include "lto-streamer.h"
 #include "streamer-hooks.h"
+#include "gimple-compat.h"
 
 /* Return true when TYPE contains an polymorphic type and thus is interesting
    for devirtualization machinery.  */
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 47a8f03..41534a6 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -74,6 +74,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "domwalk.h"
 #include "builtins.h"
 #include "calls.h"
+#include "gimple-compat.h"
 
 /* Intermediate information that we get from alias analysis about a particular
    parameter in a particular basic_block.  When a parameter or the memory it
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 145aceb..1f6c9dc 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -122,6 +122,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-pretty-print.h"
 #include "ipa-inline.h"
 #include "cfgloop.h"
+#include "gimple-compat.h"
 
 /* Per basic block info.  */
 
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index e53f4ff..da6fec3 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -81,6 +81,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-nested.h"
 #include "tree-eh.h"
 #include "cilk.h"
+#include "gimple-compat.h"
 
 
 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
diff --git a/gcc/predict.c b/gcc/predict.c
index 352417a..6674300 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -77,6 +77,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "tree-scalar-evolution.h"
 #include "cfgloop.h"
+#include "gimple-compat.h"
 
 /* real constants: 0, 1, 1-1/REG_BR_PROB_BASE, REG_BR_PROB_BASE,
 		   1/REG_BR_PROB_BASE, 0.5, BB_FREQ_MAX.  */
diff --git a/gcc/sese.c b/gcc/sese.c
index e0869e0..660d6d9 100644
--- a/gcc/sese.c
+++ b/gcc/sese.c
@@ -63,6 +63,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "value-prof.h"
 #include "sese.h"
 #include "tree-ssa-propagate.h"
+#include "gimple-compat.h"
 
 /* Helper function for debug_rename_map.  */
 
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index eb1f5be..d584ed4 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -65,6 +65,7 @@
 #include "gimple-pretty-print.h"
 #include "cfgloop.h"
 #include "tree-ssa-address.h"
+#include "gimple-compat.h"
 
 
 #define A_RUNINSTRUMENTEDCODE	0x0001
@@ -1281,7 +1282,7 @@ tm_log_emit_saves (basic_block entry_block, basic_block bb)
 {
   size_t i;
   gimple_stmt_iterator gsi = gsi_last_bb (bb);
-  gimple stmt;
+  gassign *stmt;
   struct tm_log_entry l, *lp;
 
   for (i = 0; i < tm_log_save_addresses.length (); ++i)
diff --git a/gcc/tree-affine.c b/gcc/tree-affine.c
index 4c61cd0..fda862d 100644
--- a/gcc/tree-affine.c
+++ b/gcc/tree-affine.c
@@ -44,6 +44,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dumpfile.h"
 #include "cfgexpand.h"
 #include "wide-int-print.h"
+#include "gimple-compat.h"
 
 /* Extends CST as appropriate for the affine combinations COMB.  */
 
diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
index 23c2df5..2b98ccd 100644
--- a/gcc/tree-call-cdce.c
+++ b/gcc/tree-call-cdce.c
@@ -49,6 +49,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-into-ssa.h"
 #include "tree-pass.h"
 #include "flags.h"
+#include "gimple-compat.h"
+
 \f
 
 /* Conditional dead call elimination
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index dbc01f4..eb4c85a 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-propagate.h"
 #include "tree-hasher.h"
 #include "cfgloop.h"
+#include "gimple-compat.h"
 
 
 /* For each complex ssa name, a lattice value.  We're interested in finding
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 4a16c3a..c94b2ec 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -107,6 +107,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "tree-affine.h"
 #include "params.h"
+#include "gimple-compat.h"
 
 static struct datadep_stats
 {
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index a27ed35..34da690 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -63,6 +63,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target.h"
 #include "cfgloop.h"
 #include "gimple-low.h"
+#include "gimple-compat.h"
 
 /* In some instances a tree and a gimple need to be stored in a same table,
    i.e. in hash tables. This is a structure to do this. */
diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c
index f456b4b..ec3ea61 100644
--- a/gcc/tree-emutls.c
+++ b/gcc/tree-emutls.c
@@ -489,7 +489,7 @@ lower_emutls_1 (tree *ptr, int *walk_subtrees, void *cb_data)
 	     new assignment statement, and substitute yet another SSA_NAME.  */
 	  if (wi->changed)
 	    {
-	      gimple x;
+	      gassign *x;
 
 	      addr = create_tmp_var (TREE_TYPE (t), NULL);
 	      x = gimple_build_assign (addr, t);
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index f0beb31..0cd73c4 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -126,6 +126,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dbgcnt.h"
 #include "expr.h"
 #include "optabs.h"
+#include "gimple-compat.h"
 
 /* List of basic blocks in if-conversion-suitable order.  */
 static basic_block *ifc_bbs;
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index e005da1..dd46529 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -75,6 +75,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target.h"
 #include "cfgloop.h"
 #include "builtins.h"
+#include "gimple-compat.h"
 
 #include "rtl.h"	/* FIXME: For asm_str_count.  */
 
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index 70b523c..a370f45 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -63,6 +63,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "params.h"
 #include "diagnostic-core.h"
 #include "tree-into-ssa.h"
+#include "gimple-compat.h"
 
 #define PERCENT(x,y) ((float)(x) * 100.0 / (float)(y))
 
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index 31ea04c..94b9d85 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -83,6 +83,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "gimple-pretty-print.h"
 #include "tree-vectorizer.h"
+#include "gimple-compat.h"
 
 
 /* A Reduced Dependence Graph (RDG) vertex representing a statement.  */
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index a254a1c..3fc9271 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -51,6 +51,7 @@
 #include "expr.h"	/* FIXME: For STACK_SAVEAREA_MODE and SAVE_NONLOCAL.  */
 #include "langhooks.h"
 #include "gimple-low.h"
+#include "gimple-compat.h"
 
 
 /* The object of this pass is to lower the representation of a set of nested
diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c
index 182039e..b50619f 100644
--- a/gcc/tree-nrv.c
+++ b/gcc/tree-nrv.c
@@ -49,6 +49,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "flags.h"	/* For "optimize" in gate_pass_return_slot.
 			   FIXME: That should be up to the pass manager,
 			   but pass_nrv is not in pass_all_optimizations.  */
+#include "gimple-compat.h"
 
 /* This file implements return value optimizations for functions which
    return aggregate types.
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
index 20b9956..7dfa176 100644
--- a/gcc/tree-object-size.c
+++ b/gcc/tree-object-size.c
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-phinodes.h"
 #include "ssa-iterators.h"
 #include "builtins.h"
+#include "gimple-compat.h"
 
 struct object_size_info
 {
diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c
index bb57053..798b440 100644
--- a/gcc/tree-outof-ssa.c
+++ b/gcc/tree-outof-ssa.c
@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-ter.h"
 #include "tree-ssa-coalesce.h"
 #include "tree-outof-ssa.h"
+#include "gimple-compat.h"
 
 /* FIXME: A lot of code here deals with expanding to RTL.  All that code
    should be in cfgexpand.c.  */
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index a1e0778..702a6fe 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -68,6 +68,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-parloops.h"
 #include "omp-low.h"
 #include "tree-nested.h"
+#include "gimple-compat.h"
 
 /* This pass tries to distribute iterations of loops into several threads.
    The implementation is straightforward -- for each loop we test whether its
diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index 93a523c..297805b 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -233,6 +233,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-affine.h"
 #include "tree-inline.h"
 #include "wide-int-print.h"
+#include "gimple-compat.h"
 
 /* The maximum number of iterations between the considered memory
    references.  */
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index 38b0767..746cb14 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -298,6 +298,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-propagate.h"
 #include "gimple-fold.h"
 #include "gimplify-me.h"
+#include "gimple-compat.h"
 
 static tree analyze_scalar_evolution_1 (struct loop *, tree, tree);
 static tree analyze_scalar_evolution_for_address_of (struct loop *loop,
@@ -1150,7 +1151,7 @@ follow_ssa_edge_expr (struct loop *loop, gimple at_stmt, tree expr,
    Return true if the strongly connected component has been found.  */
 
 static t_bool
-follow_ssa_edge_in_rhs (struct loop *loop, gimple stmt,
+follow_ssa_edge_in_rhs (struct loop *loop, gassign *stmt,
 			gphi *halting_phi, tree *evolution_of_loop,
 			int limit)
 {
@@ -1388,7 +1389,7 @@ follow_ssa_edge (struct loop *loop, gimple def, gphi *halting_phi,
       return t_false;
 
     case GIMPLE_ASSIGN:
-      return follow_ssa_edge_in_rhs (loop, def, halting_phi,
+      return follow_ssa_edge_in_rhs (loop, as_a <gassign *> (def), halting_phi,
 				     evolution_of_loop, limit);
 
     default:
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 85a9a87..3092125 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -123,6 +123,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-inline.h"
 #include "ipa-utils.h"
 #include "builtins.h"
+#include "gimple-compat.h"
 
 /* Enumeration of all aggregate reductions we can do.  */
 enum sra_mode { SRA_MODE_EARLY_IPA,   /* early call regularization */
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 9b55e0d..eb53fad 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "alloc-pool.h"
 #include "tree-ssa-alias.h"
 #include "ipa-reference.h"
+#include "gimple-compat.h"
 
 /* Broad overview of how alias analysis on gimple works:
 
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index bf7577a..8bb2c53 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -164,6 +164,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "params.h"
 #include "wide-int-print.h"
 #include "builtins.h"
+#include "gimple-compat.h"
 
 
 /* Possible lattice values.  */
diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c
index 7d1825d..b8b0726 100644
--- a/gcc/tree-ssa-coalesce.c
+++ b/gcc/tree-ssa-coalesce.c
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-live.h"
 #include "tree-ssa-coalesce.h"
 #include "diagnostic-core.h"
+#include "gimple-compat.h"
 
 
 /* This set of routines implements a coalesce_list.  This is an object which
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 3833dff..818a100 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-scalar-evolution.h"
 #include "tree-ssa-dom.h"
 #include "tree-ssa-loop-niter.h"
+#include "gimple-compat.h"
 
 
 /* This file implements the copy propagation pass and provides a
diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c
index cd7bac5..231ff3f 100644
--- a/gcc/tree-ssa-copyrename.c
+++ b/gcc/tree-ssa-copyrename.c
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-live.h"
 #include "tree-pass.h"
 #include "langhooks.h"
+#include "gimple-compat.h"
 
 static struct
 {
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index 06ffb24..e5e5475 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -84,6 +84,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "flags.h"
 #include "cfgloop.h"
 #include "tree-scalar-evolution.h"
+#include "gimple-compat.h"
 
 static struct stmt_stats
 {
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 747354b..9278629 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -66,6 +66,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-threadedge.h"
 #include "tree-ssa-dom.h"
 #include "inchash.h"
+#include "gimple-compat.h"
 
 /* This file implements optimizations on the dominator tree.  */
 
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index 91017ff..3093904 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "flags.h"
 #include "langhooks.h"
 #include "tree-cfgcleanup.h"
+#include "gimple-compat.h"
 
 /* This file implements dead store elimination.
 
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 55de465..b16c77a 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -67,6 +67,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-cfgcleanup.h"
 #include "tree-into-ssa.h"
 #include "cfganal.h"
+#include "gimple-compat.h"
 
 /* This pass propagates the RHS of assignment statements into use
    sites of the LHS of the assignment.  It's basically a specialized
diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c
index 9fd7113..764b9d1 100644
--- a/gcc/tree-ssa-ifcombine.c
+++ b/gcc/tree-ssa-ifcombine.c
@@ -54,6 +54,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-phinodes.h"
 #include "ssa-iterators.h"
 #include "tree-pass.h"
+#include "gimple-compat.h"
 
 #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT
 #define LOGICAL_OP_NON_SHORT_CIRCUIT \
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index db11e3e..33ab5a6 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -57,6 +57,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic-core.h"
 #include "debug.h"
 #include "flags.h"
+#include "gimple-compat.h"
 
 #ifdef ENABLE_CHECKING
 static void  verify_live_on_entry (tree_live_info_p);
diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c
index 300b2fa..5b5edf0 100644
--- a/gcc/tree-ssa-loop-ch.c
+++ b/gcc/tree-ssa-loop-ch.c
@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-inline.h"
 #include "flags.h"
 #include "tree-ssa-threadedge.h"
+#include "gimple-compat.h"
 
 /* Duplicates headers of loops if they are small enough, so that the statements
    in the loop body are always executed when the loop is entered.  This
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 6f64f4a..edfc8f3 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -64,6 +64,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-propagate.h"
 #include "trans-mem.h"
 #include "gimple-fold.h"
+#include "gimple-compat.h"
 
 /* TODO:  Support for predicated code motion.  I.e.
 
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index e205216..8aff3a9 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -83,6 +83,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target.h"
 #include "tree-cfgcleanup.h"
 #include "builtins.h"
+#include "gimple-compat.h"
 
 /* Specifies types of loops that may be unrolled.  */
 
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index f0237e0..ac71e40 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -120,6 +120,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "expmed.h"
 #include "tree-ssa-address.h"
 #include "builtins.h"
+#include "gimple-compat.h"
 
 /* FIXME: Expressions are expanded to RTL in this pass to determine the
    cost of different addressing modes.  This should be moved to a TBD
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index fd4d5bf..a6f6238 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -65,6 +65,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "stringpool.h"
 #include "tree-ssanames.h"
 #include "wide-int-print.h"
+#include "gimple-compat.h"
 
 
 #define SWAP(X, Y) do { affine_iv *tmp = (X); (X) = (Y); (Y) = tmp; } while (0)
diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c
index c06c755..41935f3 100644
--- a/gcc/tree-ssa-loop-prefetch.c
+++ b/gcc/tree-ssa-loop-prefetch.c
@@ -60,6 +60,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "tree-inline.h"
 #include "tree-data-ref.h"
+#include "gimple-compat.h"
 
 
 /* FIXME: Needed for optabs, but this should all be moved to a TBD interface
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 5211b89..d3e8d3f 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -125,6 +125,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target.h"
 #include "gimple-pretty-print.h"
 #include "builtins.h"
+#include "gimple-compat.h"
 
 /* FIXME: RTL headers have to be included here for optabs.  */
 #include "rtl.h"		/* Because optabs.h wants enum rtx_code.  */
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index ccb6c6b..c4ac573 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -65,6 +65,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "optabs.h"
 #include "tree-scalar-evolution.h"
 #include "tree-inline.h"
+#include "gimple-compat.h"
 
 #ifndef HAVE_conditional_move
 #define HAVE_conditional_move (0)
diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c
index 8caab38..8f97b39 100644
--- a/gcc/tree-ssa-phiprop.c
+++ b/gcc/tree-ssa-phiprop.c
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "langhooks.h"
 #include "flags.h"
+#include "gimple-compat.h"
 
 /* This pass propagates indirect loads through the PHI node for its
    address to make the load source possibly non-addressable and to
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 886e6fc2..4d098a7 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -76,6 +76,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-prop.h"
 #include "tree-ssa-propagate.h"
 #include "ipa-utils.h"
+#include "gimple-compat.h"
 
 /* TODO:
 
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c
index c246ed6..7140f61 100644
--- a/gcc/tree-ssa-propagate.c
+++ b/gcc/tree-ssa-propagate.c
@@ -60,6 +60,7 @@
 #include "langhooks.h"
 #include "value-prof.h"
 #include "domwalk.h"
+#include "gimple-compat.h"
 
 /* This file implements a generic value propagation engine based on
    the same propagation used by the SSA-CCP algorithm [1].
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index dec357a..4840f26 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -74,6 +74,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "builtins.h"
 #include "gimplify.h"
 #include "optabs.h"
+#include "gimple-compat.h"
 
 /*  This is a simple global reassociation pass.  It is, in part, based
     on the LLVM pass of the same name (They do some things more/less
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 683e50e..4c5e7c6 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -65,6 +65,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-sccvn.h"
 #include "tree-cfg.h"
 #include "domwalk.h"
+#include "gimple-compat.h"
 
 /* This algorithm is based on the SCC algorithm presented by Keith
    Cooper and L. Taylor Simpson in "SCC-Based Value numbering"
diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c
index c6d8712..6d8c511 100644
--- a/gcc/tree-ssa-sink.c
+++ b/gcc/tree-ssa-sink.c
@@ -54,6 +54,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "flags.h"
 #include "cfgloop.h"
 #include "params.h"
+#include "gimple-compat.h"
 
 /* TODO:
    1. Sinking store only using scalar promotion (IE without moving the RHS):
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 4d35bc9..114bbff 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -62,6 +62,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-pretty-print.h"
 #include "params.h"
 #include "expr.h"
+#include "gimple-compat.h"
 
 /* A vector indexed by SSA_NAME_VERSION.  0 means unknown, positive value
    is an index into strinfo vector, negative value stands for
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index e1f0e66..66d1dbf 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -61,6 +61,7 @@
 #include "splay-tree.h"
 #include "params.h"
 #include "alias.h"
+#include "gimple-compat.h"
 
 /* The idea behind this analyzer is to generate set constraints from the
    program, then solve the resulting constraints in order to generate the
diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
index 5678657..1bff1e6 100644
--- a/gcc/tree-ssa-tail-merge.c
+++ b/gcc/tree-ssa-tail-merge.c
@@ -228,6 +228,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfgloop.h"
 #include "tree-pass.h"
 #include "trans-mem.h"
+#include "gimple-compat.h"
 
 /* Describes a group of bbs with the same successors.  The successor bbs are
    cached in succs, and the successor edge flags are cached in succ_flags.
diff --git a/gcc/tree-ssa-ter.c b/gcc/tree-ssa-ter.c
index 96b3959..afddc00 100644
--- a/gcc/tree-ssa-ter.c
+++ b/gcc/tree-ssa-ter.c
@@ -54,6 +54,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-outof-ssa.h"
 #include "flags.h"
 #include "gimple-walk.h"
+#include "gimple-compat.h"
 
 
 /* Temporary Expression Replacement (TER)
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 1f3825d..972f1a9 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "params.h"
 #include "tree-ssa-threadedge.h"
 #include "builtins.h"
+#include "gimple-compat.h"
 
 /* To avoid code explosion due to jump threading, we limit the
    number of statements we are going to copy.  This variable
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index 9fa3acf..f4039b6 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "diagnostic-core.h"
 #include "params.h"
+#include "gimple-compat.h"
 
 /* This implements the pass that does predicate aware warning on uses of
    possibly uninitialized variables. The pass first collects the set of
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index b893df9..a433b7c 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -62,6 +62,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic-core.h"
 #include "cfgloop.h"
 #include "cfgexpand.h"
+#include "gimple-compat.h"
 
 /* Pointer map of variable mappings, keyed by edge.  */
 static hash_map<edge, auto_vec<edge_var_map> > *edge_var_maps;
diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c
index 7bf3335..f71c4f6 100644
--- a/gcc/tree-stdarg.c
+++ b/gcc/tree-stdarg.c
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "sbitmap.h"
 #include "tree-pass.h"
 #include "tree-stdarg.h"
+#include "gimple-compat.h"
 
 /* A simple pass that attempts to optimize stdarg functions on architectures
    that need to save register arguments to stack on entry to stdarg functions.
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 334d775..f5172e9 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -599,10 +599,10 @@ struct switch_conv_info
 
   /* The first load statement that loads a temporary from a new static array.
    */
-  gimple arr_ref_first;
+  gassign *arr_ref_first;
 
   /* The last load statement that loads a temporary from a new static array.  */
-  gimple arr_ref_last;
+  gassign *arr_ref_last;
 
   /* String reason why the case wasn't a good candidate that is written to the
      dump file, if there is one.  */
@@ -1037,7 +1037,7 @@ build_one_array (gswitch *swtch, int num, tree arr_index_type,
 		 gphi *phi, tree tidx, struct switch_conv_info *info)
 {
   tree name, cst;
-  gimple load;
+  gassign *load;
   gimple_stmt_iterator gsi = gsi_for_stmt (swtch);
   location_t loc = gimple_location (swtch);
 
@@ -1103,7 +1103,7 @@ build_arrays (gswitch *swtch, struct switch_conv_info *info)
 {
   tree arr_index_type;
   tree tidx, sub, utype;
-  gimple stmt;
+  gassign *stmt;
   gimple_stmt_iterator gsi;
   gphi_iterator gpi;
   int i;
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index de6a531..2f42894 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -69,6 +69,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "optabs.h"
 #include "builtins.h"
 #include "varasm.h"
+#include "gimple-compat.h"
 
 /* Return true if load- or store-lanes optab OPTAB is implemented for
    COUNT vectors of type VECTYPE.  NAME is the name of OPTAB.  */
diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index 55ab637..c3a2437 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "flags.h"
 #include "diagnostic.h"
 #include "target.h"
+#include "gimple-compat.h"
 
 /* Need to include rtl.h, expr.h, etc. for optabs.  */
 #include "expr.h"
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 5149db7..e63c21d 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -66,6 +66,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-scalar-evolution.h"
 #include "tree-vectorizer.h"
 #include "target.h"
+#include "gimple-compat.h"
 
 /* Loop Vectorization Pass.
 
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index b84248e..f16dcbf 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic-core.h"
 #include "dumpfile.h"
 #include "builtins.h"
+#include "gimple-compat.h"
 
 /* Pattern recognition functions  */
 static gimple vect_recog_widen_sum_pattern (vec<gimple> *, tree *,
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 0e9abdb..85e01ed 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "optabs.h"
 #include "tree-vectorizer.h"
 #include "langhooks.h"
+#include "gimple-compat.h"
 
 /* Extract the location of the basic block in the source code.
    Return the basic block location if succeed and NULL if not.  */
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 02ac7d0..f42adae 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -66,6 +66,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dumpfile.h"
 #include "cgraph.h"
 #include "builtins.h"
+#include "gimple-compat.h"
 
 /* For lang_hooks.types.type_for_mode.  */
 #include "langhooks.h"
@@ -1314,7 +1315,7 @@ tree
 vect_init_vector (gimple stmt, tree val, tree type, gimple_stmt_iterator *gsi)
 {
   tree new_var;
-  gimple init_stmt;
+  gassign *init_stmt;
   tree vec_oprnd;
   tree new_temp;
 
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 43ffcfe..4614fba 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -72,6 +72,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "optabs.h"
 #include "tree-ssa-threadedge.h"
 #include "wide-int.h"
+#include "gimple-compat.h"
 
 
 
diff --git a/gcc/tsan.c b/gcc/tsan.c
index 0577104..83a5931 100644
--- a/gcc/tsan.c
+++ b/gcc/tsan.c
@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-propagate.h"
 #include "tsan.h"
 #include "asan.h"
+#include "gimple-compat.h"
 
 /* Number of instrumented memory accesses in the current function.  */
 
diff --git a/gcc/ubsan.c b/gcc/ubsan.c
index 7a69000..e8dc598 100644
--- a/gcc/ubsan.c
+++ b/gcc/ubsan.c
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dfp.h"
 #include "builtins.h"
 #include "tree-object-size.h"
+#include "gimple-compat.h"
 
 /* Map from a tree to a VAR_DECL tree.  */
 
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index b35c437..5a4033e 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -69,6 +69,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "builtins.h"
 #include "tree-nested.h"
 #include "params.h"
+#include "gimple-compat.h"
 
 /* In this file value profile based optimizations are placed.  Currently the
    following optimizations are implemented (for more detailed descriptions
diff --git a/gcc/vtable-verify.c b/gcc/vtable-verify.c
index c7105d5..0815802 100644
--- a/gcc/vtable-verify.c
+++ b/gcc/vtable-verify.c
@@ -161,6 +161,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssanames.h"
 #include "tree-pass.h"
 #include "cfgloop.h"
+#include "gimple-compat.h"
 
 #include "vtable-verify.h"
 
-- 
1.8.5.3


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-13 10:47                 ` Richard Biener
                                     ` (2 preceding siblings ...)
  2014-11-14 15:44                   ` [PATCH] Add gimple-compat.h (was Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign) David Malcolm
@ 2014-11-15 11:58                   ` David Malcolm
  2014-11-17 10:23                     ` Richard Biener
  3 siblings, 1 reply; 36+ messages in thread
From: David Malcolm @ 2014-11-15 11:58 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jakub Jelinek, GCC Patches, GCC Development, Jeff Law

[-- Attachment #1: Type: text/plain, Size: 10420 bytes --]

On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote:
> On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm <dmalcolm@redhat.com> wrote:
> > On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
> >> On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> >> > On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
> >> >> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
> >> >> > On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
> >> >> > > To be constructive here - the above case is from within a
> >> >> > > GIMPLE_ASSIGN case label
> >> >> > > and thus I'd have expected
> >> >> > >
> >> >> > >     case GIMPLE_ASSIGN:
> >> >> > >       {
> >> >> > >         gassign *a1 = as_a <gassign *> (s1);
> >> >> > >         gassign *a2 = as_a <gassign *> (s2);
> >> >> > >       lhs1 = gimple_assign_lhs (a1);
> >> >> > >       lhs2 = gimple_assign_lhs (a2);
> >> >> > >       if (TREE_CODE (lhs1) != SSA_NAME
> >> >> > >           && TREE_CODE (lhs2) != SSA_NAME)
> >> >> > >         return (operand_equal_p (lhs1, lhs2, 0)
> >> >> > >                 && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
> >> >> > >                                                  gimple_assign_rhs1 (a2)));
> >> >> > >       else if (TREE_CODE (lhs1) == SSA_NAME
> >> >> > >                && TREE_CODE (lhs2) == SSA_NAME)
> >> >> > >         return vn_valueize (lhs1) == vn_valueize (lhs2);
> >> >> > >       return false;
> >> >> > >       }
> >> >> > >
> >> >> > > instead.  That's the kind of changes I have expected and have approved of.
> >> >> >
> >> >> > But even that looks like just adding extra work for all developers, with no
> >> >> > gain.  You only have to add extra code and extra temporaries, in switches
> >> >> > typically also have to add {} because of the temporaries and thus extra
> >> >> > indentation level, and it doesn't simplify anything in the code.
> >> >>
> >> >> The branch attempts to use the C++ typesystem to capture information
> >> >> about the kinds of gimple statement we expect, both:
> >> >>   (A) so that the compiler can detect type errors, and
> >> >>   (B) as a comprehension aid to the human reader of the code
> >> >>
> >> >> The ideal here is when function params and struct field can be
> >> >> strengthened from "gimple" to a subclass ptr.  This captures the
> >> >> knowledge that every use of a function or within a struct has a given
> >> >> gimple code.
> >> >
> >> > I just don't like all the as_a/is_a stuff enforced everywhere,
> >> > it means more typing, more temporaries, more indentation.
> >> > So, as I view it, instead of the checks being done cheaply (yes, I think
> >> > the gimple checking as we have right now is very cheap) under the
> >> > hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
> >> > put the burden on the developers, who has to check that manually through
> >> > the as_a/is_a stuff everywhere, more typing and uglier syntax.
> >> > I just don't see that as a step forward, instead a huge step backwards.
> >> > But perhaps I'm alone with this.
> >> > Can you e.g. compare the size of - lines in your patchset combined, and
> >> > size of + lines in your patchset?  As in, if your changes lead to less
> >> > typing or more.
> >>
> >> I see two ways out here.  One is to add overloads to all the functions
> >> taking the special types like
> >>
> >> tree
> >> gimple_assign_rhs1 (gimple *);
> >>
> >> or simply add
> >>
> >> gassign *operator ()(gimple *g) { return as_a <gassign *> (g); }
> >>
> >> into a gimple-compat.h header which you include in places that
> >> are not converted "nicely".
> >
> > Thanks for the suggestions.
> >
> > Am I missing something, or is the gimple-compat.h idea above not valid C
> > ++?
> >
> > Note that "gimple" is still a typedef to
> >   gimple_statement_base *
> > (as noted before, the gimple -> gimple * change would break everyone
> > else's patches, so we talked about that as a followup patch for early
> > stage3).
> >
> > Given that, if I try to create an "operator ()" outside of a class, I
> > get this error:
> >
> > ‘gassign* operator()(gimple)’ must be a nonstatic member function
> >
> > which is emitted from cp/decl.c's grok_op_properties:
> >       /* An operator function must either be a non-static member function
> >          or have at least one parameter of a class, a reference to a class,
> >          an enumeration, or a reference to an enumeration.  13.4.0.6 */
> >
> > I tried making it a member function of gimple_statement_base, but that
> > doesn't work either: we want a conversion
> >   from a gimple_statement_base * to a gassign *, not
> >   from a gimple_statement_base   to a gassign *.
> >
> > Is there some syntactic trick here that I'm missing?  Sorry if I'm being
> > dumb (I can imagine there's a way of doing it by making "gimple" become
> > some kind of wrapped ptr class, but that way lies madness, surely).
> 
> Hmm.
> 
> struct assign;
> struct base {
>   operator assign *() const { return (assign *)this; }
> };
> struct assign : base {
> };
> 
> void foo (assign *);
> void bar (base *b)
> {
>   foo (b);
> }
> 
> doesn't work, but
> 
> void bar (base &b)
> {
>   foo (b);
> }
> 
> does.  Indeed C++ doesn't seem to provide what is necessary
> for the compat trick :(
> 
> So the gimple-compat.h header would need to provide
> additional overloads for the affected functions like
> 
> inline tree
> gimple_assign_rhs1 (gimple *g)
> {
>   return gimple_assign_rhs1 (as_a <gassign *> (g));
> }
> 
> that would work for me as well.
> 
> >> Both avoid manually making the compiler happy (which the
> >> explicit as_a<> stuff is!  It doesn't add any "checking" - it's
> >> just placing the as_a<> at the callers and thus make the
> >> runtine ICE fire there).
> >>
> >> As much as I don't like "global" conversion operators I don't
> >> like adding overloads to all of the accessor functions even more.
> >
> > (nods)
> >
> > Some other options:
> >
> > Option 3: only convert the "easy" accessors: the ones I already did in
> > the /89 patch kit, as reviewed by Jeff, and rebased by me recently,
> > which is this 92-patch kit:
> >   "[gimple-classes, committed 00/92] Initial slew of commits":
> >      https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html
> > Doing so converts about half of the gimple_foo_ accessors to taking a
> > gfoo *, giving a mixture of GIMPLE_CHECK vs subclass use.   I believe
> > the quality of those patches was higher than the later ones on the
> > branch: I was doing the places that didn't require the invasive/verbose
> > changes seen in the later patches.  Shelve the remaining ~80
> > increasingly ugly patches, starting a new branch to contain just the
> > good ones.

I've created a branch "dmalcolm/gimple-classes-v2-option-3"
https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/gimple-classes-v2-option-3

which takes the work reviewed by Jeff and the most trivial of the merger
followup work, throwing away the ~80 unloved followup patches on
dmalcolm/gimple-classes.

I've merged from yesterday's trunk r217593 into that new branch,
resolving conflicts.

I did this in two parts: the basic merger as 
  bd7fe714158f0c600caa05be7d744fd9139b8afb
resolving conflicts, with a followup patch to fixup new code from trunk
that used accessors that on the branch required a gimple subclass.

Attached is that 2nd part of the merger.

Successfully bootstrapped and regrtested on x86_64-unknown-linux-gnu;
same regrtest results as a control bootstrap of trunk's r217593.

I appreciate Jakub and others have concerns about the overall approach.
I'm not sure which of option 2 (gimple-compat.h), option 3 (this one),
option 4 (just convert fields and non-accessor params), or defer to gcc
6 is the best one, but I'm sleep-deprived and wanted to submit this
before the stage1 deadline.

The other commits on this pruned branch that haven't been reviewed yet
are:

[gimple-classes, committed 88/92] Preparatory work before subclass
renaming
  https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02820.html

[gimple-classes, committed 89/92] Eliminate subclass typedefs from
coretypes.h
  https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02838.html

[gimple-classes, committed 90/92] Automated renaming of gimple
subclasses
  https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02828.html

[gimple-classes, committed 91/92] Remove out-of-date references to
typedefs]
  https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02874.html

[gimple-classes, committed 92/92] Update gimple.texi class hierarchy
diagram
  https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02818.html

[gimple-classes] Merge trunk r216157-r216746 into branch
  https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02982.html

Also, presumably if this were merged, it would require a followup with
the gimple to gimple * fixup you wanted? (which we talked about doing as
an early stage3 thing IIRC [1]).

Thanks
Dave
[1] e.g. https://gcc.gnu.org/ml/gcc-patches/2014-10/msg01536.html


> > Option 4: don't convert any accessors, but instead focus on fields of
> > structs (e.g. "call_stmt" within a cgraph_edge), and on params of other
> > functions (e.g. phi-manipulation code).  That way we'd avoid the
> > inconsistency of some accessors using GIMPLE_CHECK and some using
> > subclasses - all would continue to consistently use GIMPLE_CHECK, but
> > there would be some extra type-checking and self-documentation of the
> > expected statement kinds in the code.
> >
> >
> >
> > FWIW, option 3 is my preferred approach (I've already done the bulk of
> > the work and it's already been reviewed; it would need an update merger
> > from trunk, and there's the big gimple to gimple * fixup you wanted).
> 
> Works for me as well.  The compat solution looks somewhat appealing
> as we can then incrementally fix up things rather than requiring to
> mass-convert everything.
> 
> Thanks,
> Richard.
> 
> >> Whether you enable them generally or just for selected files
> >> via a gimple-compat.h will be up to you (but I'd rather get
> >> rid of them at some point).
> >>
> >> Note this allows seamless transform of "random" functions
> >> taking a gimple now but really only expecting a single kind.
> >>
> >> Note that we don't absolutely have to rush this all in for GCC 5.
> >> Being the very first for GCC 6 stage1 is another possibility.
> >> We just should get it right.
> >
> > Thanks
> > Dave
> >


[-- Attachment #2: 0001-Fixups-after-merge.patch --]
[-- Type: text/x-patch, Size: 22801 bytes --]

From 533f5852c8aef75bf4f14b03744e5e09429a882c Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Sat, 15 Nov 2014 05:02:09 -0500
Subject: [PATCH] Fixups after merge

gcc/ChangeLog.gimple-classes:
	* cgraph.c (cgraph_edge::redirect_call_stmt_to_callee):
	Strengthen locals "dbndret" and "ibndret" from gimple to gcall *.
	* gimple-iterator.c (gsi_for_phi): New function.
	* gimple-iterator.h (gsi_for_phi): New prototype.
	* internal-fn.c (expand_ADD_OVERFLOW): Strengthen param "stmt"
	from gimple to gcall *.
	(expand_SUB_OVERFLOW): Likewise.
	(expand_MUL_OVERFLOW): Likewise.
	* ipa-icf-gimple.c (func_checker::compare_bb): Add checked casts
	within case GIMPLE_CALL.
	(func_checker::compare_gimple_call): Strengthen params from gimple
	to gcall *.
	* ipa-icf-gimple.h (func_checker::compare_gimple_call): Likewise.
	* sanopt.c (sanopt_optimize_walker): Replace check for GIMPLE_ASM
	with a dyn_cast, introducing local "asm_stmt" and using it in
	place of "stmt" for typesafety.
	* tree-chkp.c (chkp_recompute_phi_bounds): Strengthen locals
	"bounds_phi" and "ptr_phi" from gimple to gphi *.
	(chkp_add_bounds_to_ret_stmt): Strengthen local "ret" from gimple
	to greturn *.
	(chkp_add_bounds_to_call_stmt): Strengthen locals "call" and
	"new_call" from gimple to gcall *.
	(chkp_build_returned_bound): Likewise for param "call".
	(chkp_retbnd_call_by_val): Likewise for return type.
	(chkp_get_bounds_by_definition): Strengthen param "iter" from
	gimple_stmt_iterator * to gphi_iterator *.  Add a checked cast
	within case GIMPLE_CALL.  Use gsi_for_phi rather than
	gsi_for_stmt.
	(chkp_find_bounds_1): Strengthen local "phi_iter" from
	gimple_stmt_iterator to gphi_iterator.  Replace check for
	GIMPLE_PHI with a dyn_cast, introducing local "def_phi" and using
	in place of "def_stmt" for typesafety.
	(chkp_copy_bounds_for_assign): Add checked cast.
	(chkp_instrument_function): Within case GIMPLE_RETURN, add local
	greturn * "r" from a checked cast and use in place of "s" for
	typesafety.
	* tree-chkp.h (chkp_retbnd_call_by_val): Strengthen return type
	from gimple to gcall *.
	* tree-inline.c (copy_bb): Update for renaming of field
	"gimple_call" to "call_stmt" on the gimple-classes branch.
	(expand_call_inline): Strengthen local "retbnc" from gimple to
	gcall *.
	* tree-ssa-forwprop.c (pass_forwprop::execute): Replace check for
	GIMPLE_COND with a dyn_cast, introducing local "cond" and using
	in place of "stmt" for typesafety.
	* value-prof.c (gimple_ic): Strengthen local "iretbnd_stmt" from
	gimple to gcall *.  Weaken top-level local "psi" from
	gphi_iterator back to gimple_stmt_iterator, reintroducing the
	name as a phi_iterator within the for loop that needs it.
---
 gcc/ChangeLog.gimple-classes | 52 ++++++++++++++++++++++++++++++
 gcc/cgraph.c                 |  4 +--
 gcc/gimple-iterator.c        | 13 ++++++++
 gcc/gimple-iterator.h        |  1 +
 gcc/internal-fn.c            |  6 ++--
 gcc/ipa-icf-gimple.c         |  5 +--
 gcc/ipa-icf-gimple.h         |  2 +-
 gcc/sanopt.c                 |  7 ++--
 gcc/tree-chkp.c              | 76 +++++++++++++++++++++++---------------------
 gcc/tree-chkp.h              |  2 +-
 gcc/tree-inline.c            | 30 ++++++++---------
 gcc/tree-ssa-forwprop.c      |  8 ++---
 gcc/value-prof.c             |  6 ++--
 13 files changed, 141 insertions(+), 71 deletions(-)

diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
index 133965c..ec8fc5a 100644
--- a/gcc/ChangeLog.gimple-classes
+++ b/gcc/ChangeLog.gimple-classes
@@ -1,3 +1,55 @@
+2014-11-14  David Malcolm  <dmalcolm@redhat.com>
+
+	* cgraph.c (cgraph_edge::redirect_call_stmt_to_callee):
+	Strengthen locals "dbndret" and "ibndret" from gimple to gcall *.
+	* gimple-iterator.c (gsi_for_phi): New function.
+	* gimple-iterator.h (gsi_for_phi): New prototype.
+	* internal-fn.c (expand_ADD_OVERFLOW): Strengthen param "stmt"
+	from gimple to gcall *.
+	(expand_SUB_OVERFLOW): Likewise.
+	(expand_MUL_OVERFLOW): Likewise.
+	* ipa-icf-gimple.c (func_checker::compare_bb): Add checked casts
+	within case GIMPLE_CALL.
+	(func_checker::compare_gimple_call): Strengthen params from gimple
+	to gcall *.
+	* ipa-icf-gimple.h (func_checker::compare_gimple_call): Likewise.
+	* sanopt.c (sanopt_optimize_walker): Replace check for GIMPLE_ASM
+	with a dyn_cast, introducing local "asm_stmt" and using it in
+	place of "stmt" for typesafety.
+	* tree-chkp.c (chkp_recompute_phi_bounds): Strengthen locals
+	"bounds_phi" and "ptr_phi" from gimple to gphi *.
+	(chkp_add_bounds_to_ret_stmt): Strengthen local "ret" from gimple
+	to greturn *.
+	(chkp_add_bounds_to_call_stmt): Strengthen locals "call" and
+	"new_call" from gimple to gcall *.
+	(chkp_build_returned_bound): Likewise for param "call".
+	(chkp_retbnd_call_by_val): Likewise for return type.
+	(chkp_get_bounds_by_definition): Strengthen param "iter" from
+	gimple_stmt_iterator * to gphi_iterator *.  Add a checked cast
+	within case GIMPLE_CALL.  Use gsi_for_phi rather than
+	gsi_for_stmt.
+	(chkp_find_bounds_1): Strengthen local "phi_iter" from
+	gimple_stmt_iterator to gphi_iterator.  Replace check for
+	GIMPLE_PHI with a dyn_cast, introducing local "def_phi" and using
+	in place of "def_stmt" for typesafety.
+	(chkp_copy_bounds_for_assign): Add checked cast.
+	(chkp_instrument_function): Within case GIMPLE_RETURN, add local
+	greturn * "r" from a checked cast and use in place of "s" for
+	typesafety.
+	* tree-chkp.h (chkp_retbnd_call_by_val): Strengthen return type
+	from gimple to gcall *.
+	* tree-inline.c (copy_bb): Update for renaming of field
+	"gimple_call" to "call_stmt" on the gimple-classes branch.
+	(expand_call_inline): Strengthen local "retbnc" from gimple to
+	gcall *.
+	* tree-ssa-forwprop.c (pass_forwprop::execute): Replace check for
+	GIMPLE_COND with a dyn_cast, introducing local "cond" and using
+	in place of "stmt" for typesafety.
+	* value-prof.c (gimple_ic): Strengthen local "iretbnd_stmt" from
+	gimple to gcall *.  Weaken top-level local "psi" from
+	gphi_iterator back to gimple_stmt_iterator, reintroducing the
+	name as a phi_iterator within the for loop that needs it.
+
 2014-10-28  David Malcolm  <dmalcolm@redhat.com>
 
 	* auto-profile.c (autofdo::function_instance::find_icall_target_map):
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index a854b4a..71e6146 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1363,8 +1363,8 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
 	    {
 	      tree dresult = gimple_call_lhs (new_stmt);
 	      tree iresult = gimple_call_lhs (e2->call_stmt);
-	      gimple dbndret = chkp_retbnd_call_by_val (dresult);
-	      gimple ibndret = chkp_retbnd_call_by_val (iresult);
+	      gcall *dbndret = chkp_retbnd_call_by_val (dresult);
+	      gcall *ibndret = chkp_retbnd_call_by_val (iresult);
 	      struct cgraph_edge *iedge
 		= e2->caller->cgraph_node::get_edge (ibndret);
 	      struct cgraph_edge *dedge;
diff --git a/gcc/gimple-iterator.c b/gcc/gimple-iterator.c
index 3d8bd6f..e7a4658 100644
--- a/gcc/gimple-iterator.c
+++ b/gcc/gimple-iterator.c
@@ -639,6 +639,19 @@ gsi_for_stmt (gimple stmt)
   return i;
 }
 
+/* Finds iterator for PHI.  */
+
+gphi_iterator
+gsi_for_phi (gphi *phi)
+{
+  gphi_iterator i;
+  basic_block bb = gimple_bb (phi);
+
+  i = gsi_start_phis (bb);
+  i.ptr = phi;
+
+  return i;
+}
 
 /* Move the statement at FROM so it comes right after the statement at TO.  */
 
diff --git a/gcc/gimple-iterator.h b/gcc/gimple-iterator.h
index 79585d2..fb6cc07 100644
--- a/gcc/gimple-iterator.h
+++ b/gcc/gimple-iterator.h
@@ -79,6 +79,7 @@ extern void gsi_insert_after (gimple_stmt_iterator *, gimple,
 			      enum gsi_iterator_update);
 extern bool gsi_remove (gimple_stmt_iterator *, bool);
 extern gimple_stmt_iterator gsi_for_stmt (gimple);
+extern gphi_iterator gsi_for_phi (gphi *);
 extern void gsi_move_after (gimple_stmt_iterator *, gimple_stmt_iterator *);
 extern void gsi_move_before (gimple_stmt_iterator *, gimple_stmt_iterator *);
 extern void gsi_move_to_bb_end (gimple_stmt_iterator *, basic_block);
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index de08486..8bf43d9 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -1813,7 +1813,7 @@ expand_arith_overflow (enum tree_code code, gimple stmt)
 /* Expand ADD_OVERFLOW STMT.  */
 
 static void
-expand_ADD_OVERFLOW (gimple stmt)
+expand_ADD_OVERFLOW (gcall *stmt)
 {
   expand_arith_overflow (PLUS_EXPR, stmt);
 }
@@ -1821,7 +1821,7 @@ expand_ADD_OVERFLOW (gimple stmt)
 /* Expand SUB_OVERFLOW STMT.  */
 
 static void
-expand_SUB_OVERFLOW (gimple stmt)
+expand_SUB_OVERFLOW (gcall *stmt)
 {
   expand_arith_overflow (MINUS_EXPR, stmt);
 }
@@ -1829,7 +1829,7 @@ expand_SUB_OVERFLOW (gimple stmt)
 /* Expand MUL_OVERFLOW STMT.  */
 
 static void
-expand_MUL_OVERFLOW (gimple stmt)
+expand_MUL_OVERFLOW (gcall *stmt)
 {
   expand_arith_overflow (MULT_EXPR, stmt);
 }
diff --git a/gcc/ipa-icf-gimple.c b/gcc/ipa-icf-gimple.c
index 2ec2a1c..8f2a438 100644
--- a/gcc/ipa-icf-gimple.c
+++ b/gcc/ipa-icf-gimple.c
@@ -595,7 +595,8 @@ func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
       switch (gimple_code (s1))
 	{
 	case GIMPLE_CALL:
-	  if (!compare_gimple_call (s1, s2))
+	  if (!compare_gimple_call (as_a <gcall *> (s1),
+				    as_a <gcall *> (s2)))
 	    return return_different_stmts (s1, s2, "GIMPLE_CALL");
 	  break;
 	case GIMPLE_ASSIGN:
@@ -656,7 +657,7 @@ func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
    call statements are semantically equivalent.  */
 
 bool
-func_checker::compare_gimple_call (gimple s1, gimple s2)
+func_checker::compare_gimple_call (gcall *s1, gcall *s2)
 {
   unsigned i;
   tree t1, t2;
diff --git a/gcc/ipa-icf-gimple.h b/gcc/ipa-icf-gimple.h
index b84b122..cb9b1fc 100644
--- a/gcc/ipa-icf-gimple.h
+++ b/gcc/ipa-icf-gimple.h
@@ -161,7 +161,7 @@ public:
 
   /* Verifies for given GIMPLEs S1 and S2 that
      call statements are semantically equivalent.  */
-  bool compare_gimple_call (gimple s1, gimple s2);
+  bool compare_gimple_call (gcall *s1, gcall *s2);
 
   /* Verifies for given GIMPLEs S1 and S2 that
      assignment statements are semantically equivalent.  */
diff --git a/gcc/sanopt.c b/gcc/sanopt.c
index f6e8ee7..e1d11e0 100644
--- a/gcc/sanopt.c
+++ b/gcc/sanopt.c
@@ -418,10 +418,11 @@ sanopt_optimize_walker (basic_block bb, struct sanopt_ctx *ctx)
 	{
 	  /* Handle asm volatile or asm with "memory" clobber
 	     the same as potentionally freeing call.  */
-	  if (gimple_code (stmt) == GIMPLE_ASM
+	  gasm *asm_stmt = dyn_cast <gasm *> (stmt);
+	  if (asm_stmt
 	      && asan_check_optimize
-	      && (gimple_asm_clobbers_memory_p (stmt)
-		  || gimple_asm_volatile_p (stmt)))
+	      && (gimple_asm_clobbers_memory_p (asm_stmt)
+		  || gimple_asm_volatile_p (asm_stmt)))
 	    info->freeing_call_events++;
 	  gsi_next (&gsi);
 	  continue;
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
index df7d425..aadb1cf 100644
--- a/gcc/tree-chkp.c
+++ b/gcc/tree-chkp.c
@@ -691,18 +691,15 @@ chkp_recompute_phi_bounds (tree const &bounds, tree *slot,
 			   void *res ATTRIBUTE_UNUSED)
 {
   tree ptr = *slot;
-  gimple bounds_phi;
-  gimple ptr_phi;
+  gphi *bounds_phi;
+  gphi *ptr_phi;
   unsigned i;
 
   gcc_assert (TREE_CODE (bounds) == SSA_NAME);
   gcc_assert (TREE_CODE (ptr) == SSA_NAME);
 
-  bounds_phi = SSA_NAME_DEF_STMT (bounds);
-  ptr_phi = SSA_NAME_DEF_STMT (ptr);
-
-  gcc_assert (bounds_phi && gimple_code (bounds_phi) == GIMPLE_PHI);
-  gcc_assert (ptr_phi && gimple_code (ptr_phi) == GIMPLE_PHI);
+  bounds_phi = as_a <gphi *> (SSA_NAME_DEF_STMT (bounds));
+  ptr_phi = as_a <gphi *> (SSA_NAME_DEF_STMT (ptr));
 
   for (i = 0; i < gimple_phi_num_args (bounds_phi); i++)
     {
@@ -1198,7 +1195,7 @@ chkp_get_registered_bounds (tree ptr)
 static void
 chkp_add_bounds_to_ret_stmt (gimple_stmt_iterator *gsi)
 {
-  gimple ret = gsi_stmt (*gsi);
+  greturn *ret = as_a <greturn *> (gsi_stmt (*gsi));
   tree retval = gimple_return_retval (ret);
   tree ret_decl = DECL_RESULT (cfun->decl);
   tree bounds;
@@ -1593,7 +1590,7 @@ chkp_find_bound_slots (const_tree type, bitmap res)
 static void
 chkp_add_bounds_to_call_stmt (gimple_stmt_iterator *gsi)
 {
-  gimple call = gsi_stmt (*gsi);
+  gcall *call = as_a <gcall *> (gsi_stmt (*gsi));
   unsigned arg_no = 0;
   tree fndecl = gimple_call_fndecl (call);
   tree fntype;
@@ -1602,7 +1599,7 @@ chkp_add_bounds_to_call_stmt (gimple_stmt_iterator *gsi)
   bool use_fntype = false;
   tree op;
   ssa_op_iter iter;
-  gimple new_call;
+  gcall *new_call;
 
   /* Do nothing for internal functions.  */
   if (gimple_call_internal_p (call))
@@ -2040,7 +2037,7 @@ chkp_get_nonpointer_load_bounds (void)
 
 /* Build bounds returned by CALL.  */
 static tree
-chkp_build_returned_bound (gimple call)
+chkp_build_returned_bound (gcall *call)
 {
   gimple_stmt_iterator gsi;
   tree bounds;
@@ -2146,7 +2143,7 @@ chkp_build_returned_bound (gimple call)
 
 /* Return bounds used as returned by call
    which produced SSA name VAL.  */
-gimple
+gcall *
 chkp_retbnd_call_by_val (tree val)
 {
   if (TREE_CODE (val) != SSA_NAME)
@@ -2159,7 +2156,7 @@ chkp_retbnd_call_by_val (tree val)
   FOR_EACH_IMM_USE_FAST (use_p, use_iter, val)
     if (gimple_code (USE_STMT (use_p)) == GIMPLE_CALL
 	&& gimple_call_fndecl (USE_STMT (use_p)) == chkp_ret_bnd_fndecl)
-      return USE_STMT (use_p);
+      return as_a <gcall *> (USE_STMT (use_p));
 
   return NULL;
 }
@@ -2554,11 +2551,11 @@ chkp_compute_bounds_for_assignment (tree node, gimple assign)
    Return computed bounds.  */
 static tree
 chkp_get_bounds_by_definition (tree node, gimple def_stmt,
-			       gimple_stmt_iterator *iter)
+			       gphi_iterator *iter)
 {
   tree var, bounds;
   enum gimple_code code = gimple_code (def_stmt);
-  gimple stmt;
+  gphi *stmt;
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -2619,7 +2616,7 @@ chkp_get_bounds_by_definition (tree node, gimple def_stmt,
       break;
 
     case GIMPLE_CALL:
-      bounds = chkp_build_returned_bound (def_stmt);
+      bounds = chkp_build_returned_bound (as_a <gcall *> (def_stmt));
       break;
 
     case GIMPLE_PHI:
@@ -2634,7 +2631,7 @@ chkp_get_bounds_by_definition (tree node, gimple def_stmt,
 	var = chkp_get_tmp_var ();
       stmt = create_phi_node (var, gimple_bb (def_stmt));
       bounds = gimple_phi_result (stmt);
-      *iter = gsi_for_stmt (stmt);
+      *iter = gsi_for_phi (stmt);
 
       bounds = chkp_maybe_copy_and_register_bounds (node, bounds);
 
@@ -3344,21 +3341,21 @@ chkp_find_bounds_1 (tree ptr, tree ptr_src, gimple_stmt_iterator *iter)
       if (!bounds)
 	{
 	  gimple def_stmt = SSA_NAME_DEF_STMT (ptr_src);
-	  gimple_stmt_iterator phi_iter;
+	  gphi_iterator phi_iter;
 
 	  bounds = chkp_get_bounds_by_definition (ptr_src, def_stmt, &phi_iter);
 
 	  gcc_assert (bounds);
 
-	  if (gimple_code (def_stmt) == GIMPLE_PHI)
+	  if (gphi *def_phi = dyn_cast <gphi *> (def_stmt))
 	    {
 	      unsigned i;
 
-	      for (i = 0; i < gimple_phi_num_args (def_stmt); i++)
+	      for (i = 0; i < gimple_phi_num_args (def_phi); i++)
 		{
-		  tree arg = gimple_phi_arg_def (def_stmt, i);
+		  tree arg = gimple_phi_arg_def (def_phi, i);
 		  tree arg_bnd;
-		  gimple phi_bnd;
+		  gphi *phi_bnd;
 
 		  arg_bnd = chkp_find_bounds (arg, NULL);
 
@@ -3368,10 +3365,10 @@ chkp_find_bounds_1 (tree ptr, tree ptr_src, gimple_stmt_iterator *iter)
 		     Previous call to chkp_find_bounds could create
 		     new basic block and therefore change phi statement
 		     phi_iter points to.  */
-		  phi_bnd = gsi_stmt (phi_iter);
+		  phi_bnd = phi_iter.phi ();
 
 		  add_phi_arg (phi_bnd, arg_bnd,
-			       gimple_phi_arg_edge (def_stmt, i),
+			       gimple_phi_arg_edge (def_phi, i),
 			       UNKNOWN_LOCATION);
 		}
 
@@ -3829,7 +3826,9 @@ chkp_copy_bounds_for_assign (gimple assign, struct cgraph_edge *edge)
 		      || fndecl == chkp_bndldx_fndecl
 		      || fndecl == chkp_ret_bnd_fndecl);
 
-	  new_edge = edge->caller->create_edge (callee, stmt, edge->count,
+	  new_edge = edge->caller->create_edge (callee,
+						as_a <gcall *> (stmt),
+						edge->count,
 						edge->frequency);
 	  new_edge->frequency = compute_call_stmt_bb_frequency
 	    (edge->caller->decl, gimple_bb (stmt));
@@ -3985,18 +3984,21 @@ chkp_instrument_function (void)
               break;
 
             case GIMPLE_RETURN:
-              if (gimple_return_retval (s) != NULL_TREE)
-		{
-		  chkp_process_stmt (&i, gimple_return_retval (s),
-				     gimple_location (s),
-				     integer_zero_node,
-				     NULL_TREE, NULL_TREE, safe);
-
-		  /* Additionally we need to add bounds
-		     to return statement.  */
-		  chkp_add_bounds_to_ret_stmt (&i);
-                }
-              break;
+	      {
+		greturn *r = as_a <greturn *> (s);
+		if (gimple_return_retval (r) != NULL_TREE)
+		  {
+		    chkp_process_stmt (&i, gimple_return_retval (r),
+				       gimple_location (r),
+				       integer_zero_node,
+				       NULL_TREE, NULL_TREE, safe);
+
+		    /* Additionally we need to add bounds
+		       to return statement.  */
+		    chkp_add_bounds_to_ret_stmt (&i);
+		  }
+	      }
+	      break;
 
 	    case GIMPLE_CALL:
 	      chkp_add_bounds_to_call_stmt (&i);
diff --git a/gcc/tree-chkp.h b/gcc/tree-chkp.h
index a349baf..71a29c0 100644
--- a/gcc/tree-chkp.h
+++ b/gcc/tree-chkp.h
@@ -46,7 +46,7 @@ extern tree chkp_build_bndstx_call (tree addr, tree ptr, tree bounds);
 extern void chkp_find_bound_slots (const_tree type, bitmap res);
 extern void chkp_build_bndstx (tree addr, tree ptr, tree bounds,
 			       gimple_stmt_iterator *gsi);
-extern gimple chkp_retbnd_call_by_val (tree val);
+extern gcall *chkp_retbnd_call_by_val (tree val);
 extern bool chkp_function_instrumented_p (tree fndecl);
 extern void chkp_function_mark_instrumented (tree fndecl);
 extern void chkp_copy_bounds_for_assign (gimple assign,
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 48bbb2e..58a0629 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1815,13 +1815,13 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 		 we handle not instrumented call in instrumented
 		 function.  */
 	      nargs_to_copy = nargs;
-	      if (gimple_call_with_bounds_p (id->gimple_call)
+	      if (gimple_call_with_bounds_p (id->call_stmt)
 		  && !gimple_call_with_bounds_p (stmt))
 		{
-		  for (i = gimple_call_num_args (id->gimple_call) - nargs;
-		       i < gimple_call_num_args (id->gimple_call);
+		  for (i = gimple_call_num_args (id->call_stmt) - nargs;
+		       i < gimple_call_num_args (id->call_stmt);
 		       i++)
-		    if (POINTER_BOUNDS_P (gimple_call_arg (id->gimple_call, i)))
+		    if (POINTER_BOUNDS_P (gimple_call_arg (id->call_stmt, i)))
 		      nargs_to_copy--;
 		  remove_bounds = true;
 		}
@@ -1840,20 +1840,20 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 		{
 		  /* Append the rest of arguments removing bounds.  */
 		  unsigned cur = gimple_call_num_args (call_stmt);
-		  i = gimple_call_num_args (id->gimple_call) - nargs;
-		  for (i = gimple_call_num_args (id->gimple_call) - nargs;
-		       i < gimple_call_num_args (id->gimple_call);
+		  i = gimple_call_num_args (id->call_stmt) - nargs;
+		  for (i = gimple_call_num_args (id->call_stmt) - nargs;
+		       i < gimple_call_num_args (id->call_stmt);
 		       i++)
-		    if (!POINTER_BOUNDS_P (gimple_call_arg (id->gimple_call, i)))
-		      argarray[cur++] = gimple_call_arg (id->gimple_call, i);
+		    if (!POINTER_BOUNDS_P (gimple_call_arg (id->call_stmt, i)))
+		      argarray[cur++] = gimple_call_arg (id->call_stmt, i);
 		  gcc_assert (cur == n);
 		}
 	      else
 		{
 		  /* Append the arguments passed in '...'  */
 		  memcpy (argarray.address () + gimple_call_num_args (call_stmt),
-			  gimple_call_arg_ptr (id->gimple_call, 0)
-			  + (gimple_call_num_args (id->gimple_call) - nargs),
+			  gimple_call_arg_ptr (id->call_stmt, 0)
+			  + (gimple_call_num_args (id->call_stmt) - nargs),
 			  nargs * sizeof (tree));
 		}
 
@@ -1889,10 +1889,10 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 		nargs--;
 
 	      /* For instrumented calls we should ignore bounds.  */
-	      for (i = gimple_call_num_args (id->gimple_call) - nargs;
-		   i < gimple_call_num_args (id->gimple_call);
+	      for (i = gimple_call_num_args (id->call_stmt) - nargs;
+		   i < gimple_call_num_args (id->call_stmt);
 		   i++)
-		if (POINTER_BOUNDS_P (gimple_call_arg (id->gimple_call, i)))
+		if (POINTER_BOUNDS_P (gimple_call_arg (id->call_stmt, i)))
 		  nargs--;
 
 	      count = build_int_cst (integer_type_node, nargs);
@@ -4509,7 +4509,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
       if (gimple_call_with_bounds_p (stmt)
 	  && TREE_CODE (modify_dest) == SSA_NAME)
 	{
-	  gimple retbnd = chkp_retbnd_call_by_val (modify_dest);
+	  gcall *retbnd = chkp_retbnd_call_by_val (modify_dest);
 	  if (retbnd)
 	    {
 	      return_bounds = gimple_call_lhs (retbnd);
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index f0e51bb..4484513 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2223,10 +2223,10 @@ pass_forwprop::execute (function *fun)
 		bitmap_set_bit (to_purge, bb->index);
 	      /* Cleanup the CFG if we simplified a condition to
 	         true or false.  */
-	      if (gimple_code (stmt) == GIMPLE_COND
-		  && (gimple_cond_true_p (stmt)
-		      || gimple_cond_false_p (stmt)))
-		cfg_changed = true;
+	      if (gcond *cond = dyn_cast <gcond *> (stmt))
+		if (gimple_cond_true_p (cond)
+		    || gimple_cond_false_p (cond))
+		  cfg_changed = true;
 	      update_stmt (stmt);
 	    }
 
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index 26cd65f..7aac67d 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -1391,7 +1391,7 @@ gimple_ic (gcall *icall_stmt, struct cgraph_node *direct_call,
   gcall *dcall_stmt;
   gassign *load_stmt;
   gcond *cond_stmt;
-  gimple iretbnd_stmt = NULL;
+  gcall *iretbnd_stmt = NULL;
   tree tmp0, tmp1, tmp;
   basic_block cond_bb, dcall_bb, icall_bb, join_bb = NULL;
   tree optype = build_pointer_type (void_type_node);
@@ -1400,7 +1400,7 @@ gimple_ic (gcall *icall_stmt, struct cgraph_node *direct_call,
   int lp_nr, dflags;
   edge e_eh, e;
   edge_iterator ei;
-  gphi_iterator psi;
+  gimple_stmt_iterator psi;
 
   cond_bb = gimple_bb (icall_stmt);
   gsi = gsi_for_stmt (icall_stmt);
@@ -1557,7 +1557,7 @@ gimple_ic (gcall *icall_stmt, struct cgraph_node *direct_call,
     if (e_eh->flags & (EDGE_EH | EDGE_ABNORMAL))
       {
 	e = make_edge (dcall_bb, e_eh->dest, e_eh->flags);
-	for (psi = gsi_start_phis (e_eh->dest);
+	for (gphi_iterator psi = gsi_start_phis (e_eh->dest);
 	     !gsi_end_p (psi); gsi_next (&psi))
 	  {
 	    gphi *phi = psi.phi ();
-- 
1.8.5.3


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] Add gimple-compat.h (was Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign)
  2014-11-14 15:44                   ` [PATCH] Add gimple-compat.h (was Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign) David Malcolm
@ 2014-11-17  9:54                     ` Richard Biener
  2014-11-17 19:44                     ` Jeff Law
  1 sibling, 0 replies; 36+ messages in thread
From: Richard Biener @ 2014-11-17  9:54 UTC (permalink / raw)
  To: David Malcolm; +Cc: Jakub Jelinek, GCC Patches, GCC Development, Jeff Law

On Fri, Nov 14, 2014 at 4:27 PM, David Malcolm <dmalcolm@redhat.com> wrote:
> On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote:
>> On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm <dmalcolm@redhat.com> wrote:
>> > On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
>> >> On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>> >> > On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
>> >> >> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
>> >> >> > On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
>> >> >> > > To be constructive here - the above case is from within a
>> >> >> > > GIMPLE_ASSIGN case label
>> >> >> > > and thus I'd have expected
>> >> >> > >
>> >> >> > >     case GIMPLE_ASSIGN:
>> >> >> > >       {
>> >> >> > >         gassign *a1 = as_a <gassign *> (s1);
>> >> >> > >         gassign *a2 = as_a <gassign *> (s2);
>> >> >> > >       lhs1 = gimple_assign_lhs (a1);
>> >> >> > >       lhs2 = gimple_assign_lhs (a2);
>> >> >> > >       if (TREE_CODE (lhs1) != SSA_NAME
>> >> >> > >           && TREE_CODE (lhs2) != SSA_NAME)
>> >> >> > >         return (operand_equal_p (lhs1, lhs2, 0)
>> >> >> > >                 && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
>> >> >> > >                                                  gimple_assign_rhs1 (a2)));
>> >> >> > >       else if (TREE_CODE (lhs1) == SSA_NAME
>> >> >> > >                && TREE_CODE (lhs2) == SSA_NAME)
>> >> >> > >         return vn_valueize (lhs1) == vn_valueize (lhs2);
>> >> >> > >       return false;
>> >> >> > >       }
>> >> >> > >
>> >> >> > > instead.  That's the kind of changes I have expected and have approved of.
>> >> >> >
>> >> >> > But even that looks like just adding extra work for all developers, with no
>> >> >> > gain.  You only have to add extra code and extra temporaries, in switches
>> >> >> > typically also have to add {} because of the temporaries and thus extra
>> >> >> > indentation level, and it doesn't simplify anything in the code.
>> >> >>
>> >> >> The branch attempts to use the C++ typesystem to capture information
>> >> >> about the kinds of gimple statement we expect, both:
>> >> >>   (A) so that the compiler can detect type errors, and
>> >> >>   (B) as a comprehension aid to the human reader of the code
>> >> >>
>> >> >> The ideal here is when function params and struct field can be
>> >> >> strengthened from "gimple" to a subclass ptr.  This captures the
>> >> >> knowledge that every use of a function or within a struct has a given
>> >> >> gimple code.
>> >> >
>> >> > I just don't like all the as_a/is_a stuff enforced everywhere,
>> >> > it means more typing, more temporaries, more indentation.
>> >> > So, as I view it, instead of the checks being done cheaply (yes, I think
>> >> > the gimple checking as we have right now is very cheap) under the
>> >> > hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
>> >> > put the burden on the developers, who has to check that manually through
>> >> > the as_a/is_a stuff everywhere, more typing and uglier syntax.
>> >> > I just don't see that as a step forward, instead a huge step backwards.
>> >> > But perhaps I'm alone with this.
>> >> > Can you e.g. compare the size of - lines in your patchset combined, and
>> >> > size of + lines in your patchset?  As in, if your changes lead to less
>> >> > typing or more.
>> >>
>> >> I see two ways out here.  One is to add overloads to all the functions
>> >> taking the special types like
>> >>
>> >> tree
>> >> gimple_assign_rhs1 (gimple *);
>> >>
>> >> or simply add
>> >>
>> >> gassign *operator ()(gimple *g) { return as_a <gassign *> (g); }
>> >>
>> >> into a gimple-compat.h header which you include in places that
>> >> are not converted "nicely".
>> >
>> > Thanks for the suggestions.
>> >
>> > Am I missing something, or is the gimple-compat.h idea above not valid C
>> > ++?
>> >
>> > Note that "gimple" is still a typedef to
>> >   gimple_statement_base *
>> > (as noted before, the gimple -> gimple * change would break everyone
>> > else's patches, so we talked about that as a followup patch for early
>> > stage3).
>> >
>> > Given that, if I try to create an "operator ()" outside of a class, I
>> > get this error:
>> >
>> > ‘gassign* operator()(gimple)’ must be a nonstatic member function
>> >
>> > which is emitted from cp/decl.c's grok_op_properties:
>> >       /* An operator function must either be a non-static member function
>> >          or have at least one parameter of a class, a reference to a class,
>> >          an enumeration, or a reference to an enumeration.  13.4.0.6 */
>> >
>> > I tried making it a member function of gimple_statement_base, but that
>> > doesn't work either: we want a conversion
>> >   from a gimple_statement_base * to a gassign *, not
>> >   from a gimple_statement_base   to a gassign *.
>> >
>> > Is there some syntactic trick here that I'm missing?  Sorry if I'm being
>> > dumb (I can imagine there's a way of doing it by making "gimple" become
>> > some kind of wrapped ptr class, but that way lies madness, surely).
>>
>> Hmm.
>>
>> struct assign;
>> struct base {
>>   operator assign *() const { return (assign *)this; }
>> };
>> struct assign : base {
>> };
>>
>> void foo (assign *);
>> void bar (base *b)
>> {
>>   foo (b);
>> }
>>
>> doesn't work, but
>>
>> void bar (base &b)
>> {
>>   foo (b);
>> }
>>
>> does.  Indeed C++ doesn't seem to provide what is necessary
>> for the compat trick :(
>>
>> So the gimple-compat.h header would need to provide
>> additional overloads for the affected functions like
>>
>> inline tree
>> gimple_assign_rhs1 (gimple *g)
>> {
>>   return gimple_assign_rhs1 (as_a <gassign *> (g));
>> }
>>
>> that would work for me as well.
>>
>> >> Both avoid manually making the compiler happy (which the
>> >> explicit as_a<> stuff is!  It doesn't add any "checking" - it's
>> >> just placing the as_a<> at the callers and thus make the
>> >> runtine ICE fire there).
>> >>
>> >> As much as I don't like "global" conversion operators I don't
>> >> like adding overloads to all of the accessor functions even more.
>> >
>> > (nods)
>> >
>> > Some other options:
>> >
>> > Option 3: only convert the "easy" accessors: the ones I already did in
>> > the /89 patch kit, as reviewed by Jeff, and rebased by me recently,
>> > which is this 92-patch kit:
>> >   "[gimple-classes, committed 00/92] Initial slew of commits":
>> >      https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html
>> > Doing so converts about half of the gimple_foo_ accessors to taking a
>> > gfoo *, giving a mixture of GIMPLE_CHECK vs subclass use.   I believe
>> > the quality of those patches was higher than the later ones on the
>> > branch: I was doing the places that didn't require the invasive/verbose
>> > changes seen in the later patches.  Shelve the remaining ~80
>> > increasingly ugly patches, starting a new branch to contain just the
>> > good ones.
>> >
>> >
>> > Option 4: don't convert any accessors, but instead focus on fields of
>> > structs (e.g. "call_stmt" within a cgraph_edge), and on params of other
>> > functions (e.g. phi-manipulation code).  That way we'd avoid the
>> > inconsistency of some accessors using GIMPLE_CHECK and some using
>> > subclasses - all would continue to consistently use GIMPLE_CHECK, but
>> > there would be some extra type-checking and self-documentation of the
>> > expected statement kinds in the code.
>> >
>> >
>> >
>> > FWIW, option 3 is my preferred approach (I've already done the bulk of
>> > the work and it's already been reviewed; it would need an update merger
>> > from trunk, and there's the big gimple to gimple * fixup you wanted).
>>
>> Works for me as well.  The compat solution looks somewhat appealing
>> as we can then incrementally fix up things rather than requiring to
>> mass-convert everything.
>>
>> Thanks,
>> Richard.
>
> I still prefer option 3 above (i.e. go with the patches Jeff reviewed,
> with the fixups discussed earlier, with a merger from trunk), but I had
> a go at implementing your gimple-compat.h idea.
>
> Attached is a patch against e74b2ecd78d21fc7bcc2f50dacc92819e0e69e6b on
> the gimple-classes branch (the last commit before I went overboard with
> the as_a changes), which converts the remaining gimple_assign_ accessors
> to take a gassign *, adding a gimple-compat.h to provide overloaded
> accessors taking just a gimple for those source files that needed them.
> It also strengthens some places I spotted where converting params,
> locals or fields from gimple to gassign * was simple and obvious.

Thanks.

> Successfully bootstrapped&regrtested on x86_64-unknown-linux-gnu,
> comparing the branch+patch against master r216746 (2014-10-27).
>
> This only covers gimple_assign_; it would still be a hybrid of is-a and
> GIMPLE_CHECK unless I extended the patch to cover all the other
> accessors.
>
> Do you want me to continue converting things for gimple-compat.h to see
> what a set of patches for that approach looks like?

I think it would be reasonable to try pushing things a bit further - esp.
providing the strongly typed interfaces by default to make new code
"forcibly" use that.

> If so, would it be better to split things out and have a
> gimple-compat-assign.h, gimple-compat-call.h etc rather than one big
> gimple-compat.h?

No, I think one gimple-compat.h is enough.

> That said, I still prefer option 3.

I think it's fine to push option 3 now (thus commit that).  I think
doing the gimple-compat.h in addition would be nice.

Thanks,
Richard.

>
>> >> Whether you enable them generally or just for selected files
>> >> via a gimple-compat.h will be up to you (but I'd rather get
>> >> rid of them at some point).
>> >>
>> >> Note this allows seamless transform of "random" functions
>> >> taking a gimple now but really only expecting a single kind.
>> >>
>> >> Note that we don't absolutely have to rush this all in for GCC 5.
>> >> Being the very first for GCC 6 stage1 is another possibility.
>> >> We just should get it right.
>> >
>> > Thanks
>> > Dave
>> >
>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-15 11:58                   ` [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign David Malcolm
@ 2014-11-17 10:23                     ` Richard Biener
  2014-11-17 19:49                       ` Jeff Law
  2014-11-18  2:40                       ` David Malcolm
  0 siblings, 2 replies; 36+ messages in thread
From: Richard Biener @ 2014-11-17 10:23 UTC (permalink / raw)
  To: David Malcolm; +Cc: Jakub Jelinek, GCC Patches, GCC Development, Jeff Law

On Sat, Nov 15, 2014 at 12:00 PM, David Malcolm <dmalcolm@redhat.com> wrote:
> On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote:
>> On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm <dmalcolm@redhat.com> wrote:
>> > On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
>> >> On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>> >> > On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
>> >> >> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
>> >> >> > On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
>> >> >> > > To be constructive here - the above case is from within a
>> >> >> > > GIMPLE_ASSIGN case label
>> >> >> > > and thus I'd have expected
>> >> >> > >
>> >> >> > >     case GIMPLE_ASSIGN:
>> >> >> > >       {
>> >> >> > >         gassign *a1 = as_a <gassign *> (s1);
>> >> >> > >         gassign *a2 = as_a <gassign *> (s2);
>> >> >> > >       lhs1 = gimple_assign_lhs (a1);
>> >> >> > >       lhs2 = gimple_assign_lhs (a2);
>> >> >> > >       if (TREE_CODE (lhs1) != SSA_NAME
>> >> >> > >           && TREE_CODE (lhs2) != SSA_NAME)
>> >> >> > >         return (operand_equal_p (lhs1, lhs2, 0)
>> >> >> > >                 && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
>> >> >> > >                                                  gimple_assign_rhs1 (a2)));
>> >> >> > >       else if (TREE_CODE (lhs1) == SSA_NAME
>> >> >> > >                && TREE_CODE (lhs2) == SSA_NAME)
>> >> >> > >         return vn_valueize (lhs1) == vn_valueize (lhs2);
>> >> >> > >       return false;
>> >> >> > >       }
>> >> >> > >
>> >> >> > > instead.  That's the kind of changes I have expected and have approved of.
>> >> >> >
>> >> >> > But even that looks like just adding extra work for all developers, with no
>> >> >> > gain.  You only have to add extra code and extra temporaries, in switches
>> >> >> > typically also have to add {} because of the temporaries and thus extra
>> >> >> > indentation level, and it doesn't simplify anything in the code.
>> >> >>
>> >> >> The branch attempts to use the C++ typesystem to capture information
>> >> >> about the kinds of gimple statement we expect, both:
>> >> >>   (A) so that the compiler can detect type errors, and
>> >> >>   (B) as a comprehension aid to the human reader of the code
>> >> >>
>> >> >> The ideal here is when function params and struct field can be
>> >> >> strengthened from "gimple" to a subclass ptr.  This captures the
>> >> >> knowledge that every use of a function or within a struct has a given
>> >> >> gimple code.
>> >> >
>> >> > I just don't like all the as_a/is_a stuff enforced everywhere,
>> >> > it means more typing, more temporaries, more indentation.
>> >> > So, as I view it, instead of the checks being done cheaply (yes, I think
>> >> > the gimple checking as we have right now is very cheap) under the
>> >> > hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
>> >> > put the burden on the developers, who has to check that manually through
>> >> > the as_a/is_a stuff everywhere, more typing and uglier syntax.
>> >> > I just don't see that as a step forward, instead a huge step backwards.
>> >> > But perhaps I'm alone with this.
>> >> > Can you e.g. compare the size of - lines in your patchset combined, and
>> >> > size of + lines in your patchset?  As in, if your changes lead to less
>> >> > typing or more.
>> >>
>> >> I see two ways out here.  One is to add overloads to all the functions
>> >> taking the special types like
>> >>
>> >> tree
>> >> gimple_assign_rhs1 (gimple *);
>> >>
>> >> or simply add
>> >>
>> >> gassign *operator ()(gimple *g) { return as_a <gassign *> (g); }
>> >>
>> >> into a gimple-compat.h header which you include in places that
>> >> are not converted "nicely".
>> >
>> > Thanks for the suggestions.
>> >
>> > Am I missing something, or is the gimple-compat.h idea above not valid C
>> > ++?
>> >
>> > Note that "gimple" is still a typedef to
>> >   gimple_statement_base *
>> > (as noted before, the gimple -> gimple * change would break everyone
>> > else's patches, so we talked about that as a followup patch for early
>> > stage3).
>> >
>> > Given that, if I try to create an "operator ()" outside of a class, I
>> > get this error:
>> >
>> > ‘gassign* operator()(gimple)’ must be a nonstatic member function
>> >
>> > which is emitted from cp/decl.c's grok_op_properties:
>> >       /* An operator function must either be a non-static member function
>> >          or have at least one parameter of a class, a reference to a class,
>> >          an enumeration, or a reference to an enumeration.  13.4.0.6 */
>> >
>> > I tried making it a member function of gimple_statement_base, but that
>> > doesn't work either: we want a conversion
>> >   from a gimple_statement_base * to a gassign *, not
>> >   from a gimple_statement_base   to a gassign *.
>> >
>> > Is there some syntactic trick here that I'm missing?  Sorry if I'm being
>> > dumb (I can imagine there's a way of doing it by making "gimple" become
>> > some kind of wrapped ptr class, but that way lies madness, surely).
>>
>> Hmm.
>>
>> struct assign;
>> struct base {
>>   operator assign *() const { return (assign *)this; }
>> };
>> struct assign : base {
>> };
>>
>> void foo (assign *);
>> void bar (base *b)
>> {
>>   foo (b);
>> }
>>
>> doesn't work, but
>>
>> void bar (base &b)
>> {
>>   foo (b);
>> }
>>
>> does.  Indeed C++ doesn't seem to provide what is necessary
>> for the compat trick :(
>>
>> So the gimple-compat.h header would need to provide
>> additional overloads for the affected functions like
>>
>> inline tree
>> gimple_assign_rhs1 (gimple *g)
>> {
>>   return gimple_assign_rhs1 (as_a <gassign *> (g));
>> }
>>
>> that would work for me as well.
>>
>> >> Both avoid manually making the compiler happy (which the
>> >> explicit as_a<> stuff is!  It doesn't add any "checking" - it's
>> >> just placing the as_a<> at the callers and thus make the
>> >> runtine ICE fire there).
>> >>
>> >> As much as I don't like "global" conversion operators I don't
>> >> like adding overloads to all of the accessor functions even more.
>> >
>> > (nods)
>> >
>> > Some other options:
>> >
>> > Option 3: only convert the "easy" accessors: the ones I already did in
>> > the /89 patch kit, as reviewed by Jeff, and rebased by me recently,
>> > which is this 92-patch kit:
>> >   "[gimple-classes, committed 00/92] Initial slew of commits":
>> >      https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html
>> > Doing so converts about half of the gimple_foo_ accessors to taking a
>> > gfoo *, giving a mixture of GIMPLE_CHECK vs subclass use.   I believe
>> > the quality of those patches was higher than the later ones on the
>> > branch: I was doing the places that didn't require the invasive/verbose
>> > changes seen in the later patches.  Shelve the remaining ~80
>> > increasingly ugly patches, starting a new branch to contain just the
>> > good ones.
>
> I've created a branch "dmalcolm/gimple-classes-v2-option-3"
> https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/gimple-classes-v2-option-3
>
> which takes the work reviewed by Jeff and the most trivial of the merger
> followup work, throwing away the ~80 unloved followup patches on
> dmalcolm/gimple-classes.
>
> I've merged from yesterday's trunk r217593 into that new branch,
> resolving conflicts.
>
> I did this in two parts: the basic merger as
>   bd7fe714158f0c600caa05be7d744fd9139b8afb
> resolving conflicts, with a followup patch to fixup new code from trunk
> that used accessors that on the branch required a gimple subclass.
>
> Attached is that 2nd part of the merger.
>
> Successfully bootstrapped and regrtested on x86_64-unknown-linux-gnu;
> same regrtest results as a control bootstrap of trunk's r217593.
>
> I appreciate Jakub and others have concerns about the overall approach.
> I'm not sure which of option 2 (gimple-compat.h), option 3 (this one),
> option 4 (just convert fields and non-accessor params), or defer to gcc
> 6 is the best one, but I'm sleep-deprived and wanted to submit this
> before the stage1 deadline.
>
> The other commits on this pruned branch that haven't been reviewed yet
> are:
>
> [gimple-classes, committed 88/92] Preparatory work before subclass
> renaming
>   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02820.html

Ok.

> [gimple-classes, committed 89/92] Eliminate subclass typedefs from
> coretypes.h
>   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02838.html

Ok.

> [gimple-classes, committed 90/92] Automated renaming of gimple
> subclasses
>   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02828.html

Ok.

> [gimple-classes, committed 91/92] Remove out-of-date references to
> typedefs]
>   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02874.html

Ok.

> [gimple-classes, committed 92/92] Update gimple.texi class hierarchy
> diagram
>   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02818.html

Ok.

> [gimple-classes] Merge trunk r216157-r216746 into branch
>   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02982.html

Ok.

> Also, presumably if this were merged, it would require a followup with
> the gimple to gimple * fixup you wanted? (which we talked about doing as
> an early stage3 thing IIRC [1]).

Yeah, that would be nice (to remind people - this is about getting rid
of const_gimple and thus avoids introducing tons of new const_
for all the subclasses).

Thanks,
Richard.

> Thanks
> Dave
> [1] e.g. https://gcc.gnu.org/ml/gcc-patches/2014-10/msg01536.html
>
>
>> > Option 4: don't convert any accessors, but instead focus on fields of
>> > structs (e.g. "call_stmt" within a cgraph_edge), and on params of other
>> > functions (e.g. phi-manipulation code).  That way we'd avoid the
>> > inconsistency of some accessors using GIMPLE_CHECK and some using
>> > subclasses - all would continue to consistently use GIMPLE_CHECK, but
>> > there would be some extra type-checking and self-documentation of the
>> > expected statement kinds in the code.
>> >
>> >
>> >
>> > FWIW, option 3 is my preferred approach (I've already done the bulk of
>> > the work and it's already been reviewed; it would need an update merger
>> > from trunk, and there's the big gimple to gimple * fixup you wanted).
>>
>> Works for me as well.  The compat solution looks somewhat appealing
>> as we can then incrementally fix up things rather than requiring to
>> mass-convert everything.
>>
>> Thanks,
>> Richard.
>>
>> >> Whether you enable them generally or just for selected files
>> >> via a gimple-compat.h will be up to you (but I'd rather get
>> >> rid of them at some point).
>> >>
>> >> Note this allows seamless transform of "random" functions
>> >> taking a gimple now but really only expecting a single kind.
>> >>
>> >> Note that we don't absolutely have to rush this all in for GCC 5.
>> >> Being the very first for GCC 6 stage1 is another possibility.
>> >> We just should get it right.
>> >
>> > Thanks
>> > Dave
>> >
>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] Add gimple-compat.h (was Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign)
  2014-11-14 15:44                   ` [PATCH] Add gimple-compat.h (was Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign) David Malcolm
  2014-11-17  9:54                     ` Richard Biener
@ 2014-11-17 19:44                     ` Jeff Law
  1 sibling, 0 replies; 36+ messages in thread
From: Jeff Law @ 2014-11-17 19:44 UTC (permalink / raw)
  To: David Malcolm, Richard Biener; +Cc: Jakub Jelinek, GCC Patches, GCC Development

On 11/14/14 08:27, David Malcolm wrote:
>>>>>
>>>>> I just don't like all the as_a/is_a stuff enforced everywhere,
>>>>> it means more typing, more temporaries, more indentation.
>>>>> So, as I view it, instead of the checks being done cheaply (yes, I think
>>>>> the gimple checking as we have right now is very cheap) under the
>>>>> hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
>>>>> put the burden on the developers, who has to check that manually through
>>>>> the as_a/is_a stuff everywhere, more typing and uglier syntax.
>>>>> I just don't see that as a step forward, instead a huge step backwards.
>>>>> But perhaps I'm alone with this.
>>>>> Can you e.g. compare the size of - lines in your patchset combined, and
>>>>> size of + lines in your patchset?  As in, if your changes lead to less
>>>>> typing or more.
So, I'm chiming in a bit late, but just want to touch on a few things.

First, as I've stated before, I see as_a/is_a as generally a wart for 
things we still need to cleanup and redesign.  I do not want to see them 
sprinkled throughout GCC.  If we find ourselves adding a bunch of these, 
then we've got some redesign/rethinking that needs to be done.

Yes, I know some will be necessary and some are more like markers for 
the limits of where we are with the gimple class work, particularly 
since we're trying to stage in this work rather than convert everything 
at once (which I believe, realistically, is impossible).


>>>>
>>>> I see two ways out here.  One is to add overloads to all the functions
>>>> taking the special types like
IIRC Andrew was doing similar things as a temporary measure in the 
gimple/tree type work as well.  Basically the overloads were to allow 
the two schemes to co-exist while conversions were done with the express 
intent that the overloads were to disappear when conversion is complete. 
  I'd be comfortable with a similar mechanism for this work as well.

>>>
>>> Option 3: only convert the "easy" accessors: the ones I already did in
>>> the /89 patch kit, as reviewed by Jeff, and rebased by me recently,
>>> which is this 92-patch kit:
>>>    "[gimple-classes, committed 00/92] Initial slew of commits":
>>>       https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html
>>> Doing so converts about half of the gimple_foo_ accessors to taking a
>>> gfoo *, giving a mixture of GIMPLE_CHECK vs subclass use.   I believe
>>> the quality of those patches was higher than the later ones on the
>>> branch: I was doing the places that didn't require the invasive/verbose
>>> changes seen in the later patches.  Shelve the remaining ~80
>>> increasingly ugly patches, starting a new branch to contain just the
>>> good ones.
And this would be my preferred option for where we are today.  That ~89 
kit was a step in the right direction.  I think going beyond that for 
the close of stage1 was ambitious :-)

>>
>> Works for me as well.  The compat solution looks somewhat appealing
>> as we can then incrementally fix up things rather than requiring to
>> mass-convert everything.
Exactly.  And it's real easy to see what's depending on those overloads 
as one can simply remove them and try to build.  In many ways, I'd 
prefer the temporary overload solution for the next round of work in 
this space so that conversions can occur piecemeal instead of in large 
series patchsets.

I've got no objection if we have the compat hack in now.   I haven't 
reviewed that work, just no philosophical objections :-)  I would be 
opposed to pushing the gimple class work further than that prior to the 
next stage1 opening.


jeff

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-17 10:23                     ` Richard Biener
@ 2014-11-17 19:49                       ` Jeff Law
  2014-11-18  2:40                       ` David Malcolm
  1 sibling, 0 replies; 36+ messages in thread
From: Jeff Law @ 2014-11-17 19:49 UTC (permalink / raw)
  To: Richard Biener, David Malcolm; +Cc: Jakub Jelinek, GCC Patches, GCC Development

On 11/17/14 03:06, Richard Biener wrote:


>
>> Also, presumably if this were merged, it would require a followup with
>> the gimple to gimple * fixup you wanted? (which we talked about doing as
>> an early stage3 thing IIRC [1]).
>
> Yeah, that would be nice (to remind people - this is about getting rid
> of const_gimple and thus avoids introducing tons of new const_
> for all the subclasses).
Right.  Mirrors what we've done for INSNs in RTL as well.

jeff

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-17 10:23                     ` Richard Biener
  2014-11-17 19:49                       ` Jeff Law
@ 2014-11-18  2:40                       ` David Malcolm
  2014-11-18 10:02                         ` Richard Biener
  1 sibling, 1 reply; 36+ messages in thread
From: David Malcolm @ 2014-11-18  2:40 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jakub Jelinek, GCC Patches, GCC Development, Jeff Law

On Mon, 2014-11-17 at 11:06 +0100, Richard Biener wrote:
> On Sat, Nov 15, 2014 at 12:00 PM, David Malcolm <dmalcolm@redhat.com> wrote:
> > On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote:
> >> On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm <dmalcolm@redhat.com> wrote:
> >> > On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
> >> >> On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> >> >> > On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
> >> >> >> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
> >> >> >> > On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
> >> >> >> > > To be constructive here - the above case is from within a
> >> >> >> > > GIMPLE_ASSIGN case label
> >> >> >> > > and thus I'd have expected
> >> >> >> > >
> >> >> >> > >     case GIMPLE_ASSIGN:
> >> >> >> > >       {
> >> >> >> > >         gassign *a1 = as_a <gassign *> (s1);
> >> >> >> > >         gassign *a2 = as_a <gassign *> (s2);
> >> >> >> > >       lhs1 = gimple_assign_lhs (a1);
> >> >> >> > >       lhs2 = gimple_assign_lhs (a2);
> >> >> >> > >       if (TREE_CODE (lhs1) != SSA_NAME
> >> >> >> > >           && TREE_CODE (lhs2) != SSA_NAME)
> >> >> >> > >         return (operand_equal_p (lhs1, lhs2, 0)
> >> >> >> > >                 && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
> >> >> >> > >                                                  gimple_assign_rhs1 (a2)));
> >> >> >> > >       else if (TREE_CODE (lhs1) == SSA_NAME
> >> >> >> > >                && TREE_CODE (lhs2) == SSA_NAME)
> >> >> >> > >         return vn_valueize (lhs1) == vn_valueize (lhs2);
> >> >> >> > >       return false;
> >> >> >> > >       }
> >> >> >> > >
> >> >> >> > > instead.  That's the kind of changes I have expected and have approved of.
> >> >> >> >
> >> >> >> > But even that looks like just adding extra work for all developers, with no
> >> >> >> > gain.  You only have to add extra code and extra temporaries, in switches
> >> >> >> > typically also have to add {} because of the temporaries and thus extra
> >> >> >> > indentation level, and it doesn't simplify anything in the code.
> >> >> >>
> >> >> >> The branch attempts to use the C++ typesystem to capture information
> >> >> >> about the kinds of gimple statement we expect, both:
> >> >> >>   (A) so that the compiler can detect type errors, and
> >> >> >>   (B) as a comprehension aid to the human reader of the code
> >> >> >>
> >> >> >> The ideal here is when function params and struct field can be
> >> >> >> strengthened from "gimple" to a subclass ptr.  This captures the
> >> >> >> knowledge that every use of a function or within a struct has a given
> >> >> >> gimple code.
> >> >> >
> >> >> > I just don't like all the as_a/is_a stuff enforced everywhere,
> >> >> > it means more typing, more temporaries, more indentation.
> >> >> > So, as I view it, instead of the checks being done cheaply (yes, I think
> >> >> > the gimple checking as we have right now is very cheap) under the
> >> >> > hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
> >> >> > put the burden on the developers, who has to check that manually through
> >> >> > the as_a/is_a stuff everywhere, more typing and uglier syntax.
> >> >> > I just don't see that as a step forward, instead a huge step backwards.
> >> >> > But perhaps I'm alone with this.
> >> >> > Can you e.g. compare the size of - lines in your patchset combined, and
> >> >> > size of + lines in your patchset?  As in, if your changes lead to less
> >> >> > typing or more.
> >> >>
> >> >> I see two ways out here.  One is to add overloads to all the functions
> >> >> taking the special types like
> >> >>
> >> >> tree
> >> >> gimple_assign_rhs1 (gimple *);
> >> >>
> >> >> or simply add
> >> >>
> >> >> gassign *operator ()(gimple *g) { return as_a <gassign *> (g); }
> >> >>
> >> >> into a gimple-compat.h header which you include in places that
> >> >> are not converted "nicely".
> >> >
> >> > Thanks for the suggestions.
> >> >
> >> > Am I missing something, or is the gimple-compat.h idea above not valid C
> >> > ++?
> >> >
> >> > Note that "gimple" is still a typedef to
> >> >   gimple_statement_base *
> >> > (as noted before, the gimple -> gimple * change would break everyone
> >> > else's patches, so we talked about that as a followup patch for early
> >> > stage3).
> >> >
> >> > Given that, if I try to create an "operator ()" outside of a class, I
> >> > get this error:
> >> >
> >> > ‘gassign* operator()(gimple)’ must be a nonstatic member function
> >> >
> >> > which is emitted from cp/decl.c's grok_op_properties:
> >> >       /* An operator function must either be a non-static member function
> >> >          or have at least one parameter of a class, a reference to a class,
> >> >          an enumeration, or a reference to an enumeration.  13.4.0.6 */
> >> >
> >> > I tried making it a member function of gimple_statement_base, but that
> >> > doesn't work either: we want a conversion
> >> >   from a gimple_statement_base * to a gassign *, not
> >> >   from a gimple_statement_base   to a gassign *.
> >> >
> >> > Is there some syntactic trick here that I'm missing?  Sorry if I'm being
> >> > dumb (I can imagine there's a way of doing it by making "gimple" become
> >> > some kind of wrapped ptr class, but that way lies madness, surely).
> >>
> >> Hmm.
> >>
> >> struct assign;
> >> struct base {
> >>   operator assign *() const { return (assign *)this; }
> >> };
> >> struct assign : base {
> >> };
> >>
> >> void foo (assign *);
> >> void bar (base *b)
> >> {
> >>   foo (b);
> >> }
> >>
> >> doesn't work, but
> >>
> >> void bar (base &b)
> >> {
> >>   foo (b);
> >> }
> >>
> >> does.  Indeed C++ doesn't seem to provide what is necessary
> >> for the compat trick :(
> >>
> >> So the gimple-compat.h header would need to provide
> >> additional overloads for the affected functions like
> >>
> >> inline tree
> >> gimple_assign_rhs1 (gimple *g)
> >> {
> >>   return gimple_assign_rhs1 (as_a <gassign *> (g));
> >> }
> >>
> >> that would work for me as well.
> >>
> >> >> Both avoid manually making the compiler happy (which the
> >> >> explicit as_a<> stuff is!  It doesn't add any "checking" - it's
> >> >> just placing the as_a<> at the callers and thus make the
> >> >> runtine ICE fire there).
> >> >>
> >> >> As much as I don't like "global" conversion operators I don't
> >> >> like adding overloads to all of the accessor functions even more.
> >> >
> >> > (nods)
> >> >
> >> > Some other options:
> >> >
> >> > Option 3: only convert the "easy" accessors: the ones I already did in
> >> > the /89 patch kit, as reviewed by Jeff, and rebased by me recently,
> >> > which is this 92-patch kit:
> >> >   "[gimple-classes, committed 00/92] Initial slew of commits":
> >> >      https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html
> >> > Doing so converts about half of the gimple_foo_ accessors to taking a
> >> > gfoo *, giving a mixture of GIMPLE_CHECK vs subclass use.   I believe
> >> > the quality of those patches was higher than the later ones on the
> >> > branch: I was doing the places that didn't require the invasive/verbose
> >> > changes seen in the later patches.  Shelve the remaining ~80
> >> > increasingly ugly patches, starting a new branch to contain just the
> >> > good ones.
> >
> > I've created a branch "dmalcolm/gimple-classes-v2-option-3"
> > https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/gimple-classes-v2-option-3
> >
> > which takes the work reviewed by Jeff and the most trivial of the merger
> > followup work, throwing away the ~80 unloved followup patches on
> > dmalcolm/gimple-classes.
> >
> > I've merged from yesterday's trunk r217593 into that new branch,
> > resolving conflicts.
> >
> > I did this in two parts: the basic merger as
> >   bd7fe714158f0c600caa05be7d744fd9139b8afb
> > resolving conflicts, with a followup patch to fixup new code from trunk
> > that used accessors that on the branch required a gimple subclass.
> >
> > Attached is that 2nd part of the merger.
> >
> > Successfully bootstrapped and regrtested on x86_64-unknown-linux-gnu;
> > same regrtest results as a control bootstrap of trunk's r217593.
> >
> > I appreciate Jakub and others have concerns about the overall approach.
> > I'm not sure which of option 2 (gimple-compat.h), option 3 (this one),
> > option 4 (just convert fields and non-accessor params), or defer to gcc
> > 6 is the best one, but I'm sleep-deprived and wanted to submit this
> > before the stage1 deadline.
> >
> > The other commits on this pruned branch that haven't been reviewed yet
> > are:
> >
> > [gimple-classes, committed 88/92] Preparatory work before subclass
> > renaming
> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02820.html
> 
> Ok.
> 
> > [gimple-classes, committed 89/92] Eliminate subclass typedefs from
> > coretypes.h
> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02838.html
> 
> Ok.
> 
> > [gimple-classes, committed 90/92] Automated renaming of gimple
> > subclasses
> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02828.html
> 
> Ok.
> 
> > [gimple-classes, committed 91/92] Remove out-of-date references to
> > typedefs]
> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02874.html
> 
> Ok.
> 
> > [gimple-classes, committed 92/92] Update gimple.texi class hierarchy
> > diagram
> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02818.html
> 
> Ok.
> 
> > [gimple-classes] Merge trunk r216157-r216746 into branch
> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02982.html
> 
> Ok.

Thanks.  You said "Ok" to the various patches I pinged, but I don't
think you commented on the patch that was attached to the email.

Is that one OK?  It's:
 https://gcc.gnu.org/ml/gcc-patches/2014-11/msg01935.html
in the archives.

I believe that's the only unreviewed patch on the branch
"dmalcolm/gimple-classes-v2-option-3":
https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/gimple-classes-v2-option-3

Assuming that's OK, I want to merge that branch to trunk in the next day
or so.

> > Also, presumably if this were merged, it would require a followup with
> > the gimple to gimple * fixup you wanted? (which we talked about doing as
> > an early stage3 thing IIRC [1]).
> 
> Yeah, that would be nice (to remind people - this is about getting rid
> of const_gimple and thus avoids introducing tons of new const_
> for all the subclasses).

FWIW I got rid of all of those typedefs in the patches above (89/92 in
particular); the subclasses on the branch are already using explicit
ptrs, so it's more about consistency between base class ptrs and
subclass ptrs, to avoid:

  gimple  stmt;
  gphi   *phi;
  gcall  *call_stmt;

in favor of:
  gimple *stmt;  /* <-- note this one */
  gphi   *phi;
  gcall  *call_stmt;


I'd already done that for the subclasses on the branch, and the diff
between the branch and trunk is relatively sane.

By contrast, doing the gimple -> gimple * fixup will generate a huge
diff, so that's something to do after merging the branch.
I'll post the patch here later this week (or a link to it, it's likely
to be too big even compressed for the ML).

Dave

> Thanks,
> Richard.
> 
> > Thanks
> > Dave
> > [1] e.g. https://gcc.gnu.org/ml/gcc-patches/2014-10/msg01536.html
> >
> >
> >> > Option 4: don't convert any accessors, but instead focus on fields of
> >> > structs (e.g. "call_stmt" within a cgraph_edge), and on params of other
> >> > functions (e.g. phi-manipulation code).  That way we'd avoid the
> >> > inconsistency of some accessors using GIMPLE_CHECK and some using
> >> > subclasses - all would continue to consistently use GIMPLE_CHECK, but
> >> > there would be some extra type-checking and self-documentation of the
> >> > expected statement kinds in the code.
> >> >
> >> >
> >> >
> >> > FWIW, option 3 is my preferred approach (I've already done the bulk of
> >> > the work and it's already been reviewed; it would need an update merger
> >> > from trunk, and there's the big gimple to gimple * fixup you wanted).
> >>
> >> Works for me as well.  The compat solution looks somewhat appealing
> >> as we can then incrementally fix up things rather than requiring to
> >> mass-convert everything.
> >>
> >> Thanks,
> >> Richard.
> >>
> >> >> Whether you enable them generally or just for selected files
> >> >> via a gimple-compat.h will be up to you (but I'd rather get
> >> >> rid of them at some point).
> >> >>
> >> >> Note this allows seamless transform of "random" functions
> >> >> taking a gimple now but really only expecting a single kind.
> >> >>
> >> >> Note that we don't absolutely have to rush this all in for GCC 5.
> >> >> Being the very first for GCC 6 stage1 is another possibility.
> >> >> We just should get it right.
> >> >
> >> > Thanks
> >> > Dave
> >> >
> >


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-18  2:40                       ` David Malcolm
@ 2014-11-18 10:02                         ` Richard Biener
  2014-11-18 21:19                           ` David Malcolm
  0 siblings, 1 reply; 36+ messages in thread
From: Richard Biener @ 2014-11-18 10:02 UTC (permalink / raw)
  To: David Malcolm; +Cc: Jakub Jelinek, GCC Patches, GCC Development, Jeff Law

On Tue, Nov 18, 2014 at 2:59 AM, David Malcolm <dmalcolm@redhat.com> wrote:
> On Mon, 2014-11-17 at 11:06 +0100, Richard Biener wrote:
>> On Sat, Nov 15, 2014 at 12:00 PM, David Malcolm <dmalcolm@redhat.com> wrote:
>> > On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote:
>> >> On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm <dmalcolm@redhat.com> wrote:
>> >> > On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
>> >> >> On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>> >> >> > On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
>> >> >> >> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
>> >> >> >> > On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
>> >> >> >> > > To be constructive here - the above case is from within a
>> >> >> >> > > GIMPLE_ASSIGN case label
>> >> >> >> > > and thus I'd have expected
>> >> >> >> > >
>> >> >> >> > >     case GIMPLE_ASSIGN:
>> >> >> >> > >       {
>> >> >> >> > >         gassign *a1 = as_a <gassign *> (s1);
>> >> >> >> > >         gassign *a2 = as_a <gassign *> (s2);
>> >> >> >> > >       lhs1 = gimple_assign_lhs (a1);
>> >> >> >> > >       lhs2 = gimple_assign_lhs (a2);
>> >> >> >> > >       if (TREE_CODE (lhs1) != SSA_NAME
>> >> >> >> > >           && TREE_CODE (lhs2) != SSA_NAME)
>> >> >> >> > >         return (operand_equal_p (lhs1, lhs2, 0)
>> >> >> >> > >                 && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
>> >> >> >> > >                                                  gimple_assign_rhs1 (a2)));
>> >> >> >> > >       else if (TREE_CODE (lhs1) == SSA_NAME
>> >> >> >> > >                && TREE_CODE (lhs2) == SSA_NAME)
>> >> >> >> > >         return vn_valueize (lhs1) == vn_valueize (lhs2);
>> >> >> >> > >       return false;
>> >> >> >> > >       }
>> >> >> >> > >
>> >> >> >> > > instead.  That's the kind of changes I have expected and have approved of.
>> >> >> >> >
>> >> >> >> > But even that looks like just adding extra work for all developers, with no
>> >> >> >> > gain.  You only have to add extra code and extra temporaries, in switches
>> >> >> >> > typically also have to add {} because of the temporaries and thus extra
>> >> >> >> > indentation level, and it doesn't simplify anything in the code.
>> >> >> >>
>> >> >> >> The branch attempts to use the C++ typesystem to capture information
>> >> >> >> about the kinds of gimple statement we expect, both:
>> >> >> >>   (A) so that the compiler can detect type errors, and
>> >> >> >>   (B) as a comprehension aid to the human reader of the code
>> >> >> >>
>> >> >> >> The ideal here is when function params and struct field can be
>> >> >> >> strengthened from "gimple" to a subclass ptr.  This captures the
>> >> >> >> knowledge that every use of a function or within a struct has a given
>> >> >> >> gimple code.
>> >> >> >
>> >> >> > I just don't like all the as_a/is_a stuff enforced everywhere,
>> >> >> > it means more typing, more temporaries, more indentation.
>> >> >> > So, as I view it, instead of the checks being done cheaply (yes, I think
>> >> >> > the gimple checking as we have right now is very cheap) under the
>> >> >> > hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
>> >> >> > put the burden on the developers, who has to check that manually through
>> >> >> > the as_a/is_a stuff everywhere, more typing and uglier syntax.
>> >> >> > I just don't see that as a step forward, instead a huge step backwards.
>> >> >> > But perhaps I'm alone with this.
>> >> >> > Can you e.g. compare the size of - lines in your patchset combined, and
>> >> >> > size of + lines in your patchset?  As in, if your changes lead to less
>> >> >> > typing or more.
>> >> >>
>> >> >> I see two ways out here.  One is to add overloads to all the functions
>> >> >> taking the special types like
>> >> >>
>> >> >> tree
>> >> >> gimple_assign_rhs1 (gimple *);
>> >> >>
>> >> >> or simply add
>> >> >>
>> >> >> gassign *operator ()(gimple *g) { return as_a <gassign *> (g); }
>> >> >>
>> >> >> into a gimple-compat.h header which you include in places that
>> >> >> are not converted "nicely".
>> >> >
>> >> > Thanks for the suggestions.
>> >> >
>> >> > Am I missing something, or is the gimple-compat.h idea above not valid C
>> >> > ++?
>> >> >
>> >> > Note that "gimple" is still a typedef to
>> >> >   gimple_statement_base *
>> >> > (as noted before, the gimple -> gimple * change would break everyone
>> >> > else's patches, so we talked about that as a followup patch for early
>> >> > stage3).
>> >> >
>> >> > Given that, if I try to create an "operator ()" outside of a class, I
>> >> > get this error:
>> >> >
>> >> > ‘gassign* operator()(gimple)’ must be a nonstatic member function
>> >> >
>> >> > which is emitted from cp/decl.c's grok_op_properties:
>> >> >       /* An operator function must either be a non-static member function
>> >> >          or have at least one parameter of a class, a reference to a class,
>> >> >          an enumeration, or a reference to an enumeration.  13.4.0.6 */
>> >> >
>> >> > I tried making it a member function of gimple_statement_base, but that
>> >> > doesn't work either: we want a conversion
>> >> >   from a gimple_statement_base * to a gassign *, not
>> >> >   from a gimple_statement_base   to a gassign *.
>> >> >
>> >> > Is there some syntactic trick here that I'm missing?  Sorry if I'm being
>> >> > dumb (I can imagine there's a way of doing it by making "gimple" become
>> >> > some kind of wrapped ptr class, but that way lies madness, surely).
>> >>
>> >> Hmm.
>> >>
>> >> struct assign;
>> >> struct base {
>> >>   operator assign *() const { return (assign *)this; }
>> >> };
>> >> struct assign : base {
>> >> };
>> >>
>> >> void foo (assign *);
>> >> void bar (base *b)
>> >> {
>> >>   foo (b);
>> >> }
>> >>
>> >> doesn't work, but
>> >>
>> >> void bar (base &b)
>> >> {
>> >>   foo (b);
>> >> }
>> >>
>> >> does.  Indeed C++ doesn't seem to provide what is necessary
>> >> for the compat trick :(
>> >>
>> >> So the gimple-compat.h header would need to provide
>> >> additional overloads for the affected functions like
>> >>
>> >> inline tree
>> >> gimple_assign_rhs1 (gimple *g)
>> >> {
>> >>   return gimple_assign_rhs1 (as_a <gassign *> (g));
>> >> }
>> >>
>> >> that would work for me as well.
>> >>
>> >> >> Both avoid manually making the compiler happy (which the
>> >> >> explicit as_a<> stuff is!  It doesn't add any "checking" - it's
>> >> >> just placing the as_a<> at the callers and thus make the
>> >> >> runtine ICE fire there).
>> >> >>
>> >> >> As much as I don't like "global" conversion operators I don't
>> >> >> like adding overloads to all of the accessor functions even more.
>> >> >
>> >> > (nods)
>> >> >
>> >> > Some other options:
>> >> >
>> >> > Option 3: only convert the "easy" accessors: the ones I already did in
>> >> > the /89 patch kit, as reviewed by Jeff, and rebased by me recently,
>> >> > which is this 92-patch kit:
>> >> >   "[gimple-classes, committed 00/92] Initial slew of commits":
>> >> >      https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html
>> >> > Doing so converts about half of the gimple_foo_ accessors to taking a
>> >> > gfoo *, giving a mixture of GIMPLE_CHECK vs subclass use.   I believe
>> >> > the quality of those patches was higher than the later ones on the
>> >> > branch: I was doing the places that didn't require the invasive/verbose
>> >> > changes seen in the later patches.  Shelve the remaining ~80
>> >> > increasingly ugly patches, starting a new branch to contain just the
>> >> > good ones.
>> >
>> > I've created a branch "dmalcolm/gimple-classes-v2-option-3"
>> > https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/gimple-classes-v2-option-3
>> >
>> > which takes the work reviewed by Jeff and the most trivial of the merger
>> > followup work, throwing away the ~80 unloved followup patches on
>> > dmalcolm/gimple-classes.
>> >
>> > I've merged from yesterday's trunk r217593 into that new branch,
>> > resolving conflicts.
>> >
>> > I did this in two parts: the basic merger as
>> >   bd7fe714158f0c600caa05be7d744fd9139b8afb
>> > resolving conflicts, with a followup patch to fixup new code from trunk
>> > that used accessors that on the branch required a gimple subclass.
>> >
>> > Attached is that 2nd part of the merger.
>> >
>> > Successfully bootstrapped and regrtested on x86_64-unknown-linux-gnu;
>> > same regrtest results as a control bootstrap of trunk's r217593.
>> >
>> > I appreciate Jakub and others have concerns about the overall approach.
>> > I'm not sure which of option 2 (gimple-compat.h), option 3 (this one),
>> > option 4 (just convert fields and non-accessor params), or defer to gcc
>> > 6 is the best one, but I'm sleep-deprived and wanted to submit this
>> > before the stage1 deadline.
>> >
>> > The other commits on this pruned branch that haven't been reviewed yet
>> > are:
>> >
>> > [gimple-classes, committed 88/92] Preparatory work before subclass
>> > renaming
>> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02820.html
>>
>> Ok.
>>
>> > [gimple-classes, committed 89/92] Eliminate subclass typedefs from
>> > coretypes.h
>> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02838.html
>>
>> Ok.
>>
>> > [gimple-classes, committed 90/92] Automated renaming of gimple
>> > subclasses
>> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02828.html
>>
>> Ok.
>>
>> > [gimple-classes, committed 91/92] Remove out-of-date references to
>> > typedefs]
>> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02874.html
>>
>> Ok.
>>
>> > [gimple-classes, committed 92/92] Update gimple.texi class hierarchy
>> > diagram
>> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02818.html
>>
>> Ok.
>>
>> > [gimple-classes] Merge trunk r216157-r216746 into branch
>> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02982.html
>>
>> Ok.
>
> Thanks.  You said "Ok" to the various patches I pinged, but I don't
> think you commented on the patch that was attached to the email.
>
> Is that one OK?  It's:
>  https://gcc.gnu.org/ml/gcc-patches/2014-11/msg01935.html
> in the archives.

Yes, that one is ok as well.

> I believe that's the only unreviewed patch on the branch
> "dmalcolm/gimple-classes-v2-option-3":
> https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/gimple-classes-v2-option-3
>
> Assuming that's OK, I want to merge that branch to trunk in the next day
> or so.

Fine with me.

>> > Also, presumably if this were merged, it would require a followup with
>> > the gimple to gimple * fixup you wanted? (which we talked about doing as
>> > an early stage3 thing IIRC [1]).
>>
>> Yeah, that would be nice (to remind people - this is about getting rid
>> of const_gimple and thus avoids introducing tons of new const_
>> for all the subclasses).
>
> FWIW I got rid of all of those typedefs in the patches above (89/92 in
> particular); the subclasses on the branch are already using explicit
> ptrs, so it's more about consistency between base class ptrs and
> subclass ptrs, to avoid:
>
>   gimple  stmt;
>   gphi   *phi;
>   gcall  *call_stmt;
>
> in favor of:
>   gimple *stmt;  /* <-- note this one */
>   gphi   *phi;
>   gcall  *call_stmt;

right.

> I'd already done that for the subclasses on the branch, and the diff
> between the branch and trunk is relatively sane.
>
> By contrast, doing the gimple -> gimple * fixup will generate a huge
> diff, so that's something to do after merging the branch.
> I'll post the patch here later this week (or a link to it, it's likely
> to be too big even compressed for the ML).

Thanks,
Richard.

> Dave
>
>> Thanks,
>> Richard.
>>
>> > Thanks
>> > Dave
>> > [1] e.g. https://gcc.gnu.org/ml/gcc-patches/2014-10/msg01536.html
>> >
>> >
>> >> > Option 4: don't convert any accessors, but instead focus on fields of
>> >> > structs (e.g. "call_stmt" within a cgraph_edge), and on params of other
>> >> > functions (e.g. phi-manipulation code).  That way we'd avoid the
>> >> > inconsistency of some accessors using GIMPLE_CHECK and some using
>> >> > subclasses - all would continue to consistently use GIMPLE_CHECK, but
>> >> > there would be some extra type-checking and self-documentation of the
>> >> > expected statement kinds in the code.
>> >> >
>> >> >
>> >> >
>> >> > FWIW, option 3 is my preferred approach (I've already done the bulk of
>> >> > the work and it's already been reviewed; it would need an update merger
>> >> > from trunk, and there's the big gimple to gimple * fixup you wanted).
>> >>
>> >> Works for me as well.  The compat solution looks somewhat appealing
>> >> as we can then incrementally fix up things rather than requiring to
>> >> mass-convert everything.
>> >>
>> >> Thanks,
>> >> Richard.
>> >>
>> >> >> Whether you enable them generally or just for selected files
>> >> >> via a gimple-compat.h will be up to you (but I'd rather get
>> >> >> rid of them at some point).
>> >> >>
>> >> >> Note this allows seamless transform of "random" functions
>> >> >> taking a gimple now but really only expecting a single kind.
>> >> >>
>> >> >> Note that we don't absolutely have to rush this all in for GCC 5.
>> >> >> Being the very first for GCC 6 stage1 is another possibility.
>> >> >> We just should get it right.
>> >> >
>> >> > Thanks
>> >> > Dave
>> >> >
>> >
>
>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-18 10:02                         ` Richard Biener
@ 2014-11-18 21:19                           ` David Malcolm
  2014-11-19 10:27                             ` Richard Biener
  0 siblings, 1 reply; 36+ messages in thread
From: David Malcolm @ 2014-11-18 21:19 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jakub Jelinek, GCC Patches, GCC Development, Jeff Law

On Tue, 2014-11-18 at 10:53 +0100, Richard Biener wrote:
> On Tue, Nov 18, 2014 at 2:59 AM, David Malcolm <dmalcolm@redhat.com> wrote:
> > On Mon, 2014-11-17 at 11:06 +0100, Richard Biener wrote:
> >> On Sat, Nov 15, 2014 at 12:00 PM, David Malcolm <dmalcolm@redhat.com> wrote:
> >> > On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote:
> >> >> On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm <dmalcolm@redhat.com> wrote:
> >> >> > On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
> >> >> >> On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> >> >> >> > On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
> >> >> >> >> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
> >> >> >> >> > On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
> >> >> >> >> > > To be constructive here - the above case is from within a
> >> >> >> >> > > GIMPLE_ASSIGN case label
> >> >> >> >> > > and thus I'd have expected
> >> >> >> >> > >
> >> >> >> >> > >     case GIMPLE_ASSIGN:
> >> >> >> >> > >       {
> >> >> >> >> > >         gassign *a1 = as_a <gassign *> (s1);
> >> >> >> >> > >         gassign *a2 = as_a <gassign *> (s2);
> >> >> >> >> > >       lhs1 = gimple_assign_lhs (a1);
> >> >> >> >> > >       lhs2 = gimple_assign_lhs (a2);
> >> >> >> >> > >       if (TREE_CODE (lhs1) != SSA_NAME
> >> >> >> >> > >           && TREE_CODE (lhs2) != SSA_NAME)
> >> >> >> >> > >         return (operand_equal_p (lhs1, lhs2, 0)
> >> >> >> >> > >                 && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
> >> >> >> >> > >                                                  gimple_assign_rhs1 (a2)));
> >> >> >> >> > >       else if (TREE_CODE (lhs1) == SSA_NAME
> >> >> >> >> > >                && TREE_CODE (lhs2) == SSA_NAME)
> >> >> >> >> > >         return vn_valueize (lhs1) == vn_valueize (lhs2);
> >> >> >> >> > >       return false;
> >> >> >> >> > >       }
> >> >> >> >> > >
> >> >> >> >> > > instead.  That's the kind of changes I have expected and have approved of.
> >> >> >> >> >
> >> >> >> >> > But even that looks like just adding extra work for all developers, with no
> >> >> >> >> > gain.  You only have to add extra code and extra temporaries, in switches
> >> >> >> >> > typically also have to add {} because of the temporaries and thus extra
> >> >> >> >> > indentation level, and it doesn't simplify anything in the code.
> >> >> >> >>
> >> >> >> >> The branch attempts to use the C++ typesystem to capture information
> >> >> >> >> about the kinds of gimple statement we expect, both:
> >> >> >> >>   (A) so that the compiler can detect type errors, and
> >> >> >> >>   (B) as a comprehension aid to the human reader of the code
> >> >> >> >>
> >> >> >> >> The ideal here is when function params and struct field can be
> >> >> >> >> strengthened from "gimple" to a subclass ptr.  This captures the
> >> >> >> >> knowledge that every use of a function or within a struct has a given
> >> >> >> >> gimple code.
> >> >> >> >
> >> >> >> > I just don't like all the as_a/is_a stuff enforced everywhere,
> >> >> >> > it means more typing, more temporaries, more indentation.
> >> >> >> > So, as I view it, instead of the checks being done cheaply (yes, I think
> >> >> >> > the gimple checking as we have right now is very cheap) under the
> >> >> >> > hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
> >> >> >> > put the burden on the developers, who has to check that manually through
> >> >> >> > the as_a/is_a stuff everywhere, more typing and uglier syntax.
> >> >> >> > I just don't see that as a step forward, instead a huge step backwards.
> >> >> >> > But perhaps I'm alone with this.
> >> >> >> > Can you e.g. compare the size of - lines in your patchset combined, and
> >> >> >> > size of + lines in your patchset?  As in, if your changes lead to less
> >> >> >> > typing or more.
> >> >> >>
> >> >> >> I see two ways out here.  One is to add overloads to all the functions
> >> >> >> taking the special types like
> >> >> >>
> >> >> >> tree
> >> >> >> gimple_assign_rhs1 (gimple *);
> >> >> >>
> >> >> >> or simply add
> >> >> >>
> >> >> >> gassign *operator ()(gimple *g) { return as_a <gassign *> (g); }
> >> >> >>
> >> >> >> into a gimple-compat.h header which you include in places that
> >> >> >> are not converted "nicely".
> >> >> >
> >> >> > Thanks for the suggestions.
> >> >> >
> >> >> > Am I missing something, or is the gimple-compat.h idea above not valid C
> >> >> > ++?
> >> >> >
> >> >> > Note that "gimple" is still a typedef to
> >> >> >   gimple_statement_base *
> >> >> > (as noted before, the gimple -> gimple * change would break everyone
> >> >> > else's patches, so we talked about that as a followup patch for early
> >> >> > stage3).
> >> >> >
> >> >> > Given that, if I try to create an "operator ()" outside of a class, I
> >> >> > get this error:
> >> >> >
> >> >> > ‘gassign* operator()(gimple)’ must be a nonstatic member function
> >> >> >
> >> >> > which is emitted from cp/decl.c's grok_op_properties:
> >> >> >       /* An operator function must either be a non-static member function
> >> >> >          or have at least one parameter of a class, a reference to a class,
> >> >> >          an enumeration, or a reference to an enumeration.  13.4.0.6 */
> >> >> >
> >> >> > I tried making it a member function of gimple_statement_base, but that
> >> >> > doesn't work either: we want a conversion
> >> >> >   from a gimple_statement_base * to a gassign *, not
> >> >> >   from a gimple_statement_base   to a gassign *.
> >> >> >
> >> >> > Is there some syntactic trick here that I'm missing?  Sorry if I'm being
> >> >> > dumb (I can imagine there's a way of doing it by making "gimple" become
> >> >> > some kind of wrapped ptr class, but that way lies madness, surely).
> >> >>
> >> >> Hmm.
> >> >>
> >> >> struct assign;
> >> >> struct base {
> >> >>   operator assign *() const { return (assign *)this; }
> >> >> };
> >> >> struct assign : base {
> >> >> };
> >> >>
> >> >> void foo (assign *);
> >> >> void bar (base *b)
> >> >> {
> >> >>   foo (b);
> >> >> }
> >> >>
> >> >> doesn't work, but
> >> >>
> >> >> void bar (base &b)
> >> >> {
> >> >>   foo (b);
> >> >> }
> >> >>
> >> >> does.  Indeed C++ doesn't seem to provide what is necessary
> >> >> for the compat trick :(
> >> >>
> >> >> So the gimple-compat.h header would need to provide
> >> >> additional overloads for the affected functions like
> >> >>
> >> >> inline tree
> >> >> gimple_assign_rhs1 (gimple *g)
> >> >> {
> >> >>   return gimple_assign_rhs1 (as_a <gassign *> (g));
> >> >> }
> >> >>
> >> >> that would work for me as well.
> >> >>
> >> >> >> Both avoid manually making the compiler happy (which the
> >> >> >> explicit as_a<> stuff is!  It doesn't add any "checking" - it's
> >> >> >> just placing the as_a<> at the callers and thus make the
> >> >> >> runtine ICE fire there).
> >> >> >>
> >> >> >> As much as I don't like "global" conversion operators I don't
> >> >> >> like adding overloads to all of the accessor functions even more.
> >> >> >
> >> >> > (nods)
> >> >> >
> >> >> > Some other options:
> >> >> >
> >> >> > Option 3: only convert the "easy" accessors: the ones I already did in
> >> >> > the /89 patch kit, as reviewed by Jeff, and rebased by me recently,
> >> >> > which is this 92-patch kit:
> >> >> >   "[gimple-classes, committed 00/92] Initial slew of commits":
> >> >> >      https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html
> >> >> > Doing so converts about half of the gimple_foo_ accessors to taking a
> >> >> > gfoo *, giving a mixture of GIMPLE_CHECK vs subclass use.   I believe
> >> >> > the quality of those patches was higher than the later ones on the
> >> >> > branch: I was doing the places that didn't require the invasive/verbose
> >> >> > changes seen in the later patches.  Shelve the remaining ~80
> >> >> > increasingly ugly patches, starting a new branch to contain just the
> >> >> > good ones.
> >> >
> >> > I've created a branch "dmalcolm/gimple-classes-v2-option-3"
> >> > https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/gimple-classes-v2-option-3
> >> >
> >> > which takes the work reviewed by Jeff and the most trivial of the merger
> >> > followup work, throwing away the ~80 unloved followup patches on
> >> > dmalcolm/gimple-classes.
> >> >
> >> > I've merged from yesterday's trunk r217593 into that new branch,
> >> > resolving conflicts.
> >> >
> >> > I did this in two parts: the basic merger as
> >> >   bd7fe714158f0c600caa05be7d744fd9139b8afb
> >> > resolving conflicts, with a followup patch to fixup new code from trunk
> >> > that used accessors that on the branch required a gimple subclass.
> >> >
> >> > Attached is that 2nd part of the merger.
> >> >
> >> > Successfully bootstrapped and regrtested on x86_64-unknown-linux-gnu;
> >> > same regrtest results as a control bootstrap of trunk's r217593.
> >> >
> >> > I appreciate Jakub and others have concerns about the overall approach.
> >> > I'm not sure which of option 2 (gimple-compat.h), option 3 (this one),
> >> > option 4 (just convert fields and non-accessor params), or defer to gcc
> >> > 6 is the best one, but I'm sleep-deprived and wanted to submit this
> >> > before the stage1 deadline.
> >> >
> >> > The other commits on this pruned branch that haven't been reviewed yet
> >> > are:
> >> >
> >> > [gimple-classes, committed 88/92] Preparatory work before subclass
> >> > renaming
> >> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02820.html
> >>
> >> Ok.
> >>
> >> > [gimple-classes, committed 89/92] Eliminate subclass typedefs from
> >> > coretypes.h
> >> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02838.html
> >>
> >> Ok.
> >>
> >> > [gimple-classes, committed 90/92] Automated renaming of gimple
> >> > subclasses
> >> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02828.html
> >>
> >> Ok.
> >>
> >> > [gimple-classes, committed 91/92] Remove out-of-date references to
> >> > typedefs]
> >> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02874.html
> >>
> >> Ok.
> >>
> >> > [gimple-classes, committed 92/92] Update gimple.texi class hierarchy
> >> > diagram
> >> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02818.html
> >>
> >> Ok.
> >>
> >> > [gimple-classes] Merge trunk r216157-r216746 into branch
> >> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02982.html
> >>
> >> Ok.
> >
> > Thanks.  You said "Ok" to the various patches I pinged, but I don't
> > think you commented on the patch that was attached to the email.
> >
> > Is that one OK?  It's:
> >  https://gcc.gnu.org/ml/gcc-patches/2014-11/msg01935.html
> > in the archives.
> 
> Yes, that one is ok as well.
> 
> > I believe that's the only unreviewed patch on the branch
> > "dmalcolm/gimple-classes-v2-option-3":
> > https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/gimple-classes-v2-option-3
> >
> > Assuming that's OK, I want to merge that branch to trunk in the next day
> > or so.
> 
> Fine with me.

Thanks.  I've merged from today's trunk into the branch, and fixed some
whitespace issues Jakub pointed out:
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=cf2cd094c5c77adb40a2f3f69021ee0b6f8534ab
(which I assume count as "obvious"), and have bootstrapped&regrtested.

Am preparing a commit of the branch to svn trunk.

Does the gcc/ChangeLog entry need to:

(A) contain a full description of the changes being committed relative
to trunk
(B) contain the body of the ChangeLog.gimple-classes (it's about 4000
lines though)
(C) simply contain a pointer back to ChangeLog.gimple-classes

?

> >> > Also, presumably if this were merged, it would require a followup with
> >> > the gimple to gimple * fixup you wanted? (which we talked about doing as
> >> > an early stage3 thing IIRC [1]).
> >>
> >> Yeah, that would be nice (to remind people - this is about getting rid
> >> of const_gimple and thus avoids introducing tons of new const_
> >> for all the subclasses).
> >
> > FWIW I got rid of all of those typedefs in the patches above (89/92 in
> > particular); the subclasses on the branch are already using explicit
> > ptrs, so it's more about consistency between base class ptrs and
> > subclass ptrs, to avoid:
> >
> >   gimple  stmt;
> >   gphi   *phi;
> >   gcall  *call_stmt;
> >
> > in favor of:
> >   gimple *stmt;  /* <-- note this one */
> >   gphi   *phi;
> >   gcall  *call_stmt;
> 
> right.
> 
> > I'd already done that for the subclasses on the branch, and the diff
> > between the branch and trunk is relatively sane.
> >
> > By contrast, doing the gimple -> gimple * fixup will generate a huge
> > diff, so that's something to do after merging the branch.
> > I'll post the patch here later this week (or a link to it, it's likely
> > to be too big even compressed for the ML).
> 
> Thanks,
> Richard.
> 
> > Dave
> >
> >> Thanks,
> >> Richard.
> >>
> >> > Thanks
> >> > Dave
> >> > [1] e.g. https://gcc.gnu.org/ml/gcc-patches/2014-10/msg01536.html
> >> >
> >> >
> >> >> > Option 4: don't convert any accessors, but instead focus on fields of
> >> >> > structs (e.g. "call_stmt" within a cgraph_edge), and on params of other
> >> >> > functions (e.g. phi-manipulation code).  That way we'd avoid the
> >> >> > inconsistency of some accessors using GIMPLE_CHECK and some using
> >> >> > subclasses - all would continue to consistently use GIMPLE_CHECK, but
> >> >> > there would be some extra type-checking and self-documentation of the
> >> >> > expected statement kinds in the code.
> >> >> >
> >> >> >
> >> >> >
> >> >> > FWIW, option 3 is my preferred approach (I've already done the bulk of
> >> >> > the work and it's already been reviewed; it would need an update merger
> >> >> > from trunk, and there's the big gimple to gimple * fixup you wanted).
> >> >>
> >> >> Works for me as well.  The compat solution looks somewhat appealing
> >> >> as we can then incrementally fix up things rather than requiring to
> >> >> mass-convert everything.
> >> >>
> >> >> Thanks,
> >> >> Richard.
> >> >>
> >> >> >> Whether you enable them generally or just for selected files
> >> >> >> via a gimple-compat.h will be up to you (but I'd rather get
> >> >> >> rid of them at some point).
> >> >> >>
> >> >> >> Note this allows seamless transform of "random" functions
> >> >> >> taking a gimple now but really only expecting a single kind.
> >> >> >>
> >> >> >> Note that we don't absolutely have to rush this all in for GCC 5.
> >> >> >> Being the very first for GCC 6 stage1 is another possibility.
> >> >> >> We just should get it right.
> >> >> >
> >> >> > Thanks
> >> >> > Dave
> >> >> >
> >> >
> >
> >


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
  2014-11-18 21:19                           ` David Malcolm
@ 2014-11-19 10:27                             ` Richard Biener
  0 siblings, 0 replies; 36+ messages in thread
From: Richard Biener @ 2014-11-19 10:27 UTC (permalink / raw)
  To: David Malcolm; +Cc: Jakub Jelinek, GCC Patches, GCC Development, Jeff Law

On Tue, Nov 18, 2014 at 10:04 PM, David Malcolm <dmalcolm@redhat.com> wrote:
> On Tue, 2014-11-18 at 10:53 +0100, Richard Biener wrote:
>> On Tue, Nov 18, 2014 at 2:59 AM, David Malcolm <dmalcolm@redhat.com> wrote:
>> > On Mon, 2014-11-17 at 11:06 +0100, Richard Biener wrote:
>> >> On Sat, Nov 15, 2014 at 12:00 PM, David Malcolm <dmalcolm@redhat.com> wrote:
>> >> > On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote:
>> >> >> On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm <dmalcolm@redhat.com> wrote:
>> >> >> > On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
>> >> >> >> On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>> >> >> >> > On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
>> >> >> >> >> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
>> >> >> >> >> > On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
>> >> >> >> >> > > To be constructive here - the above case is from within a
>> >> >> >> >> > > GIMPLE_ASSIGN case label
>> >> >> >> >> > > and thus I'd have expected
>> >> >> >> >> > >
>> >> >> >> >> > >     case GIMPLE_ASSIGN:
>> >> >> >> >> > >       {
>> >> >> >> >> > >         gassign *a1 = as_a <gassign *> (s1);
>> >> >> >> >> > >         gassign *a2 = as_a <gassign *> (s2);
>> >> >> >> >> > >       lhs1 = gimple_assign_lhs (a1);
>> >> >> >> >> > >       lhs2 = gimple_assign_lhs (a2);
>> >> >> >> >> > >       if (TREE_CODE (lhs1) != SSA_NAME
>> >> >> >> >> > >           && TREE_CODE (lhs2) != SSA_NAME)
>> >> >> >> >> > >         return (operand_equal_p (lhs1, lhs2, 0)
>> >> >> >> >> > >                 && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
>> >> >> >> >> > >                                                  gimple_assign_rhs1 (a2)));
>> >> >> >> >> > >       else if (TREE_CODE (lhs1) == SSA_NAME
>> >> >> >> >> > >                && TREE_CODE (lhs2) == SSA_NAME)
>> >> >> >> >> > >         return vn_valueize (lhs1) == vn_valueize (lhs2);
>> >> >> >> >> > >       return false;
>> >> >> >> >> > >       }
>> >> >> >> >> > >
>> >> >> >> >> > > instead.  That's the kind of changes I have expected and have approved of.
>> >> >> >> >> >
>> >> >> >> >> > But even that looks like just adding extra work for all developers, with no
>> >> >> >> >> > gain.  You only have to add extra code and extra temporaries, in switches
>> >> >> >> >> > typically also have to add {} because of the temporaries and thus extra
>> >> >> >> >> > indentation level, and it doesn't simplify anything in the code.
>> >> >> >> >>
>> >> >> >> >> The branch attempts to use the C++ typesystem to capture information
>> >> >> >> >> about the kinds of gimple statement we expect, both:
>> >> >> >> >>   (A) so that the compiler can detect type errors, and
>> >> >> >> >>   (B) as a comprehension aid to the human reader of the code
>> >> >> >> >>
>> >> >> >> >> The ideal here is when function params and struct field can be
>> >> >> >> >> strengthened from "gimple" to a subclass ptr.  This captures the
>> >> >> >> >> knowledge that every use of a function or within a struct has a given
>> >> >> >> >> gimple code.
>> >> >> >> >
>> >> >> >> > I just don't like all the as_a/is_a stuff enforced everywhere,
>> >> >> >> > it means more typing, more temporaries, more indentation.
>> >> >> >> > So, as I view it, instead of the checks being done cheaply (yes, I think
>> >> >> >> > the gimple checking as we have right now is very cheap) under the
>> >> >> >> > hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
>> >> >> >> > put the burden on the developers, who has to check that manually through
>> >> >> >> > the as_a/is_a stuff everywhere, more typing and uglier syntax.
>> >> >> >> > I just don't see that as a step forward, instead a huge step backwards.
>> >> >> >> > But perhaps I'm alone with this.
>> >> >> >> > Can you e.g. compare the size of - lines in your patchset combined, and
>> >> >> >> > size of + lines in your patchset?  As in, if your changes lead to less
>> >> >> >> > typing or more.
>> >> >> >>
>> >> >> >> I see two ways out here.  One is to add overloads to all the functions
>> >> >> >> taking the special types like
>> >> >> >>
>> >> >> >> tree
>> >> >> >> gimple_assign_rhs1 (gimple *);
>> >> >> >>
>> >> >> >> or simply add
>> >> >> >>
>> >> >> >> gassign *operator ()(gimple *g) { return as_a <gassign *> (g); }
>> >> >> >>
>> >> >> >> into a gimple-compat.h header which you include in places that
>> >> >> >> are not converted "nicely".
>> >> >> >
>> >> >> > Thanks for the suggestions.
>> >> >> >
>> >> >> > Am I missing something, or is the gimple-compat.h idea above not valid C
>> >> >> > ++?
>> >> >> >
>> >> >> > Note that "gimple" is still a typedef to
>> >> >> >   gimple_statement_base *
>> >> >> > (as noted before, the gimple -> gimple * change would break everyone
>> >> >> > else's patches, so we talked about that as a followup patch for early
>> >> >> > stage3).
>> >> >> >
>> >> >> > Given that, if I try to create an "operator ()" outside of a class, I
>> >> >> > get this error:
>> >> >> >
>> >> >> > ‘gassign* operator()(gimple)’ must be a nonstatic member function
>> >> >> >
>> >> >> > which is emitted from cp/decl.c's grok_op_properties:
>> >> >> >       /* An operator function must either be a non-static member function
>> >> >> >          or have at least one parameter of a class, a reference to a class,
>> >> >> >          an enumeration, or a reference to an enumeration.  13.4.0.6 */
>> >> >> >
>> >> >> > I tried making it a member function of gimple_statement_base, but that
>> >> >> > doesn't work either: we want a conversion
>> >> >> >   from a gimple_statement_base * to a gassign *, not
>> >> >> >   from a gimple_statement_base   to a gassign *.
>> >> >> >
>> >> >> > Is there some syntactic trick here that I'm missing?  Sorry if I'm being
>> >> >> > dumb (I can imagine there's a way of doing it by making "gimple" become
>> >> >> > some kind of wrapped ptr class, but that way lies madness, surely).
>> >> >>
>> >> >> Hmm.
>> >> >>
>> >> >> struct assign;
>> >> >> struct base {
>> >> >>   operator assign *() const { return (assign *)this; }
>> >> >> };
>> >> >> struct assign : base {
>> >> >> };
>> >> >>
>> >> >> void foo (assign *);
>> >> >> void bar (base *b)
>> >> >> {
>> >> >>   foo (b);
>> >> >> }
>> >> >>
>> >> >> doesn't work, but
>> >> >>
>> >> >> void bar (base &b)
>> >> >> {
>> >> >>   foo (b);
>> >> >> }
>> >> >>
>> >> >> does.  Indeed C++ doesn't seem to provide what is necessary
>> >> >> for the compat trick :(
>> >> >>
>> >> >> So the gimple-compat.h header would need to provide
>> >> >> additional overloads for the affected functions like
>> >> >>
>> >> >> inline tree
>> >> >> gimple_assign_rhs1 (gimple *g)
>> >> >> {
>> >> >>   return gimple_assign_rhs1 (as_a <gassign *> (g));
>> >> >> }
>> >> >>
>> >> >> that would work for me as well.
>> >> >>
>> >> >> >> Both avoid manually making the compiler happy (which the
>> >> >> >> explicit as_a<> stuff is!  It doesn't add any "checking" - it's
>> >> >> >> just placing the as_a<> at the callers and thus make the
>> >> >> >> runtine ICE fire there).
>> >> >> >>
>> >> >> >> As much as I don't like "global" conversion operators I don't
>> >> >> >> like adding overloads to all of the accessor functions even more.
>> >> >> >
>> >> >> > (nods)
>> >> >> >
>> >> >> > Some other options:
>> >> >> >
>> >> >> > Option 3: only convert the "easy" accessors: the ones I already did in
>> >> >> > the /89 patch kit, as reviewed by Jeff, and rebased by me recently,
>> >> >> > which is this 92-patch kit:
>> >> >> >   "[gimple-classes, committed 00/92] Initial slew of commits":
>> >> >> >      https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html
>> >> >> > Doing so converts about half of the gimple_foo_ accessors to taking a
>> >> >> > gfoo *, giving a mixture of GIMPLE_CHECK vs subclass use.   I believe
>> >> >> > the quality of those patches was higher than the later ones on the
>> >> >> > branch: I was doing the places that didn't require the invasive/verbose
>> >> >> > changes seen in the later patches.  Shelve the remaining ~80
>> >> >> > increasingly ugly patches, starting a new branch to contain just the
>> >> >> > good ones.
>> >> >
>> >> > I've created a branch "dmalcolm/gimple-classes-v2-option-3"
>> >> > https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/gimple-classes-v2-option-3
>> >> >
>> >> > which takes the work reviewed by Jeff and the most trivial of the merger
>> >> > followup work, throwing away the ~80 unloved followup patches on
>> >> > dmalcolm/gimple-classes.
>> >> >
>> >> > I've merged from yesterday's trunk r217593 into that new branch,
>> >> > resolving conflicts.
>> >> >
>> >> > I did this in two parts: the basic merger as
>> >> >   bd7fe714158f0c600caa05be7d744fd9139b8afb
>> >> > resolving conflicts, with a followup patch to fixup new code from trunk
>> >> > that used accessors that on the branch required a gimple subclass.
>> >> >
>> >> > Attached is that 2nd part of the merger.
>> >> >
>> >> > Successfully bootstrapped and regrtested on x86_64-unknown-linux-gnu;
>> >> > same regrtest results as a control bootstrap of trunk's r217593.
>> >> >
>> >> > I appreciate Jakub and others have concerns about the overall approach.
>> >> > I'm not sure which of option 2 (gimple-compat.h), option 3 (this one),
>> >> > option 4 (just convert fields and non-accessor params), or defer to gcc
>> >> > 6 is the best one, but I'm sleep-deprived and wanted to submit this
>> >> > before the stage1 deadline.
>> >> >
>> >> > The other commits on this pruned branch that haven't been reviewed yet
>> >> > are:
>> >> >
>> >> > [gimple-classes, committed 88/92] Preparatory work before subclass
>> >> > renaming
>> >> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02820.html
>> >>
>> >> Ok.
>> >>
>> >> > [gimple-classes, committed 89/92] Eliminate subclass typedefs from
>> >> > coretypes.h
>> >> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02838.html
>> >>
>> >> Ok.
>> >>
>> >> > [gimple-classes, committed 90/92] Automated renaming of gimple
>> >> > subclasses
>> >> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02828.html
>> >>
>> >> Ok.
>> >>
>> >> > [gimple-classes, committed 91/92] Remove out-of-date references to
>> >> > typedefs]
>> >> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02874.html
>> >>
>> >> Ok.
>> >>
>> >> > [gimple-classes, committed 92/92] Update gimple.texi class hierarchy
>> >> > diagram
>> >> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02818.html
>> >>
>> >> Ok.
>> >>
>> >> > [gimple-classes] Merge trunk r216157-r216746 into branch
>> >> >   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02982.html
>> >>
>> >> Ok.
>> >
>> > Thanks.  You said "Ok" to the various patches I pinged, but I don't
>> > think you commented on the patch that was attached to the email.
>> >
>> > Is that one OK?  It's:
>> >  https://gcc.gnu.org/ml/gcc-patches/2014-11/msg01935.html
>> > in the archives.
>>
>> Yes, that one is ok as well.
>>
>> > I believe that's the only unreviewed patch on the branch
>> > "dmalcolm/gimple-classes-v2-option-3":
>> > https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/gimple-classes-v2-option-3
>> >
>> > Assuming that's OK, I want to merge that branch to trunk in the next day
>> > or so.
>>
>> Fine with me.
>
> Thanks.  I've merged from today's trunk into the branch, and fixed some
> whitespace issues Jakub pointed out:
> https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=cf2cd094c5c77adb40a2f3f69021ee0b6f8534ab
> (which I assume count as "obvious"), and have bootstrapped&regrtested.
>
> Am preparing a commit of the branch to svn trunk.
>
> Does the gcc/ChangeLog entry need to:
>
> (A) contain a full description of the changes being committed relative
> to trunk
> (B) contain the body of the ChangeLog.gimple-classes (it's about 4000
> lines though)
> (C) simply contain a pointer back to ChangeLog.gimple-classes
>
> ?

(A) where I'd mainly document changes to gimple.[ch] and add a
boiler-plate

          * <elsewhere>: Update according to the above.

(I'm not very fond of gigantic but pretty useless boilerplate changelogs).

No need to do (B) (I usually discourage people from doing that)

Thanks,
Richard.


>> >> > Also, presumably if this were merged, it would require a followup with
>> >> > the gimple to gimple * fixup you wanted? (which we talked about doing as
>> >> > an early stage3 thing IIRC [1]).
>> >>
>> >> Yeah, that would be nice (to remind people - this is about getting rid
>> >> of const_gimple and thus avoids introducing tons of new const_
>> >> for all the subclasses).
>> >
>> > FWIW I got rid of all of those typedefs in the patches above (89/92 in
>> > particular); the subclasses on the branch are already using explicit
>> > ptrs, so it's more about consistency between base class ptrs and
>> > subclass ptrs, to avoid:
>> >
>> >   gimple  stmt;
>> >   gphi   *phi;
>> >   gcall  *call_stmt;
>> >
>> > in favor of:
>> >   gimple *stmt;  /* <-- note this one */
>> >   gphi   *phi;
>> >   gcall  *call_stmt;
>>
>> right.
>>
>> > I'd already done that for the subclasses on the branch, and the diff
>> > between the branch and trunk is relatively sane.
>> >
>> > By contrast, doing the gimple -> gimple * fixup will generate a huge
>> > diff, so that's something to do after merging the branch.
>> > I'll post the patch here later this week (or a link to it, it's likely
>> > to be too big even compressed for the ML).
>>
>> Thanks,
>> Richard.
>>
>> > Dave
>> >
>> >> Thanks,
>> >> Richard.
>> >>
>> >> > Thanks
>> >> > Dave
>> >> > [1] e.g. https://gcc.gnu.org/ml/gcc-patches/2014-10/msg01536.html
>> >> >
>> >> >
>> >> >> > Option 4: don't convert any accessors, but instead focus on fields of
>> >> >> > structs (e.g. "call_stmt" within a cgraph_edge), and on params of other
>> >> >> > functions (e.g. phi-manipulation code).  That way we'd avoid the
>> >> >> > inconsistency of some accessors using GIMPLE_CHECK and some using
>> >> >> > subclasses - all would continue to consistently use GIMPLE_CHECK, but
>> >> >> > there would be some extra type-checking and self-documentation of the
>> >> >> > expected statement kinds in the code.
>> >> >> >
>> >> >> >
>> >> >> >
>> >> >> > FWIW, option 3 is my preferred approach (I've already done the bulk of
>> >> >> > the work and it's already been reviewed; it would need an update merger
>> >> >> > from trunk, and there's the big gimple to gimple * fixup you wanted).
>> >> >>
>> >> >> Works for me as well.  The compat solution looks somewhat appealing
>> >> >> as we can then incrementally fix up things rather than requiring to
>> >> >> mass-convert everything.
>> >> >>
>> >> >> Thanks,
>> >> >> Richard.
>> >> >>
>> >> >> >> Whether you enable them generally or just for selected files
>> >> >> >> via a gimple-compat.h will be up to you (but I'd rather get
>> >> >> >> rid of them at some point).
>> >> >> >>
>> >> >> >> Note this allows seamless transform of "random" functions
>> >> >> >> taking a gimple now but really only expecting a single kind.
>> >> >> >>
>> >> >> >> Note that we don't absolutely have to rush this all in for GCC 5.
>> >> >> >> Being the very first for GCC 6 stage1 is another possibility.
>> >> >> >> We just should get it right.
>> >> >> >
>> >> >> > Thanks
>> >> >> > Dave
>> >> >> >
>> >> >
>> >
>> >
>
>

^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2014-11-19 10:14 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-07 15:25 [gimple-classes, committed 0/6] Use gassign in 6 tree-ssa-* files David Malcolm
2014-11-07 15:25 ` [gimple-classes, committed 1/6] tree-ssa-sink.c: Use gassign David Malcolm
2014-11-07 15:26 ` [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: " David Malcolm
2014-11-07 21:01   ` Richard Biener
2014-11-07 21:23     ` Jakub Jelinek
2014-11-08 10:13     ` Marek Polacek
2014-11-08 12:07     ` Richard Biener
2014-11-08 13:56       ` Jakub Jelinek
2014-11-10 22:37         ` David Malcolm
2014-11-10 23:46           ` Andrew Pinski
2014-11-11  7:35           ` Jakub Jelinek
2014-11-11  8:40             ` Eric Botcazou
2014-11-11 11:55               ` Bernd Schmidt
2014-11-11 10:46             ` Richard Biener
2014-11-13  2:08               ` David Malcolm
2014-11-13 10:47                 ` Richard Biener
2014-11-13 11:02                   ` Jonathan Wakely
2014-11-13 14:28                   ` Andrew MacLeod
2014-11-13 14:36                     ` Richard Biener
2014-11-13 15:20                       ` Andrew MacLeod
2014-11-14 15:44                   ` [PATCH] Add gimple-compat.h (was Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign) David Malcolm
2014-11-17  9:54                     ` Richard Biener
2014-11-17 19:44                     ` Jeff Law
2014-11-15 11:58                   ` [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign David Malcolm
2014-11-17 10:23                     ` Richard Biener
2014-11-17 19:49                       ` Jeff Law
2014-11-18  2:40                       ` David Malcolm
2014-11-18 10:02                         ` Richard Biener
2014-11-18 21:19                           ` David Malcolm
2014-11-19 10:27                             ` Richard Biener
2014-11-13  2:23             ` David Malcolm
2014-11-08 14:04       ` David Malcolm
2014-11-07 15:26 ` [gimple-classes, committed 2/6] tree-ssa-strlen.c: " David Malcolm
2014-11-07 15:26 ` [gimple-classes, committed 5/6] tree-ssa-ter.c: " David Malcolm
2014-11-07 15:26 ` [gimple-classes, committed 6/6] tree-ssa-threadedge.c: " David Malcolm
2014-11-07 15:26 ` [gimple-classes, committed 3/6] tree-ssa-structalias.c: " David Malcolm

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).