From patchwork Fri Dec 13 15:43:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 1209198 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-515902-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="o8pZG85v"; 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 47ZFLg1WhWz9sPT for ; Sat, 14 Dec 2019 02:43:23 +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=nfMugFU/g0IZBiMNunV/ETG0Vc9e9U2I24cn6BBpODzfEzGdTXqv6 adP7TX4ZHzegEZCliGzJ97z9BQrgXahrxYAitkS79CX/JUVvuKzJs/w4/WIjeF6o UAuNzarenODNX53258Bb/sVzkJ76k7n47tCqCBzWM51qRasAZzU3NQ= 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=GZYHnP/xEQPzSYHhzBhVakXkdvA=; b=o8pZG85vWaQpOpBcxtNJ /JzcXw9+/ge0y8rtrJOSlcGK0tWuFXxbIFUTZr2qWG1vV6z/PxuhoaxQkreE0Ll3 x5E6o71M8IjUsu/4oBk9hlUK0FqHLTTDcWpn/E+WlOwrHxKOchX5jpp7j1QysA2b FV/RMJyASji/FX50MX1k6rc= Received: (qmail 45576 invoked by alias); 13 Dec 2019 15:43:15 -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 45564 invoked by uid 89); 13 Dec 2019 15:43:14 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-13.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3 autolearn=ham version=3.3.1 spammy=speculative, Edge, Merging, confuse 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; Fri, 13 Dec 2019 15:43:12 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id F2CD528253D; Fri, 13 Dec 2019 16:43:09 +0100 (CET) Date: Fri, 13 Dec 2019 16:43:09 +0100 From: Jan Hubicka To: gcc-patches@gcc.gnu.org Subject: Fix merging of common target infos Message-ID: <20191213154309.vujpkkwefivc3akh@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: NeoMutt/20170113 (1.7.2) Hi, while looking into Firefox regression compared to gcc9 I noticed that we often confuse common target infos when profiles get merged. This patch adds the missing update bits. Honza * ipa-utils.c (ipa_merge_profiles): Improve dumping; merge common targets. Index: ipa-utils.c =================================================================== --- ipa-utils.c (revision 279178) +++ ipa-utils.c (working copy) @@ -423,11 +423,6 @@ ipa_merge_profiles (struct cgraph_node * if (!src->count.initialized_p () || !(src->count.ipa () == src->count)) return; - if (symtab->dump_file) - { - fprintf (symtab->dump_file, "Merging profiles of %s to %s\n", - src->dump_name (), dst->dump_name ()); - } profile_count orig_count = dst->count; /* Either sum the profiles if both are IPA and not global0, or @@ -451,6 +446,19 @@ ipa_merge_profiles (struct cgraph_node * if (dst->count == orig_count) return; + if (symtab->dump_file) + { + fprintf (symtab->dump_file, "Merging profiles of %s count:", + src->dump_name ()); + src->count.dump (symtab->dump_file); + fprintf (symtab->dump_file, " to %s count:", + dst->dump_name ()); + orig_count.dump (symtab->dump_file); + fprintf (symtab->dump_file, " resulting count:"); + dst->count.dump (symtab->dump_file); + fprintf (symtab->dump_file, "\n"); + } + /* First handle functions with no gimple body. */ if (dst->thunk.thunk_p || dst->alias || src->thunk.thunk_p || src->alias) @@ -516,45 +524,86 @@ ipa_merge_profiles (struct cgraph_node * else { basic_block srcbb, dstbb; + struct cgraph_edge *e, *e2; - FOR_ALL_BB_FN (srcbb, srccfun) + for (e = dst->callees, e2 = src->callees; e && e2 && match; + e2 = e2->next_callee, e = e->next_callee) { - unsigned int i; - - dstbb = BASIC_BLOCK_FOR_FN (dstcfun, srcbb->index); - if (dstbb == NULL) + if (gimple_bb (e->call_stmt)->index + != gimple_bb (e2->call_stmt)->index) { if (symtab->dump_file) fprintf (symtab->dump_file, - "No matching block for bb %i.\n", - srcbb->index); + "Giving up; call stmt mismatch.\n"); match = false; - break; } - if (EDGE_COUNT (srcbb->succs) != EDGE_COUNT (dstbb->succs)) + } + if (e || e2) + { + if (symtab->dump_file) + fprintf (symtab->dump_file, + "Giving up; number of calls differs.\n"); + match = false; + } + for (e = dst->indirect_calls, e2 = src->indirect_calls; e && e2 && match; + e2 = e2->next_callee, e = e->next_callee) + { + if (gimple_bb (e->call_stmt)->index + != gimple_bb (e2->call_stmt)->index) { if (symtab->dump_file) fprintf (symtab->dump_file, - "Edge count mismatch for bb %i.\n", - srcbb->index); + "Giving up; indirect call stmt mismatch.\n"); match = false; - break; - } - for (i = 0; i < EDGE_COUNT (srcbb->succs); i++) - { - edge srce = EDGE_SUCC (srcbb, i); - edge dste = EDGE_SUCC (dstbb, i); - if (srce->dest->index != dste->dest->index) - { - if (symtab->dump_file) - fprintf (symtab->dump_file, - "Succ edge mismatch for bb %i.\n", - srce->dest->index); - match = false; - break; - } } } + if (e || e2) + { + if (symtab->dump_file) + fprintf (symtab->dump_file, + "Giving up; number of indirect calls differs.\n"); + match=false; + } + + if (match) + FOR_ALL_BB_FN (srcbb, srccfun) + { + unsigned int i; + + dstbb = BASIC_BLOCK_FOR_FN (dstcfun, srcbb->index); + if (dstbb == NULL) + { + if (symtab->dump_file) + fprintf (symtab->dump_file, + "No matching block for bb %i.\n", + srcbb->index); + match = false; + break; + } + if (EDGE_COUNT (srcbb->succs) != EDGE_COUNT (dstbb->succs)) + { + if (symtab->dump_file) + fprintf (symtab->dump_file, + "Edge count mismatch for bb %i.\n", + srcbb->index); + match = false; + break; + } + for (i = 0; i < EDGE_COUNT (srcbb->succs); i++) + { + edge srce = EDGE_SUCC (srcbb, i); + edge dste = EDGE_SUCC (dstbb, i); + if (srce->dest->index != dste->dest->index) + { + if (symtab->dump_file) + fprintf (symtab->dump_file, + "Succ edge mismatch for bb %i.\n", + srce->dest->index); + match = false; + break; + } + } + } } if (match) { @@ -626,6 +675,70 @@ ipa_merge_profiles (struct cgraph_node * e2 = (e2 ? e2->next_callee : NULL), e = e->next_callee) { profile_count count = gimple_bb (e->call_stmt)->count; + if (copy_counts) + { + e->indirect_info->common_target_id + = e2->indirect_info->common_target_id; + e->indirect_info->common_target_probability + = e2->indirect_info->common_target_probability; + } + else if (e->indirect_info->common_target_id + || e2->indirect_info->common_target_id) + { + sreal scale1 + = e->count.ipa().to_sreal_scale (count); + sreal scale2 + = e2->count.ipa().to_sreal_scale (count); + + if (scale1 == 0 && scale2 == 0) + scale1 = scale2 = 1; + sreal sum = scale1 + scale2; + int scaled_probability1 + = ((sreal)e->indirect_info->common_target_probability + * scale1 / sum).to_int (); + int scaled_probability2 + = ((sreal)e2->indirect_info->common_target_probability + * scale2 / sum).to_int (); + if (symtab->dump_file) + { + fprintf (symtab->dump_file, + "Merging common targets %i prob %i" + " and %i prob %i with scales %f %f\n", + e->indirect_info->common_target_id, + e->indirect_info->common_target_probability, + e2->indirect_info->common_target_id, + e2->indirect_info->common_target_probability, + scale1.to_double (), + scale2.to_double ()); + fprintf (symtab->dump_file, "Combined BB count "); + count.dump (symtab->dump_file); + fprintf (symtab->dump_file, " dst edge count "); + e->count.dump (symtab->dump_file); + fprintf (symtab->dump_file, " src edge count "); + e2->count.dump (symtab->dump_file); + fprintf (symtab->dump_file, "\n"); + } + if (e->indirect_info->common_target_id + == e2->indirect_info->common_target_id) + e->indirect_info->common_target_probability + = scaled_probability1 + scaled_probability2; + else if (!e2->indirect_info->common_target_id + || scaled_probability1 > scaled_probability2) + e->indirect_info->common_target_probability + = scaled_probability1; + else + { + e->indirect_info->common_target_id + = e2->indirect_info->common_target_id; + e->indirect_info->common_target_probability + = scaled_probability2; + } + if (symtab->dump_file) + fprintf (symtab->dump_file, "Merged as %i prob %i\n", + e->indirect_info->common_target_id, + e->indirect_info->common_target_probability); + } + /* When call is speculative, we need to re-distribute probabilities the same way as they was. This is not really correct because in the other copy the speculation may differ; but probably it @@ -647,8 +760,8 @@ ipa_merge_profiles (struct cgraph_node * indirect edge. */ if (!e2) { - if (dump_file) - fprintf (dump_file, + if (symtab->dump_file) + fprintf (symtab->dump_file, "Mismatch in merging indirect edges\n"); } else if (!e2->speculative)