[3.5/3.4] Fix bug in tree-inline.c

Josef Zlomek zlomj9am@artax.karlin.mff.cuni.cz
Sat Feb 21 13:45:00 GMT 2004


> > 	* tree-inline.c (copy_body_r): Do not replace ret_label.
> 
> A better fix is to copy the insert_decl_map function 
> from tree-ssa.  This inserts identity mapings for all
> decls that we have already remapped.

Attached patch merges insert_decl_map from tree-ssa branch and
fixes the bug by inserting a mapping from id->ret_label to id->ret_label.

Bootstrapped/regtested x86-64.
OK?

Josef

2004-02-20  Josef Zlomek  <zlomekj@suse.cz>

	Merge from tree-ssa:
	2003-11-20  Richard Henderson  <rth@redhat.com>

		* tree-inline.c (insert_decl_map): New.
		(remap_decl, remap_type, remap_block, copy_body_r,
		initialize_inlined_parameters, declare_return_variable,
		remap_save_expr): Use it.

	* function.c (copy_body_r): Add mapping from id->ret_label to
	id->ret_label.  Revert test for ret_label.

Index: tree-inline.c
===================================================================
RCS file: /cvs/gcc-cvs/gcc/gcc/tree-inline.c,v
retrieving revision 1.94
diff -c -p -c -3 -p -r1.94 tree-inline.c
*** tree-inline.c	19 Feb 2004 22:39:45 -0000	1.94
--- tree-inline.c	20 Feb 2004 09:36:56 -0000
*************** static void remap_block (tree *, tree, i
*** 128,133 ****
--- 128,149 ----
  static tree add_stmt_to_compound (tree, tree, tree);
  #endif /* INLINER_FOR_JAVA */
  
+ /* Insert a tree->tree mapping for ID.  Despite the name suggests
+    that the trees should be variables, it is used for more than that.  */
+ 
+ static void
+ insert_decl_map (inline_data *id, tree key, tree value)
+ {
+   splay_tree_insert (id->decl_map, (splay_tree_key) key,
+ 		     (splay_tree_value) value);
+ 
+   /* Always insert an identity map as well.  If we see this same new
+      node again, we won't want to duplicate it a second time.  */
+   if (key != value)
+     splay_tree_insert (id->decl_map, (splay_tree_key) value,
+ 		       (splay_tree_value) value);
+ }
+ 
  /* Remap DECL during the copying of the BLOCK tree for the function.  */
  
  static tree
*************** remap_decl (tree decl, inline_data *id)
*** 189,197 ****
  
        /* Remember it, so that if we encounter this local entity
  	 again we can reuse this copy.  */
!       n = splay_tree_insert (id->decl_map,
! 			     (splay_tree_key) decl,
! 			     (splay_tree_value) t);
      }
  
    return (tree) n->value;
--- 205,212 ----
  
        /* Remember it, so that if we encounter this local entity
  	 again we can reuse this copy.  */
!       insert_decl_map (id, decl, t);
!       return t;
      }
  
    return (tree) n->value;
*************** remap_type (tree type, inline_data *id)
*** 214,228 ****
    /* The type only needs remapping if it's variably modified.  */
    if (! variably_modified_type_p (type))
      {
!       splay_tree_insert (id->decl_map, (splay_tree_key) type,
! 			 (splay_tree_value) type);
        return type;
      }
    
    /* We do need a copy.  build and register it now.  */
    new = copy_node (type);
!   splay_tree_insert (id->decl_map, (splay_tree_key) type,
! 		     (splay_tree_value) new);
  
    /* This is a new type, not a copy of an old type.  Need to reassociate
       variants.  We can handle everything except the main variant lazily.  */
--- 229,241 ----
    /* The type only needs remapping if it's variably modified.  */
    if (! variably_modified_type_p (type))
      {
!       insert_decl_map (id, type, type);
        return type;
      }
    
    /* We do need a copy.  build and register it now.  */
    new = copy_node (type);
!   insert_decl_map (id, type, new);
  
    /* This is a new type, not a copy of an old type.  Need to reassociate
       variants.  We can handle everything except the main variant lazily.  */
*************** remap_block (tree *block, tree decls, in
*** 392,400 ****
  	  *first_block = new_block;
  	}
        /* Remember the remapped block.  */
!       splay_tree_insert (id->decl_map,
! 			 (splay_tree_key) old_block,
! 			 (splay_tree_value) new_block);
      }
    /* If this is the end of a scope, set the SCOPE_STMT_BLOCK to be the
       remapped block.  */
--- 405,411 ----
  	  *first_block = new_block;
  	}
        /* Remember the remapped block.  */
!       insert_decl_map (id, old_block, new_block);
      }
    /* If this is the end of a scope, set the SCOPE_STMT_BLOCK to be the
       remapped block.  */
*************** copy_body_r (tree *tp, int *walk_subtree
*** 568,582 ****
        /* If we're not returning anything just do the jump.  */
        else
  	*tp = goto_stmt;
      }
    /* Local variables and labels need to be replaced by equivalent
       variables.  We don't want to copy static variables; there's only
       one of those, no matter how many times we inline the containing
!      function.
!      We do not also want to copy the label which we put into
!      GOTO_STMT which replaced RETURN_STMT.  */
!   else if (*tp != id->ret_label
! 	   && (*lang_hooks.tree_inlining.auto_var_in_fn_p) (*tp, fn))
      {
        tree new_decl;
  
--- 579,594 ----
        /* If we're not returning anything just do the jump.  */
        else
  	*tp = goto_stmt;
+ 
+       /* We can't replace return label while inlining function
+ 	 because it is in the outer function.  */
+       insert_decl_map (id, id->ret_label, id->ret_label);
      }
    /* Local variables and labels need to be replaced by equivalent
       variables.  We don't want to copy static variables; there's only
       one of those, no matter how many times we inline the containing
!      function.  */
!   else if ((*lang_hooks.tree_inlining.auto_var_in_fn_p) (*tp, fn))
      {
        tree new_decl;
  
*************** copy_body_r (tree *tp, int *walk_subtree
*** 611,619 ****
           will refer to it, so save a copy ready for remapping.  We
           save it in the decl_map, although it isn't a decl.  */
        tree new_block = copy_node (*tp);
!       splay_tree_insert (id->decl_map,
! 			 (splay_tree_key) *tp,
! 			 (splay_tree_value) new_block);
        *tp = new_block;
      }
    else if (TREE_CODE (*tp) == EXIT_BLOCK_EXPR)
--- 623,629 ----
           will refer to it, so save a copy ready for remapping.  We
           save it in the decl_map, although it isn't a decl.  */
        tree new_block = copy_node (*tp);
!       insert_decl_map (id, *tp, new_block);
        *tp = new_block;
      }
    else if (TREE_CODE (*tp) == EXIT_BLOCK_EXPR)
*************** DECL_ARGUMENTS (fn);
*** 784,792 ****
  	      else if (TREE_TYPE (value) != TREE_TYPE (p))
  		value = fold (build1 (NOP_EXPR, TREE_TYPE (p), value));
  
! 	      splay_tree_insert (id->decl_map,
! 				 (splay_tree_key) p,
! 				 (splay_tree_value) value);
  	      continue;
  	    }
  	}
--- 794,800 ----
  	      else if (TREE_TYPE (value) != TREE_TYPE (p))
  		value = fold (build1 (NOP_EXPR, TREE_TYPE (p), value));
  
! 	      insert_decl_map (id, p, value);
  	      continue;
  	    }
  	}
*************** DECL_ARGUMENTS (fn);
*** 807,815 ****
        /* Register the VAR_DECL as the equivalent for the PARM_DECL;
  	 that way, when the PARM_DECL is encountered, it will be
  	 automatically replaced by the VAR_DECL.  */
!       splay_tree_insert (id->decl_map,
! 			 (splay_tree_key) p,
! 			 (splay_tree_value) var_sub);
  
        /* Declare this new variable.  */
  #ifndef INLINER_FOR_JAVA
--- 815,821 ----
        /* Register the VAR_DECL as the equivalent for the PARM_DECL;
  	 that way, when the PARM_DECL is encountered, it will be
  	 automatically replaced by the VAR_DECL.  */
!       insert_decl_map (id, p, var_sub);
  
        /* Declare this new variable.  */
  #ifndef INLINER_FOR_JAVA
*************** declare_return_variable (struct inline_d
*** 947,955 ****
    /* Register the VAR_DECL as the equivalent for the RESULT_DECL; that
       way, when the RESULT_DECL is encountered, it will be
       automatically replaced by the VAR_DECL.  */
!   splay_tree_insert (id->decl_map,
! 		     (splay_tree_key) result,
! 		     (splay_tree_value) var);
  
    /* Build the USE_STMT.  If the return type of the function was
       promoted, convert it back to the expected type.  */
--- 953,959 ----
    /* Register the VAR_DECL as the equivalent for the RESULT_DECL; that
       way, when the RESULT_DECL is encountered, it will be
       automatically replaced by the VAR_DECL.  */
!   insert_decl_map (id, result, var);
  
    /* Build the USE_STMT.  If the return type of the function was
       promoted, convert it back to the expected type.  */
*************** remap_save_expr (tree *tp, void *st_, tr
*** 2005,2010 ****
--- 2009,2015 ----
  {
    splay_tree st = (splay_tree) st_;
    splay_tree_node n;
+   tree t;
  
    /* See if we already encountered this SAVE_EXPR.  */
    n = splay_tree_lookup (st, (splay_tree_key) *tp);
*************** remap_save_expr (tree *tp, void *st_, tr
*** 2012,2018 ****
    /* If we didn't already remap this SAVE_EXPR, do so now.  */
    if (!n)
      {
!       tree t = copy_node (*tp);
  
        /* The SAVE_EXPR is now part of the function into which we
  	 are inlining this body.  */
--- 2017,2023 ----
    /* If we didn't already remap this SAVE_EXPR, do so now.  */
    if (!n)
      {
!       t = copy_node (*tp);
  
        /* The SAVE_EXPR is now part of the function into which we
  	 are inlining this body.  */
*************** remap_save_expr (tree *tp, void *st_, tr
*** 2020,2038 ****
        /* And we haven't evaluated it yet.  */
        SAVE_EXPR_RTL (t) = NULL_RTX;
        /* Remember this SAVE_EXPR.  */
!       n = splay_tree_insert (st,
! 			     (splay_tree_key) *tp,
! 			     (splay_tree_value) t);
        /* Make sure we don't remap an already-remapped SAVE_EXPR.  */
        splay_tree_insert (st, (splay_tree_key) t, (splay_tree_value) t);
      }
    else
!     /* We've already walked into this SAVE_EXPR, so we needn't do it
!        again.  */
!     *walk_subtrees = 0;
  
    /* Replace this SAVE_EXPR with the copy.  */
!   *tp = (tree) n->value;
  }
  
  #ifdef INLINER_FOR_JAVA
--- 2025,2043 ----
        /* And we haven't evaluated it yet.  */
        SAVE_EXPR_RTL (t) = NULL_RTX;
        /* Remember this SAVE_EXPR.  */
!       splay_tree_insert (st, (splay_tree_key) *tp, (splay_tree_value) t);
        /* Make sure we don't remap an already-remapped SAVE_EXPR.  */
        splay_tree_insert (st, (splay_tree_key) t, (splay_tree_value) t);
      }
    else
!     {
!       /* We've already walked into this SAVE_EXPR; don't do it again.  */
!       *walk_subtrees = 0;
!       t = (tree) n->value;
!     }
  
    /* Replace this SAVE_EXPR with the copy.  */
!   *tp = t;
  }
  
  #ifdef INLINER_FOR_JAVA



More information about the Gcc-patches mailing list