diff mbox series

Fix PR rtl-optimization/91136

Message ID 1775704.MWxHBReFq7@polaris
State New
Headers show
Series Fix PR rtl-optimization/91136 | expand

Commit Message

Eric Botcazou July 12, 2019, 10:18 a.m. UTC
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  <ebotcazou@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.
diff mbox series

Patch

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.  */