Fix pessimization in EH cleanup pass
This restores the post-order traversal done by cleanup_all_empty_eh in order to eliminate empty landing pads and also contains a small tweak to the line debug info to avoid a problematic inheritance for coverage measurement. gcc/ChangeLog: * tree-eh.c (lower_try_finally_dup_block): Backward propagate slocs to stack restore builtin calls. (cleanup_all_empty_eh): Do again a post-order traversal of the EH region tree. gcc/testsuite/ChangeLog: * gnat.dg/concat4.adb: New test.
This commit is contained in:
parent
7d1be939e0
commit
aab6194d08
17
gcc/testsuite/gnat.dg/concat4.adb
Normal file
17
gcc/testsuite/gnat.dg/concat4.adb
Normal file
@ -0,0 +1,17 @@
|
||||
-- { dg-do compile }
|
||||
|
||||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
|
||||
procedure Concat4 (X : Integer) is
|
||||
Ximg : constant String := Integer'Image (X);
|
||||
begin
|
||||
if X > 0 then
|
||||
Put_Line (Ximg & " is Positive");
|
||||
elsif X < 0 then
|
||||
Put_Line (Ximg & " is Negative");
|
||||
else
|
||||
Put_Line (Ximg & " is Null");
|
||||
end if;
|
||||
end;
|
||||
|
||||
-- { dg-final { scan-assembler-not "_Unwind_Resume" } }
|
@ -899,23 +899,26 @@ lower_try_finally_dup_block (gimple_seq seq, struct leh_state *outer_state,
|
||||
gtry *region = NULL;
|
||||
gimple_seq new_seq;
|
||||
gimple_stmt_iterator gsi;
|
||||
location_t last_loc = UNKNOWN_LOCATION;
|
||||
|
||||
new_seq = copy_gimple_seq_and_replace_locals (seq);
|
||||
|
||||
for (gsi = gsi_start (new_seq); !gsi_end_p (gsi); gsi_next (&gsi))
|
||||
for (gsi = gsi_last (new_seq); !gsi_end_p (gsi); gsi_prev (&gsi))
|
||||
{
|
||||
gimple *stmt = gsi_stmt (gsi);
|
||||
/* We duplicate __builtin_stack_restore at -O0 in the hope of eliminating
|
||||
it on the EH paths. When it is not eliminated, make it transparent in
|
||||
the debug info. */
|
||||
it on the EH paths. When it is not eliminated, give it the next
|
||||
location in the sequence or make it transparent in the debug info. */
|
||||
if (gimple_call_builtin_p (stmt, BUILT_IN_STACK_RESTORE))
|
||||
gimple_set_location (stmt, UNKNOWN_LOCATION);
|
||||
gimple_set_location (stmt, last_loc);
|
||||
else if (LOCATION_LOCUS (gimple_location (stmt)) == UNKNOWN_LOCATION)
|
||||
{
|
||||
tree block = gimple_block (stmt);
|
||||
gimple_set_location (stmt, loc);
|
||||
gimple_set_block (stmt, block);
|
||||
}
|
||||
else
|
||||
last_loc = gimple_location (stmt);
|
||||
}
|
||||
|
||||
if (outer_state->tf)
|
||||
@ -4751,9 +4754,9 @@ cleanup_all_empty_eh (void)
|
||||
eh_landing_pad lp;
|
||||
int i;
|
||||
|
||||
/* Ideally we'd walk the region tree and process LPs inner to outer
|
||||
to avoid quadraticness in EH redirection. Walking the LP array
|
||||
in reverse seems to be an approximation of that. */
|
||||
/* The post-order traversal may lead to quadraticness in the redirection
|
||||
of incoming EH edges from inner LPs, so first try to walk the region
|
||||
tree from inner to outer LPs in order to eliminate these edges. */
|
||||
for (i = vec_safe_length (cfun->eh->lp_array) - 1; i >= 1; --i)
|
||||
{
|
||||
lp = (*cfun->eh->lp_array)[i];
|
||||
@ -4761,6 +4764,11 @@ cleanup_all_empty_eh (void)
|
||||
changed |= cleanup_empty_eh (lp);
|
||||
}
|
||||
|
||||
/* Now do the post-order traversal to eliminate outer empty LPs. */
|
||||
for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
|
||||
if (lp)
|
||||
changed |= cleanup_empty_eh (lp);
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user