@@ -1883,7 +1883,7 @@ set_unavailable_target_for_expr (expr_t expr, regset lv_set)
if (EXPR_SEPARABLE_P (expr))
{
if (REG_P (EXPR_LHS (expr))
- && bitmap_bit_p (lv_set, REGNO (EXPR_LHS (expr))))
+ && register_unavailable_p (lv_set, EXPR_LHS (expr)))
{
/* If it's an insn like r1 = use (r1, ...), and it exists in
different forms in each of the av_sets being merged, we can't say
@@ -1904,8 +1904,8 @@ set_unavailable_target_for_expr (expr_t expr, regset lv_set)
miss a unifying code motion along both branches using a renamed
register, but it won't affect a code correctness since upon
an actual code motion a bookkeeping code would be generated. */
- if (bitmap_bit_p (VINSN_REG_USES (EXPR_VINSN (expr)),
- REGNO (EXPR_LHS (expr))))
+ if (register_unavailable_p (VINSN_REG_USES (EXPR_VINSN (expr)),
+ EXPR_LHS (expr)))
EXPR_TARGET_AVAILABLE (expr) = -1;
else
EXPR_TARGET_AVAILABLE (expr) = false;
@@ -1971,8 +1971,8 @@ speculate_expr (expr_t expr, ds_t ds)
/* Do not allow clobbering the address register of speculative
insns. */
- if (bitmap_bit_p (VINSN_REG_USES (EXPR_VINSN (expr)),
- expr_dest_regno (expr)))
+ if (register_unavailable_p (VINSN_REG_USES (EXPR_VINSN (expr)),
+ expr_dest_reg (expr)))
{
EXPR_TARGET_AVAILABLE (expr) = false;
return 2;
@@ -2026,6 +2026,25 @@ mark_unavailable_targets (av_set_t join_set, av_set_t av_set, regset lv_set)
}
+/* Returns true if REG (at least partially) is present in REGS. */
+bool
+register_unavailable_p (regset regs, rtx reg)
+{
+ unsigned regno, end_regno;
+
+ regno = REGNO (reg);
+ if (bitmap_bit_p (regs, regno))
+ return true;
+
+ end_regno = END_REGNO (reg);
+
+ while (++regno < end_regno)
+ if (bitmap_bit_p (regs, regno))
+ return true;
+
+ return false;
+}
+
/* Av set functions. */
/* Add a new element to av set SETP.
@@ -1573,6 +1573,7 @@ extern void sel_init_global_and_expr (bb_vec_t);
extern void sel_finish_global_and_expr (void);
extern regset compute_live (insn_t);
+extern bool register_unavailable_p (regset, rtx);
/* Dependence analysis functions. */
extern void sel_clear_has_dependence (void);
@@ -794,8 +794,8 @@ substitute_reg_in_expr (expr_t expr, insn_t insn, bool undo)
/* Do not allow clobbering the address register of speculative
insns. */
if ((EXPR_SPEC_DONE_DS (expr) & SPECULATIVE)
- && bitmap_bit_p (VINSN_REG_USES (EXPR_VINSN (expr)),
- expr_dest_regno (expr)))
+ && register_unavailable_p (VINSN_REG_USES (EXPR_VINSN (expr)),
+ expr_dest_reg (expr)))
EXPR_TARGET_AVAILABLE (expr) = false;
return true;
@@ -3631,12 +3631,12 @@ av_set_could_be_blocked_by_bookkeeping_p (av_set_t orig_ops, void *static_params
renaming. Check with the right register instead. */
if (sparams->dest && REG_P (sparams->dest))
{
- unsigned regno = REGNO (sparams->dest);
+ rtx reg = sparams->dest;
vinsn_t failed_vinsn = INSN_VINSN (sparams->failed_insn);
- if (bitmap_bit_p (VINSN_REG_SETS (failed_vinsn), regno)
- || bitmap_bit_p (VINSN_REG_USES (failed_vinsn), regno)
- || bitmap_bit_p (VINSN_REG_CLOBBERS (failed_vinsn), regno))
+ if (register_unavailable_p (VINSN_REG_SETS (failed_vinsn), reg)
+ || register_unavailable_p (VINSN_REG_USES (failed_vinsn), reg)
+ || register_unavailable_p (VINSN_REG_CLOBBERS (failed_vinsn), reg))
return true;
}
From: Sergey Grechanik <mouseentity@condor.intra.ispras.ru> There are several places where bitmap_bit_p function is used to test if some register is in the regset. We need to take into account the fact that depending on mode, we need to test multiple hard regs. 2011-08-04 Sergey Grechanik <mouseentity@ispras.ru> * sel-sched-ir.h (register_unavailable_p): Declare. * sel-sched-ir.c (register_unavailable_p): New. Use it... (set_unavailable_target_for_expr): ... here to properly test availability of a register. (speculate_expr): Ditto. * sel-sched.c (substitute_reg_in_expr): Ditto. (av_set_could_be_blocked_by_bookkeeping_p): Ditto.