Mercurial > hg > CbC > CbC_gcc
diff gcc/caller-save.c @ 63:b7f97abdc517 gcc-4.6-20100522
update gcc from gcc-4.5.0 to gcc-4.6
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 24 May 2010 12:47:05 +0900 |
parents | 77e2b8dfacca |
children | f6334be47118 |
line wrap: on
line diff
--- a/gcc/caller-save.c Fri Feb 12 23:41:23 2010 +0900 +++ b/gcc/caller-save.c Mon May 24 12:47:05 2010 +0900 @@ -1,6 +1,6 @@ /* Save and restore call-clobbered registers which are live across a call. Copyright (C) 1989, 1992, 1994, 1995, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -30,6 +30,7 @@ #include "hard-reg-set.h" #include "recog.h" #include "basic-block.h" +#include "df.h" #include "reload.h" #include "function.h" #include "expr.h" @@ -37,9 +38,11 @@ #include "tm_p.h" #include "addresses.h" #include "output.h" -#include "df.h" #include "ggc.h" +/* True if caller-save has been initialized. */ +bool caller_save_initialized_p; + /* Call used hard registers which can not be saved because there is no insn for this. */ HARD_REG_SET no_caller_save_reg_set; @@ -208,6 +211,11 @@ rtx address; int i, j; + if (caller_save_initialized_p) + return; + + caller_save_initialized_p = true; + CLEAR_HARD_REG_SET (no_caller_save_reg_set); /* First find all the registers that we need to deal with and all the modes that they can have. If we can't find a mode to use, @@ -549,7 +557,7 @@ CLEAR_HARD_REG_SET (this_insn_sets); note_stores (PATTERN (insn), mark_set_regs, &this_insn_sets); /* Sibcalls are considered to set the return value, - compare flow.c:propagate_one_insn. */ + compare df-scan.c:df_get_call_refs. */ if (SIBLING_CALL_P (insn) && crtl->return_rtx) mark_set_regs (crtl->return_rtx, NULL_RTX, &this_insn_sets); @@ -754,7 +762,7 @@ void save_call_clobbered_regs (void) { - struct insn_chain *chain, *next; + struct insn_chain *chain, *next, *last = NULL; enum machine_mode save_mode [FIRST_PSEUDO_REGISTER]; /* Computed in mark_set_regs, holds all registers set by the current @@ -861,6 +869,7 @@ if (TEST_HARD_REG_BIT (hard_regs_saved, regno)) n_regs_saved++; } + last = chain; } else if (DEBUG_INSN_P (insn) && n_regs_saved) mark_referenced_regs (&PATTERN (insn), @@ -874,6 +883,36 @@ remain saved. If the last insn in the block is a JUMP_INSN, put the restore before the insn, otherwise, put it after the insn. */ + if (DEBUG_INSN_P (insn) && last && last->block == chain->block) + { + rtx ins, prev; + basic_block bb = BLOCK_FOR_INSN (insn); + + /* When adding hard reg restores after a DEBUG_INSN, move + all notes between last real insn and this DEBUG_INSN after + the DEBUG_INSN, otherwise we could get code + -g/-g0 differences. */ + for (ins = PREV_INSN (insn); ins != last->insn; ins = prev) + { + prev = PREV_INSN (ins); + if (NOTE_P (ins)) + { + NEXT_INSN (prev) = NEXT_INSN (ins); + PREV_INSN (NEXT_INSN (ins)) = prev; + PREV_INSN (ins) = insn; + NEXT_INSN (ins) = NEXT_INSN (insn); + NEXT_INSN (insn) = ins; + if (NEXT_INSN (ins)) + PREV_INSN (NEXT_INSN (ins)) = ins; + if (BB_END (bb) == insn) + BB_END (bb) = ins; + } + else + gcc_assert (DEBUG_INSN_P (ins)); + } + } + last = NULL; + if (n_regs_saved) for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (hard_regs_saved, regno))