X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Flower-subreg.c;h=3301a9db18c8bc22d7bc77974b6717ea7283874a;hb=f177c9a82242d10edc08df30d2d24814ae5c0317;hp=c61a8b7759e9dd9b0c4675a443ecea90f916db28;hpb=db2200eb29d404298af201d053500c7ca2c6896a;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c index c61a8b7759e..3301a9db18c 100644 --- a/gcc/lower-subreg.c +++ b/gcc/lower-subreg.c @@ -1,5 +1,5 @@ /* Decompose multiword subregs. - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Richard Henderson Ian Lance Taylor @@ -225,11 +225,9 @@ enum classify_move_insn { /* Not a simple move from one location to another. */ NOT_SIMPLE_MOVE, - /* A simple move from one pseudo-register to another with no - REG_RETVAL note. */ + /* A simple move from one pseudo-register to another. */ SIMPLE_PSEUDO_REG_MOVE, - /* A simple move involving a non-pseudo-register, or from one - pseudo-register to another with a REG_RETVAL note. */ + /* A simple move involving a non-pseudo-register. */ SIMPLE_MOVE }; @@ -304,10 +302,10 @@ find_decomposable_subregs (rtx *px, void *data) If this is not a simple copy from one location to another, then we can not decompose this register. If this is a simple - copy from one pseudo-register to another, with no REG_RETVAL - note, and the mode is right, then we mark the register as - decomposable. Otherwise we don't say anything about this - register--it could be decomposed, but whether that would be + copy from one pseudo-register to another, and the mode is right + then we mark the register as decomposable. + Otherwise we don't say anything about this register -- + it could be decomposed, but whether that would be profitable depends upon how it is used elsewhere. We only set bits in the bitmap for multi-word @@ -533,83 +531,32 @@ resolve_subreg_use (rtx *px, void *data) return 0; } -/* We are deleting INSN. Move any EH_REGION notes to INSNS. */ +/* This is called via for_each_rtx. Look for SUBREGs which can be + decomposed and decomposed REGs that need copying. */ -static void -move_eh_region_note (rtx insn, rtx insns) +static int +adjust_decomposed_uses (rtx *px, void *data ATTRIBUTE_UNUSED) { - rtx note, p; - - note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); - if (note == NULL_RTX) - return; + rtx x = *px; - gcc_assert (CALL_P (insn) - || (flag_non_call_exceptions && may_trap_p (PATTERN (insn)))); + if (x == NULL_RTX) + return 0; - for (p = insns; p != NULL_RTX; p = NEXT_INSN (p)) + if (resolve_subreg_p (x)) { - if (CALL_P (p) - || (flag_non_call_exceptions - && INSN_P (p) - && may_trap_p (PATTERN (p)))) - REG_NOTES (p) = gen_rtx_EXPR_LIST (REG_EH_REGION, XEXP (note, 0), - REG_NOTES (p)); - } -} - -/* If there is a REG_LIBCALL note on OLD_START, move it to NEW_START, - and link the corresponding REG_RETVAL note to NEW_START. */ - -static void -move_libcall_note (rtx old_start, rtx new_start) -{ - rtx note0, note1, end; - - note0 = find_reg_note (old_start, REG_LIBCALL, NULL); - if (note0 == NULL_RTX) - return; - - remove_note (old_start, note0); - end = XEXP (note0, 0); - note1 = find_reg_note (end, REG_RETVAL, NULL); - - XEXP (note0, 1) = REG_NOTES (new_start); - REG_NOTES (new_start) = note0; - XEXP (note1, 0) = new_start; -} - -/* Remove any REG_RETVAL note, the corresponding REG_LIBCALL note, and - any markers for a no-conflict block. We have decomposed the - registers so the non-conflict is now obvious. */ - -static void -remove_retval_note (rtx insn1) -{ - rtx note0, insn0, note1, insn; - - note1 = find_reg_note (insn1, REG_RETVAL, NULL); - if (note1 == NULL_RTX) - return; - - insn0 = XEXP (note1, 0); - note0 = find_reg_note (insn0, REG_LIBCALL, NULL); + x = simplify_subreg_concatn (GET_MODE (x), SUBREG_REG (x), + SUBREG_BYTE (x)); - remove_note (insn0, note0); - remove_note (insn1, note1); + if (x) + *px = x; + else + x = copy_rtx (*px); + } - for (insn = insn0; insn != insn1; insn = NEXT_INSN (insn)) - { - while (1) - { - rtx note; + if (resolve_reg_p (x)) + *px = copy_rtx (x); - note = find_reg_note (insn, REG_NO_CONFLICT, NULL); - if (note == NULL_RTX) - break; - remove_note (insn, note); - } - } + return 0; } /* Resolve any decomposed registers which appear in register notes on @@ -625,10 +572,7 @@ resolve_reg_notes (rtx insn) { int old_count = num_validated_changes (); if (for_each_rtx (&XEXP (note, 0), resolve_subreg_use, NULL)) - { - remove_note (insn, note); - remove_retval_note (insn); - } + remove_note (insn, note); else if (old_count != num_validated_changes ()) df_notes_rescan (insn); @@ -637,23 +581,22 @@ resolve_reg_notes (rtx insn) pnote = ®_NOTES (insn); while (*pnote != NULL_RTX) { - bool delete = false; + bool del = false; note = *pnote; switch (REG_NOTE_KIND (note)) { - case REG_NO_CONFLICT: case REG_DEAD: case REG_UNUSED: if (resolve_reg_p (XEXP (note, 0))) - delete = true; + del = true; break; default: break; } - if (delete) + if (del) *pnote = XEXP (note, 1); else pnote = &XEXP (note, 1); @@ -850,7 +793,7 @@ resolve_simple_move (rtx set, rtx insn) unsigned int i; if (REG_P (dest) && !HARD_REGISTER_NUM_P (REGNO (dest))) - emit_insn (gen_rtx_CLOBBER (VOIDmode, dest)); + emit_clobber (dest); for (i = 0; i < words; ++i) emit_move_insn (simplify_gen_subreg_concatn (word_mode, dest, @@ -880,12 +823,10 @@ resolve_simple_move (rtx set, rtx insn) insns = get_insns (); end_sequence (); - move_eh_region_note (insn, insns); + copy_reg_eh_region_note_forward (insn, insns, NULL_RTX); emit_insn_before (insns, insn); - move_libcall_note (insn, insns); - remove_retval_note (insn); delete_insn (insn); return insns; @@ -906,15 +847,6 @@ resolve_clobber (rtx pat, rtx insn) if (!resolve_reg_p (reg) && !resolve_subreg_p (reg)) return false; - /* If this clobber has a REG_LIBCALL note, then it is the initial - clobber added by emit_no_conflict_block. We were able to - decompose the register, so we no longer need the clobber. */ - if (find_reg_note (insn, REG_LIBCALL, NULL_RTX) != NULL_RTX) - { - delete_insn (insn); - return true; - } - orig_mode = GET_MODE (reg); words = GET_MODE_SIZE (orig_mode); words = (words + UNITS_PER_WORD - 1) / UNITS_PER_WORD; @@ -958,6 +890,18 @@ resolve_use (rtx pat, rtx insn) return false; } +/* A VAR_LOCATION can be simplified. */ + +static void +resolve_debug (rtx insn) +{ + for_each_rtx (&PATTERN (insn), adjust_decomposed_uses, NULL_RTX); + + df_insn_rescan (insn); + + resolve_reg_notes (insn); +} + /* Checks if INSN is a decomposable multiword-shift or zero-extend and sets the decomposable_context bitmap accordingly. A non-zero value is returned if a decomposable insn has been found. */ @@ -994,7 +938,7 @@ find_decomposable_shift_zext (rtx insn) } else /* left or right shift */ { - if (GET_CODE (XEXP (op, 1)) != CONST_INT + if (!CONST_INT_P (XEXP (op, 1)) || INTVAL (XEXP (op, 1)) < BITS_PER_WORD || GET_MODE_BITSIZE (GET_MODE (op_operand)) != 2 * BITS_PER_WORD) return 0; @@ -1043,11 +987,12 @@ resolve_shift_zext (rtx insn) endian machines this is register 0. */ src_reg_num = GET_CODE (op) == LSHIFTRT ? 1 : 0; - if (WORDS_BIG_ENDIAN) + if (WORDS_BIG_ENDIAN + && GET_MODE_SIZE (GET_MODE (op_operand)) > UNITS_PER_WORD) src_reg_num = 1 - src_reg_num; if (GET_CODE (op) == ZERO_EXTEND) - dest_reg_num = src_reg_num; + dest_reg_num = WORDS_BIG_ENDIAN ? 1 : 0; else dest_reg_num = 1 - src_reg_num; @@ -1178,34 +1123,8 @@ decompose_multiword_subregs (void) cmi = NOT_SIMPLE_MOVE; else { - bool retval; - - retval = find_reg_note (insn, REG_RETVAL, NULL_RTX) != NULL_RTX; - - if (find_pseudo_copy (set) && !retval) + if (find_pseudo_copy (set)) cmi = SIMPLE_PSEUDO_REG_MOVE; - else if (retval - && REG_P (SET_SRC (set)) - && HARD_REGISTER_P (SET_SRC (set))) - { - rtx note; - - /* We don't want to decompose an assignment which - copies the value returned by a libcall to a - pseudo-register. Doing that will lose the RETVAL - note with no real gain. */ - cmi = NOT_SIMPLE_MOVE; - - /* If we have a RETVAL note, there should be an - EQUAL note. We don't want to decompose any - registers which that EQUAL note refers to - directly. If we do, we will no longer know the - value of the libcall. */ - note = find_reg_equal_equiv_note (insn); - if (note != NULL_RTX) - for_each_rtx (&XEXP (note, 0), find_decomposable_subregs, - &cmi); - } else cmi = SIMPLE_MOVE; } @@ -1255,18 +1174,18 @@ decompose_multiword_subregs (void) FOR_BB_INSNS (bb, insn) { - rtx next, pat; + rtx pat; if (!INSN_P (insn)) continue; - next = NEXT_INSN (insn); - pat = PATTERN (insn); if (GET_CODE (pat) == CLOBBER) resolve_clobber (pat, insn); else if (GET_CODE (pat) == USE) resolve_use (pat, insn); + else if (DEBUG_INSN_P (insn)) + resolve_debug (insn); else { rtx set; @@ -1299,8 +1218,6 @@ decompose_multiword_subregs (void) insn = resolve_simple_move (set, insn); if (insn != orig_insn) { - remove_retval_note (insn); - recog_memoized (insn); extract_insn (insn); @@ -1336,13 +1253,11 @@ decompose_multiword_subregs (void) int dup_num = recog_data.dup_num[i]; rtx *px = recog_data.operand_loc[dup_num]; - validate_change (insn, pl, *px, 1); + validate_unshare_change (insn, pl, *px, 1); } i = apply_change_group (); gcc_assert (i); - - remove_retval_note (insn); } } } @@ -1390,7 +1305,7 @@ decompose_multiword_subregs (void) BITMAP_FREE (b); } - VEC_free (bitmap, heap, reg_copy_graph); + VEC_free (bitmap, heap, reg_copy_graph); BITMAP_FREE (decomposable_context); BITMAP_FREE (non_decomposable_context); @@ -1422,9 +1337,11 @@ rest_of_handle_lower_subreg2 (void) return 0; } -struct tree_opt_pass pass_lower_subreg = +struct rtl_opt_pass pass_lower_subreg = { - "subreg", /* name */ + { + RTL_PASS, + "subreg1", /* name */ gate_handle_lower_subreg, /* gate */ rest_of_handle_lower_subreg, /* execute */ NULL, /* sub */ @@ -1437,12 +1354,14 @@ struct tree_opt_pass pass_lower_subreg = 0, /* todo_flags_start */ TODO_dump_func | TODO_ggc_collect | - TODO_verify_flow, /* todo_flags_finish */ - 'u' /* letter */ + TODO_verify_flow /* todo_flags_finish */ + } }; -struct tree_opt_pass pass_lower_subreg2 = +struct rtl_opt_pass pass_lower_subreg2 = { + { + RTL_PASS, "subreg2", /* name */ gate_handle_lower_subreg, /* gate */ rest_of_handle_lower_subreg2, /* execute */ @@ -1454,9 +1373,9 @@ struct tree_opt_pass pass_lower_subreg2 = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_df_finish | + TODO_df_finish | TODO_verify_rtl_sharing | TODO_dump_func | TODO_ggc_collect | - TODO_verify_flow, /* todo_flags_finish */ - 'U' /* letter */ + TODO_verify_flow /* todo_flags_finish */ + } };