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:
Eric Botcazou 2020-09-16 13:06:34 +02:00
parent 7d1be939e0
commit aab6194d08
2 changed files with 32 additions and 7 deletions

View 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" } }

View File

@ -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;
}