From patchwork Sat Nov 17 00:11:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 999214 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-490350-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="EhuYLbXs"; 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 42xbBl4WwZz9s9G for ; Sat, 17 Nov 2018 11:12:12 +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:from :to:cc:subject:date:message-id; q=dns; s=default; b=r/APVK0ZOOPN BtQKAgaQ7Y/niEwEaoCzJfWTue1vbu98qfuVf8uTGjUG0XomCRwFFSoSlkz94kMT RdfZnEv2iE5yBkH6nXmlgdwFH/8L31NV+xLJDsD09snEZ8QcbuN6zSaSvkH1MCq0 4EzNPqo6CDxObMRF1D0nJpNy7HVLWK8= 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:from :to:cc:subject:date:message-id; s=default; bh=yRy+G3qKYj6ccvffp4 yt2Uo3HJg=; b=EhuYLbXsJ1SSYtjk+yF1uhHsE08cNG6RXstnXU0AumUbho3BOl wud+62Rr6Y2tajciHHaRd1I8SB+keTrUqM5/Sn4U5Ey8HrswhbuFiFLBJo2CHDW5 RJ5kqxrikLhO7sT7Jz1uHSvKeEJUJb1f3jUOFmbyEi6ZupwWOd5sO2wf8= Received: (qmail 76834 invoked by alias); 17 Nov 2018 00:12:04 -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 76707 invoked by uid 89); 17 Nov 2018 00:11:53 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=12518, sk:fsaveo, UD:zlib.h, sk:fsave-o X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 17 Nov 2018 00:11:50 +0000 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7BC3B85362 for ; Sat, 17 Nov 2018 00:11:49 +0000 (UTC) Received: from c64.redhat.com (ovpn-112-13.phx2.redhat.com [10.3.112.13]) by smtp.corp.redhat.com (Postfix) with ESMTP id 654CE6BF93; Sat, 17 Nov 2018 00:11:48 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 1/2] Eliminate global state from -fsave-optimization-record Date: Fri, 16 Nov 2018 19:11:53 -0500 Message-Id: <1542413514-48487-1-git-send-email-dmalcolm@redhat.com> X-IsSubscribed: yes As work towards fixing PR tree-optimization/87025, this patch eliminates global state from optinfo-emit-json.cc in favor of adding an optional m_json_writer field to dump_context, replacing the m_forcibly_enable_optinfo flag. This allows for writing selftests for the interaction of the JSON-building code with the dumpfile.c code. In particular, the existing selftest that created optinfo instances now exercise the JSON-building code (although no JSON is actually written out). The patch also simplifies the layering by replacing optinfo::emit () with dump_context::emit_optinfo, so that dump_context has responsibility for keeping track of dump destinations. Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu (in conjuction with the followup patch) OK for trunk? gcc/ChangeLog: PR tree-optimization/87025 * dump-context.h: Include "optinfo.h". (class optrecord_json_writer): New forward decl. (dump_context::forcibly_enable_optinfo_p): Delete. (dump_context::optinfo_enabled_p): New member function. (dump_context::optimization_records_enabled_p): New member function. (dump_context::set_json_writer): New member function. (dump_context::emit_optinfo): New member function. (dump_context::m_forcibly_enable_optinfo): Delete. (dump_context::m_json_writer): New member data. * dumpfile.c (dump_context::set_json_writer): New member function. (dump_context::finish_any_json_writer): New member function. (dump_context::end_scope): Replace call to optimization_records_maybe_pop_dump_scope with call to m_json_writer->pop_scope. (dump_context::optinfo_enabled_p): New member function. (dump_context::end_any_optinfo): Replace call to optinfo::emit with call to dump_context::emit_optinfo. (dump_context::emit_optinfo): New member function. (temp_dump_context::temp_dump_context): Replace m_forcibly_enable_optinfo with call to set_json_writer. (temp_dump_context::~temp_dump_context): Clean up any json writer. * optinfo-emit-json.cc (class optrecord_json_writer): Move to optinfo-emit-json.h (the_json_writer): Delete. (optimization_records_start): Delete. (optimization_records_finish): Delete. (optimization_records_enabled_p): Delete, in favor of dump_context::optimization_records_enabled_p. (optimization_records_maybe_record_optinfo): Delete. (optimization_records_maybe_pop_dump_scope): Delete. * optinfo-emit-json.h: Include "json.h". Delete forward decl of opt_pass. (optimization_records_start): Delete. (optimization_records_finish): Delete. (optimization_records_enabled_p): Delete. (optimization_records_maybe_record_optinfo): Delete. (optimization_records_maybe_pop_dump_scope): Delete. (class optrecord_json_writer): Move here from optinfo-emit-json.cc. * optinfo.cc (optinfo::emit_for_opt_problem): Replace call to optinfo::emit with call to dump_context::emit_optinfo. (optinfo::emit): Delete, in favor of dump_context::emit_optinfo. (optinfo_enabled_p): Delete, in favor of dump_context::optinfo_enabled_p. (optinfo_wants_inlining_info_p): Update for conversion o optimization_records_enabled_p to a member function of dump_context. * optinfo.h (optinfo_enabled_p): Delete, in favor of dump_context::optinfo_enabled_p. (optinfo::emit): Delete, in favor of dump_context::emit_optinfo. * toplev.c: Include "dump-context.h". (compile_file): Replace call to optimization_records_finish with dump_context::finish_any_json_writer. (do_compile): Replace call to optimization_records_start with conditionally creating a optrecord_json_writer for the dump_context. --- gcc/dump-context.h | 22 ++++++++--- gcc/dumpfile.c | 55 ++++++++++++++++++++++++-- gcc/optinfo-emit-json.cc | 101 ----------------------------------------------- gcc/optinfo-emit-json.h | 42 +++++++++++++++----- gcc/optinfo.cc | 25 +----------- gcc/optinfo.h | 8 ---- gcc/toplev.c | 8 +++- 7 files changed, 109 insertions(+), 152 deletions(-) diff --git a/gcc/dump-context.h b/gcc/dump-context.h index ace139c..2016ce7 100644 --- a/gcc/dump-context.h +++ b/gcc/dump-context.h @@ -25,7 +25,9 @@ along with GCC; see the file COPYING3. If not see #include "dumpfile.h" #include "pretty-print.h" #include "selftest.h" +#include "optinfo.h" +class optrecord_json_writer; namespace selftest { class temp_dump_context; } /* A class for handling the various dump_* calls. @@ -95,14 +97,21 @@ class dump_context void begin_scope (const char *name, const dump_location_t &loc); void end_scope (); - /* For use in selftests; if true then optinfo_enabled_p is true. */ - bool forcibly_enable_optinfo_p () const + /* Should optinfo instances be created? + All creation of optinfos should be guarded by this predicate. + Return true if any optinfo destinations are active. */ + bool optinfo_enabled_p () const; + + bool optimization_records_enabled_p () const { - return m_forcibly_enable_optinfo; + return m_json_writer != NULL; } + void set_json_writer (optrecord_json_writer *writer); + void finish_any_json_writer (); void end_any_optinfo (); + void emit_optinfo (const optinfo *info); void emit_item (optinfo_item *item, dump_flags_t dump_kind); bool apply_dump_filter_p (dump_flags_t dump_kind, dump_flags_t filter) const; @@ -111,9 +120,6 @@ class dump_context optinfo &ensure_pending_optinfo (); optinfo &begin_next_optinfo (const dump_location_t &loc); - /* For use in selftests; if true then optinfo_enabled_p is true. */ - bool m_forcibly_enable_optinfo; - /* The current nesting depth of dump scopes, for showing nesting via indentation). */ unsigned int m_scope_depth; @@ -122,6 +128,10 @@ class dump_context if any. */ optinfo *m_pending; + /* If -fsave-optimization-record is enabled, the heap-allocated JSON writer + instance, otherwise NULL. */ + optrecord_json_writer *m_json_writer; + /* For use in selftests: if non-NULL, then items are to be printed to this, using the given flags. */ pretty_printer *m_test_pp; diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c index 86651df..014acf1 100644 --- a/gcc/dumpfile.c +++ b/gcc/dumpfile.c @@ -515,6 +515,28 @@ dump_context::~dump_context () delete m_pending; } +void +dump_context::set_json_writer (optrecord_json_writer *writer) +{ + delete m_json_writer; + m_json_writer = writer; +} + +/* Perform cleanup activity for -fsave-optimization-record. + Currently, the file is written out here in one go, before cleaning + up. */ + +void +dump_context::finish_any_json_writer () +{ + if (!m_json_writer) + return; + + m_json_writer->write (); + delete m_json_writer; + m_json_writer = NULL; +} + /* Update the "dumps_are_enabled" global; to be called whenever dump_file or alt_dump_file change, or when changing dump_context in selftests. */ @@ -1121,7 +1143,19 @@ dump_context::end_scope () { end_any_optinfo (); m_scope_depth--; - optimization_records_maybe_pop_dump_scope (); + + if (m_json_writer) + m_json_writer->pop_scope (); +} + +/* Should optinfo instances be created? + All creation of optinfos should be guarded by this predicate. + Return true if any optinfo destinations are active. */ + +bool +dump_context::optinfo_enabled_p () const +{ + return (optimization_records_enabled_p ()); } /* Return the optinfo currently being accumulated, creating one if @@ -1154,11 +1188,23 @@ void dump_context::end_any_optinfo () { if (m_pending) - m_pending->emit (); + emit_optinfo (m_pending); delete m_pending; m_pending = NULL; } +/* Emit the optinfo to all of the "non-immediate" destinations + (emission to "immediate" destinations is done by + dump_context::emit_item). */ + +void +dump_context::emit_optinfo (const optinfo *info) +{ + /* -fsave-optimization-record. */ + if (m_json_writer) + m_json_writer->add_record (info); +} + /* Emit ITEM to all item destinations (those that don't require consolidation into optinfo instances). */ @@ -2004,7 +2050,8 @@ temp_dump_context::temp_dump_context (bool forcibly_enable_optinfo, m_saved (&dump_context ().get ()) { dump_context::s_current = &m_context; - m_context.m_forcibly_enable_optinfo = forcibly_enable_optinfo; + if (forcibly_enable_optinfo) + m_context.set_json_writer (new optrecord_json_writer ()); /* Conditionally enable the test dump, so that we can verify both the dump_enabled_p and the !dump_enabled_p cases in selftests. */ if (forcibly_enable_dumping) @@ -2020,6 +2067,8 @@ temp_dump_context::temp_dump_context (bool forcibly_enable_optinfo, temp_dump_context::~temp_dump_context () { + m_context.set_json_writer (NULL); + dump_context::s_current = m_saved; dump_context::get ().refresh_dumps_are_enabled (); diff --git a/gcc/optinfo-emit-json.cc b/gcc/optinfo-emit-json.cc index 6d4502c..4fa6708 100644 --- a/gcc/optinfo-emit-json.cc +++ b/gcc/optinfo-emit-json.cc @@ -47,38 +47,6 @@ along with GCC; see the file COPYING3. If not see #include "dump-context.h" #include -/* A class for writing out optimization records in JSON format. */ - -class optrecord_json_writer -{ -public: - optrecord_json_writer (); - ~optrecord_json_writer (); - void write () const; - void add_record (const optinfo *optinfo); - void pop_scope (); - - void add_record (json::object *obj); - json::object *impl_location_to_json (dump_impl_location_t loc); - json::object *location_to_json (location_t loc); - json::object *profile_count_to_json (profile_count count); - json::string *get_id_value_for_pass (opt_pass *pass); - json::object *pass_to_json (opt_pass *pass); - json::value *inlining_chain_to_json (location_t loc); - json::object *optinfo_to_json (const optinfo *optinfo); - void add_pass_list (json::array *arr, opt_pass *pass); - -private: - /* The root value for the JSON file. - Currently the JSON values are stored in memory, and flushed when the - compiler exits. It would probably be better to simply write out - the JSON as we go. */ - json::array *m_root_tuple; - - /* The currently open scopes, for expressing nested optimization records. */ - auto_vec m_scopes; -}; - /* optrecord_json_writer's ctor. Populate the top-level parts of the in-memory JSON representation. */ @@ -471,75 +439,6 @@ optrecord_json_writer::add_pass_list (json::array *arr, opt_pass *pass) while (pass); } -/* File-level interface to rest of compiler (to avoid exposing - class optrecord_json_writer outside of this file). */ - -static optrecord_json_writer *the_json_writer; - -/* Perform startup activity for -fsave-optimization-record. */ - -void -optimization_records_start () -{ - /* Bail if recording not enabled. */ - if (!flag_save_optimization_record) - return; - - the_json_writer = new optrecord_json_writer (); -} - -/* Perform cleanup activity for -fsave-optimization-record. - - Currently, the file is written out here in one go, before cleaning - up. */ - -void -optimization_records_finish () -{ - /* Bail if recording not enabled. */ - if (!the_json_writer) - return; - - the_json_writer->write (); - - delete the_json_writer; - the_json_writer = NULL; -} - -/* Did the user request optimization records to be written out? */ - -bool -optimization_records_enabled_p () -{ - return the_json_writer != NULL; -} - -/* If optimization records were requested, then add a record for OPTINFO - to the queue of records to be written. */ - -void -optimization_records_maybe_record_optinfo (const optinfo *optinfo) -{ - /* Bail if recording not enabled. */ - if (!the_json_writer) - return; - - the_json_writer->add_record (optinfo); -} - -/* Handling for the end of a dump scope for the - optimization records sink. */ - -void -optimization_records_maybe_pop_dump_scope () -{ - /* Bail if recording not enabled. */ - if (!the_json_writer) - return; - - the_json_writer->pop_scope (); -} - #if CHECKING_P namespace selftest { diff --git a/gcc/optinfo-emit-json.h b/gcc/optinfo-emit-json.h index 3628d56..2185c08 100644 --- a/gcc/optinfo-emit-json.h +++ b/gcc/optinfo-emit-json.h @@ -21,16 +21,40 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_OPTINFO_EMIT_JSON_H #define GCC_OPTINFO_EMIT_JSON_H -class optinfo; -struct opt_pass; - -extern void optimization_records_start (); -extern void optimization_records_finish (); +#include "json.h" -extern bool optimization_records_enabled_p (); - -extern void optimization_records_maybe_record_optinfo (const optinfo *); -extern void optimization_records_maybe_pop_dump_scope (); +class optinfo; +/* A class for writing out optimization records in JSON format. */ + +class optrecord_json_writer +{ +public: + optrecord_json_writer (); + ~optrecord_json_writer (); + void write () const; + void add_record (const optinfo *optinfo); + void pop_scope (); + + void add_record (json::object *obj); + json::object *impl_location_to_json (dump_impl_location_t loc); + json::object *location_to_json (location_t loc); + json::object *profile_count_to_json (profile_count count); + json::string *get_id_value_for_pass (opt_pass *pass); + json::object *pass_to_json (opt_pass *pass); + json::value *inlining_chain_to_json (location_t loc); + json::object *optinfo_to_json (const optinfo *optinfo); + void add_pass_list (json::array *arr, opt_pass *pass); + + private: + /* The root value for the JSON file. + Currently the JSON values are stored in memory, and flushed when the + compiler exits. It would probably be better to simply write out + the JSON as we go. */ + json::array *m_root_tuple; + + /* The currently open scopes, for expressing nested optimization records. */ + auto_vec m_scopes; +}; #endif /* #ifndef GCC_OPTINFO_EMIT_JSON_H */ diff --git a/gcc/optinfo.cc b/gcc/optinfo.cc index de781a5..f8e08de 100644 --- a/gcc/optinfo.cc +++ b/gcc/optinfo.cc @@ -125,18 +125,7 @@ optinfo::emit_for_opt_problem () const dump_context::get ().emit_item (item, dump_kind); /* Re-emit to "non-immediate" destinations. */ - emit (); -} - -/* Emit the optinfo to all of the "non-immediate" destinations - (emission to "immediate" destinations is done by - dump_context::emit_item). */ - -void -optinfo::emit () const -{ - /* -fsave-optimization-record. */ - optimization_records_maybe_record_optinfo (this); + dump_context::get ().emit_optinfo (this); } /* Update the optinfo's kind based on DUMP_KIND. */ @@ -152,21 +141,11 @@ optinfo::handle_dump_file_kind (dump_flags_t dump_kind) m_kind = OPTINFO_KIND_NOTE; } -/* Should optinfo instances be created? - All creation of optinfos should be guarded by this predicate. - Return true if any optinfo destinations are active. */ - -bool optinfo_enabled_p () -{ - return (dump_context::get ().forcibly_enable_optinfo_p () - || optimization_records_enabled_p ()); -} - /* Return true if any of the active optinfo destinations make use of inlining information. (if true, then the information is preserved). */ bool optinfo_wants_inlining_info_p () { - return optimization_records_enabled_p (); + return dump_context::get ().optimization_records_enabled_p (); } diff --git a/gcc/optinfo.h b/gcc/optinfo.h index 99bd22c..4a678ff 100644 --- a/gcc/optinfo.h +++ b/gcc/optinfo.h @@ -68,12 +68,6 @@ along with GCC; see the file COPYING3. If not see struct opt_pass; class optinfo_item; -/* Should optinfo instances be created? - All creation of optinfos should be guarded by this predicate. - Return true if any optinfo destinations are active. */ - -extern bool optinfo_enabled_p (); - /* Return true if any of the active optinfo destinations make use of inlining information. (if true, then the information is preserved). */ @@ -130,8 +124,6 @@ class optinfo void emit_for_opt_problem () const; private: - void emit () const; - /* Pre-canned ways of manipulating the optinfo, for use by friend class dump_context. */ void handle_dump_file_kind (dump_flags_t); diff --git a/gcc/toplev.c b/gcc/toplev.c index 3fd4ec4..ab20cd9 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -83,6 +83,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "dumpfile.h" #include "ipa-fnsummary.h" +#include "dump-context.h" #include "optinfo-emit-json.h" #if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) @@ -488,7 +489,7 @@ compile_file (void) if (lang_hooks.decls.post_compilation_parsing_cleanups) lang_hooks.decls.post_compilation_parsing_cleanups (); - optimization_records_finish (); + dump_context::get ().finish_any_json_writer (); if (seen_error ()) return; @@ -2131,7 +2132,10 @@ do_compile () timevar_start (TV_PHASE_SETUP); - optimization_records_start (); + if (flag_save_optimization_record) + { + dump_context::get ().set_json_writer (new optrecord_json_writer ()); + } /* This must be run always, because it is needed to compute the FP predefined macros, such as __LDBL_MAX__, for targets using non