aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2020-09-16 13:06:34 +0200
committerEric Botcazou <ebotcazou@adacore.com>2020-09-16 17:42:51 +0200
commitaab6194d0898f5c592708fe2d44a14046b4d9097 (patch)
treee8cbe88c94b858475d9c3d28b8062b08fdf68afd
parent7d1be939e0fbc5ce63ba17db3d20ccc39ac17527 (diff)
downloadgcc-aab6194d0898f5c592708fe2d44a14046b4d9097.zip
gcc-aab6194d0898f5c592708fe2d44a14046b4d9097.tar.gz
gcc-aab6194d0898f5c592708fe2d44a14046b4d9097.tar.bz2
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.
-rw-r--r--gcc/testsuite/gnat.dg/concat4.adb17
-rw-r--r--gcc/tree-eh.c22
2 files changed, 32 insertions, 7 deletions
diff --git a/gcc/testsuite/gnat.dg/concat4.adb b/gcc/testsuite/gnat.dg/concat4.adb
new file mode 100644
index 0000000..fe3f4ed
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/concat4.adb
@@ -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" } }
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 4246dca..1376b82 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -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;
}