As explained in the audit trail, the goal of the fix for PR debug/44205:
* tree-cfgcleanup.c (tree_forwarder_block_p): Return false if
at -O0 goto_locus of any of the incoming edges differs from
goto_locus of outgoing edge, or gimple_location of any of the
labels differs.
was to enable the bypassing of forwarder blocks at -O0 when the locus on the
edges to be threaded represent both either UNKNOWN_LOCATION or the same
location. It was made for GCC 4.6 and below when the locus value represented
only the location information so a simple locus comparison was used.
Since then the locus value was changed and represents now a combination of
location information and block information. This means that you can have 2
locus representing both UNKNOWN_LOCATION but with different values and the
change disabled the bypassing of forwarder blocks in this case.
The attached patch reenables it, i.e. when the locus on the edges represent
both UNKNOWN_LOCATION. The idiom is already used at the RTL level e.g. in
try_forward_edges. That's quite effective in Ada to remove dead branches
generated for size computations of variable-sized types at -O0.
Tested (GCC and GDB) on x86-64/Linux, applied on the mainline as obvious.
2018-06-19 Eric Botcazou <ebotca...@adacore.com>
* tree-cfgcleanup.c (tree_forwarder_block_p): Do not return false at
-O0 if the locus represent UNKNOWN_LOCATION but have different values.
--
Eric Botcazou
Index: tree-cfgcleanup.c
===================================================================
--- tree-cfgcleanup.c (revision 261687)
+++ tree-cfgcleanup.c (working copy)
@@ -346,8 +346,11 @@ tree_forwarder_block_p (basic_block bb,
if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun) || (e->flags & EDGE_EH))
return false;
/* If goto_locus of any of the edges differs, prevent removing
- the forwarder block for -O0. */
- else if (optimize == 0 && e->goto_locus != locus)
+ the forwarder block when not optimizing. */
+ else if (!optimize
+ && (LOCATION_LOCUS (e->goto_locus) != UNKNOWN_LOCATION
+ || LOCATION_LOCUS (locus) != UNKNOWN_LOCATION)
+ && e->goto_locus != locus)
return false;
}
@@ -362,7 +365,10 @@ tree_forwarder_block_p (basic_block bb,
case GIMPLE_LABEL:
if (DECL_NONLOCAL (gimple_label_label (as_a <glabel *> (stmt))))
return false;
- if (optimize == 0 && gimple_location (stmt) != locus)
+ if (!optimize
+ && (gimple_has_location (stmt)
+ || LOCATION_LOCUS (locus) != UNKNOWN_LOCATION)
+ && gimple_location (stmt) != locus)
return false;
break;