/* RTL utility routines.
Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003 Free Software Foundation, Inc.
+ 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
#undef DEF_RTL_EXPR
-/* Indexed by machine mode, gives the name of that machine mode.
- This name does not include the letters "mode". */
-
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) NAME,
-
-const char * const mode_name[NUM_MACHINE_MODES] = {
-#include "machmode.def"
-};
-
-#undef DEF_MACHMODE
-
-/* Indexed by machine mode, gives the class mode for GET_MODE_CLASS. */
-
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) CLASS,
-
-const enum mode_class mode_class[NUM_MACHINE_MODES] = {
-#include "machmode.def"
-};
-
-#undef DEF_MACHMODE
-
-/* Indexed by machine mode, gives the length of the mode, in bits.
- GET_MODE_BITSIZE uses this. */
-
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) BITSIZE,
-
-const unsigned short mode_bitsize[NUM_MACHINE_MODES] = {
-#include "machmode.def"
-};
-
-#undef DEF_MACHMODE
-
-/* Indexed by machine mode, gives the length of the mode, in bytes.
- GET_MODE_SIZE uses this. */
-
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) SIZE,
-
-const unsigned char mode_size[NUM_MACHINE_MODES] = {
-#include "machmode.def"
-};
-
-#undef DEF_MACHMODE
-
-/* Indexed by machine mode, gives the length of the mode's subunit.
- GET_MODE_UNIT_SIZE uses this. */
-
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) UNIT,
-
-const unsigned char mode_unit_size[NUM_MACHINE_MODES] = {
-#include "machmode.def" /* machine modes are documented here */
-};
-
-#undef DEF_MACHMODE
-
-/* Indexed by machine mode, gives next wider natural mode
- (QI -> HI -> SI -> DI, etc.) Widening multiply instructions
- use this. */
-
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) \
- (unsigned char) WIDER,
-
-const unsigned char mode_wider_mode[NUM_MACHINE_MODES] = {
-#include "machmode.def" /* machine modes are documented here */
-};
-
-#undef DEF_MACHMODE
-
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) \
- ((BITSIZE) >= HOST_BITS_PER_WIDE_INT) ? ~(unsigned HOST_WIDE_INT) 0 : ((unsigned HOST_WIDE_INT) 1 << (BITSIZE)) - 1,
-
-/* Indexed by machine mode, gives mask of significant bits in mode. */
-
-const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES] = {
-#include "machmode.def"
-};
-
-#undef DEF_MACHMODE
-
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) INNER,
-
-/* Indexed by machine mode, gives the mode of the inner elements in a
- vector type. */
-
-const enum machine_mode inner_mode_array[NUM_MACHINE_MODES] = {
-#include "machmode.def"
-};
-
-/* Indexed by mode class, gives the narrowest mode for each class.
- The Q modes are always of width 1 (2 for complex) - it is impossible
- for any mode to be narrower.
-
- Note that we use QImode instead of BImode for MODE_INT, since
- otherwise the middle end will try to use it for bitfields in
- structures and the like, which we do not want. Only the target
- md file should generate BImode widgets. */
-
-const enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS] = {
- /* MODE_RANDOM */ VOIDmode,
- /* MODE_INT */ QImode,
- /* MODE_FLOAT */ QFmode,
- /* MODE_PARTIAL_INT */ PQImode,
- /* MODE_CC */ CCmode,
- /* MODE_COMPLEX_INT */ CQImode,
- /* MODE_COMPLEX_FLOAT */ QCmode,
- /* MODE_VECTOR_INT */ V1DImode,
- /* MODE_VECTOR_FLOAT */ V2SFmode
-};
-
-
/* Indexed by rtx code, gives a sequence of operand-types for
rtx's of that code. The sequence is a C string in which
each character describes one operand. */
#undef DEF_RTL_EXPR
};
+/* Indexed by rtx code, gives the size of the rtx in bytes. */
+
+const unsigned char rtx_size[NUM_RTX_CODE] = {
+#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) \
+ ((ENUM) == CONST_INT || (ENUM) == CONST_DOUBLE \
+ ? RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (HOST_WIDE_INT) \
+ : RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (rtunion)),
+
+#include "rtl.def"
+#undef DEF_RTL_EXPR
+};
+
/* Names for kinds of NOTEs and REG_NOTEs. */
const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS] =
"NOTE_INSN_EH_REGION_BEG", "NOTE_INSN_EH_REGION_END",
"NOTE_INSN_REPEATED_LINE_NUMBER",
"NOTE_INSN_BASIC_BLOCK", "NOTE_INSN_EXPECTED_VALUE",
- "NOTE_INSN_PREDICTION"
+ "NOTE_INSN_PREDICTION", "NOTE_INSN_VAR_LOCATION"
};
const char * const reg_note_name[] =
"REG_VTABLE_REF"
};
+
+#ifdef GATHER_STATISTICS
+static int rtx_alloc_counts[(int) LAST_AND_UNUSED_RTX_CODE];
+static int rtx_alloc_sizes[(int) LAST_AND_UNUSED_RTX_CODE];
+static int rtvec_alloc_counts;
+static int rtvec_alloc_sizes;
+#endif
+
\f
/* Allocate an rtx vector of N elements.
Store the length, and initialize all elements to zero. */
rtvec rt;
rt = ggc_alloc_rtvec (n);
- /* clear out the vector */
+ /* Clear out the vector. */
memset (&rt->elem[0], 0, n * sizeof (rtx));
PUT_NUM_ELEM (rt, n);
+
+#ifdef GATHER_STATISTICS
+ rtvec_alloc_counts++;
+ rtvec_alloc_sizes += n * sizeof (rtx);
+#endif
+
return rt;
}
rtx_alloc (RTX_CODE code)
{
rtx rt;
- int n = GET_RTX_LENGTH (code);
- rt = ggc_alloc_rtx (n);
+ rt = ggc_alloc_rtx (code);
/* We want to clear everything up to the FLD array. Normally, this
is one int, but we don't want to assume that and it isn't very
portable anyway; this is. */
- memset (rt, 0, sizeof (struct rtx_def) - sizeof (rtunion));
+ memset (rt, 0, RTX_HDR_SIZE);
PUT_CODE (rt, code);
+
+#ifdef GATHER_STATISTICS
+ rtx_alloc_counts[code]++;
+ rtx_alloc_sizes[code] += RTX_SIZE (code);
+#endif
+
return rt;
}
/* SCRATCH must be shared because they represent distinct values. */
case ADDRESSOF:
return orig;
+ case CLOBBER:
+ if (REG_P (XEXP (orig, 0)) && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER)
+ return orig;
+ break;
case CONST:
/* CONST can be shared if it contains a SYMBOL_REF. If it contains
all fields need copying, and then clear the fields that should
not be copied. That is the sensible default behavior, and forces
us to explicitly document why we are *not* copying a flag. */
- memcpy (copy, orig, sizeof (struct rtx_def) - sizeof (rtunion));
+ memcpy (copy, orig, RTX_HDR_SIZE);
/* We do not copy the USED flag, which is used as a mark bit during
walks over the RTL. */
for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
{
- copy->fld[i] = orig->fld[i];
+ copy->u.fld[i] = orig->u.fld[i];
switch (*format_ptr++)
{
case 'e':
rtx
shallow_copy_rtx (rtx orig)
{
- RTX_CODE code = GET_CODE (orig);
- size_t n = GET_RTX_LENGTH (code);
- rtx copy = ggc_alloc_rtx (n);
-
- memcpy (copy, orig,
- sizeof (struct rtx_def) + sizeof (rtunion) * (n - 1));
+ rtx copy;
+ copy = ggc_alloc_rtx (GET_CODE (orig));
+ memcpy (copy, orig, RTX_SIZE (GET_CODE (orig)));
return copy;
}
\f
}
/* Compare the elements. If any pair of corresponding elements
- fail to match, return 0 for the whole things. */
+ fail to match, return 0 for the whole thing. */
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
}
return 1;
}
+
+void dump_rtx_statistics (void)
+{
+#ifdef GATHER_STATISTICS
+ int i;
+ int total_counts = 0;
+ int total_sizes = 0;
+ fprintf (stderr, "\nRTX Kind Count Bytes\n");
+ fprintf (stderr, "---------------------------------------\n");
+ for (i = 0; i < LAST_AND_UNUSED_RTX_CODE; i++)
+ if (rtx_alloc_counts[i])
+ {
+ fprintf (stderr, "%-20s %7d %10d\n", GET_RTX_NAME (i),
+ rtx_alloc_counts[i], rtx_alloc_sizes[i]);
+ total_counts += rtx_alloc_counts[i];
+ total_sizes += rtx_alloc_sizes[i];
+ }
+ if (rtvec_alloc_counts)
+ {
+ fprintf (stderr, "%-20s %7d %10d\n", "rtvec",
+ rtvec_alloc_counts, rtvec_alloc_sizes);
+ total_counts += rtvec_alloc_counts;
+ total_sizes += rtvec_alloc_sizes;
+ }
+ fprintf (stderr, "---------------------------------------\n");
+ fprintf (stderr, "%-20s %7d %10d\n",
+ "Total", total_counts, total_sizes);
+ fprintf (stderr, "---------------------------------------\n");
+#endif
+}
\f
#if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007)
void