This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix selective scheduling failures on power6 [1/3]
- From: Andrey Belevantsev <abel at ispras dot ru>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: "Vladimir N. Makarov" <vmakarov at redhat dot com>
- Date: Mon, 29 Sep 2008 19:37:19 +0400
- Subject: Fix selective scheduling failures on power6 [1/3]
- References: <48E0F439.2080500@ispras.ru>
Hello,
This patch fixes a failure when compiling perl from SPEC CPU2k. The
problem was that when the chosen destination register for an expression
is the same as the existing register, we short-circuited the checks for
validity of all insns that originated this expression with the chosen
register. Obviously not all of the original insns will have the same
register as the expression -- some of them can have different registers,
and the check should still be made.
The fix is actually shorter than the explanation. There is a test
reduced from SPEC code, I will include it in the commit if this is
acceptable.
OK for trunk?
Andrey
2008-09-29 Andrey Belevantsev <abel@ispras.ru>
* sel-sched.c (try_replace_dest_reg): When chosen register
and original register is the same, do not bail out early, but
still check all original insns for validity of replacing destination
register. Set EXPR_TARGET_AVAILABLE to 1 before leaving function
in this case.
Index: gcc/sel-sched.c
===================================================================
*** gcc/sel-sched.c (revision 140752)
--- gcc/sel-sched.c (working copy)
*************** collect_unavailable_regs_from_bnds (expr
*** 1640,1653 ****
static bool
try_replace_dest_reg (ilist_t orig_insns, rtx best_reg, expr_t expr)
{
- if (expr_dest_regno (expr) == REGNO (best_reg))
- {
- EXPR_TARGET_AVAILABLE (expr) = 1;
- return true;
- }
-
- gcc_assert (orig_insns);
-
/* Try whether we'll be able to generate the insn
'dest := best_reg' at the place of the original operation. */
for (; orig_insns; orig_insns = ILIST_NEXT (orig_insns))
--- 1640,1645 ----
*************** try_replace_dest_reg (ilist_t orig_insns
*** 1655,1669 ****
insn_t orig_insn = DEF_LIST_DEF (orig_insns)->orig_insn;
gcc_assert (EXPR_SEPARABLE_P (INSN_EXPR (orig_insn)));
!
! if (!replace_src_with_reg_ok_p (orig_insn, best_reg)
! || !replace_dest_with_reg_ok_p (orig_insn, best_reg))
return false;
}
/* Make sure that EXPR has the right destination
register. */
! replace_dest_with_reg_in_expr (expr, best_reg);
return true;
}
--- 1647,1666 ----
insn_t orig_insn = DEF_LIST_DEF (orig_insns)->orig_insn;
gcc_assert (EXPR_SEPARABLE_P (INSN_EXPR (orig_insn)));
!
! if (REGNO (best_reg) != REGNO (INSN_LHS (orig_insn))
! && (! replace_src_with_reg_ok_p (orig_insn, best_reg)
! || ! replace_dest_with_reg_ok_p (orig_insn, best_reg)))
return false;
}
/* Make sure that EXPR has the right destination
register. */
! if (expr_dest_regno (expr) != REGNO (best_reg))
! replace_dest_with_reg_in_expr (expr, best_reg);
! else
! EXPR_TARGET_AVAILABLE (expr) = 1;
!
return true;
}