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


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

[tuples] Fix EH lowering (part 1)



This fixes about 200 testsuite failures related to EH lowering. It still doesn't fix all the problems, we cannot get libstdc++ compiled. I will be posting a patch for that shortly.


Tested on x86_64 and ppc64.


Diego.



2008-03-03 Diego Novillo <dnovillo@google.com>


        * expr.c (expand_expr_real): Call lookup_expr_eh_region.
        * tree-eh.c (lookup_stmt_eh_region_fn):
        (lookup_stmt_eh_region): Fix comment.
        (lookup_expr_eh_region): Handle missing cfun and missing
        EH table.
        (record_in_finally_tree): Fix comment.
        (collect_finally_tree_1): Remove handler for
        GIMPLE_SWITCH.
        (maybe_record_in_goto_queue): Remove local variable
        NEW_IS_LABEL.
        Record GIMPLE_GOTOs instead of their label.
        (verify_norecord_switch_expr): Retrieve the CASE_LABEL
        from the case label expression.
        (do_return_redirection): Change sign of assertion.
        (lower_try_finally_onedest): Assert that
        TF->GOTO_QUEUE[0] contains a GIMPLE statement.
        (lower_try_finally_copy): Assert that Q contains a GIMPLE
        statement.
        (lower_try_finally_switch): Build a new GIMPLE label for
        CONT_STMT.
        (mark_eh_edge): Tuplify.
        (verify_eh_edges): Tuplify.
        (tree_can_throw_external): Remove unused function.
        (optimize_double_finally): Remove #if 0.
        * gimple-pretty-print.c (GIMPLE_NIY): Tidy.
        (dump_gimple_resx): Fix format string for
        dump_gimple_fmt.
        * gimplify.c (gimplify_cleanup_point_expr): Initialize
        BODY_SEQUENCE.
        * calls.c (emit_call_1): Remove ATTRIBUTE_UNUSED markers.
        * cfgexpand.c (gimple_to_tree) <GIMPLE_NOP>: Assign new
        expression to T.
        <GIMPLE_RESX>: Handle.
        Always assign the value from lookup_stmt_eh_region to
        ANN->RN.
        * tree-cfg.c (start_recording_case_labels):
        (recording_case_labels_p): Re-enable.
        (get_cases_for_edge): Likewise.
        (gimple_verify_flow_info): Re-enable call to
        verify_eh_edges.
        (gimple_redirect_edge_and_branch): Re-enable handling of
        GIMPLE_SWITCH.
        (gimple_block_ends_with_call_p): Tuplify.
        (struct gimple_cfg_hooks): Enable block_ends_with_call_p
        callback.


2008-03-03  Diego Novillo  <dnovillo@google.com>

	* expr.c (expand_expr_real): Call lookup_expr_eh_region.
	* tree-eh.c (lookup_stmt_eh_region_fn):
	(lookup_stmt_eh_region): Fix comment.
	(lookup_expr_eh_region): Handle missing cfun and missing
	EH table.
	(record_in_finally_tree): Fix comment.
	(collect_finally_tree_1): Remove handler for
	GIMPLE_SWITCH.
	(maybe_record_in_goto_queue): Remove local variable
	NEW_IS_LABEL.
	Record GIMPLE_GOTOs instead of their label.
	(verify_norecord_switch_expr): Retrieve the CASE_LABEL
	from the case label expression.
	(do_return_redirection): Change sign of assertion.
	(lower_try_finally_onedest): Assert that
	TF->GOTO_QUEUE[0] contains a GIMPLE statement.
	(lower_try_finally_copy): Assert that Q contains a GIMPLE
	statement.
	(lower_try_finally_switch): Build a new GIMPLE label for
	CONT_STMT.
	(mark_eh_edge): Tuplify.
	(verify_eh_edges): Tuplify.
	(tree_can_throw_external): Remove unused function.
	(optimize_double_finally): Remove #if 0.
	* gimple-pretty-print.c (GIMPLE_NIY): Tidy.
	(dump_gimple_resx): Fix format string for
	dump_gimple_fmt.
	* gimplify.c (gimplify_cleanup_point_expr): Initialize
	BODY_SEQUENCE.
	* calls.c (emit_call_1): Remove ATTRIBUTE_UNUSED markers.
	* cfgexpand.c (gimple_to_tree) <GIMPLE_NOP>: Assign new
	expression to T.
	<GIMPLE_RESX>: Handle.
	Always assign the value from lookup_stmt_eh_region to
	ANN->RN.
	* tree-cfg.c (start_recording_case_labels):
	(recording_case_labels_p): Re-enable.
	(get_cases_for_edge): Likewise.
	(gimple_verify_flow_info): Re-enable call to
	verify_eh_edges.
	(gimple_redirect_edge_and_branch): Re-enable handling of
	GIMPLE_SWITCH.
	(gimple_block_ends_with_call_p): Tuplify.
	(struct gimple_cfg_hooks): Enable block_ends_with_call_p
	callback.

Index: expr.c
===================================================================
--- expr.c	(revision 132841)
+++ expr.c	(working copy)
@@ -7061,11 +7061,7 @@ expand_expr_real (tree exp, rtx target, 
 
   if (flag_non_call_exceptions)
     {
-#if 0
-      rn = lookup_stmt_eh_region (exp);
-#else
       rn = lookup_expr_eh_region (exp);
-#endif
 
       /* If rn < 0, then either (1) tree-ssa not used or (2) doesn't throw.  */
       if (rn >= 0)
Index: tree-eh.c
===================================================================
--- tree-eh.c	(revision 132841)
+++ tree-eh.c	(working copy)
@@ -185,8 +185,8 @@ lookup_stmt_eh_region_fn (struct functio
 
 /* Determine if statement T is inside an EH region in the current
    function (cfun).  Return the EH region number if found, return -2
-   if IFUN does not have an EH table and -1 if T could not be found in
-   IFUN's EH region table.  */
+   if cfun does not have an EH table and -1 if T could not be found in
+   cfun's EH region table.  */
 
 int
 lookup_stmt_eh_region (gimple t)
@@ -199,6 +199,7 @@ lookup_stmt_eh_region (gimple t)
   return lookup_stmt_eh_region_fn (cfun, t);
 }
 
+
 /* Determine if expression T is inside an EH region in the current
    function (cfun).  Return the EH region number if found, return -2
    if IFUN does not have an EH table and -1 if T could not be found in
@@ -210,7 +211,15 @@ lookup_stmt_eh_region (gimple t)
 int
 lookup_expr_eh_region (tree t)
 {
-  if (EXPR_P (t))
+  /* We can get called from initialized data when -fnon-call-exceptions
+     is on; prevent crash.  */
+  if (!cfun)
+    return -1;
+
+  if (!get_eh_throw_stmt_table (cfun))
+    return -2;
+
+  if (t && EXPR_P (t))
     {
       tree_ann_common_t ann = get_tree_common_ann (t);
       return (int) ann->rn;
@@ -255,7 +264,7 @@ record_in_finally_tree (treemple child, 
 static void
 collect_finally_tree (gimple stmt, gimple region);
 
-/* Go through the gimple sequence. Works with collect_finally_tree() to 
+/* Go through the gimple sequence.  Works with collect_finally_tree to 
    record all GIMPLE_LABEL and GIMPLE_TRY statements. */
 
 static void
@@ -270,22 +279,10 @@ collect_finally_tree_1 (gimple_seq seq, 
 static void
 collect_finally_tree (gimple stmt, gimple region)
 {
-  size_t i, n;
   treemple temp;
 
   switch (gimple_code (stmt))
     {
-    /* FIXME tuples: Why is GIMPLE_SWITCH necessary? */
-    case GIMPLE_SWITCH:
-      n = gimple_switch_num_labels (stmt);
-      for (i = 0; i < n; i++)
-      {
-        tree lab = gimple_switch_label (stmt, i);
-        temp.t = lab;
-        record_in_finally_tree (temp, region);
-      }
-      break;
-
     case GIMPLE_LABEL:
       temp.t = gimple_label_label (stmt);
       record_in_finally_tree (temp, region);
@@ -585,7 +582,6 @@ maybe_record_in_goto_queue (struct leh_s
   struct leh_tf_state *tf = state->tf;
   struct goto_queue_node *q;
   treemple new_stmt;
-  int new_is_label;
   size_t active, size;
   int index;
 
@@ -629,8 +625,7 @@ maybe_record_in_goto_queue (struct leh_s
         /* In the case of a GOTO we want to record the destination label,
 	   since with a GIMPLE_COND we have an easy access to the then/else
 	   labels. */
-        new_stmt.t = lab;
-        new_is_label = 1;
+        new_stmt.g = stmt;
       }
       break;
 
@@ -638,7 +633,6 @@ maybe_record_in_goto_queue (struct leh_s
       tf->may_return = true;
       index = -1;
       new_stmt.g = stmt;
-      new_is_label = 0;
       break;
 
     default:
@@ -662,7 +656,6 @@ maybe_record_in_goto_queue (struct leh_s
 
   memset (q, 0, sizeof (*q));
   q->stmt = new_stmt;
-  q->is_label = new_is_label;
   q->index = index;
 }
 
@@ -684,8 +677,8 @@ verify_norecord_switch_expr (struct leh_
 
   for (i = 0; i < n; ++i)
     {
-      tree lab = gimple_switch_label (switch_expr, i);
       treemple temp;
+      tree lab = CASE_LABEL (gimple_switch_label (switch_expr, i));
       temp.t = lab;
       gcc_assert (!outside_finally_tree (temp, tf->try_finally_expr));
     }
@@ -707,7 +700,7 @@ do_return_redirection (struct goto_queue
   gimple x;
 
   /* In the case of a return, the queue node must be a gimple statement. */
-  gcc_assert (q->is_label);
+  gcc_assert (!q->is_label);
 
   ret_expr = gimple_return_retval (q->stmt.g);
 
@@ -1149,6 +1142,7 @@ lower_try_finally_onedest (struct leh_st
 
   /* Reset the locus of the goto since we're moving
      goto to a different block which might be on a different line. */
+  gcc_assert (!tf->goto_queue[0].is_label);
   gimple_set_locus (tf->goto_queue[0].cont_stmt.g, 0);
   gimple_seq_add_stmt (&tf->top_p_seq, tf->goto_queue[0].cont_stmt.g);
   maybe_record_in_goto_queue (state, tf->goto_queue[0].cont_stmt.g);
@@ -1241,6 +1235,7 @@ lower_try_finally_copy (struct leh_state
 	  lower_eh_constructs_1 (state, seq);
           gimple_seq_add_seq (&new_stmt, seq);
 
+	  gcc_assert (!q->is_label);
           gimple_seq_add_stmt (&new_stmt, q->cont_stmt.g);
 	  maybe_record_in_goto_queue (state, q->cont_stmt.g);
 	}
@@ -1429,7 +1424,7 @@ lower_try_finally_switch (struct leh_sta
 
       /* As the comment above suggests, CASE_LABEL (last_case) was just a
          placeholder, it does not store an actual label, yet. */
-      cont_stmt.t = CASE_LABEL (last_case);
+      cont_stmt.g = gimple_build_label (CASE_LABEL (last_case));
 
       label = create_artificial_label ();
       CASE_LABEL (last_case) = label;
@@ -1914,20 +1909,20 @@ make_eh_edges (gimple stmt)
   foreach_reachable_handler (region_nr, is_resx, make_eh_edge, stmt);
 }
 
-/* FIXME tuples.  */
-#if 0
 static bool mark_eh_edge_found_error;
 
 /* Mark edge make_eh_edge would create for given region by setting it aux
    field, output error if something goes wrong.  */
+
 static void
 mark_eh_edge (struct eh_region *region, void *data)
 {
-  tree stmt, lab;
+  gimple stmt;
+  tree lab;
   basic_block src, dst;
   edge e;
 
-  stmt = (tree) data;
+  stmt = (gimple) data;
   lab = get_eh_region_tree_label (region);
 
   src = gimple_bb (stmt);
@@ -1954,10 +1949,11 @@ mark_eh_edge (struct eh_region *region, 
     e->aux = (void *)1;
 }
 
-/* Verify that BB containing stmt as last stmt has precisely the edges
-   make_eh_edges would create.  */
+/* Verify that BB containing STMT as the last statement, has precisely the
+   edges that make_eh_edges would create.  */
+
 bool
-verify_eh_edges (tree stmt)
+verify_eh_edges (gimple stmt)
 {
   int region_nr;
   bool is_resx;
@@ -1968,9 +1964,9 @@ verify_eh_edges (tree stmt)
   FOR_EACH_EDGE (e, ei, bb->succs)
     gcc_assert (!e->aux);
   mark_eh_edge_found_error = false;
-  if (TREE_CODE (stmt) == RESX_EXPR)
+  if (gimple_code (stmt) == GIMPLE_RESX)
     {
-      region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0));
+      region_nr = gimple_resx_region (stmt);
       is_resx = true;
     }
   else
@@ -1986,7 +1982,7 @@ verify_eh_edges (tree stmt)
 	      }
 	   return false;
 	}
-      if (!tree_could_throw_p (stmt))
+      if (!stmt_could_throw_p (stmt))
 	{
 	  error ("BB %i last statement has incorrectly set region", bb->index);
 	  return true;
@@ -2008,7 +2004,6 @@ verify_eh_edges (tree stmt)
 
   return mark_eh_edge_found_error;
 }
-#endif
 
 
 /* Return true if operation OP may trap.  FP_OPERATION is true if OP is applied
@@ -2396,32 +2391,6 @@ stmt_can_throw_internal (gimple stmt)
 }
 
 
-/* Return true if STMT can throw an exception that is visible outside
-   the current function (CFUN).  */
-
-bool
-tree_can_throw_external (tree stmt ATTRIBUTE_UNUSED)
-{
-  /* FIXME tuples.  */
-#if 0
-  int region_nr;
-  bool is_resx = false;
-
-  if (TREE_CODE (stmt) == RESX_EXPR)
-    region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0)), is_resx = true;
-  else
-    region_nr = lookup_stmt_eh_region (stmt);
-  if (region_nr < 0)
-    return tree_could_throw_p (stmt);
-  else
-    return can_throw_external_1 (region_nr, is_resx);
-#else
-  gimple_unreachable ();
-  return false;
-#endif
-}
-
-
 /* Given a statement OLD_STMT and a new statement NEW_STMT that has replaced
    OLD_STMT in the function, remove OLD_STMT from the EH table and put NEW_STMT
    in the table if it should be in there.  Return TRUE if a replacement was
@@ -2520,12 +2489,7 @@ optimize_double_finally (tree one, tree 
       TREE_SET_CODE (one, TRY_CATCH_EXPR);
 
       i = tsi_start (TREE_OPERAND (two, 0));
-      /* FIXME tuples.  */
-#if 0
       tsi_link_before (&i, unsave_expr_now (b), TSI_SAME_STMT);
-#else
-      gimple_unreachable ();
-#endif
     }
 }
 
Index: gimple-pretty-print.c
===================================================================
--- gimple-pretty-print.c	(revision 132841)
+++ gimple-pretty-print.c	(working copy)
@@ -40,7 +40,7 @@ Software Foundation, 51 Franklin Street,
 static pretty_printer buffer;
 static bool initialized = false;
 
-#define GIMPLE_NIY do_niy(buffer,gs)
+#define GIMPLE_NIY do_niy (buffer,gs)
 
 /* Try to print on BUFFER a default message for the unrecognized
    gimple statement GS.  */
@@ -632,8 +632,7 @@ dump_gimple_resx (pretty_printer *buffer
     dump_gimple_fmt (buffer, spc, flags, "%G <%d>", gs,
                      gimple_resx_region (gs));
   else
-    dump_gimple_fmt (buffer, spc, flags, "resx %T", gimple_resx_region (gs));
-    GIMPLE_NIY;
+    dump_gimple_fmt (buffer, spc, flags, "resx %d", gimple_resx_region (gs));
 }
 
 /* Dump a GIMPLE_OMP_FOR tuple on the pretty_printer BUFFER.  */
Index: gimplify.c
===================================================================
--- gimplify.c	(revision 132841)
+++ gimplify.c	(working copy)
@@ -4500,7 +4500,7 @@ static enum gimplify_status
 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
 {
   gimple_stmt_iterator iter;
-  gimple_seq body_sequence;
+  gimple_seq body_sequence = NULL;
 
   tree temp = voidify_wrapper_expr (*expr_p, NULL);
 
Index: calls.c
===================================================================
--- calls.c	(revision 132841)
+++ calls.c	(working copy)
@@ -238,7 +238,7 @@ prepare_call_address (rtx funexp, rtx st
    denote registers used by the called function.  */
 
 static void
-emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNUSED,
+emit_call_1 (rtx funexp, tree fntree, tree fndecl ATTRIBUTE_UNUSED,
 	     tree funtype ATTRIBUTE_UNUSED,
 	     HOST_WIDE_INT stack_size ATTRIBUTE_UNUSED,
 	     HOST_WIDE_INT rounded_stack_size,
Index: cfgexpand.c
===================================================================
--- cfgexpand.c	(revision 132841)
+++ cfgexpand.c	(working copy)
@@ -208,7 +208,12 @@ gimple_to_tree (gimple stmt)
     break;
 
     case GIMPLE_NOP:
-      return build1 (NOP_EXPR, void_type_node, size_zero_node);
+      t = build1 (NOP_EXPR, void_type_node, size_zero_node);
+      break;
+
+    case GIMPLE_RESX:
+      t = build_resx (gimple_resx_region (stmt));
+      break;
 	
     default:
       error ("Unrecognized GIMPLE statement during RTL expansion");
@@ -221,8 +226,7 @@ gimple_to_tree (gimple stmt)
   {
     int rn = lookup_stmt_eh_region (stmt);
     tree_ann_common_t ann = get_tree_common_ann (t);
-    if (rn >= 0)
-      ann->rn = rn;
+    ann->rn = rn;
   }
 
   SET_EXPR_LOCATION (t, gimple_locus (stmt));
Index: tree-flow.h
===================================================================
--- tree-flow.h	(revision 132841)
+++ tree-flow.h	(working copy)
@@ -1049,7 +1049,6 @@ extern bool operation_could_trap_p (enum
 extern bool stmt_could_throw_p (gimple);
 extern bool tree_could_throw_p (tree);
 extern bool stmt_can_throw_internal (gimple);
-extern bool tree_can_throw_external (tree);
 extern void add_stmt_to_eh_region (gimple, int);
 extern bool remove_stmt_from_eh_region (gimple);
 extern bool maybe_clean_or_replace_eh_stmt (gimple, gimple);
@@ -1058,7 +1057,7 @@ extern bool remove_stmt_from_eh_region_f
 extern int lookup_stmt_eh_region_fn (struct function *, gimple);
 extern int lookup_expr_eh_region (tree);
 extern int lookup_stmt_eh_region (gimple);
-extern bool verify_eh_edges (tree);
+extern bool verify_eh_edges (gimple);
 
 
 /* In tree-ssa-pre.c  */
Index: tree-cfg.c
===================================================================
--- tree-cfg.c	(revision 132841)
+++ tree-cfg.c	(working copy)
@@ -700,8 +700,6 @@ start_recording_case_labels (void)
   edge_to_cases = pointer_map_create ();
 }
 
-/* FIXME tuples.  */
-#if 0
 /* Return nonzero if we are recording information for case labels.  */
 
 static bool
@@ -709,7 +707,6 @@ recording_case_labels_p (void)
 {
   return (edge_to_cases != NULL);
 }
-#endif
 
 /* Stop recording information mapping edges to case labels and
    remove any information we have recorded.  */
@@ -721,8 +718,6 @@ end_recording_case_labels (void)
   edge_to_cases = NULL;
 }
 
-/* FIXME tuples.  */
-#if 0
 /* If we are inside a {start,end}_recording_cases block, then return
    a chain of CASE_LABEL_EXPRs from T which reference E.
 
@@ -764,7 +759,6 @@ get_cases_for_edge (edge e, gimple t)
 
   return (tree) *pointer_map_contains (edge_to_cases, e);
 }
-#endif
 
 /* Create the edges for a GIMPLE_SWITCH starting at block BB.  */
 
@@ -4159,10 +4153,7 @@ gimple_verify_flow_info (void)
 
       stmt = gsi_stmt (gsi);
 
-      /* FIXME tuples.  */
-#if 0
       err |= verify_eh_edges (stmt);
-#endif
 
       if (is_ctrl_stmt (stmt))
 	{
@@ -4498,8 +4489,6 @@ gimple_redirect_edge_and_branch (edge e,
     case GIMPLE_SWITCH:
       {
 	tree label = gimple_block_label (dest);
-/* FIXME tuples.  */
-#if 0
         tree cases = get_cases_for_edge (e, stmt);
 
 	/* If we have a list of cases associated with E, then use it
@@ -4528,7 +4517,6 @@ gimple_redirect_edge_and_branch (edge e,
 	      }
 	  }
 	else
-#endif
 	  {
 	    size_t i, n = gimple_switch_num_labels (stmt);
 
@@ -6065,15 +6053,12 @@ debug_loop_num (unsigned num, int verbos
    instructions that must stay with the call.  Return false,
    otherwise.  */
 
-/* FIXME tuples.  */
-#if 0
 static bool
 gimple_block_ends_with_call_p (basic_block bb)
 {
-  gimple_stmt_iterator gsi = gsi_last (bb);
-  return get_call_expr_in (gsi_stmt (gsi)) != NULL;
+  gimple_stmt_iterator gsi = gsi_last_bb (bb);
+  return gimple_code (gsi_stmt (gsi)) == GIMPLE_CALL;
 }
-#endif
 
 
 /* Return true if BB ends with a conditional branch.  Return false,
@@ -6563,7 +6548,7 @@ struct cfg_hooks gimple_cfg_hooks = {
   gimple_split_edge,		/* split_edge  */
   gimple_make_forwarder_block,	/* make_forward_block  */
   NULL,				/* tidy_fallthru_edge  */
-  0 /* FIXME tuples gimple_block_ends_with_call_p */,	/* block_ends_with_call_p */
+  gimple_block_ends_with_call_p,/* block_ends_with_call_p */
   0 /* FIXME tuples gimple_block_ends_with_condjump_p */, /* block_ends_with_condjump_p */
   0 /* FIXME tuples gimple_flow_call_edges_add */,     /* flow_call_edges_add */
   gimple_execute_on_growing_pred,	/* execute_on_growing_pred */

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