This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: gcse basic block analysis optimizes EH return stub away (was: Re: Testsuite Results for gcc-2.96 19990628)
- To: Mike Stump <mrs at wrs dot com>
- Subject: Re: gcse basic block analysis optimizes EH return stub away (was: Re: Testsuite Results for gcc-2.96 19990628)
- From: Richard Henderson <rth at cygnus dot com>
- Date: Thu, 1 Jul 1999 16:47:36 -0700
- Cc: law at cygnus dot com, oliva at dcc dot unicamp dot br, egcs at egcs dot cygnus dot com, kunert at physik dot tu-dresden dot de, ronis at onsager dot chem dot mcgill dot ca, egcs-patches at egcs dot cygnus dot com
- References: <199907012216.PAA23541@kankakee.wrs.com>
On Thu, Jul 01, 1999 at 03:16:02PM -0700, Mike Stump wrote:
> :-) Those instructions don't do what you think they do. :-) I wonder
> if we can add a volatile asm, a memory barrier, or something to keep
> the optimizer from looking at it.
Actually, that wouldn't have helped. The basic block was being
deleted because it was unreachable.
The expand_eh_return change below is the crucial one. If we allow
the function to be inlined, we'll collect rtl then finally call
output_inline_function. Which will call init_function_start, which
calls init_eh_for_function, which zeros eh_return_stub_label, which
disables all the magic in flow.
The other two changes are things I tried on the way to a correct
solution, but they seem like good ideas anyway. The flow change
to not merge across EH edges can't happen often, but I suspect the
wrong thing would happen if it did.
r~
* except.c (expand_eh_return): Set current_function_cannot_inline.
(save_eh_status, restore_eh_status): Twiddle eh_return_stub_label.
* function.h (struct function): Add eh_return_stub_label.
* flow.c (delete_unreachable_blocks): Don't merge across EH edges.
Index: except.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/except.c,v
retrieving revision 1.82
diff -c -p -d -r1.82 except.c
*** except.c 1999/04/15 19:54:09 1.82
--- except.c 1999/07/01 23:38:57
*************** save_eh_status (p)
*** 2446,2451 ****
--- 2446,2452 ----
p->caught_return_label_stack = caught_return_label_stack;
p->protect_list = protect_list;
p->ehc = current_function_ehc;
+ p->eh_return_stub_label = eh_return_stub_label;
init_eh_for_function ();
}
*************** restore_eh_status (p)
*** 2469,2474 ****
--- 2470,2476 ----
ehstack = p->ehstack;
catchstack = p->catchstack;
current_function_ehc = p->ehc;
+ eh_return_stub_label = p->eh_return_stub_label;
}
/* This section is for the exception handling specific optimization
*************** expand_eh_return ()
*** 2791,2796 ****
--- 2793,2800 ----
if (!eh_return_context)
return;
+
+ current_function_cannot_inline = 1;
eh_regs (®1, ®2, ®3, 1);
#ifdef POINTERS_EXTEND_UNSIGNED
Index: function.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/function.h,v
retrieving revision 1.18.4.1
diff -c -p -d -r1.18.4.1 function.h
*** function.h 1999/05/30 13:19:42 1.18.4.1
--- function.h 1999/07/01 23:38:57
*************** struct function
*** 146,151 ****
--- 146,152 ----
struct label_node *caught_return_label_stack;
tree protect_list;
rtx ehc;
+ rtx eh_return_stub_label;
/* For expr.c. */
rtx pending_chain;
Index: flow.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/flow.c,v
retrieving revision 1.120.4.2
diff -c -p -d -r1.120.4.2 flow.c
*** flow.c 1999/06/01 21:49:28 1.120.4.2
--- flow.c 1999/07/01 23:38:57
*************** delete_unreachable_blocks ()
*** 1578,1583 ****
--- 1578,1584 ----
/* A loop because chains of blocks might be combineable. */
while ((s = b->succ) != NULL
&& s->succ_next == NULL
+ && (s->flags & EDGE_EH) == 0
&& (c = s->dest) != EXIT_BLOCK_PTR
&& c->pred->pred_next == NULL
&& merge_blocks (s, b, c))