[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