On 11/05/2015 12:18 PM, Kyrill Tkachov wrote:
Hi Nikolai,
On 05/11/15 08:29, Nikolai Bozhenov wrote:
Hi!
The attached patch adds a procedure to dump the scheduler's dependency
graph into a dot file. The patch has been bootstrapped and regtested
on x86_64. Please commit if it is OK for trunk.
Thanks,
Nikolai
A couple of style nits.
+ // begin subgraph (basic block)
+ pp_printf (&pp, "subgraph cluster_block_%d {\n", bb);
+ pp_printf (&pp, "\t" "color=blue;" "\n");
+ pp_printf (&pp, "\t" "style=bold;" "\n");
+ pp_printf (&pp, "\t" "label=\"BB #%d\";\n", BB_TO_BLOCK (bb));
+
+ // setup head and tail (no support for EBBs)
+ gcc_assert (EBB_FIRST_BB (bb) == EBB_LAST_BB (bb));
+ get_ebb_head_tail (EBB_FIRST_BB (bb), EBB_LAST_BB (bb), &head,
&tail);
+ tail = NEXT_INSN (tail);
+
+ // dump all insns
+ for (con = head; con != tail; con = NEXT_INSN (con))
+ {
+ if (!INSN_P (con))
+ continue;
+
+ // pretty print the insn
+ pp_printf (&pp, "\t%d [label=\"{", INSN_UID (con));
Please use C-style comments i.e. /**/ instead of //.
Also, throughout the comments leave two empty spaces after a full stop
i.e. /* <text>. */.
You can use the check_GNU_style.sh script in the contrib/ directory on
your patches to highlight similar issues. For example:
$ ./contrib/check_GNU_style.sh ~/patches/dep-graph.patch
Dot, space, space, end of comment.
83:+/* Dump dependency graph for the current region to a file using
dot syntax. */
166:+/* Dump dependency graph for the current region to a file using
dot syntax. */
Sentences should end with a dot. Dot, space, space, end of the comment.
127:+ /* dump all deps */
Cheers,
Kyrill
Thanks for your remarks, Kyrill!
I've uploaded an updated patch.
Nikolai
2015-11-04 Nikolai Bozhenov <n.bozhe...@samsung.com>
* sched-int.h (dump_rgn_dependencies_dot): Declare
* sched-rgn.c (dump_rgn_dependencies_dot): New function
* print-rtl.h (print_insn): Add prototype
diff --git a/gcc/print-rtl.h b/gcc/print-rtl.h
index eb079af..f601d33 100644
--- a/gcc/print-rtl.h
+++ b/gcc/print-rtl.h
@@ -25,12 +25,14 @@ extern void print_rtl (FILE *, const_rtx);
#endif
extern void dump_value_slim (FILE *, const_rtx, int);
extern void dump_insn_slim (FILE *, const rtx_insn *);
extern void dump_rtl_slim (FILE *, const rtx_insn *, const rtx_insn *,
int, int);
extern void print_value (pretty_printer *, const_rtx, int);
extern void print_pattern (pretty_printer *, const_rtx, int);
+extern void print_insn (pretty_printer *pp, const rtx_insn *x, int verbose);
+
extern void rtl_dump_bb_for_graph (pretty_printer *, basic_block);
extern const char *str_pattern_slim (const_rtx);
#endif // GCC_PRINT_RTL_H
diff --git a/gcc/sched-int.h b/gcc/sched-int.h
index 86f5821..4600347 100644
--- a/gcc/sched-int.h
+++ b/gcc/sched-int.h
@@ -1492,16 +1492,19 @@ extern void sched_rgn_local_finish (void);
extern void sched_rgn_local_free (void);
extern void extend_regions (void);
extern void rgn_make_new_region_out_of_new_block (basic_block);
extern void compute_priorities (void);
extern void increase_insn_priority (rtx_insn *, int);
extern void debug_rgn_dependencies (int);
extern void debug_dependencies (rtx_insn *, rtx_insn *);
+extern void dump_rgn_dependencies_dot (FILE *);
+extern void dump_rgn_dependencies_dot (const char *);
+
extern void free_rgn_deps (void);
extern int contributes_to_priority (rtx_insn *, rtx_insn *);
extern void extend_rgns (int *, int *, sbitmap, int *);
extern void deps_join (struct deps_desc *, struct deps_desc *);
extern void rgn_setup_common_sched_info (void);
extern void rgn_setup_sched_infos (void);
diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
index eafb3fd..d744d83 100644
--- a/gcc/sched-rgn.c
+++ b/gcc/sched-rgn.c
@@ -58,16 +58,18 @@ along with GCC; see the file COPYING3. If not see
#include "insn-attr.h"
#include "except.h"
#include "params.h"
#include "cfganal.h"
#include "sched-int.h"
#include "sel-sched.h"
#include "tree-pass.h"
#include "dbgcnt.h"
+#include "pretty-print.h"
+#include "print-rtl.h"
#ifdef INSN_SCHEDULING
/* Some accessor macros for h_i_d members only used within this file. */
#define FED_BY_SPEC_LOAD(INSN) (HID (INSN)->fed_by_spec_load)
#define IS_LOAD_INSN(INSN) (HID (insn)->is_load_insn)
/* nr_inter/spec counts interblock/speculative motion for the function. */
@@ -2855,16 +2857,118 @@ void debug_dependencies (rtx_insn *head, rtx_insn *tail)
DEP_NONREG (dep) ? "n" : "",
DEP_MULTIPLE (dep) ? "m" : "");
}
fprintf (sched_dump, "\n");
}
fprintf (sched_dump, "\n");
}
+
+/* Dump dependency graph for the current region to a file using dot syntax. */
+
+void
+dump_rgn_dependencies_dot (FILE *file)
+{
+ rtx_insn *head, *tail, *con, *pro;
+ sd_iterator_def sd_it;
+ dep_t dep;
+ int bb;
+ pretty_printer pp;
+
+ pp.buffer->stream = file;
+ pp_printf (&pp, "digraph SchedDG {\n");
+
+ for (bb = 0; bb < current_nr_blocks; ++bb)
+ {
+ /* Begin subgraph (basic block). */
+ pp_printf (&pp, "subgraph cluster_block_%d {\n", bb);
+ pp_printf (&pp, "\t" "color=blue;" "\n");
+ pp_printf (&pp, "\t" "style=bold;" "\n");
+ pp_printf (&pp, "\t" "label=\"BB #%d\";\n", BB_TO_BLOCK (bb));
+
+ /* Setup head and tail (no support for EBBs). */
+ gcc_assert (EBB_FIRST_BB (bb) == EBB_LAST_BB (bb));
+ get_ebb_head_tail (EBB_FIRST_BB (bb), EBB_LAST_BB (bb), &head, &tail);
+ tail = NEXT_INSN (tail);
+
+ /* Dump all insns. */
+ for (con = head; con != tail; con = NEXT_INSN (con))
+ {
+ if (!INSN_P (con))
+ continue;
+
+ /* Pretty print the insn. */
+ pp_printf (&pp, "\t%d [label=\"{", INSN_UID (con));
+ pp_write_text_to_stream (&pp);
+ print_insn (&pp, con, /*verbose=*/false);
+ pp_write_text_as_dot_label_to_stream (&pp, /*for_record=*/true);
+ pp_write_text_to_stream (&pp);
+
+ /* Dump instruction attributes. */
+ pp_printf (&pp, "|{ uid:%d | luid:%d | prio:%d }}\",shape=record]\n",
+ INSN_UID (con), INSN_LUID (con), INSN_PRIORITY (con));
+
+ /* Dump all deps. */
+ FOR_EACH_DEP (con, SD_LIST_BACK, sd_it, dep)
+ {
+ int weight = 0;
+ const char *color;
+ pro = DEP_PRO (dep);
+
+ switch (DEP_TYPE (dep))
+ {
+ case REG_DEP_TRUE:
+ color = "black";
+ weight = 1;
+ break;
+ case REG_DEP_OUTPUT:
+ case REG_DEP_ANTI:
+ color = "orange";
+ break;
+ case REG_DEP_CONTROL:
+ color = "blue";
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ pp_printf (&pp, "\t%d -> %d [color=%s",
+ INSN_UID (pro), INSN_UID (con), color);
+ if (int cost = dep_cost (dep))
+ pp_printf (&pp, ",label=%d", cost);
+ pp_printf (&pp, ",weight=%d", weight);
+ pp_printf (&pp, "];\n");
+ }
+ }
+ pp_printf (&pp, "}\n");
+ }
+
+ pp_printf (&pp, "}\n");
+ pp_flush (&pp);
+}
+
+/* Dump dependency graph for the current region to a file using dot syntax. */
+
+DEBUG_FUNCTION void
+dump_rgn_dependencies_dot (const char *fname)
+{
+ FILE *fp;
+
+ fp = fopen (fname, "w");
+ if (!fp)
+ {
+ perror ("fopen");
+ return;
+ }
+
+ dump_rgn_dependencies_dot (fp);
+ fclose (fp);
+}
+
/* Returns true if all the basic blocks of the current region have
NOTE_DISABLE_SCHED_OF_BLOCK which means not to schedule that region. */
bool
sched_is_disabled_for_current_region_p (void)
{
int bb;