/* 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.
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); )
{
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);
/* 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);
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])
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)));
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
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;
}
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
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);
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). */
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++)
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))
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. */
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)
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)
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;
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;
}
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. */
moveop_static_params_p params)
{
bool insn_emitted = false;
- rtx cur_reg = expr_dest_reg (params->c_expr);
+ rtx cur_reg;
+
+ /* Bail out early when expression can not be renamed at all. */
+ if (!EXPR_SEPARABLE_P (params->c_expr))
+ return false;
- gcc_assert (!cur_reg || (params->dest && REG_P (params->dest)));
+ 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;