[committed] fix another scheduler dependency issue

James E Wilson wilson@specifix.com
Tue Oct 25 01:18:00 GMT 2005


This is a continuation of my work for PR 24232.  I pointed out in the pr
that there was another potential regression my patch did not fix, and I
hypothesized that I could reproduce it if I tried a bootstrap with
--param max-pending-list-length=X for various X.  I did find a bug, but
not the one I was looking for.

I tried an IA-64 bootstrap with X set to 2, and got about 22 object file
comparison errors.  I tracked this down to a problem with
simplify_using_assignment in loop-iv.c being miscompiled, between the
find_reg_equal_equiv_note call and the simple_rhs_p call.  We had RTL
like this
  (cond_exec (eq p6 0) (set rhs ...))
  (cond_exec (ne p6 0) (set rhs ...))  -> calls flush_pending_list
  (... read rhs)
There was no dependency between the two cond_exec insns, because they
are mutex.  There was a dependency between the read and the second
cond_exec.  There was no dependency between the read and the first
cond_exec, because it had already been flushed from the pending lists. 
The end result is that the first cond_exec insn got moved by the
scheduler after the read, and the code failed to work properly.

This is actually a flaw in my previous patch.  I had meant to make all
dependencies on last_pending_memory_flush unconditional, but I missed
two places.  The first two add_dependence_list_and_free calls in
flush_pending_memory need to be unconditional dependencies, because insn
ends being stores into last_pending_memory_flush at the end of the
function.

With this patch, a --param max-pending-list-length=2 bootstrap succeeds
on an ia64-linux machine.  I ran the testsuite and got only a couple of
differences for pthread related tests.  That happens occasionally on my
ia64 machine.  I don't believe these differences are significant.

I have checked in the patch.
-- 
Jim Wilson, GNU Tools Support, http://www.specifix.com
-------------- next part --------------
2005-10-24  James E. Wilson  <wilson@specifix.com>

	* sched-deps.c (flush_pending_lists): Pass 1 not 0 in first two
	add_dependence_list_and_free calls.

Index: sched-deps.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sched-deps.c,v
retrieving revision 1.95
diff -p -p -r1.95 sched-deps.c
*** sched-deps.c	15 Oct 2005 16:34:13 -0000	1.95
--- sched-deps.c	25 Oct 2005 00:51:16 -0000
*************** flush_pending_lists (struct deps *deps, 
*** 469,480 ****
  {
    if (for_write)
      {
!       add_dependence_list_and_free (insn, &deps->pending_read_insns, 0,
  				    REG_DEP_ANTI);
        free_EXPR_LIST_list (&deps->pending_read_mems);
      }
  
!   add_dependence_list_and_free (insn, &deps->pending_write_insns, 0,
  				for_read ? REG_DEP_ANTI : REG_DEP_OUTPUT);
    free_EXPR_LIST_list (&deps->pending_write_mems);
    deps->pending_lists_length = 0;
--- 469,480 ----
  {
    if (for_write)
      {
!       add_dependence_list_and_free (insn, &deps->pending_read_insns, 1,
  				    REG_DEP_ANTI);
        free_EXPR_LIST_list (&deps->pending_read_mems);
      }
  
!   add_dependence_list_and_free (insn, &deps->pending_write_insns, 1,
  				for_read ? REG_DEP_ANTI : REG_DEP_OUTPUT);
    free_EXPR_LIST_list (&deps->pending_write_mems);
    deps->pending_lists_length = 0;


More information about the Gcc-patches mailing list