diff options
-rw-r--r-- | gcc/ChangeLog | 65 | ||||
-rw-r--r-- | gcc/cse.c | 3 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 22 | ||||
-rw-r--r-- | gcc/function.c | 4 | ||||
-rw-r--r-- | gcc/gencheck.c | 2 | ||||
-rw-r--r-- | gcc/gengenrtl.c | 10 | ||||
-rw-r--r-- | gcc/integrate.c | 11 | ||||
-rw-r--r-- | gcc/jump.c | 1 | ||||
-rw-r--r-- | gcc/print-rtl.c | 73 | ||||
-rw-r--r-- | gcc/reload1.c | 4 | ||||
-rw-r--r-- | gcc/rtl.c | 8 | ||||
-rw-r--r-- | gcc/rtl.def | 6 | ||||
-rw-r--r-- | gcc/rtl.h | 78 | ||||
-rw-r--r-- | gcc/rtlanal.c | 1 | ||||
-rw-r--r-- | gcc/stmt.c | 2 | ||||
-rw-r--r-- | gcc/tree.c | 133 | ||||
-rw-r--r-- | gcc/tree.h | 104 |
17 files changed, 324 insertions, 203 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8f83f30..5a3bc47 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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> @@ -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: diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index aa0b21e..b3c63b5 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -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)); } diff --git a/gcc/function.c b/gcc/function.c index c30c0d1..e321cc5 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -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); diff --git a/gcc/gencheck.c b/gcc/gencheck.c index 80d7c4f..11aed53 100644 --- a/gcc/gencheck.c +++ b/gcc/gencheck.c @@ -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; diff --git a/gcc/gengenrtl.c b/gcc/gengenrtl.c index bf98a71..37bdd9c 100644 --- a/gcc/gengenrtl.c +++ b/gcc/gengenrtl.c @@ -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 (); } diff --git a/gcc/integrate.c b/gcc/integrate.c index af7f9d2..70f69fe 100644 --- a/gcc/integrate.c +++ b/gcc/integrate.c @@ -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': @@ -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 diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c index 17a750c..a6349f3 100644 --- a/gcc/print-rtl.c +++ b/gcc/print-rtl.c @@ -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': diff --git a/gcc/reload1.c b/gcc/reload1.c index e3c3a7f..e4bda8b 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -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); @@ -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); diff --git a/gcc/rtl.def b/gcc/rtl.def index 0a5e7de..4a8e8d6 100644 --- a/gcc/rtl.def +++ b/gcc/rtl.def @@ -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 @@ -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)); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 52ff6a9..a7d335b 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -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 @@ -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))); @@ -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) + 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)]); +} + +#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 +tree_check (node, code, file, line) + const tree node; + enum tree_code code; + const char *file; + int line; +{ + if (TREE_CODE (node) == code) 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 at %s:%d:\n\texpected %s, have %s\n", + file, trim_filename (file), tree_code_name[code], tree_code_name[TREE_CODE(node)]); } -/* Likewise, but complain if the tree node is not an expression. */ +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 -expr_check (node, ignored, file, line, nofatal) - tree node; - int ignored; +cst_or_constructor_check (node, file, line) + const tree node; 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; + enum tree_code code = TREE_CODE (node); + + if (code == CONSTRUCTOR || TREE_CODE_CLASS (code) == 'c') + return node; - default: - if (nofatal) - return 0; - else - fatal ("%s:%d: Expect expression, have '%s'\n", file, line, - tree_code_name[TREE_CODE (node)]); - } + fatal ("Internal compiler error at %s:%d:\n\ +\texpected constructor, have %s\n", + file, line, tree_code_name[code]); +} - return node; +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 + +#endif /* not gcc or old gcc */ +#endif /* ENABLE_CHECKING */ /* Return the alias set for T, which may be either a type or an expression. */ @@ -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)); -#include "tree-check.h" +#endif /* not gcc or old gcc */ -#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) +#else /* not ENABLE_CHECKING */ -/* 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 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) 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)); |