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]

Fix selective scheduling failures on power6 [1/3]


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;
  }
  

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