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]

[tree-ssa] Make assignment of scopes independent on bind_exprs


Hello,

the patch implements this change (more or less):

> At the moment, rtl has two things that compose the block tree:
> (1) the block tree itself, rooted by DECL_INITIAL (fndecl),
> (2) the locator identifier in INSN_LOCATOR, which maps back
>     to the block in the block tree.
> 
> Since we are prepared to rebuild the block tree after optimization,
> all you have to do is make sure that INSN_LOCATOR gets built properly;
> everything else should Just Work.
> 
> And it seems to me that you could do that with only minor changes.
> Especially if you hijack expand_expr by renaming the existing function
> and providing a new wrapper that examines the expr being expanded and
> installs INSN_LOCATOR for each insn created for the expr if we had
> data for it in stmt_ann.  Or something.
> 
> 
> r~

notes and differences against the described proposal:

1) Recording of scope for statements is done in gimple-low.c, which
   should be place where lowering of gimple to unstructured form
   (including elimination of bind_exprs) occurs.
2) I could not use INSN_LOCATOR directly, since it is also used for
   recording line numbers.  Also the arrays for INSN_LOCATOR are global,
   which would cause problems with deferred functions.  I have therefore
   added a new array to map insns to scopes to cfun; this is transfered
   to INSN_LOCATOR stuff at the same place "notes -> INSN_LOCATOR"
   transition would occur.
3) Recording of the scopes to the array is done based on growing uids of
   generated insns -- i.e. all insns produced between two statements
   with blocks assigned are set to belong to the former block.  Not
   really sure how well it works, the testcases I tried it on looked
   sane.
4) Unlike in INSN_LOCATOR arrays, I record the scope for insn directly,
   not just the block boundaries.  By my tests the former requieres
   about 5x more memory, which seems acceptable to me (its just an array
   of pointers) and it avoids a need for binary search when finding the
   insn's scope.

Zdenek

	* gimple-low.c: New.
	* Makefile.in (gimple-low.o): Add.
	(tree-optimize.c): Add function.h dependency.
	* cfglayout.c (insn_locators_initialize): Use new info about blocks.
	* expr.c (expand_expr): Record block changes.
	* function.c (blocks_nreverse): Export.
	(uninitialized_vars_warning): Use DECL_RTL_SET_P to test for presence
	of rtl.
	(reset_block_changes, record_block_change, finalize_block_changes,
	check_block_change, free_block_changes): New functions.
	* function.h (struct function): New bitfield dont_emit_block_notes.
	New field ib_boundaries_block.
	(blocks_nreverse, reset_block_changes, record_block_change,
	finalize_block_changes, check_block_change,
	free_block_changes): Declare.
	* sibcall.c (optimize_sibling_and_tail_recursive_call): Don't call
	reorder_blocks when dont_emit_block_notes.
	* stmt.c (expand_start_bindings_and_block, expand_end_bindings):
	Don't emit block notes when dont_emit_block_notes.
	* toplev.c (rest_of_compilation): Don't call reorder_blocks when
	dont_emit_block_notes.
	* tree-flow.h (lower_function_body): Declare.
	* tree-optimize.c: Include function.h.
	(optimize_function_tree): Call lower_function_body.
	* tree.h (struct tree_exp): Add block field.
	(TREE_BLOCK): New macro.

gimple-low.c:

/* Tree lowering pass.  Lowers GIMPLE into unstructured form.

   Copyright (C) 2003 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 2, 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 COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "errors.h"
#include "varray.h"
#include "tree-simple.h"
#include "tree-inline.h"
#include "diagnostic.h"
#include "langhooks.h"
#include "langhooks-def.h"
#include "tree-flow.h"
#include "timevar.h"
#include "except.h"
#include "hashtab.h"
#include "flags.h"
#include "function.h"

struct lower_data
{
  /* Block the current statement belongs to.  */
  tree block;
};

static void lower_stmt_body (tree *, struct lower_data *);
static void lower_stmt (tree_stmt_iterator *, struct lower_data *);
static void lower_bind_expr (tree_stmt_iterator *, struct lower_data *);
static void lower_loop_expr (tree_stmt_iterator *, struct lower_data *);
static void lower_cond_expr (tree_stmt_iterator *, struct lower_data *);
static void lower_switch_expr (tree_stmt_iterator *, struct lower_data *);
static void lower_try_finally_expr (tree_stmt_iterator *, struct lower_data *);
static void lower_try_catch_expr (tree_stmt_iterator *, struct lower_data *);
static void lower_eh_filter_expr (tree_stmt_iterator *, struct lower_data *);
static void lower_catch_expr (tree_stmt_iterator *, struct lower_data *);

/* Lowers the BODY.  */
void
lower_function_body (tree *body)
{
  struct lower_data data;

  if (TREE_CODE (*body) != BIND_EXPR)
    abort ();

  data.block = DECL_INITIAL (current_function_decl);
  BLOCK_SUBBLOCKS (data.block) = NULL_TREE;
  BLOCK_CHAIN (data.block) = NULL_TREE;

  lower_stmt_body (&BIND_EXPR_BODY (*body), &data);

  if (data.block != DECL_INITIAL (current_function_decl))
    abort ();
  BLOCK_SUBBLOCKS (data.block) =
	  blocks_nreverse (BLOCK_SUBBLOCKS (data.block));
}

/* Lowers the EXPR.  Unlike gimplification the statements are not relowered
   when they are changed -- if this has to be done, the lowering routine must
   do it explicitly.  DATA is passed through the recursion.  */

static void
lower_stmt_body (tree *expr, struct lower_data *data)
{
  tree_stmt_iterator tsi;

  for (tsi = tsi_start (expr); !tsi_end_p (tsi); tsi_next (&tsi))
    lower_stmt (&tsi, data);
}

/* Lowers statement TSI.  DATA is passed through the recursion.  */
static void
lower_stmt (tree_stmt_iterator *tsi, struct lower_data *data)
{
  tree stmt = tsi_stmt (*tsi);

  if (TREE_LOCUS (stmt))
    TREE_BLOCK (stmt) = data->block;

  switch (TREE_CODE (stmt))
    {
    case BIND_EXPR:
      lower_bind_expr (tsi, data);
      break;

    case COMPOUND_EXPR:
      abort ();

    case NOP_EXPR:
    case ASM_EXPR:
    case RETURN_EXPR:
    case MODIFY_EXPR:
    case CALL_EXPR:
    case GOTO_EXPR:
    case LABEL_EXPR:
    case CASE_LABEL_EXPR:
    case VA_ARG_EXPR:
      break;

    case LOOP_EXPR:
      lower_loop_expr (tsi, data);
      break;

    case COND_EXPR:
      lower_cond_expr (tsi, data);
      break;

    case SWITCH_EXPR:
      lower_switch_expr (tsi, data);
      break;

    case TRY_FINALLY_EXPR:
      lower_try_finally_expr (tsi, data);
      break;

    case TRY_CATCH_EXPR:
      lower_try_catch_expr (tsi, data);
      break;

    case EH_FILTER_EXPR:
      lower_eh_filter_expr (tsi, data);
      break;

    case CATCH_EXPR:
      lower_catch_expr (tsi, data);
      break;

    default:
      print_node_brief (stderr, "", tsi_stmt (*tsi), 0);
      abort ();
    }
}

/* Lowers a bind_expr TSI.  DATA is passed through the recursion.  */

static void
lower_bind_expr (tree_stmt_iterator *tsi, struct lower_data *data)
{
  tree old_block = data->block;
  tree stmt = tsi_stmt (*tsi);

  if (BIND_EXPR_BLOCK (stmt))
    {
      data->block = BIND_EXPR_BLOCK (stmt);

      /* Block tree may get clobbered by inlining.  Normally this would be
	 fixed in rest_of_decl_compilation using block notes, but since we
	 are not going to emit them, it is up to us.  */
      BLOCK_CHAIN (data->block) = BLOCK_SUBBLOCKS (old_block);
      BLOCK_SUBBLOCKS (old_block) = data->block;
      BLOCK_SUBBLOCKS (data->block) = NULL_TREE;
      BLOCK_SUPERCONTEXT (data->block) = old_block;
    }
  lower_stmt_body (&BIND_EXPR_BODY (stmt), data);

  if (BIND_EXPR_BLOCK (stmt))
    {
      if (data->block != BIND_EXPR_BLOCK (stmt))
	abort ();

      BLOCK_SUBBLOCKS (data->block) =
	      blocks_nreverse (BLOCK_SUBBLOCKS (data->block));
      data->block = old_block;
    }
}

/* Lowers a loop_expr TSI.  DATA is passed through the recursion.  */

static void
lower_loop_expr (tree_stmt_iterator *tsi, struct lower_data *data)
{
  lower_stmt_body (&LOOP_EXPR_BODY (tsi_stmt (*tsi)), data);
}

/* Lowers a cond_expr TSI.  DATA is passed through the recursion.  */

static void
lower_cond_expr (tree_stmt_iterator *tsi, struct lower_data *data)
{
  tree stmt = tsi_stmt (*tsi);

  lower_stmt_body (&COND_EXPR_THEN (stmt), data);
  lower_stmt_body (&COND_EXPR_ELSE (stmt), data);
}

/* Lowers a switch_expr TSI.  DATA is passed through the recursion.  */

static void
lower_switch_expr (tree_stmt_iterator *tsi, struct lower_data *data)
{
  lower_stmt_body (&SWITCH_BODY (tsi_stmt (*tsi)), data);
}

/* Lowers a try_finally_expr TSI.  DATA is passed through the recursion.  */

static void
lower_try_finally_expr (tree_stmt_iterator *tsi, struct lower_data *data)
{
  lower_stmt_body (&TREE_OPERAND (tsi_stmt (*tsi), 0), data);
  lower_stmt_body (&TREE_OPERAND (tsi_stmt (*tsi), 1), data);
}

/* Lowers a try_catch_expr TSI.  DATA is passed through the recursion.  */

static void
lower_try_catch_expr (tree_stmt_iterator *tsi, struct lower_data *data)
{
  lower_stmt_body (&TREE_OPERAND (tsi_stmt (*tsi), 0), data);
  lower_stmt_body (&TREE_OPERAND (tsi_stmt (*tsi), 1), data);
}

/* Lowers an eh_filter_expr TSI.  DATA is passed through the recursion.  */

static void
lower_eh_filter_expr (tree_stmt_iterator *tsi, struct lower_data *data)
{
  lower_stmt_body (&EH_FILTER_FAILURE (tsi_stmt (*tsi)), data);
}

/* Lowers a catch_expr TSI.  DATA is passed through the recursion.  */

static void
lower_catch_expr (tree_stmt_iterator *tsi, struct lower_data *data)
{
  lower_stmt_body (&CATCH_BODY (tsi_stmt (*tsi)), data);
}

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.903.2.110
diff -c -3 -p -r1.903.2.110 Makefile.in
*** Makefile.in	20 Aug 2003 20:43:55 -0000	1.903.2.110
--- Makefile.in	29 Aug 2003 17:37:21 -0000
*************** OBJS-common = \
*** 849,855 ****
   tree-alias-type.o gimplify.o tree-nomudflap.o tree-pretty-print.o         \
   tree-alias-common.o tree-ssa-ccp.o tree-browser.o @ANDER@ tree-ssa-dce.o  \
   tree-ssa-pre.o tree-ssa-copyprop.o tree-ssa-live.o tree-must-alias.o	   \
!  tree-ssa-dom.o								   \
   alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o	  	   \
   cfg.o cfganal.o cfgbuild.o cfgcleanup.o cfglayout.o cfgloop.o		   \
   cfgloopanal.o cfgloopmanip.o loop-init.o loop-unswitch.o loop-unroll.o	   \
--- 849,855 ----
   tree-alias-type.o gimplify.o tree-nomudflap.o tree-pretty-print.o         \
   tree-alias-common.o tree-ssa-ccp.o tree-browser.o @ANDER@ tree-ssa-dce.o  \
   tree-ssa-pre.o tree-ssa-copyprop.o tree-ssa-live.o tree-must-alias.o	   \
!  tree-ssa-dom.o gimple-low.o						   \
   alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o	  	   \
   cfg.o cfganal.o cfgbuild.o cfgcleanup.o cfglayout.o cfgloop.o		   \
   cfgloopanal.o cfgloopmanip.o loop-init.o loop-unswitch.o loop-unroll.o	   \
*************** tree-dfa.o : tree-dfa.c $(TREE_FLOW_H) $
*** 1559,1565 ****
  tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) \
     $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) \
     $(GGC_H) output.h diagnostic.h ssa.h errors.h flags.h tree-alias-common.h \
!    $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H)
  c-simplify.o : c-simplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
     $(C_TREE_H) $(C_COMMON_H) diagnostic.h $(TREE_SIMPLE_H) varray.h flags.h \
     langhooks.h toplev.h rtl.h $(TREE_FLOW_H) langhooks-def.h \
--- 1559,1565 ----
  tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) \
     $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) \
     $(GGC_H) output.h diagnostic.h ssa.h errors.h flags.h tree-alias-common.h \
!    $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) function.h
  c-simplify.o : c-simplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
     $(C_TREE_H) $(C_COMMON_H) diagnostic.h $(TREE_SIMPLE_H) varray.h flags.h \
     langhooks.h toplev.h rtl.h $(TREE_FLOW_H) langhooks-def.h \
*************** gimplify.o : gimplify.c $(CONFIG_H) $(SY
*** 1568,1573 ****
--- 1568,1577 ----
     diagnostic.h $(TREE_SIMPLE_H) tree-inline.h varray.h langhooks.h \
     langhooks-def.h $(TREE_FLOW_H) $(TIMEVAR_H) $(TM_H) coretypes.h except.h \
     flags.h $(RTL_H)
+ gimple-low.o : gimple-low.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
+    diagnostic.h $(TREE_SIMPLE_H) tree-inline.h varray.h langhooks.h \
+    langhooks-def.h $(TREE_FLOW_H) $(TIMEVAR_H) $(TM_H) coretypes.h except.h \
+    flags.h $(RTL_H) function.h
  tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \
     $(TREE_H) errors.h tree-inline.h diagnostic.h $(HASHTAB_H) \
     $(TM_H) coretypes.h
Index: cfglayout.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfglayout.c,v
retrieving revision 1.19.2.11
diff -c -3 -p -r1.19.2.11 cfglayout.c
*** cfglayout.c	23 Jul 2003 16:59:32 -0000	1.19.2.11
--- cfglayout.c	29 Aug 2003 17:37:38 -0000
*************** insn_locators_initialize (void)
*** 310,319 ****
--- 295,308 ----
  	  switch (NOTE_LINE_NUMBER (insn))
  	    {
  	    case NOTE_INSN_BLOCK_BEG:
+ 	      if (cfun->dont_emit_block_notes)
+ 		abort ();
  	      block = NOTE_BLOCK (insn);
  	      delete_insn (insn);
  	      break;
  	    case NOTE_INSN_BLOCK_END:
+ 	      if (cfun->dont_emit_block_notes)
+ 		abort ();
  	      block = BLOCK_SUPERCONTEXT (block);
  	      if (block && TREE_CODE (block) == FUNCTION_DECL)
  		block = 0;
*************** insn_locators_initialize (void)
*** 328,338 ****
--- 317,333 ----
  	      break;
  	    }
  	}
+ 
+       if (cfun->dont_emit_block_notes)
+ 	check_block_change (insn, &block);
      }
  
    /* Tag the blocks with a depth number so that change_scope can find
       the common parent easily.  */
    set_block_levels (DECL_INITIAL (cfun->decl), 0);
+ 
+   if (cfun->dont_emit_block_notes)
+     free_block_changes ();
  }
  
  /* For each lexical block, set BLOCK_NUMBER to the depth at which it is
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.467.2.45
diff -c -3 -p -r1.467.2.45 expr.c
*** expr.c	26 Aug 2003 22:29:34 -0000	1.467.2.45
--- expr.c	29 Aug 2003 17:38:22 -0000
*************** expand_expr (tree exp, rtx target, enum 
*** 6737,6742 ****
--- 6746,6755 ----
  	input_line = TREE_LINENO (exp);
  	emit_line_note (input_location);
  
+ 	/* Record where the insns produced belong.  */
+ 	if (cfun->dont_emit_block_notes)
+ 	  record_block_change (TREE_BLOCK (exp));
+ 
  	/* This is a gross hack.  Temporarily remove the locus information
  	   and re-call expand_expr.
  
*************** expand_expr (tree exp, rtx target, enum 
*** 8903,8909 ****
  	    {
  	      expand_start_else ();
  	      if (TREE_LOCUS (exp))
! 		emit_line_note (*(TREE_LOCUS (exp)));
  	      expand_elseif (TREE_OPERAND (exp, 0));
  	      expand_expr (TREE_OPERAND (exp, 1), const0_rtx, VOIDmode, 0);
  	    }
--- 8916,8926 ----
  	    {
  	      expand_start_else ();
  	      if (TREE_LOCUS (exp))
! 		{
! 		  emit_line_note (*(TREE_LOCUS (exp)));
! 		  if (cfun->dont_emit_block_notes)
! 		    record_block_change (TREE_BLOCK (exp));
! 		}
  	      expand_elseif (TREE_OPERAND (exp, 0));
  	      expand_expr (TREE_OPERAND (exp, 1), const0_rtx, VOIDmode, 0);
  	    }
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.374.2.22
diff -c -3 -p -r1.374.2.22 function.c
*** function.c	20 Aug 2003 20:44:21 -0000	1.374.2.22
--- function.c	29 Aug 2003 17:38:36 -0000
*************** static tree *identify_blocks_1 (rtx, tre
*** 262,268 ****
  static void reorder_blocks_0 (tree);
  static void reorder_blocks_1 (rtx, tree, varray_type *);
  static void reorder_fix_fragments (tree);
- static tree blocks_nreverse (tree);
  static int all_blocks (tree, tree *);
  static tree *get_block_vector (tree, int *);
  extern tree debug_find_var_in_block_tree (tree, tree);
--- 262,267 ----
*************** uninitialized_vars_warning (tree block)
*** 5557,5563 ****
  	     flow.c that the entire aggregate was initialized.
  	     Unions are troublesome because members may be shorter.  */
  	  && ! AGGREGATE_TYPE_P (TREE_TYPE (decl))
! 	  && DECL_RTL (decl) != 0
  	  && GET_CODE (DECL_RTL (decl)) == REG
  	  /* Global optimizations can make it difficult to determine if a
  	     particular variable has been initialized.  However, a VAR_DECL
--- 5556,5562 ----
  	     flow.c that the entire aggregate was initialized.
  	     Unions are troublesome because members may be shorter.  */
  	  && ! AGGREGATE_TYPE_P (TREE_TYPE (decl))
! 	  && DECL_RTL_SET_P (decl)
  	  && GET_CODE (DECL_RTL (decl)) == REG
  	  /* Global optimizations can make it difficult to determine if a
  	     particular variable has been initialized.  However, a VAR_DECL
*************** uninitialized_vars_warning (tree block)
*** 5572,5578 ****
                   TREE_LOCUS (decl), decl);
        if (extra_warnings
  	  && TREE_CODE (decl) == VAR_DECL
! 	  && DECL_RTL (decl) != 0
  	  && GET_CODE (DECL_RTL (decl)) == REG
  	  && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
  	warning ("%Hvariable '%D' might be clobbered by `longjmp' or `vfork'",
--- 5571,5577 ----
                   TREE_LOCUS (decl), decl);
        if (extra_warnings
  	  && TREE_CODE (decl) == VAR_DECL
! 	  && DECL_RTL_SET_P (decl)
  	  && GET_CODE (DECL_RTL (decl)) == REG
  	  && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
  	warning ("%Hvariable '%D' might be clobbered by `longjmp' or `vfork'",
*************** reorder_fix_fragments (tree block)
*** 6136,6142 ****
  /* Reverse the order of elements in the chain T of blocks,
     and return the new head of the chain (old last element).  */
  
! static tree
  blocks_nreverse (tree t)
  {
    tree prev = 0, decl, next;
--- 6135,6141 ----
  /* Reverse the order of elements in the chain T of blocks,
     and return the new head of the chain (old last element).  */
  
! tree
  blocks_nreverse (tree t)
  {
    tree prev = 0, decl, next;
*************** init_function_once (void)
*** 7970,7973 ****
--- 7969,8024 ----
    VARRAY_INT_INIT (sibcall_epilogue, 0, "sibcall_epilogue");
  }
  
+ /* Resets insn_block_boundaries array.  */
+ 
+ void
+ reset_block_changes ()
+ {
+   VARRAY_TREE_INIT (cfun->ib_boundaries_block, 100, "ib_boundaries_block");
+   VARRAY_PUSH_TREE (cfun->ib_boundaries_block, NULL_TREE);
+ }
+ 
+ /* Record the boundary for BLOCK.  */
+ void
+ record_block_change (tree block)
+ {
+   int i, n;
+   tree last_block;
+ 
+   if (!block)
+     return;
+ 
+   last_block = VARRAY_TOP_TREE (cfun->ib_boundaries_block);
+   VARRAY_POP (cfun->ib_boundaries_block);
+   n = get_max_uid ();
+   for (i = VARRAY_ACTIVE_SIZE (cfun->ib_boundaries_block); i < n; i++)
+     VARRAY_PUSH_TREE (cfun->ib_boundaries_block, last_block);
+ 
+   VARRAY_PUSH_TREE (cfun->ib_boundaries_block, block);
+ }
+ 
+ /* Finishes record of boundaries.  */
+ void finalize_block_changes ()
+ {
+   record_block_change (DECL_INITIAL (current_function_decl));
+ }
+ 
+ /* For INSN return the BLOCK it belongs to.  */ 
+ void
+ check_block_change (rtx insn, tree *block)
+ {
+   unsigned uid = INSN_UID (insn);
+ 
+   if (uid >= VARRAY_ACTIVE_SIZE (cfun->ib_boundaries_block))
+     return;
+ 
+   *block = VARRAY_TREE (cfun->ib_boundaries_block, uid);
+ }
+ 
+ /* Releases the ib_boundaries_block records.  */
+ void
+ free_block_changes ()
+ {
+   cfun->ib_boundaries_block = NULL;
+ }
  #include "gt-function.h"
Index: function.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.h,v
retrieving revision 1.83.2.11
diff -c -3 -p -r1.83.2.11 function.h
*** function.h	21 Jul 2003 13:50:48 -0000	1.83.2.11
--- function.h	29 Aug 2003 17:38:37 -0000
*************** struct function GTY(())
*** 488,493 ****
--- 488,497 ----
    /* Nonzero if code to initialize arg_pointer_save_area has been emitted.  */
    unsigned int arg_pointer_save_area_init : 1;
  
+   /* Nonzero if NOTE_INSN_BLOCK_BEG / NOTE_INSN_BLOCK_END notes should not
+      be emitted.  */
+   unsigned int dont_emit_block_notes : 1;
+ 
    /* How commonly executed the function is.  Initialized during branch
       probabilities pass.  */
    enum function_frequency {
*************** struct function GTY(())
*** 504,509 ****
--- 508,516 ----
    /* Maximal number of entities in the single jumptable.  Used to estimate
       final flowgraph size.  */
    int max_jumptable_ents;
+ 
+   /* Array mapping insn uids to blocks.  */
+   struct varray_head_tag *ib_boundaries_block;
  };
  
  /* The function currently being compiled.  */
*************** extern void reorder_blocks (void);
*** 590,595 ****
--- 597,609 ----
  
  /* Set BLOCK_NUMBER for all the blocks in FN.  */
  extern void number_blocks (tree);
+ 
+ extern tree blocks_nreverse (tree);
+ extern void reset_block_changes (void);
+ extern void record_block_change (tree);
+ extern void finalize_block_changes (void);
+ extern void check_block_change (rtx, tree *);
+ extern void free_block_changes (void);
  
  /* Return size needed for stack frame based on slots so far allocated.
     This size counts from zero.  It is not rounded to STACK_BOUNDARY;
Index: sibcall.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sibcall.c,v
retrieving revision 1.38.2.6
diff -c -3 -p -r1.38.2.6 sibcall.c
*** sibcall.c	23 Jul 2003 16:59:57 -0000	1.38.2.6
--- sibcall.c	29 Aug 2003 17:39:16 -0000
*************** optimize_sibling_and_tail_recursive_call
*** 748,754 ****
    /* There may have been NOTE_INSN_BLOCK_{BEGIN,END} notes in the
       CALL_PLACEHOLDER alternatives that we didn't emit.  Rebuild the
       lexical block tree to correspond to the notes that still exist.  */
!   if (replaced_call_placeholder)
      reorder_blocks ();
  
    /* This information will be invalid after inline expansion.  Kill it now.  */
--- 748,755 ----
    /* There may have been NOTE_INSN_BLOCK_{BEGIN,END} notes in the
       CALL_PLACEHOLDER alternatives that we didn't emit.  Rebuild the
       lexical block tree to correspond to the notes that still exist.  */
!   if (replaced_call_placeholder
!       && !cfun->dont_emit_block_notes)
      reorder_blocks ();
  
    /* This information will be invalid after inline expansion.  Kill it now.  */
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.267.2.29
diff -c -3 -p -r1.267.2.29 stmt.c
*** stmt.c	28 Aug 2003 19:02:58 -0000	1.267.2.29
--- stmt.c	29 Aug 2003 17:39:23 -0000
*************** expand_start_bindings_and_block (int fla
*** 3424,3430 ****
      abort ();
  
    /* Create a note to mark the beginning of the block.  */
!   if (block_flag)
      {
        note = emit_note (NOTE_INSN_BLOCK_BEG);
        NOTE_BLOCK (note) = block;
--- 3403,3409 ----
      abort ();
  
    /* Create a note to mark the beginning of the block.  */
!   if (block_flag && !cfun->dont_emit_block_notes)
      {
        note = emit_note (NOTE_INSN_BLOCK_BEG);
        NOTE_BLOCK (note) = block;
*************** expand_end_bindings (tree vars, int mark
*** 3844,3850 ****
       We do this now, after running cleanups on the variables
       just going out of scope, so they are in scope for their cleanups.  */
  
!   if (mark_ends)
      {
        rtx note = emit_note (NOTE_INSN_BLOCK_END);
        NOTE_BLOCK (note) = NOTE_BLOCK (thisblock->data.block.first_insn);
--- 3823,3829 ----
       We do this now, after running cleanups on the variables
       just going out of scope, so they are in scope for their cleanups.  */
  
!   if (mark_ends && !cfun->dont_emit_block_notes)
      {
        rtx note = emit_note (NOTE_INSN_BLOCK_END);
        NOTE_BLOCK (note) = NOTE_BLOCK (thisblock->data.block.first_insn);
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.654.2.62
diff -c -3 -p -r1.654.2.62 toplev.c
*** toplev.c	20 Aug 2003 20:44:30 -0000	1.654.2.62
--- toplev.c	29 Aug 2003 17:39:30 -0000
*************** rest_of_compilation (tree decl)
*** 3054,3068 ****
       have been run to re-initialize it.  */
    cse_not_expected = ! optimize;
  
!   /* First, make sure that NOTE_BLOCK is set correctly for each
!      NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END note.  */
!   if (!cfun->x_whole_function_mode_p)
!     identify_blocks ();
! 
!   /* In function-at-a-time mode, we do not attempt to keep the BLOCK
!      tree in sensible shape.  So, we just recalculate it here.  */
!   if (cfun->x_whole_function_mode_p)
!     reorder_blocks ();
  
    init_flow ();
  
--- 3010,3029 ----
       have been run to re-initialize it.  */
    cse_not_expected = ! optimize;
  
!   if (!cfun->dont_emit_block_notes)
!     {
!       /* First, make sure that NOTE_BLOCK is set correctly for each
! 	 NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END note.  */
!       if (!cfun->x_whole_function_mode_p)
! 	identify_blocks ();
! 
!       /* In function-at-a-time mode, we do not attempt to keep the BLOCK
! 	 tree in sensible shape.  So, we just recalculate it here.  */
!       if (cfun->x_whole_function_mode_p)
! 	reorder_blocks ();
!     }
!   else
!     finalize_block_changes ();
  
    init_flow ();
  
*************** rest_of_compilation (tree decl)
*** 3090,3096 ****
       over the instruction sequence faster, and allow the garbage
       collector to reclaim the memory used by the notes.  */
    remove_unnecessary_notes ();
!   reorder_blocks ();
  
    ggc_collect ();
  
--- 3051,3058 ----
       over the instruction sequence faster, and allow the garbage
       collector to reclaim the memory used by the notes.  */
    remove_unnecessary_notes ();
!   if (!cfun->dont_emit_block_notes)
!     reorder_blocks ();
  
    ggc_collect ();
  
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.107
diff -c -3 -p -r1.1.4.107 tree-flow.h
*** tree-flow.h	28 Aug 2003 01:14:21 -0000	1.1.4.107
--- tree-flow.h	29 Aug 2003 17:39:36 -0000
*************** static inline bool may_propagate_copy (t
*** 525,530 ****
--- 526,533 ----
  /* In tree-must-alias.c  */
  void tree_compute_must_alias (tree);
  
+ /* In gimple-low.c  */
+ void lower_function_body (tree *);
  
  #include "tree-flow-inline.h"
  
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-optimize.c,v
retrieving revision 1.1.4.43
diff -c -3 -p -r1.1.4.43 tree-optimize.c
*** tree-optimize.c	8 Aug 2003 00:27:10 -0000	1.1.4.43
--- tree-optimize.c	29 Aug 2003 17:39:36 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 36,41 ****
--- 36,42 ----
  #include "tree-flow.h"
  #include "tree-dump.h"
  #include "timevar.h"
+ #include "function.h"
  
  /* Rewrite a function tree to the SSA form and perform the SSA-based
     optimizations on it.  */
*************** optimize_function_tree (tree fndecl)
*** 52,58 ****
--- 53,64 ----
    if (errorcount || sorrycount)
      return;
  
+   lower_function_body (&DECL_SAVED_TREE (fndecl));
    fnbody = DECL_SAVED_TREE (fndecl);
+ 
+   /* Avoid producing notes for blocks.  */
+   cfun->dont_emit_block_notes = 1;
+   reset_block_changes ();
  
    /* Build the flowgraph.  */
    init_flow ();
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.92
diff -c -3 -p -r1.342.2.92 tree.h
*** tree.h	28 Aug 2003 19:02:59 -0000	1.342.2.92
--- tree.h	29 Aug 2003 18:22:42 -0000
*************** extern void tree_operand_check_failed (i
*** 425,430 ****
--- 425,432 ----
  
  #endif
  
+ #define TREE_BLOCK(NODE)		((NODE)->exp.block)
+ 
  #include "tree-check.h"
  
  #define TYPE_CHECK(T)		TREE_CLASS_CHECK (T, 't')
*************** struct tree_exp GTY(())
*** 965,970 ****
--- 967,973 ----
  {
    struct tree_common common;
    int complexity;
+   tree block;
    tree GTY ((special ("tree_exp"),
  	     desc ("TREE_CODE ((tree) &%0)")))
      operands[1];


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