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


Hello,

> Has this been bootstrapped and tested?

yes.

> If so, the patch is OK after a
> couple of minor changes:
...
> > *************** struct stmt_ann_d GTY(())
> > *** 232,237 ****
> > --- 235,246 ----
> >   
> >     /* Array of variables that have had their address taken in the statement.  */
> >     varray_type addresses_taken;
> > + 
> > +   /* The binding block to that the statement belongs.  */
> > +   tree scope;
> > + 
> > +   /* For BIND_EXPRs, a level of the scope.  */
> > +   int scope_level;
> >     ^^^^^^^^^^^^^^^^
> >
> Not needed.  You can use BLOCK_NUMBER (BIND_EXPR_BLOCK (scope))

Not really -- not every BIND_EXPR has a BIND_EXPR_BLOCK.

Here is the patch with the comment changes (+ a minor cleanup of the
place in tree-ssa-dom.c where I tried to missuse propagate_copy,
forgetting that it tests for may_propagate_copy).

Zdenek

Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.150
diff -c -3 -p -r1.1.4.150 tree-cfg.c
*** tree-cfg.c	17 Aug 2003 18:51:29 -0000	1.1.4.150
--- tree-cfg.c	17 Aug 2003 21:30:14 -0000
*************** 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);
--- 84,98 ----
  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, tree);
! static void make_loop_expr_blocks (tree *, basic_block, tree);
! static void make_cond_expr_blocks (tree *, tree, basic_block, tree);
! static void make_catch_expr_blocks (tree *, tree, basic_block, tree);
! static void make_eh_filter_expr_blocks (tree *, tree, basic_block, tree);
! static void make_try_expr_blocks (tree *, tree, basic_block, tree);
! static void make_switch_expr_blocks (tree *, tree, basic_block, tree);
! static basic_block make_bind_expr_blocks (tree *, tree, basic_block, tree,
! 					  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 ****
--- 107,113 ----
  static void make_case_label_edges (basic_block);
  
  /* Various helpers.  */
+ static void assign_vars_to_scope (tree);
  static basic_block successor_block (basic_block);
  static basic_block last_exec_block (tree *);
  static tree *first_exec_stmt (tree *);
*************** build_tree_cfg (tree fnbody)
*** 268,274 ****
    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)
  	{
--- 270,276 ----
    first_p = first_exec_stmt (&BIND_EXPR_BODY (fnbody));
    if (first_p)
      {
!       make_blocks (first_p, NULL_TREE, NULL, NULL, fnbody);
  
        if (n_basic_blocks > 0)
  	{
*************** clear_blocks_annotations (void)
*** 388,400 ****
     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;
--- 390,404 ----
     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.
  
+    SCOPE is the BIND_EXPR block containing *FIRST_P.
+ 
     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 scope)
  {
    tree_stmt_iterator i;
    tree stmt, last;
*************** make_blocks (tree *first_p, tree next_bl
*** 430,448 ****
        /* 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;
--- 434,453 ----
        /* Now add STMT to BB and create the subgraphs for special statement
  	 codes.  */
        append_stmt_to_bb (stmt_p, bb, parent_stmt);
+       get_stmt_ann (stmt)->scope = scope;
  
        if (code == LOOP_EXPR)
! 	make_loop_expr_blocks (stmt_p, bb, scope);
        else if (code == COND_EXPR)
! 	make_cond_expr_blocks (stmt_p, next_block_link, bb, scope);
        else if (code == SWITCH_EXPR)
! 	make_switch_expr_blocks (stmt_p, next_block_link, bb, scope);
        else if (code == CATCH_EXPR)
! 	make_catch_expr_blocks (stmt_p, next_block_link, bb, scope);
        else if (code == EH_FILTER_EXPR)
! 	make_eh_filter_expr_blocks (stmt_p, next_block_link, bb, scope);
        else if (code == TRY_CATCH_EXPR || code == TRY_FINALLY_EXPR)
! 	make_try_expr_blocks (stmt_p, next_block_link, bb, scope);
        else if (code == BIND_EXPR)
  	{
  	  int num_blocks_before;
*************** make_blocks (tree *first_p, tree next_bl
*** 454,462 ****
  	     will be the last basic block of the BIND_EXPR's subgraph.  We
  	     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;
--- 459,471 ----
  	     will be the last basic block of the BIND_EXPR's subgraph.  We
  	     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;
! 	  assign_vars_to_scope (stmt);
! 	  get_stmt_ann (stmt)->scope_level =
! 		  get_stmt_ann (scope)->scope_level + 1;
! 
  	  last_bb = make_bind_expr_blocks (stmt_p, next_block_link, bb,
! 	                                   parent_stmt, stmt);
  	  if (last_bb)
  	    {
  	      bb = last_bb;
*************** could_trap_p (tree expr)
*** 548,557 ****
        lexical scope, this will be the statement that comes after LOOP_P's
        container (see the documentation for NEXT_BLOCK_LINK).
  
!    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;
--- 557,568 ----
        lexical scope, this will be the statement that comes after LOOP_P's
        container (see the documentation for NEXT_BLOCK_LINK).
  
!    ENTRY is the block whose last statement is *LOOP_P.
!    
!    SCOPE is the BIND_EXPR node holding *LOOP_P. */
  
  static void
! make_loop_expr_blocks (tree *loop_p, basic_block entry, tree scope)
  {
    tree_stmt_iterator si;
    tree loop = *loop_p;
*************** make_loop_expr_blocks (tree *loop_p, bas
*** 585,591 ****
  	next_block_link = *(tsi_container (si));
      }
  
!   make_blocks (&LOOP_EXPR_BODY (loop), next_block_link, loop, NULL);
  }
  
  
--- 596,602 ----
  	next_block_link = *(tsi_container (si));
      }
  
!   make_blocks (&LOOP_EXPR_BODY (loop), next_block_link, loop, NULL, scope);
  }
  
  
*************** make_loop_expr_blocks (tree *loop_p, bas
*** 596,606 ****
        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;
--- 607,619 ----
        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.
!    
!    SCOPE is the BIND_EXPR node holding *COND_P.  */
  
  static void
  make_cond_expr_blocks (tree *cond_p, tree next_block_link,
! 		       basic_block entry, tree scope)
  {
    tree_stmt_iterator si;
    tree cond = *cond_p;
*************** make_cond_expr_blocks (tree *cond_p, tre
*** 618,625 ****
      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.  */
--- 631,638 ----
      next_block_link = *(tsi_container (si));
  
    STRIP_CONTAINERS (cond);
!   make_blocks (&COND_EXPR_THEN (cond), next_block_link, cond, NULL, scope);
!   make_blocks (&COND_EXPR_ELSE (cond), next_block_link, cond, NULL, scope);
  }
  
  /* Derive an exception handling region type from STMT.  */
*************** get_eh_region_type (tree stmt)
*** 642,652 ****
  }
  
  /* Create the blocks for the TRY_CATCH_EXPR or TRY_FINALLY_EXPR node
!    pointed by expr_p.  */
  
  static void
  make_try_expr_blocks (tree *expr_p, tree next_block_link,
! 		      basic_block entry)
  {
    tree_stmt_iterator si;
    tree expr = *expr_p;
--- 655,667 ----
  }
  
  /* Create the blocks for the TRY_CATCH_EXPR or TRY_FINALLY_EXPR node
!    pointed by expr_p.
!    
!    SCOPE is the BIND_EXPR node holding *EXPR_P.  */
  
  static void
  make_try_expr_blocks (tree *expr_p, tree next_block_link,
! 		      basic_block entry, tree scope)
  {
    tree_stmt_iterator si;
    tree expr = *expr_p;
*************** make_try_expr_blocks (tree *expr_p, tree
*** 670,682 ****
    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.  */
--- 685,697 ----
    VARRAY_PUSH_TREE (eh_stack, expr);
  
    /* Make blocks for the TRY block.  */
!   make_blocks (&TREE_OPERAND (expr, 0), next_block_link, expr, NULL, scope);
  
    /* 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, scope);
  
    /* 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
*** 689,699 ****
      }
  }
  
! /* Create the blocks for the CATCH_EXPR node pointed to by expr_p.  */
  
  static void
  make_catch_expr_blocks (tree *expr_p, tree next_block_link,
! 			basic_block entry)
  {
    tree_stmt_iterator si;
    tree expr = *expr_p;
--- 704,716 ----
      }
  }
  
! /* Create the blocks for the CATCH_EXPR node pointed to by expr_p.
!    
!    SCOPE is the BIND_EXPR node holding *EXPR_P.  */
  
  static void
  make_catch_expr_blocks (tree *expr_p, tree next_block_link,
! 			basic_block entry, tree scope)
  {
    tree_stmt_iterator si;
    tree expr = *expr_p;
*************** make_catch_expr_blocks (tree *expr_p, tr
*** 708,721 ****
      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;
--- 725,740 ----
      tsi_next (&si);
  
    STRIP_CONTAINERS (expr);
!   make_blocks (&CATCH_BODY (expr), next_block_link, expr, NULL, scope);
  }
  
! /* Create the blocks for the EH_FILTER_EXPR node pointed to by expr_p.
!    
!    SCOPE is the BIND_EXPR node holding *EXPR_P.  */
  
  static void
  make_eh_filter_expr_blocks (tree *expr_p, tree next_block_link,
! 			    basic_block entry, tree scope)
  {
    tree_stmt_iterator si;
    tree expr = *expr_p;
*************** make_eh_filter_expr_blocks (tree *expr_p
*** 730,736 ****
      tsi_next (&si);
  
    STRIP_CONTAINERS (expr);
!   make_blocks (&EH_FILTER_FAILURE (expr), next_block_link, expr, NULL);
  }
  
  
--- 749,755 ----
      tsi_next (&si);
  
    STRIP_CONTAINERS (expr);
!   make_blocks (&EH_FILTER_FAILURE (expr), next_block_link, expr, NULL, scope);
  }
  
  
*************** make_eh_filter_expr_blocks (tree *expr_p
*** 741,751 ****
        inside a lexical scope, this will be the statement that comes after
        *SWITCH_E_P's container (see the documentation for NEXT_BLOCK_LINK).
  
!    ENTRY is the block whose last statement is *SWITCH_E_P.  */
  
  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;
--- 760,772 ----
        inside a lexical scope, this will be the statement that comes after
        *SWITCH_E_P's container (see the documentation for NEXT_BLOCK_LINK).
  
!    ENTRY is the block whose last statement is *SWITCH_E_P.
!    
!    SCOPE is the BIND_EXPR node holding *SWITCH_E_P.  */
  
  static void
  make_switch_expr_blocks (tree *switch_e_p, tree next_block_link,
! 			 basic_block entry, tree scope)
  {
    tree_stmt_iterator si;
    tree switch_e = *switch_e_p;
*************** make_switch_expr_blocks (tree *switch_e_
*** 763,769 ****
      next_block_link = *(tsi_container (si));
  
    STRIP_CONTAINERS (switch_e);
!   make_blocks (&SWITCH_BODY (switch_e), next_block_link, switch_e, NULL);
  }
  
  
--- 784,790 ----
      next_block_link = *(tsi_container (si));
  
    STRIP_CONTAINERS (switch_e);
!   make_blocks (&SWITCH_BODY (switch_e), next_block_link, switch_e, NULL, scope);
  }
  
  
*************** make_switch_expr_blocks (tree *switch_e_
*** 782,792 ****
  
     Return the last basic block added to the BIND_EXPR's subgraph.  This
     allows the caller to determine whether a new block should be started or
!    not.  */
  
  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;
--- 803,816 ----
  
     Return the last basic block added to the BIND_EXPR's subgraph.  This
     allows the caller to determine whether a new block should be started or
!    not.
!    
!    SCOPE is the BIND_EXPR node holding *BIND_P (in fact it is equal to
!    *BIND_P).  */
  
  static basic_block
  make_bind_expr_blocks (tree *bind_p, tree next_block_link,
! 		       basic_block entry, tree parent_stmt, tree scope)
  {
    tree_stmt_iterator si;
    tree bind = *bind_p;
*************** make_bind_expr_blocks (tree *bind_p, tre
*** 810,816 ****
       ends with a block terminating statement.  */
    STRIP_CONTAINERS (bind);
    return make_blocks (&BIND_EXPR_BODY (bind), next_block_link, parent_stmt,
! 		      entry);
  }
  
  
--- 834,840 ----
       ends with a block terminating statement.  */
    STRIP_CONTAINERS (bind);
    return make_blocks (&BIND_EXPR_BODY (bind), next_block_link, parent_stmt,
! 		      entry, scope);
  }
  
  
*************** tree_loop_optimizer_finalize (struct loo
*** 5103,5106 ****
--- 5127,5140 ----
  #ifdef ENABLE_CHECKING
    verify_flow_info ();
  #endif
+ }
+ 
+ /* Assigns a scope to variables defined in bind_expr SCOPE.  */
+ static void
+ assign_vars_to_scope (tree scope)
+ {
+   tree var;
+ 
+   for (var = BIND_EXPR_VARS (scope); var; var = TREE_CHAIN (var))
+     get_var_ann (var)->scope = scope;
  }
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.103
diff -c -3 -p -r1.1.4.103 tree-flow.h
*** tree-flow.h	15 Aug 2003 20:47:55 -0000	1.1.4.103
--- tree-flow.h	17 Aug 2003 21:30:15 -0000
*************** struct var_ann_d GTY(())
*** 120,125 ****
--- 120,128 ----
  
    /* Used by the root-var object in tree-ssa-live.[ch].  */
    unsigned root_index;
+ 
+   /* The BIND_EXPR in that the variable is declared.  */
+   tree scope;
  };
  
  
*************** struct stmt_ann_d GTY(())
*** 232,237 ****
--- 235,246 ----
  
    /* Array of variables that have had their address taken in the statement.  */
    varray_type addresses_taken;
+ 
+   /* The BIND_EXPR to that the statement belongs.  */
+   tree scope;
+ 
+   /* For BIND_EXPR, its level in the tree of BIND_EXPRs.  */
+   int scope_level;
  };
  
  
*************** void tree_ssa_dce (tree);
*** 491,498 ****
  
  /* In tree-ssa-copyprop.c  */
  void tree_ssa_copyprop (tree);
! void propagate_copy (tree *, tree);
! 
  
  /* In tree-flow-inline.h  */
  static inline int phi_arg_from_edge (tree, edge);
--- 500,507 ----
  
  /* In tree-ssa-copyprop.c  */
  void tree_ssa_copyprop (tree);
! void propagate_copy (tree *, tree, tree);
! void fixup_var_scope (tree, tree);
  
  /* In tree-flow-inline.h  */
  static inline int phi_arg_from_edge (tree, edge);
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	17 Aug 2003 21:30:15 -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, tree, 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,213 ****
  
  /* 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))
--- 205,216 ----
  
  /* 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, tree scope)
  {
  #if defined ENABLE_CHECKING
    if (!may_propagate_copy (*op_p, var))
*************** propagate_copy (tree *op_p, tree var)
*** 225,228 ****
--- 228,292 ----
      }
  
    *op_p = var;
+  
+   fixup_var_scope (var, scope);
+ }
+ 
+ /* Fixes scope of variable VAR if it does not currently belong to SCOPE.  */
+ void
+ fixup_var_scope (tree var, tree scope)
+ {
+   tree old_scope = var_ann (SSA_NAME_VAR (var))->scope;
+ 
+   /* If there is no old_scope, it is a newly created temporary, i.e. it is
+      in the topmost bind_expr and we have nothing to do.  */
+   if (old_scope)
+     {
+       if (!scope)
+ 	scope = DECL_SAVED_TREE (current_function_decl);
+       else
+ 	{
+ 	  while (stmt_ann (scope)->scope_level
+ 		 > stmt_ann (old_scope)->scope_level)
+ 	    scope = stmt_ann (scope)->scope;
+ 	}
+       if (scope != old_scope)
+ 	move_var_to_scope (SSA_NAME_VAR (var), old_scope,
+ 			   DECL_SAVED_TREE (current_function_decl));
+     }
+ }
+ 
+ /* Moves variable VAR from OLD_SCOPE to SCOPE.  */
+ static void
+ move_var_to_scope (tree var, tree old_scope, tree scope)
+ {
+   tree avar, prev;
+   tree block = BIND_EXPR_BLOCK (old_scope);
+ 
+   prev = NULL_TREE;
+   for (avar = BIND_EXPR_VARS (old_scope);
+        avar;
+        prev = avar, avar = TREE_CHAIN (avar))
+     if (avar == var)
+       break;
+   if (!avar)
+     abort ();
+ 
+   if (block)
+     remove_decl (avar, block);
+   else
+     remove_decl (avar, DECL_INITIAL (current_function_decl));
+ 
+   if (prev)
+     TREE_CHAIN (prev) = TREE_CHAIN (avar);
+   else
+     BIND_EXPR_VARS (old_scope) = TREE_CHAIN (avar);
+ 
+   TREE_CHAIN (var) = BIND_EXPR_VARS (scope);
+   BIND_EXPR_VARS (scope) = var;
+   var_ann (var)->scope = scope;
+ 
+   /* Dwarf2out ices (in add_abstract_origin_attribute) when it encounters
+      variable that is not declared, but has DECL_ABSTRACT_ORIGIN set.  */
+   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.26
diff -c -3 -p -r1.1.2.26 tree-ssa-dom.c
*** tree-ssa-dom.c	17 Aug 2003 19:00:35 -0000	1.1.2.26
--- tree-ssa-dom.c	17 Aug 2003 21:30:16 -0000
*************** optimize_stmt (block_stmt_iterator si, v
*** 759,765 ****
  	      addr_expr_propagated_p = true;
  
  	    if (TREE_CODE (val) == SSA_NAME)
! 	      propagate_copy (op_p, val);
  	    else
  	      *op_p = val;
  
--- 759,765 ----
  	      addr_expr_propagated_p = true;
  
  	    if (TREE_CODE (val) == SSA_NAME)
! 	      propagate_copy (op_p, val, stmt_ann (stmt)->scope);
  	    else
  	      *op_p = val;
  
*************** optimize_stmt (block_stmt_iterator si, v
*** 828,833 ****
--- 828,835 ----
  	    }
  
  	  opt_stats.num_re++;
+ 	  if (TREE_CODE (cached_lhs) == SSA_NAME)
+ 	    fixup_var_scope (cached_lhs, stmt_ann (stmt)->scope);
  	  *expr_p = cached_lhs;
  	  ann->modified = 1;
  	}


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