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]

Cleanup some switch expanding code and leftovers from RTL EH


Hi,

While cleaning up a few more switch expanding related functions,
I noted some other garbage, mostly in stmt.c and emit-rtl.c, that
should go away.  Some of them are leftovers from rth removing RTL
exception handling, and the others because we already lower switch
statements in gimplify.c.

Bootstrapped&tested on x86_64-unknown-linux-gnu, OK?

Gr.
Steven


	* emit-rtl.c (force_line_numbers, restore_line_number_status):
	Remove.
	* rtl.h (force_line_numbers, restore_line_number_status):
	Remove prototypes.

	* stmt.c (using_eh_for_cleanups_p, using_eh_for_cleanups): Move...
	* tree-eh.c (using_eh_for_cleanups_p): ...here.  Make static.
	(using_eh_for_cleanups): Also moved here.

	* expr.c (expand_expr_real_1) <CASE_LABEL_EXPR>: Die if we see one.
	<SWITCH_EXPR>: Die if we have a non-NULL SWITCH_BODY.  Update calls
	to expand_start_case and add_case_node.
	* stmt.c (struct nesting): Cleanup unused fields condition_code,
	last_unconditional_cleanup, nominal_type, printname, and
	line_number_status.
	(struct fixup_goto): Remove.
	(struct stmt_status): Remove x_goto_fixup_chain field.
	(goto_fixup_chain): Remove.
	(strip_default_case_nodes, group_case_nodes, emit_jump_if_reachable,
	pushcase, pushcase_range): Remove.
	(expand_start_bindings_and_block): Don't set unused fields in
	the nesting stack.
	(expand_start_case, add_case_node): Cleanup unused formal arguments.
	(expand_end_case_type): Don't simplify the case-list.  Use emit_jump
	instead of emit_jump_if_reachable.
	(emit_case_nodes): Likewise.
	* tree-cfg.c (group_case_labels, cleanup_dead_labels): No longer
	static.
	(update_eh_label): Work around left-over exception handing regions.
	* tree-flow.h (group_case_labels, cleanup_dead_labels): Add protos.
	* tree-optimize.c (execute_cleanup_cfg_post_optimizing): New function.
	(pass_cleanup_cfg_post_optimizing): New pass.
	(init_tree_optimization_passes): Run the new pass after all
	optimizations.
	* tree.h (pushcase, pushcase_range): Remove prototypes.
	(expand_start_case, add_case_node): Update prototypes.

cp/
	* cp-tree.h (struct lang_type): Don't have three GTY options on a
	single bit GTY desc.

java/
	* parse.y (java_complete_expand_methods, java_expand_classes): Don't
	abuse restore_line_number_status.

Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/emit-rtl.c,v
retrieving revision 1.402
diff -c -3 -p -r1.402 emit-rtl.c
*** emit-rtl.c	9 Jul 2004 03:29:27 -0000	1.402
--- emit-rtl.c	11 Jul 2004 15:22:27 -0000
*************** init_emit_once (int line_numbers)
*** 5444,5470 ****
      pic_offset_table_rtx = gen_raw_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
  }
  
- /* Query and clear/ restore no_line_numbers.  This is used by the
-    switch / case handling in stmt.c to give proper line numbers in
-    warnings about unreachable code.  */
- 
- int
- force_line_numbers (void)
- {
-   int old = no_line_numbers;
- 
-   no_line_numbers = 0;
-   if (old)
-     force_next_line_note ();
-   return old;
- }
- 
- void
- restore_line_number_status (int old_value)
- {
-   no_line_numbers = old_value;
- }
- 
  /* Produce exact duplicate of insn INSN after AFTER.
     Care updating of libcall regions if present.  */
  
--- 5444,5449 ----
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.679
diff -c -3 -p -r1.679 expr.c
*** expr.c	11 Jul 2004 11:11:36 -0000	1.679
--- expr.c	11 Jul 2004 15:22:27 -0000
*************** expand_expr_real_1 (tree exp, rtx target
*** 8824,8829 ****
--- 8824,8830 ----
      case WITH_CLEANUP_EXPR:
      case CLEANUP_POINT_EXPR:
      case TARGET_EXPR:
+     case CASE_LABEL_EXPR:
        /* Lowered by gimplify.c.  */
        abort ();
  
*************** expand_expr_real_1 (tree exp, rtx target
*** 8842,8851 ****
        abort ();
  
      case SWITCH_EXPR:
!       expand_start_case (0, SWITCH_COND (exp), integer_type_node,
! 			 "switch");
        if (SWITCH_BODY (exp))
!         expand_expr_stmt (SWITCH_BODY (exp));
        if (SWITCH_LABELS (exp))
  	{
  	  tree duplicate = 0;
--- 8843,8853 ----
        abort ();
  
      case SWITCH_EXPR:
!       expand_start_case (SWITCH_COND (exp));
!       /* The switch body is lowered in gimplify.c, we should never have
! 	 switches with a non-NULL SWITCH_BODY here.  */
        if (SWITCH_BODY (exp))
!         abort ();
        if (SWITCH_LABELS (exp))
  	{
  	  tree duplicate = 0;
*************** expand_expr_real_1 (tree exp, rtx target
*** 8904,8910 ****
  		    }
  		}
  	      
! 	      add_case_node (case_low, case_high, CASE_LABEL (elt), &duplicate, true);
  	      if (duplicate)
  		abort ();
  	    }
--- 8906,8912 ----
  		    }
  		}
  	      
! 	      add_case_node (case_low, case_high, CASE_LABEL (elt), &duplicate);
  	      if (duplicate)
  		abort ();
  	    }
*************** expand_expr_real_1 (tree exp, rtx target
*** 8916,8931 ****
        expand_label (TREE_OPERAND (exp, 0));
        return const0_rtx;
  
-     case CASE_LABEL_EXPR:
-       {
- 	tree duplicate = 0;
- 	add_case_node (CASE_LOW (exp), CASE_HIGH (exp), CASE_LABEL (exp),
- 		       &duplicate, false);
- 	if (duplicate)
- 	  abort ();
- 	return const0_rtx;
-       }
- 
      case ASM_EXPR:
        expand_asm_expr (exp);
        return const0_rtx;
--- 8918,8923 ----
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.489
diff -c -3 -p -r1.489 rtl.h
*** rtl.h	9 Jul 2004 03:29:34 -0000	1.489
--- rtl.h	11 Jul 2004 15:22:28 -0000
*************** extern void remove_insn (rtx);
*** 2199,2209 ****
  extern void emit_insn_after_with_line_notes (rtx, rtx, rtx);
  extern enum rtx_code classify_insn (rtx);
  extern rtx emit (rtx);
- /* Query and clear/ restore no_line_numbers.  This is used by the
-    switch / case handling in stmt.c to give proper line numbers in
-    warnings about unreachable code.  */
- int force_line_numbers (void);
- void restore_line_number_status (int old_value);
  extern void renumber_insns (FILE *);
  extern void remove_unnecessary_notes (void);
  extern rtx delete_insn (rtx);
--- 2199,2204 ----
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.375
diff -c -3 -p -r1.375 stmt.c
*** stmt.c	10 Jul 2004 08:04:57 -0000	1.375
--- stmt.c	11 Jul 2004 15:22:28 -0000
*************** struct nesting GTY(())
*** 174,189 ****
  	     reverts to the saved target_temp_slot_level at the very
  	     end of the block.  */
  	  int block_target_temp_slot_level;
- 	  /* True if we are currently emitting insns in an area of
- 	     output code that is controlled by a conditional
- 	     expression.  This is used by the cleanup handling code to
- 	     generate conditional cleanup actions.  */
- 	  int conditional_code;
- 	  /* A place to move the start of the exception region for any
- 	     of the conditional cleanups, must be at the end or after
- 	     the start of the last unconditional cleanup, and before any
- 	     conditional branch points.  */
- 	  rtx last_unconditional_cleanup;
  	} GTY ((tag ("BLOCK_NESTING"))) block;
        /* For switch (C) or case (Pascal) statements.  */
        struct nesting_case
--- 174,179 ----
*************** struct nesting GTY(())
*** 199,212 ****
  	  tree default_label;
  	  /* The expression to be dispatched on.  */
  	  tree index_expr;
- 	  /* Type that INDEX_EXPR should be converted to.  */
- 	  tree nominal_type;
- 	  /* Name of this kind of statement, for warnings.  */
- 	  const char *printname;
- 	  /* Used to save no_line_numbers till we see the first case label.
- 	     We set this to -1 when we see the first case label in this
- 	     case statement.  */
- 	  int line_number_status;
  	} GTY ((tag ("CASE_NESTING"))) case_stmt;
      } GTY ((desc ("%1.desc"))) data;
  };
--- 189,194 ----
*************** do { struct nesting *target = STACK;			\
*** 234,265 ****
  	  nesting_stack = this->all; }			\
       while (this != target); } while (0)
  
- /* In some cases it is impossible to generate code for a forward goto
-    until the label definition is seen.  This happens when it may be necessary
-    for the goto to reset the stack pointer: we don't yet know how to do that.
-    So expand_goto puts an entry on this fixup list.
-    Each time a binding contour that resets the stack is exited,
-    we check each fixup.
-    If the target label has now been defined, we can insert the proper code.  */
- 
- struct goto_fixup GTY(())
- {
-   /* Points to following fixup.  */
-   struct goto_fixup *next;
-   /* Points to the insn before the jump insn.
-      If more code must be inserted, it goes after this insn.  */
-   rtx before_jump;
-   /* The LABEL_DECL that this jump is jumping to, or 0
-      for break, continue or return.  */
-   tree target;
-   /* The BLOCK for the place where this goto was found.  */
-   tree context;
-   /* The CODE_LABEL rtx that this is jumping to.  */
-   rtx target_rtl;
-   /* Number of binding contours started in current function
-      before the label reference.  */
-   int block_start_count;
- };
  
  struct stmt_status GTY(())
  {
--- 216,221 ----
*************** struct stmt_status GTY(())
*** 287,294 ****
    /* Location of last line-number note, whether we actually
       emitted it or not.  */
    location_t x_emit_locus;
- 
-   struct goto_fixup *x_goto_fixup_chain;
  };
  
  #define block_stack (cfun->stmt->x_block_stack)
--- 243,248 ----
*************** struct stmt_status GTY(())
*** 298,307 ****
  #define nesting_depth (cfun->stmt->x_nesting_depth)
  #define current_block_start_count (cfun->stmt->x_block_start_count)
  #define emit_locus (cfun->stmt->x_emit_locus)
- #define goto_fixup_chain (cfun->stmt->x_goto_fixup_chain)
- 
- /* Nonzero if we are using EH to handle cleanups.  */
- int using_eh_for_cleanups_p = 0;
  
  static int n_occurrences (int, const char *);
  static bool decl_conflicts_with_clobbers_p (tree, const HARD_REG_SET);
--- 252,257 ----
*************** static void expand_value_return (rtx);
*** 316,341 ****
  static void do_jump_if_equal (rtx, rtx, rtx, int);
  static int estimate_case_costs (case_node_ptr);
  static bool same_case_target_p (rtx, rtx);
- static void strip_default_case_nodes (case_node_ptr *, rtx);
  static bool lshift_cheap_p (void);
  static int case_bit_test_cmp (const void *, const void *);
  static void emit_case_bit_tests (tree, tree, tree, tree, case_node_ptr, rtx);
- static void group_case_nodes (case_node_ptr);
  static void balance_case_nodes (case_node_ptr *, case_node_ptr);
  static int node_has_low_bound (case_node_ptr, tree);
  static int node_has_high_bound (case_node_ptr, tree);
  static int node_is_bounded (case_node_ptr, tree);
- static void emit_jump_if_reachable (rtx);
  static void emit_case_nodes (rtx, case_node_ptr, rtx, tree);
  static struct case_node *case_tree2list (case_node *, case_node *);
  
  void
- using_eh_for_cleanups (void)
- {
-   using_eh_for_cleanups_p = 1;
- }
- 
- void
  init_stmt_for_function (void)
  {
    cfun->stmt = ggc_alloc_cleared (sizeof (struct stmt_status));
--- 266,282 ----
*************** expand_start_bindings_and_block (int fla
*** 2224,2231 ****
    thisblock->depth = ++nesting_depth;
    thisblock->data.block.block_target_temp_slot_level = target_temp_slot_level;
  
-   thisblock->data.block.conditional_code = 0;
-   thisblock->data.block.last_unconditional_cleanup = note;
    /* When we insert instructions after the last unconditional cleanup,
       we don't adjust last_insn.  That means that a later add_insn will
       clobber the instructions we've just added.  The easiest way to
--- 2165,2170 ----
*************** expand_anon_union_decl (tree decl, tree 
*** 2779,2786 ****
     but instead we take short cuts.  */
  
  void
! expand_start_case (int exit_flag, tree expr, tree type,
! 		   const char *printname)
  {
    struct nesting *thiscase = ALLOC_NESTING ();
  
--- 2718,2724 ----
     but instead we take short cuts.  */
  
  void
! expand_start_case (tree index_expr)
  {
    struct nesting *thiscase = ALLOC_NESTING ();
  
*************** expand_start_case (int exit_flag, tree e
*** 2790,2802 ****
    thiscase->next = case_stack;
    thiscase->all = nesting_stack;
    thiscase->depth = ++nesting_depth;
!   thiscase->exit_label = exit_flag ? gen_label_rtx () : 0;
    thiscase->data.case_stmt.case_list = 0;
!   thiscase->data.case_stmt.index_expr = expr;
!   thiscase->data.case_stmt.nominal_type = type;
    thiscase->data.case_stmt.default_label = 0;
-   thiscase->data.case_stmt.printname = printname;
-   thiscase->data.case_stmt.line_number_status = force_line_numbers ();
    case_stack = thiscase;
    nesting_stack = thiscase;
  
--- 2728,2737 ----
    thiscase->next = case_stack;
    thiscase->all = nesting_stack;
    thiscase->depth = ++nesting_depth;
!   thiscase->exit_label = 0;
    thiscase->data.case_stmt.case_list = 0;
!   thiscase->data.case_stmt.index_expr = index_expr;
    thiscase->data.case_stmt.default_label = 0;
    case_stack = thiscase;
    nesting_stack = thiscase;
  
*************** expand_start_case (int exit_flag, tree e
*** 2811,2929 ****
    thiscase->data.case_stmt.start = get_last_insn ();
  }
  
! /* Accumulate one case or default label inside a case or switch statement.
!    VALUE is the value of the case (a null pointer, for a default label).
!    The function CONVERTER, when applied to arguments T and V,
!    converts the value V to the type T.
! 
!    If not currently inside a case or switch statement, return 1 and do
!    nothing.  The caller will print a language-specific error message.
!    If VALUE is a duplicate or overlaps, return 2 and do nothing
!    except store the (first) duplicate node in *DUPLICATE.
!    If VALUE is out of range, return 3 and do nothing.
!    Return 0 on success.
! 
!    Extended to handle range statements.  */
! 
! int
! pushcase (tree value, tree (*converter) (tree, tree), tree label,
! 	  tree *duplicate)
! {
!   tree index_type;
!   tree nominal_type;
! 
!   /* Fail if not inside a real case statement.  */
!   if (! (case_stack && case_stack->data.case_stmt.start))
!     return 1;
! 
!   index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr);
!   nominal_type = case_stack->data.case_stmt.nominal_type;
! 
!   /* If the index is erroneous, avoid more problems: pretend to succeed.  */
!   if (index_type == error_mark_node)
!     return 0;
! 
!   /* Convert VALUE to the type in which the comparisons are nominally done.  */
!   if (value != 0)
!     value = (*converter) (nominal_type, value);
! 
!   /* Fail if this value is out of range for the actual type of the index
!      (which may be narrower than NOMINAL_TYPE).  */
!   if (value != 0
!       && (TREE_CONSTANT_OVERFLOW (value)
! 	  || ! int_fits_type_p (value, index_type)))
!     return 3;
! 
!   return add_case_node (value, value, label, duplicate, false);
! }
! 
! /* Like pushcase but this case applies to all values between VALUE1 and
!    VALUE2 (inclusive).  If VALUE1 is NULL, the range starts at the lowest
!    value of the index type and ends at VALUE2.  If VALUE2 is NULL, the range
!    starts at VALUE1 and ends at the highest value of the index type.
!    If both are NULL, this case applies to all values.
! 
!    The return value is the same as that of pushcase but there is one
!    additional error code: 4 means the specified range was empty.  */
! 
! int
! pushcase_range (tree value1, tree value2, tree (*converter) (tree, tree),
! 		tree label, tree *duplicate)
! {
!   tree index_type;
!   tree nominal_type;
! 
!   /* Fail if not inside a real case statement.  */
!   if (! (case_stack && case_stack->data.case_stmt.start))
!     return 1;
! 
!   index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr);
!   nominal_type = case_stack->data.case_stmt.nominal_type;
! 
!   /* If the index is erroneous, avoid more problems: pretend to succeed.  */
!   if (index_type == error_mark_node)
!     return 0;
! 
!   /* Convert VALUEs to type in which the comparisons are nominally done
!      and replace any unspecified value with the corresponding bound.  */
!   if (value1 == 0)
!     value1 = TYPE_MIN_VALUE (index_type);
!   if (value2 == 0)
!     value2 = TYPE_MAX_VALUE (index_type);
! 
!   /* Fail if the range is empty.  Do this before any conversion since
!      we want to allow out-of-range empty ranges.  */
!   if (value2 != 0 && tree_int_cst_lt (value2, value1))
!     return 4;
! 
!   /* If the max was unbounded, use the max of the nominal_type we are
!      converting to.  Do this after the < check above to suppress false
!      positives.  */
!   if (value2 == 0)
!     value2 = TYPE_MAX_VALUE (nominal_type);
! 
!   value1 = (*converter) (nominal_type, value1);
!   value2 = (*converter) (nominal_type, value2);
! 
!   /* Fail if these values are out of range.  */
!   if (TREE_CONSTANT_OVERFLOW (value1)
!       || ! int_fits_type_p (value1, index_type))
!     return 3;
! 
!   if (TREE_CONSTANT_OVERFLOW (value2)
!       || ! int_fits_type_p (value2, index_type))
!     return 3;
! 
!   return add_case_node (value1, value2, label, duplicate, false);
! }
! 
! /* Do the actual insertion of a case label for pushcase and pushcase_range
!    into case_stack->data.case_stmt.case_list.  Use an AVL tree to avoid
     slowdown for large switch statements.  */
  
  int
! add_case_node (tree low, tree high, tree label, tree *duplicate,
! 	       bool dont_expand_label)
  {
    struct case_node *p, **q, *r;
  
--- 2746,2757 ----
    thiscase->data.case_stmt.start = get_last_insn ();
  }
  
! /* Do the insertion of a case label into
!    case_stack->data.case_stmt.case_list.  Use an AVL tree to avoid
     slowdown for large switch statements.  */
  
  int
! add_case_node (tree low, tree high, tree label, tree *duplicate)
  {
    struct case_node *p, **q, *r;
  
*************** add_case_node (tree low, tree high, tree
*** 2942,2949 ****
  	  return 2;
  	}
        case_stack->data.case_stmt.default_label = label;
-       if (!dont_expand_label)
-         expand_label (label);
        return 0;
      }
  
--- 2770,2775 ----
*************** add_case_node (tree low, tree high, tree
*** 2982,2989 ****
      r->high = high;
  
    r->code_label = label;
-   if (!dont_expand_label)
-     expand_label (label);
  
    *q = r;
    r->parent = p;
--- 2808,2813 ----
*************** expand_end_case_type (tree orig_index, t
*** 3377,3387 ****
  	thiscase->data.case_stmt.case_list
  	  = case_tree2list (thiscase->data.case_stmt.case_list, 0);
  
-       /* Simplify the case-list before we count it.  */
-       group_case_nodes (thiscase->data.case_stmt.case_list);
-       strip_default_case_nodes (&thiscase->data.case_stmt.case_list,
- 				default_label);
- 
        /* Get upper and lower bounds of case values.
  	 Also convert all the case values to the index expr's data type.  */
  
--- 3201,3206 ----
*************** expand_end_case_type (tree orig_index, t
*** 3559,3565 ****
  	      balance_case_nodes (&thiscase->data.case_stmt.case_list, NULL);
  	      emit_case_nodes (index, thiscase->data.case_stmt.case_list,
  			       default_label, index_type);
! 	      emit_jump_if_reachable (default_label);
  	    }
  	}
        else
--- 3378,3384 ----
  	      balance_case_nodes (&thiscase->data.case_stmt.case_list, NULL);
  	      emit_case_nodes (index, thiscase->data.case_stmt.case_list,
  			       default_label, index_type);
! 	      emit_jump (default_label);
  	    }
  	}
        else
*************** expand_end_case_type (tree orig_index, t
*** 3568,3574 ****
  	  if (! try_casesi (index_type, index_expr, minval, range,
  			    table_label, default_label))
  	    {
! 	      index_type = thiscase->data.case_stmt.nominal_type;
  
  	      /* Index jumptables from zero for suitable values of
                   minval to avoid a subtraction.  */
--- 3387,3393 ----
  	  if (! try_casesi (index_type, index_expr, minval, range,
  			    table_label, default_label))
  	    {
! 	      index_type = integer_type_node;
  
  	      /* Index jumptables from zero for suitable values of
                   minval to avoid a subtraction.  */
*************** estimate_case_costs (case_node_ptr node)
*** 3770,3869 ****
    return 1;
  }
  
! /* Determine whether two case labels branch to the same target.  */
  
  static bool
  same_case_target_p (rtx l1, rtx l2)
  {
- #if 0
-   rtx i1, i2;
- 
-   if (l1 == l2)
-     return true;
- 
-   i1 = next_real_insn (l1);
-   i2 = next_real_insn (l2);
-   if (i1 == i2)
-     return true;
- 
-   if (i1 && simplejump_p (i1))
-     {
-       l1 = XEXP (SET_SRC (PATTERN (i1)), 0);
-     }
- 
-   if (i2 && simplejump_p (i2))
-     {
-       l2 = XEXP (SET_SRC (PATTERN (i2)), 0);
-     }
- #endif
-   /* When coming from gimple, we usually won't have emitted either
-      the labels or the body of the switch statement.  The job being
-      done here should be done via jump threading at the tree level.
-      Cases that go the same place should have the same label.  */
    return l1 == l2;
  }
  
- /* Delete nodes that branch to the default label from a list of
-    case nodes.  Eg. case 5: default: becomes just default:  */
- 
- static void
- strip_default_case_nodes (case_node_ptr *prev, rtx deflab)
- {
-   case_node_ptr ptr;
- 
-   while (*prev)
-     {
-       ptr = *prev;
-       if (same_case_target_p (label_rtx (ptr->code_label), deflab))
- 	*prev = ptr->right;
-       else
- 	prev = &ptr->right;
-     }
- }
- 
- /* Scan an ordered list of case nodes
-    combining those with consecutive values or ranges.
- 
-    Eg. three separate entries 1: 2: 3: become one entry 1..3:  */
- 
- static void
- group_case_nodes (case_node_ptr head)
- {
-   case_node_ptr node = head;
- 
-   while (node)
-     {
-       rtx lab;
-       case_node_ptr np = node;
- 
-       lab = label_rtx (node->code_label);
- 
-       /* Try to group the successors of NODE with NODE.  */
-       while (((np = np->right) != 0)
- 	     /* Do they jump to the same place?  */
- 	     && same_case_target_p (label_rtx (np->code_label), lab)
- 	     /* Are their ranges consecutive?  */
- 	     && tree_int_cst_equal (np->low,
- 				    fold (build (PLUS_EXPR,
- 						 TREE_TYPE (node->high),
- 						 node->high,
- 						 integer_one_node)))
- 	     /* An overflow is not consecutive.  */
- 	     && tree_int_cst_lt (node->high,
- 				 fold (build (PLUS_EXPR,
- 					      TREE_TYPE (node->high),
- 					      node->high,
- 					      integer_one_node))))
- 	{
- 	  node->high = np->high;
- 	}
-       /* NP is the first node after NODE which can't be grouped with it.
- 	 Delete the nodes in between, and move on to that node.  */
-       node->right = np;
-       node = np;
-     }
- }
- 
  /* Take an ordered list of case nodes
     and transform them into a near optimal binary tree,
     on the assumption that any target code selection value is as
--- 3589,3604 ----
    return 1;
  }
  
! /* Determine whether two case labels branch to the same target.
!    Since we now do tree optimizations, just comparing labels is
!    good enough.  */
  
  static bool
  same_case_target_p (rtx l1, rtx l2)
  {
    return l1 == l2;
  }
  
  /* Take an ordered list of case nodes
     and transform them into a near optimal binary tree,
     on the assumption that any target code selection value is as
*************** node_is_bounded (case_node_ptr node, tre
*** 4086,4100 ****
    return (node_has_low_bound (node, index_type)
  	  && node_has_high_bound (node, index_type));
  }
- 
- /*  Emit an unconditional jump to LABEL unless it would be dead code.  */
- 
- static void
- emit_jump_if_reachable (rtx label)
- {
-   if (!BARRIER_P (get_last_insn ()))
-     emit_jump (label);
- }
  
  /* Emit step-by-step code to select a case for the value of INDEX.
     The thus generated decision tree follows the form of the
--- 3821,3826 ----
*************** emit_case_nodes (rtx index, case_node_pt
*** 4240,4246 ****
  	      emit_case_nodes (index, node->left, default_label, index_type);
  	      /* If left-hand subtree does nothing,
  		 go to default.  */
! 	      emit_jump_if_reachable (default_label);
  
  	      /* Code branches here for the right-hand subtree.  */
  	      expand_label (test_label);
--- 3966,3972 ----
  	      emit_case_nodes (index, node->left, default_label, index_type);
  	      /* If left-hand subtree does nothing,
  		 go to default.  */
! 	      emit_jump (default_label);
  
  	      /* Code branches here for the right-hand subtree.  */
  	      expand_label (test_label);
*************** emit_case_nodes (rtx index, case_node_pt
*** 4381,4387 ****
  	    {
  	      /* If the left-hand subtree fell through,
  		 don't let it fall into the right-hand subtree.  */
! 	      emit_jump_if_reachable (default_label);
  
  	      expand_label (test_label);
  	      emit_case_nodes (index, node->right, default_label, index_type);
--- 4107,4113 ----
  	    {
  	      /* If the left-hand subtree fell through,
  		 don't let it fall into the right-hand subtree.  */
! 	      emit_jump (default_label);
  
  	      expand_label (test_label);
  	      emit_case_nodes (index, node->right, default_label, index_type);
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-cfg.c,v
retrieving revision 2.29
diff -c -3 -p -r2.29 tree-cfg.c
*** tree-cfg.c	9 Jul 2004 22:42:37 -0000	2.29
--- tree-cfg.c	11 Jul 2004 15:22:28 -0000
*************** static void tree_cfg2vcg (FILE *);
*** 99,106 ****
  static void tree_merge_blocks (basic_block, basic_block);
  static bool tree_can_merge_blocks_p (basic_block, basic_block);
  static void remove_bb (basic_block);
- static void group_case_labels (void);
- static void cleanup_dead_labels (void);
  static bool cleanup_control_flow (void);
  static bool cleanup_control_expr_graph (basic_block, block_stmt_iterator);
  static edge find_taken_edge_cond_expr (basic_block, tree);
--- 99,104 ----
*************** update_eh_label (struct eh_region *regio
*** 769,775 ****
    tree old_label = get_eh_region_tree_label (region);
    if (old_label)
      {
!       tree new_label = label_for_bb[label_to_block (old_label)->index];
        set_eh_region_tree_label (region, new_label);
      }
  }
--- 767,782 ----
    tree old_label = get_eh_region_tree_label (region);
    if (old_label)
      {
!       tree new_label;
!       basic_block bb = label_to_block (old_label);
! 
!       /* ??? After optimizing, there may be EH regions with labels
! 	 that have already been removed from the function body, so
! 	 there is no basic block for them.  */
!       if (! bb)
! 	return;
! 
!       new_label = label_for_bb[bb->index];
        set_eh_region_tree_label (region, new_label);
      }
  }
*************** main_block_label (tree label)
*** 791,797 ****
       2) Redirect all references to labels to the leading labels.
       3) Cleanup all useless labels.  */
  
! static void
  cleanup_dead_labels (void)
  {
    basic_block bb;
--- 798,804 ----
       2) Redirect all references to labels to the leading labels.
       3) Cleanup all useless labels.  */
  
! void
  cleanup_dead_labels (void)
  {
    basic_block bb;
*************** cleanup_dead_labels (void)
*** 924,930 ****
     same label.
     Eg. three separate entries 1: 2: 3: become one entry 1..3:  */
  
! static void
  group_case_labels (void)
  {
    basic_block bb;
--- 931,937 ----
     same label.
     Eg. three separate entries 1: 2: 3: become one entry 1..3:  */
  
! void
  group_case_labels (void)
  {
    basic_block bb;
Index: tree-eh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-eh.c,v
retrieving revision 2.10
diff -c -3 -p -r2.10 tree-eh.c
*** tree-eh.c	10 Jul 2004 04:57:54 -0000	2.10
--- tree-eh.c	11 Jul 2004 15:22:28 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 37,44 ****
  #include "langhooks.h"
  #include "ggc.h"
  
! /* HACK */
! extern int using_eh_for_cleanups_p;
  
  /* Misc functions used in this file.  */
  
--- 37,51 ----
  #include "langhooks.h"
  #include "ggc.h"
  
! 
! /* Nonzero if we are using EH to handle cleanups.  */
! static int using_eh_for_cleanups_p = 0;
! 
! void
! using_eh_for_cleanups (void)
! {
!   using_eh_for_cleanups_p = 1;
! }
  
  /* Misc functions used in this file.  */
  
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-flow.h,v
retrieving revision 2.23
diff -c -3 -p -r2.23 tree-flow.h
*** tree-flow.h	10 Jul 2004 04:57:54 -0000	2.23
--- tree-flow.h	11 Jul 2004 15:22:28 -0000
*************** extern void dump_cfg_stats (FILE *);
*** 486,491 ****
--- 486,493 ----
  extern void debug_cfg_stats (void);
  extern void debug_loop_ir (void);
  extern void print_loop_ir (FILE *);
+ extern void cleanup_dead_labels (void);
+ extern void group_case_labels (void);
  extern void cleanup_tree_cfg (void);
  extern tree first_stmt (basic_block);
  extern tree last_stmt (basic_block);
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v
retrieving revision 2.28
diff -c -3 -p -r2.28 tree-optimize.c
*** tree-optimize.c	10 Jul 2004 04:57:54 -0000	2.28
--- tree-optimize.c	11 Jul 2004 15:22:28 -0000
*************** static struct tree_opt_pass pass_all_opt
*** 101,106 ****
--- 101,135 ----
    0					/* todo_flags_finish */
  };
  
+ /* Pass: cleanup the CFG just before expanding trees to RTL.
+    This is just a round of label cleanups and case node grouping
+    because after the tree optimizers have run such cleanups may
+    may be necessary.  */
+ 
+ static void 
+ execute_cleanup_cfg_post_optimizing (void)
+ {
+   cleanup_tree_cfg ();
+   cleanup_dead_labels ();
+   group_case_labels ();
+ }
+ 
+ static struct tree_opt_pass pass_cleanup_cfg_post_optimizing=
+ {
+   NULL,					/* name */
+   NULL,					/* gate */
+   execute_cleanup_cfg_post_optimizing,	/* execute */
+   NULL,					/* sub */
+   NULL,					/* next */
+   0,					/* static_pass_number */
+   0,					/* tv_id */
+   PROP_cfg,				/* properties_required */
+   0,					/* properties_provided */
+   0,					/* properties_destroyed */
+   0,					/* todo_flags_start */
+   0					/* todo_flags_finish */
+ };
+ 
  /* Pass: do the actions required to finish with tree-ssa optimization
     passes.  */
  
*************** init_tree_optimization_passes (void)
*** 324,329 ****
--- 353,359 ----
    NEXT_PASS (pass_del_ssa);
    NEXT_PASS (pass_nrv);
    NEXT_PASS (pass_remove_useless_vars);
+   NEXT_PASS (pass_cleanup_cfg_post_optimizing);
    *p = NULL;
  
    p = &pass_loop.sub;
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.554
diff -c -3 -p -r1.554 tree.h
*** tree.h	11 Jul 2004 10:04:57 -0000	1.554
--- tree.h	11 Jul 2004 15:22:29 -0000
*************** extern void warn_about_unused_variables 
*** 3352,3363 ****
  extern int is_body_block (tree);
  
  extern struct nesting * current_nesting_level (void);
! extern void expand_start_case (int, tree, tree, const char *);
  extern void expand_end_case_type (tree, tree);
  #define expand_end_case(cond) expand_end_case_type (cond, NULL)
! extern int add_case_node (tree, tree, tree, tree *, bool);
! extern int pushcase (tree, tree (*) (tree, tree), tree, tree *);
! extern int pushcase_range (tree, tree, tree (*) (tree, tree), tree, tree *);
  extern void using_eh_for_cleanups (void);
  
  /* In fold-const.c */
--- 3352,3363 ----
  extern int is_body_block (tree);
  
  extern struct nesting * current_nesting_level (void);
! extern void expand_start_case (tree);
  extern void expand_end_case_type (tree, tree);
  #define expand_end_case(cond) expand_end_case_type (cond, NULL)
! extern int add_case_node (tree, tree, tree, tree *);
! 
! /* In tree-eh.c */
  extern void using_eh_for_cleanups (void);
  
  /* In fold-const.c */
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1000
diff -c -3 -p -r1.1000 cp-tree.h
*** cp/cp-tree.h	11 Jul 2004 09:53:02 -0000	1.1000
--- cp/cp-tree.h	11 Jul 2004 15:22:33 -0000
*************** struct lang_type GTY(())
*** 1049,1055 ****
  {
    union lang_type_u 
    {
!     struct lang_type_header GTY((tag ("2"))) h;
      struct lang_type_class  GTY((tag ("1"))) c;
      struct lang_type_ptrmem GTY((tag ("0"))) ptrmem;
    } GTY((desc ("%h.h.is_lang_type_class"))) u;
--- 1049,1055 ----
  {
    union lang_type_u 
    {
!     struct lang_type_header GTY((skip (""))) h;
      struct lang_type_class  GTY((tag ("1"))) c;
      struct lang_type_ptrmem GTY((tag ("0"))) ptrmem;
    } GTY((desc ("%h.h.is_lang_type_class"))) u;
Index: java/parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.491
diff -c -3 -p -r1.491 parse.y
*** java/parse.y	10 Jul 2004 05:38:15 -0000	1.491
--- java/parse.y	11 Jul 2004 15:22:35 -0000
*************** java_complete_expand_methods (tree class
*** 7746,7766 ****
    /* Now do the constructors */
    for (decl = first_decl ; !java_error_count && decl; decl = TREE_CHAIN (decl))
      {
-       int no_body;
- 
        if (!DECL_CONSTRUCTOR_P (decl))
  	continue;
- 
-       no_body = !DECL_FUNCTION_BODY (decl);
-       /* Don't generate debug info on line zero when expanding a
- 	 generated constructor. */
-       if (no_body)
- 	restore_line_number_status (1);
- 
        java_complete_expand_method (decl);
- 
-       if (no_body)
- 	restore_line_number_status (0);
      }
  
    /* First, do the ordinary methods. */
--- 7746,7754 ----
*************** java_expand_classes (void)
*** 9036,9044 ****
  		{
  		  if (DECL_CONSTRUCTOR_P (d))
  		    {
- 		      restore_line_number_status (1);
  		      java_complete_expand_method (d);
- 		      restore_line_number_status (0);
  		      break;	/* There is only one constructor. */
  		    }
  		}
--- 9024,9030 ----
*************** java_expand_classes (void)
*** 9060,9070 ****
  	  for (d = TYPE_METHODS (current_class); d; d = TREE_CHAIN (d))
  	    {
  	      if (DECL_RESULT (d) == NULL_TREE)
! 		{
! 		  restore_line_number_status (1);
! 		  java_complete_expand_method (d);
! 		  restore_line_number_status (0);
! 		}
  	    }
  	}
      }
--- 9046,9052 ----
  	  for (d = TYPE_METHODS (current_class); d; d = TREE_CHAIN (d))
  	    {
  	      if (DECL_RESULT (d) == NULL_TREE)
! 		java_complete_expand_method (d);
  	    }
  	}
      }
*************** java_expand_classes (void)
*** 9093,9101 ****
  		      if (DECL_RESULT (d) == NULL_TREE)
  			{
  			  something_changed = 1;
- 			  restore_line_number_status (1);
  			  java_complete_expand_method (d);
- 			  restore_line_number_status (0);
  			}
  		    }
  		}
--- 9075,9081 ----


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