OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / sel-sched.c
index e5ebc57..0981440 100644 (file)
@@ -1,5 +1,5 @@
 /* Instruction scheduling pass.  Selective scheduler and pipeliner.
-   Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -588,6 +588,7 @@ advance_one_cycle (fence_t fence)
   FENCE_ISSUED_INSNS (fence) = 0;
   FENCE_STARTS_CYCLE_P (fence) = 1;
   can_issue_more = issue_rate;
+  FENCE_ISSUE_MORE (fence) = can_issue_more;
 
   for (i = 0; VEC_iterate (rtx, FENCE_EXECUTING_INSNS (fence), i, insn); )
     {
@@ -1228,19 +1229,19 @@ mark_unavailable_hard_regs (def_t def, struct reg_rename *reg_rename_p,
   if (!reload_completed && !HARD_REGISTER_NUM_P (regno))
     return;
 
-  mode = GET_MODE (orig_dest);
+  if (reload_completed)
+    cl = get_reg_class (def->orig_insn);
 
-  /* Stop when mode is not supported for renaming.  Also can't proceed
-     if the original register is one of the fixed_regs, global_regs or
-     frame pointer.  */
+  /* Stop if the original register is one of the fixed_regs, global_regs or
+     frame pointer, or we could not discover its class.  */
   if (fixed_regs[regno]
       || global_regs[regno]
 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
-       || (frame_pointer_needed && regno == HARD_FRAME_POINTER_REGNUM)
+      || (frame_pointer_needed && regno == HARD_FRAME_POINTER_REGNUM)
 #else
-       || (frame_pointer_needed && regno == FRAME_POINTER_REGNUM)
+      || (frame_pointer_needed && regno == FRAME_POINTER_REGNUM)
 #endif
-      )
+      || (reload_completed && cl == NO_REGS))
     {
       SET_HARD_REG_SET (reg_rename_p->unavailable_hard_regs);
 
@@ -1295,11 +1296,11 @@ mark_unavailable_hard_regs (def_t def, struct reg_rename *reg_rename_p,
 
   /* Leave regs as 'available' only from the current
      register class.  */
-  cl = get_reg_class (def->orig_insn);
-  gcc_assert (cl != NO_REGS);
   COPY_HARD_REG_SET (reg_rename_p->available_for_renaming,
                      reg_class_contents[cl]);
 
+  mode = GET_MODE (orig_dest);
+
   /* Leave only registers available for this mode.  */
   if (!sel_hrd.regs_for_mode_ok[mode])
     init_regs_for_mode (mode);
@@ -1428,6 +1429,16 @@ choose_best_reg_1 (HARD_REG_SET hard_regs_used,
                                   0, cur_reg, hrsi)
     if (! TEST_HARD_REG_BIT (hard_regs_used, cur_reg))
       {
+       /* Check that all hard regs for mode are available.  */
+       for (i = 1, n = hard_regno_nregs[cur_reg][mode]; i < n; i++)
+         if (TEST_HARD_REG_BIT (hard_regs_used, cur_reg + i)
+             || !TEST_HARD_REG_BIT (reg_rename_p->available_for_renaming,
+                                    cur_reg + i))
+           break;
+
+       if (i < n)
+         continue;
+
         /* All hard registers are available.  */
         if (best_new_reg < 0
             || reg_rename_tick[cur_reg] < reg_rename_tick[best_new_reg])
@@ -1459,6 +1470,7 @@ choose_best_reg (HARD_REG_SET hard_regs_used, struct reg_rename *reg_rename_p,
   rtx best_reg = choose_best_reg_1 (hard_regs_used, reg_rename_p,
                                     original_insns, is_orig_reg_p_ptr);
 
+  /* FIXME loop over hard_regno_nregs here.  */
   gcc_assert (best_reg == NULL_RTX
              || TEST_HARD_REG_BIT (sel_hrd.regs_ever_used, REGNO (best_reg)));
 
@@ -1642,14 +1654,6 @@ collect_unavailable_regs_from_bnds (expr_t expr, blist_t bnds, regset used_regs,
 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))
@@ -1658,14 +1662,19 @@ try_replace_dest_reg (ilist_t orig_insns, rtx best_reg, expr_t expr)
 
       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))
+      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.  */
-  replace_dest_with_reg_in_expr (expr, best_reg);
+  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;
 }
 
@@ -1857,14 +1866,13 @@ create_speculation_check (expr_t c_expr, ds_t check_ds, insn_t orig_insn)
   if (recovery_block != NULL)
     {
       rtx twin_rtx;
-      insn_t twin;
 
       twin_rtx = copy_rtx (PATTERN (EXPR_INSN_RTX (c_expr)));
       twin_rtx = create_insn_rtx_from_pattern (twin_rtx, NULL_RTX);
-      twin = sel_gen_recovery_insn_from_rtx_after (twin_rtx,
-                                                  INSN_EXPR (orig_insn),
-                                                  INSN_SEQNO (insn),
-                                                  bb_note (recovery_block));
+      sel_gen_recovery_insn_from_rtx_after (twin_rtx,
+                                           INSN_EXPR (orig_insn),
+                                           INSN_SEQNO (insn),
+                                           bb_note (recovery_block));
     }
 
   /* If we've generated a data speculation check, make sure
@@ -2402,10 +2410,6 @@ try_transformation_cache (expr_t expr, insn_t insn,
         EXPR_TARGET_AVAILABLE (expr) = false;
       if (pti->type == TRANS_SPECULATION)
         {
-          ds_t ds;
-
-          ds = EXPR_SPEC_DONE_DS (expr);
-
           EXPR_SPEC_DONE_DS (expr) = pti->ds;
           EXPR_NEEDS_SPEC_CHECK_P (expr) |= pti->needs_check;
         }
@@ -2743,8 +2747,7 @@ compute_av_set_at_bb_end (insn_t insn, ilist_t p, int ws)
                                VEC_index (int, sinfo->probs_ok, is),
                                sinfo->all_prob);
 
-      if (sinfo->all_succs_n > 1
-          && sinfo->all_succs_n == sinfo->succs_ok_n)
+      if (sinfo->all_succs_n > 1)
        {
           /* Find EXPR'es that came from *all* successors and save them
              into expr_in_all_succ_branches.  This set will be used later
@@ -3304,8 +3307,8 @@ sel_target_adjust_priority (expr_t expr)
 
   gcc_assert (EXPR_PRIORITY_ADJ (expr) >= 0);
 
-  if (sched_verbose >= 2)
-    sel_print ("sel_target_adjust_priority: insn %d,  %d +%d = %d.\n",
+  if (sched_verbose >= 4)
+    sel_print ("sel_target_adjust_priority: insn %d,  %d+%d = %d.\n",
               INSN_UID (EXPR_INSN_RTX (expr)), EXPR_PRIORITY (expr),
               EXPR_PRIORITY_ADJ (expr), new_priority);
 
@@ -4106,7 +4109,7 @@ invoke_reorder_hooks (fence_t fence)
       ran_hook = true;
     }
   else
-    issue_more = issue_rate;
+    issue_more = FENCE_ISSUE_MORE (fence);
 
   /* Ensure that ready list and vec_av_set are in line with each other,
      i.e. vec_av_set[i] == ready_element (&ready, i).  */
@@ -4208,7 +4211,6 @@ static int
 calculate_privileged_insns (void)
 {
   expr_t cur_expr, min_spec_expr = NULL;
-  insn_t cur_insn, min_spec_insn;
   int privileged_n = 0, i;
 
   for (i = 0; i < ready.n_ready; i++)
@@ -4217,12 +4219,8 @@ calculate_privileged_insns (void)
         continue;
 
       if (! min_spec_expr)
-        {
-          min_spec_insn = ready_element (&ready, i);
-          min_spec_expr = find_expr_for_ready (i, true);
-        }
+       min_spec_expr = find_expr_for_ready (i, true);
 
-      cur_insn = ready_element (&ready, i);
       cur_expr = find_expr_for_ready (i, true);
 
       if (EXPR_SPEC (cur_expr) > EXPR_SPEC (min_spec_expr))
@@ -4297,8 +4295,6 @@ get_expr_cost (expr_t expr, fence_t fence)
   if (recog_memoized (insn) < 0)
     {
       if (!FENCE_STARTS_CYCLE_P (fence)
-          /* FIXME: Is this condition necessary?  */
-          && VINSN_UNIQUE_P (EXPR_VINSN (expr))
          && INSN_ASM_P (insn))
        /* This is asm insn which is tryed to be issued on the
           cycle not first.  Issue it on the next cycle.  */
@@ -4378,7 +4374,7 @@ find_best_expr (av_set_t *av_vliw_ptr, blist_t bnds, fence_t fence,
   best = fill_ready_list (av_vliw_ptr, bnds, fence, pneed_stall);
   if (best == NULL && ready.n_ready > 0)
     {
-      int privileged_n, index, avail_n;
+      int privileged_n, index;
 
       can_issue_more = invoke_reorder_hooks (fence);
       if (can_issue_more > 0)
@@ -4387,7 +4383,7 @@ find_best_expr (av_set_t *av_vliw_ptr, blist_t bnds, fence_t fence,
              scheduled due to liveness restrictions on its destination register.
              In the future, we'd like to choose once and then just probe insns
              in the order of their priority.  */
-          avail_n = invoke_dfa_lookahead_guard ();
+          invoke_dfa_lookahead_guard ();
           privileged_n = calculate_privileged_insns ();
           can_issue_more = choose_best_insn (fence, privileged_n, &index);
           if (can_issue_more)
@@ -5211,12 +5207,21 @@ move_exprs_to_boundary (bnd_t bnd, expr_t expr_vliw,
 
   EXECUTE_IF_SET_IN_BITMAP (current_copies, 0, book_uid, bi)
     {
+      unsigned uid;
+      bitmap_iterator bi;
+
       /* We allocate these bitmaps lazily.  */
       if (! INSN_ORIGINATORS_BY_UID (book_uid))
         INSN_ORIGINATORS_BY_UID (book_uid) = BITMAP_ALLOC (NULL);
 
       bitmap_copy (INSN_ORIGINATORS_BY_UID (book_uid),
                    current_originators);
+
+      /* Transitively add all originators' originators.  */
+      EXECUTE_IF_SET_IN_BITMAP (current_originators, 0, uid, bi)
+       if (INSN_ORIGINATORS_BY_UID (uid))
+        bitmap_ior_into (INSN_ORIGINATORS_BY_UID (book_uid),
+                         INSN_ORIGINATORS_BY_UID (uid));
     }
 
   return should_move;
@@ -5277,6 +5282,7 @@ advance_state_on_fence (fence_t fence, insn_t insn)
     debug_state (FENCE_STATE (fence));
   if (!DEBUG_INSN_P (insn))
     FENCE_STARTS_CYCLE_P (fence) = 0;
+  FENCE_ISSUE_MORE (fence) = can_issue_more;
   return asm_p;
 }
 
@@ -5474,6 +5480,7 @@ fill_insns (fence_t fence, int seqno, ilist_t **scheduled_insns_tailpp)
   blist_add (&bnds, insn, NULL, FENCE_DC (fence));
   bnds_tailp = &BLIST_NEXT (bnds);
   set_target_context (FENCE_TC (fence));
+  can_issue_more = FENCE_ISSUE_MORE (fence);
   target_bb = INSN_BB (insn);
 
   /* Do while we can add any operation to the current group.  */
@@ -5805,14 +5812,19 @@ maybe_emit_renaming_copy (rtx insn,
                           moveop_static_params_p params)
 {
   bool insn_emitted  = false;
-  rtx cur_reg = expr_dest_reg (params->c_expr);
+  rtx cur_reg;
 
-  gcc_assert (!cur_reg || (params->dest && REG_P (params->dest)));
+  /* Bail out early when expression can not be renamed at all.  */
+  if (!EXPR_SEPARABLE_P (params->c_expr))
+    return false;
+
+  cur_reg = expr_dest_reg (params->c_expr);
+  gcc_assert (cur_reg && params->dest && REG_P (params->dest));
 
   /* If original operation has expr and the register chosen for
      that expr is not original operation's dest reg, substitute
      operation's right hand side with the register chosen.  */
-  if (cur_reg != NULL_RTX && REGNO (params->dest) != REGNO (cur_reg))
+  if (REGNO (params->dest) != REGNO (cur_reg))
     {
       insn_t reg_move_insn, reg_move_insn_rtx;
 
@@ -6768,24 +6780,6 @@ setup_current_loop_nest (int rgn)
   gcc_assert (LOOP_MARKED_FOR_PIPELINING_P (current_loop_nest));
 }
 
-/* Purge meaningless empty blocks in the middle of a region.  */
-static void
-purge_empty_blocks (void)
-{
-  /* Do not attempt to delete preheader.  */
-  int i = sel_is_loop_preheader_p (BASIC_BLOCK (BB_TO_BLOCK (0))) ? 1 : 0;
-
-  while (i < current_nr_blocks)
-    {
-      basic_block b = BASIC_BLOCK (BB_TO_BLOCK (i));
-
-      if (maybe_tidy_empty_bb (b))
-       continue;
-
-      i++;
-    }
-}
-
 /* Compute instruction priorities for current region.  */
 static void
 sel_compute_priorities (int rgn)