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]

C++ PATCH for EH-only cleanups, part 2


Various cleanup enabled by the previous patch.  Most notably, all the
partial-object exception handling machinery can now go away, as we can use
EH-only cleanups to perform the same function using the normal machinery.

The build_new_1 change is a minor optimization, to avoid emitting some dead
code in the first place.

Tested i686-pc-linux-gnu, applied to trunk only.

2002-04-04  Jason Merrill  <jason@redhat.com>

	* except.c (struct eh_status): Remove protect_list.
	(begin_protect_partials, end_protect_partials): Remove.
	(add_partial_entry): Remove.
	* except.h: Remove prototypes.

	* expr.c (expand_expr) [WITH_CLEANUP_EXPR, TARGET_EXPR]: Use
	expand_decl_cleanup_eh.

cp/:
	* semantics.c (finish_eh_cleanup): New fn.
	* cp-tree.h: Add prototype.
	* init.c (perform_member_init, expand_cleanup_for_base): Use 
	finish_eh_cleanup.
	* cp-tree.def (SUBOBJECT, CTOR_STMT): Remove.
	* cp-tree.h: Remove references.
	* decl.c (begin_constructor_body, end_constructor_body): Likewise.
	* dump.c (cp_dump_tree): Likewise.
	* pt.c (tsubst_expr): Likewise.
	* semantics.c (genrtl_ctor_stmt, genrtl_subobject): Remove.
	(cp_expand_stmt): Remove handling of CTOR_STMT and SUBOBJECT.
	* tree.c (cp_statement_code_p): Likewise.

	* init.c (build_new_1): Set CLEANUP_EH_ONLY on deleting cleanup.

*** ./cp/pt.c.~1~	Wed Apr  3 21:36:21 2002
--- ./cp/pt.c	Wed Apr  3 21:17:33 2002
*************** tsubst_expr (t, args, complain, in_decl)
*** 7584,7593 ****
        tsubst (TREE_TYPE (t), args, complain, NULL_TREE);
        break;
  
-     case CTOR_STMT:
-       add_stmt (copy_node (t));
-       break;
- 
      default:
        abort ();
      }
--- 7584,7589 ----
*** ./cp/cp-tree.def.~1~	Wed Apr  3 21:36:21 2002
--- ./cp/cp-tree.def	Wed Apr  3 14:36:27 2002
*************** DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr
*** 220,235 ****
  DEFTREECODE (TYPEID_EXPR, "typeid_expr", 'e', 1)
  DEFTREECODE (PSEUDO_DTOR_EXPR, "pseudo_dtor_expr", 'e', 3)
  
- /* A SUBOBJECT statement marks the point at which a sub-object is
-    fully constructed.  After this point, the SUBOBJECT_CLEANUP must be
-    run if an exception is thrown before the end of the enclosing
-    function.  */
- DEFTREECODE (SUBOBJECT, "subobject", 'e', 1)
- /* An CTOR_STMT marks the beginning (if CTOR_BEGIN_P holds) or end of
-    a constructor (if CTOR_END_P) holds.  At the end of a constructor,
-    the cleanups associated with any SUBOBJECT_CLEANUPS need no longer
-    be run.  */
- DEFTREECODE (CTOR_STMT, "ctor_stmt", 'e', 0)
  /* CTOR_INITIALIZER is a placeholder in template code for a call to
     setup_vtbl_pointer (and appears in all functions, not just ctors).  */
  DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 2)
--- 220,225 ----
*** ./cp/cp-tree.h.~1~	Wed Apr  3 21:36:21 2002
--- ./cp/cp-tree.h	Wed Apr  3 21:17:24 2002
*************** struct diagnostic_context;
*** 47,53 ****
        ICS_USER_FLAG (in _CONV)
        CLEANUP_P (in TRY_BLOCK)
        AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR)
-       CTOR_BEGIN_P (in CTOR_STMT)
        BV_USE_VCALL_INDEX_P (in the BINFO_VIRTUALS TREE_LIST)
        PTRMEM_OK_P (in ADDR_EXPR, OFFSET_REF)
        PARMLIST_ELLIPSIS_P (in PARMLIST)
--- 47,52 ----
*************** enum ptrmemfunc_vbit_where_t
*** 2969,2983 ****
  #define HANDLER_PARMS(NODE)     TREE_OPERAND (HANDLER_CHECK (NODE), 0)
  #define HANDLER_BODY(NODE)      TREE_OPERAND (HANDLER_CHECK (NODE), 1)
  #define HANDLER_TYPE(NODE)	TREE_TYPE (HANDLER_CHECK (NODE))
- #define SUBOBJECT_CLEANUP(NODE) TREE_OPERAND (SUBOBJECT_CHECK (NODE), 0)
- 
- /* Nonzero if this CTOR_STMT is for the beginning of a constructor.  */
- #define CTOR_BEGIN_P(NODE) \
-   (TREE_LANG_FLAG_0 (CTOR_STMT_CHECK (NODE)))
- 
- /* Nonzero if this CTOR_STMT is for the end of a constructor.  */
- #define CTOR_END_P(NODE) \
-   (!CTOR_BEGIN_P (NODE))
  
  /* The parameters for a call-declarator.  */
  #define CALL_DECLARATOR_PARMS(NODE) \
--- 2968,2973 ----
*************** extern tree finish_typeof			PARAMS ((tre
*** 4217,4222 ****
--- 4207,4213 ----
  extern tree finish_sizeof			PARAMS ((tree));
  extern tree finish_alignof			PARAMS ((tree));
  extern void finish_decl_cleanup                 PARAMS ((tree, tree));
+ extern void finish_eh_cleanup                   PARAMS ((tree));
  extern void finish_named_return_value           PARAMS ((tree, tree));
  extern void expand_body                         PARAMS ((tree));
  extern tree nullify_returns_r		      PARAMS ((tree *, int *, void *));
*** ./cp/decl.c.~1~	Wed Apr  3 21:36:21 2002
--- ./cp/decl.c	Wed Apr  3 21:17:29 2002
*************** save_function_data (decl)
*** 13951,13959 ****
  static void
  begin_constructor_body ()
  {
-   tree ctor_stmt = build_stmt (CTOR_STMT);
-   CTOR_BEGIN_P (ctor_stmt) = 1;
-   add_stmt (ctor_stmt);
  }
  
  /* Add a note to mark the end of the main body of the constructor.  This is
--- 13951,13956 ----
*************** begin_constructor_body ()
*** 13963,13974 ****
  static void
  finish_constructor_body ()
  {
-   /* Mark the end of the cleanups for a partially constructed object.
- 
-      ??? These should really be handled automatically by closing the block,
-      as with the destructor cleanups; the only difference is that these are
-      only run if an exception is thrown.  */
-   add_stmt (build_stmt (CTOR_STMT));
  }
  
  /* Do all the processing for the beginning of a destructor; set up the
--- 13960,13965 ----
*** ./cp/dump.c.~1~	Wed Apr  3 21:36:21 2002
--- ./cp/dump.c	Wed Apr  3 14:36:10 2002
*************** cp_dump_tree (dump_info, t)
*** 390,404 ****
        dump_child ("decl", TREE_OPERAND (t, 2));
        break;
        
-     case CTOR_STMT:
-       dump_stmt (di, t);
-       if (CTOR_BEGIN_P (t))
- 	dump_string (di, "begn");
-       else
- 	dump_string (di, "end");
-       dump_next_stmt (di, t);
-       break;
- 
      case HANDLER:
        dump_stmt (di, t);
        dump_child ("parm", HANDLER_PARMS (t));
--- 390,395 ----
*************** cp_dump_tree (dump_info, t)
*** 412,423 ****
        dump_next_stmt (di, t);
        break;
  
-     case SUBOBJECT:
-       dump_stmt (di, t);
-       dump_child ("clnp", TREE_OPERAND (t, 0));
-       dump_next_stmt (di, t);
-       break;
- 
      case USING_STMT:
        dump_stmt (di, t);
        dump_child ("nmsp", USING_STMT_NAMESPACE (t));
--- 403,408 ----
*** ./cp/init.c.~1~	Wed Apr  3 21:36:21 2002
--- ./cp/init.c	Thu Apr  4 00:56:27 2002
*************** perform_member_init (member, init, expli
*** 296,302 ****
  			   LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
  
        if (expr != error_mark_node)
! 	finish_subobject (expr);
      }
  }
  
--- 296,302 ----
  			   LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
  
        if (expr != error_mark_node)
! 	finish_eh_cleanup (expr);
      }
  }
  
*************** expand_cleanup_for_base (binfo, flag)
*** 844,850 ****
  			truthvalue_conversion (flag),
  			expr, integer_zero_node));
  
!   finish_subobject (expr);
  }
  
  /* Subroutine of `expand_aggr_vbase_init'.
--- 844,850 ----
  			truthvalue_conversion (flag),
  			expr, integer_zero_node));
  
!   finish_eh_cleanup (expr);
  }
  
  /* Subroutine of `expand_aggr_vbase_init'.
*************** build_new_1 (exp)
*** 2498,2506 ****
  	      tree end, sentry, begin;
  
  	      begin = get_target_expr (boolean_true_node);
! 	      sentry = TREE_OPERAND (begin, 0);
  
! 	      TREE_OPERAND (begin, 2)
  		= build (COND_EXPR, void_type_node, sentry,
  			 cleanup, void_zero_node);
  
--- 2498,2508 ----
  	      tree end, sentry, begin;
  
  	      begin = get_target_expr (boolean_true_node);
! 	      CLEANUP_EH_ONLY (begin) = 1;
  
! 	      sentry = TARGET_EXPR_SLOT (begin);
! 
! 	      TARGET_EXPR_CLEANUP (begin)
  		= build (COND_EXPR, void_type_node, sentry,
  			 cleanup, void_zero_node);
  
*** ./cp/semantics.c.~1~	Wed Apr  3 21:36:21 2002
--- ./cp/semantics.c	Wed Apr  3 21:17:35 2002
*************** static void emit_associated_thunks PARAM
*** 56,63 ****
  static void genrtl_try_block PARAMS ((tree));
  static void genrtl_eh_spec_block PARAMS ((tree));
  static void genrtl_handler PARAMS ((tree));
- static void genrtl_ctor_stmt PARAMS ((tree));
- static void genrtl_subobject PARAMS ((tree));
  static void genrtl_named_return_value PARAMS ((void));
  static void cp_expand_stmt PARAMS ((tree));
  static void genrtl_start_function PARAMS ((tree));
--- 56,61 ----
*************** finish_handler (handler)
*** 777,797 ****
    RECHAIN_STMTS (handler, HANDLER_BODY (handler));
  }
  
- /* Generate the RTL for T, which is a CTOR_STMT. */
- 
- static void
- genrtl_ctor_stmt (t)
-      tree t;
- {
-   if (CTOR_BEGIN_P (t))
-     begin_protect_partials ();
-   else
-     /* After this point, any exceptions will cause the
-        destructor to be executed, so we no longer need to worry
-        about destroying the various subobjects ourselves.  */
-     end_protect_partials ();
- }
- 
  /* Begin a compound-statement.  If HAS_NO_SCOPE is non-zero, the
     compound-statement does not define a scope.  Returns a new
     COMPOUND_STMT if appropriate.  */
--- 775,780 ----
*************** finish_label_decl (name)
*** 976,1002 ****
    add_decl_stmt (decl);
  }
  
- /* Generate the RTL for a SUBOBJECT. */
- 
- static void 
- genrtl_subobject (cleanup)
-      tree cleanup;
- {
-   add_partial_entry (cleanup);
- }
- 
- /* We're in a constructor, and have just constructed a a subobject of
-    *THIS.  CLEANUP is code to run if an exception is thrown before the
-    end of the current function is reached.   */
- 
- void 
- finish_subobject (cleanup)
-      tree cleanup;
- {
-   tree r = build_stmt (SUBOBJECT, cleanup);
-   add_stmt (r);
- }
- 
  /* When DECL goes out of scope, make sure that CLEANUP is executed.  */
  
  void 
--- 959,964 ----
*************** finish_decl_cleanup (decl, cleanup)
*** 1007,1012 ****
--- 969,983 ----
    add_stmt (build_stmt (CLEANUP_STMT, decl, cleanup));
  }
  
+ void
+ finish_eh_cleanup (cleanup)
+      tree cleanup;
+ {
+   tree r = build_stmt (CLEANUP_STMT, NULL_TREE, cleanup);
+   CLEANUP_EH_ONLY (r) = 1;
+   add_stmt (r);
+ }
+ 
  /* Generate the RTL for a RETURN_INIT. */
  
  static void
*************** cp_expand_stmt (t)
*** 2130,2139 ****
  {
    switch (TREE_CODE (t))
      {
-     case CTOR_STMT:
-       genrtl_ctor_stmt (t);
-       break;
- 
      case TRY_BLOCK:
        genrtl_try_block (t);
        break;
--- 2101,2106 ----
*************** cp_expand_stmt (t)
*** 2146,2155 ****
        genrtl_handler (t);
        break;
  
-     case SUBOBJECT:
-       genrtl_subobject (SUBOBJECT_CLEANUP (t));
-       break;
- 
      case RETURN_INIT:
        genrtl_named_return_value ();
        break;
--- 2113,2118 ----
*** ./cp/tree.c.~1~	Wed Apr  3 21:36:21 2002
--- ./cp/tree.c	Wed Apr  3 21:17:35 2002
*************** cp_statement_code_p (code)
*** 1030,1037 ****
  {
    switch (code)
      {
-     case SUBOBJECT:
-     case CTOR_STMT:
      case CTOR_INITIALIZER:
      case RETURN_INIT:
      case TRY_BLOCK:
--- 1030,1035 ----
*** ./except.c.~1~	Wed Apr  3 21:36:20 2002
--- ./except.c	Wed Apr  3 21:15:45 2002
*************** struct eh_status
*** 214,225 ****
    /* This is the region for which we are processing catch blocks.  */
    struct eh_region *try_region;
  
-   /* A stack (TREE_LIST) of lists of handlers.  The TREE_VALUE of each
-      node is itself a TREE_CHAINed list of handlers for regions that
-      are not yet closed. The TREE_VALUE of each entry contains the
-      handler for the corresponding entry on the ehstack.  */
-   tree protect_list;
- 
    rtx filter;
    rtx exc_ptr;
  
--- 214,219 ----
*************** mark_eh_status (eh)
*** 560,566 ****
      tree_done:;
      }
  
-   ggc_mark_tree (eh->protect_list);
    ggc_mark_rtx (eh->filter);
    ggc_mark_rtx (eh->exc_ptr);
    ggc_mark_tree_varray (eh->ttype_data);
--- 554,559 ----
*************** get_exception_filter (fun)
*** 1012,1066 ****
    return filter;
  }
  
- /* Begin a region that will contain entries created with
-    add_partial_entry.  */
- 
- void
- begin_protect_partials ()
- {
-   /* Push room for a new list.  */
-   cfun->eh->protect_list
-     = tree_cons (NULL_TREE, NULL_TREE, cfun->eh->protect_list);
- }
- 
- /* Start a new exception region for a region of code that has a
-    cleanup action and push the HANDLER for the region onto
-    protect_list. All of the regions created with add_partial_entry
-    will be ended when end_protect_partials is invoked.
- 
-    ??? The only difference between this purpose and that of
-    expand_decl_cleanup is that in this case, we only want the cleanup to
-    run if an exception is thrown.  This should also be handled using
-    binding levels.  */
- 
- void
- add_partial_entry (handler)
-      tree handler;
- {
-   expand_eh_region_start ();
- 
-   /* Add this entry to the front of the list.  */
-   TREE_VALUE (cfun->eh->protect_list)
-     = tree_cons (NULL_TREE, handler, TREE_VALUE (cfun->eh->protect_list));
- }
- 
- /* End all the pending exception regions on protect_list.  */
- 
- void
- end_protect_partials ()
- {
-   tree t;
- 
-   /* Pop the topmost entry.  */
-   t = TREE_VALUE (cfun->eh->protect_list);
-   cfun->eh->protect_list = TREE_CHAIN (cfun->eh->protect_list);
- 
-   /* End all the exception regions.  */
-   for (; t; t = TREE_CHAIN (t))
-     expand_eh_region_end_cleanup (TREE_VALUE (t));
- }
- 
- 
  /* This section is for the exception handling specific optimization pass.  */
  
  /* Random access the exception region tree.  It's just as simple to
--- 1005,1010 ----
*** ./except.h.~1~	Wed Apr  3 21:36:20 2002
--- ./except.h	Wed Apr  3 14:38:19 2002
*************** extern void expand_eh_region_end_throw		
*** 83,102 ****
     destroying an object twice.  */
  extern void expand_eh_region_end_fixup		PARAMS ((tree));
  
- /* Begin a region that will contain entries created with
-    add_partial_entry.  */
- extern void begin_protect_partials              PARAMS ((void));
- 
- /* Create a new exception region and add the handler for the region
-    onto a list. These regions will be ended (and their handlers emitted)
-    when end_protect_partials is invoked.  */
- extern void add_partial_entry			PARAMS ((tree));
- 
- /* End all of the pending exception regions that have handlers added with
-    add_partial_entry.  */
- extern void end_protect_partials		PARAMS ((void));
- 
- 
  /* A list of labels used for exception handlers.  */
  extern rtx exception_handler_labels;
  
--- 83,88 ----
*** ./expr.c.~1~	Wed Apr  3 21:36:20 2002
--- ./expr.c	Wed Apr  3 21:15:52 2002
*************** expand_expr (exp, target, tmode, modifie
*** 7209,7215 ****
  	{
  	  WITH_CLEANUP_EXPR_RTL (exp)
  	    = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
! 	  expand_decl_cleanup (NULL_TREE, TREE_OPERAND (exp, 1));
  
  	  /* That's it for this cleanup.  */
  	  TREE_OPERAND (exp, 1) = 0;
--- 7209,7216 ----
  	{
  	  WITH_CLEANUP_EXPR_RTL (exp)
  	    = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
! 	  expand_decl_cleanup_eh (NULL_TREE, TREE_OPERAND (exp, 1),
! 				  CLEANUP_EH_ONLY (exp));
  
  	  /* That's it for this cleanup.  */
  	  TREE_OPERAND (exp, 1) = 0;
*************** expand_expr (exp, target, tmode, modifie
*** 8422,8428 ****
  
  	store_expr (exp1, target, 0);
  
! 	expand_decl_cleanup (NULL_TREE, cleanups);
  
  	return target;
        }
--- 8423,8429 ----
  
  	store_expr (exp1, target, 0);
  
! 	expand_decl_cleanup_eh (NULL_TREE, cleanups, CLEANUP_EH_ONLY (exp));
  
  	return target;
        }

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