diff gcc/optinfo-emit-json.cc @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
line wrap: on
line diff
--- a/gcc/optinfo-emit-json.cc	Thu Oct 25 07:37:49 2018 +0900
+++ b/gcc/optinfo-emit-json.cc	Thu Feb 13 11:34:05 2020 +0900
@@ -1,5 +1,5 @@
 /* Emit optimization information as JSON files.
-   Copyright (C) 2018 Free Software Foundation, Inc.
+   Copyright (C) 2018-2020 Free Software Foundation, Inc.
    Contributed by David Malcolm <dmalcolm@redhat.com>.
 
 This file is part of GCC.
@@ -45,38 +45,7 @@
 #include "pass_manager.h"
 #include "selftest.h"
 #include "dump-context.h"
-
-/* 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<json::array *> m_scopes;
-};
+#include <zlib.h>
 
 /* optrecord_json_writer's ctor.  Populate the top-level parts of the
    in-memory JSON representation.  */
@@ -133,16 +102,34 @@
 void
 optrecord_json_writer::write () const
 {
-  char *filename = concat (dump_base_name, ".opt-record.json", NULL);
-  FILE *outfile = fopen (filename, "w");
-  if (outfile)
+  pretty_printer pp;
+  m_root_tuple->print (&pp);
+
+  bool emitted_error = false;
+  char *filename = concat (dump_base_name, ".opt-record.json.gz", NULL);
+  gzFile outfile = gzopen (filename, "w");
+  if (outfile == NULL)
     {
-      m_root_tuple->dump (outfile);
-      fclose (outfile);
+      error_at (UNKNOWN_LOCATION, "cannot open file %qs for writing optimization records",
+		filename); // FIXME: more info?
+      goto cleanup;
     }
-  else
-    error_at (UNKNOWN_LOCATION, "unable to write optimization records to %qs",
-	      filename); // FIXME: more info?
+
+  if (gzputs (outfile, pp_formatted_text (&pp)) <= 0)
+    {
+      int tmp;
+      error_at (UNKNOWN_LOCATION, "error writing optimization records to %qs: %s",
+		filename, gzerror (outfile, &tmp));
+      emitted_error = true;
+    }
+
+ cleanup:
+  if (outfile)
+    if (gzclose (outfile) != Z_OK)
+      if (!emitted_error)
+	error_at (UNKNOWN_LOCATION, "error closing optimization records %qs",
+		  filename);
+
   free (filename);
 }
 
@@ -182,6 +169,9 @@
 optrecord_json_writer::pop_scope ()
 {
   m_scopes.pop ();
+
+  /* We should never pop the top-level records array.  */
+  gcc_assert (m_scopes.length () > 0);
 }
 
 /* Create a JSON object representing LOC.  */
@@ -191,7 +181,7 @@
 {
   json::object *obj = new json::object ();
   obj->set ("file", new json::string (loc.m_file));
-  obj->set ("line", new json::number (loc.m_line));
+  obj->set ("line", new json::integer_number (loc.m_line));
   if (loc.m_function)
     obj->set ("function", new json::string (loc.m_function));
   return obj;
@@ -206,8 +196,8 @@
   expanded_location exploc = expand_location (loc);
   json::object *obj = new json::object ();
   obj->set ("file", new json::string (exploc.file));
-  obj->set ("line", new json::number (exploc.line));
-  obj->set ("column", new json::number (exploc.column));
+  obj->set ("line", new json::integer_number (exploc.line));
+  obj->set ("column", new json::integer_number (exploc.column));
   return obj;
 }
 
@@ -217,7 +207,7 @@
 optrecord_json_writer::profile_count_to_json (profile_count count)
 {
   json::object *obj = new json::object ();
-  obj->set ("value", new json::number (count.to_gcov_type ()));
+  obj->set ("value", new json::integer_number (count.to_gcov_type ()));
   obj->set ("quality",
 	    new json::string (profile_quality_as_string (count.quality ())));
   return obj;
@@ -272,7 +262,7 @@
 	  && (pass->optinfo_flags & optgroup->value))
 	optgroups->append (new json::string (optgroup->name));
   }
-  obj->set ("num", new json::number (pass->static_pass_number));
+  obj->set ("num", new json::integer_number (pass->static_pass_number));
   return obj;
 }
 
@@ -421,7 +411,8 @@
 
   if (current_function_decl)
     {
-      const char *fnname = get_fnname_from_decl (current_function_decl);
+      const char *fnname
+	= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
       obj->set ("function", new json::string (fnname));
     }
 
@@ -452,75 +443,6 @@
   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 {
@@ -532,7 +454,7 @@
 test_building_json_from_dump_calls ()
 {
   temp_dump_context tmp (true, true, MSG_NOTE);
-  dump_location_t loc;
+  dump_user_location_t loc;
   dump_printf_loc (MSG_NOTE, loc, "test of tree: ");
   dump_generic_expr (MSG_NOTE, TDF_SLIM, integer_zero_node);
   optinfo *info = tmp.get_pending_optinfo ();