diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2009-06-30 17:26:32 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2009-06-30 17:26:32 +0000 |
commit | f82a627cf51e998b3d1c5c02f7e7c00b4aef1b0c (patch) | |
tree | 46e380a758cc2f203dbeec25be5417a9a9bca764 /gcc/tree-inline.c | |
parent | c1a5cfab17521708db174ed25707f2eee57727fe (diff) | |
download | gcc-f82a627cf51e998b3d1c5c02f7e7c00b4aef1b0c.tar.gz |
cgraphunit.c (cgraph_finalize_compilation_unit): Call finalize_size_functions before further processing.
* cgraphunit.c (cgraph_finalize_compilation_unit): Call
finalize_size_functions before further processing.
* stor-layout.c: Include cgraph.h, tree-inline.h and tree-dump.h.
(variable_size): Call self_referential_size on size expressions
that contain a PLACEHOLDER_EXPR.
(size_functions): New static variable.
(copy_self_referential_tree_r): New static function.
(self_referential_size): Likewise.
(finalize_size_functions): New global function.
* tree.c: Include tree-inline.h.
(push_without_duplicates): New static function.
(find_placeholder_in_expr): New global function.
(substitute_in_expr) <tcc_declaration>: Return the replacement object
on equality.
<tcc_expression>: Likewise.
<tcc_vl_exp>: If the replacement object is a constant, try to inline
the call in the expression.
* tree.h (finalize_size_functions): Declare.
(find_placeholder_in_expr): Likewise.
(FIND_PLACEHOLDER_IN_EXPR): New macro.
(substitute_placeholder_in_expr): Update comment.
* tree-inline.c (remap_decl): Do not unshare trees if do_not_unshare
is true.
(copy_tree_body_r): Likewise.
(copy_tree_body): New static function.
(maybe_inline_call_in_expr): New global function.
* tree-inline.h (struct copy_body_data): Add do_not_unshare field.
(maybe_inline_call_in_expr): Declare.
* Makefile.in (tree.o): Depend on TREE_INLINE_H.
(stor-layout.o): Depend on CGRAPH_H, TREE_INLINE_H, TREE_DUMP_H and
GIMPLE_H.
ada/
* gcc-interface/decl.c: Include tree-inline.h.
(annotate_value) <CALL_EXPR>: Try to inline the call in the expression.
* gcc-interface/utils.c (max_size) <CALL_EXPR>: Likewise.
* gcc-interface/utils2.c: Include tree-inline.
(known_alignment) <CALL_EXPR>: Likewise.
From-SVN: r149112
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r-- | gcc/tree-inline.c | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index b97b9b2b772..648e30b47b3 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -287,7 +287,10 @@ remap_decl (tree decl, copy_body_data *id) return t; } - return unshare_expr (*n); + if (id->do_not_unshare) + return *n; + else + return unshare_expr (*n); } static tree @@ -997,7 +1000,10 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data) but we absolutely rely on that. As fold_indirect_ref does other useful transformations, try that first, though. */ tree type = TREE_TYPE (TREE_TYPE (*n)); - new_tree = unshare_expr (*n); + if (id->do_not_unshare) + new_tree = *n; + else + new_tree = unshare_expr (*n); old = *tp; *tp = gimple_fold_indirect_ref (new_tree); if (! *tp) @@ -1993,6 +1999,20 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency, return new_fndecl; } +/* Make a copy of the body of SRC_FN so that it can be inserted inline in + another function. */ + +static tree +copy_tree_body (copy_body_data *id) +{ + tree fndecl = id->src_fn; + tree body = DECL_SAVED_TREE (fndecl); + + walk_tree (&body, copy_tree_body_r, id, NULL); + + return body; +} + static tree copy_body (copy_body_data *id, gcov_type count, int frequency, basic_block entry_block_map, basic_block exit_block_map) @@ -4605,6 +4625,60 @@ tree_function_versioning (tree old_decl, tree new_decl, return; } +/* EXP is CALL_EXPR present in a GENERIC expression tree. Try to integrate + the callee and return the inlined body on success. */ + +tree +maybe_inline_call_in_expr (tree exp) +{ + tree fn = get_callee_fndecl (exp); + + /* We can only try to inline "const" functions. */ + if (fn && TREE_READONLY (fn) && DECL_SAVED_TREE (fn)) + { + struct pointer_map_t *decl_map = pointer_map_create (); + call_expr_arg_iterator iter; + copy_body_data id; + tree param, arg, t; + + /* 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)) + *pointer_map_insert (decl_map, param) = arg; + + memset (&id, 0, sizeof (id)); + id.src_fn = fn; + id.dst_fn = current_function_decl; + id.src_cfun = DECL_STRUCT_FUNCTION (fn); + id.decl_map = decl_map; + + id.copy_decl = copy_decl_no_change; + id.transform_call_graph_edges = CB_CGE_DUPLICATE; + id.transform_new_cfg = false; + id.transform_return_to_modify = true; + id.transform_lang_insert_block = false; + + /* Make sure not to unshare trees behind the front-end's back + since front-end specific mechanisms may rely on sharing. */ + id.regimplify = false; + id.do_not_unshare = true; + + /* We're not inside any EH region. */ + id.eh_region = -1; + + t = copy_tree_body (&id); + pointer_map_destroy (decl_map); + + /* We can only return something suitable for use in a GENERIC + expression tree. */ + if (TREE_CODE (t) == MODIFY_EXPR) + return TREE_OPERAND (t, 1); + } + + return NULL_TREE; +} + /* Duplicate a type, fields and all. */ tree |