From patchwork Thu Aug 29 15:57:45 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Teresa Johnson X-Patchwork-Id: 270875 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "www.sourceware.org", Issuer "StartCom Class 1 Primary Intermediate Server CA" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 82F222C009C for ; Fri, 30 Aug 2013 01:57:58 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; q=dns; s=default; b=FStN0+NnZI2fRLtgkE G7A/4fbJU9RBVo0DN62hjLHnflM3hrSvv4Gz+Ji9nmrlNTu4jJGT5wVqCp+2MQ1G K9p9wllStqabs/Ys4SpCVREnjkaisC417wCtIMlvqxfrM6aVlr5AJTY43y9bIDAR wHAVQWozrBXUOz50mm7IlaAg0= 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 :mime-version:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; s=default; bh=Ps0kZXpBUKzORtTOMla+LI5k Cn0=; b=qQrlpKOqdqzDKXlmYUz3wkeZuF0GCDKnLyilZ5OGYSo49+RhF+B5lxRS cPFafvy7acbnRCMS7MU2yP0zbKIENOFKIQBPvzmLpQre7sO9VOqBtuuf/W/pdx/X xsrqhInfUhB6ffDk+yf2X42FaQHxXZq8DEZ9eVfgXJfToujWxPs= Received: (qmail 7890 invoked by alias); 29 Aug 2013 15:57:50 -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 7877 invoked by uid 89); 29 Aug 2013 15:57:49 -0000 Received: from mail-qc0-f182.google.com (HELO mail-qc0-f182.google.com) (209.85.216.182) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Thu, 29 Aug 2013 15:57:49 +0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.3 required=5.0 tests=AWL, BAYES_00, KHOP_THREADED, NO_RELAYS autolearn=ham version=3.3.2 X-HELO: mail-qc0-f182.google.com Received: by mail-qc0-f182.google.com with SMTP id k18so280573qcv.27 for ; Thu, 29 Aug 2013 08:57:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=Vh3t645w4YtgzKd2D82myVUhIwr/YLxAiFmKgd/ghYw=; b=dfKGcHsMvf64tAcIY9sd0CZ+l79asikSu3fxu6OQ6CTQrTVEyBJgMBzhvfq5rJeGzj oCSvHHVN5RuwEfJYWB19vtNogBWdLACshFctlaBHJMBcQymssyRYT1tdt6Uvok0aOC2A j5+BlgphC4q57wMlpkeTf9O886z6MSpcfepgAGNuzeSBqvvZDpfWtBP4Q+yHlQhLSPmr WCUcQbhnHAbQcChD/Sf0TjRrIZzCgrxpEinR3lP7YcwWdQS2rleQz3vUmt2s9aacxoHp YFwJ4VtO01qM5Br8Pv0H1egSFlTkK1zKmo8wfZh3bhyc6tnWRViO/awenZEOl6KunCOK +dSQ== X-Gm-Message-State: ALoCoQmx4K3rZ9cBRkYYDdThBqc5JGL6Ea8oRRGgID3E2bTFnOH2YqETD5t0Xd9AZ9pmYnzTd28wWIPd4qkHunSPg/smxrAeGoCeFomErStg70pWE20CpLF4xXmgrKFSFHMYsCnypSl6G2ifCKGVPGMv+mD6i9KU1o2UGGHNvv/+/cV/rXwgk1HCRa8EazEXQT64WblMtsGB41jXejrYhPxHZM+JT2ReYw== MIME-Version: 1.0 X-Received: by 10.49.82.43 with SMTP id f11mr4849110qey.26.1377791865935; Thu, 29 Aug 2013 08:57:45 -0700 (PDT) Received: by 10.49.40.161 with HTTP; Thu, 29 Aug 2013 08:57:45 -0700 (PDT) In-Reply-To: References: <20130806123714.GD3166@virgil.suse> <20130806160102.GE3166@virgil.suse> Date: Thu, 29 Aug 2013 08:57:45 -0700 Message-ID: Subject: Re: [PATCH] Convert more passes to new dump framework From: Teresa Johnson To: Richard Biener Cc: "gcc-patches@gcc.gnu.org" , Dehao Chen , Sharad Singhai , David Li On Wed, Aug 28, 2013 at 7:09 AM, Teresa Johnson wrote: >> The inline stuff should be split and re-sent, it's non-obvious to me (extra >> function parameters are not documented for example). I'd rather have >> inline_and_report_call () for example instead of an extra bool parameter. >> But let's iterate over this once it's split out. > > Ok, I will send this separately. I guess we could have a separate > interface inline_and_report_call that is a wrapper around inline_call > and simply invokes the dumper. Note that flatten_function will need to > conditionally call one of the two interfaces based on the value of its > bool early parameter though. Here is the split out patch. I realized why I need the extra bool parameter to indicate early inlining: the early inliner messages are emitted only under the more verbose MSG_NOTE, so we need to know whether we are in early or ipa inlining in dump_inline_decision. I have documented the additional parameter. Thanks, Teresa 2013-08-29 Teresa Johnson Dehao Chen * ipa-inline.c (recursive_inlining): New inline_call parameter. (inline_small_functions): Ditto. (flatten_function): Ditto. (ipa_inline): Ditto. (inline_always_inline_functions): Ditto. (early_inline_small_functions): Ditto. * ipa-inline.h: Ditto. * ipa-inline-transform.c (cgraph_node_opt_info): New function. (cgraph_node_call_chain): Ditto. (dump_inline_decision): Ditto. (inline_call): Invoke dump_inline_decision, new parameter. result of inlining. */ @@ -215,7 +322,8 @@ clone_inlined_nodes (struct cgraph_edge *e, bool d bool inline_call (struct cgraph_edge *e, bool update_original, vec *new_edges, - int *overall_size, bool update_overall_summary) + int *overall_size, bool update_overall_summary, + bool early) { int old_size = 0, new_size = 0; struct cgraph_node *to = NULL; @@ -228,6 +336,9 @@ inline_call (struct cgraph_edge *e, bool update_or bool predicated = inline_edge_summary (e)->predicate != NULL; #endif + if (dump_enabled_p ()) + dump_inline_decision (e, early); + speculation_removed = false; /* Don't inline inlined edges. */ gcc_assert (e->inline_failed); Index: ipa-inline.c =================================================================== --- ipa-inline.c (revision 202059) +++ ipa-inline.c (working copy) @@ -1342,7 +1342,7 @@ recursive_inlining (struct cgraph_edge *edge, reset_edge_growth_cache (curr); } - inline_call (curr, false, new_edges, &overall_size, true); + inline_call (curr, false, new_edges, &overall_size, true, false); lookup_recursive_calls (node, curr->callee, heap); n++; } @@ -1757,7 +1757,8 @@ inline_small_functions (void) fprintf (dump_file, " Peeling recursion with depth %i\n", depth); gcc_checking_assert (!callee->global.inlined_to); - inline_call (edge, true, &new_indirect_edges, &overall_size, true); + inline_call (edge, true, &new_indirect_edges, &overall_size, true, + false); if (flag_indirect_inlining) add_new_edges_to_heap (edge_heap, new_indirect_edges); @@ -1879,7 +1880,7 @@ flatten_function (struct cgraph_node *node, bool e xstrdup (cgraph_node_name (callee)), xstrdup (cgraph_node_name (e->caller))); orig_callee = callee; - inline_call (e, true, NULL, NULL, false); + inline_call (e, true, NULL, NULL, false, early); if (e->callee != orig_callee) orig_callee->symbol.aux = (void *) node; flatten_function (e->callee, early); @@ -2017,7 +2018,7 @@ ipa_inline (void) inline_summary (node->callers->caller)->size); } - inline_call (node->callers, true, NULL, NULL, true); + inline_call (node->callers, true, NULL, NULL, true, false); if (dump_file) fprintf (dump_file, " Inlined into %s which now has %i size\n", @@ -2089,7 +2090,7 @@ inline_always_inline_functions (struct cgraph_node fprintf (dump_file, " Inlining %s into %s (always_inline).\n", xstrdup (cgraph_node_name (e->callee)), xstrdup (cgraph_node_name (e->caller))); - inline_call (e, true, NULL, NULL, false); + inline_call (e, true, NULL, NULL, false, true); inlined = true; } if (inlined) @@ -2141,7 +2142,7 @@ early_inline_small_functions (struct cgraph_node * fprintf (dump_file, " Inlining %s into %s.\n", xstrdup (cgraph_node_name (callee)), xstrdup (cgraph_node_name (e->caller))); - inline_call (e, true, NULL, NULL, true); + inline_call (e, true, NULL, NULL, true, true); inlined = true; } Index: ipa-inline.h =================================================================== --- ipa-inline.h (revision 202059) +++ ipa-inline.h (working copy) @@ -229,7 +229,8 @@ void compute_inline_parameters (struct cgraph_node bool speculation_useful_p (struct cgraph_edge *e, bool anticipate_inlining); /* In ipa-inline-transform.c */ -bool inline_call (struct cgraph_edge *, bool, vec *, int *, bool); +bool inline_call (struct cgraph_edge *, bool, vec *, int *, + bool, bool); unsigned int inline_transform (struct cgraph_node *); void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *); Index: ipa-inline-transform.c =================================================================== --- ipa-inline-transform.c (revision 202059) +++ ipa-inline-transform.c (working copy) @@ -202,12 +202,119 @@ clone_inlined_nodes (struct cgraph_edge *e, bool d } +#define MAX_INT_LENGTH 20 + +/* Return NODE's name and profile count, if available. */ + +static const char * +cgraph_node_opt_info (struct cgraph_node *node) +{ + char *buf; + size_t buf_size; + const char *bfd_name = lang_hooks.dwarf_name (node->symbol.decl, 0); + + if (!bfd_name) + bfd_name = "unknown"; + + buf_size = strlen (bfd_name) + 1; + if (profile_info) + buf_size += (MAX_INT_LENGTH + 3); + buf_size += MAX_INT_LENGTH; + + buf = (char *) xmalloc (buf_size); + + strcpy (buf, bfd_name); + sprintf (buf, "%s/%i", buf, node->symbol.order); + + if (profile_info) + sprintf (buf, "%s ("HOST_WIDEST_INT_PRINT_DEC")", buf, node->count); + return buf; +} + + +/* Return CALLER's inlined call chain. Save the cgraph_node of the ultimate + function that the caller is inlined to in FINAL_CALLER. */ + +static const char * +cgraph_node_call_chain (struct cgraph_node *caller, + struct cgraph_node **final_caller) +{ + struct cgraph_node *node; + const char *via_str = " (via inline instance"; + size_t current_string_len = strlen (via_str) + 1; + size_t buf_size = current_string_len; + char *buf = (char *) xmalloc (buf_size); + + buf[0] = 0; + gcc_assert (caller->global.inlined_to != NULL); + strcat (buf, via_str); + for (node = caller; node->global.inlined_to != NULL; + node = node->callers->caller) + { + const char *name = cgraph_node_opt_info (node); + current_string_len += (strlen (name) + 1); + if (current_string_len >= buf_size) + { + buf_size = current_string_len * 2; + buf = (char *) xrealloc (buf, buf_size); + } + strcat (buf, " "); + strcat (buf, name); + } + strcat (buf, ")"); + *final_caller = node; + return buf; +} + + +/* Dump the inline decision of EDGE. If EARLY is true this is called + from early inlining, which is printed only under more verbose + reporting options, otherwise we are in ipa inlining. */ + +static void +dump_inline_decision (struct cgraph_edge *edge, bool early) +{ + location_t locus; + const char *inline_chain_text; + const char *call_count_text; + struct cgraph_node *final_caller = edge->caller; + + if (final_caller->global.inlined_to != NULL) + inline_chain_text = cgraph_node_call_chain (final_caller, &final_caller); + else + inline_chain_text = ""; + + if (edge->count > 0) + { + const char *call_count_str = " with call count "; + char *buf = (char *) xmalloc (strlen (call_count_str) + MAX_INT_LENGTH); + sprintf (buf, "%s"HOST_WIDEST_INT_PRINT_DEC, call_count_str, + edge->count); + call_count_text = buf; + } + else + { + call_count_text = ""; + } + + locus = gimple_location (edge->call_stmt); + dump_printf_loc (early ? MSG_NOTE : MSG_OPTIMIZED_LOCATIONS, + locus, + "%s inlined into %s%s%s\n", + cgraph_node_opt_info (edge->callee), + cgraph_node_opt_info (final_caller), + call_count_text, + inline_chain_text); +} + + /* Mark edge E as inlined and update callgraph accordingly. UPDATE_ORIGINAL specify whether profile of original function should be updated. If any new indirect edges are discovered in the process, add them to NEW_EDGES, unless - it is NULL. If UPDATE_OVERALL_SUMMARY is false, do not bother to recompute overall - size of caller after inlining. Caller is required to eventually do it via - inline_update_overall_summary. + it is NULL. If UPDATE_OVERALL_SUMMARY is false, do not bother to recompute + overall size of caller after inlining. Caller is required to eventually do + it via inline_update_overall_summary. If EARLY is true then we are in + early inlining, otherwise ipa inlining. Return true iff any new callgraph edges were discovered as a