This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

(take 3) [RFA:] Fix g77.f-torture/compile/970915-0.f, -Os verify_local_live_at_start, MMIX


On Wed, 17 Apr 2002, Hans-Peter Nilsson wrote:
> On Tue, 16 Apr 2002, Richard Henderson wrote:
> > On Tue, Apr 16, 2002 at 09:52:07PM -0400, Hans-Peter Nilsson wrote:
> > > 	* flow.c (update_life_info): Ignore return value of cleanup_cfg.
> > > 	Mask out PROP_SCAN_DEAD_CODE | PROP_KILL_DEAD_CODE in
> > > 	propagate_block calls after relaxation loop.
> >
> > Ok.
>
> Thanks, but don't apply this patch.  It doesn't even survive
> bootstrap.  I'll get back with an analysis and a tested patch.
> *sigh*.

Blindly masking off PROP_SCAN_DEAD_CODE | PROP_KILL_DEAD_CODE as
in my previous patch is of course wrong; only those bits that
would make global register liveness inconsistent must be masked
off.

The problem with that patch is first seen (for most simulator
targets, not for bootstrap) in the guess-the-EH-model-code with
no optimization:

struct S { ~S(); };
void bar();
void foo()
{
  S s;
  bar();
}

In this case, for mmix-knuth-mmixware we have the usual call to
life_analysis with PROP_FINAL (0x7f, everything), but since
we're not optimizing, some of the flags are masked off in that
function, so update_life_info is called with PROP_SCAN_DEAD_CODE
|PROP_KILL_DEAD_CODE|PROP_REG_INFO|PROP_DEATH_NOTES.  This means
that the code:

          if ((prop_flags & (PROP_KILL_DEAD_CODE | PROP_ALLOW_CFG_CHANGES))
              != (PROP_KILL_DEAD_CODE | PROP_ALLOW_CFG_CHANGES))
            break;

in the relaxation loop in update_life_info breaks out of the
relaxation loop before any changes.  In the
calculate_global_regs_live call above it, PROP_SCAN_DEAD_CODE
was used to calculate global liveness info.  Masking it off in
subsequent propagate_block calls will of course cause liveness
info inconsistency.  Only when code is modified, are there
flags to mask off.

This patch is a proper implementation of the intention of the
patch previously ok:ed for trunk and 3.1.  It was bootstrapped
and checked on i686-pc-linux-gnu and cross-tested on
mmix-knuth-mmixware, cris-axis-elf, v850-unknown-elf,
i960-unknown-coff, m32r-unknown-elf, mn10300-unknown-elf and
arm-unknown-elf.

Ok (still?) for trunk and 3.1 branch?

	* flow.c (update_life_info): Ignore return value of cleanup_cfg.
	Mask out PROP_SCAN_DEAD_CODE | PROP_KILL_DEAD_CODE in
	propagate_block calls after relaxation loop using new variable
	stabilized_prop_flags.

Index: flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.514
diff -p -c -r1.514 flow.c
*** flow.c	12 Apr 2002 07:52:02 -0000	1.514
--- flow.c	17 Apr 2002 12:25:08 -0000
*************** update_life_info (blocks, extent, prop_f
*** 637,642 ****
--- 637,643 ----
    regset tmp;
    regset_head tmp_head;
    int i;
+   int stabilized_prop_flags = prop_flags;

    tmp = INITIALIZE_REG_SET (tmp_head);
    ndead = 0;
*************** update_life_info (blocks, extent, prop_f
*** 677,684 ****
  					      | PROP_KILL_DEAD_CODE));
  	    }

! 	  if (! changed || ! cleanup_cfg (CLEANUP_EXPENSIVE))
  	    break;
  	}

        /* If asked, remove notes from the blocks we'll update.  */
--- 678,698 ----
  					      | PROP_KILL_DEAD_CODE));
  	    }

! 	  /* Don't pass PROP_SCAN_DEAD_CODE or PROP_KILL_DEAD_CODE to
! 	     subsequent propagate_block calls, since removing or acting as
! 	     removing dead code can affect global register liveness, which
! 	     is supposed to be finalized for this call after this loop.  */
! 	  stabilized_prop_flags
! 	    &= ~(PROP_SCAN_DEAD_CODE | PROP_KILL_DEAD_CODE);
!
! 	  if (! changed)
  	    break;
+
+ 	  /* We repeat regardless of what cleanup_cfg says.  If there were
+ 	     instructions deleted above, that might have been only a
+ 	     partial improvement (see MAX_MEM_SET_LIST_LEN usage).
+ 	     Further improvement may be possible.  */
+ 	  cleanup_cfg (CLEANUP_EXPENSIVE);
  	}

        /* If asked, remove notes from the blocks we'll update.  */
*************** update_life_info (blocks, extent, prop_f
*** 697,703 ****
  	  basic_block bb = BASIC_BLOCK (i);

  	  COPY_REG_SET (tmp, bb->global_live_at_end);
! 	  propagate_block (bb, tmp, NULL, NULL, prop_flags);

  	  if (extent == UPDATE_LIFE_LOCAL)
  	    verify_local_live_at_start (tmp, bb);
--- 711,717 ----
  	  basic_block bb = BASIC_BLOCK (i);

  	  COPY_REG_SET (tmp, bb->global_live_at_end);
! 	  propagate_block (bb, tmp, NULL, NULL, stabilized_prop_flags);

  	  if (extent == UPDATE_LIFE_LOCAL)
  	    verify_local_live_at_start (tmp, bb);
*************** update_life_info (blocks, extent, prop_f
*** 710,716 ****
  	  basic_block bb = BASIC_BLOCK (i);

  	  COPY_REG_SET (tmp, bb->global_live_at_end);
! 	  propagate_block (bb, tmp, NULL, NULL, prop_flags);

  	  if (extent == UPDATE_LIFE_LOCAL)
  	    verify_local_live_at_start (tmp, bb);
--- 724,731 ----
  	  basic_block bb = BASIC_BLOCK (i);

  	  COPY_REG_SET (tmp, bb->global_live_at_end);
!
! 	  propagate_block (bb, tmp, NULL, NULL, stabilized_prop_flags);

  	  if (extent == UPDATE_LIFE_LOCAL)
  	    verify_local_live_at_start (tmp, bb);

brgds, H-P


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]