X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fsel-sched.c;h=0981440fde77da4b9a024e871859c8f0b16c1c4c;hb=40e175e78b8bfcaf6afa0f75e705d62f752cc3e9;hp=1b8f47187a92ede2d9efbbe930a033518708fbb3;hpb=abb9c563a3f38041f2907a9c8c0ec14e71a34039;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index 1b8f47187a9..0981440fde7 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -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. @@ -1229,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); @@ -1296,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); @@ -1429,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]) @@ -1460,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))); @@ -1855,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 @@ -2400,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; } @@ -2741,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 @@ -4206,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++) @@ -4215,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)) @@ -4374,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) @@ -4383,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) @@ -5812,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; + + /* 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;