X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Flower-subreg.c;h=3ff20eb3de52647a18f38515c92d9fbc7c47f5e7;hb=a4f7c8f77479aa46ba7962e91b975c0492386a6d;hp=67a95984fab266f82ee96bd65a84193e00bba908;hpb=1e5b92fa15f6677249b1fc9e240955537ae33bd2;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c index 67a95984fab..3ff20eb3de5 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 @@ -531,6 +531,34 @@ resolve_subreg_use (rtx *px, void *data) return 0; } +/* This is called via for_each_rtx. Look for SUBREGs which can be + decomposed and decomposed REGs that need copying. */ + +static int +adjust_decomposed_uses (rtx *px, void *data ATTRIBUTE_UNUSED) +{ + rtx x = *px; + + if (x == NULL_RTX) + return 0; + + if (resolve_subreg_p (x)) + { + x = simplify_subreg_concatn (GET_MODE (x), SUBREG_REG (x), + SUBREG_BYTE (x)); + + if (x) + *px = x; + else + x = copy_rtx (*px); + } + + if (resolve_reg_p (x)) + *px = copy_rtx (x); + + return 0; +} + /* We are deleting INSN. Move any EH_REGION notes to INSNS. */ static void @@ -551,8 +579,7 @@ move_eh_region_note (rtx insn, rtx insns) || (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)); + add_reg_note (p, REG_EH_REGION, XEXP (note, 0)); } } @@ -578,7 +605,7 @@ 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)) @@ -586,14 +613,14 @@ resolve_reg_notes (rtx insn) 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); @@ -887,6 +914,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. */ @@ -923,7 +962,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; @@ -1171,6 +1210,8 @@ decompose_multiword_subregs (void) 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; @@ -1326,7 +1367,7 @@ struct rtl_opt_pass pass_lower_subreg = { { RTL_PASS, - "subreg", /* name */ + "subreg1", /* name */ gate_handle_lower_subreg, /* gate */ rest_of_handle_lower_subreg, /* execute */ NULL, /* sub */