#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "toplev.h"
+#include "toplev.h" /* floor_log2 */
+#include "diagnostic-core.h"
#include "tree.h"
#include "tree-inline.h"
#include "flags.h"
/* Prototypes. */
-static tree declare_return_variable (copy_body_data *, tree, tree);
+static tree declare_return_variable (copy_body_data *, tree, tree, basic_block);
static void remap_block (tree *, copy_body_data *);
static void copy_bind_expr (tree *, int *, copy_body_data *);
static tree mark_local_for_remap_r (tree *, int *, void *);
{
tree f, nf = NULL;
- for (f = TYPE_FIELDS (new_tree); f ; f = TREE_CHAIN (f))
+ for (f = TYPE_FIELDS (new_tree); f ; f = DECL_CHAIN (f))
{
t = remap_decl (f, id);
DECL_CONTEXT (t) = new_tree;
- TREE_CHAIN (t) = nf;
+ DECL_CHAIN (t) = nf;
nf = t;
}
TYPE_FIELDS (new_tree) = nreverse (nf);
tree new_decls = NULL_TREE;
/* Remap its variables. */
- for (old_var = decls; old_var; old_var = TREE_CHAIN (old_var))
+ for (old_var = decls; old_var; old_var = DECL_CHAIN (old_var))
{
tree new_var;
if (TREE_CODE (old_var) == VAR_DECL
&& ! DECL_EXTERNAL (old_var)
&& (var_ann (old_var) || !gimple_in_ssa_p (cfun)))
- cfun->local_decls = tree_cons (NULL_TREE, old_var,
- cfun->local_decls);
+ add_local_decl (cfun, old_var);
if ((!optimize || debug_info_level > DINFO_LEVEL_TERSE)
&& !DECL_IGNORED_P (old_var)
&& nonlocalized_list)
else
{
gcc_assert (DECL_P (new_var));
- TREE_CHAIN (new_var) = new_decls;
+ DECL_CHAIN (new_var) = new_decls;
new_decls = new_var;
/* Also copy value-expressions. */
{
/* Otherwise, just copy the node. Note that copy_tree_r already
knows not to copy VAR_DECLs, etc., so this is safe. */
- if (TREE_CODE (*tp) == INDIRECT_REF)
+ if (TREE_CODE (*tp) == MEM_REF)
{
- /* Get rid of *& from inline substitutions that can happen when a
- pointer argument is an ADDR_EXPR. */
+ /* We need to re-canonicalize MEM_REFs from inline substitutions
+ that can happen when a pointer argument is an ADDR_EXPR. */
tree decl = TREE_OPERAND (*tp, 0);
tree *n;
+ /* See remap_ssa_name. */
+ if (TREE_CODE (decl) == SSA_NAME
+ && TREE_CODE (SSA_NAME_VAR (decl)) == RESULT_DECL
+ && id->transform_return_to_modify)
+ decl = SSA_NAME_VAR (decl);
+
n = (tree *) pointer_map_contains (id->decl_map, decl);
if (n)
{
- tree type, new_tree, old;
-
- /* If we happen to get an ADDR_EXPR in n->value, strip
- it manually here as we'll eventually get ADDR_EXPRs
- which lie about their types pointed to. In this case
- build_fold_indirect_ref wouldn't strip the
- INDIRECT_REF, but we absolutely rely on that. As
- fold_indirect_ref does other useful transformations,
- try that first, though. */
- type = TREE_TYPE (TREE_TYPE (*n));
- new_tree = unshare_expr (*n);
- old = *tp;
- *tp = gimple_fold_indirect_ref (new_tree);
- if (!*tp)
- {
- if (TREE_CODE (new_tree) == ADDR_EXPR)
- {
- *tp = fold_indirect_ref_1 (EXPR_LOCATION (new_tree),
- type, new_tree);
- /* ??? We should either assert here or build
- a VIEW_CONVERT_EXPR instead of blindly leaking
- incompatible types to our IL. */
- if (! *tp)
- *tp = TREE_OPERAND (new_tree, 0);
- }
- else
- {
- *tp = build1 (INDIRECT_REF, type, new_tree);
- TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
- TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
- }
+ tree old = *tp;
+ tree ptr = unshare_expr (*n);
+ tree tem;
+ if ((tem = maybe_fold_offset_to_reference (EXPR_LOCATION (*tp),
+ ptr,
+ TREE_OPERAND (*tp, 1),
+ TREE_TYPE (*tp)))
+ && TREE_THIS_VOLATILE (tem) == TREE_THIS_VOLATILE (old))
+ {
+ tree *tem_basep = &tem;
+ while (handled_component_p (*tem_basep))
+ tem_basep = &TREE_OPERAND (*tem_basep, 0);
+ if (TREE_CODE (*tem_basep) == MEM_REF)
+ *tem_basep
+ = build2 (MEM_REF, TREE_TYPE (*tem_basep),
+ TREE_OPERAND (*tem_basep, 0),
+ fold_convert (TREE_TYPE (TREE_OPERAND (*tp, 1)),
+ TREE_OPERAND (*tem_basep, 1)));
+ else
+ *tem_basep
+ = build2 (MEM_REF, TREE_TYPE (*tem_basep),
+ build_fold_addr_expr (*tem_basep),
+ build_int_cst
+ (TREE_TYPE (TREE_OPERAND (*tp, 1)), 0));
+ *tp = tem;
+ }
+ else
+ {
+ *tp = fold_build2 (MEM_REF, TREE_TYPE (*tp),
+ ptr, TREE_OPERAND (*tp, 1));
+ TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
}
+ TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
*walk_subtrees = 0;
return NULL;
}
else if (TREE_CODE (*tp) == ADDR_EXPR)
{
/* Variable substitution need not be simple. In particular,
- the INDIRECT_REF substitution above. Make sure that
+ the MEM_REF substitution above. Make sure that
TREE_CONSTANT and friends are up-to-date. But make sure
to not improperly set TREE_BLOCK on some sub-expressions. */
int invariant = is_gimple_min_invariant (*tp);
id->block = NULL_TREE;
walk_tree (&TREE_OPERAND (*tp, 0), remap_gimple_op_r, data, NULL);
id->block = block;
-
- /* Handle the case where we substituted an INDIRECT_REF
- into the operand of the ADDR_EXPR. */
- if (TREE_CODE (TREE_OPERAND (*tp, 0)) == INDIRECT_REF)
- *tp = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0);
- else
- recompute_tree_invariant_for_addr_expr (*tp);
+ recompute_tree_invariant_for_addr_expr (*tp);
/* If this used to be invariant, but is not any longer,
then regimplification is probably needed. */
return NULL;
}
}
+ else if (TREE_CODE (*tp) == MEM_REF)
+ {
+ /* We need to re-canonicalize MEM_REFs from inline substitutions
+ that can happen when a pointer argument is an ADDR_EXPR. */
+ tree decl = TREE_OPERAND (*tp, 0);
+ tree *n;
+
+ n = (tree *) pointer_map_contains (id->decl_map, decl);
+ if (n)
+ {
+ tree old = *tp;
+ *tp = fold_build2 (MEM_REF, TREE_TYPE (*tp),
+ unshare_expr (*n), TREE_OPERAND (*tp, 1));
+ TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
+ TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
+ *walk_subtrees = 0;
+ return NULL;
+ }
+ }
/* Here is the "usual case". Copy this tree node, and then
tweak some special cases. */
If RETVAL is just the result decl, the result decl has
already been set (e.g. a recent "foo (&result_decl, ...)");
just toss the entire GIMPLE_RETURN. */
- if (retval && TREE_CODE (retval) != RESULT_DECL)
+ if (retval
+ && (TREE_CODE (retval) != RESULT_DECL
+ && (TREE_CODE (retval) != SSA_NAME
+ || TREE_CODE (SSA_NAME_VAR (retval)) != RESULT_DECL)))
{
copy = gimple_build_assign (id->retvar, retval);
/* id->retvar is already substituted. Skip it on later remapping. */
size_t nargs = gimple_call_num_args (id->gimple_call);
size_t n;
- for (p = DECL_ARGUMENTS (id->src_fn); p; p = TREE_CHAIN (p))
+ for (p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p))
nargs--;
/* Create the new array of arguments. */
tree count, p;
gimple new_stmt;
- for (p = DECL_ARGUMENTS (id->src_fn); p; p = TREE_CHAIN (p))
+ for (p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p))
nargs--;
count = build_int_cst (integer_type_node, nargs);
if (!id->debug_stmts)
return;
- for (i = 0; VEC_iterate (gimple, id->debug_stmts, i, stmt); i++)
+ FOR_EACH_VEC_ELT (gimple, id->debug_stmts, i, stmt)
copy_debug_stmt (stmt, id);
VEC_free (gimple, heap, id->debug_stmts);
}
/* Declare this new variable. */
- TREE_CHAIN (var) = *vars;
+ DECL_CHAIN (var) = *vars;
*vars = var;
/* Make gimplifier happy about this variable. */
/* Loop through the parameter declarations, replacing each with an
equivalent VAR_DECL, appropriately initialized. */
- for (p = parms, i = 0; p; p = TREE_CHAIN (p), i++)
+ for (p = parms, i = 0; p; p = DECL_CHAIN (p), i++)
{
tree val;
val = i < gimple_call_num_args (stmt) ? gimple_call_arg (stmt, i) : NULL;
in a second loop over all parameters to appropriately remap
variable sized arrays when the size is specified in a
parameter following the array. */
- for (p = parms, i = 0; p; p = TREE_CHAIN (p), i++)
+ for (p = parms, i = 0; p; p = DECL_CHAIN (p), i++)
{
tree *varp = (tree *) pointer_map_contains (id->decl_map, p);
if (varp
&& TREE_CODE (*varp) == VAR_DECL)
{
- tree def = (gimple_in_ssa_p (cfun)
+ tree def = (gimple_in_ssa_p (cfun) && is_gimple_reg (p)
? gimple_default_def (id->src_cfun, p) : NULL);
- TREE_TYPE (*varp) = remap_type (TREE_TYPE (*varp), id);
+ tree var = *varp;
+ TREE_TYPE (var) = remap_type (TREE_TYPE (var), id);
/* Also remap the default definition if it was remapped
to the default definition of the parameter replacement
by the parameter setup. */
- if (def && gimple_in_ssa_p (cfun) && is_gimple_reg (p))
+ if (def)
{
tree *defp = (tree *) pointer_map_contains (id->decl_map, def);
if (defp
&& TREE_CODE (*defp) == SSA_NAME
- && SSA_NAME_VAR (*defp) == *varp)
- TREE_TYPE (*defp) = TREE_TYPE (*varp);
+ && SSA_NAME_VAR (*defp) == var)
+ TREE_TYPE (*defp) = TREE_TYPE (var);
}
}
}
as seen by the caller. */
static tree
-declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest)
+declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest,
+ basic_block entry_bb)
{
tree callee = id->src_fn;
tree caller = id->dst_fn;
}
DECL_SEEN_IN_BIND_EXPR_P (var) = 1;
- DECL_STRUCT_FUNCTION (caller)->local_decls
- = tree_cons (NULL_TREE, var,
- DECL_STRUCT_FUNCTION (caller)->local_decls);
+ add_local_decl (DECL_STRUCT_FUNCTION (caller), var);
/* Do not have the rest of GCC warn about this variable as it should
not be visible to the user. */
done:
/* Register the VAR_DECL as the equivalent for the RESULT_DECL; that
way, when the RESULT_DECL is encountered, it will be
- automatically replaced by the VAR_DECL. */
- insert_decl_map (id, result, var);
+ automatically replaced by the VAR_DECL.
+
+ When returning by reference, ensure that RESULT_DECL remaps to
+ gimple_val. */
+ if (DECL_BY_REFERENCE (result)
+ && !is_gimple_val (var))
+ {
+ tree temp = create_tmp_var (TREE_TYPE (result), "retvalptr");
+ if (gimple_in_ssa_p (id->src_cfun))
+ {
+ get_var_ann (temp);
+ add_referenced_var (temp);
+ }
+ insert_decl_map (id, result, temp);
+ /* When RESULT_DECL is in SSA form, we need to use it's default_def
+ SSA_NAME. */
+ if (gimple_in_ssa_p (id->src_cfun) && gimple_default_def (id->src_cfun, result))
+ temp = remap_ssa_name (gimple_default_def (id->src_cfun, result), id);
+ insert_init_stmt (id, entry_bb, gimple_build_assign (temp, var));
+ }
+ else
+ insert_decl_map (id, result, var);
/* Remember this so we can ignore it in remap_decls. */
id->retvar = var;
copy_forbidden (struct function *fun, tree fndecl)
{
const char *reason = fun->cannot_be_copied_reason;
- tree step;
+ tree decl;
+ unsigned ix;
/* Only examine the function once. */
if (fun->cannot_be_copied_set)
goto fail;
}
- for (step = fun->local_decls; step; step = TREE_CHAIN (step))
- {
- tree decl = TREE_VALUE (step);
-
- if (TREE_CODE (decl) == VAR_DECL
- && TREE_STATIC (decl)
- && !DECL_EXTERNAL (decl)
- && DECL_INITIAL (decl)
- && walk_tree_without_duplicates (&DECL_INITIAL (decl),
- has_label_address_in_static_1,
- fndecl))
- {
- reason = G_("function %q+F can never be copied because it saves "
- "address of local label in a static variable");
- goto fail;
- }
- }
+ FOR_EACH_LOCAL_DECL (fun, ix, decl)
+ if (TREE_CODE (decl) == VAR_DECL
+ && TREE_STATIC (decl)
+ && !DECL_EXTERNAL (decl)
+ && DECL_INITIAL (decl)
+ && walk_tree_without_duplicates (&DECL_INITIAL (decl),
+ has_label_address_in_static_1,
+ fndecl))
+ {
+ reason = G_("function %q+F can never be copied because it saves "
+ "address of local label in a static variable");
+ goto fail;
+ }
fail:
fun->cannot_be_copied_reason = reason;
if (POINTER_TYPE_P (funtype))
funtype = TREE_TYPE (funtype);
- if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_MD)
+ if (is_simple_builtin (decl))
+ return 0;
+ else if (is_inexpensive_builtin (decl))
cost = weights->target_builtin_call_cost;
else
cost = weights->call_cost;
- if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
- switch (DECL_FUNCTION_CODE (decl))
- {
- /* Builtins that expand to constants. */
- case BUILT_IN_CONSTANT_P:
- case BUILT_IN_EXPECT:
- case BUILT_IN_OBJECT_SIZE:
- case BUILT_IN_UNREACHABLE:
- /* Simple register moves or loads from stack. */
- case BUILT_IN_RETURN_ADDRESS:
- case BUILT_IN_EXTRACT_RETURN_ADDR:
- case BUILT_IN_FROB_RETURN_ADDR:
- case BUILT_IN_RETURN:
- case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
- case BUILT_IN_FRAME_ADDRESS:
- case BUILT_IN_VA_END:
- case BUILT_IN_STACK_SAVE:
- case BUILT_IN_STACK_RESTORE:
- /* Exception state returns or moves registers around. */
- case BUILT_IN_EH_FILTER:
- case BUILT_IN_EH_POINTER:
- case BUILT_IN_EH_COPY_VALUES:
- return 0;
-
- /* builtins that are not expensive (that is they are most probably
- expanded inline into resonably simple code). */
- case BUILT_IN_ABS:
- case BUILT_IN_ALLOCA:
- case BUILT_IN_BSWAP32:
- case BUILT_IN_BSWAP64:
- case BUILT_IN_CLZ:
- case BUILT_IN_CLZIMAX:
- case BUILT_IN_CLZL:
- case BUILT_IN_CLZLL:
- case BUILT_IN_CTZ:
- case BUILT_IN_CTZIMAX:
- case BUILT_IN_CTZL:
- case BUILT_IN_CTZLL:
- case BUILT_IN_FFS:
- case BUILT_IN_FFSIMAX:
- case BUILT_IN_FFSL:
- case BUILT_IN_FFSLL:
- case BUILT_IN_IMAXABS:
- case BUILT_IN_FINITE:
- case BUILT_IN_FINITEF:
- case BUILT_IN_FINITEL:
- case BUILT_IN_FINITED32:
- case BUILT_IN_FINITED64:
- case BUILT_IN_FINITED128:
- case BUILT_IN_FPCLASSIFY:
- case BUILT_IN_ISFINITE:
- case BUILT_IN_ISINF_SIGN:
- case BUILT_IN_ISINF:
- case BUILT_IN_ISINFF:
- case BUILT_IN_ISINFL:
- case BUILT_IN_ISINFD32:
- case BUILT_IN_ISINFD64:
- case BUILT_IN_ISINFD128:
- case BUILT_IN_ISNAN:
- case BUILT_IN_ISNANF:
- case BUILT_IN_ISNANL:
- case BUILT_IN_ISNAND32:
- case BUILT_IN_ISNAND64:
- case BUILT_IN_ISNAND128:
- case BUILT_IN_ISNORMAL:
- case BUILT_IN_ISGREATER:
- case BUILT_IN_ISGREATEREQUAL:
- case BUILT_IN_ISLESS:
- case BUILT_IN_ISLESSEQUAL:
- case BUILT_IN_ISLESSGREATER:
- case BUILT_IN_ISUNORDERED:
- case BUILT_IN_VA_ARG_PACK:
- case BUILT_IN_VA_ARG_PACK_LEN:
- case BUILT_IN_VA_COPY:
- case BUILT_IN_TRAP:
- case BUILT_IN_SAVEREGS:
- case BUILT_IN_POPCOUNTL:
- case BUILT_IN_POPCOUNTLL:
- case BUILT_IN_POPCOUNTIMAX:
- case BUILT_IN_POPCOUNT:
- case BUILT_IN_PARITYL:
- case BUILT_IN_PARITYLL:
- case BUILT_IN_PARITYIMAX:
- case BUILT_IN_PARITY:
- case BUILT_IN_LABS:
- case BUILT_IN_LLABS:
- case BUILT_IN_PREFETCH:
- cost = weights->target_builtin_call_cost;
- break;
-
- default:
- break;
- }
-
if (decl)
funtype = TREE_TYPE (decl);
if (decl && DECL_ARGUMENTS (decl) && !stdarg)
{
tree arg;
- for (arg = DECL_ARGUMENTS (decl); arg; arg = TREE_CHAIN (arg))
+ for (arg = DECL_ARGUMENTS (decl); arg; arg = DECL_CHAIN (arg))
if (!VOID_TYPE_P (TREE_TYPE (arg)))
cost += estimate_move_cost (TREE_TYPE (arg));
}
BLOCK_SUPERCONTEXT (new_block) = current_block;
}
-/* Fetch callee declaration from the call graph edge going from NODE and
- associated with STMR call statement. Return NULL_TREE if not found. */
-static tree
-get_indirect_callee_fndecl (struct cgraph_node *node, gimple stmt)
+/* Add local variables from CALLEE to CALLER. */
+
+static inline void
+add_local_variables (struct function *callee, struct function *caller,
+ copy_body_data *id, bool check_var_ann)
{
- struct cgraph_edge *cs;
+ tree var;
+ unsigned ix;
- cs = cgraph_edge (node, stmt);
- if (cs && !cs->indirect_unknown_callee)
- return cs->callee->decl;
+ FOR_EACH_LOCAL_DECL (callee, ix, var)
+ if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var))
+ {
+ if (!check_var_ann
+ || (var_ann (var) && add_referenced_var (var)))
+ add_local_decl (caller, var);
+ }
+ else if (!can_be_nonlocal (var, id))
+ {
+ tree new_var = remap_decl (var, id);
- return NULL_TREE;
+ /* Remap debug-expressions. */
+ if (TREE_CODE (new_var) == VAR_DECL
+ && DECL_DEBUG_EXPR_IS_FROM (new_var)
+ && new_var != var)
+ {
+ tree tem = DECL_DEBUG_EXPR (var);
+ bool old_regimplify = id->regimplify;
+ id->remapping_type_depth++;
+ walk_tree (&tem, copy_tree_body_r, id, NULL);
+ id->remapping_type_depth--;
+ id->regimplify = old_regimplify;
+ SET_DECL_DEBUG_EXPR (new_var, tem);
+ }
+ add_local_decl (caller, new_var);
+ }
}
/* If STMT is a GIMPLE_CALL, replace it with its inline expansion. */
gimple_stmt_iterator gsi, stmt_gsi;
bool successfully_inlined = FALSE;
bool purge_dead_abnormal_edges;
- tree t_step;
- tree var;
/* Set input_location here so we get the right instantiation context
if we call instantiate_decl from inlinable_function_p. */
If we cannot, then there is no hope of inlining the function. */
fn = gimple_call_fndecl (stmt);
if (!fn)
- {
- fn = get_indirect_callee_fndecl (id->dst_node, stmt);
- if (!fn)
- goto egress;
- }
+ goto egress;
/* Turn forward declarations into real ones. */
fn = cgraph_node (fn)->decl;
}
/* Declare the return variable for the function. */
- use_retvar = declare_return_variable (id, return_slot, modify_dest);
+ use_retvar = declare_return_variable (id, return_slot, modify_dest, bb);
/* Add local vars in this inlined callee to caller. */
- t_step = id->src_cfun->local_decls;
- for (; t_step; t_step = TREE_CHAIN (t_step))
- {
- var = TREE_VALUE (t_step);
- if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var))
- {
- if (var_ann (var) && add_referenced_var (var))
- cfun->local_decls = tree_cons (NULL_TREE, var,
- cfun->local_decls);
- }
- else if (!can_be_nonlocal (var, id))
- cfun->local_decls = tree_cons (NULL_TREE, remap_decl (var, id),
- cfun->local_decls);
- }
+ add_local_variables (id->src_cfun, cfun, id, true);
if (dump_file && (dump_flags & TDF_DETAILS))
{
declare_inline_vars (tree block, tree vars)
{
tree t;
- for (t = vars; t; t = TREE_CHAIN (t))
+ for (t = vars; t; t = DECL_CHAIN (t))
{
DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
gcc_assert (!TREE_STATIC (t) && !TREE_ASM_WRITTEN (t));
- cfun->local_decls = tree_cons (NULL_TREE, t, cfun->local_decls);
+ add_local_decl (cfun, t);
}
if (block)
parg = &new_parm;
- for (arg = orig_parm; arg; arg = TREE_CHAIN (arg), i++)
+ for (arg = orig_parm; arg; arg = DECL_CHAIN (arg), i++)
if (!args_to_skip || !bitmap_bit_p (args_to_skip, i))
{
tree new_tree = remap_decl (arg, id);
lang_hooks.dup_lang_specific_decl (new_tree);
*parg = new_tree;
- parg = &TREE_CHAIN (new_tree);
+ parg = &DECL_CHAIN (new_tree);
}
else if (!pointer_map_contains (id->decl_map, arg))
{
add_referenced_var (var);
insert_decl_map (id, arg, var);
/* Declare this new variable. */
- TREE_CHAIN (var) = *vars;
+ DECL_CHAIN (var) = *vars;
*vars = var;
}
return new_parm;
tree *chain_copy, *pvar;
chain_copy = &static_chain;
- for (pvar = chain_copy; *pvar; pvar = &TREE_CHAIN (*pvar))
+ for (pvar = chain_copy; *pvar; pvar = &DECL_CHAIN (*pvar))
{
tree new_tree = remap_decl (*pvar, id);
lang_hooks.dup_lang_specific_decl (new_tree);
- TREE_CHAIN (new_tree) = TREE_CHAIN (*pvar);
+ DECL_CHAIN (new_tree) = DECL_CHAIN (*pvar);
*pvar = new_tree;
}
return static_chain;
basic_block old_entry_block, bb;
VEC (gimple, heap) *init_stmts = VEC_alloc (gimple, heap, 10);
- tree t_step;
tree old_current_function_decl = current_function_decl;
tree vars = NULL_TREE;
{
int i = replace_info->parm_num;
tree parm;
- for (parm = DECL_ARGUMENTS (old_decl); i; parm = TREE_CHAIN (parm))
+ for (parm = DECL_ARGUMENTS (old_decl); i; parm = DECL_CHAIN (parm))
i --;
replace_info->old_tree = parm;
}
declare_inline_vars (DECL_INITIAL (new_decl), vars);
- if (DECL_STRUCT_FUNCTION (old_decl)->local_decls != NULL_TREE)
+ if (!VEC_empty (tree, DECL_STRUCT_FUNCTION (old_decl)->local_decls))
/* Add local vars. */
- for (t_step = DECL_STRUCT_FUNCTION (old_decl)->local_decls;
- t_step; t_step = TREE_CHAIN (t_step))
- {
- tree var = TREE_VALUE (t_step);
- if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var))
- cfun->local_decls = tree_cons (NULL_TREE, var, cfun->local_decls);
- else if (!can_be_nonlocal (var, &id))
- cfun->local_decls =
- tree_cons (NULL_TREE, remap_decl (var, &id),
- cfun->local_decls);
- }
+ add_local_variables (DECL_STRUCT_FUNCTION (old_decl), cfun, &id, false);
/* Copy the Function's body. */
copy_body (&id, old_entry_block->count, REG_BR_PROB_BASE,
for (e = new_version_node->callees; e; e = e->next_callee)
{
basic_block bb = gimple_bb (e->call_stmt);
- e->frequency = compute_call_stmt_bb_frequency (current_function_decl, bb);
+ e->frequency = compute_call_stmt_bb_frequency (current_function_decl,
+ bb);
+ e->count = bb->count;
+ }
+ for (e = new_version_node->indirect_calls; e; e = e->next_callee)
+ {
+ basic_block bb = gimple_bb (e->call_stmt);
+ e->frequency = compute_call_stmt_bb_frequency (current_function_decl,
+ bb);
e->count = bb->count;
}
}
/* Remap the parameters. */
for (param = DECL_ARGUMENTS (fn), arg = first_call_expr_arg (exp, &iter);
param;
- param = TREE_CHAIN (param), arg = next_call_expr_arg (&iter))
+ param = DECL_CHAIN (param), arg = next_call_expr_arg (&iter))
*pointer_map_insert (decl_map, param) = arg;
memset (&id, 0, sizeof (id));