diff options
Diffstat (limited to 'contrib/gcc/ra-debug.c')
-rw-r--r-- | contrib/gcc/ra-debug.c | 1087 |
1 files changed, 0 insertions, 1087 deletions
diff --git a/contrib/gcc/ra-debug.c b/contrib/gcc/ra-debug.c deleted file mode 100644 index 26aac12..0000000 --- a/contrib/gcc/ra-debug.c +++ /dev/null @@ -1,1087 +0,0 @@ -/* Graph coloring register allocator - Copyright (C) 2001, 2002 Free Software Foundation, Inc. - Contributed by Michael Matz <matz@suse.de> - and Daniel Berlin <dan@cgsoftware.com>. - - 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 2, 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 COPYING. If not, write to the Free Software - Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "rtl.h" -#include "insn-config.h" -#include "recog.h" -#include "function.h" -#include "hard-reg-set.h" -#include "basic-block.h" -#include "df.h" -#include "output.h" -#include "ra.h" -#include "tm_p.h" - -/* This file contains various dumping and debug functions for - the graph coloring register allocator. */ - -static void ra_print_rtx_1op (FILE *, rtx); -static void ra_print_rtx_2op (FILE *, rtx); -static void ra_print_rtx_3op (FILE *, rtx); -static void ra_print_rtx_object (FILE *, rtx); - -/* The hardregs as names, for debugging. */ -static const char *const reg_class_names[] = REG_CLASS_NAMES; - -/* Print a message to the dump file, if debug_new_regalloc and LEVEL - have any bits in common. */ - -void -ra_debug_msg (unsigned int level, const char *format, ...) -{ - va_list ap; - - va_start (ap, format); - if ((debug_new_regalloc & level) != 0 && rtl_dump_file != NULL) - vfprintf (rtl_dump_file, format, ap); - va_end (ap); -} - - -/* The following ra_print_xxx() functions print RTL expressions - in concise infix form. If the mode can be seen from context it's - left out. Most operators are represented by their graphical - characters, e.g. LE as "<=". Unknown constructs are currently - printed with print_inline_rtx(), which disrupts the nice layout. - Currently only the inline asm things are written this way. */ - -/* Print rtx X, which is a one operand rtx (op:mode (Y)), as - "op(Y)" to FILE. */ - -static void -ra_print_rtx_1op (FILE *file, rtx x) -{ - enum rtx_code code = GET_CODE (x); - rtx op0 = XEXP (x, 0); - switch (code) - { - case NEG: - case NOT: - fputs ((code == NEG) ? "-(" : "~(", file); - ra_print_rtx (file, op0, 0); - fputs (")", file); - break; - case HIGH: - fputs ("hi(", file); - ra_print_rtx (file, op0, 0); - fputs (")", file); - break; - default: - fprintf (file, "%s", GET_RTX_NAME (code)); - if (GET_MODE (x) != VOIDmode) - fprintf (file, ":%s(", GET_MODE_NAME (GET_MODE (x))); - else - fputs ("(", file); - ra_print_rtx (file, op0, 0); - fputs (")", file); - break; - } -} - -/* Print rtx X, which is a two operand rtx (op:mode (Y) (Z)) - as "(Y op Z)", if the operand is know, or as "op(Y, Z)", if not, - to FILE. */ - -static void -ra_print_rtx_2op (FILE *file, rtx x) -{ - int infix = 1; - const char *opname = "shitop"; - enum rtx_code code = GET_CODE (x); - rtx op0 = XEXP (x, 0); - rtx op1 = XEXP (x, 1); - switch (code) - { - /* class '2' */ - case COMPARE: opname = "?"; break; - case MINUS: opname = "-"; break; - case DIV: opname = "/"; break; - case UDIV: opname = "u/"; break; - case MOD: opname = "%"; break; - case UMOD: opname = "u%"; break; - case ASHIFT: opname = "<<"; break; - case ASHIFTRT: opname = "a>>"; break; - case LSHIFTRT: opname = "l>>"; break; - /* class 'c' */ - case PLUS: opname = "+"; break; - case MULT: opname = "*"; break; - case AND: opname = "&"; break; - case IOR: opname = "|"; break; - case XOR: opname = "^"; break; - /* class '<' */ - case NE: opname = "!="; break; - case EQ: opname = "=="; break; - case GE: opname = "s>="; break; - case GT: opname = "s>"; break; - case LE: opname = "s<="; break; - case LT: opname = "s<"; break; - case GEU: opname = "u>="; break; - case GTU: opname = "u>"; break; - case LEU: opname = "u<="; break; - case LTU: opname = "u<"; break; - default: - infix = 0; - opname = GET_RTX_NAME (code); - break; - } - if (infix) - { - fputs ("(", file); - ra_print_rtx (file, op0, 0); - fprintf (file, " %s ", opname); - ra_print_rtx (file, op1, 0); - fputs (")", file); - } - else - { - fprintf (file, "%s(", opname); - ra_print_rtx (file, op0, 0); - fputs (", ", file); - ra_print_rtx (file, op1, 0); - fputs (")", file); - } -} - -/* Print rtx X, which a three operand rtx to FILE. - I.e. X is either an IF_THEN_ELSE, or a bitmap operation. */ - -static void -ra_print_rtx_3op (FILE *file, rtx x) -{ - enum rtx_code code = GET_CODE (x); - rtx op0 = XEXP (x, 0); - rtx op1 = XEXP (x, 1); - rtx op2 = XEXP (x, 2); - if (code == IF_THEN_ELSE) - { - ra_print_rtx (file, op0, 0); - fputs (" ? ", file); - ra_print_rtx (file, op1, 0); - fputs (" : ", file); - ra_print_rtx (file, op2, 0); - } - else - { - /* Bitmap-operation */ - fprintf (file, "%s:%s(", GET_RTX_NAME (code), - GET_MODE_NAME (GET_MODE (x))); - ra_print_rtx (file, op0, 0); - fputs (", ", file); - ra_print_rtx (file, op1, 0); - fputs (", ", file); - ra_print_rtx (file, op2, 0); - fputs (")", file); - } -} - -/* Print rtx X, which represents an object (class 'o' or some constructs - of class 'x' (e.g. subreg)), to FILE. - (reg XX) rtl is represented as "pXX", of XX was a pseudo, - as "name" it name is the nonnull hardreg name, or as "hXX", if XX - is a hardreg, whose name is NULL, or empty. */ - -static void -ra_print_rtx_object (FILE *file, rtx x) -{ - enum rtx_code code = GET_CODE (x); - enum machine_mode mode = GET_MODE (x); - switch (code) - { - case CONST_INT: - fprintf (file, HOST_WIDE_INT_PRINT_DEC, XWINT (x, 0)); - break; - case CONST_DOUBLE: - { - int i, num = 0; - const char *fmt = GET_RTX_FORMAT (code); - fputs ("dbl(", file); - for (i = 0; i < GET_RTX_LENGTH (code); i++) - { - if (num) - fputs (", ", file); - if (fmt[i] == 'e' && XEXP (x, i)) - /* The MEM or other stuff */ - { - ra_print_rtx (file, XEXP (x, i), 0); - num++; - } - else if (fmt[i] == 'w') - { - fprintf (file, HOST_WIDE_INT_PRINT_HEX, XWINT (x, i)); - num++; - } - } - break; - } - case CONST_STRING: fprintf (file, "\"%s\"", XSTR (x, 0)); break; - case CONST: fputs ("const(", file); - ra_print_rtx (file, XEXP (x, 0), 0); - fputs (")", file); - break; - case PC: fputs ("pc", file); break; - case REG: - { - int regno = REGNO (x); - if (regno < FIRST_PSEUDO_REGISTER) - { - int i, nregs = HARD_REGNO_NREGS (regno, mode); - if (nregs > 1) - fputs ("[", file); - for (i = 0; i < nregs; i++) - { - if (i) - fputs (", ", file); - if (reg_names[regno+i] && *reg_names[regno + i]) - fprintf (file, "%s", reg_names[regno + i]); - else - fprintf (file, "h%d", regno + i); - } - if (nregs > 1) - fputs ("]", file); - } - else - fprintf (file, "p%d", regno); - break; - } - case SUBREG: - { - rtx sub = SUBREG_REG (x); - int ofs = SUBREG_BYTE (x); - if (GET_CODE (sub) == REG - && REGNO (sub) < FIRST_PSEUDO_REGISTER) - { - int regno = REGNO (sub); - int i, nregs = HARD_REGNO_NREGS (regno, mode); - regno += subreg_regno_offset (regno, GET_MODE (sub), - ofs, mode); - if (nregs > 1) - fputs ("[", file); - for (i = 0; i < nregs; i++) - { - if (i) - fputs (", ", file); - if (reg_names[regno+i]) - fprintf (file, "%s", reg_names[regno + i]); - else - fprintf (file, "h%d", regno + i); - } - if (nregs > 1) - fputs ("]", file); - } - else - { - ra_print_rtx (file, sub, 0); - fprintf (file, ":[%s+%d]", GET_MODE_NAME (mode), ofs); - } - break; - } - case SCRATCH: fputs ("scratch", file); break; - case CONCAT: ra_print_rtx_2op (file, x); break; - case HIGH: ra_print_rtx_1op (file, x); break; - case LO_SUM: - fputs ("(", file); - ra_print_rtx (file, XEXP (x, 0), 0); - fputs (" + lo(", file); - ra_print_rtx (file, XEXP (x, 1), 0); - fputs ("))", file); - break; - case MEM: fputs ("[", file); - ra_print_rtx (file, XEXP (x, 0), 0); - fprintf (file, "]:%s", GET_MODE_NAME (GET_MODE (x))); - /* XXX print alias set too ?? */ - break; - case LABEL_REF: - { - rtx sub = XEXP (x, 0); - if (GET_CODE (sub) == NOTE - && NOTE_LINE_NUMBER (sub) == NOTE_INSN_DELETED_LABEL) - fprintf (file, "(deleted uid=%d)", INSN_UID (sub)); - else if (GET_CODE (sub) == CODE_LABEL) - fprintf (file, "L%d", CODE_LABEL_NUMBER (sub)); - else - fprintf (file, "(nonlabel uid=%d)", INSN_UID (sub)); - } - break; - case SYMBOL_REF: - fprintf (file, "sym(\"%s\")", XSTR (x, 0)); break; - case CC0: fputs ("cc0", file); break; - default: print_inline_rtx (file, x, 0); break; - } -} - -/* Print a general rtx X to FILE in nice infix form. - If WITH_PN is set, and X is one of the toplevel constructs - (insns, notes, labels or barriers), then print also the UIDs of - the preceding and following insn. */ - -void -ra_print_rtx (FILE *file, rtx x, int with_pn) -{ - enum rtx_code code; - char class; - int unhandled = 0; - if (!x) - return; - code = GET_CODE (x); - class = GET_RTX_CLASS (code); - - /* First handle the insn like constructs. */ - if (INSN_P (x) || code == NOTE || code == CODE_LABEL || code == BARRIER) - { - if (INSN_P (x)) - fputs (" ", file); - /* Non-insns are prefixed by a ';'. */ - if (code == BARRIER) - fputs ("; ", file); - else if (code == NOTE) - /* But notes are indented very far right. */ - fprintf (file, "\t\t\t\t\t; "); - else if (code == CODE_LABEL) - /* And labels have their Lxx name first, before the actual UID. */ - { - fprintf (file, "L%d:\t; ", CODE_LABEL_NUMBER (x)); - if (LABEL_NAME (x)) - fprintf (file, "(%s) ", LABEL_NAME (x)); - switch (LABEL_KIND (x)) - { - case LABEL_NORMAL: break; - case LABEL_STATIC_ENTRY: fputs (" (entry)", file); break; - case LABEL_GLOBAL_ENTRY: fputs (" (global entry)", file); break; - case LABEL_WEAK_ENTRY: fputs (" (weak entry)", file); break; - default: abort(); - } - fprintf (file, " [%d uses] uid=(", LABEL_NUSES (x)); - } - fprintf (file, "%d", INSN_UID (x)); - if (with_pn) - fprintf (file, " %d %d", PREV_INSN (x) ? INSN_UID (PREV_INSN (x)) : 0, - NEXT_INSN (x) ? INSN_UID (NEXT_INSN (x)) : 0); - if (code == BARRIER) - fputs (" -------- barrier ---------", file); - else if (code == CODE_LABEL) - fputs (")", file); - else if (code == NOTE) - { - int ln = NOTE_LINE_NUMBER (x); - if (ln >= (int) NOTE_INSN_BIAS && ln < (int) NOTE_INSN_MAX) - fprintf (file, " %s", GET_NOTE_INSN_NAME (ln)); - else - { - fprintf (file, " line %d", ln); - if (NOTE_SOURCE_FILE (x)) - fprintf (file, ":%s", NOTE_SOURCE_FILE (x)); - } - } - else - { - fprintf (file, "\t"); - ra_print_rtx (file, PATTERN (x), 0); - } - return; - } - switch (code) - { - /* Top-level stuff. */ - case PARALLEL: - { - int j; - for (j = 0; j < XVECLEN (x, 0); j++) - { - if (j) - fputs ("\t;; ", file); - ra_print_rtx (file, XVECEXP (x, 0, j), 0); - } - break; - } - case UNSPEC: case UNSPEC_VOLATILE: - { - int j; - fprintf (file, "unspec%s(%d", - (code == UNSPEC) ? "" : "_vol", XINT (x, 1)); - for (j = 0; j < XVECLEN (x, 0); j++) - { - fputs (", ", file); - ra_print_rtx (file, XVECEXP (x, 0, j), 0); - } - fputs (")", file); - break; - } - case SET: - if (GET_CODE (SET_DEST (x)) == PC) - { - if (GET_CODE (SET_SRC (x)) == IF_THEN_ELSE - && GET_CODE (XEXP (SET_SRC(x), 2)) == PC) - { - fputs ("if ", file); - ra_print_rtx (file, XEXP (SET_SRC (x), 0), 0); - fputs (" jump ", file); - ra_print_rtx (file, XEXP (SET_SRC (x), 1), 0); - } - else - { - fputs ("jump ", file); - ra_print_rtx (file, SET_SRC (x), 0); - } - } - else - { - ra_print_rtx (file, SET_DEST (x), 0); - fputs (" <= ", file); - ra_print_rtx (file, SET_SRC (x), 0); - } - break; - case USE: - fputs ("use <= ", file); - ra_print_rtx (file, XEXP (x, 0), 0); - break; - case CLOBBER: - ra_print_rtx (file, XEXP (x, 0), 0); - fputs (" <= clobber", file); - break; - case CALL: - fputs ("call ", file); - ra_print_rtx (file, XEXP (x, 0), 0); /* Address */ - fputs (" numargs=", file); - ra_print_rtx (file, XEXP (x, 1), 0); /* Num arguments */ - break; - case RETURN: - fputs ("return", file); - break; - case TRAP_IF: - fputs ("if (", file); - ra_print_rtx (file, XEXP (x, 0), 0); - fputs (") trap ", file); - ra_print_rtx (file, XEXP (x, 1), 0); - break; - case RESX: - fprintf (file, "resx from region %d", XINT (x, 0)); - break; - - /* Different things of class 'x' */ - case SUBREG: ra_print_rtx_object (file, x); break; - case STRICT_LOW_PART: - fputs ("low(", file); - ra_print_rtx (file, XEXP (x, 0), 0); - fputs (")", file); - break; - default: - unhandled = 1; - break; - } - if (!unhandled) - return; - if (class == '1') - ra_print_rtx_1op (file, x); - else if (class == '2' || class == 'c' || class == '<') - ra_print_rtx_2op (file, x); - else if (class == '3' || class == 'b') - ra_print_rtx_3op (file, x); - else if (class == 'o') - ra_print_rtx_object (file, x); - else - print_inline_rtx (file, x, 0); -} - -/* This only calls ra_print_rtx(), but emits a final newline. */ - -void -ra_print_rtx_top (FILE *file, rtx x, int with_pn) -{ - ra_print_rtx (file, x, with_pn); - fprintf (file, "\n"); -} - -/* Callable from gdb. This prints rtx X onto stderr. */ - -void -ra_debug_rtx (rtx x) -{ - ra_print_rtx_top (stderr, x, 1); -} - -/* This prints the content of basic block with index BBI. - The first and last insn are emitted with UIDs of prev and next insns. */ - -void -ra_debug_bbi (int bbi) -{ - basic_block bb = BASIC_BLOCK (bbi); - rtx insn; - for (insn = BB_HEAD (bb); insn; insn = NEXT_INSN (insn)) - { - ra_print_rtx_top (stderr, insn, - (insn == BB_HEAD (bb) || insn == BB_END (bb))); - fprintf (stderr, "\n"); - if (insn == BB_END (bb)) - break; - } -} - -/* Beginning from INSN, emit NUM insns (if NUM is non-negative) - or emit a window of NUM insns around INSN, to stderr. */ - -void -ra_debug_insns (rtx insn, int num) -{ - int i, count = (num == 0 ? 1 : num < 0 ? -num : num); - if (num < 0) - for (i = count / 2; i > 0 && PREV_INSN (insn); i--) - insn = PREV_INSN (insn); - for (i = count; i > 0 && insn; insn = NEXT_INSN (insn), i--) - { - if (GET_CODE (insn) == CODE_LABEL) - fprintf (stderr, "\n"); - ra_print_rtx_top (stderr, insn, (i == count || i == 1)); - } -} - -/* Beginning with INSN, emit the whole insn chain into FILE. - This also outputs comments when basic blocks start or end and omits - some notes, if flag_ra_dump_notes is zero. */ - -void -ra_print_rtl_with_bb (FILE *file, rtx insn) -{ - basic_block last_bb, bb; - unsigned int num = 0; - if (!insn) - fputs ("nil", file); - last_bb = NULL; - for (; insn; insn = NEXT_INSN (insn)) - { - if (GET_CODE (insn) == BARRIER) - bb = NULL; - else - bb = BLOCK_FOR_INSN (insn); - if (bb != last_bb) - { - if (last_bb) - fprintf (file, ";; End of basic block %d\n", last_bb->index); - if (bb) - fprintf (file, ";; Begin of basic block %d\n", bb->index); - last_bb = bb; - } - if (GET_CODE (insn) == CODE_LABEL) - fputc ('\n', file); - if (GET_CODE (insn) == NOTE) - { - /* Ignore basic block and maybe other notes not referencing - deleted things. */ - if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK - && (flag_ra_dump_notes - || NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED - || NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)) - { - ra_print_rtx_top (file, insn, (num == 0 || !NEXT_INSN (insn))); - num++; - } - } - else - { - ra_print_rtx_top (file, insn, (num == 0 || !NEXT_INSN (insn))); - num++; - } - } -} - -/* Count how many insns were seen how often, while building the interference - graph, and prints the findings. */ - -void -dump_number_seen (void) -{ -#define N 17 - int num[N]; - int i; - - for (i = 0; i < N; i++) - num[i] = 0; - for (i = 0; i < get_max_uid (); i++) - if (number_seen[i] < N - 1) - num[number_seen[i]]++; - else - num[N - 1]++; - for (i = 0; i < N - 1; i++) - if (num[i]) - ra_debug_msg (DUMP_PROCESS, "%d insns seen %d times\n", num[i], i); - if (num[N - 1]) - ra_debug_msg (DUMP_PROCESS, "%d insns seen %d and more times\n", num[i], - N - 1); - ra_debug_msg (DUMP_PROCESS, "from overall %d insns\n", get_max_uid ()); -#undef N -} - -/* Dump the interference graph, the move list and the webs. */ - -void -dump_igraph (struct df *df ATTRIBUTE_UNUSED) -{ - struct move_list *ml; - unsigned int def1, def2; - int num = 0; - int num2; - unsigned int i; - if (!rtl_dump_file || (debug_new_regalloc & (DUMP_IGRAPH | DUMP_WEBS)) == 0) - return; - ra_debug_msg (DUMP_IGRAPH, "conflicts:\n "); - for (def1 = 0; def1 < num_webs; def1++) - { - int num1 = num; - num2 = 0; - for (def2 = 0; def2 < num_webs; def2++) - if (def1 != def2 && TEST_BIT (igraph, igraph_index (def1, def2))) - { - if (num1 == num) - { - if (SUBWEB_P (ID2WEB (def1))) - ra_debug_msg (DUMP_IGRAPH, "%d (SUBREG %d, %d) with ", def1, - ID2WEB (def1)->regno, - SUBREG_BYTE (ID2WEB (def1)->orig_x)); - else - ra_debug_msg (DUMP_IGRAPH, "%d (REG %d) with ", def1, - ID2WEB (def1)->regno); - } - if ((num2 % 9) == 8) - ra_debug_msg (DUMP_IGRAPH, "\n "); - num++; - num2++; - if (SUBWEB_P (ID2WEB (def2))) - ra_debug_msg (DUMP_IGRAPH, "%d(%d,%d) ", def2, ID2WEB (def2)->regno, - SUBREG_BYTE (ID2WEB (def2)->orig_x)); - else - ra_debug_msg (DUMP_IGRAPH, "%d(%d) ", def2, ID2WEB (def2)->regno); - } - if (num1 != num) - ra_debug_msg (DUMP_IGRAPH, "\n "); - } - ra_debug_msg (DUMP_IGRAPH, "\n"); - for (ml = wl_moves; ml; ml = ml->next) - if (ml->move) - { - ra_debug_msg (DUMP_IGRAPH, "move: insn %d: Web %d <-- Web %d\n", - INSN_UID (ml->move->insn), ml->move->target_web->id, - ml->move->source_web->id); - } - ra_debug_msg (DUMP_WEBS, "\nWebs:\n"); - for (i = 0; i < num_webs; i++) - { - struct web *web = ID2WEB (i); - - ra_debug_msg (DUMP_WEBS, " %4d : regno %3d", i, web->regno); - if (SUBWEB_P (web)) - { - ra_debug_msg (DUMP_WEBS, " sub %d", SUBREG_BYTE (web->orig_x)); - ra_debug_msg (DUMP_WEBS, " par %d", find_web_for_subweb (web)->id); - } - ra_debug_msg (DUMP_WEBS, " +%d (span %d, cost " - HOST_WIDE_INT_PRINT_DEC ") (%s)", - web->add_hardregs, web->span_deaths, web->spill_cost, - reg_class_names[web->regclass]); - if (web->spill_temp == 1) - ra_debug_msg (DUMP_WEBS, " (spilltemp)"); - else if (web->spill_temp == 2) - ra_debug_msg (DUMP_WEBS, " (spilltem2)"); - else if (web->spill_temp == 3) - ra_debug_msg (DUMP_WEBS, " (short)"); - if (web->type == PRECOLORED) - ra_debug_msg (DUMP_WEBS, " (precolored, color=%d)", web->color); - else if (find_web_for_subweb (web)->num_uses == 0) - ra_debug_msg (DUMP_WEBS, " dead"); - if (web->crosses_call) - ra_debug_msg (DUMP_WEBS, " xcall"); - if (web->regno >= max_normal_pseudo) - ra_debug_msg (DUMP_WEBS, " stack"); - ra_debug_msg (DUMP_WEBS, "\n"); - } -} - -/* Dump the interference graph and webs in a format easily - parsable by programs. Used to emit real world interference graph - to my custom graph colorizer. */ - -void -dump_igraph_machine (void) -{ - unsigned int i; - - if (!rtl_dump_file || (debug_new_regalloc & DUMP_IGRAPH_M) == 0) - return; - ra_debug_msg (DUMP_IGRAPH_M, "g %d %d\n", num_webs - num_subwebs, - FIRST_PSEUDO_REGISTER); - for (i = 0; i < num_webs - num_subwebs; i++) - { - struct web *web = ID2WEB (i); - struct conflict_link *cl; - int flags = 0; - int numc = 0; - int col = 0; - flags = web->spill_temp & 0xF; - flags |= ((web->type == PRECOLORED) ? 1 : 0) << 4; - flags |= (web->add_hardregs & 0xF) << 5; - for (cl = web->conflict_list; cl; cl = cl->next) - if (cl->t->id < web->id) - numc++; - ra_debug_msg (DUMP_IGRAPH_M, "n %d %d %d %d %d %d %d\n", - web->id, web->color, flags, - (unsigned int)web->spill_cost, web->num_defs, web->num_uses, - numc); - if (web->type != PRECOLORED) - { - ra_debug_msg (DUMP_IGRAPH_M, "s %d", web->id); - while (1) - { - unsigned int u = 0; - int n; - for (n = 0; n < 32 && col < FIRST_PSEUDO_REGISTER; n++, col++) - if (TEST_HARD_REG_BIT (web->usable_regs, col)) - u |= 1 << n; - ra_debug_msg (DUMP_IGRAPH_M, " %u", u); - if (col >= FIRST_PSEUDO_REGISTER) - break; - } - ra_debug_msg (DUMP_IGRAPH_M, "\n"); - } - if (numc) - { - ra_debug_msg (DUMP_IGRAPH_M, "c %d", web->id); - for (cl = web->conflict_list; cl; cl = cl->next) - { - if (cl->t->id < web->id) - ra_debug_msg (DUMP_IGRAPH_M, " %d", cl->t->id); - } - ra_debug_msg (DUMP_IGRAPH_M, "\n"); - } - } - ra_debug_msg (DUMP_IGRAPH_M, "e\n"); -} - -/* This runs after colorization and changing the insn stream. - It temporarily replaces all pseudo registers with their colors, - and emits information, if the resulting insns are strictly valid. */ - -void -dump_constraints (void) -{ - rtx insn; - int i; - if (!rtl_dump_file || (debug_new_regalloc & DUMP_CONSTRAINTS) == 0) - return; - for (i = FIRST_PSEUDO_REGISTER; i < ra_max_regno; i++) - if (regno_reg_rtx[i] && GET_CODE (regno_reg_rtx[i]) == REG) - REGNO (regno_reg_rtx[i]) - = ra_reg_renumber[i] >= 0 ? ra_reg_renumber[i] : i; - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - if (INSN_P (insn)) - { - int code; - int uid = INSN_UID (insn); - int o; - /* Don't simply force rerecognition, as combine might left us - with some unrecognizable ones, which later leads to aborts - in regclass, if we now destroy the remembered INSN_CODE(). */ - /*INSN_CODE (insn) = -1;*/ - code = recog_memoized (insn); - if (code < 0) - { - ra_debug_msg (DUMP_CONSTRAINTS, - "%d: asm insn or not recognizable.\n", uid); - continue; - } - ra_debug_msg (DUMP_CONSTRAINTS, - "%d: code %d {%s}, %d operands, constraints: ", - uid, code, insn_data[code].name, recog_data.n_operands); - extract_insn (insn); - /*preprocess_constraints ();*/ - for (o = 0; o < recog_data.n_operands; o++) - { - ra_debug_msg (DUMP_CONSTRAINTS, - "%d:%s ", o, recog_data.constraints[o]); - } - if (constrain_operands (1)) - ra_debug_msg (DUMP_CONSTRAINTS, "matches strictly alternative %d", - which_alternative); - else - ra_debug_msg (DUMP_CONSTRAINTS, "doesn't match strictly"); - ra_debug_msg (DUMP_CONSTRAINTS, "\n"); - } - for (i = FIRST_PSEUDO_REGISTER; i < ra_max_regno; i++) - if (regno_reg_rtx[i] && GET_CODE (regno_reg_rtx[i]) == REG) - REGNO (regno_reg_rtx[i]) = i; -} - -/* This counts and emits the cumulated cost of all spilled webs, - preceded by a custom message MSG, with debug level LEVEL. */ - -void -dump_graph_cost (unsigned int level, const char *msg) -{ - unsigned int i; - unsigned HOST_WIDE_INT cost; - if (!rtl_dump_file || (debug_new_regalloc & level) == 0) - return; - - cost = 0; - for (i = 0; i < num_webs; i++) - { - struct web *web = id2web[i]; - if (alias (web)->type == SPILLED) - cost += web->orig_spill_cost; - } - ra_debug_msg (level, " spill cost of graph (%s) = " - HOST_WIDE_INT_PRINT_UNSIGNED "\n", - msg ? msg : "", cost); -} - -/* Dump the color assignment per web, the coalesced and spilled webs. */ - -void -dump_ra (struct df *df ATTRIBUTE_UNUSED) -{ - struct web *web; - struct dlist *d; - if (!rtl_dump_file || (debug_new_regalloc & DUMP_RESULTS) == 0) - return; - - ra_debug_msg (DUMP_RESULTS, "\nColored:\n"); - for (d = WEBS(COLORED); d; d = d->next) - { - web = DLIST_WEB (d); - ra_debug_msg (DUMP_RESULTS, " %4d : color %d\n", web->id, web->color); - } - ra_debug_msg (DUMP_RESULTS, "\nCoalesced:\n"); - for (d = WEBS(COALESCED); d; d = d->next) - { - web = DLIST_WEB (d); - ra_debug_msg (DUMP_RESULTS, " %4d : to web %d, color %d\n", web->id, - alias (web)->id, web->color); - } - ra_debug_msg (DUMP_RESULTS, "\nSpilled:\n"); - for (d = WEBS(SPILLED); d; d = d->next) - { - web = DLIST_WEB (d); - ra_debug_msg (DUMP_RESULTS, " %4d\n", web->id); - } - ra_debug_msg (DUMP_RESULTS, "\n"); - dump_cost (DUMP_RESULTS); -} - -/* Calculate and dump the cumulated costs of certain types of insns - (loads, stores and copies). */ - -void -dump_static_insn_cost (FILE *file, const char *message, const char *prefix) -{ - struct cost - { - unsigned HOST_WIDE_INT cost; - unsigned int count; - }; - basic_block bb; - struct cost load, store, regcopy, selfcopy, overall; - memset (&load, 0, sizeof(load)); - memset (&store, 0, sizeof(store)); - memset (®copy, 0, sizeof(regcopy)); - memset (&selfcopy, 0, sizeof(selfcopy)); - memset (&overall, 0, sizeof(overall)); - - if (!file) - return; - - FOR_EACH_BB (bb) - { - unsigned HOST_WIDE_INT block_cost = bb->frequency; - rtx insn, set; - for (insn = BB_HEAD (bb); insn; insn = NEXT_INSN (insn)) - { - /* Yes, yes. We don't calculate the costs precisely. - Only for "simple enough" insns. Those containing single - sets only. */ - if (INSN_P (insn) && ((set = single_set (insn)) != NULL)) - { - rtx src = SET_SRC (set); - rtx dest = SET_DEST (set); - struct cost *pcost = NULL; - overall.cost += block_cost; - overall.count++; - if (rtx_equal_p (src, dest)) - pcost = &selfcopy; - else if (GET_CODE (src) == GET_CODE (dest) - && ((GET_CODE (src) == REG) - || (GET_CODE (src) == SUBREG - && GET_CODE (SUBREG_REG (src)) == REG - && GET_CODE (SUBREG_REG (dest)) == REG))) - pcost = ®copy; - else - { - if (GET_CODE (src) == SUBREG) - src = SUBREG_REG (src); - if (GET_CODE (dest) == SUBREG) - dest = SUBREG_REG (dest); - if (GET_CODE (src) == MEM && GET_CODE (dest) != MEM - && memref_is_stack_slot (src)) - pcost = &load; - else if (GET_CODE (src) != MEM && GET_CODE (dest) == MEM - && memref_is_stack_slot (dest)) - pcost = &store; - } - if (pcost) - { - pcost->cost += block_cost; - pcost->count++; - } - } - if (insn == BB_END (bb)) - break; - } - } - - if (!prefix) - prefix = ""; - fprintf (file, "static insn cost %s\n", message ? message : ""); - fprintf (file, " %soverall:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n", - prefix, overall.count, overall.cost); - fprintf (file, " %sloads:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n", - prefix, load.count, load.cost); - fprintf (file, " %sstores:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n", - prefix, store.count, store.cost); - fprintf (file, " %sregcopy:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n", - prefix, regcopy.count, regcopy.cost); - fprintf (file, " %sselfcpy:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n", - prefix, selfcopy.count, selfcopy.cost); -} - -/* Returns nonzero, if WEB1 and WEB2 have some possible - hardregs in common. */ - -int -web_conflicts_p (struct web *web1, struct web *web2) -{ - if (web1->type == PRECOLORED && web2->type == PRECOLORED) - return 0; - - if (web1->type == PRECOLORED) - return TEST_HARD_REG_BIT (web2->usable_regs, web1->regno); - - if (web2->type == PRECOLORED) - return TEST_HARD_REG_BIT (web1->usable_regs, web2->regno); - - return hard_regs_intersect_p (&web1->usable_regs, &web2->usable_regs); -} - -/* Dump all uids of insns in which WEB is mentioned. */ - -void -dump_web_insns (struct web *web) -{ - unsigned int i; - - ra_debug_msg (DUMP_EVER, "Web: %i(%i)+%i class: %s freedom: %i degree %i\n", - web->id, web->regno, web->add_hardregs, - reg_class_names[web->regclass], - web->num_freedom, web->num_conflicts); - ra_debug_msg (DUMP_EVER, " def insns:"); - - for (i = 0; i < web->num_defs; ++i) - { - ra_debug_msg (DUMP_EVER, " %d ", INSN_UID (web->defs[i]->insn)); - } - - ra_debug_msg (DUMP_EVER, "\n use insns:"); - for (i = 0; i < web->num_uses; ++i) - { - ra_debug_msg (DUMP_EVER, " %d ", INSN_UID (web->uses[i]->insn)); - } - ra_debug_msg (DUMP_EVER, "\n"); -} - -/* Dump conflicts for web WEB. */ - -void -dump_web_conflicts (struct web *web) -{ - int num = 0; - unsigned int def2; - - ra_debug_msg (DUMP_EVER, "Web: %i(%i)+%i class: %s freedom: %i degree %i\n", - web->id, web->regno, web->add_hardregs, - reg_class_names[web->regclass], - web->num_freedom, web->num_conflicts); - - for (def2 = 0; def2 < num_webs; def2++) - if (TEST_BIT (igraph, igraph_index (web->id, def2)) && web->id != def2) - { - if ((num % 9) == 5) - ra_debug_msg (DUMP_EVER, "\n "); - num++; - - ra_debug_msg (DUMP_EVER, " %d(%d)", def2, id2web[def2]->regno); - if (id2web[def2]->add_hardregs) - ra_debug_msg (DUMP_EVER, "+%d", id2web[def2]->add_hardregs); - - if (web_conflicts_p (web, id2web[def2])) - ra_debug_msg (DUMP_EVER, "/x"); - - if (id2web[def2]->type == SELECT) - ra_debug_msg (DUMP_EVER, "/s"); - - if (id2web[def2]->type == COALESCED) - ra_debug_msg (DUMP_EVER,"/c/%d", alias (id2web[def2])->id); - } - ra_debug_msg (DUMP_EVER, "\n"); - { - struct conflict_link *wl; - num = 0; - ra_debug_msg (DUMP_EVER, "By conflicts: "); - for (wl = web->conflict_list; wl; wl = wl->next) - { - struct web* w = wl->t; - if ((num % 9) == 8) - ra_debug_msg (DUMP_EVER, "\n "); - num++; - ra_debug_msg (DUMP_EVER, "%d(%d)%s ", w->id, w->regno, - web_conflicts_p (web, w) ? "+" : ""); - } - ra_debug_msg (DUMP_EVER, "\n"); - } -} - -/* Output HARD_REG_SET to stderr. */ - -void -debug_hard_reg_set (HARD_REG_SET set) -{ - int i; - for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i) - { - if (TEST_HARD_REG_BIT (set, i)) - { - fprintf (stderr, "%s ", reg_names[i]); - } - } - fprintf (stderr, "\n"); -} - -/* -vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4: -*/ |