X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Freg-stack.c;h=ce29fdcaf834e98344d0da1fe405179c80889c4b;hb=eec86b214a56292b6b65834f0caff7ae2bda9cc9;hp=60835c75528d0c09a9472bf89fe9d6ad06a715dc;hpb=54f21e20a8888ed9862f57194c1270949c9b7ac8;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 60835c75528..ce29fdcaf83 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -1,6 +1,6 @@ /* Register to Stack convert for GNU compiler. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011, 2012 Free Software Foundation, Inc. This file is part of GCC. @@ -434,7 +434,8 @@ get_true_reg (rtx *pat) break; case UNSPEC: - if (XINT (*pat, 1) == UNSPEC_TRUNC_NOOP) + if (XINT (*pat, 1) == UNSPEC_TRUNC_NOOP + || XINT (*pat, 1) == UNSPEC_LDA) pat = & XVECEXP (*pat, 0, 0); return pat; @@ -1322,17 +1323,18 @@ compare_for_stack_reg (rtx insn, stack regstack, rtx pat_src) static int subst_stack_regs_in_debug_insn (rtx *loc, void *data) { - rtx *tloc = get_true_reg (loc); stack regstack = (stack)data; int hard_regno; - if (!STACK_REG_P (*tloc)) - return 0; - - if (tloc != loc) + if (!STACK_REG_P (*loc)) return 0; hard_regno = get_hard_regnum (regstack, *loc); + + /* If we can't find an active register, reset this debug insn. */ + if (hard_regno == -1) + return 1; + gcc_assert (hard_regno >= FIRST_STACK_REG); replace_reg (loc, hard_regno); @@ -1340,6 +1342,23 @@ subst_stack_regs_in_debug_insn (rtx *loc, void *data) return -1; } +/* Substitute hardware stack regs in debug insn INSN, using stack + layout REGSTACK. If we can't find a hardware stack reg for any of + the REGs in it, reset the debug insn. */ + +static void +subst_all_stack_regs_in_debug_insn (rtx insn, struct stack_def *regstack) +{ + int ret = for_each_rtx (&INSN_VAR_LOCATION_LOC (insn), + subst_stack_regs_in_debug_insn, + regstack); + + if (ret == 1) + INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC (); + else + gcc_checking_assert (ret == 0); +} + /* Substitute new registers in PAT, which is part of INSN. REGSTACK is the current register layout. Return whether a control flow insn was deleted in the process. */ @@ -1655,6 +1674,7 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat) case UNSPEC: switch (XINT (pat_src, 1)) { + case UNSPEC_STA: case UNSPEC_FIST: case UNSPEC_FIST_FLOOR: @@ -2947,8 +2967,7 @@ convert_regs_1 (basic_block block) debug_insns_with_starting_stack++; else { - for_each_rtx (&PATTERN (insn), subst_stack_regs_in_debug_insn, - ®stack); + subst_all_stack_regs_in_debug_insn (insn, ®stack); /* Nothing must ever die at a debug insn. If something is referenced in it that becomes dead, it should have @@ -2986,8 +3005,7 @@ convert_regs_1 (basic_block block) continue; debug_insns_with_starting_stack--; - for_each_rtx (&PATTERN (insn), subst_stack_regs_in_debug_insn, - &bi->stack_in); + subst_all_stack_regs_in_debug_insn (insn, &bi->stack_in); } } @@ -3332,7 +3350,6 @@ struct rtl_opt_pass pass_stack_regs_run = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ } };