This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Unify tree/RTL dump file handling (4/5)
- From: Paolo Bonzini <bonzini at gnu dot org>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 26 Aug 2004 00:26:33 +0200
- Subject: [PATCH] Unify tree/RTL dump file handling (4/5)
This part augments the dump file manager to handle enabling/disabling
of RTL dumps, and to be able to dump RTL files.
Some of the changes in tree-dump.c expose information that I'll need
in part 5, when open_dump_file, close_dump_file, and
enable_rtl_dump_file will go through the routines in tree-dump.c.
The changes in tree-optimize.c, instead, augment execute_todo and
execute_one_pass so that it can dump RTL, and start adding support for
-fdump-rtl-* flags.
Paolo
2004-08-13 Paolo Bonzini <bonzini@gnu.org>
* Makefile.in (tree-dump.o): Add new dependencies.
* cgraph.c (cgraph_remove_node): TDF_all -> TDF_tree_all.
* cgraphunit.c (cgraph_preserve_function_body_p, cgraph_optimize):
Likewise.
* toplev.c (dump_file_name): New.
* tree-dump.c (dump_enable_all): Add LETTER parameter.
(struct dump_file_info): Add NUM and LETTER fields.
(dump_files): Adjust and add RTL dump files.
(dump_register): Add NUM and LETTER fields.
(get_dump_file_name, dump_initialized_p, enable_rtl_dump_file): New.
(dump_begin): Use get_dump_file_name.
(dump_switch_p_1): Adjust call to dump_enable_all.
* tree-dump.h (dump_register): Adjust prototype.
* tree-optimize.c (register_one_dump_file): Take dump file index.
Support flags for RTL dumps.
(register_dump_files): Fill in NUM field of struct dump_file_info.
Track properties both when the gate is executed and when it is not.
(execute_todo): Dump RTL. Add PROPERTIES parameter.
(execute_one_pass): Pass properties to execute_todo. Handle VCG
dumps of RTL.
* tree-pass.h (dump_file_name): New.
* tree.h (TDF_TREE, TDF_RTL, get_dump_file_name, dump_initialized_p): New.
diff -rpu gcc-backup/gcc/Makefile.in gcc-pass/gcc/Makefile.in
--- gcc-backup/gcc/Makefile.in 2004-08-09 19:40:24.000000000 +0200
+++ gcc-pass/gcc/Makefile.in 2004-08-13 15:15:59.000000000 +0200
@@ -1573,7 +1573,7 @@
real.h gt-tree.h tree-iterator.h $(BASIC_BLOCK_H) $(TREE_FLOW_H)
tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(C_TREE_H) $(FLAGS_H) langhooks.h toplev.h output.h $(C_PRAGMA_H) $(RTL_H) \
- $(GGC_H) $(EXPR_H) $(SPLAY_TREE_H) $(TREE_DUMP_H) tree-iterator.h
+ $(GGC_H) $(EXPR_H) $(SPLAY_TREE_H) $(TREE_DUMP_H) tree-iterator.h tree-pass.h
tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(RTL_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h insn-config.h \
$(INTEGRATE_H) $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \
diff -rpu gcc-backup/gcc/cgraph.c gcc-pass/gcc/cgraph.c
--- gcc-backup/gcc/cgraph.c 2004-08-08 10:20:19.000000000 +0200
+++ gcc-pass/gcc/cgraph.c 2004-08-08 10:35:32.000000000 +0200
@@ -328,7 +328,7 @@
else
{
htab_clear_slot (cgraph_hash, slot);
- if (!dump_enabled_p (TDI_all))
+ if (!dump_enabled_p (TDI_tree_all))
{
DECL_SAVED_TREE (node->decl) = NULL;
DECL_STRUCT_FUNCTION (node->decl) = NULL;
@@ -356,7 +356,7 @@
|| (!n->global.inlined_to
&& !TREE_ASM_WRITTEN (n->decl) && !DECL_EXTERNAL (n->decl)))
break;
- if (!n && !dump_enabled_p (TDI_all))
+ if (!n && !dump_enabled_p (TDI_tree_all))
{
DECL_SAVED_TREE (node->decl) = NULL;
DECL_STRUCT_FUNCTION (node->decl) = NULL;
diff -rpu gcc-backup/gcc/cgraphunit.c gcc-pass/gcc/cgraphunit.c
--- gcc-backup/gcc/cgraphunit.c 2004-08-08 10:20:19.000000000 +0200
+++ gcc-pass/gcc/cgraphunit.c 2004-08-08 10:35:32.000000000 +0200
@@ -1712,7 +1712,7 @@
{
struct cgraph_node *node;
/* Keep the body; we're going to dump it. */
- if (dump_enabled_p (TDI_all))
+ if (dump_enabled_p (TDI_tree_all))
return true;
if (!cgraph_global_info_ready)
return (DECL_INLINE (decl) && !flag_really_no_inline);
@@ -1771,7 +1771,7 @@
/* Double check that all inline clones are gone and that all
function bodies have been released from memory. */
if (flag_unit_at_a_time
- && !dump_enabled_p (TDI_all)
+ && !dump_enabled_p (TDI_tree_all)
&& !(sorrycount || errorcount))
{
struct cgraph_node *node;
diff -rpu gcc-backup/gcc/toplev.c gcc-pass/gcc/toplev.c
--- gcc-backup/gcc/toplev.c 2004-08-08 10:20:19.000000000 +0200
+++ gcc-pass/gcc/toplev.c 2004-08-08 10:45:51.000000000 +0200
@@ -418,6 +418,7 @@
FILE *aux_info_file;
FILE *dump_file = NULL;
FILE *cgraph_dump_file = NULL;
+char *dump_file_name;
/* The current working directory of a translation. It's generally the
directory from which compilation was initiated, but a preprocessed
diff -rpu gcc-backup/gcc/tree-dump.c gcc-pass/gcc/tree-dump.c
--- gcc-backup/gcc/tree-dump.c 2004-08-08 10:20:19.000000000 +0200
+++ gcc-pass/gcc/tree-dump.c 2004-08-13 15:45:35.000000000 +0200
@@ -28,6 +28,7 @@
#include "diagnostic.h"
#include "toplev.h"
#include "tree-dump.h"
+#include "tree-pass.h"
#include "langhooks.h"
#include "tree-iterator.h"
@@ -37,7 +38,7 @@
static void dump_new_line (dump_info_p);
static void dump_maybe_newline (dump_info_p);
static void dump_string_field (dump_info_p, const char *, const char *);
-static void dump_enable_all (int);
+static int dump_enable_all (int, int);
/* Add T to the end of the queue of nodes to dump. Returns the index
assigned to T. */
@@ -658,15 +659,7 @@
}
splay_tree_delete (di.nodes);
}
-
-/* Define a tree dump switch. */
-struct dump_file_info
-{
- const char *suffix; /* suffix to give output file. */
- const char *swtch; /* command line switch */
- int flags; /* user flags */
- int state; /* state of play */
-};
+
/* Table of tree dump switches. This must be consistent with the
TREE_DUMP_INDEX enumeration in tree.h */
@@ -714,7 +746,8 @@
};
unsigned int
-dump_register (const char *suffix, const char *swtch)
+dump_register (const char *suffix, const char *swtch, int flags,
+ unsigned int num, int letter)
{
size_t this = extra_dump_files_in_use++;
@@ -732,19 +765,22 @@
memset (&extra_dump_files[this], 0, sizeof (struct dump_file_info));
extra_dump_files[this].suffix = suffix;
extra_dump_files[this].swtch = swtch;
+ extra_dump_files[this].flags = flags;
+ extra_dump_files[this].num = num;
+ extra_dump_files[this].letter = letter;
return this + TDI_end;
}
/* Return the dump_file_info for the given phase. */
-static struct dump_file_info *
+struct dump_file_info *
get_dump_file_info (enum tree_dump_index phase)
{
if (phase < TDI_end)
return &dump_files[phase];
else if (phase - TDI_end >= extra_dump_files_in_use)
- abort ();
+ return NULL;
else
return extra_dump_files + (phase - TDI_end);
}
@@ -755,12 +792,10 @@
enabled, returns NULL.
Multiple calls will reopen and append to the dump file. */
-FILE *
-dump_begin (enum tree_dump_index phase, int *flag_ptr)
+char *
+get_dump_file_name (enum tree_dump_index phase)
{
- FILE *stream;
- char *name;
- char dump_id[10];
+ char dump_id[5], *p = dump_id;
struct dump_file_info *dfi;
if (phase == TDI_none)
@@ -770,10 +805,33 @@
if (dfi->state == 0)
return NULL;
- if (snprintf (dump_id, sizeof (dump_id), ".t%02d", phase) < 0)
- dump_id[0] = '\0';
+ if (dfi->num >= 0 && dfi->num < 100)
+ {
+ *p++ = '.';
+ if (dfi->flags & TDF_TREE)
+ *p++ = 't';
+
+ *p++ = '0' + (dfi->num / 10);
+ *p++ = '0' + (dfi->num % 10);
+ }
+
+ *p = '\0';
+
+ return concat (dump_base_name, dump_id, dfi->suffix, NULL);
+}
+
+FILE *
+dump_begin (enum tree_dump_index phase, int *flag_ptr)
+{
+ char *name;
+ struct dump_file_info *dfi;
+ FILE *stream;
+
+ if (phase == TDI_none || !dump_enabled_p (phase))
+ return NULL;
- name = concat (dump_base_name, dump_id, dfi->suffix, NULL);
+ name = get_dump_file_name (phase);
+ dfi = get_dump_file_info (phase);
stream = fopen (name, dfi->state < 0 ? "w" : "a");
if (!stream)
error ("could not open dump file `%s': %s", name, strerror (errno));
@@ -796,6 +854,15 @@
return dfi->state;
}
+/* Returns nonzero if tree dump PHASE has been initialized. */
+
+int
+dump_initialized_p (enum tree_dump_index phase)
+{
+ struct dump_file_info *dfi = get_dump_file_info (phase);
+ return dfi->state > 0;
+}
+
/* Returns the switch name of PHASE. */
const char *
@@ -814,28 +881,33 @@
fclose (stream);
}
-/* Enable all tree dumps. */
+/* Enable all tree dumps. Return number of enabled tree dumps. */
-static void
-dump_enable_all (int flags)
+static int
+dump_enable_all (int flags, int letter)
{
+ int n = 0;
size_t i;
for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
- {
- dump_files[i].state = -1;
- dump_files[i].flags = flags;
- }
+ if ((dump_files[i].flags & flags)
+ && (letter == 0 || letter == dump_files[i].letter))
+ {
+ dump_files[i].state = -1;
+ dump_files[i].flags = flags;
+ n++;
+ }
for (i = 0; i < extra_dump_files_in_use; i++)
- {
- extra_dump_files[i].state = -1;
- extra_dump_files[i].flags = flags;
- }
+ if ((extra_dump_files[i].flags & flags)
+ && (letter == 0 || letter == extra_dump_files[i].letter))
+ {
+ extra_dump_files[i].state = -1;
+ extra_dump_files[i].flags = flags;
+ n++;
+ }
- /* FIXME -fdump-call-graph is broken. */
- dump_files[TDI_xml].state = 0;
- dump_files[TDI_xml].flags = 0;
+ return n;
}
/* Parse ARG as a dump switch. Return nonzero if it is, and store the
@@ -882,11 +954,12 @@
}
dfi->state = -1;
- dfi->flags = flags;
+ dfi->flags |= flags;
- /* Process -fdump-tree-all by enabling all the known dumps. */
+ /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
+ known dumps. */
if (dfi->suffix == NULL)
- dump_enable_all (flags);
+ dump_enable_all (dfi->flags, 0);
return 1;
}
diff -rpu gcc-backup/gcc/tree-dump.h gcc-pass/gcc/tree-dump.h
--- gcc-backup/gcc/tree-dump.h 2004-08-08 10:20:19.000000000 +0200
+++ gcc-pass/gcc/tree-dump.h 2004-08-08 10:35:32.000000000 +0200
@@ -88,6 +88,6 @@
extern void dump_function (enum tree_dump_index, tree);
extern void dump_function_to_file (tree, FILE *, int);
-extern unsigned int dump_register (const char *, const char *);
+extern unsigned int dump_register (const char *, const char *, int, unsigned int, int);
#endif /* ! GCC_TREE_DUMP_H */
diff -rpu gcc-backup/gcc/tree-optimize.c gcc-pass/gcc/tree-optimize.c
--- gcc-backup/gcc/tree-optimize.c 2004-08-08 10:20:19.000000000 +0200
+++ gcc-pass/gcc/tree-optimize.c 2004-08-13 15:56:32.000000000 +0200
@@ -47,6 +47,7 @@
#include "tree-alias-common.h"
#include "ggc.h"
#include "cgraph.h"
+#include "graph.h"
/* Global variables used to communicate with passes. */
@@ -205,14 +211,11 @@
enabled or not. */
static void
-register_one_dump_file (struct tree_opt_pass *pass)
+register_one_dump_file (struct tree_opt_pass *pass, int n)
{
char *dot_name, *flag_name;
char num[10];
- if (!pass->name)
- return;
-
/* See below in next_pass_1. */
num[0] = '\0';
if (pass->static_pass_number != -1)
@@ -220,31 +223,55 @@
? 1 : pass->static_pass_number));
dot_name = concat (".", pass->name, num, NULL);
- flag_name = concat ("tree-", pass->name, num, NULL);
-
- pass->static_pass_number = dump_register (dot_name, flag_name);
+ if (pass->properties_provided & PROP_trees)
+ {
+ flag_name = concat ("tree-", pass->name, num, NULL);
+ pass->static_pass_number = dump_register (dot_name, flag_name,
+ TDF_TREE, n + TDI_tree_all, 0);
+ }
+ else
+ {
+ flag_name = concat ("rtl-", pass->name, num, NULL);
+ pass->static_pass_number = dump_register (dot_name, flag_name,
+ TDF_RTL, n, pass->letter);
+ }
}
static int
register_dump_files (struct tree_opt_pass *pass, int properties)
{
+ static int n = 0;
do
{
- /* Verify that all required properties are present. */
- if (pass->properties_required & ~properties)
- abort ();
-
- if (pass->properties_destroyed & pass->properties_provided)
- abort ();
+ int new_properties;
+ int pass_number;
pass->properties_required = properties;
- pass->properties_provided = properties =
+ new_properties =
(properties | pass->properties_provided) & ~pass->properties_destroyed;
- if (properties & PROP_trees)
- register_one_dump_file (pass);
+ /* Reset the counter when we reach RTL-based passes. */
+ if ((pass->properties_provided ^ pass->properties_required) & PROP_rtl)
+ n = 0;
+
+ pass_number = n;
+ if (pass->name)
+ n++;
+
if (pass->sub)
- properties = register_dump_files (pass->sub, properties);
+ new_properties = register_dump_files (pass->sub, new_properties);
+
+ /* If we have a gate, combine the properties that we could have with
+ and without the pass being examined. */
+ if (pass->gate)
+ properties &= new_properties;
+ else
+ properties = new_properties;
+
+ pass->properties_provided = properties;
+ if (pass->name)
+ register_one_dump_file (pass, pass_number);
+
pass = pass->next;
}
while (pass);
@@ -381,7 +408,7 @@
static unsigned int last_verified;
static void
-execute_todo (unsigned int flags)
+execute_todo (int properties, unsigned int flags)
{
if (flags & TODO_rename_vars)
{
@@ -391,8 +418,13 @@
if ((flags & TODO_dump_func) && dump_file)
{
- dump_function_to_file (current_function_decl,
- dump_file, dump_flags);
+ if (properties & PROP_trees)
+ dump_function_to_file (current_function_decl,
+ dump_file, dump_flags);
+ else if (properties & PROP_cfg)
+ print_rtl_with_bb (dump_file, get_insns ());
+ else
+ print_rtl (dump_file, get_insns ());
/* Flush the file. If verification fails, we won't be able to
close the file before aborting. */
@@ -428,11 +460,13 @@
/* Run pre-pass verification. */
todo = pass->todo_flags_start & ~last_verified;
if (todo)
- execute_todo (todo);
+ execute_todo (pass->properties_required, todo);
/* If a dump file name is present, open it if enabled. */
if (pass->static_pass_number != -1)
{
+ bool initializing_dump = !dump_initialized_p (pass->static_pass_number);
+ dump_file_name = get_dump_file_name (pass->static_pass_number);
dump_file = dump_begin (pass->static_pass_number, &dump_flags);
if (dump_file)
{
@@ -440,8 +474,19 @@
dname = lang_hooks.decl_printable_name (current_function_decl, 2);
aname = (IDENTIFIER_POINTER
(DECL_ASSEMBLER_NAME (current_function_decl)));
- fprintf (dump_file, "\n;; Function %s (%s)\n\n", dname, aname);
+ fprintf (dump_file, "\n;; Function %s (%s)%s\n\n", dname, aname,
+ cfun->function_frequency == FUNCTION_FREQUENCY_HOT
+ ? " (hot)"
+ : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED
+ ? " (unlikely executed)"
+ : "");
}
+
+ if (initializing_dump
+ && graph_dump_format != no_graph
+ && (pass->properties_provided & (PROP_cfg | PROP_rtl))
+ == (PROP_cfg | PROP_rtl))
+ clean_graph_dump_file (dump_file_name);
}
/* If a timevar is present, start it. */
@@ -452,15 +497,25 @@
if (pass->execute)
pass->execute ();
+ if (dump_file
+ && (pass->properties_provided & (PROP_cfg | PROP_rtl))
+ == (PROP_cfg | PROP_rtl))
+ print_rtl_graph_with_bb (dump_file_name, get_insns ());
+
/* Run post-pass cleanup and verification. */
todo = pass->todo_flags_finish;
last_verified = todo & TODO_verify_all;
if (todo)
- execute_todo (todo);
+ execute_todo (pass->properties_provided, todo);
/* Close down timevar and dump file. */
if (pass->tv_id)
timevar_pop (pass->tv_id);
+ if (dump_file_name)
+ {
+ free ((char *) dump_file_name);
+ dump_file_name = NULL;
+ }
if (dump_file)
{
dump_end (pass->static_pass_number, dump_file);
diff -rpu gcc-backup/gcc/tree-pass.h gcc-pass/gcc/tree-pass.h
--- gcc-backup/gcc/tree-pass.h 2004-08-08 10:20:19.000000000 +0200
+++ gcc-pass/gcc/tree-pass.h 2004-08-13 15:12:53.000000000 +0200
@@ -26,9 +26,13 @@
/* Global variables used to communicate with passes. */
extern FILE *dump_file;
extern int dump_flags;
+extern const char *dump_file_name;
extern struct bitmap_head_def *vars_to_rename;
+/* Return the dump_file_info for the given phase. */
+extern struct dump_file_info *get_dump_file_info (enum tree_dump_index);
+
/* Describe one pass. */
struct tree_opt_pass
{
diff -rpu gcc-backup/gcc/tree.h gcc-pass/gcc/tree.h
--- gcc-backup/gcc/tree.h 2004-08-09 19:40:24.000000000 +0200
+++ gcc-pass/gcc/tree.h 2004-08-13 15:27:09.000000000 +0200
@@ -3689,8 +3689,8 @@
TDI_end
};
-/* Bit masks to control tree dumping. Not all values are applicable to
- all tree dumps. Add new ones at the end. When you define new
+/* Bit masks to control dumping. Not all values are applicable to
+ all dumps. Add new ones at the end. When you define new
values, extend the DUMP_OPTIONS array in tree-dump.c */
#define TDF_ADDRESS (1 << 0) /* dump node addresses */
#define TDF_SLIM (1 << 1) /* don't go wild following links */
@@ -3708,11 +3748,15 @@
#define TDF_LINENO (1 << 7) /* display statement line numbers */
#define TDF_UID (1 << 8) /* display decl UIDs */
+#define TDF_TREE (1 << 9) /* is a tree dump */
+#define TDF_RTL (1 << 10) /* is a RTL dump */
typedef struct dump_info *dump_info_p;
+extern char *get_dump_file_name (enum tree_dump_index);
extern int dump_flag (dump_info_p, int, tree);
extern int dump_enabled_p (enum tree_dump_index);
+extern int dump_initialized_p (enum tree_dump_index);
extern FILE *dump_begin (enum tree_dump_index, int *);
extern void dump_end (enum tree_dump_index, FILE *);
extern void dump_node (tree, int, FILE *);