X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree-inline.c;h=b34844d82f3945f7cb3537046c1ad9eaa32795c5;hb=e84a95efdd5bd8bffb3654c5f7a2d60b34b4bb88;hp=edd5faece9536bb45d535794b4b14089c897dd1e;hpb=80f0648113a67e5f40ab1c19bed50d37262dbfdf;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index edd5faece95..b34844d82f3 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -154,7 +154,7 @@ insert_decl_map (inline_data *id, tree key, tree value) (splay_tree_value) value); } -/* Remap DECL during the copying of the BLOCK tree for the function. +/* Remap DECL during the copying of the BLOCK tree for the function. We are only called to remap local variables in the current function. */ static tree @@ -243,7 +243,7 @@ remap_type (tree type, inline_data *id) insert_decl_map (id, type, type); return type; } - + /* We do need a copy. build and register it now. If this is a pointer or reference type, remap the designated type and make a new pointer or reference type. */ @@ -303,7 +303,7 @@ remap_type (tree type, inline_data *id) if (t && TREE_CODE (t) != INTEGER_CST) walk_tree (&TYPE_MAX_VALUE (new), copy_body_r, id, NULL); return new; - + case FUNCTION_TYPE: TREE_TYPE (new) = remap_type (TREE_TYPE (new), id); walk_tree (&TYPE_ARG_TYPES (new), copy_body_r, id, NULL); @@ -518,9 +518,6 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data) copy_statement_list (tp); else if (TREE_CODE (*tp) == SAVE_EXPR) remap_save_expr (tp, id->decl_map, walk_subtrees); - else if (TREE_CODE (*tp) == UNSAVE_EXPR) - /* UNSAVE_EXPRs should not be generated until expansion time. */ - abort (); else if (TREE_CODE (*tp) == BIND_EXPR) copy_bind_expr (tp, walk_subtrees, id); else if (TREE_CODE (*tp) == LABELED_BLOCK_EXPR) @@ -576,33 +573,6 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data) } } } - else if (TREE_CODE (*tp) == ADDR_EXPR - && (lang_hooks.tree_inlining.auto_var_in_fn_p - (TREE_OPERAND (*tp, 0), fn))) - { - /* Get rid of &* from inline substitutions. It can occur when - someone takes the address of a parm or return slot passed by - invisible reference. */ - tree decl = TREE_OPERAND (*tp, 0), value; - splay_tree_node n; - - n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl); - if (n) - { - value = (tree) n->value; - if (TREE_CODE (value) == INDIRECT_REF) - { - if (!lang_hooks.types_compatible_p - (TREE_TYPE (*tp), TREE_TYPE (TREE_OPERAND (value, 0)))) - *tp = fold_convert (TREE_TYPE (*tp), - TREE_OPERAND (value, 0)); - else - *tp = TREE_OPERAND (value, 0); - - return copy_body_r (tp, walk_subtrees, data); - } - } - } else if (TREE_CODE (*tp) == INDIRECT_REF) { /* Get rid of *& from inline substitutions that can happen when a @@ -693,7 +663,6 @@ setup_one_parameter (inline_data *id, tree p, tree value, tree fn, { tree init_stmt; tree var; - tree var_sub; /* If the parameter is never assigned to, we may not need to create a new variable here at all. Instead, we may be able @@ -724,23 +693,10 @@ setup_one_parameter (inline_data *id, tree p, tree value, tree fn, function. */ var = copy_decl_for_inlining (p, fn, VARRAY_TREE (id->fns, 0)); - /* See if the frontend wants to pass this by invisible reference. If - so, our new VAR_DECL will have REFERENCE_TYPE, and we need to - replace uses of the PARM_DECL with dereferences. */ - if (TREE_TYPE (var) != TREE_TYPE (p) - && POINTER_TYPE_P (TREE_TYPE (var)) - && TREE_TYPE (TREE_TYPE (var)) == TREE_TYPE (p)) - { - insert_decl_map (id, var, var); - var_sub = build1 (INDIRECT_REF, TREE_TYPE (p), var); - } - else - var_sub = var; - /* Register the VAR_DECL as the equivalent for the PARM_DECL; that way, when the PARM_DECL is encountered, it will be automatically replaced by the VAR_DECL. */ - insert_decl_map (id, p, var_sub); + insert_decl_map (id, p, var); /* Declare this new variable. */ TREE_CHAIN (var) = *vars; @@ -878,7 +834,7 @@ declare_return_variable (inline_data *id, tree return_slot_addr, return NULL_TREE; } - /* If there was a return slot, then the return value the the + /* If there was a return slot, then the return value is the dereferenced address of that object. */ if (return_slot_addr) { @@ -886,7 +842,10 @@ declare_return_variable (inline_data *id, tree return_slot_addr, a modify expression. */ if (modify_dest) abort (); - var = build_fold_indirect_ref (return_slot_addr); + if (DECL_BY_REFERENCE (result)) + var = return_slot_addr; + else + var = build_fold_indirect_ref (return_slot_addr); use = NULL; goto done; } @@ -1220,7 +1179,7 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data) return NULL; switch (TREE_CODE (x)) - { + { /* Containers have no cost. */ case TREE_LIST: case TREE_VEC: @@ -1240,7 +1199,6 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data) case NOP_EXPR: case VIEW_CONVERT_EXPR: case SAVE_EXPR: - case UNSAVE_EXPR: case ADDR_EXPR: case COMPLEX_EXPR: case EXIT_BLOCK_EXPR: @@ -1251,7 +1209,6 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data) case STATEMENT_LIST: case ERROR_MARK: case NON_LVALUE_EXPR: - case ENTRY_VALUE_EXPR: case FDESC_EXPR: case VA_ARG_EXPR: case TRY_CATCH_EXPR: @@ -1364,7 +1321,7 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data) case ASM_EXPR: case RESX_EXPR: - *count++; + *count += 1; break; /* Few special cases of expensive operations. This is useful @@ -1594,7 +1551,7 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data) Note we need to save and restore the saved tree statement iterator to avoid having it clobbered by expand_calls_inline. */ tree_stmt_iterator save_tsi; - + save_tsi = id->tsi; expand_calls_inline (&arg_inits, id); id->tsi = save_tsi; @@ -1715,7 +1672,7 @@ static void expand_calls_inline (tree *stmt_p, inline_data *id) { tree stmt = *stmt_p; - enum tree_code code = TREE_CODE (stmt); + enum tree_code code = TREE_CODE (stmt); int dummy; switch (code) @@ -1891,10 +1848,11 @@ clone_body (tree clone, tree fn, void *arg_map) append_to_statement_list_force (copy_body (&id), &DECL_SAVED_TREE (clone)); } -/* Save duplicate of body in FN. MAP is used to pass around splay tree - used to update arguments in restore_body. */ +/* Make and return duplicate of body in FN. Put copies of DECL_ARGUMENTS + in *arg_copy and of the static chain, if any, in *sc_copy. */ + tree -save_body (tree fn, tree *arg_copy) +save_body (tree fn, tree *arg_copy, tree *sc_copy) { inline_data id; tree body, *parg; @@ -1918,6 +1876,18 @@ save_body (tree fn, tree *arg_copy) *parg = new; } + *sc_copy = DECL_STRUCT_FUNCTION (fn)->static_chain_decl; + if (*sc_copy) + { + tree new = copy_node (*sc_copy); + + lang_hooks.dup_lang_specific_decl (new); + DECL_ABSTRACT_ORIGIN (new) = DECL_ORIGIN (*sc_copy); + insert_decl_map (&id, *sc_copy, new); + TREE_CHAIN (new) = TREE_CHAIN (*sc_copy); + *sc_copy = new; + } + insert_decl_map (&id, DECL_RESULT (fn), DECL_RESULT (fn)); /* Actually copy the body. */ @@ -2327,7 +2297,7 @@ copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) if (TREE_CODE (*tp) == BIND_EXPR) BIND_EXPR_BLOCK (*tp) = NULL_TREE; } - + else if (TREE_CODE_CLASS (code) == 't') *walk_subtrees = 0; else if (TREE_CODE_CLASS (code) == 'd') @@ -2393,7 +2363,7 @@ mark_local_for_remap_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, /* Copy the decl and remember the copy. */ insert_decl_map (id, decl, - copy_decl_for_inlining (decl, DECL_CONTEXT (decl), + copy_decl_for_inlining (decl, DECL_CONTEXT (decl), DECL_CONTEXT (decl))); } @@ -2417,7 +2387,7 @@ unsave_r (tree *tp, int *walk_subtrees, void *data) { /* Lookup the declaration. */ n = splay_tree_lookup (st, (splay_tree_key) *tp); - + /* If it's there, remap it. */ if (n) *tp = (tree) n->value;