/* Graph coloring register allocator
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
Contributed by Michael Matz <matz@suse.de>
and Daniel Berlin <dan@cgsoftware.com>.
#include "output.h"
#include "ra.h"
#include "tm_p.h"
+#include "regs.h"
/* This file contains various dumping and debug functions for
the graph coloring register allocator. */
-static void ra_print_rtx_1op PARAMS ((FILE *, rtx));
-static void ra_print_rtx_2op PARAMS ((FILE *, rtx));
-static void ra_print_rtx_3op PARAMS ((FILE *, rtx));
-static void ra_print_rtx_object PARAMS ((FILE *, rtx));
+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;
va_list ap;
va_start (ap, format);
- if ((debug_new_regalloc & level) != 0 && rtl_dump_file != NULL)
- vfprintf (rtl_dump_file, format, ap);
+ if ((debug_new_regalloc & level) != 0 && dump_file != NULL)
+ vfprintf (dump_file, format, ap);
va_end (ap);
}
"op(Y)" to FILE. */
static void
-ra_print_rtx_1op (file, x)
- FILE *file;
- rtx x;
+ra_print_rtx_1op (FILE *file, rtx x)
{
enum rtx_code code = GET_CODE (x);
rtx op0 = XEXP (x, 0);
to FILE. */
static void
-ra_print_rtx_2op (file, x)
- FILE *file;
- rtx x;
+ra_print_rtx_2op (FILE *file, rtx x)
{
int infix = 1;
const char *opname = "shitop";
case AND: opname = "&"; break;
case IOR: opname = "|"; break;
case XOR: opname = "^"; break;
- /* class '<' */
+ /* class '=' */
case NE: opname = "!="; break;
case EQ: opname = "=="; break;
+ case LTGT: opname = "<>"; break;
+ /* class '<' */
case GE: opname = "s>="; break;
case GT: opname = "s>"; break;
case LE: opname = "s<="; break;
I.e. X is either an IF_THEN_ELSE, or a bitmap operation. */
static void
-ra_print_rtx_3op (file, x)
- FILE *file;
- rtx x;
+ra_print_rtx_3op (FILE *file, rtx x)
{
enum rtx_code code = GET_CODE (x);
rtx op0 = XEXP (x, 0);
}
}
-/* Print rtx X, which represents an object (class 'o' or some constructs
+/* Print rtx X, which represents an object (class 'o', 'C', 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, x)
- FILE *file;
- rtx x;
+ra_print_rtx_object (FILE *file, rtx x)
{
enum rtx_code code = GET_CODE (x);
enum machine_mode mode = GET_MODE (x);
int regno = REGNO (x);
if (regno < FIRST_PSEUDO_REGISTER)
{
- int i, nregs = HARD_REGNO_NREGS (regno, mode);
+ int i, nregs = hard_regno_nregs[regno][mode];
if (nregs > 1)
fputs ("[", file);
for (i = 0; i < nregs; i++)
&& REGNO (sub) < FIRST_PSEUDO_REGISTER)
{
int regno = REGNO (sub);
- int i, nregs = HARD_REGNO_NREGS (regno, mode);
+ int i, nregs = hard_regno_nregs[regno][mode];
regno += subreg_regno_offset (regno, GET_MODE (sub),
ofs, mode);
if (nregs > 1)
the preceding and following insn. */
void
-ra_print_rtx (file, x, with_pn)
- FILE *file;
- rtx x;
- int with_pn;
+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 (!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);
+ switch (GET_RTX_CLASS (code))
+ {
+ case RTX_UNARY:
+ ra_print_rtx_1op (file, x);
+ break;
+ case RTX_BIN_ARITH:
+ case RTX_COMM_ARITH:
+ case RTX_COMPARE:
+ case RTX_COMM_COMPARE:
+ ra_print_rtx_2op (file, x);
+ break;
+ case RTX_TERNARY:
+ case RTX_BITFIELD_OPS:
+ ra_print_rtx_3op (file, x);
+ break;
+ case RTX_OBJ:
+ case RTX_CONST_OBJ:
+ ra_print_rtx_object (file, x);
+ break;
+ default:
+ print_inline_rtx (file, x, 0);
+ break;
+ }
}
/* This only calls ra_print_rtx(), but emits a final newline. */
void
-ra_print_rtx_top (file, x, with_pn)
- FILE *file;
- rtx x;
- int with_pn;
+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 (x)
- rtx x;
+ra_debug_rtx (rtx x)
{
ra_print_rtx_top (stderr, x, 1);
}
The first and last insn are emitted with UIDs of prev and next insns. */
void
-ra_debug_bbi (bbi)
- int bbi;
+ra_debug_bbi (int bbi)
{
basic_block bb = BASIC_BLOCK (bbi);
rtx insn;
- for (insn = bb->head; insn; insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (bb); insn; insn = NEXT_INSN (insn))
{
- ra_print_rtx_top (stderr, insn, (insn == bb->head || insn == bb->end));
+ ra_print_rtx_top (stderr, insn,
+ (insn == BB_HEAD (bb) || insn == BB_END (bb)));
fprintf (stderr, "\n");
- if (insn == bb->end)
+ if (insn == BB_END (bb))
break;
}
}
or emit a window of NUM insns around INSN, to stderr. */
void
-ra_debug_insns (insn, num)
- rtx insn;
- int num;
+ra_debug_insns (rtx insn, int num)
{
int i, count = (num == 0 ? 1 : num < 0 ? -num : num);
if (num < 0)
some notes, if flag_ra_dump_notes is zero. */
void
-ra_print_rtl_with_bb (file, insn)
- FILE *file;
- rtx insn;
+ra_print_rtl_with_bb (FILE *file, rtx insn)
{
basic_block last_bb, bb;
unsigned int num = 0;
graph, and prints the findings. */
void
-dump_number_seen ()
+dump_number_seen (void)
{
#define N 17
int num[N];
/* Dump the interference graph, the move list and the webs. */
void
-dump_igraph (df)
- struct df *df ATTRIBUTE_UNUSED;
+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)
+ if (!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++)
to my custom graph colorizer. */
void
-dump_igraph_machine ()
+dump_igraph_machine (void)
{
unsigned int i;
- if (!rtl_dump_file || (debug_new_regalloc & DUMP_IGRAPH_M) == 0)
+ if (!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);
and emits information, if the resulting insns are strictly valid. */
void
-dump_constraints ()
+dump_constraints (void)
{
rtx insn;
int i;
- if (!rtl_dump_file || (debug_new_regalloc & DUMP_CONSTRAINTS) == 0)
+ if (!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)
preceded by a custom message MSG, with debug level LEVEL. */
void
-dump_graph_cost (level, msg)
- unsigned int level;
- const char *msg;
+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)
+ if (!dump_file || (debug_new_regalloc & level) == 0)
return;
cost = 0;
/* Dump the color assignment per web, the coalesced and spilled webs. */
void
-dump_ra (df)
- struct df *df ATTRIBUTE_UNUSED;
+dump_ra (struct df *df ATTRIBUTE_UNUSED)
{
struct web *web;
struct dlist *d;
- if (!rtl_dump_file || (debug_new_regalloc & DUMP_RESULTS) == 0)
+ if (!dump_file || (debug_new_regalloc & DUMP_RESULTS) == 0)
return;
ra_debug_msg (DUMP_RESULTS, "\nColored:\n");
(loads, stores and copies). */
void
-dump_static_insn_cost (file, message, prefix)
- FILE *file;
- const char *message;
- const char *prefix;
+dump_static_insn_cost (FILE *file, const char *message, const char *prefix)
{
struct cost
{
{
unsigned HOST_WIDE_INT block_cost = bb->frequency;
rtx insn, set;
- for (insn = bb->head; insn; insn = NEXT_INSN (insn))
+ 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
pcost->count++;
}
}
- if (insn == bb->end)
+ if (insn == BB_END (bb))
break;
}
}
if (!prefix)
prefix = "";
fprintf (file, "static insn cost %s\n", message ? message : "");
- fprintf (file, " %soverall:\tnum=%6d\tcost="
- HOST_WIDE_INT_PRINT_DEC_SPACE "\n",
- prefix, overall.count, 8, overall.cost);
- fprintf (file, " %sloads:\tnum=%6d\tcost="
- HOST_WIDE_INT_PRINT_DEC_SPACE "\n",
- prefix, load.count, 8, load.cost);
- fprintf (file, " %sstores:\tnum=%6d\tcost="
- HOST_WIDE_INT_PRINT_DEC_SPACE "\n",
- prefix, store.count, 8, store.cost);
- fprintf (file, " %sregcopy:\tnum=%6d\tcost="
- HOST_WIDE_INT_PRINT_DEC_SPACE "\n",
- prefix, regcopy.count, 8, regcopy.cost);
- fprintf (file, " %sselfcpy:\tnum=%6d\tcost="
- HOST_WIDE_INT_PRINT_DEC_SPACE "\n",
- prefix, selfcopy.count, 8, selfcopy.cost);
+ 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 (web1, web2)
- struct web *web1;
- struct web *web2;
+web_conflicts_p (struct web *web1, struct web *web2)
{
if (web1->type == PRECOLORED && web2->type == PRECOLORED)
return 0;
/* Dump all uids of insns in which WEB is mentioned. */
void
-dump_web_insns (web)
- struct web *web;
+dump_web_insns (struct web *web)
{
unsigned int i;
/* Dump conflicts for web WEB. */
void
-dump_web_conflicts (web)
- struct web *web;
+dump_web_conflicts (struct web *web)
{
int num = 0;
unsigned int def2;
/* Output HARD_REG_SET to stderr. */
void
-debug_hard_reg_set (set)
- HARD_REG_SET set;
+debug_hard_reg_set (HARD_REG_SET set)
{
int i;
for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)