X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fintegrate.c;h=0884017e3916e20ffc3dfd5f1d60156d22ad7101;hb=022b3380cc939bd06e310f17578c670e5365050c;hp=3573b443b95ea5c618d4c057984c1e4cb42dc543;hpb=9732dffb5cb0757535e7cb935997b1201cb13dcb;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/integrate.c b/gcc/integrate.c index 3573b443b95..0884017e391 100644 --- a/gcc/integrate.c +++ b/gcc/integrate.c @@ -1,13 +1,14 @@ /* Procedure integration for GCC. Copyright (C) 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later +Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY @@ -16,9 +17,8 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ +along with GCC; see the file COPYING3. If not see +. */ #include "config.h" #include "system.h" @@ -45,17 +45,19 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "ggc.h" #include "target.h" #include "langhooks.h" +#include "tree-pass.h" +#include "df.h" /* Round to the next highest integer that meets the alignment. */ #define CEIL_ROUND(VALUE,ALIGN) (((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1)) /* Private type used by {get/has}_hard_reg_initial_val. */ -typedef struct initial_value_pair GTY(()) { +typedef struct GTY(()) initial_value_pair { rtx hard_reg; rtx pseudo; } initial_value_pair; -typedef struct initial_value_struct GTY(()) { +typedef struct GTY(()) initial_value_struct { int num_entries; int max_entries; initial_value_pair * GTY ((length ("%h.num_entries"))) entries; @@ -68,15 +70,15 @@ static void set_block_abstract_flags (tree, int); /* Return false if the function FNDECL cannot be inlined on account of its attributes, true otherwise. */ bool -function_attribute_inlinable_p (tree fndecl) +function_attribute_inlinable_p (const_tree fndecl) { if (targetm.attribute_table) { - tree a; + const_tree a; for (a = DECL_ATTRIBUTES (fndecl); a; a = TREE_CHAIN (a)) { - tree name = TREE_PURPOSE (a); + const_tree name = TREE_PURPOSE (a); int i; for (i = 0; targetm.attribute_table[i].name != NULL; i++) @@ -88,79 +90,6 @@ function_attribute_inlinable_p (tree fndecl) return true; } -/* Copy NODE (which must be a DECL). The DECL originally was in the FROM_FN, - but now it will be in the TO_FN. */ - -tree -copy_decl_for_inlining (tree decl, tree from_fn, tree to_fn) -{ - tree copy; - - /* Copy the declaration. */ - if (TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == RESULT_DECL) - { - tree type = TREE_TYPE (decl); - - /* For a parameter or result, we must make an equivalent VAR_DECL, not a - new PARM_DECL. */ - copy = build_decl (VAR_DECL, DECL_NAME (decl), type); - TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl); - TREE_READONLY (copy) = TREE_READONLY (decl); - TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl); - } - else - { - copy = copy_node (decl); - /* The COPY is not abstract; it will be generated in TO_FN. */ - DECL_ABSTRACT (copy) = 0; - lang_hooks.dup_lang_specific_decl (copy); - - /* TREE_ADDRESSABLE isn't used to indicate that a label's - address has been taken; it's for internal bookkeeping in - expand_goto_internal. */ - if (TREE_CODE (copy) == LABEL_DECL) - { - TREE_ADDRESSABLE (copy) = 0; - } - } - - /* Don't generate debug information for the copy if we wouldn't have - generated it for the copy either. */ - DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (decl); - DECL_IGNORED_P (copy) = DECL_IGNORED_P (decl); - - /* Set the DECL_ABSTRACT_ORIGIN so the debugging routines know what - declaration inspired this copy. */ - DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (decl); - - /* The new variable/label has no RTL, yet. */ - if (!TREE_STATIC (copy) && !DECL_EXTERNAL (copy)) - SET_DECL_RTL (copy, NULL_RTX); - - /* These args would always appear unused, if not for this. */ - TREE_USED (copy) = 1; - - /* Set the context for the new declaration. */ - if (!DECL_CONTEXT (decl)) - /* Globals stay global. */ - ; - else if (DECL_CONTEXT (decl) != from_fn) - /* Things that weren't in the scope of the function we're inlining - from aren't in the scope we're inlining to, either. */ - ; - else if (TREE_STATIC (decl)) - /* Function-scoped static variables should stay in the original - function. */ - ; - else - /* Ordinary automatic local variables are now in the scope of the - new function. */ - DECL_CONTEXT (copy) = to_fn; - - return copy; -} - - /* Given a pointer to some BLOCK node, if the BLOCK_ABSTRACT_ORIGIN for the given BLOCK node is NULL, set the BLOCK_ABSTRACT_ORIGIN for the node so that it points to the node itself, thus indicating that the node is its @@ -238,6 +167,7 @@ set_block_abstract_flags (tree stmt, int setting) { tree local_decl; tree subblock; + unsigned int i; BLOCK_ABSTRACT (stmt) = setting; @@ -246,6 +176,14 @@ set_block_abstract_flags (tree stmt, int setting) local_decl = TREE_CHAIN (local_decl)) set_decl_abstract_flags (local_decl, setting); + for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (stmt); i++) + { + local_decl = BLOCK_NONLOCALIZED_VAR (stmt, i); + if ((TREE_CODE (local_decl) == VAR_DECL && !TREE_STATIC (local_decl)) + || TREE_CODE (local_decl) == PARM_DECL) + set_decl_abstract_flags (local_decl, setting); + } + for (subblock = BLOCK_SUBBLOCKS (stmt); subblock != NULL_TREE; subblock = BLOCK_CHAIN (subblock)) @@ -278,9 +216,9 @@ set_decl_abstract_flags (tree decl, int setting) the function. */ rtx -get_hard_reg_initial_reg (struct function *fun, rtx reg) +get_hard_reg_initial_reg (rtx reg) { - struct initial_value_struct *ivs = fun->hard_reg_initial_vals; + struct initial_value_struct *ivs = crtl->hard_reg_initial_vals; int i; if (ivs == 0) @@ -306,22 +244,21 @@ get_hard_reg_initial_val (enum machine_mode mode, unsigned int regno) if (rv) return rv; - ivs = cfun->hard_reg_initial_vals; + ivs = crtl->hard_reg_initial_vals; if (ivs == 0) { - ivs = ggc_alloc (sizeof (initial_value_struct)); + ivs = GGC_NEW (initial_value_struct); ivs->num_entries = 0; ivs->max_entries = 5; - ivs->entries = ggc_alloc (5 * sizeof (initial_value_pair)); - cfun->hard_reg_initial_vals = ivs; + ivs->entries = GGC_NEWVEC (initial_value_pair, 5); + crtl->hard_reg_initial_vals = ivs; } if (ivs->num_entries >= ivs->max_entries) { ivs->max_entries += 5; - ivs->entries = ggc_realloc (ivs->entries, - ivs->max_entries - * sizeof (initial_value_pair)); + ivs->entries = GGC_RESIZEVEC (initial_value_pair, ivs->entries, + ivs->max_entries); } ivs->entries[ivs->num_entries].hard_reg = gen_rtx_REG (mode, regno); @@ -340,7 +277,7 @@ has_hard_reg_initial_val (enum machine_mode mode, unsigned int regno) struct initial_value_struct *ivs; int i; - ivs = cfun->hard_reg_initial_vals; + ivs = crtl->hard_reg_initial_vals; if (ivs != 0) for (i = 0; i < ivs->num_entries; i++) if (GET_MODE (ivs->entries[i].hard_reg) == mode @@ -350,15 +287,15 @@ has_hard_reg_initial_val (enum machine_mode mode, unsigned int regno) return NULL_RTX; } -void +unsigned int emit_initial_value_sets (void) { - struct initial_value_struct *ivs = cfun->hard_reg_initial_vals; + struct initial_value_struct *ivs = crtl->hard_reg_initial_vals; int i; rtx seq; if (ivs == 0) - return; + return 0; start_sequence (); for (i = 0; i < ivs->num_entries; i++) @@ -366,53 +303,74 @@ emit_initial_value_sets (void) seq = get_insns (); end_sequence (); - emit_insn_after (seq, entry_of_function ()); + emit_insn_at_entry (seq); + return 0; } +struct rtl_opt_pass pass_initial_value_sets = +{ + { + RTL_PASS, + "initvals", /* name */ + NULL, /* gate */ + emit_initial_value_sets, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_NONE, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func /* todo_flags_finish */ + } +}; + /* If the backend knows where to allocate pseudos for hard register initial values, register these allocations now. */ void -allocate_initial_values (rtx *reg_equiv_memory_loc ATTRIBUTE_UNUSED) +allocate_initial_values (rtx *reg_equiv_memory_loc) { -#ifdef ALLOCATE_INITIAL_VALUE - struct initial_value_struct *ivs = cfun->hard_reg_initial_vals; - int i; - - if (ivs == 0) - return; - - for (i = 0; i < ivs->num_entries; i++) + if (targetm.allocate_initial_value) { - int regno = REGNO (ivs->entries[i].pseudo); - rtx x = ALLOCATE_INITIAL_VALUE (ivs->entries[i].hard_reg); + struct initial_value_struct *ivs = crtl->hard_reg_initial_vals; + int i; + + if (ivs == 0) + return; - if (x && REG_N_SETS (REGNO (ivs->entries[i].pseudo)) <= 1) + for (i = 0; i < ivs->num_entries; i++) { - if (MEM_P (x)) - reg_equiv_memory_loc[regno] = x; - else + int regno = REGNO (ivs->entries[i].pseudo); + rtx x = targetm.allocate_initial_value (ivs->entries[i].hard_reg); + + if (x && REG_N_SETS (REGNO (ivs->entries[i].pseudo)) <= 1) { - basic_block bb; - int new_regno; - - gcc_assert (REG_P (x)); - new_regno = REGNO (x); - reg_renumber[regno] = new_regno; - /* Poke the regno right into regno_reg_rtx so that even - fixed regs are accepted. */ - REGNO (ivs->entries[i].pseudo) = new_regno; - /* Update global register liveness information. */ - FOR_EACH_BB (bb) + if (MEM_P (x)) + reg_equiv_memory_loc[regno] = x; + else { - if (REGNO_REG_SET_P(bb->global_live_at_start, regno)) - SET_REGNO_REG_SET (bb->global_live_at_start, new_regno); - if (REGNO_REG_SET_P(bb->global_live_at_end, regno)) - SET_REGNO_REG_SET (bb->global_live_at_end, new_regno); + basic_block bb; + int new_regno; + + gcc_assert (REG_P (x)); + new_regno = REGNO (x); + reg_renumber[regno] = new_regno; + /* Poke the regno right into regno_reg_rtx so that even + fixed regs are accepted. */ + SET_REGNO (ivs->entries[i].pseudo, new_regno); + /* Update global register liveness information. */ + FOR_EACH_BB (bb) + { + if (REGNO_REG_SET_P(df_get_live_in (bb), regno)) + SET_REGNO_REG_SET (df_get_live_in (bb), new_regno); + if (REGNO_REG_SET_P(df_get_live_out (bb), regno)) + SET_REGNO_REG_SET (df_get_live_out (bb), new_regno); + } } } } } -#endif } #include "gt-integrate.h"