From f2c6b33f08656ecf93afce51b49038e4a2050293 Mon Sep 17 00:00:00 2001 From: hubicka Date: Sat, 3 Aug 2013 11:02:37 +0000 Subject: [PATCH] * cgraphunit.c (add_new_function): Fix logic when adding from late IPA pass. (assemble_thunk): Rename to ... (expand_thunk); .. this one; export; get it working with general functions; make produced gimple valid. * cgraph.h (expand_thunk): Declare. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201463 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 9 ++++ gcc/cgraph.h | 1 + gcc/cgraphunit.c | 134 ++++++++++++++++++++++++++++++------------------------- 3 files changed, 84 insertions(+), 60 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f54c696bcf1..1d48fc0da36 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2013-08-02 Jan Hubicka + * cgraphunit.c (add_new_function): Fix logic when adding from + late IPA pass. + (assemble_thunk): Rename to ... + (expand_thunk); .. this one; export; get it working with general functions; + make produced gimple valid. + * cgraph.h (expand_thunk): Declare. + +2013-08-02 Jan Hubicka + * ipa-cp.c (gather_context_independent_values): Use ipa_get_param_move_cost. (get_replacement_map): Remove PARAM; move parameter folding into tree-inline.c (create_specialized_node): Update. diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 4e4dddc0c3e..734f556cd9f 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -716,6 +716,7 @@ void fixup_same_cpp_alias_visibility (symtab_node, symtab_node target, tree); IN_SSA is true if the gimple is in SSA. */ basic_block init_lowered_empty_function (tree, bool); void cgraph_reset_node (struct cgraph_node *); +void expand_thunk (struct cgraph_node *); /* In cgraphclones.c */ diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index de7bb93d2c3..e308b524850 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -323,13 +323,10 @@ cgraph_process_new_functions (void) if (!node->symbol.analyzed) analyze_function (node); push_cfun (DECL_STRUCT_FUNCTION (fndecl)); - if ((cgraph_state == CGRAPH_STATE_IPA_SSA + if (cgraph_state == CGRAPH_STATE_IPA_SSA && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl))) - /* When not optimizing, be sure we run early local passes anyway - to expand OMP. */ - || !optimize) execute_pass_list (pass_early_local_passes.pass.sub); - else + else if (inline_summary_vec != NULL) compute_inline_parameters (node, true); free_dominance_info (CDI_POST_DOMINATORS); free_dominance_info (CDI_DOMINATORS); @@ -1327,8 +1324,8 @@ thunk_adjust (gimple_stmt_iterator * bsi, /* Produce assembler for thunk NODE. */ -static void -assemble_thunk (struct cgraph_node *node) +void +expand_thunk (struct cgraph_node *node) { bool this_adjusting = node->thunk.this_adjusting; HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset; @@ -1420,7 +1417,9 @@ assemble_thunk (struct cgraph_node *node) /* Build call to the function being thunked. */ if (!VOID_TYPE_P (restype)) { - if (!is_gimple_reg_type (restype)) + if (DECL_BY_REFERENCE (resdecl)) + restmp = gimple_fold_indirect_ref (resdecl); + else if (!is_gimple_reg_type (restype)) { restmp = resdecl; add_local_decl (cfun, restmp); @@ -1436,74 +1435,91 @@ assemble_thunk (struct cgraph_node *node) if (this_adjusting) vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset, virtual_offset)); - else + else if (nargs) vargs.quick_push (a); - for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg)) - vargs.quick_push (arg); + + if (nargs) + for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg)) + vargs.quick_push (arg); call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs); vargs.release (); gimple_call_set_from_thunk (call, true); if (restmp) - gimple_call_set_lhs (call, restmp); + { + gimple_call_set_lhs (call, restmp); + gcc_assert (useless_type_conversion_p (TREE_TYPE (restmp), + TREE_TYPE (TREE_TYPE (alias)))); + } gsi_insert_after (&bsi, call, GSI_NEW_STMT); + if (!(gimple_call_flags (call) & ECF_NORETURN)) + { + if (restmp && !this_adjusting + && (fixed_offset || virtual_offset)) + { + tree true_label = NULL_TREE; - if (restmp && !this_adjusting) - { - tree true_label = NULL_TREE; + if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE) + { + gimple stmt; + /* If the return type is a pointer, we need to + protect against NULL. We know there will be an + adjustment, because that's why we're emitting a + thunk. */ + then_bb = create_basic_block (NULL, (void *) 0, bb); + return_bb = create_basic_block (NULL, (void *) 0, then_bb); + else_bb = create_basic_block (NULL, (void *) 0, else_bb); + add_bb_to_loop (then_bb, bb->loop_father); + add_bb_to_loop (return_bb, bb->loop_father); + add_bb_to_loop (else_bb, bb->loop_father); + remove_edge (single_succ_edge (bb)); + true_label = gimple_block_label (then_bb); + stmt = gimple_build_cond (NE_EXPR, restmp, + build_zero_cst (TREE_TYPE (restmp)), + NULL_TREE, NULL_TREE); + gsi_insert_after (&bsi, stmt, GSI_NEW_STMT); + make_edge (bb, then_bb, EDGE_TRUE_VALUE); + make_edge (bb, else_bb, EDGE_FALSE_VALUE); + make_edge (return_bb, EXIT_BLOCK_PTR, 0); + make_edge (then_bb, return_bb, EDGE_FALLTHRU); + make_edge (else_bb, return_bb, EDGE_FALLTHRU); + bsi = gsi_last_bb (then_bb); + } - if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE) - { - gimple stmt; - /* If the return type is a pointer, we need to - protect against NULL. We know there will be an - adjustment, because that's why we're emitting a - thunk. */ - then_bb = create_basic_block (NULL, (void *) 0, bb); - return_bb = create_basic_block (NULL, (void *) 0, then_bb); - else_bb = create_basic_block (NULL, (void *) 0, else_bb); - add_bb_to_loop (then_bb, bb->loop_father); - add_bb_to_loop (return_bb, bb->loop_father); - add_bb_to_loop (else_bb, bb->loop_father); - remove_edge (single_succ_edge (bb)); - true_label = gimple_block_label (then_bb); - stmt = gimple_build_cond (NE_EXPR, restmp, - build_zero_cst (TREE_TYPE (restmp)), - NULL_TREE, NULL_TREE); - gsi_insert_after (&bsi, stmt, GSI_NEW_STMT); - make_edge (bb, then_bb, EDGE_TRUE_VALUE); - make_edge (bb, else_bb, EDGE_FALSE_VALUE); - make_edge (return_bb, EXIT_BLOCK_PTR, 0); - make_edge (then_bb, return_bb, EDGE_FALLTHRU); - make_edge (else_bb, return_bb, EDGE_FALLTHRU); - bsi = gsi_last_bb (then_bb); + restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0, + fixed_offset, virtual_offset); + if (true_label) + { + gimple stmt; + bsi = gsi_last_bb (else_bb); + stmt = gimple_build_assign (restmp, + build_zero_cst (TREE_TYPE (restmp))); + gsi_insert_after (&bsi, stmt, GSI_NEW_STMT); + bsi = gsi_last_bb (return_bb); + } } + else + gimple_call_set_tail (call, true); - restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0, - fixed_offset, virtual_offset); - if (true_label) - { - gimple stmt; - bsi = gsi_last_bb (else_bb); - stmt = gimple_build_assign (restmp, - build_zero_cst (TREE_TYPE (restmp))); - gsi_insert_after (&bsi, stmt, GSI_NEW_STMT); - bsi = gsi_last_bb (return_bb); - } + /* Build return value. */ + ret = gimple_build_return (restmp); + gsi_insert_after (&bsi, ret, GSI_NEW_STMT); } else - gimple_call_set_tail (call, true); - - /* Build return value. */ - ret = gimple_build_return (restmp); - gsi_insert_after (&bsi, ret, GSI_NEW_STMT); + { + gimple_call_set_tail (call, true); + remove_edge (single_succ_edge (bb)); + } delete_unreachable_blocks (); update_ssa (TODO_update_ssa); +#ifdef ENABLE_CHECKING + verify_flow_info (); +#endif /* Since we want to emit the thunk, we explicitly mark its name as referenced. */ node->thunk.thunk_p = false; - cgraph_node_remove_callees (node); + rebuild_cgraph_edges (); cgraph_add_new_function (thunk_fndecl, true); bitmap_obstack_release (NULL); } @@ -1511,8 +1527,6 @@ assemble_thunk (struct cgraph_node *node) set_cfun (NULL); } - - /* Assemble thunks and aliases associated to NODE. */ static void @@ -1529,7 +1543,7 @@ assemble_thunks_and_aliases (struct cgraph_node *node) e = e->next_caller; assemble_thunks_and_aliases (thunk); - assemble_thunk (thunk); + expand_thunk (thunk); } else e = e->next_caller; -- 2.11.4.GIT