summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/rtl.c
diff options
context:
space:
mode:
authorkan <kan@FreeBSD.org>2007-05-19 01:19:51 +0000
committerkan <kan@FreeBSD.org>2007-05-19 01:19:51 +0000
commit1f9ea4d0a40cca64d60cf4dab152349da7b9dddf (patch)
tree0cb530c9c38af219e6dda2994c078b6b2b9ad853 /contrib/gcc/rtl.c
parent4895159b2b4f648051c1f139faa7b6dc50c2bfcb (diff)
downloadFreeBSD-src-1f9ea4d0a40cca64d60cf4dab152349da7b9dddf.zip
FreeBSD-src-1f9ea4d0a40cca64d60cf4dab152349da7b9dddf.tar.gz
GCC 4.2.0 release.
Diffstat (limited to 'contrib/gcc/rtl.c')
-rw-r--r--contrib/gcc/rtl.c224
1 files changed, 127 insertions, 97 deletions
diff --git a/contrib/gcc/rtl.c b/contrib/gcc/rtl.c
index 313e2cb..71bd3ae 100644
--- a/contrib/gcc/rtl.c
+++ b/contrib/gcc/rtl.c
@@ -1,6 +1,6 @@
/* RTL utility routines.
Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003 Free Software Foundation, Inc.
+ 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GCC.
@@ -16,17 +16,28 @@ 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. */
-
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
+
+/* This file is compiled twice: once for the generator programs
+ once for the compiler. */
+#ifdef GENERATOR_FILE
+#include "bconfig.h"
+#else
#include "config.h"
+#endif
+
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "real.h"
#include "ggc.h"
-#include "errors.h"
+#ifdef GENERATOR_FILE
+# include "errors.h"
+#else
+# include "toplev.h"
+#endif
/* Indexed by rtx code, gives number of operands for an rtx with that code.
@@ -90,7 +101,7 @@ const char * const rtx_format[NUM_RTX_CODE] = {
/* Indexed by rtx code, gives a character representing the "class" of
that rtx code. See rtl.def for documentation on the defined classes. */
-const char rtx_class[NUM_RTX_CODE] = {
+const enum rtx_class rtx_class[NUM_RTX_CODE] = {
#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) CLASS,
#include "rtl.def" /* rtl expressions are defined here */
#undef DEF_RTL_EXPR
@@ -98,7 +109,7 @@ const char rtx_class[NUM_RTX_CODE] = {
/* Indexed by rtx code, gives the size of the rtx in bytes. */
-const unsigned char rtx_size[NUM_RTX_CODE] = {
+const unsigned char rtx_code_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) \
@@ -108,37 +119,27 @@ const unsigned char rtx_size[NUM_RTX_CODE] = {
#undef DEF_RTL_EXPR
};
+/* Make sure all NOTE_INSN_* values are negative. */
+extern char NOTE_INSN_MAX_isnt_negative_adjust_NOTE_INSN_BIAS
+[NOTE_INSN_MAX < 0 ? 1 : -1];
+
/* Names for kinds of NOTEs and REG_NOTEs. */
const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS] =
{
- "", "NOTE_INSN_DELETED",
- "NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END",
- "NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END",
- "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
- "NOTE_INSN_LOOP_END_TOP_COND", "NOTE_INSN_FUNCTION_END",
- "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
- "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG",
- "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"
+ "",
+#define DEF_INSN_NOTE(NAME) #NAME,
+#include "insn-notes.def"
+#undef DEF_INSN_NOTE
};
-const char * const reg_note_name[] =
+const char * const reg_note_name[REG_NOTE_MAX] =
{
- "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_EQUAL",
- "REG_RETVAL", "REG_LIBCALL", "REG_NONNEG",
- "REG_NO_CONFLICT", "REG_UNUSED", "REG_CC_SETTER", "REG_CC_USER",
- "REG_LABEL", "REG_DEP_ANTI", "REG_DEP_OUTPUT", "REG_BR_PROB",
- "REG_VALUE_PROFILE", "REG_NOALIAS", "REG_SAVE_AREA", "REG_BR_PRED",
- "REG_FRAME_RELATED_EXPR", "REG_EH_CONTEXT", "REG_EH_REGION",
- "REG_SAVE_NOTE", "REG_MAYBE_DEAD", "REG_NORETURN",
- "REG_NON_LOCAL_GOTO", "REG_SETJMP", "REG_ALWAYS_RETURN",
- "REG_VTABLE_REF"
+#define DEF_REG_NOTE(NAME) #NAME,
+#include "reg-notes.def"
+#undef DEF_REG_NOTE
};
-
#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];
@@ -156,7 +157,7 @@ rtvec_alloc (int n)
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);
@@ -169,15 +170,25 @@ rtvec_alloc (int n)
return rt;
}
+/* Return the number of bytes occupied by rtx value X. */
+
+unsigned int
+rtx_size (rtx x)
+{
+ if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_HAS_BLOCK_INFO_P (x))
+ return RTX_HDR_SIZE + sizeof (struct block_symbol);
+ return RTX_CODE_SIZE (GET_CODE (x));
+}
+
/* Allocate an rtx of code CODE. The CODE is stored in the rtx;
all the rest is initialized to zero. */
rtx
-rtx_alloc (RTX_CODE code)
+rtx_alloc_stat (RTX_CODE code MEM_STAT_DECL)
{
rtx rt;
- rt = ggc_alloc_rtx (code);
+ rt = (rtx) ggc_alloc_zone_pass_stat (RTX_CODE_SIZE (code), &rtl_zone);
/* 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
@@ -188,7 +199,7 @@ rtx_alloc (RTX_CODE code)
#ifdef GATHER_STATISTICS
rtx_alloc_counts[code]++;
- rtx_alloc_sizes[code] += RTX_SIZE (code);
+ rtx_alloc_sizes[code] += RTX_CODE_SIZE (code);
#endif
return rt;
@@ -212,7 +223,6 @@ copy_rtx (rtx orig)
switch (code)
{
case REG:
- case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
@@ -222,8 +232,11 @@ copy_rtx (rtx orig)
case CC0:
case SCRATCH:
/* 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
@@ -243,20 +256,18 @@ copy_rtx (rtx orig)
break;
}
- copy = rtx_alloc (code);
-
- /* Copy the various flags, and other information. We assume that
- all fields need copying, and then clear the fields that should
+ /* Copy the various flags, fields, and other information. We assume
+ that 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, RTX_HDR_SIZE);
+ copy = shallow_copy_rtx (orig);
/* We do not copy the USED flag, which is used as a mark bit during
walks over the RTL. */
RTX_FLAG (copy, used) = 0;
/* We do not copy FRAME_RELATED for INSNs. */
- if (GET_RTX_CLASS (code) == 'i')
+ if (INSN_P (orig))
RTX_FLAG (copy, frame_related) = 0;
RTX_FLAG (copy, jump) = RTX_FLAG (orig, jump);
RTX_FLAG (copy, call) = RTX_FLAG (orig, call);
@@ -264,61 +275,61 @@ copy_rtx (rtx orig)
format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
- {
- copy->u.fld[i] = orig->u.fld[i];
- switch (*format_ptr++)
- {
- case 'e':
- if (XEXP (orig, i) != NULL)
- XEXP (copy, i) = copy_rtx (XEXP (orig, i));
- break;
-
- case 'E':
- case 'V':
- if (XVEC (orig, i) != NULL)
- {
- XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
- for (j = 0; j < XVECLEN (copy, i); j++)
- XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
- }
- break;
-
- case 't':
- case 'w':
- case 'i':
- case 's':
- case 'S':
- case 'T':
- case 'u':
- case 'B':
- case '0':
- /* These are left unchanged. */
- break;
-
- default:
- abort ();
- }
- }
+ switch (*format_ptr++)
+ {
+ case 'e':
+ if (XEXP (orig, i) != NULL)
+ XEXP (copy, i) = copy_rtx (XEXP (orig, i));
+ break;
+
+ case 'E':
+ case 'V':
+ if (XVEC (orig, i) != NULL)
+ {
+ XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
+ for (j = 0; j < XVECLEN (copy, i); j++)
+ XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
+ }
+ break;
+
+ case 't':
+ case 'w':
+ case 'i':
+ case 's':
+ case 'S':
+ case 'T':
+ case 'u':
+ case 'B':
+ case '0':
+ /* These are left unchanged. */
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
return copy;
}
/* Create a new copy of an rtx. Only copy just one level. */
rtx
-shallow_copy_rtx (rtx orig)
+shallow_copy_rtx_stat (rtx orig MEM_STAT_DECL)
{
+ unsigned int size;
rtx copy;
- copy = ggc_alloc_rtx (GET_CODE (orig));
- memcpy (copy, orig, RTX_SIZE (GET_CODE (orig)));
+ size = rtx_size (orig);
+ copy = (rtx) ggc_alloc_zone_pass_stat (size, &rtl_zone);
+ memcpy (copy, orig, size);
return copy;
}
-/* This is 1 until after the rtl generation pass. */
-int rtx_equal_function_value_matters;
-
/* Nonzero when we are generating CONCATs. */
int generating_concat_p;
+
+/* Nonzero when we are expanding trees to RTL. */
+int currently_expanding_to_rtl;
+
/* Return 1 if X and Y are identical-looking rtx's.
This is the Lisp function EQUAL for rtx arguments. */
@@ -351,14 +362,7 @@ rtx_equal_p (rtx x, rtx y)
switch (code)
{
case REG:
- /* Until rtl generation is complete, don't consider a reference
- to the return register of the current function the same as
- the return from a called function. This eases the job of
- function integration. Once the distinction is no longer
- needed, they can be considered equivalent. */
- return (REGNO (x) == REGNO (y)
- && (! rtx_equal_function_value_matters
- || REG_FUNCTION_VALUE_P (x) == REG_FUNCTION_VALUE_P (y)));
+ return (REGNO (x) == REGNO (y));
case LABEL_REF:
return XEXP (x, 0) == XEXP (y, 0);
@@ -369,7 +373,6 @@ rtx_equal_p (rtx x, rtx y)
case SCRATCH:
case CONST_DOUBLE:
case CONST_INT:
- case CONST_VECTOR:
return 0;
default:
@@ -432,13 +435,14 @@ rtx_equal_p (rtx x, rtx y)
contain anything but integers and other rtx's,
except for within LABEL_REFs and SYMBOL_REFs. */
default:
- abort ();
+ gcc_unreachable ();
}
}
return 1;
}
-void dump_rtx_statistics (void)
+void
+dump_rtx_statistics (void)
{
#ifdef GATHER_STATISTICS
int i;
@@ -474,7 +478,7 @@ rtl_check_failed_bounds (rtx r, int n, const char *file, int line,
const char *func)
{
internal_error
- ("RTL check: access of elt %d of `%s' with last elt %d in %s, at %s:%d",
+ ("RTL check: access of elt %d of '%s' with last elt %d in %s, at %s:%d",
n, GET_RTX_NAME (GET_CODE (r)), GET_RTX_LENGTH (GET_CODE (r)) - 1,
func, trim_filename (file), line);
}
@@ -503,7 +507,7 @@ void
rtl_check_failed_code1 (rtx r, enum rtx_code code, const char *file,
int line, const char *func)
{
- internal_error ("RTL check: expected code `%s', have `%s' in %s, at %s:%d",
+ internal_error ("RTL check: expected code '%s', have '%s' in %s, at %s:%d",
GET_RTX_NAME (code), GET_RTX_NAME (GET_CODE (r)), func,
trim_filename (file), line);
}
@@ -513,11 +517,37 @@ rtl_check_failed_code2 (rtx r, enum rtx_code code1, enum rtx_code code2,
const char *file, int line, const char *func)
{
internal_error
- ("RTL check: expected code `%s' or `%s', have `%s' in %s, at %s:%d",
+ ("RTL check: expected code '%s' or '%s', have '%s' in %s, at %s:%d",
GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (GET_CODE (r)),
func, trim_filename (file), line);
}
+void
+rtl_check_failed_code_mode (rtx r, enum rtx_code code, enum machine_mode mode,
+ bool not_mode, const char *file, int line,
+ const char *func)
+{
+ internal_error ((not_mode
+ ? ("RTL check: expected code '%s' and not mode '%s', "
+ "have code '%s' and mode '%s' in %s, at %s:%d")
+ : ("RTL check: expected code '%s' and mode '%s', "
+ "have code '%s' and mode '%s' in %s, at %s:%d")),
+ GET_RTX_NAME (code), GET_MODE_NAME (mode),
+ GET_RTX_NAME (GET_CODE (r)), GET_MODE_NAME (GET_MODE (r)),
+ func, trim_filename (file), line);
+}
+
+/* Report that line LINE of FILE tried to access the block symbol fields
+ of a non-block symbol. FUNC is the function that contains the line. */
+
+void
+rtl_check_failed_block_symbol (const char *file, int line, const char *func)
+{
+ internal_error
+ ("RTL check: attempt to treat non-block symbol as a block symbol "
+ "in %s, at %s:%d", func, trim_filename (file), line);
+}
+
/* XXX Maybe print the vector? */
void
rtvec_check_failed_bounds (rtvec r, int n, const char *file, int line,
@@ -535,7 +565,7 @@ rtl_check_failed_flag (const char *name, rtx r, const char *file,
int line, const char *func)
{
internal_error
- ("RTL flag check: %s used with unexpected rtx code `%s' in %s, at %s:%d",
+ ("RTL flag check: %s used with unexpected rtx code '%s' in %s, at %s:%d",
name, GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line);
}
#endif /* ENABLE_RTL_FLAG_CHECKING */
OpenPOWER on IntegriCloud