re PR debug/66691 (ICE on valid code at -O3 with -g enabled in simplify_subreg, at...
[gcc.git] / gcc / dumpfile.c
index e80f9bf37e27fd48fcae2fa63b2fd71e636e61cc..d5f601f139de66d6a1d5020ab8e79867820aff9a 100644 (file)
@@ -1,5 +1,5 @@
 /* Dump infrastructure for optimizations and intermediate representation.
-   Copyright (C) 2012-2013 Free Software Foundation, Inc.
+   Copyright (C) 2012-2015 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -22,6 +22,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "diagnostic-core.h"
 #include "dumpfile.h"
+#include "alias.h"
+#include "symtab.h"
+#include "options.h"
 #include "tree.h"
 #include "gimple-pretty-print.h"
 #include "context.h"
@@ -49,29 +52,29 @@ int dump_flags;
    TREE_DUMP_INDEX enumeration in dumpfile.h.  */
 static struct dump_file_info dump_files[TDI_end] =
 {
-  {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0},
+  {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, false},
   {".cgraph", "ipa-cgraph", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
-   0, 0, 0, 0, 0},
+   0, 0, 0, 0, 0, false},
   {".type-inheritance", "ipa-type-inheritance", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
-   0, 0, 0, 0, 0},
+   0, 0, 0, 0, 0, false},
   {".tu", "translation-unit", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
-   0, 0, 0, 0, 1},
+   0, 0, 0, 0, 1, false},
   {".class", "class-hierarchy", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
-   0, 0, 0, 0, 2},
+   0, 0, 0, 0, 2, false},
   {".original", "tree-original", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
-   0, 0, 0, 0, 3},
+   0, 0, 0, 0, 3, false},
   {".gimple", "tree-gimple", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
-   0, 0, 0, 0, 4},
+   0, 0, 0, 0, 4, false},
   {".nested", "tree-nested", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
-   0, 0, 0, 0, 5},
+   0, 0, 0, 0, 5, false},
 #define FIRST_AUTO_NUMBERED_DUMP 6
 
   {NULL, "tree-all", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
-   0, 0, 0, 0, 0},
+   0, 0, 0, 0, 0, false},
   {NULL, "rtl-all", NULL, NULL, NULL, NULL, NULL, TDF_RTL,
-   0, 0, 0, 0, 0},
+   0, 0, 0, 0, 0, false},
   {NULL, "ipa-all", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
-   0, 0, 0, 0, 0},
+   0, 0, 0, 0, 0, false},
 };
 
 /* Define a name->number mapping for a dump flag value.  */
@@ -107,6 +110,10 @@ static const struct dump_option_value_info dump_options[] =
   {"nouid", TDF_NOUID},
   {"enumerate_locals", TDF_ENUMERATE_LOCALS},
   {"scev", TDF_SCEV},
+  {"optimized", MSG_OPTIMIZED_LOCATIONS},
+  {"missed", MSG_MISSED_OPTIMIZATION},
+  {"note", MSG_NOTE},
+  {"optall", MSG_ALL},
   {"all", ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_TREE | TDF_RTL | TDF_IPA
            | TDF_STMTADDR | TDF_GRAPH | TDF_DIAGNOSTIC | TDF_VERBOSE
            | TDF_RHS_ONLY | TDF_NOUID | TDF_ENUMERATE_LOCALS | TDF_SCEV)},
@@ -144,10 +151,32 @@ gcc::dump_manager::dump_manager ():
 {
 }
 
+gcc::dump_manager::~dump_manager ()
+{
+  for (size_t i = 0; i < m_extra_dump_files_in_use; i++)
+    {
+      dump_file_info *dfi = &m_extra_dump_files[i];
+      /* suffix, swtch, glob are statically allocated for the entries
+        in dump_files, and for statistics, but are dynamically allocated
+        for those for passes.  */
+      if (dfi->owns_strings)
+       {
+         XDELETEVEC (const_cast <char *> (dfi->suffix));
+         XDELETEVEC (const_cast <char *> (dfi->swtch));
+         XDELETEVEC (const_cast <char *> (dfi->glob));
+       }
+      /* These, if non-NULL, are always dynamically allocated.  */
+      XDELETEVEC (const_cast <char *> (dfi->pfilename));
+      XDELETEVEC (const_cast <char *> (dfi->alt_filename));
+    }
+  XDELETEVEC (m_extra_dump_files);
+}
+
 unsigned int
 gcc::dump_manager::
 dump_register (const char *suffix, const char *swtch, const char *glob,
-              int flags, int optgroup_flags)
+              int flags, int optgroup_flags,
+              bool take_ownership)
 {
   int num = m_next_dump++;
 
@@ -171,6 +200,7 @@ dump_register (const char *suffix, const char *swtch, const char *glob,
   m_extra_dump_files[count].pflags = flags;
   m_extra_dump_files[count].optgroup_flags = optgroup_flags;
   m_extra_dump_files[count].num = num;
+  m_extra_dump_files[count].owns_strings = take_ownership;
 
   return count + TDI_end;
 }
@@ -190,21 +220,54 @@ get_dump_file_info (int phase) const
     return m_extra_dump_files + (phase - TDI_end);
 }
 
+/* Locate the dump_file_info with swtch equal to SWTCH,
+   or return NULL if no such dump_file_info exists.  */
+
+struct dump_file_info *
+gcc::dump_manager::
+get_dump_file_info_by_switch (const char *swtch) const
+{
+  for (unsigned i = 0; i < m_extra_dump_files_in_use; i++)
+    if (0 == strcmp (m_extra_dump_files[i].swtch, swtch))
+      return &m_extra_dump_files[i];
+
+  /* Not found.  */
+  return NULL;
+}
+
 
 /* Return the name of the dump file for the given phase.
+   The caller is responsible for calling free on the returned
+   buffer.
    If the dump is not enabled, returns NULL.  */
 
 char *
 gcc::dump_manager::
 get_dump_file_name (int phase) const
 {
-  char dump_id[10];
   struct dump_file_info *dfi;
 
   if (phase == TDI_none)
     return NULL;
 
   dfi = get_dump_file_info (phase);
+
+  return get_dump_file_name (dfi);
+}
+
+/* Return the name of the dump file for the given dump_file_info.
+   The caller is responsible for calling free on the returned
+   buffer.
+   If the dump is not enabled, returns NULL.  */
+
+char *
+gcc::dump_manager::
+get_dump_file_name (struct dump_file_info *dfi) const
+{
+  char dump_id[10];
+
+  gcc_assert (dfi);
+
   if (dfi->pstate == 0)
     return NULL;