diff options
Diffstat (limited to 'contrib/gcc/integrate.c')
-rw-r--r-- | contrib/gcc/integrate.c | 346 |
1 files changed, 142 insertions, 204 deletions
diff --git a/contrib/gcc/integrate.c b/contrib/gcc/integrate.c index 7e36070f..d45bbfc 100644 --- a/contrib/gcc/integrate.c +++ b/contrib/gcc/integrate.c @@ -1,6 +1,6 @@ /* Procedure integration for GCC. - Copyright (C) 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. @@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "config.h" #include "system.h" +#include "coretypes.h" +#include "tm.h" #include "rtl.h" #include "tree.h" @@ -72,29 +74,23 @@ typedef struct initial_value_struct GTY(()) { initial_value_pair * GTY ((length ("%h.num_entries"))) entries; } initial_value_struct; -static void setup_initial_hard_reg_value_integration PARAMS ((struct function *, struct inline_remap *)); - -static rtvec initialize_for_inline PARAMS ((tree)); -static void note_modified_parmregs PARAMS ((rtx, rtx, void *)); -static void integrate_parm_decls PARAMS ((tree, struct inline_remap *, - rtvec)); -static tree integrate_decl_tree PARAMS ((tree, - struct inline_remap *)); -static void subst_constants PARAMS ((rtx *, rtx, - struct inline_remap *, int)); -static void set_block_origin_self PARAMS ((tree)); -static void set_block_abstract_flags PARAMS ((tree, int)); -static void process_reg_param PARAMS ((struct inline_remap *, rtx, - rtx)); -void set_decl_abstract_flags PARAMS ((tree, int)); -static void mark_stores PARAMS ((rtx, rtx, void *)); -static void save_parm_insns PARAMS ((rtx, rtx)); -static void copy_insn_list PARAMS ((rtx, struct inline_remap *, - rtx)); -static void copy_insn_notes PARAMS ((rtx, struct inline_remap *, - int)); -static int compare_blocks PARAMS ((const PTR, const PTR)); -static int find_block PARAMS ((const PTR, const PTR)); +static void setup_initial_hard_reg_value_integration (struct function *, + struct inline_remap *); + +static rtvec initialize_for_inline (tree); +static void note_modified_parmregs (rtx, rtx, void *); +static void integrate_parm_decls (tree, struct inline_remap *, rtvec); +static tree integrate_decl_tree (tree, struct inline_remap *); +static void subst_constants (rtx *, rtx, struct inline_remap *, int); +static void set_block_origin_self (tree); +static void set_block_abstract_flags (tree, int); +static void process_reg_param (struct inline_remap *, rtx, rtx); +static void mark_stores (rtx, rtx, void *); +static void save_parm_insns (rtx, rtx); +static void copy_insn_list (rtx, struct inline_remap *, rtx); +static void copy_insn_notes (rtx, struct inline_remap *, int); +static int compare_blocks (const void *, const void *); +static int find_block (const void *, const void *); /* Used by copy_rtx_and_substitute; this indicates whether the function is called for the purpose of inlining or some other purpose (i.e. loop @@ -108,9 +104,7 @@ static struct function *inlining = 0; explosions when the label_map gets very large. */ rtx -get_label_from_map (map, i) - struct inline_remap *map; - int i; +get_label_from_map (struct inline_remap *map, int i) { rtx x = map->label_map[i]; @@ -123,8 +117,7 @@ get_label_from_map (map, i) /* Return false if the function FNDECL cannot be inlined on account of its attributes, true otherwise. */ bool -function_attribute_inlinable_p (fndecl) - tree fndecl; +function_attribute_inlinable_p (tree fndecl) { if (targetm.attribute_table) { @@ -150,8 +143,7 @@ function_attribute_inlinable_p (fndecl) for the function's name. */ const char * -function_cannot_inline_p (fndecl) - tree fndecl; +function_cannot_inline_p (tree fndecl) { rtx insn; tree last = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))); @@ -180,6 +172,9 @@ function_cannot_inline_p (fndecl) if (current_function_calls_alloca) return N_("function using alloca cannot be inline"); + if (current_function_calls_longjmp) + return N_("function using longjmp cannot be inline"); + if (current_function_calls_setjmp) return N_("function using setjmp cannot be inline"); @@ -264,7 +259,7 @@ function_cannot_inline_p (fndecl) } /* If the function has a target specific attribute attached to it, - then we assume that we should not inline it. This can be overriden + then we assume that we should not inline it. This can be overridden by the target if it defines TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P. */ if (!function_attribute_inlinable_p (fndecl)) return N_("function with target specific attribute(s) cannot be inlined"); @@ -284,15 +279,14 @@ static int in_nonparm_insns; needed to save FNDECL's insns and info for future inline expansion. */ static rtvec -initialize_for_inline (fndecl) - tree fndecl; +initialize_for_inline (tree fndecl) { int i; rtvec arg_vector; tree parms; /* Clear out PARMDECL_MAP. It was allocated in the caller's frame. */ - memset ((char *) parmdecl_map, 0, max_parm_reg * sizeof (tree)); + memset (parmdecl_map, 0, max_parm_reg * sizeof (tree)); arg_vector = rtvec_alloc (list_length (DECL_ARGUMENTS (fndecl))); for (parms = DECL_ARGUMENTS (fndecl), i = 0; @@ -336,10 +330,7 @@ initialize_for_inline (fndecl) TO_FN. */ tree -copy_decl_for_inlining (decl, from_fn, to_fn) - tree decl; - tree from_fn; - tree to_fn; +copy_decl_for_inlining (tree decl, tree from_fn, tree to_fn) { tree copy; @@ -396,7 +387,8 @@ copy_decl_for_inlining (decl, from_fn, to_fn) DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (decl); /* The new variable/label has no RTL, yet. */ - SET_DECL_RTL (copy, NULL_RTX); + 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; @@ -407,10 +399,10 @@ copy_decl_for_inlining (decl, from_fn, to_fn) ; 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 too, either. */ + from aren't in the scope we're inlining to, either. */ ; else if (TREE_STATIC (decl)) - /* Function-scoped static variables should say in the original + /* Function-scoped static variables should stay in the original function. */ ; else @@ -441,8 +433,7 @@ copy_decl_for_inlining (decl, from_fn, to_fn) functions at the end of compilation. */ void -save_for_inline (fndecl) - tree fndecl; +save_for_inline (tree fndecl) { rtx insn; rtvec argvec; @@ -454,7 +445,7 @@ save_for_inline (fndecl) for the parms, prior to elimination of virtual registers. These values are needed for substituting parms properly. */ if (! flag_no_inline) - parmdecl_map = (tree *) xmalloc (max_parm_reg * sizeof (tree)); + parmdecl_map = xmalloc (max_parm_reg * sizeof (tree)); /* Make and emit a return-label if we have not already done so. */ @@ -504,7 +495,7 @@ save_for_inline (fndecl) } cfun->original_decl_initial = DECL_INITIAL (fndecl); cfun->no_debugging_symbols = (write_symbols == NO_DEBUG); - DECL_SAVED_INSNS (fndecl) = cfun; + cfun->saved_for_inline = 1; /* Clean up. */ if (! flag_no_inline) @@ -518,9 +509,7 @@ save_for_inline (fndecl) register and track the new register's life. */ static void -save_parm_insns (insn, first_nonparm_insn) - rtx insn; - rtx first_nonparm_insn; +save_parm_insns (rtx insn, rtx first_nonparm_insn) { if (insn == NULL_RTX) return; @@ -554,10 +543,7 @@ save_parm_insns (insn, first_nonparm_insn) /* Note whether a parameter is modified or not. */ static void -note_modified_parmregs (reg, x, data) - rtx reg; - rtx x ATTRIBUTE_UNUSED; - void *data ATTRIBUTE_UNUSED; +note_modified_parmregs (rtx reg, rtx x ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED) { if (GET_CODE (reg) == REG && in_nonparm_insns && REGNO (reg) < max_parm_reg @@ -588,9 +574,7 @@ varray_type global_const_equiv_varray; Also, don't allow hard registers here; they might not be valid when substituted into insns. */ static void -process_reg_param (map, loc, copy) - struct inline_remap *map; - rtx loc, copy; +process_reg_param (struct inline_remap *map, rtx loc, rtx copy) { if ((GET_CODE (copy) != REG && GET_CODE (copy) != SUBREG) || (GET_CODE (copy) == REG && REG_USERVAR_P (loc) @@ -612,9 +596,7 @@ process_reg_param (map, loc, copy) two pointers, because it may overflow sizeof(int). */ static int -compare_blocks (v1, v2) - const PTR v1; - const PTR v2; +compare_blocks (const void *v1, const void *v2) { tree b1 = *((const tree *) v1); tree b2 = *((const tree *) v2); @@ -630,9 +612,7 @@ compare_blocks (v1, v2) an original block; the second to a remapped equivalent. */ static int -find_block (v1, v2) - const PTR v1; - const PTR v2; +find_block (const void *v1, const void *v2) { const union tree_node *b1 = (const union tree_node *) v1; tree b2 = *((const tree *) v2); @@ -658,13 +638,8 @@ find_block (v1, v2) else an rtx for where the value is stored. */ rtx -expand_inline_function (fndecl, parms, target, ignore, type, - structure_value_addr) - tree fndecl, parms; - rtx target; - int ignore; - tree type; - rtx structure_value_addr; +expand_inline_function (tree fndecl, tree parms, rtx target, int ignore, + tree type, rtx structure_value_addr) { struct function *inlining_previous; struct function *inl_f = DECL_SAVED_INSNS (fndecl); @@ -735,6 +710,14 @@ expand_inline_function (fndecl, parms, target, ignore, type, return (rtx) (size_t) -1; } + /* If there is a TARGET which is a readonly BLKmode MEM and DECL_RESULT + is also a mem, we are going to lose the readonly on the stores, so don't + inline. */ + if (target != 0 && GET_CODE (target) == MEM && GET_MODE (target) == BLKmode + && RTX_UNCHANGING_P (target) && DECL_RTL_SET_P (DECL_RESULT (fndecl)) + && GET_CODE (DECL_RTL (DECL_RESULT (fndecl))) == MEM) + return (rtx) (size_t) -1; + /* Extra arguments are valid, but will be ignored below, so we must evaluate them here for side-effects. */ for (; actual; actual = TREE_CHAIN (actual)) @@ -744,8 +727,8 @@ expand_inline_function (fndecl, parms, target, ignore, type, /* Expand the function arguments. Do this first so that any new registers get created before we allocate the maps. */ - arg_vals = (rtx *) xmalloc (nargs * sizeof (rtx)); - arg_trees = (tree *) xmalloc (nargs * sizeof (tree)); + arg_vals = xmalloc (nargs * sizeof (rtx)); + arg_trees = xmalloc (nargs * sizeof (tree)); for (formal = DECL_ARGUMENTS (fndecl), actual = parms, i = 0; formal; @@ -788,7 +771,7 @@ expand_inline_function (fndecl, parms, target, ignore, type, abort (); /* The mode if LOC and ARG can differ if LOC was a variable - that had its mode promoted via PROMOTED_MODE. */ + that had its mode promoted. */ arg_vals[i] = convert_modes (pmode, TYPE_MODE (TREE_TYPE (arg)), expand_expr (arg, NULL_RTX, mode, @@ -801,6 +784,14 @@ expand_inline_function (fndecl, parms, target, ignore, type, else arg_vals[i] = 0; + /* If the formal type was const but the actual was not, we might + end up here with an rtx wrongly tagged unchanging in the caller's + context. Fix that. */ + if (arg_vals[i] != 0 + && (GET_CODE (arg_vals[i]) == REG || GET_CODE (arg_vals[i]) == MEM) + && ! TREE_READONLY (TREE_VALUE (actual))) + RTX_UNCHANGING_P (arg_vals[i]) = 0; + if (arg_vals[i] != 0 && (! TREE_READONLY (formal) /* If the parameter is not read-only, copy our argument through @@ -832,22 +823,21 @@ expand_inline_function (fndecl, parms, target, ignore, type, /* Allocate the structures we use to remap things. */ - map = (struct inline_remap *) xcalloc (1, sizeof (struct inline_remap)); + map = xcalloc (1, sizeof (struct inline_remap)); map->fndecl = fndecl; VARRAY_TREE_INIT (map->block_map, 10, "block_map"); - map->reg_map = (rtx *) xcalloc (max_regno, sizeof (rtx)); + map->reg_map = xcalloc (max_regno, sizeof (rtx)); /* We used to use alloca here, but the size of what it would try to allocate would occasionally cause it to exceed the stack limit and cause unpredictable core dumps. */ - real_label_map - = (rtx *) xmalloc ((max_labelno) * sizeof (rtx)); + real_label_map = xmalloc ((max_labelno) * sizeof (rtx)); map->label_map = real_label_map; map->local_return_label = NULL_RTX; inl_max_uid = (inl_f->emit->x_cur_insn_uid + 1); - map->insn_map = (rtx *) xcalloc (inl_max_uid, sizeof (rtx)); + map->insn_map = xcalloc (inl_max_uid, sizeof (rtx)); map->min_insnno = 0; map->max_insnno = inl_max_uid; @@ -881,7 +871,7 @@ expand_inline_function (fndecl, parms, target, ignore, type, insn that can be used as an insertion point. */ map->insns_at_start = get_last_insn (); if (map->insns_at_start == 0) - map->insns_at_start = emit_note (NULL, NOTE_INSN_DELETED); + map->insns_at_start = emit_note (NOTE_INSN_DELETED); map->regno_pointer_align = inl_f->emit->regno_pointer_align; map->x_regno_reg_rtx = inl_f->emit->x_regno_reg_rtx; @@ -900,11 +890,16 @@ expand_inline_function (fndecl, parms, target, ignore, type, if (inl_f->needs_context) static_chain_value = lookup_static_chain (fndecl); + /* If the inlined function calls __builtin_constant_p, then we'll + need to call purge_builtin_constant_p on this function. */ + if (inl_f->calls_constant_p) + current_function_calls_constant_p = 1; + if (GET_CODE (parm_insns) == NOTE && NOTE_LINE_NUMBER (parm_insns) > 0) { - rtx note = emit_note (NOTE_SOURCE_FILE (parm_insns), - NOTE_LINE_NUMBER (parm_insns)); + rtx note = emit_note_copy (parm_insns); + if (note) RTX_INTEGRATED_P (note) = 1; } @@ -995,8 +990,8 @@ expand_inline_function (fndecl, parms, target, ignore, type, && ! (GET_CODE (XEXP (loc, 0)) == REG && REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER)) { - rtx note = emit_note (DECL_SOURCE_FILE (formal), - DECL_SOURCE_LINE (formal)); + rtx note = emit_line_note (DECL_SOURCE_LOCATION (formal)); + if (note) RTX_INTEGRATED_P (note) = 1; @@ -1018,7 +1013,7 @@ expand_inline_function (fndecl, parms, target, ignore, type, REG_FUNCTION_RETURN_VALUE_P. */ map->inline_target = 0; - loc = (DECL_RTL_SET_P (DECL_RESULT (fndecl)) + loc = (DECL_RTL_SET_P (DECL_RESULT (fndecl)) ? DECL_RTL (DECL_RESULT (fndecl)) : NULL_RTX); if (TYPE_MODE (type) == VOIDmode) @@ -1036,7 +1031,7 @@ expand_inline_function (fndecl, parms, target, ignore, type, else { if (! structure_value_addr - || ! aggregate_value_p (DECL_RESULT (fndecl))) + || ! aggregate_value_p (DECL_RESULT (fndecl), fndecl)) abort (); /* Pass the function the address in which to return a structure @@ -1192,8 +1187,8 @@ expand_inline_function (fndecl, parms, target, ignore, type, /* Initialize label_map. get_label_from_map will actually make the labels. */ - memset ((char *) &map->label_map[min_labelno], 0, - (max_labelno - min_labelno) * sizeof (rtx)); + memset (&map->label_map[min_labelno], 0, + (max_labelno - min_labelno) * sizeof (rtx)); /* Make copies of the decls of the symbols in the inline function, so that the copies of the variables get declared in the current function. Set @@ -1283,15 +1278,15 @@ expand_inline_function (fndecl, parms, target, ignore, type, This line number note is still needed for debugging though, so we can't delete it. */ if (flag_test_coverage) - emit_note (0, NOTE_INSN_REPEATED_LINE_NUMBER); + emit_note (NOTE_INSN_REPEATED_LINE_NUMBER); - emit_line_note (input_filename, lineno); + emit_line_note (input_location); /* If the function returns a BLKmode object in a register, copy it out of the temp register into a BLKmode memory object. */ if (target && TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl))) == BLKmode - && ! aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)))) + && ! aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)), fndecl)) target = copy_blkmode_from_reg (0, target, TREE_TYPE (TREE_TYPE (fndecl))); if (structure_value_addr) @@ -1327,10 +1322,7 @@ expand_inline_function (fndecl, parms, target, ignore, type, register for the function. */ static void -copy_insn_list (insns, map, static_chain_value) - rtx insns; - struct inline_remap *map; - rtx static_chain_value; +copy_insn_list (rtx insns, struct inline_remap *map, rtx static_chain_value) { int i; rtx insn; @@ -1429,7 +1421,7 @@ copy_insn_list (insns, map, static_chain_value) gen_rtx_MEM (GET_MODE (static_chain_incoming_rtx), SET_DEST (set)); - /* emit the instruction in case it is used for something + /* Emit the instruction in case it is used for something other than setting the static chain; if it's not used, it can always be removed as dead code */ copy = emit_insn (copy_rtx_and_substitute (pattern, map, 0)); @@ -1524,7 +1516,7 @@ copy_insn_list (insns, map, static_chain_value) #else try_constants (copy, map); #endif - INSN_SCOPE (copy) = INSN_SCOPE (insn); + INSN_LOCATOR (copy) = INSN_LOCATOR (insn); break; case JUMP_INSN: @@ -1545,7 +1537,7 @@ copy_insn_list (insns, map, static_chain_value) cc0_insn = 0; #endif try_constants (copy, map); - INSN_SCOPE (copy) = INSN_SCOPE (insn); + INSN_LOCATOR (copy) = INSN_LOCATOR (insn); /* If this used to be a conditional jump insn but whose branch direction is now know, we must do something special. */ @@ -1613,7 +1605,7 @@ copy_insn_list (insns, map, static_chain_value) SIBLING_CALL_P (copy) = SIBLING_CALL_P (insn); CONST_OR_PURE_CALL_P (copy) = CONST_OR_PURE_CALL_P (insn); - INSN_SCOPE (copy) = INSN_SCOPE (insn); + INSN_LOCATOR (copy) = INSN_LOCATOR (insn); /* Because the USAGE information potentially contains objects other than hard registers, we need to copy it. */ @@ -1665,12 +1657,12 @@ copy_insn_list (insns, map, static_chain_value) && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_BEG && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED) { - copy = emit_note (NOTE_SOURCE_FILE (insn), - NOTE_LINE_NUMBER (insn)); - if (copy - && (NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_BEG - || NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_END) - && NOTE_BLOCK (insn)) + copy = emit_note_copy (insn); + if (!copy) + /*Copied a line note, but line numbering is off*/; + else if ((NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_BEG + || NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_END) + && NOTE_BLOCK (insn)) { tree *mapped_block_p; @@ -1686,8 +1678,7 @@ copy_insn_list (insns, map, static_chain_value) else NOTE_BLOCK (copy) = *mapped_block_p; } - else if (copy - && NOTE_LINE_NUMBER (copy) == NOTE_INSN_EXPECTED_VALUE) + else if (NOTE_LINE_NUMBER (copy) == NOTE_INSN_EXPECTED_VALUE) NOTE_EXPECTED_VALUE (copy) = copy_rtx_and_substitute (NOTE_EXPECTED_VALUE (insn), map, 0); @@ -1712,10 +1703,7 @@ copy_insn_list (insns, map, static_chain_value) that are valid across the entire function. */ static void -copy_insn_notes (insns, map, eh_region_offset) - rtx insns; - struct inline_remap *map; - int eh_region_offset; +copy_insn_notes (rtx insns, struct inline_remap *map, int eh_region_offset) { rtx insn, new_insn; @@ -1771,10 +1759,7 @@ copy_insn_notes (insns, map, eh_region_offset) push all of those decls and give each one the corresponding home. */ static void -integrate_parm_decls (args, map, arg_vector) - tree args; - struct inline_remap *map; - rtvec arg_vector; +integrate_parm_decls (tree args, struct inline_remap *map, rtvec arg_vector) { tree tail; int i; @@ -1807,9 +1792,7 @@ integrate_parm_decls (args, map, arg_vector) no mapping is necessary. */ static tree -integrate_decl_tree (let, map) - tree let; - struct inline_remap *map; +integrate_decl_tree (tree let, struct inline_remap *map) { tree t; tree new_block; @@ -1839,14 +1822,6 @@ integrate_decl_tree (let, map) subst_constants (&r, NULL_RTX, map, 1); SET_DECL_RTL (d, r); - if (GET_CODE (r) == REG) - REGNO_DECL (REGNO (r)) = d; - else if (GET_CODE (r) == CONCAT) - { - REGNO_DECL (REGNO (XEXP (r, 0))) = d; - REGNO_DECL (REGNO (XEXP (r, 1))) = d; - } - apply_change_group (); } @@ -1886,10 +1861,7 @@ integrate_decl_tree (let, map) calling `force_const_mem'. */ rtx -copy_rtx_and_substitute (orig, map, for_lhs) - rtx orig; - struct inline_remap *map; - int for_lhs; +copy_rtx_and_substitute (rtx orig, struct inline_remap *map, int for_lhs) { rtx copy, temp; int i, j; @@ -2038,7 +2010,7 @@ copy_rtx_and_substitute (orig, map, for_lhs) { if (!map->leaf_reg_map[regno][mode]) map->leaf_reg_map[regno][mode] = gen_rtx_REG (mode, regno); - return map->leaf_reg_map[regno][mode]; + return map->leaf_reg_map[regno][mode]; } #endif else @@ -2118,7 +2090,7 @@ copy_rtx_and_substitute (orig, map, for_lhs) if (NOTE_LINE_NUMBER (orig) != NOTE_INSN_DELETED_LABEL) break; - /* ... FALLTHRU ... */ + /* Fall through. */ case CODE_LABEL: LABEL_PRESERVE_P (get_label_from_map (map, CODE_LABEL_NUMBER (orig))) = LABEL_PRESERVE_P (orig); @@ -2188,11 +2160,7 @@ copy_rtx_and_substitute (orig, map, for_lhs) #endif temp = XEXP (temp, 0); - -#ifdef POINTERS_EXTEND_UNSIGNED - if (GET_MODE (temp) != GET_MODE (orig)) - temp = convert_memory_address (GET_MODE (orig), temp); -#endif + temp = convert_memory_address (GET_MODE (orig), temp); return temp; } else if (GET_CODE (constant) == LABEL_REF) @@ -2201,6 +2169,8 @@ copy_rtx_and_substitute (orig, map, for_lhs) copy_rtx_and_substitute (constant, map, for_lhs)), 0); } + else if (TREE_CONSTANT_POOL_ADDRESS_P (orig) && inlining) + notice_rtl_inlining_of_deferred_constant (); return orig; @@ -2266,7 +2236,7 @@ copy_rtx_and_substitute (orig, map, for_lhs) MEM_COPY_ATTRIBUTES (copy, XEXP (orig, 0)); return - gen_rtx_CALL (GET_MODE (orig), copy, + gen_rtx_CALL (GET_MODE (orig), copy, copy_rtx_and_substitute (XEXP (orig, 1), map, 0)); } break; @@ -2371,8 +2341,7 @@ copy_rtx_and_substitute (orig, map, for_lhs) switch (*format_ptr++) { case '0': - /* Copy this through the wide int field; that's safest. */ - X0WINT (copy, i) = X0WINT (orig, i); + X0ANY (copy, i) = X0ANY (orig, i); break; case 'e': @@ -2433,9 +2402,7 @@ copy_rtx_and_substitute (orig, map, for_lhs) /* Substitute known constant values into INSN, if that is valid. */ void -try_constants (insn, map) - rtx insn; - struct inline_remap *map; +try_constants (rtx insn, struct inline_remap *map) { int i; @@ -2450,6 +2417,14 @@ try_constants (insn, map) subst_constants (&PATTERN (insn), insn, map, 0); apply_change_group (); + /* Enforce consistency between the addresses in the regular insn flow + and the ones in CALL_INSN_FUNCTION_USAGE lists, if any. */ + if (GET_CODE (insn) == CALL_INSN && CALL_INSN_FUNCTION_USAGE (insn)) + { + subst_constants (&CALL_INSN_FUNCTION_USAGE (insn), insn, map, 1); + apply_change_group (); + } + /* Show we don't know the value of anything stored or clobbered. */ note_stores (PATTERN (insn), mark_stores, NULL); map->last_pc_value = 0; @@ -2499,11 +2474,7 @@ try_constants (insn, map) If MEMONLY is nonzero, only make changes inside a MEM. */ static void -subst_constants (loc, insn, map, memonly) - rtx *loc; - rtx insn; - struct inline_remap *map; - int memonly; +subst_constants (rtx *loc, rtx insn, struct inline_remap *map, int memonly) { rtx x = *loc; int i, j; @@ -2577,7 +2548,7 @@ subst_constants (loc, insn, map, memonly) integral mode and extracting the low part. */ subst_constants (&inner, NULL_RTX, map, 0); new = simplify_gen_subreg (GET_MODE (x), inner, - GET_MODE (SUBREG_REG (x)), + GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x)); if (new) @@ -2615,10 +2586,7 @@ subst_constants (loc, insn, map, memonly) { src = SET_SRC (x); if (GET_MODE_CLASS (GET_MODE (src)) == MODE_CC -#ifdef HAVE_cc0 - || dest == cc0_rtx -#endif - ) + || CC0_P (dest)) { compare_mode = GET_MODE (XEXP (src, 0)); if (compare_mode == VOIDmode) @@ -2670,9 +2638,7 @@ subst_constants (loc, insn, map, memonly) || REGNO (XEXP (src, 0)) == VIRTUAL_STACK_VARS_REGNUM) && CONSTANT_P (XEXP (src, 1))) || GET_CODE (src) == COMPARE -#ifdef HAVE_cc0 - || dest == cc0_rtx -#endif + || CC0_P (dest) || (dest == pc_rtx && (src == pc_rtx || GET_CODE (src) == RETURN || GET_CODE (src) == LABEL_REF)))) @@ -2686,10 +2652,7 @@ subst_constants (loc, insn, map, memonly) if (compare_mode != VOIDmode && GET_CODE (src) == COMPARE && (GET_MODE_CLASS (GET_MODE (src)) == MODE_CC -#ifdef HAVE_cc0 - || dest == cc0_rtx -#endif - ) + || CC0_P (dest)) && GET_MODE (XEXP (src, 0)) == VOIDmode && GET_MODE (XEXP (src, 1)) == VOIDmode) { @@ -2842,10 +2805,7 @@ subst_constants (loc, insn, map, memonly) called from note_stores with parts of the new insn. */ static void -mark_stores (dest, x, data) - rtx dest; - rtx x ATTRIBUTE_UNUSED; - void *data ATTRIBUTE_UNUSED; +mark_stores (rtx dest, rtx x ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED) { int regno = -1; enum machine_mode mode = VOIDmode; @@ -2894,8 +2854,7 @@ mark_stores (dest, x, data) values to point to themselves. */ static void -set_block_origin_self (stmt) - tree stmt; +set_block_origin_self (tree stmt) { if (BLOCK_ABSTRACT_ORIGIN (stmt) == NULL_TREE) { @@ -2933,8 +2892,7 @@ set_block_origin_self (stmt) point to themselves. */ void -set_decl_origin_self (decl) - tree decl; +set_decl_origin_self (tree decl) { if (DECL_ABSTRACT_ORIGIN (decl) == NULL_TREE) { @@ -2958,9 +2916,7 @@ set_decl_origin_self (decl) (recursively) which are contained therein. */ static void -set_block_abstract_flags (stmt, setting) - tree stmt; - int setting; +set_block_abstract_flags (tree stmt, int setting) { tree local_decl; tree subblock; @@ -2985,9 +2941,7 @@ set_block_abstract_flags (stmt, setting) blocks and sub-blocks (recursively) to the same setting. */ void -set_decl_abstract_flags (decl, setting) - tree decl; - int setting; +set_decl_abstract_flags (tree decl, int setting) { DECL_ABSTRACT (decl) = setting; if (TREE_CODE (decl) == FUNCTION_DECL) @@ -3009,8 +2963,7 @@ set_decl_abstract_flags (decl, setting) static GTY(()) struct function *old_cfun; void -output_inline_function (fndecl) - tree fndecl; +output_inline_function (tree fndecl) { enum debug_info_type old_write_symbols = write_symbols; const struct gcc_debug_hooks *const old_debug_hooks = debug_hooks; @@ -3034,8 +2987,7 @@ output_inline_function (fndecl) /* Make sure warnings emitted by the optimizers (e.g. control reaches end of non-void function) is not wildly incorrect. */ - input_filename = DECL_SOURCE_FILE (fndecl); - lineno = DECL_SOURCE_LINE (fndecl); + input_location = DECL_SOURCE_LOCATION (fndecl); /* Compile this function all the way down to assembly code. As a side effect this destroys the saved RTL representation, but @@ -3054,9 +3006,7 @@ output_inline_function (fndecl) the function. */ rtx -get_hard_reg_initial_reg (fun, reg) - struct function *fun; - rtx reg; +get_hard_reg_initial_reg (struct function *fun, rtx reg) { struct initial_value_struct *ivs = fun->hard_reg_initial_vals; int i; @@ -3072,9 +3022,7 @@ get_hard_reg_initial_reg (fun, reg) } rtx -has_func_hard_reg_initial_val (fun, reg) - struct function *fun; - rtx reg; +has_func_hard_reg_initial_val (struct function *fun, rtx reg) { struct initial_value_struct *ivs = fun->hard_reg_initial_vals; int i; @@ -3090,9 +3038,7 @@ has_func_hard_reg_initial_val (fun, reg) } rtx -get_func_hard_reg_initial_val (fun, reg) - struct function *fun; - rtx reg; +get_func_hard_reg_initial_val (struct function *fun, rtx reg) { struct initial_value_struct *ivs = fun->hard_reg_initial_vals; rtx rv = has_func_hard_reg_initial_val (fun, reg); @@ -3102,20 +3048,19 @@ get_func_hard_reg_initial_val (fun, reg) if (ivs == 0) { - fun->hard_reg_initial_vals = (void *) ggc_alloc (sizeof (initial_value_struct)); + fun->hard_reg_initial_vals = ggc_alloc (sizeof (initial_value_struct)); ivs = fun->hard_reg_initial_vals; ivs->num_entries = 0; ivs->max_entries = 5; - ivs->entries = (initial_value_pair *) ggc_alloc (5 * sizeof (initial_value_pair)); + ivs->entries = ggc_alloc (5 * sizeof (initial_value_pair)); } if (ivs->num_entries >= ivs->max_entries) { ivs->max_entries += 5; - ivs->entries = - (initial_value_pair *) ggc_realloc (ivs->entries, - ivs->max_entries - * sizeof (initial_value_pair)); + ivs->entries = ggc_realloc (ivs->entries, + ivs->max_entries + * sizeof (initial_value_pair)); } ivs->entries[ivs->num_entries].hard_reg = reg; @@ -3125,25 +3070,19 @@ get_func_hard_reg_initial_val (fun, reg) } rtx -get_hard_reg_initial_val (mode, regno) - enum machine_mode mode; - int regno; +get_hard_reg_initial_val (enum machine_mode mode, int regno) { return get_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno)); } rtx -has_hard_reg_initial_val (mode, regno) - enum machine_mode mode; - int regno; +has_hard_reg_initial_val (enum machine_mode mode, int regno) { return has_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno)); } static void -setup_initial_hard_reg_value_integration (inl_f, remap) - struct function *inl_f; - struct inline_remap *remap; +setup_initial_hard_reg_value_integration (struct function *inl_f, struct inline_remap *remap) { struct initial_value_struct *ivs = inl_f->hard_reg_initial_vals; int i; @@ -3158,7 +3097,7 @@ setup_initial_hard_reg_value_integration (inl_f, remap) void -emit_initial_value_sets () +emit_initial_value_sets (void) { struct initial_value_struct *ivs = cfun->hard_reg_initial_vals; int i; @@ -3179,8 +3118,7 @@ emit_initial_value_sets () /* If the backend knows where to allocate pseudos for hard register initial values, register these allocations now. */ void -allocate_initial_values (reg_equiv_memory_loc) - rtx *reg_equiv_memory_loc ATTRIBUTE_UNUSED; +allocate_initial_values (rtx *reg_equiv_memory_loc ATTRIBUTE_UNUSED) { #ifdef ALLOCATE_INITIAL_VALUE struct initial_value_struct *ivs = cfun->hard_reg_initial_vals; |