12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073 |
- /* Instruction scheduling pass. Log dumping infrastructure.
- Copyright (C) 2006-2015 Free Software Foundation, Inc.
- This file is part of GCC.
- GCC is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 3, or (at your option) any later
- version.
- GCC is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
- You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
- #include "config.h"
- #include "system.h"
- #include "coretypes.h"
- #include "tm.h"
- #include "diagnostic-core.h"
- #include "rtl.h"
- #include "tm_p.h"
- #include "hard-reg-set.h"
- #include "regs.h"
- #include "hashtab.h"
- #include "hash-set.h"
- #include "vec.h"
- #include "machmode.h"
- #include "input.h"
- #include "function.h"
- #include "predict.h"
- #include "dominance.h"
- #include "cfg.h"
- #include "basic-block.h"
- #include "flags.h"
- #include "insn-config.h"
- #include "insn-attr.h"
- #include "params.h"
- #include "cselib.h"
- #include "target.h"
- #ifdef INSN_SCHEDULING
- #include "sel-sched-ir.h"
- #include "sel-sched-dump.h"
- /* These variables control high-level pretty printing. */
- static int sel_dump_cfg_flags = SEL_DUMP_CFG_FLAGS;
- static int sel_debug_cfg_flags = SEL_DUMP_CFG_FLAGS;
- /* True when a cfg should be dumped. */
- static bool sel_dump_cfg_p;
- /* Variables that are used to build the cfg dump file name. */
- static const char * const sel_debug_cfg_root = "./";
- static const char * const sel_debug_cfg_root_postfix_default = "";
- static const char *sel_debug_cfg_root_postfix = "";
- static int sel_dump_cfg_fileno = -1;
- static int sel_debug_cfg_fileno = -1;
- /* When this flag is on, we are dumping to the .dot file.
- When it is off, we are dumping to log.
- This is useful to differentiate formatting between log and .dot
- files. */
- bool sched_dump_to_dot_p = false;
- /* Controls how insns from a fence list should be dumped. */
- static int dump_flist_insn_flags = (DUMP_INSN_UID | DUMP_INSN_BBN
- | DUMP_INSN_SEQNO);
- /* The variable used to hold the value of sched_dump when temporarily
- switching dump output to the other source, e.g. the .dot file. */
- static FILE *saved_sched_dump = NULL;
- /* Switch sched_dump to TO. It must not be called twice. */
- static void
- switch_dump (FILE *to)
- {
- gcc_assert (saved_sched_dump == NULL);
- saved_sched_dump = sched_dump;
- sched_dump = to;
- }
- /* Restore previously switched dump. */
- static void
- restore_dump (void)
- {
- sched_dump = saved_sched_dump;
- saved_sched_dump = NULL;
- }
- /* Functions for dumping instructions, av sets, and exprs. */
- /* Default flags for dumping insns. */
- static int dump_insn_rtx_flags = DUMP_INSN_RTX_UID | DUMP_INSN_RTX_PATTERN;
- /* Default flags for dumping vinsns. */
- static int dump_vinsn_flags = (DUMP_VINSN_INSN_RTX | DUMP_VINSN_TYPE
- | DUMP_VINSN_COUNT);
- /* Default flags for dumping expressions. */
- static int dump_expr_flags = DUMP_EXPR_ALL;
- /* Default flags for dumping insns when debugging. */
- static int debug_insn_rtx_flags = DUMP_INSN_RTX_ALL;
- /* Default flags for dumping vinsns when debugging. */
- static int debug_vinsn_flags = DUMP_VINSN_ALL;
- /* Default flags for dumping expressions when debugging. */
- static int debug_expr_flags = DUMP_EXPR_ALL;
- /* Controls how an insn from stream should be dumped when debugging. */
- static int debug_insn_flags = DUMP_INSN_ALL;
- /* Print an rtx X. */
- void
- sel_print_rtl (rtx x)
- {
- print_rtl_single (sched_dump, x);
- }
- /* Dump insn INSN honoring FLAGS. */
- void
- dump_insn_rtx_1 (rtx insn, int flags)
- {
- int all;
- /* flags == -1 also means dumping all. */
- all = (flags & 1);;
- if (all)
- flags |= DUMP_INSN_RTX_ALL;
- sel_print ("(");
- if (flags & DUMP_INSN_RTX_UID)
- sel_print ("%d;", INSN_UID (insn));
- if (flags & DUMP_INSN_RTX_PATTERN)
- sel_print ("%s;", str_pattern_slim (PATTERN (insn)));
- if (flags & DUMP_INSN_RTX_BBN)
- {
- basic_block bb = BLOCK_FOR_INSN (insn);
- sel_print ("bb:%d;", bb != NULL ? bb->index : -1);
- }
- sel_print (")");
- }
- /* Dump INSN with default flags. */
- void
- dump_insn_rtx (rtx insn)
- {
- dump_insn_rtx_1 (insn, dump_insn_rtx_flags);
- }
- /* Dump INSN to stderr. */
- DEBUG_FUNCTION void
- debug_insn_rtx (rtx insn)
- {
- switch_dump (stderr);
- dump_insn_rtx_1 (insn, debug_insn_rtx_flags);
- sel_print ("\n");
- restore_dump ();
- }
- /* Dump vinsn VI honoring flags. */
- void
- dump_vinsn_1 (vinsn_t vi, int flags)
- {
- int all;
- /* flags == -1 also means dumping all. */
- all = flags & 1;
- if (all)
- flags |= DUMP_VINSN_ALL;
- sel_print ("(");
- if (flags & DUMP_VINSN_INSN_RTX)
- dump_insn_rtx_1 (VINSN_INSN_RTX (vi), dump_insn_rtx_flags | all);
- if (flags & DUMP_VINSN_TYPE)
- sel_print ("type:%s;", GET_RTX_NAME (VINSN_TYPE (vi)));
- if (flags & DUMP_VINSN_COUNT)
- sel_print ("count:%d;", VINSN_COUNT (vi));
- if (flags & DUMP_VINSN_COST)
- {
- int cost = vi->cost;
- if (cost != -1)
- sel_print ("cost:%d;", cost);
- }
- sel_print (")");
- }
- /* Dump vinsn VI with default flags. */
- void
- dump_vinsn (vinsn_t vi)
- {
- dump_vinsn_1 (vi, dump_vinsn_flags);
- }
- DEBUG_FUNCTION void
- debug (vinsn_def &ref)
- {
- switch_dump (stderr);
- dump_vinsn_1 (&ref, dump_vinsn_flags);
- sel_print ("\n");
- restore_dump ();
- }
- DEBUG_FUNCTION void
- debug (vinsn_def *ptr)
- {
- if (ptr)
- debug (*ptr);
- else
- fprintf (stderr, "<nil>\n");
- }
- DEBUG_FUNCTION void
- debug_verbose (vinsn_def &ref)
- {
- switch_dump (stderr);
- dump_vinsn_1 (&ref, debug_vinsn_flags);
- sel_print ("\n");
- restore_dump ();
- }
- DEBUG_FUNCTION void
- debug_verbose (vinsn_def *ptr)
- {
- if (ptr)
- debug (*ptr);
- else
- fprintf (stderr, "<nil>\n");
- }
- /* Dump vinsn VI to stderr. */
- DEBUG_FUNCTION void
- debug_vinsn (vinsn_t vi)
- {
- switch_dump (stderr);
- dump_vinsn_1 (vi, debug_vinsn_flags);
- sel_print ("\n");
- restore_dump ();
- }
- /* Dump EXPR honoring flags. */
- void
- dump_expr_1 (expr_t expr, int flags)
- {
- int all;
- /* flags == -1 also means dumping all. */
- all = flags & 1;
- if (all)
- flags |= DUMP_EXPR_ALL;
- sel_print ("[");
- if (flags & DUMP_EXPR_VINSN)
- dump_vinsn_1 (EXPR_VINSN (expr), dump_vinsn_flags | all);
- if (flags & DUMP_EXPR_SPEC)
- {
- int spec = EXPR_SPEC (expr);
- if (spec != 0)
- sel_print ("spec:%d;", spec);
- }
- if (flags & DUMP_EXPR_USEFULNESS)
- {
- int use = EXPR_USEFULNESS (expr);
- if (use != REG_BR_PROB_BASE)
- sel_print ("use:%d;", use);
- }
- if (flags & DUMP_EXPR_PRIORITY)
- sel_print ("prio:%d;", EXPR_PRIORITY (expr));
- if (flags & DUMP_EXPR_SCHED_TIMES)
- {
- int times = EXPR_SCHED_TIMES (expr);
- if (times != 0)
- sel_print ("times:%d;", times);
- }
- if (flags & DUMP_EXPR_SPEC_DONE_DS)
- {
- ds_t spec_done_ds = EXPR_SPEC_DONE_DS (expr);
- if (spec_done_ds != 0)
- sel_print ("ds:%d;", spec_done_ds);
- }
- if (flags & DUMP_EXPR_ORIG_BB)
- {
- int orig_bb = EXPR_ORIG_BB_INDEX (expr);
- if (orig_bb != 0)
- sel_print ("orig_bb:%d;", orig_bb);
- }
- if (EXPR_TARGET_AVAILABLE (expr) < 1)
- sel_print ("target:%d;", EXPR_TARGET_AVAILABLE (expr));
- sel_print ("]");
- }
- /* Dump expression EXPR with default flags. */
- void
- dump_expr (expr_t expr)
- {
- dump_expr_1 (expr, dump_expr_flags);
- }
- /* Dump expression EXPR to stderr. */
- DEBUG_FUNCTION void
- debug_expr (expr_t expr)
- {
- switch_dump (stderr);
- dump_expr_1 (expr, debug_expr_flags);
- sel_print ("\n");
- restore_dump ();
- }
- /* Dump expression REF. */
- DEBUG_FUNCTION void
- debug (expr_def &ref)
- {
- switch_dump (stderr);
- dump_expr_1 (&ref, 0);
- sel_print ("\n");
- restore_dump ();
- }
- DEBUG_FUNCTION void
- debug (expr_def *ptr)
- {
- if (ptr)
- debug (*ptr);
- else
- fprintf (stderr, "<nil>\n");
- }
- /* Dump expression REF verbosely. */
- DEBUG_FUNCTION void
- debug_verbose (expr_def &ref)
- {
- switch_dump (stderr);
- dump_expr_1 (&ref, DUMP_EXPR_ALL);
- sel_print ("\n");
- restore_dump ();
- }
- DEBUG_FUNCTION void
- debug_verbose (expr_def *ptr)
- {
- if (ptr)
- debug_verbose (*ptr);
- else
- fprintf (stderr, "<nil>\n");
- }
- /* Dump insn I honoring FLAGS. */
- void
- dump_insn_1 (insn_t i, int flags)
- {
- int all;
- all = flags & 1;
- if (all)
- flags |= DUMP_INSN_ALL;
- if (!sched_dump_to_dot_p)
- sel_print ("(");
- if (flags & DUMP_INSN_EXPR)
- {
- dump_expr_1 (INSN_EXPR (i), dump_expr_flags | all);
- sel_print (";");
- }
- else if (flags & DUMP_INSN_PATTERN)
- {
- dump_insn_rtx_1 (i, DUMP_INSN_RTX_PATTERN | all);
- sel_print (";");
- }
- else if (flags & DUMP_INSN_UID)
- sel_print ("uid:%d;", INSN_UID (i));
- if (flags & DUMP_INSN_SEQNO)
- sel_print ("seqno:%d;", INSN_SEQNO (i));
- if (flags & DUMP_INSN_SCHED_CYCLE)
- {
- int cycle = INSN_SCHED_CYCLE (i);
- if (cycle != 0)
- sel_print ("cycle:%d;", cycle);
- }
- if (!sched_dump_to_dot_p)
- sel_print (")");
- }
- /* Dump insn I with default flags. */
- void
- dump_insn (insn_t i)
- {
- dump_insn_1 (i, DUMP_INSN_EXPR | DUMP_INSN_SCHED_CYCLE);
- }
- /* Dump INSN to stderr. */
- DEBUG_FUNCTION void
- debug_insn (insn_t insn)
- {
- switch_dump (stderr);
- dump_insn_1 (insn, debug_insn_flags);
- sel_print ("\n");
- restore_dump ();
- }
- /* Dumps av_set AV. */
- void
- dump_av_set (av_set_t av)
- {
- av_set_iterator i;
- expr_t expr;
- if (!sched_dump_to_dot_p)
- sel_print ("{");
- FOR_EACH_EXPR (expr, i, av)
- {
- dump_expr (expr);
- if (!sched_dump_to_dot_p)
- sel_print (" ");
- else
- sel_print ("\n");
- }
- if (!sched_dump_to_dot_p)
- sel_print ("}");
- }
- /* Dumps lvset LV. */
- void
- dump_lv_set (regset lv)
- {
- sel_print ("{");
- /* This code was adapted from cfg.c: dump_regset (). */
- if (lv == NULL)
- sel_print ("nil");
- else
- {
- unsigned i;
- reg_set_iterator rsi;
- int count = 0;
- EXECUTE_IF_SET_IN_REG_SET (lv, 0, i, rsi)
- {
- sel_print (" %d", i);
- if (i < FIRST_PSEUDO_REGISTER)
- {
- sel_print (" [%s]", reg_names[i]);
- ++count;
- }
- ++count;
- if (sched_dump_to_dot_p && count == 12)
- {
- count = 0;
- sel_print ("\n");
- }
- }
- }
- sel_print ("}\n");
- }
- /* Dumps a list of instructions pointed to by P. */
- static void
- dump_ilist (ilist_t p)
- {
- while (p)
- {
- dump_insn (ILIST_INSN (p));
- p = ILIST_NEXT (p);
- }
- }
- /* Dumps a list of boundaries pointed to by BNDS. */
- void
- dump_blist (blist_t bnds)
- {
- for (; bnds; bnds = BLIST_NEXT (bnds))
- {
- bnd_t bnd = BLIST_BND (bnds);
- sel_print ("[to: %d; ptr: ", INSN_UID (BND_TO (bnd)));
- dump_ilist (BND_PTR (bnd));
- sel_print ("] ");
- }
- }
- /* Dumps a list of fences pointed to by L. */
- void
- dump_flist (flist_t l)
- {
- while (l)
- {
- dump_insn_1 (FENCE_INSN (FLIST_FENCE (l)), dump_flist_insn_flags);
- sel_print (" ");
- l = FLIST_NEXT (l);
- }
- }
- /* Dumps an insn vector SUCCS. */
- void
- dump_insn_vector (rtx_vec_t succs)
- {
- int i;
- rtx_insn *succ;
- FOR_EACH_VEC_ELT (succs, i, succ)
- if (succ)
- dump_insn (succ);
- else
- sel_print ("NULL ");
- }
- /* Dumps a hard reg set SET to FILE using PREFIX. */
- static void
- print_hard_reg_set (FILE *file, const char *prefix, HARD_REG_SET set)
- {
- int i;
- fprintf (file, "%s{ ", prefix);
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- {
- if (TEST_HARD_REG_BIT (set, i))
- fprintf (file, "%d ", i);
- }
- fprintf (file, "}\n");
- }
- /* Dumps a hard reg set SET using PREFIX. */
- void
- dump_hard_reg_set (const char *prefix, HARD_REG_SET set)
- {
- print_hard_reg_set (sched_dump, prefix, set);
- }
- /* Pretty print INSN. This is used as a hook. */
- const char *
- sel_print_insn (const rtx_insn *insn, int aligned ATTRIBUTE_UNUSED)
- {
- static char buf[80];
- /* '+' before insn means it is a new cycle start and it's not been
- scheduled yet. '>' - has been scheduled. */
- if (s_i_d.exists () && INSN_LUID (insn) > 0)
- if (GET_MODE (insn) == TImode)
- sprintf (buf, "%s %4d",
- INSN_SCHED_TIMES (insn) > 0 ? "> " : "< ",
- INSN_UID (insn));
- else
- sprintf (buf, "%s %4d",
- INSN_SCHED_TIMES (insn) > 0 ? "! " : " ",
- INSN_UID (insn));
- else
- if (GET_MODE (insn) == TImode)
- sprintf (buf, "+ %4d", INSN_UID (insn));
- else
- sprintf (buf, " %4d", INSN_UID (insn));
- return buf;
- }
- /* Functions for pretty printing of CFG. */
- /* FIXME: Using pretty-print here could simplify this stuff. */
- /* Replace all occurencies of STR1 to STR2 in BUF.
- The BUF must be large enough to hold the result. */
- static void
- replace_str_in_buf (char *buf, const char *str1, const char *str2)
- {
- int buf_len = strlen (buf);
- int str1_len = strlen (str1);
- int str2_len = strlen (str2);
- int diff = str2_len - str1_len;
- char *p = buf;
- do
- {
- p = strstr (p, str1);
- if (p)
- {
- char *p1 = p + str1_len;
- /* Copy the rest of buf and '\0'. */
- int n = buf + buf_len - p1;
- int i;
- /* Shift str by DIFF chars. */
- if (diff > 0)
- for (i = n; i >= 0; i--)
- p1[i + diff] = p1[i];
- else
- for (i = 0; i <= n; i++)
- p1[i + diff] = p1[i];
- /* Copy str2. */
- for (i = 0; i < str2_len; i++)
- p[i] = str2[i];
- p += str2_len;
- buf_len += diff;
- }
- }
- while (p);
- }
- /* Replace characters in BUF that have special meaning in .dot file.
- Similar to pp_write_text_as_dot_label_to_stream. */
- static void
- sel_prepare_string_for_dot_label (char *buf)
- {
- static char specials_from[7][2] = { "<", ">", "{", "|", "}", "\"",
- "\n" };
- static char specials_to[7][3] = { "\\<", "\\>", "\\{", "\\|", "\\}",
- "\\\"", "\\l" };
- unsigned i;
- for (i = 0; i < 7; i++)
- replace_str_in_buf (buf, specials_from[i], specials_to[i]);
- }
- /* This function acts like printf but dumps to the sched_dump file. */
- void
- sel_print (const char *fmt, ...)
- {
- va_list ap;
- va_start (ap, fmt);
- if (sched_dump_to_dot_p)
- {
- char *message;
- if (vasprintf (&message, fmt, ap) >= 0 && message != NULL)
- {
- message = (char *) xrealloc (message, 2 * strlen (message) + 1);
- sel_prepare_string_for_dot_label (message);
- fprintf (sched_dump, "%s", message);
- free (message);
- }
- }
- else
- vfprintf (sched_dump, fmt, ap);
- va_end (ap);
- }
- /* Dump INSN with FLAGS. */
- static void
- sel_dump_cfg_insn (insn_t insn, int flags)
- {
- int insn_flags = DUMP_INSN_UID | DUMP_INSN_PATTERN;
- if (sched_luids.exists () && INSN_LUID (insn) > 0)
- {
- if (flags & SEL_DUMP_CFG_INSN_SEQNO)
- insn_flags |= DUMP_INSN_SEQNO | DUMP_INSN_SCHED_CYCLE | DUMP_INSN_EXPR;
- }
- dump_insn_1 (insn, insn_flags);
- }
- /* Dump E to the dot file F. */
- static void
- sel_dump_cfg_edge (FILE *f, edge e)
- {
- int w;
- const char *color;
- if (e->flags & EDGE_FALLTHRU)
- {
- w = 10;
- color = ", color = red";
- }
- else if (e->src->next_bb == e->dest)
- {
- w = 3;
- color = ", color = blue";
- }
- else
- {
- w = 1;
- color = "";
- }
- fprintf (f, "\tbb%d -> bb%d [weight = %d%s];\n",
- e->src->index, e->dest->index, w, color);
- }
- /* Return true if BB has a predesessor from current region.
- TODO: Either make this function to trace back through empty block
- or just remove those empty blocks. */
- static bool
- has_preds_in_current_region_p (basic_block bb)
- {
- edge e;
- edge_iterator ei;
- gcc_assert (!in_current_region_p (bb));
- FOR_EACH_EDGE (e, ei, bb->preds)
- if (in_current_region_p (e->src))
- return true;
- return false;
- }
- /* Dump a cfg region to the dot file F honoring FLAGS. */
- static void
- sel_dump_cfg_2 (FILE *f, int flags)
- {
- basic_block bb;
- sched_dump_to_dot_p = true;
- switch_dump (f);
- fprintf (f, "digraph G {\n"
- "\tratio = 2.25;\n"
- "\tnode [shape = record, fontsize = 9];\n");
- if (flags & SEL_DUMP_CFG_FUNCTION_NAME)
- fprintf (f, "function [label = \"%s\"];\n", current_function_name ());
- FOR_EACH_BB_FN (bb, cfun)
- {
- insn_t insn = BB_HEAD (bb);
- insn_t next_tail = NEXT_INSN (BB_END (bb));
- edge e;
- edge_iterator ei;
- bool in_region_p = ((flags & SEL_DUMP_CFG_CURRENT_REGION)
- && in_current_region_p (bb));
- bool full_p = (!(flags & SEL_DUMP_CFG_CURRENT_REGION)
- || in_region_p);
- bool some_p = full_p || has_preds_in_current_region_p (bb);
- const char *color;
- const char *style;
- if (!some_p)
- continue;
- if ((flags & SEL_DUMP_CFG_CURRENT_REGION)
- && in_current_region_p (bb)
- && BLOCK_TO_BB (bb->index) == 0)
- color = "color = green, ";
- else
- color = "";
- if ((flags & SEL_DUMP_CFG_FENCES)
- && in_region_p)
- {
- style = "";
- if (!sel_bb_empty_p (bb))
- {
- bool first_p = true;
- insn_t tail = BB_END (bb);
- insn_t cur_insn;
- cur_insn = bb_note (bb);
- do
- {
- fence_t fence;
- cur_insn = NEXT_INSN (cur_insn);
- fence = flist_lookup (fences, cur_insn);
- if (fence != NULL)
- {
- if (!FENCE_SCHEDULED_P (fence))
- {
- if (first_p)
- color = "color = red, ";
- else
- color = "color = yellow, ";
- }
- else
- color = "color = blue, ";
- }
- first_p = false;
- }
- while (cur_insn != tail);
- }
- }
- else if (!full_p)
- style = "style = dashed, ";
- else
- style = "";
- fprintf (f, "\tbb%d [%s%slabel = \"{Basic block %d", bb->index,
- style, color, bb->index);
- if ((flags & SEL_DUMP_CFG_BB_LOOP)
- && bb->loop_father != NULL)
- fprintf (f, ", loop %d", bb->loop_father->num);
- if (full_p
- && (flags & SEL_DUMP_CFG_BB_NOTES_LIST))
- {
- insn_t notes = BB_NOTE_LIST (bb);
- if (notes != NULL_RTX)
- {
- fprintf (f, "|");
- /* For simplicity, we dump notes from note_list in reversed order
- to that what they will appear in the code. */
- while (notes != NULL_RTX)
- {
- sel_dump_cfg_insn (notes, flags);
- fprintf (f, "\\l");
- notes = PREV_INSN (notes);
- }
- }
- }
- if (full_p
- && (flags & SEL_DUMP_CFG_AV_SET)
- && in_current_region_p (bb)
- && !sel_bb_empty_p (bb))
- {
- fprintf (f, "|");
- if (BB_AV_SET_VALID_P (bb))
- dump_av_set (BB_AV_SET (bb));
- else if (BB_AV_LEVEL (bb) == -1)
- fprintf (f, "AV_SET needs update");
- }
- if ((flags & SEL_DUMP_CFG_LV_SET)
- && !sel_bb_empty_p (bb))
- {
- fprintf (f, "|");
- if (BB_LV_SET_VALID_P (bb))
- dump_lv_set (BB_LV_SET (bb));
- else
- fprintf (f, "LV_SET needs update");
- }
- if (full_p
- && (flags & SEL_DUMP_CFG_BB_INSNS))
- {
- fprintf (f, "|");
- while (insn != next_tail)
- {
- sel_dump_cfg_insn (insn, flags);
- fprintf (f, "\\l");
- insn = NEXT_INSN (insn);
- }
- }
- fprintf (f, "}\"];\n");
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (full_p || in_current_region_p (e->dest))
- sel_dump_cfg_edge (f, e);
- }
- fprintf (f, "}");
- restore_dump ();
- sched_dump_to_dot_p = false;
- }
- /* Dump a cfg region to the file specified by TAG honoring flags.
- The file is created by the function. */
- static void
- sel_dump_cfg_1 (const char *tag, int flags)
- {
- char *buf;
- int i;
- FILE *f;
- ++sel_dump_cfg_fileno;
- if (!sel_dump_cfg_p)
- return;
- i = 1 + snprintf (NULL, 0, "%s/%s%05d-%s.dot", sel_debug_cfg_root,
- sel_debug_cfg_root_postfix, sel_dump_cfg_fileno, tag);
- buf = XNEWVEC (char, i);
- snprintf (buf, i, "%s/%s%05d-%s.dot", sel_debug_cfg_root,
- sel_debug_cfg_root_postfix, sel_dump_cfg_fileno, tag);
- f = fopen (buf, "w");
- if (f == NULL)
- fprintf (stderr, "Can't create file: %s.\n", buf);
- else
- {
- sel_dump_cfg_2 (f, flags);
- fclose (f);
- }
- free (buf);
- }
- /* Setup cfg dumping flags. Used for debugging. */
- void
- setup_dump_cfg_params (void)
- {
- sel_dump_cfg_flags = SEL_DUMP_CFG_FLAGS;
- sel_dump_cfg_p = 0;
- sel_debug_cfg_root_postfix = sel_debug_cfg_root_postfix_default;
- }
- /* Debug a cfg region with FLAGS. */
- void
- sel_debug_cfg_1 (int flags)
- {
- bool t1 = sel_dump_cfg_p;
- int t2 = sel_dump_cfg_fileno;
- sel_dump_cfg_p = true;
- sel_dump_cfg_fileno = ++sel_debug_cfg_fileno;
- sel_dump_cfg_1 ("sel-debug-cfg", flags);
- sel_dump_cfg_fileno = t2;
- sel_dump_cfg_p = t1;
- }
- /* Dumps av_set AV to stderr. */
- DEBUG_FUNCTION void
- debug_av_set (av_set_t av)
- {
- switch_dump (stderr);
- dump_av_set (av);
- sel_print ("\n");
- restore_dump ();
- }
- /* Dump LV to stderr. */
- DEBUG_FUNCTION void
- debug_lv_set (regset lv)
- {
- switch_dump (stderr);
- dump_lv_set (lv);
- sel_print ("\n");
- restore_dump ();
- }
- /* Dump an instruction list P to stderr. */
- DEBUG_FUNCTION void
- debug_ilist (ilist_t p)
- {
- switch_dump (stderr);
- dump_ilist (p);
- sel_print ("\n");
- restore_dump ();
- }
- /* Dump a boundary list BNDS to stderr. */
- DEBUG_FUNCTION void
- debug_blist (blist_t bnds)
- {
- switch_dump (stderr);
- dump_blist (bnds);
- sel_print ("\n");
- restore_dump ();
- }
- /* Dump a rtx vector REF. */
- DEBUG_FUNCTION void
- debug (vec<rtx_insn *> &ref)
- {
- switch_dump (stderr);
- dump_insn_vector (ref);
- sel_print ("\n");
- restore_dump ();
- }
- DEBUG_FUNCTION void
- debug (vec<rtx_insn *> *ptr)
- {
- if (ptr)
- debug (*ptr);
- else
- fprintf (stderr, "<nil>\n");
- }
- /* Dump an insn vector SUCCS. */
- DEBUG_FUNCTION void
- debug_insn_vector (rtx_vec_t succs)
- {
- switch_dump (stderr);
- dump_insn_vector (succs);
- sel_print ("\n");
- restore_dump ();
- }
- /* Dump a hard reg set SET to stderr. */
- DEBUG_FUNCTION void
- debug_hard_reg_set (HARD_REG_SET set)
- {
- switch_dump (stderr);
- dump_hard_reg_set ("", set);
- sel_print ("\n");
- restore_dump ();
- }
- /* Debug a cfg region with default flags. */
- void
- sel_debug_cfg (void)
- {
- sel_debug_cfg_1 (sel_debug_cfg_flags);
- }
- /* Print a current cselib value for X's address to stderr. */
- DEBUG_FUNCTION rtx
- debug_mem_addr_value (rtx x)
- {
- rtx t, addr;
- machine_mode address_mode;
- gcc_assert (MEM_P (x));
- address_mode = get_address_mode (x);
- t = shallow_copy_rtx (x);
- if (cselib_lookup (XEXP (t, 0), address_mode, 0, GET_MODE (t)))
- XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0), GET_MODE (t));
- t = canon_rtx (t);
- addr = get_addr (XEXP (t, 0));
- debug_rtx (t);
- debug_rtx (addr);
- return t;
- }
- #endif
|