From: Sergey Grechanik <mouseent...@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  <mouseent...@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.

diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c
index 8f5cd3f..f22e637 100644
--- a/gcc/sel-sched-ir.c
+++ b/gcc/sel-sched-ir.c
@@ -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.
diff --git a/gcc/sel-sched-ir.h b/gcc/sel-sched-ir.h
index 838c0d1..c8f8be6 100644
--- a/gcc/sel-sched-ir.h
+++ b/gcc/sel-sched-ir.h
@@ -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);
diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index e791e4c..f11faca 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -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;
     }
 

Reply via email to