Mercurial > hg > CbC > CbC_gcc
comparison 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 |
comparison
equal
deleted
inserted
replaced
56:3c8a44c06a95 | 63:b7f97abdc517 |
---|---|
1 /* Save and restore call-clobbered registers which are live across a call. | 1 /* Save and restore call-clobbered registers which are live across a call. |
2 Copyright (C) 1989, 1992, 1994, 1995, 1997, 1998, 1999, 2000, | 2 Copyright (C) 1989, 1992, 1994, 1995, 1997, 1998, 1999, 2000, |
3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 | 3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 |
4 Free Software Foundation, Inc. | 4 Free Software Foundation, Inc. |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
8 GCC is free software; you can redistribute it and/or modify it under | 8 GCC is free software; you can redistribute it and/or modify it under |
28 #include "insn-config.h" | 28 #include "insn-config.h" |
29 #include "flags.h" | 29 #include "flags.h" |
30 #include "hard-reg-set.h" | 30 #include "hard-reg-set.h" |
31 #include "recog.h" | 31 #include "recog.h" |
32 #include "basic-block.h" | 32 #include "basic-block.h" |
33 #include "df.h" | |
33 #include "reload.h" | 34 #include "reload.h" |
34 #include "function.h" | 35 #include "function.h" |
35 #include "expr.h" | 36 #include "expr.h" |
36 #include "toplev.h" | 37 #include "toplev.h" |
37 #include "tm_p.h" | 38 #include "tm_p.h" |
38 #include "addresses.h" | 39 #include "addresses.h" |
39 #include "output.h" | 40 #include "output.h" |
40 #include "df.h" | |
41 #include "ggc.h" | 41 #include "ggc.h" |
42 | |
43 /* True if caller-save has been initialized. */ | |
44 bool caller_save_initialized_p; | |
42 | 45 |
43 /* Call used hard registers which can not be saved because there is no | 46 /* Call used hard registers which can not be saved because there is no |
44 insn for this. */ | 47 insn for this. */ |
45 HARD_REG_SET no_caller_save_reg_set; | 48 HARD_REG_SET no_caller_save_reg_set; |
46 | 49 |
205 { | 208 { |
206 rtx addr_reg; | 209 rtx addr_reg; |
207 int offset; | 210 int offset; |
208 rtx address; | 211 rtx address; |
209 int i, j; | 212 int i, j; |
213 | |
214 if (caller_save_initialized_p) | |
215 return; | |
216 | |
217 caller_save_initialized_p = true; | |
210 | 218 |
211 CLEAR_HARD_REG_SET (no_caller_save_reg_set); | 219 CLEAR_HARD_REG_SET (no_caller_save_reg_set); |
212 /* First find all the registers that we need to deal with and all | 220 /* First find all the registers that we need to deal with and all |
213 the modes that they can have. If we can't find a mode to use, | 221 the modes that they can have. If we can't find a mode to use, |
214 we can't have the register live over calls. */ | 222 we can't have the register live over calls. */ |
547 live during the call, but the subreg that is set | 555 live during the call, but the subreg that is set |
548 isn't. */ | 556 isn't. */ |
549 CLEAR_HARD_REG_SET (this_insn_sets); | 557 CLEAR_HARD_REG_SET (this_insn_sets); |
550 note_stores (PATTERN (insn), mark_set_regs, &this_insn_sets); | 558 note_stores (PATTERN (insn), mark_set_regs, &this_insn_sets); |
551 /* Sibcalls are considered to set the return value, | 559 /* Sibcalls are considered to set the return value, |
552 compare flow.c:propagate_one_insn. */ | 560 compare df-scan.c:df_get_call_refs. */ |
553 if (SIBLING_CALL_P (insn) && crtl->return_rtx) | 561 if (SIBLING_CALL_P (insn) && crtl->return_rtx) |
554 mark_set_regs (crtl->return_rtx, NULL_RTX, &this_insn_sets); | 562 mark_set_regs (crtl->return_rtx, NULL_RTX, &this_insn_sets); |
555 | 563 |
556 AND_COMPL_HARD_REG_SET (used_regs, call_fixed_reg_set); | 564 AND_COMPL_HARD_REG_SET (used_regs, call_fixed_reg_set); |
557 AND_COMPL_HARD_REG_SET (used_regs, this_insn_sets); | 565 AND_COMPL_HARD_REG_SET (used_regs, this_insn_sets); |
752 /* Find the places where hard regs are live across calls and save them. */ | 760 /* Find the places where hard regs are live across calls and save them. */ |
753 | 761 |
754 void | 762 void |
755 save_call_clobbered_regs (void) | 763 save_call_clobbered_regs (void) |
756 { | 764 { |
757 struct insn_chain *chain, *next; | 765 struct insn_chain *chain, *next, *last = NULL; |
758 enum machine_mode save_mode [FIRST_PSEUDO_REGISTER]; | 766 enum machine_mode save_mode [FIRST_PSEUDO_REGISTER]; |
759 | 767 |
760 /* Computed in mark_set_regs, holds all registers set by the current | 768 /* Computed in mark_set_regs, holds all registers set by the current |
761 instruction. */ | 769 instruction. */ |
762 HARD_REG_SET this_insn_sets; | 770 HARD_REG_SET this_insn_sets; |
859 n_regs_saved = 0; | 867 n_regs_saved = 0; |
860 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) | 868 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) |
861 if (TEST_HARD_REG_BIT (hard_regs_saved, regno)) | 869 if (TEST_HARD_REG_BIT (hard_regs_saved, regno)) |
862 n_regs_saved++; | 870 n_regs_saved++; |
863 } | 871 } |
872 last = chain; | |
864 } | 873 } |
865 else if (DEBUG_INSN_P (insn) && n_regs_saved) | 874 else if (DEBUG_INSN_P (insn) && n_regs_saved) |
866 mark_referenced_regs (&PATTERN (insn), | 875 mark_referenced_regs (&PATTERN (insn), |
867 replace_reg_with_saved_mem, | 876 replace_reg_with_saved_mem, |
868 save_mode); | 877 save_mode); |
871 { | 880 { |
872 int regno; | 881 int regno; |
873 /* At the end of the basic block, we must restore any registers that | 882 /* At the end of the basic block, we must restore any registers that |
874 remain saved. If the last insn in the block is a JUMP_INSN, put | 883 remain saved. If the last insn in the block is a JUMP_INSN, put |
875 the restore before the insn, otherwise, put it after the insn. */ | 884 the restore before the insn, otherwise, put it after the insn. */ |
885 | |
886 if (DEBUG_INSN_P (insn) && last && last->block == chain->block) | |
887 { | |
888 rtx ins, prev; | |
889 basic_block bb = BLOCK_FOR_INSN (insn); | |
890 | |
891 /* When adding hard reg restores after a DEBUG_INSN, move | |
892 all notes between last real insn and this DEBUG_INSN after | |
893 the DEBUG_INSN, otherwise we could get code | |
894 -g/-g0 differences. */ | |
895 for (ins = PREV_INSN (insn); ins != last->insn; ins = prev) | |
896 { | |
897 prev = PREV_INSN (ins); | |
898 if (NOTE_P (ins)) | |
899 { | |
900 NEXT_INSN (prev) = NEXT_INSN (ins); | |
901 PREV_INSN (NEXT_INSN (ins)) = prev; | |
902 PREV_INSN (ins) = insn; | |
903 NEXT_INSN (ins) = NEXT_INSN (insn); | |
904 NEXT_INSN (insn) = ins; | |
905 if (NEXT_INSN (ins)) | |
906 PREV_INSN (NEXT_INSN (ins)) = ins; | |
907 if (BB_END (bb) == insn) | |
908 BB_END (bb) = ins; | |
909 } | |
910 else | |
911 gcc_assert (DEBUG_INSN_P (ins)); | |
912 } | |
913 } | |
914 last = NULL; | |
876 | 915 |
877 if (n_regs_saved) | 916 if (n_regs_saved) |
878 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) | 917 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) |
879 if (TEST_HARD_REG_BIT (hard_regs_saved, regno)) | 918 if (TEST_HARD_REG_BIT (hard_regs_saved, regno)) |
880 regno += insert_restore (chain, JUMP_P (insn), | 919 regno += insert_restore (chain, JUMP_P (insn), |