re checking -fdump-passes
authorXinliang David Li <davidxl@gcc.gnu.org>
Fri, 10 Jun 2011 20:19:28 +0000 (20:19 +0000)
committerXinliang David Li <davidxl@gcc.gnu.org>
Fri, 10 Jun 2011 20:19:28 +0000 (20:19 +0000)
From-SVN: r174930

gcc/ChangeLog
gcc/cgraphunit.c
gcc/common.opt
gcc/doc/invoke.texi
gcc/passes.c
gcc/testsuite/gcc.dg/dump-pass.c
gcc/tree-pass.h

index be07c9afd0c6d511a71de9568ef6e12efaf7736f..712e22009cca137f2c623555f0e478fd2b9131b9 100644 (file)
@@ -1,3 +1,13 @@
+2011-06-10  David Li  <davidxl@google.com>
+
+       * cgraphunit.c (cgraph_finalize_compilation_unit): Pass dump.
+       * passes.c (passr_eq): New function.
+       (create_pass_tab): New function.
+       (pass_traverse): New function.
+       (dump_one_pass): New function.
+       (dump_pass_list): New function.
+       (dump_passes): New function.
+
 2011-06-10  Jan Hubicka  <jh@suse.cz>
 
        * cgraph.c (cgraph_set_nothrow_flag_1): Update cgraph after
        register classes.
        * doc/tm.texi: Regenerate.
 
+>>>>>>> .r174929
 2011-06-09  Kaz Kojima  <kkojima@gcc.gnu.org>
 
        PR target/49307
index 1e3aa0ddf19f1b3f58509200ac59066ff0c4588a..dd247eb231d7b6a44f55341baa08d557e928d067 100644 (file)
@@ -1106,6 +1106,9 @@ cgraph_finalize_compilation_unit (void)
       fflush (stderr);
     }
 
+  if (flag_dump_passes)
+    dump_passes ();
+
   /* Gimplify and lower all functions, compute reachability and
      remove unreachable nodes.  */
   cgraph_analyze_functions ();
index d412f57202008c593cdd9c6baddf1cc20664eab9..d1f286f164ee010d3b3d2aaff1e28c0658dcb1b3 100644 (file)
@@ -1012,6 +1012,10 @@ fdump-noaddr
 Common Report Var(flag_dump_noaddr)
 Suppress output of addresses in debugging dumps
 
+fdump-passes
+Common Var(flag_dump_passes) Init(0)
+Dump optimization passes
+
 fdump-unnumbered
 Common Report Var(flag_dump_unnumbered)
 Suppress output of instruction numbers, line number notes and addresses in debugging dumps
index fee3a2f6356d9e8185b0792b4fadf0d69db653e0..44a17b041f147a2221ddc969d07214c77872f8b1 100644 (file)
@@ -291,6 +291,7 @@ Objective-C and Objective-C++ Dialects}.
 -fdump-translation-unit@r{[}-@var{n}@r{]} @gol
 -fdump-class-hierarchy@r{[}-@var{n}@r{]} @gol
 -fdump-ipa-all -fdump-ipa-cgraph -fdump-ipa-inline @gol
+-fdump-passes @gol
 -fdump-statistics @gol
 -fdump-tree-all @gol
 -fdump-tree-original@r{[}-@var{n}@r{]}  @gol
@@ -5071,7 +5072,8 @@ pair seperated by a colon.  The range is inclusive in both ends.  If the range
 is trivial, the number pair can be simplified as a single number.  If the
 function's cgraph node's @var{uid} is falling within one of the specified ranges,
 the @var{pass} is disabled for that function.  The @var{uid} is shown in the
-function header of a dump file.
+function header of a dump file, and the pass names can be dumped by using
+option @option{-fdump-passes}.
 
 @item -fdisable-tree-@var{pass}
 @item -fdisable-tree-@var{pass}=@var{range-list}
@@ -5495,6 +5497,11 @@ Dump after function inlining.
 
 @end table
 
+@item -fdump-passes
+@opindex fdump-passes
+Dump the list of optimization passes that are turned on and off by
+the current command line options.
+
 @item -fdump-statistics-@var{option}
 @opindex fdump-statistics
 Enable and control dumping of pass statistics in a separate file.  The
index f06a67c4d90d6a6f0cc60279e37e13c2ae30a40d..0faef10b59050f3a8434ea8fff0c91559b4dc8dd 100644 (file)
@@ -478,7 +478,7 @@ passr_eq (const void *p1, const void *p2)
   return !strcmp (s1->unique_name, s2->unique_name);
 }
 
-static htab_t pass_name_tab = NULL;
+static htab_t name_to_pass_map = NULL;
 
 /* Register PASS with NAME.  */
 
@@ -488,11 +488,11 @@ register_pass_name (struct opt_pass *pass, const char *name)
   struct pass_registry **slot;
   struct pass_registry pr;
 
-  if (!pass_name_tab)
-    pass_name_tab = htab_create (256, passr_hash, passr_eq, NULL);
+  if (!name_to_pass_map)
+    name_to_pass_map = htab_create (256, passr_hash, passr_eq, NULL);
 
   pr.unique_name = name;
-  slot = (struct pass_registry **) htab_find_slot (pass_name_tab, &pr, INSERT);
+  slot = (struct pass_registry **) htab_find_slot (name_to_pass_map, &pr, INSERT);
   if (!*slot)
     {
       struct pass_registry *new_pr;
@@ -506,6 +506,124 @@ register_pass_name (struct opt_pass *pass, const char *name)
     return; /* Ignore plugin passes.  */
 }
 
+/* Map from pass id to canonicalized pass name.  */
+
+typedef const char *char_ptr;
+DEF_VEC_P(char_ptr);
+DEF_VEC_ALLOC_P(char_ptr, heap);
+static VEC(char_ptr, heap) *pass_tab = NULL;
+
+/* Callback function for traversing NAME_TO_PASS_MAP.  */
+
+static int
+pass_traverse (void **slot, void *data ATTRIBUTE_UNUSED)
+{
+  struct pass_registry **p = (struct pass_registry **)slot;
+  struct opt_pass *pass = (*p)->pass;
+
+  gcc_assert (pass->static_pass_number > 0);
+  gcc_assert (pass_tab);
+
+  VEC_replace (char_ptr, pass_tab, pass->static_pass_number,
+               (*p)->unique_name);
+
+  return 1;
+}
+
+/* The function traverses NAME_TO_PASS_MAP and creates a pass info
+   table for dumping purpose.  */
+
+static void
+create_pass_tab (void)
+{
+  if (!flag_dump_passes)
+    return;
+
+  VEC_safe_grow_cleared (char_ptr, heap,
+                         pass_tab, passes_by_id_size + 1);
+  htab_traverse (name_to_pass_map, pass_traverse, NULL);
+}
+
+static bool override_gate_status (struct opt_pass *, tree, bool);
+
+/* Dump the instantiated name for PASS. IS_ON indicates if PASS
+   is turned on or not.  */
+
+static void
+dump_one_pass (struct opt_pass *pass, int pass_indent)
+{
+  int indent = 3 * pass_indent;
+  const char *pn;
+  bool is_on, is_really_on;
+
+  is_on = (pass->gate == NULL) ? true : pass->gate();
+  is_really_on = override_gate_status (pass, current_function_decl, is_on);
+
+  if (pass->static_pass_number <= 0)
+    pn = pass->name;
+  else
+    pn = VEC_index (char_ptr, pass_tab, pass->static_pass_number);
+
+  fprintf (stderr, "%*s%-40s%*s:%s%s\n", indent, " ", pn,
+           (15 - indent < 0 ? 0 : 15 - indent), " ",
+           is_on ? "  ON" : "  OFF",
+           ((!is_on) == (!is_really_on) ? ""
+            : (is_really_on ? " (FORCED_ON)" : " (FORCED_OFF)")));
+}
+
+/* Dump pass list PASS with indentation INDENT.  */
+
+static void
+dump_pass_list (struct opt_pass *pass, int indent)
+{
+  do
+    {
+      dump_one_pass (pass, indent);
+      if (pass->sub)
+        dump_pass_list (pass->sub, indent + 1);
+      pass = pass->next;
+    }
+  while (pass);
+}
+
+/* Dump all optimization passes.  */
+
+void
+dump_passes (void)
+{
+  struct cgraph_node *n, *node = NULL;
+  tree save_fndecl = current_function_decl;
+
+  create_pass_tab();
+
+  n = cgraph_nodes;
+  while (n)
+    {
+      if (DECL_STRUCT_FUNCTION (n->decl))
+        {
+          node = n;
+          break;
+        }
+      n = n->next;
+    }
+
+  if (!node)
+    return;
+
+  push_cfun (DECL_STRUCT_FUNCTION (node->decl));
+  current_function_decl = node->decl;
+
+  dump_pass_list (all_lowering_passes, 1);
+  dump_pass_list (all_small_ipa_passes, 1);
+  dump_pass_list (all_regular_ipa_passes, 1);
+  dump_pass_list (all_lto_gen_passes, 1);
+  dump_pass_list (all_passes, 1);
+
+  pop_cfun ();
+  current_function_decl = save_fndecl;
+}
+
+
 /* Returns the pass with NAME.  */
 
 static struct opt_pass *
@@ -513,9 +631,8 @@ get_pass_by_name (const char *name)
 {
   struct pass_registry **slot, pr;
 
-  gcc_assert (pass_name_tab);
   pr.unique_name = name;
-  slot = (struct pass_registry **) htab_find_slot (pass_name_tab,
+  slot = (struct pass_registry **) htab_find_slot (name_to_pass_map,
                                                    &pr, NO_INSERT);
 
   if (!slot || !*slot)
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..bcdf99ae0286c169d498d109d79e07ec5810e023 100644 (file)
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-passes" } */
+
+unsigned res;
+
+void
+foo (unsigned code, int len)
+{
+  int i;
+  for (i = 0; i < len; i++)
+    res |= code & 1;
+}
+
+/* { dg-prune-output ".*" } */
index daf7202f4f6f7f3e33bc77bd511d9c5795b1d834..f3a03b07127afd20a34f216cb7059070236cb3d8 100644 (file)
@@ -639,5 +639,6 @@ extern void do_per_function_toporder (void (*) (void *), void *);
 
 extern void disable_pass (const char *);
 extern void enable_pass (const char *);
+extern void dump_passes (void);
 
 #endif /* GCC_TREE_PASS_H */