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]

Fix the tree part of the mainline breakage


Hi,

This _should_ fix the eon breakage that Diego saw.
I say "should" because exception handling on mainline is so
broken now that I can't properly test this patch.

[ And when I revert Honza's patch to i386.md, I get another
  exceptions related failure that I cannot see being caused by
  my switch handling efforts:
====================================
int
_Unwind_ForcedUnwind (void)
{
  long offset;
  void *handler;
  __builtin_eh_return (offset, handler);
}

Analyzing compilation unit
Performing intraprocedural optimizations
Assembling functions:

 _Unwind_ForcedUnwind

t.i: In function `_Unwind_ForcedUnwind':
t.i:7: internal compiler error: in make_edges, at cfgbuild.c:394
====================================
  ]

Since I'm away from my computer until tomorrow, I wanted to
post this now.  I just completely overlooked the fact that
in tree-eh.c we create a SWITCH_EXPR after gimplifying, and
the assumption that SWITCH_LABELS is sorted did not hold for
the switches created here.

Gr.
Steven

	* gimplify.c (sort_case_labels): New.  Split out from...
	(gimplify_switch_expr): ...here.  Use it.
	* tree-eh.c (lower_try_finally_switch): Sort the labels of
	the SWITCH_EXPR created here before leaving the function.
	* tree.c (sort_case_labels): Add prototype.
	
Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.6
diff -c -3 -p -r2.6 gimplify.c
*** gimplify.c	26 May 2004 22:36:49 -0000	2.6
--- gimplify.c	27 May 2004 18:58:23 -0000
*************** compare_case_labels (const void *p1, con
*** 994,999 ****
--- 994,1030 ----
    return tree_int_cst_compare (CASE_LOW (case1), CASE_LOW (case2));
  }
  
+ /* Sort the case labels in LABEL_VEC in ascending order.  */
+ 
+ void
+ sort_case_labels (tree label_vec)
+ {
+   size_t len = TREE_VEC_LENGTH (label_vec);
+   tree default_case = TREE_VEC_ELT (label_vec, len - 1);
+ 
+   if (CASE_LOW (default_case))
+     {
+       size_t i;
+ 
+       /* The last label in the vector should be the default case
+          but it is not.  */
+       for (i = 0; i < len; ++i)
+ 	{
+ 	  tree t = TREE_VEC_ELT (label_vec, i);
+ 	  if (!CASE_LOW (t))
+ 	    {
+ 	      default_case = t;
+ 	      TREE_VEC_ELT (label_vec, i) = TREE_VEC_ELT (label_vec, len - 1);
+ 	      TREE_VEC_ELT (label_vec, len - 1) = default_case;
+ 	      break;
+ 	    }
+ 	}
+     }
+ 
+   qsort (&TREE_VEC_ELT (label_vec, 0), len - 1, sizeof (tree),
+ 	 compare_case_labels);
+ }
+ 
  /* Gimplify a SWITCH_EXPR, and collect a TREE_VEC of the labels it can
     branch to.  */
  
*************** gimplify_switch_expr (tree *expr_p, tree
*** 1057,1068 ****
        else
  	*expr_p = SWITCH_BODY (switch_expr);
  
-       qsort (&VARRAY_TREE (labels, 0), len, sizeof (tree),
- 	     compare_case_labels);
        for (i = 0; i < len; ++i)
  	TREE_VEC_ELT (label_vec, i) = VARRAY_TREE (labels, i);
        TREE_VEC_ELT (label_vec, len) = default_case;
  
        SWITCH_BODY (switch_expr) = NULL;
      }
    else if (!SWITCH_LABELS (switch_expr))
--- 1088,1099 ----
        else
  	*expr_p = SWITCH_BODY (switch_expr);
  
        for (i = 0; i < len; ++i)
  	TREE_VEC_ELT (label_vec, i) = VARRAY_TREE (labels, i);
        TREE_VEC_ELT (label_vec, len) = default_case;
  
+       sort_case_labels (label_vec);
+ 
        SWITCH_BODY (switch_expr) = NULL;
      }
    else if (!SWITCH_LABELS (switch_expr))
Index: tree-eh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-eh.c,v
retrieving revision 2.1
diff -c -3 -p -r2.1 tree-eh.c
*** tree-eh.c	13 May 2004 06:39:48 -0000	2.1
--- tree-eh.c	27 May 2004 18:58:24 -0000
*************** lower_try_finally_switch (struct leh_sta
*** 1200,1207 ****
    replace_goto_queue (tf);
    last_case_index += nlabels;
  
!   /* Make sure that we have a default label, as one is required.  */
    CASE_LOW (last_case) = NULL;
  
    /* Need to link switch_stmt after running replace_goto_queue due
       to not wanting to process the same goto stmts twice.  */
--- 1200,1209 ----
    replace_goto_queue (tf);
    last_case_index += nlabels;
  
!   /* Make sure that the last case is the default label, as one is required.
!      Then sort the labels, which is also required in GIMPLE.  */
    CASE_LOW (last_case) = NULL;
+   sort_case_labels (case_label_vec);
  
    /* Need to link switch_stmt after running replace_goto_queue due
       to not wanting to process the same goto stmts twice.  */
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.500
diff -c -3 -p -r1.500 tree.h
*** tree.h	26 May 2004 23:22:04 -0000	1.500
--- tree.h	27 May 2004 18:58:24 -0000
*************** extern tree create_artificial_label (voi
*** 3675,3680 ****
--- 3675,3681 ----
  extern void gimplify_function_tree (tree);
  extern const char *get_name (tree);
  extern tree unshare_expr (tree);
+ extern void sort_case_labels (tree);
  
  /* If KIND=='I', return a suitable global initializer (constructor) name.
     If KIND=='D', return a suitable global clean-up (destructor) name.  */


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