From patchwork Sun Nov 10 11:30:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 1192548 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-512892-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ucw.cz Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="yTbJtcaY"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 479sJj25xZz9sPF for ; Sun, 10 Nov 2019 22:30:58 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=TzMaximBGlzPfvrUajkHA4DjjdN91GH0jc9L4xblv4xYuvEIH3Xok T9Qu+1NLTHvWEbkygE5sGOK4mpx9wzJgLlEsEfT4qw9KVMIEHRrSYwJsCuACe5Lo Woq3Ga7S4L4pJZhiVBhm2vTQWBUM/6dJlslwlqfOSuwT6yibmdfYQ0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=valgd0UGo/UhDbmgGtEHv3yXtUA=; b=yTbJtcaYKWsqk8f7SGdU uUy0hRp2qHb8Zj2BN5Cqf/0J5l4Q14L9cN6Aq5q/+s0baMxRnwv1scm9W4wvRpY3 aIjEdxrIW9f0wetq6RGS1IzpqidLll3sz0aNEiEPEctO6DsW9VW7YvL8uclGPTRU Y6HFeBeIQO8ig3PxtCAHXhQ= Received: (qmail 97668 invoked by alias); 10 Nov 2019 11:30:46 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 97565 invoked by uid 89); 10 Nov 2019 11:30:38 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-12.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS autolearn=ham version=3.3.1 spammy=Watch, avail, cgraphclones.c, UD:cgraphclones.c X-HELO: nikam.ms.mff.cuni.cz Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 10 Nov 2019 11:30:35 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 73C4F282892; Sun, 10 Nov 2019 12:30:26 +0100 (CET) Date: Sun, 10 Nov 2019 12:30:26 +0100 From: Jan Hubicka To: gcc-patches@gcc.gnu.org, mjambor@suse.cz Subject: Remove ipa-prop node summaries for inline clones Message-ID: <20191110113026.lbm3soybhsrw44pu@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: NeoMutt/20170113 (1.7.2) Hi, this patch makes creation of IPA_NODE_REF summaries explicit and fixes the fallout. It also removes the summaries after stuff is propagated into caller when function is inlined. Martin, I had to add flag ipcp_clone_p into cgraph_node since that was used while resolving cloned references. I do not see why this flag is needed at all. I understand it is about chain of references when multiple thinkgs was cloned first and inlined later, but it seems to me that we have all the info and there can not me non-clones in chain. Also it seems to me that ipa-cp should simply remove those parameters earlier and not get multiplied references then. Honza * cgraph.h (struct cgraph_node): Add ipcp_clone flag. (cgraph_node::create_virtual_clone): Copy it. * ipa-cp.c (ipcp_versionable_function_p): Watch for missing summaries. (ignore_edge_p): If caller has ipa-cp disabled, skip the edge, too. (ipcp_verify_propagated_values): Do not verify nodes where ipcp is disabled. (propagate_constants_across_call): If callee is not analyzed, give up. (propagate_constants_topo): Lower to bottom latties of all callees of functions with ipa-cp disabled. (ipcp_propagate_stage): Skip functions with ipa-cp disabled. (cgraph_edge_brings_value_p): Check for availability first. (create_specialized_node): Set ipcp_clone. (ipcp_store_bits_results): Check that info is present. * ipa-fnsummary.c (evaluate_properties_for_edge): Do not analyze thunks. (ipa_call_context::duplicate_from, ipa_call_context::equal_to): Be conservative when callee summary is missing. (remap_edge_summaries): Lookup call summary only when needed. * ipa-icf.c (sem_function::param_used_p): Be ready for missing summary. * ipa-prpo.c (ipa_alloc_node_params, ipa_initialize_node_params): Use get_create. (ipa_analyze_node): Use get_create. (propagate_controlled_uses): Do not propagate when function is not analyzed. (ipa_propagate_indirect_call_infos): Remove summary of inline clone. (ipa_read_node_info): Use get_create. * ipa-prop.h (IPA_NODE_REF): Use get. (IPA_NODE_REF_GET_CREATE): New. Index: cgraph.h =================================================================== --- cgraph.h (revision 278009) +++ cgraph.h (working copy) @@ -1484,6 +1484,8 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cg unsigned redefined_extern_inline : 1; /* True if the function may enter serial irrevocable mode. */ unsigned tm_may_enter_irr : 1; + /* True if this was a clone created by ipa-cp. */ + unsigned ipcp_clone : 1; private: /* Unique id of the node. */ Index: cgraphclones.c =================================================================== --- cgraphclones.c (revision 278009) +++ cgraphclones.c (working copy) @@ -570,6 +570,7 @@ cgraph_node::create_virtual_clone (vecipcp_clone = ipcp_clone; new_node->clone.tree_map = tree_map; if (!implicit_section) new_node->set_section (get_section ()); Index: ipa-cp.c =================================================================== --- ipa-cp.c (revision 278009) +++ ipa-cp.c (working copy) @@ -656,7 +656,7 @@ determine_versionability (struct cgraph_ static bool ipcp_versionable_function_p (struct cgraph_node *node) { - return IPA_NODE_REF (node)->versionable; + return IPA_NODE_REF (node) && IPA_NODE_REF (node)->versionable; } /* Structure holding accumulated information about callers of a node. */ @@ -817,6 +817,7 @@ ignore_edge_p (cgraph_edge *e) = e->callee->function_or_virtual_thunk_symbol (&avail, e->caller); return (avail <= AVAIL_INTERPOSABLE + || !opt_for_fn (e->caller->decl, flag_ipa_cp) || !opt_for_fn (ultimate_target->decl, flag_ipa_cp)); } @@ -1471,6 +1472,8 @@ ipcp_verify_propagated_values (void) FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) { class ipa_node_params *info = IPA_NODE_REF (node); + if (!opt_for_fn (node->decl, flag_ipa_cp)) + continue; int i, count = ipa_get_param_count (info); for (i = 0; i < count; i++) @@ -2307,6 +2310,8 @@ propagate_constants_across_call (struct return false; gcc_checking_assert (callee->has_gimple_body_p ()); callee_info = IPA_NODE_REF (callee); + if (!callee_info) + return false; args = IPA_EDGE_REF (cs); parms_count = ipa_get_param_count (callee_info); @@ -3233,7 +3238,17 @@ propagate_constants_topo (class ipa_topo until all lattices stabilize. */ FOR_EACH_VEC_ELT (cycle_nodes, j, v) if (v->has_gimple_body_p ()) - push_node_to_stack (topo, v); + { + if (opt_for_fn (v->decl, flag_ipa_cp)) + push_node_to_stack (topo, v); + /* When V is not optimized, we can not push it to stac, but + still we need to set all its callees lattices to bottom. */ + else + { + for (cgraph_edge *cs = v->callees; cs; cs = cs->next_callee) + propagate_constants_across_call (cs); + } + } v = pop_node_from_stack (topo); while (v) @@ -3254,7 +3269,8 @@ propagate_constants_topo (class ipa_topo the local effects of the discovered constants and all valid values to their topological sort. */ FOR_EACH_VEC_ELT (cycle_nodes, j, v) - if (v->has_gimple_body_p ()) + if (v->has_gimple_body_p () + && opt_for_fn (v->decl, flag_ipa_cp)) { struct cgraph_edge *cs; @@ -3333,11 +3349,10 @@ ipcp_propagate_stage (class ipa_topo_inf FOR_EACH_DEFINED_FUNCTION (node) { - class ipa_node_params *info = IPA_NODE_REF (node); - - determine_versionability (node, info); - if (node->has_gimple_body_p ()) + if (node->has_gimple_body_p () && opt_for_fn (node->decl, flag_ipa_cp)) { + class ipa_node_params *info = IPA_NODE_REF (node); + determine_versionability (node, info); info->lattices = XCNEWVEC (class ipcp_param_lattices, ipa_get_param_count (info)); initialize_node_lattices (node); @@ -3526,8 +3541,8 @@ cgraph_edge_brings_value_p (cgraph_edge enum availability availability; cgraph_node *real_dest = cs->callee->function_symbol (&availability); - if (!same_node_or_its_all_contexts_clone_p (real_dest, dest) - || availability <= AVAIL_INTERPOSABLE + if (availability <= AVAIL_INTERPOSABLE + || !same_node_or_its_all_contexts_clone_p (real_dest, dest) || caller_info->node_dead) return false; @@ -3583,9 +3598,11 @@ cgraph_edge_brings_value_p (cgraph_edge ipcp_value *) { class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); - cgraph_node *real_dest = cs->callee->function_symbol (); + enum availability avail; + cgraph_node *real_dest = cs->callee->function_symbol (&avail); - if (!same_node_or_its_all_contexts_clone_p (real_dest, dest) + if (avail <= AVAIL_INTERPOSABLE + || !same_node_or_its_all_contexts_clone_p (real_dest, dest) || caller_info->node_dead) return false; if (!src->val) @@ -4018,6 +4035,7 @@ create_specialized_node (struct cgraph_n update_profiling_info (node, new_node); new_info = IPA_NODE_REF (new_node); new_info->ipcp_orig_node = node; + new_node->ipcp_clone = true; new_info->known_csts = known_csts; new_info->known_contexts = known_contexts; @@ -5053,7 +5071,7 @@ ipcp_store_bits_results (void) bool dumped_sth = false; bool found_useful_result = false; - if (!opt_for_fn (node->decl, flag_ipa_bit_cp)) + if (!opt_for_fn (node->decl, flag_ipa_bit_cp) || !info) { if (dump_file) fprintf (dump_file, "Not considering %s for ipa bitwise propagation " Index: ipa-fnsummary.c =================================================================== --- ipa-fnsummary.c (revision 278009) +++ ipa-fnsummary.c (working copy) @@ -483,36 +483,39 @@ evaluate_properties_for_edge (struct cgr if (count && known_contexts_ptr) known_contexts_ptr->safe_grow_cleared (count); - for (i = 0; i < count; i++) - { - struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i); - tree cst = ipa_value_from_jfunc (caller_parms_info, jf, - ipa_get_type (callee_pi, i)); - - if (!cst && e->call_stmt - && i < (int)gimple_call_num_args (e->call_stmt)) - { - cst = gimple_call_arg (e->call_stmt, i); - if (!is_gimple_min_invariant (cst)) - cst = NULL; - } - if (cst) - { - gcc_checking_assert (TREE_CODE (cst) != TREE_BINFO); - if (known_vals.exists ()) - known_vals[i] = cst; - } - else if (inline_p && !es->param[i].change_prob) - known_vals[i] = error_mark_node; - - if (known_contexts_ptr) - (*known_contexts_ptr)[i] - = ipa_context_from_jfunc (caller_parms_info, e, i, jf); - /* TODO: When IPA-CP starts propagating and merging aggregate jump - functions, use its knowledge of the caller too, just like the - scalar case above. */ - known_aggs[i] = &jf->agg; - } + if (callee_pi) + for (i = 0; i < count; i++) + { + struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i); + tree cst = ipa_value_from_jfunc (caller_parms_info, jf, + ipa_get_type (callee_pi, i)); + + if (!cst && e->call_stmt + && i < (int)gimple_call_num_args (e->call_stmt)) + { + cst = gimple_call_arg (e->call_stmt, i); + if (!is_gimple_min_invariant (cst)) + cst = NULL; + } + if (cst) + { + gcc_checking_assert (TREE_CODE (cst) != TREE_BINFO); + if (known_vals.exists ()) + known_vals[i] = cst; + } + else if (inline_p && !es->param[i].change_prob) + known_vals[i] = error_mark_node; + + if (known_contexts_ptr) + (*known_contexts_ptr)[i] + = ipa_context_from_jfunc (caller_parms_info, e, i, jf); + /* TODO: When IPA-CP starts propagating and merging aggregate jump + functions, use its knowledge of the caller too, just like the + scalar case above. */ + known_aggs[i] = &jf->agg; + } + else + gcc_assert (callee->thunk.thunk_p); } else if (e->call_stmt && !e->call_stmt_cannot_inline_p && ((clause_ptr && info->conds) || known_vals_ptr)) @@ -3004,7 +3007,8 @@ ipa_call_context::duplicate_from (const m_possible_truths = ctx.m_possible_truths; m_nonspec_possible_truths = ctx.m_nonspec_possible_truths; class ipa_node_params *params_summary = IPA_NODE_REF (m_node); - unsigned int nargs = ipa_get_param_count (params_summary); + unsigned int nargs = params_summary + ? ipa_get_param_count (params_summary) : 0; m_inline_param_summary = vNULL; /* Copy the info only if there is at least one useful entry. */ @@ -3093,7 +3097,8 @@ ipa_call_context::equal_to (const ipa_ca return false; class ipa_node_params *params_summary = IPA_NODE_REF (m_node); - unsigned int nargs = ipa_get_param_count (params_summary); + unsigned int nargs = params_summary + ? ipa_get_param_count (params_summary) : 0; if (m_inline_param_summary.exists () || ctx.m_inline_param_summary.exists ()) { @@ -3404,7 +3409,7 @@ inline_update_callee_summaries (struct c } /* Update change_prob of EDGE after INLINED_EDGE has been inlined. - When functoin A is inlined in B and A calls C with parameter that + When function A is inlined in B and A calls C with parameter that changes with probability PROB1 and C is known to be passthroug of argument if B that change with probability PROB2, the probability of change is now PROB1*PROB2. */ @@ -3472,12 +3477,12 @@ remap_edge_summaries (struct cgraph_edge struct cgraph_edge *e, *next; for (e = node->callees; e; e = next) { - class ipa_call_summary *es = ipa_call_summaries->get (e); predicate p; next = e->next_callee; if (e->inline_failed) { + class ipa_call_summary *es = ipa_call_summaries->get (e); remap_edge_change_prob (inlined_edge, e); if (es->predicate) Index: ipa-icf.c =================================================================== --- ipa-icf.c (revision 278009) +++ ipa-icf.c (working copy) @@ -484,7 +484,7 @@ sem_function::param_used_p (unsigned int class ipa_node_params *parms_info = IPA_NODE_REF (get_node ()); - if (vec_safe_length (parms_info->descriptors) <= i) + if (!parms_info || vec_safe_length (parms_info->descriptors) <= i) return true; return ipa_is_param_used (IPA_NODE_REF (get_node ()), i); Index: ipa-prop.c =================================================================== --- ipa-prop.c (revision 278009) +++ ipa-prop.c (working copy) @@ -271,7 +271,7 @@ ipa_dump_param (FILE *file, class ipa_no static bool ipa_alloc_node_params (struct cgraph_node *node, int param_count) { - class ipa_node_params *info = IPA_NODE_REF (node); + class ipa_node_params *info = IPA_NODE_REF_GET_CREATE (node); if (!info->descriptors && param_count) { @@ -289,7 +289,7 @@ ipa_alloc_node_params (struct cgraph_nod void ipa_initialize_node_params (struct cgraph_node *node) { - class ipa_node_params *info = IPA_NODE_REF (node); + class ipa_node_params *info = IPA_NODE_REF_GET_CREATE (node); if (!info->descriptors && ipa_alloc_node_params (node, count_formal_params (node->decl))) @@ -2605,7 +2605,7 @@ ipa_analyze_node (struct cgraph_node *no ipa_check_create_node_params (); ipa_check_create_edge_args (); - info = IPA_NODE_REF (node); + info = IPA_NODE_REF_GET_CREATE (node); if (info->analysis_done) return; @@ -3601,6 +3601,9 @@ propagate_controlled_uses (struct cgraph class ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee); int count, i; + if (!old_root_info) + return; + count = MIN (ipa_get_cs_argument_count (args), ipa_get_param_count (old_root_info)); for (i = 0; i < count; i++) @@ -3662,8 +3665,8 @@ propagate_controlled_uses (struct cgraph clone = cs->caller; while (clone->inlined_to - && clone != rdesc->cs->caller - && IPA_NODE_REF (clone)->ipcp_orig_node) + && clone->ipcp_clone + && clone != rdesc->cs->caller) { struct ipa_ref *ref; ref = clone->find_reference (n, NULL, 0); @@ -3722,6 +3725,7 @@ ipa_propagate_indirect_call_infos (struc propagate_controlled_uses (cs); changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges); + ipa_node_params_sum->remove (cs->callee); return changed; } @@ -4507,7 +4511,8 @@ ipa_read_node_info (class lto_input_bloc struct cgraph_edge *e; struct bitpack_d bp; bool prevails = node->prevailing_p (); - class ipa_node_params *info = prevails ? IPA_NODE_REF (node) : NULL; + class ipa_node_params *info = prevails + ? IPA_NODE_REF_GET_CREATE (node) : NULL; int param_count = streamer_read_uhwi (ib); if (prevails) Index: ipa-prop.h =================================================================== --- ipa-prop.h (revision 278009) +++ ipa-prop.h (working copy) @@ -766,7 +766,8 @@ extern GTY(()) function_summary get_create (NODE)) +#define IPA_NODE_REF(NODE) (ipa_node_params_sum->get (NODE)) +#define IPA_NODE_REF_GET_CREATE(NODE) (ipa_node_params_sum->get_create (NODE)) #define IPA_EDGE_REF(EDGE) (ipa_edge_args_sum->get (EDGE)) #define IPA_EDGE_REF_GET_CREATE(EDGE) (ipa_edge_args_sum->get_create (EDGE)) /* This macro checks validity of index returned by