This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for EH-only cleanups, part 2
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 04 Apr 2002 01:05:11 +0100
- Subject: 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;
}