rtl.def (NOTE): Change format to "iuu0n".

1999-08-19 14:44 -0700  Zack Weinberg  <zack@bitmover.com>

	* rtl.def (NOTE): Change format to "iuu0n".
	(ADDR_DIFF_VEC): Change format to "eEee0".
	(ADDRESSOF): Change format to "eit".

	* rtl.h (rtvec): Make "elem" an array of rtx, not rtunion.
	(RTVEC_ELT): Change to match.
	(XVECEXP): Use XVEC and RTVEC_ELT.
	(INSN_UID, INSN_CODE, CODE_LABEL_NUMBER, NOTE_LINE_NUMBER,
	ADDRESSOF_REGNO, REGNO, SUBREG_WORD): Use XINT.
	(PREV_INSN, NEXT_INSN, PATTERN, REG_NOTES,
	CALL_INSN_FUNCTION_USAGE, SUBREG_REG, SET_SRC, SET_DEST,
	TRAP_CONDITION, TRAP_CODE): Use XEXP.
	(INTVAL): Use XWINT.
	(ADDRESSOF_DECL): Use XTREE.
	(SET_ADDRESSOF_DECL): Delete.
	(NOTE_DECL_NAME, NOTE_DECL_CODE, NOTE_DECL_RTL,
	NOTE_DECL_IDENTIFIER, NOTE_DECL_TYPE): Kill.  These have been
	ifdefed out since 2.6 at least.
	(gen_rtvec_vv): Delete prototype.

	* rtl.h (rtvec_alloc): rt->elem is now an array of rtx,
	not rtunion.
	(copy_most_rtx): Handle 't' format letter.
	* emit-rtl.c (gen_rtvec_v): rt_val->elem is an array of rtx.
	(gen_rtvec_vv): Delete function.  All callers changed to use
	gen_rtvec_v instead.
	* print-rtl.c (print_rtx): Move special casing of NOTEs to
	the '0' format letter.

	* function.c (gen_mem_addressof): Don't use
	SET_ADDRESSOF_DECL; provide `decl' to gen_rtx_ADDRESSOF
	instead.
	* integrate.c (copy_rtx_and_substitute): Likewise.
	Copy 't' slots with XTREE.
	(subst_constants): Treat 't' slots like '[swi]' slots.
	* cse.c (canon_hash, exp_equiv_p): Treat 't' slots like	'0' slots.
	* jump.c (rtx_equal_for_thread_p): Likewise.
	* rtlanal.c (rtx_equal_p): Likewise.
	* stmt.c (expand_end_case): gen_rtx_ADDR_DIFF_VEC now takes
	only four arguments.
	* gengenrtl.c (type_from_format): Provide correct types for
	'b' and 't' slots.


	* tree.h [ENABLE_CHECKING] (TREE_CHECK, TREE_CLASS_CHECK):
	If a recent gcc is in use (always in stage2 and beyond), use
	statement expressions, so we don't make a function call unless
	the check fails.  Evaluate arguments exactly once.
	(CHAIN_CHECK, DO_CHECK, DO_CHECK1, TREE_CHECK1,
	TREE_CLASS_CHECK1, TYPE_CHECK1, DECL_CHECK1, CST_CHECK1):
	Delete.
	(CST_OR_CONSTRUCTOR_CHECK, EXPR_CHECK): Redefine such that
	they evaluate their arguments exactly once, irrespective of
	the compiler in use.

	* tree.c [ENABLE_CHECKING]: Define whichever set of functions
	is used by the currently-enabled check macros.  This is:
	(tree_check_failed, tree_class_check_failed): For gcc.
	(tree_check, tree_class_check, cst_or_constructor_check,
	expr_check): For other compilers.

	* gencheck.c: Do not define any *_CHECK1 macros.

From-SVN: r28769
This commit is contained in:
Zack Weinberg 1999-08-19 22:33:38 +00:00 committed by Zack Weinberg
parent 02af3af651
commit 8f985ec4c7
17 changed files with 327 additions and 206 deletions

View File

@ -1,3 +1,68 @@
1999-08-19 14:44 -0700 Zack Weinberg <zack@bitmover.com>
* rtl.def (NOTE): Change format to "iuu0n".
(ADDR_DIFF_VEC): Change format to "eEee0".
(ADDRESSOF): Change format to "eit".
* rtl.h (rtvec): Make "elem" an array of rtx, not rtunion.
(RTVEC_ELT): Change to match.
(XVECEXP): Use XVEC and RTVEC_ELT.
(INSN_UID, INSN_CODE, CODE_LABEL_NUMBER, NOTE_LINE_NUMBER,
ADDRESSOF_REGNO, REGNO, SUBREG_WORD): Use XINT.
(PREV_INSN, NEXT_INSN, PATTERN, REG_NOTES,
CALL_INSN_FUNCTION_USAGE, SUBREG_REG, SET_SRC, SET_DEST,
TRAP_CONDITION, TRAP_CODE): Use XEXP.
(INTVAL): Use XWINT.
(ADDRESSOF_DECL): Use XTREE.
(SET_ADDRESSOF_DECL): Delete.
(NOTE_DECL_NAME, NOTE_DECL_CODE, NOTE_DECL_RTL,
NOTE_DECL_IDENTIFIER, NOTE_DECL_TYPE): Kill. These have been
ifdefed out since 2.6 at least.
(gen_rtvec_vv): Delete prototype.
* rtl.h (rtvec_alloc): rt->elem is now an array of rtx,
not rtunion.
(copy_most_rtx): Handle 't' format letter.
* emit-rtl.c (gen_rtvec_v): rt_val->elem is an array of rtx.
(gen_rtvec_vv): Delete function. All callers changed to use
gen_rtvec_v instead.
* print-rtl.c (print_rtx): Move special casing of NOTEs to
the '0' format letter.
* function.c (gen_mem_addressof): Don't use
SET_ADDRESSOF_DECL; provide `decl' to gen_rtx_ADDRESSOF
instead.
* integrate.c (copy_rtx_and_substitute): Likewise.
Copy 't' slots with XTREE.
(subst_constants): Treat 't' slots like '[swi]' slots.
* cse.c (canon_hash, exp_equiv_p): Treat 't' slots like '0' slots.
* jump.c (rtx_equal_for_thread_p): Likewise.
* rtlanal.c (rtx_equal_p): Likewise.
* stmt.c (expand_end_case): gen_rtx_ADDR_DIFF_VEC now takes
only four arguments.
* gengenrtl.c (type_from_format): Provide correct types for
'b' and 't' slots.
* tree.h [ENABLE_CHECKING] (TREE_CHECK, TREE_CLASS_CHECK):
If a recent gcc is in use (always in stage2 and beyond), use
statement expressions, so we don't make a function call unless
the check fails. Evaluate arguments exactly once.
(CHAIN_CHECK, DO_CHECK, DO_CHECK1, TREE_CHECK1,
TREE_CLASS_CHECK1, TYPE_CHECK1, DECL_CHECK1, CST_CHECK1):
Delete.
(CST_OR_CONSTRUCTOR_CHECK, EXPR_CHECK): Redefine such that
they evaluate their arguments exactly once, irrespective of
the compiler in use.
* tree.c [ENABLE_CHECKING]: Define whichever set of functions
is used by the currently-enabled check macros. This is:
(tree_check_failed, tree_class_check_failed): For gcc.
(tree_check, tree_class_check, cst_or_constructor_check,
expr_check): For other compilers.
* gencheck.c: Do not define any *_CHECK1 macros.
Thu Aug 19 14:42:38 1999 Mike Stump <mrs@wrs.com>
Mark Mitchell <mark@codesourcery.com>

View File

@ -2261,7 +2261,7 @@ canon_hash (x, mode)
register unsigned tem = XINT (x, i);
hash += tem;
}
else if (fmt[i] == '0')
else if (fmt[i] == '0' || fmt[i] == 't')
/* unused */;
else
abort ();
@ -2444,6 +2444,7 @@ exp_equiv_p (x, y, validate, equal_values)
break;
case '0':
case 't':
break;
default:

View File

@ -455,29 +455,11 @@ gen_rtvec_v (n, argp)
rt_val = rtvec_alloc (n); /* Allocate an rtvec... */
for (i = 0; i < n; i++)
rt_val->elem[i].rtx = *argp++;
rt_val->elem[i] = *argp++;
return rt_val;
}
rtvec
gen_rtvec_vv (n, argp)
int n;
rtunion *argp;
{
register int i;
register rtvec rt_val;
if (n == 0)
return NULL_RTVEC; /* Don't allocate an empty rtvec... */
rt_val = rtvec_alloc (n); /* Allocate an rtvec... */
for (i = 0; i < n; i++)
rt_val->elem[i].rtx = (argp++)->rtx;
return rt_val;
}
/* Generate a REG rtx for a new pseudo register of mode MODE.
This pseudo is assigned the next sequential register number. */
@ -1761,7 +1743,7 @@ copy_rtx_if_shared (orig)
int len = XVECLEN (x, i);
if (copied && len > 0)
XVEC (x, i) = gen_rtvec_vv (len, XVEC (x, i)->elem);
XVEC (x, i) = gen_rtvec_v (len, XVEC (x, i)->elem);
for (j = 0; j < len; j++)
XVECEXP (x, i, j) = copy_rtx_if_shared (XVECEXP (x, i, j));
}

View File

@ -2630,8 +2630,8 @@ gen_mem_addressof (reg, decl)
tree decl;
{
tree type = TREE_TYPE (decl);
rtx r = gen_rtx_ADDRESSOF (Pmode, gen_reg_rtx (GET_MODE (reg)), REGNO (reg));
SET_ADDRESSOF_DECL (r, decl);
rtx r = gen_rtx_ADDRESSOF (Pmode, gen_reg_rtx (GET_MODE (reg)),
REGNO (reg), decl);
/* If the original REG was a user-variable, then so is the REG whose
address is being taken. */
REG_USERVAR_P (XEXP (r, 0)) = REG_USERVAR_P (reg);

View File

@ -55,8 +55,6 @@ int main (argc, argv)
{
printf ("#define %s_CHECK(t)\tTREE_CHECK (t, %s)\n",
tree_codes[i], tree_codes[i]);
printf ("#define %s_CHECK1(t)\tTREE_CHECK1 (t, %s)\n",
tree_codes[i], tree_codes[i]);
}
return 0;

View File

@ -72,16 +72,10 @@ type_from_format (c)
return "rtx";
case 'E':
return "rtvec";
/* ?!? These should be bitmap and tree respectively, but those types
are not available in many of the files which include the output
of gengenrtl.
These are only used in prototypes, so I think we can assume that
void * is useable. */
case 'b':
return "void *";
return "struct bitmap_head_def *"; /* bitmap - typedef not available */
case 't':
return "void *";
return "union tree_node *"; /* tree - typedef not available */
default:
abort ();
}

View File

@ -1233,7 +1233,7 @@ copy_for_inline (orig)
{
register int j;
XVEC (x, i) = gen_rtvec_vv (XVECLEN (x, i), XVEC (x, i)->elem);
XVEC (x, i) = gen_rtvec_v (XVECLEN (x, i), XVEC (x, i)->elem);
for (j = 0; j < XVECLEN (x, i); j++)
XVECEXP (x, i, j)
= copy_for_inline (XVECEXP (x, i, j));
@ -2428,8 +2428,8 @@ copy_rtx_and_substitute (orig, map)
case ADDRESSOF:
copy = gen_rtx_ADDRESSOF (mode,
copy_rtx_and_substitute (XEXP (orig, 0), map), 0);
SET_ADDRESSOF_DECL (copy, ADDRESSOF_DECL (orig));
copy_rtx_and_substitute (XEXP (orig, 0), map),
0, ADDRESSOF_DECL(orig));
regno = ADDRESSOF_REGNO (orig);
if (map->reg_map[regno])
regno = REGNO (map->reg_map[regno]);
@ -2730,6 +2730,10 @@ copy_rtx_and_substitute (orig, map)
XSTR (copy, i) = XSTR (orig, i);
break;
case 't':
XTREE (copy, i) = XTREE (orig, i);
break;
default:
abort ();
}
@ -3002,6 +3006,7 @@ subst_constants (loc, insn, map)
case 'i':
case 's':
case 'w':
case 't':
break;
case 'E':

View File

@ -5253,6 +5253,7 @@ rtx_equal_for_thread_p (x, y, yinsn)
break;
case '0':
case 't':
break;
/* It is believed that rtx's at this level will never

View File

@ -146,38 +146,6 @@ print_rtx (in_rtx)
{
case 'S':
case 's':
if (i == 3 && GET_CODE (in_rtx) == NOTE
&& (NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_EH_REGION_BEG
|| NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_EH_REGION_END
|| NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_BLOCK_BEG
|| NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_BLOCK_END))
{
fprintf (outfile, " %d", NOTE_BLOCK_NUMBER (in_rtx));
sawclose = 1;
break;
}
if (i == 3 && GET_CODE (in_rtx) == NOTE
&& (NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_RANGE_START
|| NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_RANGE_END
|| NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_LIVE))
{
indent += 2;
if (!sawclose)
fprintf (outfile, " ");
print_rtx (NOTE_RANGE_INFO (in_rtx));
indent -= 2;
break;
}
if (i == 3 && GET_CODE (in_rtx) == NOTE
&& NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_BASIC_BLOCK)
{
basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
fprintf (outfile, " [bb %d]", bb->index);
break;
}
if (XSTR (in_rtx, i) == 0)
fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile);
else
@ -186,8 +154,47 @@ print_rtx (in_rtx)
sawclose = 1;
break;
/* 0 indicates a field for internal use that should not be printed. */
/* 0 indicates a field for internal use that should not be printed.
An exception is the third field of a NOTE, where it indicates
that the field has several different valid contents. */
case '0':
if (i == 3 && GET_CODE (in_rtx) == NOTE)
{
if (NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_EH_REGION_BEG
|| NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_EH_REGION_END
|| NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_BLOCK_BEG
|| NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_BLOCK_END)
{
fprintf (outfile, " %d", NOTE_BLOCK_NUMBER (in_rtx));
sawclose = 1;
}
else if (NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_RANGE_START
|| NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_RANGE_END
|| NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_LIVE)
{
indent += 2;
if (!sawclose)
fprintf (outfile, " ");
print_rtx (NOTE_RANGE_INFO (in_rtx));
indent -= 2;
}
else if (NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_BASIC_BLOCK)
{
basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
fprintf (outfile, " [bb %d]", bb->index);
}
else
{
/* Can't use XSTR because of type checking. */
char *str = in_rtx->fld[i].rtstr;
if (str == 0)
fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile);
else
fprintf (outfile,
dump_for_graph ? " (\\\"%s\\\")" : " (\"%s\")",
str);
}
}
break;
case 'e':

View File

@ -3225,8 +3225,8 @@ eliminate_regs (x, mem_mode, insn)
new = eliminate_regs (XVECEXP (x, i, j), mem_mode, insn);
if (new != XVECEXP (x, i, j) && ! copied_vec)
{
rtvec new_v = gen_rtvec_vv (XVECLEN (x, i),
XVEC (x, i)->elem);
rtvec new_v = gen_rtvec_v (XVECLEN (x, i),
XVEC (x, i)->elem);
if (! copied)
{
rtx new_x = rtx_alloc (code);

View File

@ -212,13 +212,13 @@ rtvec_alloc (n)
rt = (rtvec) obstack_alloc (rtl_obstack,
sizeof (struct rtvec_def)
+ (( n - 1) * sizeof (rtunion)));
+ (( n - 1) * sizeof (rtx)));
/* clear out the vector */
PUT_NUM_ELEM (rt, n);
for (i = 0; i < n; i++)
rt->elem[i].rtwint = 0;
rt->elem[i] = 0;
return rt;
}
@ -477,6 +477,10 @@ copy_most_rtx (orig, may_share)
XINT (copy, i) = XINT (orig, i);
break;
case 't':
XTREE (copy, i) = XTREE (orig, i);
break;
case 's':
case 'S':
XSTR (copy, i) = XSTR (orig, i);

View File

@ -390,7 +390,7 @@ DEF_RTL_EXPR(CODE_LABEL, "code_label", "iuuis00", 'x')
are really changed to NOTEs with a number of -1.
-2 means beginning of a name binding contour; output N_LBRAC.
-3 means end of a contour; output N_RBRAC. */
DEF_RTL_EXPR(NOTE, "note", "iuusn", 'x')
DEF_RTL_EXPR(NOTE, "note", "iuu0n", 'x')
/* ----------------------------------------------------------------------
Top level constituents of INSN, JUMP_INSN and CALL_INSN.
@ -462,7 +462,7 @@ DEF_RTL_EXPR(ADDR_VEC, "addr_vec", "E", 'x')
CASE_VECTOR_SHORTEN_MODE is defined, and only in an optimizing
compilations. */
DEF_RTL_EXPR(ADDR_DIFF_VEC, "addr_diff_vec", "eEeei", 'x')
DEF_RTL_EXPR(ADDR_DIFF_VEC, "addr_diff_vec", "eEee0", 'x')
/* ----------------------------------------------------------------------
At the top level of an instruction (perhaps under PARALLEL).
@ -610,7 +610,7 @@ DEF_RTL_EXPR(CC0, "cc0", "", 'o')
3rd operand: the decl for the object in the register, for
put_reg_in_stack. */
DEF_RTL_EXPR(ADDRESSOF, "addressof", "ei0", 'o')
DEF_RTL_EXPR(ADDRESSOF, "addressof", "eit", 'o')
/* =====================================================================
A QUEUED expression really points to a member of the queue of instructions

View File

@ -200,7 +200,7 @@ typedef struct rtx_def
typedef struct rtvec_def{
int num_elem; /* number of elements */
rtunion elem[1];
struct rtx_def *elem[1];
} *rtvec;
#define NULL_RTVEC (rtvec) 0
@ -208,8 +208,6 @@ typedef struct rtvec_def{
#define GET_NUM_ELEM(RTVEC) ((RTVEC)->num_elem)
#define PUT_NUM_ELEM(RTVEC, NUM) ((RTVEC)->num_elem = (NUM))
#define RTVEC_ELT(RTVEC, I) ((RTVEC)->elem[(I)].rtx)
/* 1 if X is a REG. */
#define REG_P(X) (GET_CODE (X) == REG)
@ -224,40 +222,44 @@ typedef struct rtvec_def{
/* General accessor macros for accessing the fields of an rtx. */
#define XEXP(RTX, N) ((RTX)->fld[N].rtx)
#define XINT(RTX, N) ((RTX)->fld[N].rtint)
#define XWINT(RTX, N) ((RTX)->fld[N].rtwint)
#define XSTR(RTX, N) ((RTX)->fld[N].rtstr)
#define XVEC(RTX, N) ((RTX)->fld[N].rtvec)
#define XVECLEN(RTX, N) ((RTX)->fld[N].rtvec->num_elem)
#define XVECEXP(RTX,N,M)((RTX)->fld[N].rtvec->elem[M].rtx)
#define XBITMAP(RTX, N) ((RTX)->fld[N].rtbit)
#define XTREE(RTX, N) ((RTX)->fld[N].rttree)
#define XWINT(RTX, N) ((RTX)->fld[N].rtwint) /* w */
#define XINT(RTX, N) ((RTX)->fld[N].rtint) /* i,n */
#define XSTR(RTX, N) ((RTX)->fld[N].rtstr) /* s,S */
#define XEXP(RTX, N) ((RTX)->fld[N].rtx) /* e,u */
#define XVEC(RTX, N) ((RTX)->fld[N].rtvec) /* E,V */
#define XVECLEN(RTX, N) ((RTX)->fld[N].rtvec->num_elem) /* E,V */
#define XMODE(RTX, N) ((RTX)->fld[N].rttype) /* M */
#define XBITMAP(RTX, N) ((RTX)->fld[N].rtbit) /* b */
#define XTREE(RTX, N) ((RTX)->fld[N].rttree) /* t */
#define XBBDEF(RTX, N) ((RTX)->fld[N].bb) /* B */
#define RTVEC_ELT(RTVEC, I) ((RTVEC)->elem[I])
#define XVECEXP(RTX,N,M) RTVEC_ELT (XVEC (RTX, N), M)
/* ACCESS MACROS for particular fields of insns. */
/* Holds a unique number for each insn.
These are not necessarily sequentially increasing. */
#define INSN_UID(INSN) ((INSN)->fld[0].rtint)
#define INSN_UID(INSN) XINT(INSN, 0)
/* Chain insns together in sequence. */
#define PREV_INSN(INSN) ((INSN)->fld[1].rtx)
#define NEXT_INSN(INSN) ((INSN)->fld[2].rtx)
#define PREV_INSN(INSN) XEXP(INSN, 1)
#define NEXT_INSN(INSN) XEXP(INSN, 2)
/* The body of an insn. */
#define PATTERN(INSN) ((INSN)->fld[3].rtx)
#define PATTERN(INSN) XEXP(INSN, 3)
/* Code number of instruction, from when it was recognized.
-1 means this instruction has not been recognized yet. */
#define INSN_CODE(INSN) ((INSN)->fld[4].rtint)
#define INSN_CODE(INSN) XINT(INSN, 4)
/* Set up in flow.c; empty before then.
Holds a chain of INSN_LIST rtx's whose first operands point at
previous insns with direct data-flow connections to this one.
That means that those insns set variables whose next use is in this insn.
They are always in the same basic block as this insn. */
#define LOG_LINKS(INSN) ((INSN)->fld[5].rtx)
#define LOG_LINKS(INSN) XEXP(INSN, 5)
/* 1 if insn has been deleted. */
#define INSN_DELETED_P(INSN) ((INSN)->volatil)
@ -353,7 +355,7 @@ typedef struct rtvec_def{
non standard flow edges required for a rethrow. */
#define REG_NOTES(INSN) ((INSN)->fld[6].rtx)
#define REG_NOTES(INSN) XEXP(INSN, 6)
#define ADDR_DIFF_VEC_FLAGS(RTX) ((RTX)->fld[4].rt_addr_diff_vec_flags)
@ -386,12 +388,12 @@ extern char *reg_note_name[];
CLOBBER expressions document the registers explicitly clobbered
by this CALL_INSN.
Pseudo registers can not be mentioned in this list. */
#define CALL_INSN_FUNCTION_USAGE(INSN) ((INSN)->fld[7].rtx)
#define CALL_INSN_FUNCTION_USAGE(INSN) XEXP(INSN, 7)
/* The label-number of a code-label. The assembler label
is made from `L' and the label-number printed in decimal.
Label numbers are unique in a compilation. */
#define CODE_LABEL_NUMBER(INSN) ((INSN)->fld[3].rtint)
#define CODE_LABEL_NUMBER(INSN) XINT(INSN, 3)
#define LINE_NUMBER NOTE
@ -414,7 +416,7 @@ extern char *reg_note_name[];
/* In a NOTE that is a line number, this is the line number.
Other kinds of NOTEs are identified by negative numbers here. */
#define NOTE_LINE_NUMBER(INSN) ((INSN)->fld[4].rtint)
#define NOTE_LINE_NUMBER(INSN) XINT(INSN, 4)
/* Codes that appear in the NOTE_LINE_NUMBER field
for kinds of notes that are not line numbers.
@ -475,14 +477,6 @@ extern char *reg_note_name[];
/* Record the struct for the following basic block. */
#define NOTE_INSN_BASIC_BLOCK -20
#if 0 /* These are not used, and I don't know what they were for. --rms. */
#define NOTE_DECL_NAME(INSN) ((INSN)->fld[3].rtstr)
#define NOTE_DECL_CODE(INSN) ((INSN)->fld[4].rtint)
#define NOTE_DECL_RTL(INSN) ((INSN)->fld[5].rtx)
#define NOTE_DECL_IDENTIFIER(INSN) ((INSN)->fld[6].rtint)
#define NOTE_DECL_TYPE(INSN) ((INSN)->fld[7].rtint)
#endif /* 0 */
/* Names for NOTE insn's other than line numbers. */
extern char *note_insn_name[];
@ -490,18 +484,17 @@ extern char *note_insn_name[];
/* The name of a label, in case it corresponds to an explicit label
in the input source code. */
#define LABEL_NAME(LABEL) ((LABEL)->fld[4].rtstr)
#define LABEL_NAME(LABEL) XSTR(LABEL, 4)
/* In jump.c, each label contains a count of the number
of LABEL_REFs that point at it, so unused labels can be deleted. */
#define LABEL_NUSES(LABEL) ((LABEL)->fld[5].rtint)
/* The original regno this ADDRESSOF was built for. */
#define ADDRESSOF_REGNO(RTX) ((RTX)->fld[1].rtint)
#define ADDRESSOF_REGNO(RTX) XINT(RTX, 1)
/* The variable in the register we took the address of. */
#define ADDRESSOF_DECL(X) ((tree) XEXP ((X), 2))
#define SET_ADDRESSOF_DECL(X, T) (XEXP ((X), 2) = (rtx) (T))
#define ADDRESSOF_DECL(RTX) XTREE(RTX, 2)
/* In jump.c, each JUMP_INSN can point to a label that it can jump to,
so that if the JUMP_INSN is deleted, the label's LABEL_NUSES can
@ -527,7 +520,7 @@ extern char *note_insn_name[];
/* For a REG rtx, REGNO extracts the register number. */
#define REGNO(RTX) ((RTX)->fld[0].rtint)
#define REGNO(RTX) XINT(RTX, 0)
/* For a REG rtx, REG_FUNCTION_VALUE_P is nonzero if the reg
is the current function's return value. */
@ -539,13 +532,13 @@ extern char *note_insn_name[];
/* For a CONST_INT rtx, INTVAL extracts the integer. */
#define INTVAL(RTX) ((RTX)->fld[0].rtwint)
#define INTVAL(RTX) XWINT(RTX, 0)
/* For a SUBREG rtx, SUBREG_REG extracts the value we want a subreg of.
SUBREG_WORD extracts the word-number. */
#define SUBREG_REG(RTX) ((RTX)->fld[0].rtx)
#define SUBREG_WORD(RTX) ((RTX)->fld[1].rtint)
#define SUBREG_REG(RTX) XEXP(RTX, 0)
#define SUBREG_WORD(RTX) XINT(RTX, 1)
/* 1 if the REG contained in SUBREG_REG is already known to be
sign- or zero-extended from the mode of the SUBREG to the mode of
@ -640,12 +633,12 @@ extern char *note_insn_name[];
/* For a SET rtx, SET_DEST is the place that is set
and SET_SRC is the value it is set to. */
#define SET_DEST(RTX) ((RTX)->fld[0].rtx)
#define SET_SRC(RTX) ((RTX)->fld[1].rtx)
#define SET_DEST(RTX) XEXP(RTX, 0)
#define SET_SRC(RTX) XEXP(RTX, 1)
/* For a TRAP_IF rtx, TRAP_CONDITION is an expression. */
#define TRAP_CONDITION(RTX) ((RTX)->fld[0].rtx)
#define TRAP_CODE(RTX) (RTX)->fld[1].rtx
#define TRAP_CONDITION(RTX) XEXP(RTX, 0)
#define TRAP_CODE(RTX) XEXP(RTX, 1)
/* 1 in a SYMBOL_REF if it addresses this function's constants pool. */
#define CONSTANT_POOL_ADDRESS_P(RTX) ((RTX)->unchanging)
@ -870,7 +863,6 @@ extern rtx copy_rtx_if_shared PROTO((rtx));
extern rtx copy_most_rtx PROTO((rtx, rtx));
extern rtx shallow_copy_rtx PROTO((rtx));
extern rtvec gen_rtvec_v PROTO((int, rtx *));
extern rtvec gen_rtvec_vv PROTO((int, rtunion *));
extern rtx gen_reg_rtx PROTO((enum machine_mode));
extern rtx gen_label_rtx PROTO((void));
extern rtx gen_lowpart_common PROTO((enum machine_mode, rtx));

View File

@ -1161,6 +1161,7 @@ rtx_equal_p (x, y)
break;
case '0':
case 't':
break;
/* It is believed that rtx's at this level will never

View File

@ -5348,7 +5348,7 @@ expand_end_case (orig_index)
emit_jump_insn (gen_rtx_ADDR_DIFF_VEC (CASE_VECTOR_MODE,
gen_rtx_LABEL_REF (Pmode, table_label),
gen_rtvec_v (ncases, labelvec),
const0_rtx, const0_rtx, 0));
const0_rtx, const0_rtx));
else
emit_jump_insn (gen_rtx_ADDR_VEC (CASE_VECTOR_MODE,
gen_rtvec_v (ncases, labelvec)));

View File

@ -5077,81 +5077,112 @@ get_set_constructor_bytes (init, buffer, wd_size)
#ifdef ENABLE_CHECKING
/* Complain if the tree code does not match the expected one.
NODE is the tree node in question, CODE is the expected tree code,
and FILE and LINE are the filename and line number, respectively,
of the line on which the check was done. If NONFATAL is nonzero,
don't abort if the reference is invalid; instead, return 0.
If the reference is valid, return NODE. */
#if defined __GNUC__ && (__GNUC__ > 2 || __GNUC_MINOR__ > 6)
tree
tree_check (node, code, file, line, nofatal)
tree node;
/* Complain that the tree code of NODE does not match the expected CODE.
FILE, LINE, and FUNCTION are of the caller.
FIXME: should print the blather about reporting the bug. */
void
tree_check_failed (node, code, file, line, function)
const tree node;
enum tree_code code;
const char *file;
int line;
int nofatal;
const char *function;
{
if (TREE_CODE (node) == code)
return node;
else if (nofatal)
return 0;
else
fatal ("%s:%d: Expect %s, have %s\n", file, line,
tree_code_name[code], tree_code_name[TREE_CODE (node)]);
fatal ("Internal compiler error in `%s', at %s:%d:\n\
\texpected %s, have %s\n",
function, trim_filename (file), line,
tree_code_name[code], tree_code_name[TREE_CODE (node)]);
}
/* Similar to above, except that we check for a class of tree
code, given in CL. */
tree
tree_class_check (node, cl, file, line, nofatal)
tree node;
void
tree_class_check_failed (node, cl, file, line, function)
const tree node;
char cl;
const char *file;
int line;
int nofatal;
const char *function;
{
if (TREE_CODE_CLASS (TREE_CODE (node)) == cl)
return node;
else if (nofatal)
return 0;
else
fatal ("%s:%d: Expect '%c', have '%s'\n", file, line,
cl, tree_code_name[TREE_CODE (node)]);
fatal ("Internal compiler error in `%s', at %s:%d:\n\
\texpected '%c', have '%c' (%s)\n",
function, trim_filename (file), line, cl,
TREE_CODE_CLASS (TREE_CODE (node)),
tree_code_name[TREE_CODE (node)]);
}
/* Likewise, but complain if the tree node is not an expression. */
#else /* not gcc or old gcc */
/* These functions are just like the above, but they have to
do the check as well as report the error. */
tree
expr_check (node, ignored, file, line, nofatal)
tree node;
int ignored;
tree_check (node, code, file, line)
const tree node;
enum tree_code code;
const char *file;
int line;
int nofatal;
{
switch (TREE_CODE_CLASS (TREE_CODE (node)))
{
case 'r':
case 's':
case 'e':
case '<':
case '1':
case '2':
break;
{
if (TREE_CODE (node) == code)
return node;
default:
if (nofatal)
return 0;
else
fatal ("%s:%d: Expect expression, have '%s'\n", file, line,
tree_code_name[TREE_CODE (node)]);
}
return node;
fatal ("Internal compiler error at %s:%d:\n\texpected %s, have %s\n",
file, trim_filename (file), tree_code_name[code], tree_code_name[TREE_CODE(node)]);
}
#endif
tree
tree_class_check (node, class, file, line)
const tree node;
char class;
const char *file;
int line;
{
if (TREE_CODE_CLASS (TREE_CODE (node)) == class)
return node;
fatal ("Internal compiler error at %s:%d:\n\
\texpected '%c', have '%c' (%s)\n",
file, trim_filename (file), class, TREE_CODE_CLASS (TREE_CODE (node)),
tree_code_name[TREE_CODE(node)]);
}
tree
cst_or_constructor_check (node, file, line)
const tree node;
const char *file;
int line;
{
enum tree_code code = TREE_CODE (node);
if (code == CONSTRUCTOR || TREE_CODE_CLASS (code) == 'c')
return node;
fatal ("Internal compiler error at %s:%d:\n\
\texpected constructor, have %s\n",
file, line, tree_code_name[code]);
}
tree
cst_or_constructor_check (node, file, line)
const tree node;
const char *file;
int line;
{
char c = TREE_CODE_CLASS (TREE_CODE (node));
if (c == 'r' || c == 's' || c == '<'
|| c == '1' || c == '2' || c == 'e')
return node;
fatal ("Internal compiler error at %s:%d:\n\
\texpected 'e', have '%c' (%s)\n",
file, trim_filename (file), c, tree_code_name[TREE_CODE (node)]);
}
#endif /* not gcc or old gcc */
#endif /* ENABLE_CHECKING */
/* Return the alias set for T, which may be either a type or an
expression. */

View File

@ -311,38 +311,84 @@ struct tree_common
#define TREE_SET_CODE(NODE, VALUE) ((NODE)->common.code = (int) (VALUE))
/* When checking is enabled, errors will be generated if a tree node
is accessed incorrectly. The macros abort with a fatal error,
except for the *1 variants, which just return 0 on failure. The
latter variants should only be used for combination checks, which
succeed when one of the checks succeed. The CHAIN_CHECK macro helps
defining such checks. */
is accessed incorrectly. The macros abort with a fatal error. */
#ifdef ENABLE_CHECKING
#define DO_CHECK(FUNC, t, param) FUNC (t, param, __FILE__, __LINE__, 0)
#define DO_CHECK1(FUNC, t, param) FUNC (t, param, __FILE__, __LINE__, 1)
#define CHAIN_CHECK(t, c1, c2) (c1 (t) ? t : c2 (t))
#else
#define DO_CHECK(FUNC, t, param) (t)
#define DO_CHECK1(FUNC, t, param) (t)
#define CHAIN_CHECK(t, c1, c2) (t)
#endif
#define TREE_CHECK(t, code) DO_CHECK (tree_check, t, code)
#define TREE_CHECK1(t, code) DO_CHECK1 (tree_check, t, code)
#if defined __GNUC__ && (__GNUC__ > 2 || __GNUC_MINOR__ > 6)
/* This optimization can only be done in stage2/3, because it
uses statement expressions. You might think that you could use
conditional (?:) expressions, but you would be wrong: these macros
need to evaluate `t' only once. */
#define TREE_CHECK(t, code) \
({ const tree __t = t; \
if (TREE_CODE(__t) != (code)) \
tree_check_failed (__t, code, __FILE__, \
__LINE__, __PRETTY_FUNCTION__); \
__t; })
#define TREE_CLASS_CHECK(t, class) \
({ const tree __t = t; \
if (TREE_CODE_CLASS(TREE_CODE(__t)) != (class)) \
tree_class_check_failed (__t, class, __FILE__, \
__LINE__, __PRETTY_FUNCTION__); \
__t; })
/* These checks have to be special cased. */
#define CST_OR_CONSTRUCTOR_CHECK(t) \
({ const tree __t = t; \
enum tree_code __c = TREE_CODE(__t); \
if (__c != CONSTRUCTOR && TREE_CODE_CLASS(__c) != 'c') \
tree_check_failed (__t, CONSTRUCTOR, __FILE__, \
__LINE__, __PRETTY_FUNCTION__); \
__t; })
#define EXPR_CHECK(t) \
({ const tree __t = t; \
char __c = TREE_CODE_CLASS(TREE_CODE(__t)); \
if (__c != 'r' && __c != 's' && __c != '<' \
&& __c != '1' && __c != '2' && __c != 'e') \
tree_class_check_failed(__t, 'e', __FILE__, \
__LINE__, __PRETTY_FUNCTION__); \
__t; })
extern void tree_check_failed PROTO((const tree, enum tree_code,
const char *, int, const char *))
ATTRIBUTE_NORETURN;
extern void tree_class_check_failed PROTO((const tree, char,
const char *, int, const char *))
ATTRIBUTE_NORETURN;
#else /* not gcc or old gcc */
#define TREE_CHECK(t, code) \
tree_check (t, code, __FILE__, __LINE__)
#define TREE_CLASS_CHECK(t, code) \
tree_class_check (t, code, __FILE__, __LINE__)
#define CST_OR_CONSTRUCTOR_CHECK(t) \
cst_or_constructor_check (t, __FILE__, __LINE__)
#define EXPR_CHECK(t) \
expr_check (t, __FILE__, __LINE__)
extern tree tree_check PROTO((const tree, enum tree_code, const char *, int));
extern tree tree_class_check PROTO((const tree, char, const char *, int));
extern tree cst_or_constructor_check PROTO((const tree, const char *, int));
extern tree expr_check PROTO((const tree, enum tree_code, const char *, int));
#endif /* not gcc or old gcc */
#else /* not ENABLE_CHECKING */
#define TREE_CHECK(t, code) (t)
#define TREE_CLASS_CHECK(t, code) (t)
#define CST_OR_CONSTRUCTOR_CHECK(t) (t)
#define EXPR_CHECK(t) (t)
#endif
#include "tree-check.h"
#define TYPE_CHECK(tree) DO_CHECK (tree_class_check, tree, 't')
#define TYPE_CHECK1(tree) DO_CHECK1 (tree_class_check, tree, 't')
#define DECL_CHECK(t) DO_CHECK (tree_class_check, t, 'd')
#define DECL_CHECK1(t) DO_CHECK1 (tree_class_check, t, 'd')
#define CST_CHECK(t) DO_CHECK (tree_class_check, t, 'c')
#define CST_CHECK1(t) DO_CHECK1 (tree_class_check, t, 'c')
#define EXPR_CHECK(t) DO_CHECK (expr_check, t, 0)
/* Chained checks. The last check has to succeed, the others may fail. */
#define CST_OR_CONSTRUCTOR_CHECK(t) \
CHAIN_CHECK (t, CST_CHECK1, CONSTRUCTOR_CHECK)
#define TYPE_CHECK(tree) TREE_CLASS_CHECK (tree, 't')
#define DECL_CHECK(tree) TREE_CLASS_CHECK (tree, 'd')
#define CST_CHECK(tree) TREE_CLASS_CHECK (tree, 'c')
/* In all nodes that are expressions, this is the data type of the expression.
In POINTER_TYPE nodes, this is the type that the pointer points to.
@ -2198,12 +2244,6 @@ extern void start_identifier_warnings PROTO ((void));
extern void gcc_obstack_init PROTO ((struct obstack *));
extern void init_obstacks PROTO ((void));
extern void obfree PROTO ((char *));
extern tree tree_check PROTO ((tree, enum tree_code,
const char *, int, int));
extern tree tree_class_check PROTO ((tree, char, const char *,
int, int));
extern tree expr_check PROTO ((tree, int, const char *,
int, int));
/* In function.c */
extern void setjmp_protect_args PROTO ((void));