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


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

[tree-ssa] Mainline merge as of 2003-04-06


This merge exposed a few bugs in the flowgraph builder.  Thanks
to Steven Bosscher for finding the hundreds of new C++
regressions.  In cp/call.c:print_z_candidate, I had stupidly
changed the call to errfn to pass &TREE_LOCUS instead of
TREE_LOCUS.

There are a couple new regressions due to line number mismatch.
Also, we are failing g++.dg/eh/cond1.C.  The gimplifier is trying
to put the call to __cxa_throw on the RHS of an assignment.
Since __cxa_throw is  of type void, we go on to ICE in the RTL
expanders.

This patch to the gimplifier fixes the symptom, but I'm not sure
if it fixes the problem.  It's odd that we have a void object in
an INIT_EXPR, but I'm not at all familiar with the C++ FE.
Jason, does this fix look right? (it's still not committed):

--- gimplify.c	20 Mar 2003 21:21:15 -0000	1.1.2.32
+++ gimplify.c	9 Apr 2003 19:17:29 -0000
@@ -2319,7 +2320,8 @@ simplify_target_expr (expr_p, pre_p, pos
   gimple_add_tmp_var (temp);
 
   /* Build up the initialization and add it to pre_p.  */
-  init = build (MODIFY_EXPR, void_type_node, temp, init);
+  if (!VOID_TYPE_P (TREE_TYPE (init)))
+    init = build (MODIFY_EXPR, void_type_node, temp, init);
   simplify_expr (&init, pre_p, post_p, is_simple_stmt, fb_none);
   add_tree (init, pre_p);
 

The fixes to the flowgraph code were needed to better handle the
presence of empty statements in the function.  The inliner is now
inlining functions after they've been optimized by the tree
optimizers.  This was confusing the flowgraph in various places.

Bootstrapped and tested on ppc, x86 and x86-64.  treelang should
now bootstrap, but I still haven't looked at the problems with Ada.


Diego.


	* gimplify.c (simplify_expr): Handle VECTOR_CST nodes.
	* tree-cfg.c (make_blocks): Ignore empty statement containers.
	Create a basic block before processing containers that only have
	empty statements.
	(make_loop_expr_blocks): Use the container instead of the statement
	when setting NEXT_BLOCK_LINK.
	(make_cond_expr_blocks): Likewise.
	(make_switch_expr_blocks): Likewise.
	(make_bind_expr_blocks): Likewise.
	(successor_block): If the last statement of the block is the empty
	statement, use its container to get NEXT_BLOCK_LINK.
	(stmt_starts_bb_p): Return false if the statement is NULL.
	* tree-pretty-print.c (dump_generic_node): Handle VECTOR_CST nodes.
	* tree-simple.c (is_simple_const): Accept VECTOR_CST as constants.
	* objc/objc-lang.c (LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P):
	Define.

--- gimplify.c	2003/04/06 23:45:14	1.1
+++ gimplify.c	2003/04/06 23:45:27
@@ -457,6 +457,7 @@ simplify_expr (expr_p, pre_p, post_p, si
 	case REAL_CST:
 	case STRING_CST:
 	case COMPLEX_CST:
+	case VECTOR_CST:
 	  break;
 
 	  /* FIXME make this a decl.  */
--- tree-cfg.c	2003/04/06 23:45:14	1.1
+++ tree-cfg.c	2003/04/08 03:24:25
@@ -278,14 +278,28 @@ make_blocks (first_p, next_block_link, p
       tree prev_stmt;
       tree *stmt_p = tsi_container (i);
 
+      /* Ignore empty containers.  */
+      if (*stmt_p == empty_stmt_node || *stmt_p == error_mark_node)
+	continue;
+
       prev_stmt = stmt;
       stmt = tsi_stmt (i);
 
+      /* If the statement starts a new basic block or if we have determined
+	 in a previous pass that we need to create a new block for STMT, do
+	 so now.  */
+      if (start_new_block || stmt_starts_bb_p (stmt, prev_stmt))
+	{
+	  bb = create_bb ();
+	  start_new_block = false;
+	}
+
       /* Set the block for the container of non-executable statements.  */
       if (stmt == NULL_TREE)
 	{
-	  if (bb && *stmt_p != empty_stmt_node)
+	  if (bb)
 	    append_stmt_to_bb (stmt_p, bb, parent_stmt);
+	  last = *stmt_p;
 	  continue;
 	}
 
@@ -293,15 +307,6 @@ make_blocks (first_p, next_block_link, p
       NEXT_BLOCK_LINK (stmt) = NULL_TREE;
       code = TREE_CODE (stmt);
 
-      /* If the statement starts a new basic block or if we have determined
-	 in a previous pass that we need to create a new block for STMT, do
-	 so now.  */
-      if (start_new_block || stmt_starts_bb_p (stmt, prev_stmt))
-	{
-	  bb = create_bb ();
-	  start_new_block = false;
-	}
-
       /* Now add STMT to BB and create the subgraphs for special statement
 	 codes.  */
       append_stmt_to_bb (stmt_p, bb, parent_stmt);
@@ -380,9 +385,8 @@ make_blocks (first_p, next_block_link, p
       last = stmt;
     }
 
-  /* If LAST_STMT is set, link it to NEXT_BLOCK_LINK.  This allows making
-     edges from the last block inside a lexical scope (see
-     successor_block).  */
+  /* If LAST is set, link it to NEXT_BLOCK_LINK.  This allows making edges
+     from the last block inside a lexical scope (see successor_block).  */
   if (last)
     {
       NEXT_BLOCK_LINK (last) = next_block_link;
@@ -421,17 +425,17 @@ make_loop_expr_blocks (loop_p, next_bloc
      LOOP_EXPR body, will naturally loop back.  */
   STRIP_CONTAINERS (loop);
   si = tsi_start (&LOOP_EXPR_BODY (loop));
-  next_block_link = tsi_stmt (si);
+  next_block_link = *(tsi_container (si));
 
   /* If the loop body is empty, point NEXT_BLOCK_LINK to the statement
      following the LOOP_EXPR node, as we do with the other control
      structures.  */
-  if (next_block_link == NULL_TREE)
+  if (body_is_empty (LOOP_EXPR_BODY (loop)))
     {
       si = tsi_start (loop_p);
       tsi_next (&si);
       if (!tsi_end_p (si))
-	next_block_link = tsi_stmt (si);
+	next_block_link = *(tsi_container (si));
     }
 
   make_blocks (&LOOP_EXPR_BODY (loop), next_block_link, loop, NULL);
@@ -461,7 +465,7 @@ make_cond_expr_blocks (cond_p, next_bloc
   si = tsi_start (cond_p);
   tsi_next (&si);
   if (!tsi_end_p (si))
-    next_block_link = tsi_stmt (si);
+    next_block_link = *(tsi_container (si));
 
   STRIP_CONTAINERS (cond);
   make_blocks (&COND_EXPR_THEN (cond), next_block_link, cond, NULL);
@@ -492,7 +496,7 @@ make_switch_expr_blocks (switch_e_p, nex
   si = tsi_start (switch_e_p);
   tsi_next (&si);
   if (!tsi_end_p (si))
-    next_block_link = tsi_stmt (si);
+    next_block_link = *(tsi_container (si));
 
   STRIP_CONTAINERS (switch_e);
   make_blocks (&SWITCH_BODY (switch_e), next_block_link, switch_e, NULL);
@@ -531,7 +535,7 @@ make_bind_expr_blocks (bind_p, next_bloc
   si = tsi_start (bind_p);
   tsi_next (&si);
   if (!tsi_end_p (si))
-    next_block_link = tsi_stmt (si);
+    next_block_link = *(tsi_container (si));
 
   /* By passing the current block ENTRY to make_blocks, we will keep adding
      statements to ENTRY until we find a block terminating statement inside
@@ -1103,17 +1107,9 @@ remove_bb (bb, remove_stmts)
       remove_edge (bb->pred);
     }
 
+  /* Remove edges to BB's successors.  */
   while (bb->succ != NULL)
-    {
-      tree phi;
-
-      /* PHI nodes in successors of this block now have one less
-         alternative.  */
-      for (phi = phi_nodes (bb->succ->dest); phi; phi = TREE_CHAIN (phi))
-	remove_phi_arg (phi, bb);
-
-      remove_edge (bb->succ);
-    }
+    ssa_remove_edge (bb->succ);
 
   bb->pred = NULL;
   bb->succ = NULL;
@@ -1384,15 +1380,7 @@ cleanup_cond_expr_graph (bb)
 	{
 	  next = e->succ_next;
 	  if (e != taken_edge)
-	    {
-	      tree phi;
-
-	      /* Remove the appropriate PHI alternative in the
-	         target block for each non executable edge.  */
-	      for (phi = phi_nodes (e->dest); phi; phi = TREE_CHAIN (phi))
-		remove_phi_arg (phi, e->dest);
-	      remove_edge (e);
-	    }
+	    ssa_remove_edge (e);
 	}
     }
 }
@@ -1431,15 +1419,7 @@ cleanup_switch_expr_graph (switch_bb)
 	  basic_block chain_bb = successor_block (switch_bb);
 	  edge e = find_edge (switch_bb, chain_bb);
 	  if (e)
-	    {
-	      tree phi;
-
-	      /* Remove the appropriate PHI alternative in the
-	         target block for each unexecutable edge.  */
-	      for (phi = phi_nodes (e->dest); phi; phi = TREE_CHAIN (phi))
-		remove_phi_arg (phi, e->src);
-	      remove_edge (e);
-	    }
+	    ssa_remove_edge (e);
 	  break;
 	}
     }
@@ -1474,15 +1454,7 @@ disconnect_unreachable_case_labels (bb)
 	{
 	  next = e->succ_next;
 	  if (e != taken_edge)
-	    {
-	      tree phi;
-
-	      /* Remove the appropriate PHI alternative in the
-	         target block for each non executable edge.  */
-	      for (phi = phi_nodes (e->dest); phi; phi = TREE_CHAIN (phi))
-		remove_phi_arg (phi, e->src);
-	      remove_edge (e);
-	    }
+	    ssa_remove_edge (e);
 	}
     }
 }
@@ -1749,6 +1721,7 @@ dump_tree_bb (outf, prefix, bb, indent)
   char *s_indent;
   basic_block loop_bb;
   block_stmt_iterator si;
+  tree phi;
 
   s_indent = (char *) alloca ((size_t) indent + 1);
   memset ((void *) s_indent, ' ', (size_t) indent);
@@ -1792,6 +1765,14 @@ dump_tree_bb (outf, prefix, bb, indent)
   else
     fprintf (outf, "nil\n");
 
+  if (bb->aux)
+    for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+      {
+	fprintf (outf, "%s%s# ", s_indent, prefix);
+	print_generic_stmt (outf, phi, 0);
+	fprintf (outf, "\n");
+      }
+
   for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
     {
       fprintf (outf, "%s%s%d  ", s_indent, prefix, get_lineno (bsi_stmt (si)));
@@ -2062,7 +2043,10 @@ successor_block (bb)
      NEXT_BLOCK_LINK for BB's last statement.  If NEXT_BLOCK_LINK is still
      NULL, then BB is the last basic block in the function.  In which case
      we have reached the end of the flowgraph and return EXIT_BLOCK_PTR.  */
-  if (last_stmt && NEXT_BLOCK_LINK (last_stmt))
+  if (last_stmt == NULL_TREE)
+    last_stmt = *bb->end_tree_p;
+
+  if (NEXT_BLOCK_LINK (last_stmt))
     return bb_for_stmt (NEXT_BLOCK_LINK (last_stmt));
   else
     return EXIT_BLOCK_PTR;
@@ -2181,12 +2165,16 @@ stmt_starts_bb_p (t, prev_t)
      tree t;
      tree prev_t;
 {
-  enum tree_code code = TREE_CODE (t);
-
+  enum tree_code code;
+  
+  if (t == NULL_TREE)
+    return false;
+  
   /* LABEL_EXPRs and CASE_LABEL_EXPRs start a new basic block only if the
      preceding statement wasn't a label of the same type.  This prevents
      the creation of consecutive blocks that have nothing but a single
      label.  */
+  code = TREE_CODE (t);
   if (code == LABEL_EXPR || code == CASE_LABEL_EXPR)
     {
       if (prev_t && TREE_CODE (prev_t) == code)
@@ -3126,6 +3114,60 @@ bsi_insert_on_edge (e, stmt)
   
 }
 
+/* These 2 routines are used to process BSI's in reverse within a block.
+   When there is a decent implementation of bsi_prev, we can get rid of 
+   these forever!  */
+
+/* Push another block_stmt_iterator onto the stack.  */
+void 
+push_bsi (list, bsi)
+     bsi_list_p *list;
+     block_stmt_iterator bsi;
+{
+  bsi_list_p tmp;
+  if (*list == NULL)
+    {
+      *list = new_bsi_list ();
+      (*list)->bsi[0] = bsi;
+    }
+  else
+    {
+      if ((*list)->curr_index == (BSI_NUM_ELEMENTS - 1))
+        {
+	  tmp = new_bsi_list ();
+	  tmp->bsi[0] = bsi;
+	  tmp->next = *list;
+	  *list = tmp;
+	}
+      else
+        {
+	  (*list)->bsi[++((*list)->curr_index)] = bsi;
+	}
+    }
+}
+
+/* Pop a block_stmt_iterator off the stack.  */
+block_stmt_iterator
+pop_bsi (list)
+     bsi_list_p *list;
+{
+  block_stmt_iterator bsi;
+  bsi_list_p tmp;
+  if (!list)
+    abort ();
+    
+  tmp = *list;
+  bsi = tmp->bsi[(tmp->curr_index)--];
+  if (tmp->curr_index< 0)
+    {
+      tmp = *list;
+      *list = (*list)->next;
+      free (tmp);
+    }
+  return bsi;
+}
+
+
 /* Replace the statement pointed by TP1 with the statement pointed by TP2.
    Note that this function will not replace COMPOUND_EXPR nodes, only
    individual statements.
@@ -3216,13 +3258,29 @@ merge_tree_blocks (basic_block bb1, basi
 
     /* BB2's successors are now BB1's.  */
     while (bb1->succ)
-      remove_edge (bb1->succ);
+      ssa_remove_edge (bb1->succ);
 
     while (bb2->succ)
       {
-	edge e = bb2->succ;
-	make_edge (bb1, e->dest, e->flags);
-	remove_edge (e);
+	tree phi;
+	edge new_edge, old_edge;
+	
+	old_edge = bb2->succ;
+	new_edge = make_edge (bb1, old_edge->dest, old_edge->flags);
+
+	/* Update PHI nodes at BB2's successor.  The arguments that used to
+	   come from BB2 now come from BB1.  */
+	for (phi = phi_nodes (old_edge->dest); phi; phi = TREE_CHAIN (phi))
+	  {
+	    int i;
+	    for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+	      if (PHI_ARG_EDGE (phi, i) == old_edge)
+		PHI_ARG_EDGE (phi, i) = new_edge;
+	  }
+
+	/* Note that we shouldn't call ssa_remove_edge here because we've
+	   already dealt with PHI nodes.  */
+	remove_edge (old_edge);
       }
 
     /* BB2's dominator children are now BB1's.  Also, remove BB2 as a
--- tree-pretty-print.c	2003/04/06 23:45:14	1.1
+++ tree-pretty-print.c	2003/04/07 01:37:51
@@ -37,7 +37,7 @@ static const char *op_symbol		PARAMS ((t
 static void pretty_print_string		PARAMS ((output_buffer *, const char*));
 static void print_call_name		PARAMS ((output_buffer *, tree));
 static void newline_and_indent		PARAMS ((output_buffer *, int));
-static inline void maybe_init_pretty_print PARAMS ((void));
+static void maybe_init_pretty_print	PARAMS ((void));
 static void print_declaration		PARAMS ((output_buffer *, tree, int,
       						 int));
 static void print_struct_decl		PARAMS ((output_buffer *, tree, int));
@@ -477,6 +477,20 @@ dump_generic_node (buffer, node, spc, fl
       output_add_string (buffer, "\"");
       break;
 
+    case VECTOR_CST:
+      {
+	tree elt;
+	output_add_string (buffer, "{ ");
+	for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
+	  {
+	    dump_generic_node (buffer, TREE_VALUE (elt), spc, flags);
+	    if (TREE_CHAIN (elt))
+	      output_add_string (buffer, ", ");
+	  }
+	output_add_string (buffer, " }");
+      }
+      break;
+
     case FUNCTION_TYPE:
       break;
 
@@ -1335,6 +1349,9 @@ dump_generic_node (buffer, node, spc, fl
 	for (i = 0; i < PHI_NUM_ARGS (node); i++)
 	  {
 	    dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags);
+	    output_add_string (buffer, "(");
+	    output_decimal (buffer, PHI_ARG_EDGE (node, i)->src->index);
+	    output_add_string (buffer, ")");
 	    if (i < PHI_NUM_ARGS (node) - 1)
 	      output_add_string (buffer, ", ");
 	  }
--- tree-simple.c	2003/04/06 23:45:14	1.1
+++ tree-simple.c	2003/04/06 23:45:27
@@ -649,7 +649,8 @@ is_simple_const (t)
 	  || TREE_CODE (t) == STRING_CST
 	  || TREE_CODE (t) == LABEL_DECL
 	  || TREE_CODE (t) == RESULT_DECL
-	  || TREE_CODE (t) == COMPLEX_CST);
+	  || TREE_CODE (t) == COMPLEX_CST
+	  || TREE_CODE (t) == VECTOR_CST);
 }
 
 int
--- objc/objc-lang.c	2 Mar 2003 19:59:14 -0000	1.24.2.5
+++ objc/objc-lang.c	8 Apr 2003 18:12:40 -0000
@@ -100,6 +100,9 @@ static void objc_init_options           
 #undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
 #define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
   c_convert_parm_for_inlining
+#undef LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P
+#define LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P \
+  c_tree_chain_matters_p
 
 #undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
 #define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION c_expand_body


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