X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree-inline.c;h=bb2ee237ff3323ab424579cdce32962b1be5dc4b;hb=e5a0a98b1e6a141043771523b2ae60734eff330b;hp=59661a7d5096cf3cf5d470babd0a22ae7ab1a417;hpb=da8160feb432efa1bf314f3f29bde7f035a8bdc5;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 59661a7d509..bb2ee237ff3 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -101,10 +101,6 @@ along with GCC; see the file COPYING3. If not see calls? */ -/* Weights that estimate_num_insns uses for heuristics in inlining. */ - -eni_weights eni_inlining_weights; - /* Weights that estimate_num_insns uses to estimate the size of the produced code. */ @@ -669,16 +665,30 @@ copy_bind_expr (tree *tp, int *walk_subtrees, copy_body_data *id) } if (BIND_EXPR_VARS (*tp)) - /* This will remap a lot of the same decls again, but this should be - harmless. */ - BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), NULL, id); + { + tree t; + + /* This will remap a lot of the same decls again, but this should be + harmless. */ + BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), NULL, id); + + /* Also copy value-expressions. */ + for (t = BIND_EXPR_VARS (*tp); t; t = TREE_CHAIN (t)) + if (TREE_CODE (t) == VAR_DECL + && DECL_HAS_VALUE_EXPR_P (t)) + { + tree tem = DECL_VALUE_EXPR (t); + walk_tree (&tem, copy_tree_body_r, id, NULL); + SET_DECL_VALUE_EXPR (t, tem); + } + } } /* Create a new gimple_seq by remapping all the statements in BODY using the inlining information in ID. */ -gimple_seq +static gimple_seq remap_gimple_seq (gimple_seq body, copy_body_data *id) { gimple_stmt_iterator si; @@ -1688,9 +1698,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, /* Constant propagation on argument done during inlining may create new direct call. Produce an edge for it. */ if ((!edge - || (edge->indirect_call + || (edge->indirect_inlining_edge && id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)) - && is_gimple_call (stmt) && (fn = gimple_call_fndecl (stmt)) != NULL) { struct cgraph_node *dest = cgraph_node (fn); @@ -1702,6 +1711,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, other cases we hit a bug (incorrect node sharing is the most common reason for missing edges). */ gcc_assert (dest->needed || !dest->analyzed + || dest->address_taken || !id->src_node->analyzed); if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES) cgraph_create_edge_including_clones @@ -2014,7 +2024,6 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count) cfun->last_verified = src_cfun->last_verified; cfun->va_list_gpr_size = src_cfun->va_list_gpr_size; cfun->va_list_fpr_size = src_cfun->va_list_fpr_size; - cfun->function_frequency = src_cfun->function_frequency; cfun->has_nonlocal_label = src_cfun->has_nonlocal_label; cfun->stdarg = src_cfun->stdarg; cfun->dont_save_pending_sizes_p = src_cfun->dont_save_pending_sizes_p; @@ -3269,22 +3278,93 @@ estimate_num_insns (gimple stmt, eni_weights *weights) 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: - return 0; case BUILT_IN_EXPECT: - return 0; - - /* Prefetch instruction is not expensive. */ - case BUILT_IN_PREFETCH: - cost = weights->target_builtin_call_cost; - break; - + 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; } @@ -3473,7 +3553,7 @@ get_indirect_callee_fndecl (struct cgraph_node *node, gimple stmt) struct cgraph_edge *cs; cs = cgraph_edge (node, stmt); - if (cs) + if (cs && !cs->indirect_unknown_callee) return cs->callee->decl; return NULL_TREE; @@ -3556,7 +3636,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id) /* If this call was originally indirect, we do not want to emit any inlining related warnings or sorry messages because there are no guarantees regarding those. */ - if (cg_edge->indirect_call) + if (cg_edge->indirect_inlining_edge) goto egress; if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) @@ -4845,6 +4925,8 @@ tree_function_versioning (tree old_decl, tree new_decl, (DECL_STRUCT_FUNCTION (old_decl)); initialize_cfun (new_decl, old_decl, old_entry_block->count); + DECL_STRUCT_FUNCTION (new_decl)->gimple_df->ipa_pta + = id.src_cfun->gimple_df->ipa_pta; push_cfun (DECL_STRUCT_FUNCTION (new_decl)); /* Copy the function's static chain. */ @@ -4863,6 +4945,15 @@ tree_function_versioning (tree old_decl, tree new_decl, if (replace_info->replace_p) { tree op = replace_info->new_tree; + if (!replace_info->old_tree) + { + int i = replace_info->parm_num; + tree parm; + for (parm = DECL_ARGUMENTS (old_decl); i; parm = TREE_CHAIN (parm)) + i --; + replace_info->old_tree = parm; + } + STRIP_NOPS (op); @@ -4956,6 +5047,8 @@ tree_function_versioning (tree old_decl, tree new_decl, pointer_set_destroy (id.statements_to_fold); fold_cond_expr_cond (); delete_unreachable_blocks_update_callgraph (&id); + if (id.dst_node->analyzed) + cgraph_rebuild_references (); update_ssa (TODO_update_ssa); free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS);