[tree-ssa] Make C++ NRV opts work with tree-ssa

law@redhat.com law@redhat.com
Tue Apr 15 19:45:00 GMT 2003


I originally thought we could simply defer the NRV optimization until
after tree-ssa optimizations were complete.  I couldn't have been more 
wrong :(

Once we gimplify the code we've got little hope of applying the
NRV optimization because of how we're forced to simplify return
statements for exception handling.

It would also be rather difficult to preserve the NRV optimization
in inlined functions.

So I've taken another approach for the short term -- specifically
I use the same mechanisms currently in place to prevent variables
used in VLAs from being deleted by DCE.   ie, we just mark the
variable for the named return value as being implicitly needed
and everything "just works".

Anyway, this has been bootstrapped and regression tested without any 
new failures.  And (of course) it fixes failures in my tree since
I'm running C++ code through the tree-ssa optimizers :-)



	* tree-flow.h (struct var_ann_d): Renamed is_vla_decl field to
	has_hidden_use.
	(has_hidden_use, set_has_hidden_use): Renamed from is_vla_decl
	and set_vla_decl.
	* tree-flow-inline.h (has_hidden_use): Renamed from is_vla_decl.
	Updated to use "has_hidden_use" instead of "is_vla_decl" field.
	(set_has_hidden_use): Renamed from set_vla_decl.
	Updated to use "has_hidden_use" instead of "is_vla_decl" field.
	* tree-dfa.c (dump_variable): Corresponding changes.
	(find_vla_decls_r): Likewise.
	* c-simplify.c (simplify_decl_stmt): Likewise.
	* tree-ssa-dce.c: Likewise.

	* cp/Makefile.in (decl.o): Depends on tree-flow.h.
	* cp/decl.c (finish_function): Call set_has_hidden_use when
	nullifying returns for named value return optimization.

Index: c-simplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/c-simplify.c,v
retrieving revision 1.1.4.45
diff -c -3 -p -r1.1.4.45 c-simplify.c
*** c-simplify.c	14 Mar 2003 00:19:01 -0000	1.1.4.45
--- c-simplify.c	15 Apr 2003 19:22:31 -0000
*************** simplify_decl_stmt (stmt_p, next_p)
*** 773,779 ****
  
  	  /* Mark the unit size as being used in the VLA's declaration so
  	     it will not be deleted by DCE.  */
! 	  set_vla_decl (usize);
  
  	  DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (TREE_TYPE (decl)) = usize;
  
--- 773,779 ----
  
  	  /* Mark the unit size as being used in the VLA's declaration so
  	     it will not be deleted by DCE.  */
! 	  set_has_hidden_use (usize);
  
  	  DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (TREE_TYPE (decl)) = usize;
  
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.96
diff -c -3 -p -r1.1.4.96 tree-dfa.c
*** tree-dfa.c	14 Apr 2003 17:52:28 -0000	1.1.4.96
--- tree-dfa.c	15 Apr 2003 19:22:49 -0000
*************** dump_variable (file, var)
*** 1311,1318 ****
    if (may_alias_global_mem_p (var))
      fprintf (file, ", may alias global memory");
  
!   if (is_vla_decl (var))
!     fprintf (file, ", is used to declare a VLA");
  
    if (may_point_to_global_mem_p (var))
      fprintf (file, ", may point to global memory");
--- 1311,1318 ----
    if (may_alias_global_mem_p (var))
      fprintf (file, ", may alias global memory");
  
!   if (has_hidden_use (var))
!     fprintf (file, ", has a hidden use");
  
    if (may_point_to_global_mem_p (var))
      fprintf (file, ", may point to global memory");
*************** find_vla_decls (block)
*** 2552,2558 ****
  /* Callback for walk_tree used by find_vla_decls to analyze each array in a
     lexical block.  For each array type, it walks its TYPE_SIZE and
     TYPE_SIZE_UNIT trees looking for VAR_DECLs.  Those VAR_DECLs will be
!    marked as needed for VLA.  */
  
  static tree
  find_vla_decls_r (tp, walk_subtrees, data)
--- 2552,2558 ----
  /* Callback for walk_tree used by find_vla_decls to analyze each array in a
     lexical block.  For each array type, it walks its TYPE_SIZE and
     TYPE_SIZE_UNIT trees looking for VAR_DECLs.  Those VAR_DECLs will be
!    marked as having a hidden use.  */
  
  static tree
  find_vla_decls_r (tp, walk_subtrees, data)
*************** find_vla_decls_r (tp, walk_subtrees, dat
*** 2569,2575 ****
        walk_tree (&TYPE_SIZE_UNIT (*tp), find_vla_decls_r, inside_vla, NULL);
      }
    else if (*inside_vla && SSA_DECL_P (*tp))
!     set_vla_decl (*tp);
  
    return NULL_TREE;
  }
--- 2569,2575 ----
        walk_tree (&TYPE_SIZE_UNIT (*tp), find_vla_decls_r, inside_vla, NULL);
      }
    else if (*inside_vla && SSA_DECL_P (*tp))
!     set_has_hidden_use (*tp);
  
    return NULL_TREE;
  }
Index: tree-flow-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow-inline.h,v
retrieving revision 1.1.2.33
diff -c -3 -p -r1.1.2.33 tree-flow-inline.h
*** tree-flow-inline.h	6 Apr 2003 17:10:04 -0000	1.1.2.33
--- tree-flow-inline.h	15 Apr 2003 19:22:50 -0000
*************** indirect_ref (var)
*** 145,165 ****
  }
  
  static inline bool
! is_vla_decl (var)
       tree var;
  {
    var_ann_t ann = var_ann (var);
!   return ann ? ann->is_vla_decl : false;
  }
  
  static inline void
! set_vla_decl (var)
       tree var;
  {
    var_ann_t ann = var_ann (var);
    if (ann == NULL)
      ann = create_var_ann (var);
!   ann->is_vla_decl = 1;
  }
  
  static inline int
--- 145,165 ----
  }
  
  static inline bool
! has_hidden_use (var)
       tree var;
  {
    var_ann_t ann = var_ann (var);
!   return ann ? ann->has_hidden_use : false;
  }
  
  static inline void
! set_has_hidden_use (var)
       tree var;
  {
    var_ann_t ann = var_ann (var);
    if (ann == NULL)
      ann = create_var_ann (var);
!   ann->has_hidden_use = 1;
  }
  
  static inline int
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.69
diff -c -3 -p -r1.1.4.69 tree-flow.h
*** tree-flow.h	7 Apr 2003 01:07:57 -0000	1.1.4.69
--- tree-flow.h	15 Apr 2003 19:22:50 -0000
*************** struct var_ann_d GTY(())
*** 60,68 ****
    /* Nonzero if this pointer may point to global memory.  */
    unsigned may_point_to_global_mem : 1;
  
!   /* Nonzero if this variable is used to declare a VLA (see
!      find_vla_decl_r).  */
!   unsigned is_vla_decl : 1;
  
    /* Nonzero if this variable was stored/written in the function.
       
--- 60,75 ----
    /* Nonzero if this pointer may point to global memory.  */
    unsigned may_point_to_global_mem : 1;
  
!   /* Nonzero if this variable has uses which may not appear
!      in the IL.  This can happen in the following cases:
! 
!        1. If the variable is used in a variable length
!           array declaration.
! 
! 	2. If the variable is the return value in a C++
! 	   function where the named return value optimization
! 	   has been performed.  */
!   unsigned has_hidden_use : 1;
  
    /* Nonzero if this variable was stored/written in the function.
       
*************** static inline varray_type use_ops		PARAM
*** 246,253 ****
  static inline tree *def_op			PARAMS ((tree));
  static inline varray_type immediate_uses	PARAMS ((tree));
  static inline varray_type reaching_defs		PARAMS ((tree));
! static inline bool is_vla_decl			PARAMS ((tree));
! static inline void set_vla_decl			PARAMS ((tree));
  static inline tree parent_stmt			PARAMS ((tree));
  
  
--- 257,264 ----
  static inline tree *def_op			PARAMS ((tree));
  static inline varray_type immediate_uses	PARAMS ((tree));
  static inline varray_type reaching_defs		PARAMS ((tree));
! static inline bool has_hidden_use		PARAMS ((tree));
! static inline void set_has_hidden_use		PARAMS ((tree));
  static inline tree parent_stmt			PARAMS ((tree));
  
  
Index: tree-ssa-dce.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dce.c,v
retrieving revision 1.1.2.32
diff -c -3 -p -r1.1.2.32 tree-ssa-dce.c
*** tree-ssa-dce.c	7 Apr 2003 01:07:57 -0000	1.1.2.32
--- tree-ssa-dce.c	15 Apr 2003 19:22:55 -0000
*************** need_to_preserve_store (var)
*** 219,226 ****
    if (may_alias_global_mem_p (sym))
      return true;
  
!   /* If SYM is used to declare VLAs, we need to preserve it.  */
!   if (is_vla_decl (sym))
      return true;
  
    return false;
--- 219,229 ----
    if (may_alias_global_mem_p (sym))
      return true;
  
!   /* If SYM is used in some way we can not readily see in the IL, then
!      we need to preserve it.
! 
!      Long term this needs to go away.  */
!   if (has_hidden_use (sym))
      return true;
  
    return false;
Index: cp/Make-lang.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/Make-lang.in,v
retrieving revision 1.115.2.25
diff -c -3 -p -r1.115.2.25 Make-lang.in
*** cp/Make-lang.in	9 Apr 2003 19:28:23 -0000	1.115.2.25
--- cp/Make-lang.in	15 Apr 2003 19:23:12 -0000
*************** cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H)
*** 243,249 ****
  cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h cp/decl.h 
stack.h \
    output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(RTL_H) \
    cp/operators.def $(TM_P_H) tree-inline.h diagnostic.h c-pragma.h \
!   debug.h gt-cp-decl.h gtype-cp.h timevar.h
  cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h cp/decl.h 
$(EXPR_H) \
    output.h except.h toplev.h $(RTL_H) c-common.h gt-cp-decl2.h
  cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h output.h 
$(TM_P_H) \
--- 243,249 ----
  cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h cp/decl.h 
stack.h \
    output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(RTL_H) \
    cp/operators.def $(TM_P_H) tree-inline.h diagnostic.h c-pragma.h \
!   debug.h gt-cp-decl.h gtype-cp.h timevar.h $(TREE_FLOW_H)
  cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h cp/decl.h 
$(EXPR_H) \
    output.h except.h toplev.h $(RTL_H) c-common.h gt-cp-decl2.h
  cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h output.h 
$(TM_P_H) \
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.911.2.28
diff -c -3 -p -r1.911.2.28 decl.c
*** cp/decl.c	9 Apr 2003 19:28:26 -0000	1.911.2.28
--- cp/decl.c	15 Apr 2003 19:24:00 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 51,56 ****
--- 51,57 ----
  #include "diagnostic.h"
  #include "debug.h"
  #include "timevar.h"
+ #include "tree-flow.h"
  
  static tree grokparms (tree);
  static const char *redeclaration_error_message (tree, tree);
*************** finish_function (int flags)
*** 14008,14013 ****
--- 14009,14016 ----
  	      chain_member (r, BLOCK_VARS (outer))))
  	{
  	  
+ 	  if (!flag_disable_simple)
+ 	    set_has_hidden_use (r);
  	  DECL_ALIGN (r) = DECL_ALIGN (DECL_RESULT (fndecl));
  	  walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
  					nullify_returns_r, r);




More information about the Gcc-patches mailing list