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
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;