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]

Re: [tree-ssa] Fix variables getting out of their scope


[ Adding gcc-patches.  The original message was mis-addressed. ]

On Sun, 2003-08-10 at 16:37, Zdenek Dvorak wrote:
> Hello,
> 
> this patch fixes the problem with variables being copy-propagated out
> of their scope, by moving their declaration to the top-most bind_expr
> if it occurs.
> 
I'm not sure this is a valid transformation.  I believe that it disrupts
debugging information.  Jason?

If not, then I would vote for moving *all* local declarations to the top
BIND_EXPR and remove all BIND_EXPRs inside the function.  IIRC, I once
suggested something along those lines but it didn't turn out to be a
good idea because it would break debugging info.

> Moving them just to the innermost bind_expr that encloses
> both old declaration and the new position would of course be possible
> (and probably better), but I am not sure whether bind_exprs with no
> variables are not removed somewhere, in this case just this patch could
> move the declarations to the removed bind_expr, which would be wrong.
> 
> The patch also assumes that all newly created variables are declared
> in the topmost bind_expr (which afaik is true currently).
> 
Yes.

> The patch is partially derived from the ir change patch, so perhaps it
> is a bit more complicated than it has to be.
> 
Please break it appart then.  The patch has unrelated changes which are
not necessary for what you're trying to fix here.


Diego.

> Zdenek
> 
> The testcase for fixed problem:
> 
> void foo(void)
> {
>   int k;
> 
>   goto forward;
> back:
>   bla (k);
>   return;
> 
> forward:
>     {
>       int i = bar ();
> 
>       k = i;
> 
>       goto back;
>     }
> }
> 
> Changelog:
> 	* tree-flow.h (struct block_tree): New.
> 	(block_tree): Declare.
> 	(struct var_ann_d): New field scope.
> 	(struct stmt_ann_d): New field scope.
> 	(bti_start, bti_end_p, bti_next, dump_block_tree): Declare.
> 	(propagate_copy): Declaration changed.
> 	* tree-cfg.c (block_tree, block_tree_obstack_initialized,
> 	block_tree_obstack): New variables.
> 	(make_blocks, make_cond_expr_blocks, make_catch_expr_blocks,
> 	make_eh_filter_expr_blocks, make_try_expr_blocks,
> 	make_loop_expr_blocks, make_switch_expr_blocks,
> 	make_bind_expr_blocks, build_tree_cfg): Initialize block_tree,
> 	assign variables to scopes.
> 	(delete_tree_cfg): Release block_tree.
> 	(block_tree_alloc, block_tree_free, assign_vars_to_scope,
> 	dump_block_tree): New.
> 	* tree-flow-inline.h (bti_start, bti_end_p, bti_next): New.
> 	* tree-ssa-copyprop.c (move_var_to_scope): New.
> 	(copyprop_stmt): Pass scope of statement to propagate_copy.
> 	(propagate_copy): Assign variable to the right bind_expr.
> 	* tree-ssa-dom.c (optimize_stmt): Pass scope of statement to
> 	propagate_copy.
> 
> Index: tree-cfg.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
> retrieving revision 1.1.4.143
> diff -c -3 -p -r1.1.4.143 tree-cfg.c
> *** tree-cfg.c	9 Aug 2003 18:19:23 -0000	1.1.4.143
> --- tree-cfg.c	10 Aug 2003 20:17:13 -0000
> *************** static dominance_info pdom_info = NULL;
> *** 76,81 ****
> --- 76,85 ----
>   
>   static struct cfg_stats_d cfg_stats;
>   
> + struct block_tree *block_tree;
> + static int block_tree_obstack_initialized = false;
> + static struct obstack block_tree_obstack;
> + 
>   static struct obstack block_tree_ann_obstack;
>   static void *first_block_tree_ann_obj = 0;
>   
> *************** static void create_blocks_annotations (v
> *** 84,97 ****
>   static void create_block_annotation (basic_block);
>   static void free_blocks_annotations (void);
>   static void clear_blocks_annotations (void);
> ! static basic_block make_blocks (tree *, tree, tree, basic_block);
> ! static void make_cond_expr_blocks (tree *, tree, basic_block);
> ! static void make_catch_expr_blocks (tree *, tree, basic_block);
> ! static void make_eh_filter_expr_blocks (tree *, tree, basic_block);
> ! static void make_try_expr_blocks (tree *, tree, basic_block);
> ! static void make_loop_expr_blocks (tree *, basic_block);
> ! static void make_switch_expr_blocks (tree *, tree, basic_block);
> ! static basic_block make_bind_expr_blocks (tree *, tree, basic_block, tree);
>   static inline void add_stmt_to_bb (tree *, basic_block, tree);
>   static inline void append_stmt_to_bb (tree *, basic_block, tree);
>   static inline void set_parent_stmt (tree *, tree);
> --- 88,108 ----
>   static void create_block_annotation (basic_block);
>   static void free_blocks_annotations (void);
>   static void clear_blocks_annotations (void);
> ! static basic_block make_blocks (tree *, tree, tree, basic_block,
> ! 				struct block_tree *);
> ! static void make_loop_expr_blocks (tree *, basic_block, struct block_tree *);
> ! static void make_cond_expr_blocks (tree *, tree, basic_block,
> ! 				   struct block_tree *);
> ! static void make_catch_expr_blocks (tree *, tree, basic_block,
> ! 				    struct block_tree *);
> ! static void make_eh_filter_expr_blocks (tree *, tree, basic_block,
> ! 					struct block_tree *);
> ! static void make_try_expr_blocks (tree *, tree, basic_block,
> ! 				  struct block_tree *);
> ! static void make_switch_expr_blocks (tree *, tree, basic_block,
> ! 				     struct block_tree *);
> ! static basic_block make_bind_expr_blocks (tree *, tree, basic_block, tree,
> ! 					  struct block_tree *);
>   static inline void add_stmt_to_bb (tree *, basic_block, tree);
>   static inline void append_stmt_to_bb (tree *, basic_block, tree);
>   static inline void set_parent_stmt (tree *, tree);
> *************** static void make_goto_expr_edges (basic_
> *** 106,111 ****
> --- 117,125 ----
>   static void make_case_label_edges (basic_block);
>   
>   /* Various helpers.  */
> + static struct block_tree *block_tree_alloc (struct block_tree *);
> + static void block_tree_free (void);
> + static void assign_vars_to_scope (struct block_tree *);
>   static basic_block successor_block (basic_block);
>   static basic_block last_exec_block (tree *);
>   static tree *first_exec_stmt (tree *);
> *************** void
> *** 230,235 ****
> --- 244,250 ----
>   build_tree_cfg (tree fnbody)
>   {
>     tree *first_p;
> +   struct block_tree *block_tree_curr;
>   
>     timevar_push (TV_TREE_CFG);
>   
> *************** build_tree_cfg (tree fnbody)
> *** 258,267 ****
>         return;
>       }
>   
>     first_p = first_exec_stmt (&BIND_EXPR_BODY (fnbody));
>     if (first_p)
>       {
> !       make_blocks (first_p, NULL_TREE, NULL, NULL);
>   
>         if (n_basic_blocks > 0)
>   	{
> --- 273,285 ----
>         return;
>       }
>   
> +   block_tree_curr = block_tree_alloc (NULL);
> +   block_tree_curr->bind = fnbody;
> + 
>     first_p = first_exec_stmt (&BIND_EXPR_BODY (fnbody));
>     if (first_p)
>       {
> !       make_blocks (first_p, NULL_TREE, NULL, NULL, block_tree_curr);
>   
>         if (n_basic_blocks > 0)
>   	{
> *************** clear_blocks_annotations (void)
> *** 381,393 ****
>      BB is the block where the statements should be added to.  If BB is NULL,
>         a new basic block will be created for the statements.
>   
>      Return the last basic block added to the graph.  This is used to know if
>      a recursive invocation built a sub-graph whose last block can accept
>      more statements or not.  */
>   
>   static basic_block
>   make_blocks (tree *first_p, tree next_block_link, tree parent_stmt,
> ! 	     basic_block bb)
>   {
>     tree_stmt_iterator i;
>     tree stmt, last;
> --- 399,413 ----
>      BB is the block where the statements should be added to.  If BB is NULL,
>         a new basic block will be created for the statements.
>   
> +    BLOCK_TREE_CURR is the actual bind block.
> + 
>      Return the last basic block added to the graph.  This is used to know if
>      a recursive invocation built a sub-graph whose last block can accept
>      more statements or not.  */
>   
>   static basic_block
>   make_blocks (tree *first_p, tree next_block_link, tree parent_stmt,
> ! 	     basic_block bb, struct block_tree *block_tree_curr)
>   {
>     tree_stmt_iterator i;
>     tree stmt, last;
> *************** make_blocks (tree *first_p, tree next_bl
> *** 423,441 ****
>         /* Now add STMT to BB and create the subgraphs for special statement
>   	 codes.  */
>         append_stmt_to_bb (stmt_p, bb, parent_stmt);
>   
>         if (code == LOOP_EXPR)
> ! 	make_loop_expr_blocks (stmt_p, bb);
>         else if (code == COND_EXPR)
> ! 	make_cond_expr_blocks (stmt_p, next_block_link, bb);
>         else if (code == SWITCH_EXPR)
> ! 	make_switch_expr_blocks (stmt_p, next_block_link, bb);
>         else if (code == CATCH_EXPR)
> ! 	make_catch_expr_blocks (stmt_p, next_block_link, bb);
>         else if (code == EH_FILTER_EXPR)
> ! 	make_eh_filter_expr_blocks (stmt_p, next_block_link, bb);
>         else if (code == TRY_CATCH_EXPR || code == TRY_FINALLY_EXPR)
> ! 	make_try_expr_blocks (stmt_p, next_block_link, bb);
>         else if (code == BIND_EXPR)
>   	{
>   	  int num_blocks_before;
> --- 443,463 ----
>         /* Now add STMT to BB and create the subgraphs for special statement
>   	 codes.  */
>         append_stmt_to_bb (stmt_p, bb, parent_stmt);
> +       stmt_ann (stmt)->scope = block_tree_curr;
>   
>         if (code == LOOP_EXPR)
> ! 	make_loop_expr_blocks (stmt_p, bb, block_tree_curr);
>         else if (code == COND_EXPR)
> ! 	make_cond_expr_blocks (stmt_p, next_block_link, bb, block_tree_curr);
>         else if (code == SWITCH_EXPR)
> ! 	make_switch_expr_blocks (stmt_p, next_block_link, bb, block_tree_curr);
>         else if (code == CATCH_EXPR)
> ! 	make_catch_expr_blocks (stmt_p, next_block_link, bb, block_tree_curr);
>         else if (code == EH_FILTER_EXPR)
> ! 	make_eh_filter_expr_blocks (stmt_p, next_block_link, bb,
> ! 				    block_tree_curr);
>         else if (code == TRY_CATCH_EXPR || code == TRY_FINALLY_EXPR)
> ! 	make_try_expr_blocks (stmt_p, next_block_link, bb, block_tree_curr);
>         else if (code == BIND_EXPR)
>   	{
>   	  int num_blocks_before;
> *************** make_blocks (tree *first_p, tree next_bl
> *** 448,455 ****
>   	     point STMT to LAST_BB's last statement to determine if we
>   	     should start a new block or not.  */
>   	  num_blocks_before = n_basic_blocks;
>   	  last_bb = make_bind_expr_blocks (stmt_p, next_block_link, bb,
> ! 	                                   parent_stmt);
>   	  if (last_bb)
>   	    {
>   	      bb = last_bb;
> --- 470,481 ----
>   	     point STMT to LAST_BB's last statement to determine if we
>   	     should start a new block or not.  */
>   	  num_blocks_before = n_basic_blocks;
> + 	  block_tree_curr = block_tree_alloc (block_tree_curr);
> + 	  block_tree_curr->bind = stmt;
> + 	  assign_vars_to_scope (block_tree_curr);
> + 
>   	  last_bb = make_bind_expr_blocks (stmt_p, next_block_link, bb,
> ! 	                                   parent_stmt, block_tree_curr);
>   	  if (last_bb)
>   	    {
>   	      bb = last_bb;
> *************** could_trap_p (tree expr)
> *** 544,550 ****
>      ENTRY is the block whose last statement is *LOOP_P.  */
>   
>   static void
> ! make_loop_expr_blocks (tree *loop_p, basic_block entry)
>   {
>     tree_stmt_iterator si;
>     tree loop = *loop_p;
> --- 570,577 ----
>      ENTRY is the block whose last statement is *LOOP_P.  */
>   
>   static void
> ! make_loop_expr_blocks (tree *loop_p, basic_block entry,
> ! 		       struct block_tree *block_tree_curr)
>   {
>     tree_stmt_iterator si;
>     tree loop = *loop_p;
> *************** make_loop_expr_blocks (tree *loop_p, bas
> *** 578,584 ****
>   	next_block_link = *(tsi_container (si));
>       }
>   
> !   make_blocks (&LOOP_EXPR_BODY (loop), next_block_link, loop, NULL);
>   }
>   
>   
> --- 605,612 ----
>   	next_block_link = *(tsi_container (si));
>       }
>   
> !   make_blocks (&LOOP_EXPR_BODY (loop), next_block_link, loop, NULL,
> ! 	       block_tree_curr);
>   }
>   
>   
> *************** make_loop_expr_blocks (tree *loop_p, bas
> *** 589,599 ****
>         lexical scope, this will be the statement that comes after COND_P's
>         container (see the documentation for NEXT_BLOCK_LINK).
>   
> !    ENTRY is the block whose last statement is *COND_P.  */
>   
>   static void
>   make_cond_expr_blocks (tree *cond_p, tree next_block_link,
> ! 		       basic_block entry)
>   {
>     tree_stmt_iterator si;
>     tree cond = *cond_p;
> --- 617,629 ----
>         lexical scope, this will be the statement that comes after COND_P's
>         container (see the documentation for NEXT_BLOCK_LINK).
>   
> !    ENTRY is the block whose last statement is *COND_P.
> !    
> !    BLOCK_TREE_CURR is the bind scope to that it belongs.  */
>   
>   static void
>   make_cond_expr_blocks (tree *cond_p, tree next_block_link,
> ! 		       basic_block entry, struct block_tree *block_tree_curr)
>   {
>     tree_stmt_iterator si;
>     tree cond = *cond_p;
> *************** make_cond_expr_blocks (tree *cond_p, tre
> *** 611,618 ****
>       next_block_link = *(tsi_container (si));
>   
>     STRIP_CONTAINERS (cond);
> !   make_blocks (&COND_EXPR_THEN (cond), next_block_link, cond, NULL);
> !   make_blocks (&COND_EXPR_ELSE (cond), next_block_link, cond, NULL);
>   }
>   
>   /* Derive an exception handling region type from STMT.  */
> --- 641,650 ----
>       next_block_link = *(tsi_container (si));
>   
>     STRIP_CONTAINERS (cond);
> !   make_blocks (&COND_EXPR_THEN (cond), next_block_link, cond, NULL,
> ! 	       block_tree_curr);
> !   make_blocks (&COND_EXPR_ELSE (cond), next_block_link, cond, NULL,
> ! 	       block_tree_curr);
>   }
>   
>   /* Derive an exception handling region type from STMT.  */
> *************** get_eh_region_type (tree stmt)
> *** 639,645 ****
>   
>   static void
>   make_try_expr_blocks (tree *expr_p, tree next_block_link,
> ! 		      basic_block entry)
>   {
>     tree_stmt_iterator si;
>     tree expr = *expr_p;
> --- 671,677 ----
>   
>   static void
>   make_try_expr_blocks (tree *expr_p, tree next_block_link,
> ! 		      basic_block entry, struct block_tree *block_tree_curr)
>   {
>     tree_stmt_iterator si;
>     tree expr = *expr_p;
> *************** make_try_expr_blocks (tree *expr_p, tree
> *** 663,675 ****
>     VARRAY_PUSH_TREE (eh_stack, expr);
>   
>     /* Make blocks for the TRY block.  */
> !   make_blocks (&TREE_OPERAND (expr, 0), next_block_link, expr, NULL);
>   
>     /* And pop the stack of exception handlers.  */
>     VARRAY_POP (eh_stack);
>   
>     /* Make blocks for the handler itself.  */
> !   make_blocks (&TREE_OPERAND (expr, 1), next_block_link, expr, NULL);
>   
>     /* If this is a cleanup, then record which cleanup higher in the
>        stack it can directly reach.  */
> --- 695,709 ----
>     VARRAY_PUSH_TREE (eh_stack, expr);
>   
>     /* Make blocks for the TRY block.  */
> !   make_blocks (&TREE_OPERAND (expr, 0), next_block_link, expr, NULL,
> ! 	       block_tree_curr);
>   
>     /* And pop the stack of exception handlers.  */
>     VARRAY_POP (eh_stack);
>   
>     /* Make blocks for the handler itself.  */
> !   make_blocks (&TREE_OPERAND (expr, 1), next_block_link, expr, NULL,
> ! 	       block_tree_curr);
>   
>     /* If this is a cleanup, then record which cleanup higher in the
>        stack it can directly reach.  */
> *************** make_try_expr_blocks (tree *expr_p, tree
> *** 686,692 ****
>   
>   static void
>   make_catch_expr_blocks (tree *expr_p, tree next_block_link,
> ! 			basic_block entry)
>   {
>     tree_stmt_iterator si;
>     tree expr = *expr_p;
> --- 720,726 ----
>   
>   static void
>   make_catch_expr_blocks (tree *expr_p, tree next_block_link,
> ! 			basic_block entry, struct block_tree *block_tree_curr)
>   {
>     tree_stmt_iterator si;
>     tree expr = *expr_p;
> *************** make_catch_expr_blocks (tree *expr_p, tr
> *** 701,714 ****
>       tsi_next (&si);
>   
>     STRIP_CONTAINERS (expr);
> !   make_blocks (&CATCH_BODY (expr), next_block_link, expr, NULL);
>   }
>   
>   /* Create the blocks for the EH_FILTER_EXPR node pointed to by expr_p.  */
>   
>   static void
>   make_eh_filter_expr_blocks (tree *expr_p, tree next_block_link,
> ! 			    basic_block entry)
>   {
>     tree_stmt_iterator si;
>     tree expr = *expr_p;
> --- 735,750 ----
>       tsi_next (&si);
>   
>     STRIP_CONTAINERS (expr);
> !   make_blocks (&CATCH_BODY (expr), next_block_link, expr, NULL,
> ! 	       block_tree_curr);
>   }
>   
>   /* Create the blocks for the EH_FILTER_EXPR node pointed to by expr_p.  */
>   
>   static void
>   make_eh_filter_expr_blocks (tree *expr_p, tree next_block_link,
> ! 			    basic_block entry,
> ! 			    struct block_tree *block_tree_curr)
>   {
>     tree_stmt_iterator si;
>     tree expr = *expr_p;
> *************** make_eh_filter_expr_blocks (tree *expr_p
> *** 723,729 ****
>       tsi_next (&si);
>   
>     STRIP_CONTAINERS (expr);
> !   make_blocks (&EH_FILTER_FAILURE (expr), next_block_link, expr, NULL);
>   }
>   
>   
> --- 759,766 ----
>       tsi_next (&si);
>   
>     STRIP_CONTAINERS (expr);
> !   make_blocks (&EH_FILTER_FAILURE (expr), next_block_link, expr, NULL,
> ! 	       block_tree_curr);
>   }
>   
>   
> *************** make_eh_filter_expr_blocks (tree *expr_p
> *** 738,744 ****
>   
>   static void
>   make_switch_expr_blocks (tree *switch_e_p, tree next_block_link,
> ! 			 basic_block entry)
>   {
>     tree_stmt_iterator si;
>     tree switch_e = *switch_e_p;
> --- 775,781 ----
>   
>   static void
>   make_switch_expr_blocks (tree *switch_e_p, tree next_block_link,
> ! 			 basic_block entry, struct block_tree *block_tree_curr)
>   {
>     tree_stmt_iterator si;
>     tree switch_e = *switch_e_p;
> *************** make_switch_expr_blocks (tree *switch_e_
> *** 756,762 ****
>       next_block_link = *(tsi_container (si));
>   
>     STRIP_CONTAINERS (switch_e);
> !   make_blocks (&SWITCH_BODY (switch_e), next_block_link, switch_e, NULL);
>   }
>   
>   
> --- 793,800 ----
>       next_block_link = *(tsi_container (si));
>   
>     STRIP_CONTAINERS (switch_e);
> !   make_blocks (&SWITCH_BODY (switch_e), next_block_link, switch_e, NULL,
> ! 	       block_tree_curr);
>   }
>   
>   
> *************** make_switch_expr_blocks (tree *switch_e_
> *** 779,785 ****
>   
>   static basic_block
>   make_bind_expr_blocks (tree *bind_p, tree next_block_link,
> ! 		       basic_block entry, tree parent_stmt)
>   {
>     tree_stmt_iterator si;
>     tree bind = *bind_p;
> --- 817,824 ----
>   
>   static basic_block
>   make_bind_expr_blocks (tree *bind_p, tree next_block_link,
> ! 		       basic_block entry, tree parent_stmt,
> ! 		       struct block_tree *block_tree_curr)
>   {
>     tree_stmt_iterator si;
>     tree bind = *bind_p;
> *************** make_bind_expr_blocks (tree *bind_p, tre
> *** 803,809 ****
>        ends with a block terminating statement.  */
>     STRIP_CONTAINERS (bind);
>     return make_blocks (&BIND_EXPR_BODY (bind), next_block_link, parent_stmt,
> ! 		      entry);
>   }
>   
>   
> --- 842,848 ----
>        ends with a block terminating statement.  */
>     STRIP_CONTAINERS (bind);
>     return make_blocks (&BIND_EXPR_BODY (bind), next_block_link, parent_stmt,
> ! 		      entry, block_tree_curr);
>   }
>   
>   
> *************** delete_tree_cfg (void)
> *** 3183,3188 ****
> --- 3222,3228 ----
>       free_blocks_annotations ();
>   
>     free_basic_block_vars (0);
> +   block_tree_free ();
>   }
>   
>   
> *************** tree_loop_optimizer_finalize (struct loo
> *** 5047,5050 ****
> --- 5087,5159 ----
>   #ifdef ENABLE_CHECKING
>     verify_flow_info ();
>   #endif
> + }
> + 
> + /* Allocates a block_tree node with outer node OUTER.  */
> + static struct block_tree *
> + block_tree_alloc (struct block_tree *outer)
> + {
> +   struct block_tree *nw;
> + 
> +   if (!block_tree_obstack_initialized)
> +     {
> +       block_tree_obstack_initialized = true;
> +       gcc_obstack_init (&block_tree_obstack);
> +     }
> +   nw = obstack_alloc (&block_tree_obstack, sizeof (struct block_tree));
> +   nw->outer = outer;
> +   nw->subtree = NULL;
> +   nw->bind = NULL_TREE;
> + 
> +   if (outer)
> +     {
> +       nw->next = outer->subtree;
> +       outer->subtree = nw;
> +       nw->level = outer->level + 1;
> +     }
> +   else
> +     {
> +       block_tree = nw;
> +       nw->next = NULL;
> +       nw->level = 0;
> +     }
> + 
> +   return nw;
> + }
> + 
> + /* Releases the block_tree obstack.  */
> + static void
> + block_tree_free ()
> + {
> +   if (block_tree_obstack_initialized)
> +     {
> +       block_tree_obstack_initialized = false;
> +       obstack_free (&block_tree_obstack, NULL);
> +     }
> + }
> + 
> + /* Assigns a scope to variables defined in block SCOPE.  */
> + static void
> + assign_vars_to_scope (struct block_tree *scope)
> + {
> +   tree var;
> + 
> +   for (var = BIND_EXPR_VARS (scope->bind); var; var = TREE_CHAIN (var))
> +     get_var_ann (var)->scope = scope;
> + }
> + 
> + /* Dumps information about block tree BLOCK to FILE, indenting INDENT
> +    spaces.  */
> + void
> + dump_block_tree (FILE *file)
> + {
> +   struct block_tree *act;
> +   int i;
> + 
> +   for (act = bti_start (); !bti_end_p (act); bti_next (&act))
> +     {
> +       for (i = 0; i < act->level; i++)
> + 	fprintf (file, "  ");
> +       fprintf (file, "%p\n", (void *) act->bind);
> +     }
>   }
> Index: tree-flow-inline.h
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow-inline.h,v
> retrieving revision 1.1.2.47
> diff -c -3 -p -r1.1.2.47 tree-flow-inline.h
> *** tree-flow-inline.h	4 Aug 2003 18:44:02 -0000	1.1.2.47
> --- tree-flow-inline.h	10 Aug 2003 20:17:14 -0000
> *************** dom_children (basic_block bb)
> *** 342,347 ****
> --- 342,376 ----
>   
>   /*  -----------------------------------------------------------------------  */
>   
> + static inline struct block_tree *
> + bti_start ()
> + {
> +   return block_tree;
> + }
> + 
> + static inline bool
> + bti_end_p (struct block_tree *block)
> + {
> +   return !block;
> + }
> + 
> + static inline void
> + bti_next (struct block_tree **block)
> + {
> +   struct block_tree *act = *block;
> + 
> +   if (act->subtree)
> +     {
> +       *block = act->subtree;
> +       return;
> +     }
> + 
> +   while (act->outer && !act->next)
> +     act = act->outer;
> + 
> +   *block = act->next;
> + }
> + 
>   static inline bool
>   bsi_end_p (block_stmt_iterator i)
>   {
> Index: tree-flow.h
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
> retrieving revision 1.1.4.101
> diff -c -3 -p -r1.1.4.101 tree-flow.h
> *** tree-flow.h	8 Aug 2003 00:27:10 -0000	1.1.4.101
> --- tree-flow.h	10 Aug 2003 20:17:14 -0000
> *************** struct basic_block_def;
> *** 36,41 ****
> --- 36,52 ----
>   typedef struct basic_block_def *basic_block;
>   #endif
>   
> + /* Tree of bind blocks in the function.  */
> + extern struct block_tree
> + {
> +   tree bind;			/* The bind block itself.  */
> +  
> +   int level;			/* Of the node in the tree.  */
> +   struct block_tree *outer;	/* Outer block.  */
> +   struct block_tree *subtree;	/* Head of list of inner block.  */
> +   struct block_tree *next;	/* Next block on the same level.  */
> + } *block_tree;
> + 
>   /*---------------------------------------------------------------------------
>   		   Tree annotations stored in tree_common.ann
>   ---------------------------------------------------------------------------*/
> *************** struct var_ann_d GTY(())
> *** 120,125 ****
> --- 131,139 ----
>   
>     /* Used by the root-var object in tree-ssa-live.[ch].  */
>     unsigned root_index;
> + 
> +   /* The binding block in that the variable is declared.  */
> +   struct block_tree * GTY ((skip (""))) scope;
>   };
>   
>   
> *************** struct stmt_ann_d GTY(())
> *** 232,237 ****
> --- 246,254 ----
>   
>     /* Array of variables that have had their address taken in the statement.  */
>     varray_type addresses_taken;
> + 
> +   /* The binding block to that the statement belongs.  */
> +   struct block_tree * GTY ((skip (""))) scope;
>   };
>   
>   
> *************** struct bb_ann_d
> *** 293,298 ****
> --- 310,320 ----
>   
>   typedef struct bb_ann_d *bb_ann_t;
>   
> + /* Iterator for traversing block tree.  */
> + static inline struct block_tree *bti_start (void);
> + static inline bool bti_end_p (struct block_tree *);
> + static inline void bti_next (struct block_tree **);
> + 
>   /* Accessors for basic block annotations.  */
>   static inline bb_ann_t bb_ann (basic_block);
>   static inline basic_block parent_block (basic_block);
> *************** extern GTY(()) varray_type call_clobbere
> *** 390,395 ****
> --- 412,418 ----
>   ---------------------------------------------------------------------------*/
>   /* In tree-cfg.c  */
>   extern void build_tree_cfg (tree);
> + extern void dump_block_tree (FILE *);
>   extern void delete_tree_cfg (void);
>   extern bool is_ctrl_stmt (tree);
>   extern bool is_ctrl_altering_stmt (tree);
> *************** void tree_ssa_dce (tree);
> *** 489,495 ****
>   
>   /* In tree-ssa-copyprop.c  */
>   void tree_ssa_copyprop (tree);
> ! void propagate_copy (tree *, tree);
>   
>   
>   /* In tree-flow-inline.h  */
> --- 512,518 ----
>   
>   /* In tree-ssa-copyprop.c  */
>   void tree_ssa_copyprop (tree);
> ! void propagate_copy (tree *, tree, struct block_tree *);
>   
>   
>   /* In tree-flow-inline.h  */
> Index: tree-ssa-copyprop.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-copyprop.c,v
> retrieving revision 1.1.2.11
> diff -c -3 -p -r1.1.2.11 tree-ssa-copyprop.c
> *** tree-ssa-copyprop.c	28 Jul 2003 17:16:20 -0000	1.1.2.11
> --- tree-ssa-copyprop.c	10 Aug 2003 20:17:14 -0000
> *************** static int dump_flags;
> *** 45,50 ****
> --- 45,51 ----
>   static void copyprop_stmt (tree);
>   static void copyprop_phi (tree);
>   static inline tree get_original (tree);
> + static void move_var_to_scope (tree, struct block_tree *, struct block_tree *);
>   
>   
>   /* Main entry point to the copy propagator.  The algorithm is a simple
> *************** copyprop_stmt (tree stmt)
> *** 122,128 ****
>   	      fprintf (dump_file, "\n");
>   	    }
>   
> ! 	  propagate_copy (use_p, orig);
>   	  modified = true;
>   	}
>       }
> --- 123,129 ----
>   	      fprintf (dump_file, "\n");
>   	    }
>   
> ! 	  propagate_copy (use_p, orig, stmt_ann (stmt)->scope);
>   	  modified = true;
>   	}
>       }
> *************** get_original (tree var)
> *** 204,214 ****
>   
>   /* Replace the operand pointed to by OP_P with variable VAR.  If *OP_P is a
>      pointer, copy the memory tag used originally by *OP_P into VAR.  This is
> !    needed in cases where VAR had never been dereferenced in the program.  */
>      
>   void
> ! propagate_copy (tree *op_p, tree var)
>   {
>   #if defined ENABLE_CHECKING
>     if (!may_propagate_copy (*op_p, var))
>       abort ();
> --- 205,219 ----
>   
>   /* Replace the operand pointed to by OP_P with variable VAR.  If *OP_P is a
>      pointer, copy the memory tag used originally by *OP_P into VAR.  This is
> !    needed in cases where VAR had never been dereferenced in the program.
> !    
> !    SCOPE is the bind block in that the *OP_P occurs.  */
>      
>   void
> ! propagate_copy (tree *op_p, tree var, struct block_tree *scope)
>   {
> +   struct block_tree *old_scope;
> + 
>   #if defined ENABLE_CHECKING
>     if (!may_propagate_copy (*op_p, var))
>       abort ();
> *************** propagate_copy (tree *op_p, tree var)
> *** 225,228 ****
> --- 230,271 ----
>       }
>   
>     *op_p = var;
> +  
> +   old_scope = var_ann (SSA_NAME_VAR (var))->scope;
> +   if (old_scope)
> +     {
> +       if (!scope)
> + 	scope = block_tree;
> +       else
> + 	{
> + 	  while (scope->level > old_scope->level)
> + 	    scope = scope->outer;
> + 	  if (scope != old_scope)
> + 	    scope = block_tree;
> + 	}
> +       if (scope != old_scope)
> + 	move_var_to_scope (SSA_NAME_VAR (var), old_scope, scope);
> +     }
> + }
> + 
> + /* Moves variable VAR from OLD_SCOPE to SCOPE.  */
> + static void
> + move_var_to_scope (tree var, struct block_tree *old_scope,
> + 		   struct block_tree *scope)
> + {
> +   tree *ch;
> + 
> +   for (ch = &BIND_EXPR_VARS (old_scope->bind); *ch; ch = &TREE_CHAIN (*ch))
> +     if (*ch == var)
> +       break;
> +   if (!*ch)
> +     abort ();
> +   *ch = TREE_CHAIN (*ch);
> + 
> +   TREE_CHAIN (var) = BIND_EXPR_VARS (scope->bind);
> +   BIND_EXPR_VARS (scope->bind) = var;
> +   var_ann (var)->scope = scope;
> + 
> +   /* ??? Not sure why, but it makes dwarf2out happy.  */
> +   DECL_ABSTRACT_ORIGIN (var) = NULL_TREE;
>   }
> Index: tree-ssa-dom.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dom.c,v
> retrieving revision 1.1.2.17
> diff -c -3 -p -r1.1.2.17 tree-ssa-dom.c
> *** tree-ssa-dom.c	6 Aug 2003 03:16:40 -0000	1.1.2.17
> --- tree-ssa-dom.c	10 Aug 2003 20:17:16 -0000
> *************** optimize_stmt (block_stmt_iterator si, v
> *** 601,607 ****
>   	      addr_expr_propagated_p = true;
>   
>   	    if (TREE_CODE (val) == SSA_NAME)
> ! 	      propagate_copy (op_p, val);
>   	    else
>   	      *op_p = val;
>   
> --- 601,607 ----
>   	      addr_expr_propagated_p = true;
>   
>   	    if (TREE_CODE (val) == SSA_NAME)
> ! 	      propagate_copy (op_p, val, stmt_ann (stmt)->scope);
>   	    else
>   	      *op_p = val;
>   


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