From 38a8aecfb882072900434499696b5c32a2274515 Mon Sep 17 00:00:00 2001 From: Rong Xu Date: Mon, 21 Jul 2014 16:47:22 -0700 Subject: [4.9] Switch gcc-4.9 to use google/gcc-4_9 branch. This source drop uses svn version r212828 of google/gcc-4.9 branch. We also cherry-picked r213062, r213063 and r213064 to fix windows build issues. All gcc-4.9 patches before July 3rd are ported to google/gcc-4.9. The following prior commits has not been merged to google branch yet. (They are included in this commit). e7af147f979e657fe2df00808e5b4319b0e088c6, baf87df3cb2683649ba7e9872362a7e721117c23, and c231900e5dcc14d8296bd9f62b45997a49d4d5e7. Change-Id: I4bea3ea470387ff751c2be4cb0d4a12059b9299b --- gcc-4.9/gcc/tree-inline.c | 65 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 10 deletions(-) (limited to 'gcc-4.9/gcc/tree-inline.c') diff --git a/gcc-4.9/gcc/tree-inline.c b/gcc-4.9/gcc/tree-inline.c index 04d099f61..beb65f0b1 100644 --- a/gcc-4.9/gcc/tree-inline.c +++ b/gcc-4.9/gcc/tree-inline.c @@ -66,6 +66,8 @@ along with GCC; see the file COPYING3. If not see #include "value-prof.h" #include "tree-pass.h" #include "target.h" +#include "langhooks.h" +#include "l-ipo.h" #include "cfgloop.h" #include "rtl.h" /* FIXME: For asm_str_count. */ @@ -1984,9 +1986,11 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb, edge new_edge; flags = old_edge->flags; + flags &= (~EDGE_ANNOTATED); /* Return edges do get a FALLTHRU flag when the get inlined. */ - if (old_edge->dest->index == EXIT_BLOCK && !old_edge->flags + if (old_edge->dest->index == EXIT_BLOCK + && !(old_edge->flags & (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE|EDGE_FAKE)) && old_edge->dest->aux != EXIT_BLOCK_PTR_FOR_FN (cfun)) flags |= EDGE_FALLTHRU; new_edge = make_edge (new_bb, (basic_block) old_edge->dest->aux, flags); @@ -2226,17 +2230,18 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count) cfun->can_delete_dead_exceptions = src_cfun->can_delete_dead_exceptions; cfun->returns_struct = src_cfun->returns_struct; cfun->returns_pcc_struct = src_cfun->returns_pcc_struct; + cfun->module_id = src_cfun->module_id; init_empty_tree_cfg (); profile_status_for_fn (cfun) = profile_status_for_fn (src_cfun); ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = - (ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count * count_scale / + (ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count * (double)count_scale / REG_BR_PROB_BASE); ENTRY_BLOCK_PTR_FOR_FN (cfun)->frequency = ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->frequency; EXIT_BLOCK_PTR_FOR_FN (cfun)->count = - (EXIT_BLOCK_PTR_FOR_FN (src_cfun)->count * count_scale / + (EXIT_BLOCK_PTR_FOR_FN (src_cfun)->count * (double)count_scale / REG_BR_PROB_BASE); EXIT_BLOCK_PTR_FOR_FN (cfun)->frequency = EXIT_BLOCK_PTR_FOR_FN (src_cfun)->frequency; @@ -2645,8 +2650,20 @@ copy_debug_stmt (gimple stmt, copy_body_data *id) gimple_debug_bind_set_var (stmt, t); if (gimple_debug_bind_has_value_p (stmt)) - walk_tree (gimple_debug_bind_get_value_ptr (stmt), - remap_gimple_op_r, &wi, NULL); + { + tree v = gimple_debug_bind_get_value (stmt); + if (TREE_CODE (v) == ADDR_EXPR) + v = TREE_OPERAND (v, 0); + + /* The global var may be deleted */ + if (L_IPO_COMP_MODE && + ((TREE_CODE (v) != VAR_DECL) + || is_global_var (v))) + processing_debug_stmt = -1; + else + walk_tree (gimple_debug_bind_get_value_ptr (stmt), + remap_gimple_op_r, &wi, NULL); + } /* Punt if any decl couldn't be remapped. */ if (processing_debug_stmt < 0) @@ -3524,8 +3541,13 @@ tree_inlinable_function_p (tree fn) tree always_inline; /* If we've already decided this function shouldn't be inlined, - there's no need to check again. */ - if (DECL_UNINLINABLE (fn)) + there's no need to check again. But the cached bit from analysis + can be reset during decl merge in multi-module compilation (C FE only). + The problem is we can not really use a 2 state cached value -- + can not tell the init state (unknown value) from a computed value. */ + if (DECL_UNINLINABLE (fn) + && (!L_IPO_COMP_MODE + || lookup_attribute ("noinline", DECL_ATTRIBUTES (fn)))) return false; /* We only warn for functions declared `inline' by the user. */ @@ -3695,6 +3717,7 @@ estimate_operator_cost (enum tree_code code, eni_weights *weights, case WIDEN_SUM_EXPR: case WIDEN_MULT_EXPR: case DOT_PROD_EXPR: + case SAD_EXPR: case WIDEN_MULT_PLUS_EXPR: case WIDEN_MULT_MINUS_EXPR: case WIDEN_LSHIFT_EXPR: @@ -4068,6 +4091,16 @@ add_local_variables (struct function *callee, struct function *caller, { tree tem = DECL_DEBUG_EXPR (var); bool old_regimplify = id->regimplify; + + /* The mapped debug expression might be deleted + as a varpool node (the reachbility analysis + of varpool node does not check the reference + from debug expressions. + Set it to 0 for all global vars. */ + if (L_IPO_COMP_MODE && tem && TREE_CODE (tem) == VAR_DECL + && is_global_var (tem)) + tem = NULL; + id->remapping_type_depth++; walk_tree (&tem, copy_tree_body_r, id, NULL); id->remapping_type_depth--; @@ -4355,7 +4388,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id) function in any way before this point, as this CALL_EXPR may be a self-referential call; if we're calling ourselves, we need to duplicate our body before altering anything. */ - copy_body (id, bb->count, + copy_body (id, cg_edge->callee->count, GCOV_COMPUTE_SCALE (cg_edge->frequency, CGRAPH_FREQ_BASE), bb, return_block, NULL); @@ -4621,7 +4654,7 @@ optimize_inline_calls (tree fn) /* Double check that we inlined everything we are supposed to inline. */ for (e = id.dst_node->callees; e; e = e->next_callee) - gcc_assert (e->inline_failed); + gcc_assert (e->inline_failed || !e->call_stmt /*fake edge*/); } #endif @@ -4711,7 +4744,19 @@ copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) else if (TREE_CODE_CLASS (code) == tcc_type) *walk_subtrees = 0; else if (TREE_CODE_CLASS (code) == tcc_declaration) - *walk_subtrees = 0; + { + *walk_subtrees = 0; + if (L_IPO_COMP_MODE + && (code == VAR_DECL) + && (TREE_STATIC (*tp) || DECL_EXTERNAL (*tp))) + { + tree resolved_decl = real_varpool_node (*tp)->decl; + if (resolved_decl != *tp) + { + *tp = resolved_decl; + } + } + } else if (TREE_CODE_CLASS (code) == tcc_constant) *walk_subtrees = 0; return NULL_TREE; -- cgit v1.2.3