This is another installment in the famous series "how can this have worked for
so long?". The delayed branches scheduling pass, aka dbr in reorg.c, uses its
own dataflow algorithm implemented in resource.c to do liveness analysis after
starting from seeds obtained from DF. It's a forward scan starting from the
DF_LR_IN set of a well-chosen basic block and then updating this set as the
instructions are being processed.
The problem is that, when this basic block has incoming EH edges, there are
implicitly live registers on entry by virtue of EH_RETURN_DATA_REGNO. Now DF
encodes them specially:
For blocks that are at the destination of eh edges, the
artificial uses and defs occur at the beginning. The defs relate
to the registers specified in EH_RETURN_DATA_REGNO and the uses
relate to the registers specified in EH_USES. Logically these
defs and uses should really occur along the eh edge, but there is
no convenient way to do this. Artificial defs that occur at the
beginning of the block have the DF_REF_AT_TOP flag set.
This means in particular that the artificial defs are not in the DF_LR_IN set,
which means that resource.c doesn't see them at all. Another pass has exactly
the same issue (register renaming) but has been adjusted, so the attached fix
just mimics what init_rename_info in regrename.c does.
Bootstrapped/regtested on SPARC/Solaris, applied on all active branches.
2019-07-12 Eric Botcazou <ebotca...@adacore.com>
PR rtl-optimization/91136
* df-core.c (ACCESSING REFS): Fix typos in comment.
* resource.c (mark_target_live_reg): Add artificial defs that occur at
the beginning of the block to the initial set of live registers.
--
Eric Botcazou
Index: df-core.c
===================================================================
--- df-core.c (revision 273294)
+++ df-core.c (working copy)
@@ -298,12 +298,12 @@ There are 4 ways to obtain access to ref
Artificial defs and uses occur both at the beginning and ends of blocks.
- For blocks that area at the destination of eh edges, the
+ For blocks that are at the destination of eh edges, the
artificial uses and defs occur at the beginning. The defs relate
to the registers specified in EH_RETURN_DATA_REGNO and the uses
- relate to the registers specified in ED_USES. Logically these
+ relate to the registers specified in EH_USES. Logically these
defs and uses should really occur along the eh edge, but there is
- no convenient way to do this. Artificial edges that occur at the
+ no convenient way to do this. Artificial defs that occur at the
beginning of the block have the DF_REF_AT_TOP flag set.
Artificial uses occur at the end of all blocks. These arise from
Index: resource.c
===================================================================
--- resource.c (revision 273294)
+++ resource.c (working copy)
@@ -987,9 +987,13 @@ mark_target_live_regs (rtx_insn *insns,
{
regset regs_live = DF_LR_IN (BASIC_BLOCK_FOR_FN (cfun, b));
rtx_insn *start_insn, *stop_insn;
+ df_ref def;
/* Compute hard regs live at start of block. */
REG_SET_TO_HARD_REG_SET (current_live_regs, regs_live);
+ FOR_EACH_ARTIFICIAL_DEF (def, b)
+ if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+ SET_HARD_REG_BIT (current_live_regs, DF_REF_REGNO (def));
/* Get starting and ending insn, handling the case where each might
be a SEQUENCE. */