diff options
author | Zack Weinberg <zack@bitmover.com> | 1999-08-31 19:39:10 +0000 |
---|---|---|
committer | Zack Weinberg <zack@gcc.gnu.org> | 1999-08-31 19:39:10 +0000 |
commit | ef178af3a4faba2594c5a106ca721a5c3db4f693 (patch) | |
tree | 0b67c4cdc852a2b9c74808c3b360549b5fc234f0 | |
parent | 8230525836955815b66b3e2a7a46fd6a0dbb7fd6 (diff) | |
download | gcc-ef178af3a4faba2594c5a106ca721a5c3db4f693.zip gcc-ef178af3a4faba2594c5a106ca721a5c3db4f693.tar.gz gcc-ef178af3a4faba2594c5a106ca721a5c3db4f693.tar.bz2 |
rtl.h (RTL_CHECK1, RTL_CHECK2): New macros which type- and bounds- check RTL accesses if --enable-checking.
1999-08-31 12:20 -0700 Zack Weinberg <zack@bitmover.com>
* rtl.h (RTL_CHECK1, RTL_CHECK2): New macros which type- and
bounds- check RTL accesses if --enable-checking.
(RTVEC_ELT): Bounds check if --enable-checking.
(XWINT, XINT, XSTR, XEXP, XVEC, XMODE, XBITMAP, XTREE,
XBBDEF): Use RTL_CHECK1/RTL_CHECK2 as appropriate.
(XVECEXP, XVECLEN): Define in terms of XVEC, RTVEC_ELT, and
GET_NUM_ELEM.
(X0WINT, X0INT, X0STR, X0EXP, X0VEC, X0MODE, X0BITMAP, X0TREE,
X0BBDEF, X0ADVFLAGS): New macros for accessing '0' slots of RTXes.
(ADDR_DIFF_VEC_FLAGS): Use X0ADVFLAGS.
(NOTE_SOURCE_FILE): Use X0STR.
(NOTE_BLOCK_NUMBER, NOTE_EH_HANDLER, LABEL_NUSES,
MEM_ALIAS_SET): Use X0INT.
(NOTE_RANGE_INFO, NOTE_LIVE_INFO, NOTE_BASIC_BLOCK,
JUMP_LABEL, LABEL_REFS, LABEL_NEXTREF, CONTAINING_INSN):
Use X0EXP.
* real.h (CONST_DOUBLE_CHAIN): Use X0EXP.
* rtl.c (copy_rtx, copy_most_rtx): Copy '0' slots with X0WINT.
(rtl_check_failed_bounds, rtl_check_failed_type1,
rtl_check_failed_type2, rtvec_check_failed_bounds): New
functions.
(fancy_abort): Fix comment.
* cse.c (canon_hash): Read CONST_DOUBLE data slots with XWINT.
(cse_insn): Decrement LABEL_NUSES for jump target before
deleting jump insn.
* emit-rtl.c (gen_rtx_CONST_DOUBLE): Use X0EXP for slot 1.
* final.c (alter_subreg): Compute regno before changing x to
REG; set REGNO(x) after changing it.
* flow.c (count_basic_blocks): Use XWINT to inspect EH_REGION
notes containing CONST_INTs.
(delete_eh_regions): Use NOTE_EH_HANDLER.
* function.c (put_reg_into_stack): Make reg a MEM before
initializing it.
(fixup_var_refs_insns): Save REG_NOTES (insn) in case we
delete insn.
(gen_mem_addressof): Make reg a MEM before initializing it.
* integrate.c (copy_rtx_and_substitute): Copy '0' slots with
X0WINT.
* local-alloc.c (update_equiv_regs): Zap REG_NOTES before
deleting an insn, not after.
(block_alloc): Only look at PATTERN(insn) if we have to, and
only if it's format class 'i'.
* loop.c (check_dbra_loop): Check bl->biv->add_val is a
CONST_INT before using its INTVAL.
* print-rtl.c (print_rtx): Use X0STR.
* regmove.c (fixup_match_1): Don't look at PATTERN of
non-class-'i' insn chain elements.
* reload.c (loc_mentioned_in_p): Take address of
in->fld[1].rtx directly.
* reload1.c (reload): Change reg to a MEM before initializing
it.
* varasm.c (mark_constant_pool): Skip CONST_DOUBLES, which
have no names.
* config/i386/i386.md (decrement_and_branch_if_zero): Fix typo.
From-SVN: r29008
-rw-r--r-- | gcc/ChangeLog | 59 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 2 | ||||
-rw-r--r-- | gcc/cse.c | 8 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 2 | ||||
-rw-r--r-- | gcc/final.c | 10 | ||||
-rw-r--r-- | gcc/flow.c | 6 | ||||
-rw-r--r-- | gcc/function.c | 18 | ||||
-rw-r--r-- | gcc/genattrtab.c | 2 | ||||
-rw-r--r-- | gcc/integrate.c | 3 | ||||
-rw-r--r-- | gcc/local-alloc.c | 13 | ||||
-rw-r--r-- | gcc/loop.c | 3 | ||||
-rw-r--r-- | gcc/print-rtl.c | 3 | ||||
-rw-r--r-- | gcc/real.h | 2 | ||||
-rw-r--r-- | gcc/regmove.c | 4 | ||||
-rw-r--r-- | gcc/reload.c | 2 | ||||
-rw-r--r-- | gcc/reload1.c | 2 | ||||
-rw-r--r-- | gcc/rtl.c | 76 | ||||
-rw-r--r-- | gcc/rtl.h | 118 | ||||
-rw-r--r-- | gcc/varasm.c | 3 |
19 files changed, 273 insertions, 63 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 417a342..d84191d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,62 @@ +1999-08-31 12:20 -0700 Zack Weinberg <zack@bitmover.com> + + * rtl.h (RTL_CHECK1, RTL_CHECK2): New macros which type- and + bounds- check RTL accesses if --enable-checking. + (RTVEC_ELT): Bounds check if --enable-checking. + (XWINT, XINT, XSTR, XEXP, XVEC, XMODE, XBITMAP, XTREE, + XBBDEF): Use RTL_CHECK1/RTL_CHECK2 as appropriate. + (XVECEXP, XVECLEN): Define in terms of XVEC, RTVEC_ELT, and + GET_NUM_ELEM. + (X0WINT, X0INT, X0STR, X0EXP, X0VEC, X0MODE, X0BITMAP, X0TREE, + X0BBDEF, X0ADVFLAGS): New macros for accessing '0' slots of RTXes. + + (ADDR_DIFF_VEC_FLAGS): Use X0ADVFLAGS. + (NOTE_SOURCE_FILE): Use X0STR. + (NOTE_BLOCK_NUMBER, NOTE_EH_HANDLER, LABEL_NUSES, + MEM_ALIAS_SET): Use X0INT. + (NOTE_RANGE_INFO, NOTE_LIVE_INFO, NOTE_BASIC_BLOCK, + JUMP_LABEL, LABEL_REFS, LABEL_NEXTREF, CONTAINING_INSN): + Use X0EXP. + * real.h (CONST_DOUBLE_CHAIN): Use X0EXP. + * rtl.c (copy_rtx, copy_most_rtx): Copy '0' slots with X0WINT. + (rtl_check_failed_bounds, rtl_check_failed_type1, + rtl_check_failed_type2, rtvec_check_failed_bounds): New + functions. + (fancy_abort): Fix comment. + + * cse.c (canon_hash): Read CONST_DOUBLE data slots with XWINT. + (cse_insn): Decrement LABEL_NUSES for jump target before + deleting jump insn. + * emit-rtl.c (gen_rtx_CONST_DOUBLE): Use X0EXP for slot 1. + * final.c (alter_subreg): Compute regno before changing x to + REG; set REGNO(x) after changing it. + * flow.c (count_basic_blocks): Use XWINT to inspect EH_REGION + notes containing CONST_INTs. + (delete_eh_regions): Use NOTE_EH_HANDLER. + * function.c (put_reg_into_stack): Make reg a MEM before + initializing it. + (fixup_var_refs_insns): Save REG_NOTES (insn) in case we + delete insn. + (gen_mem_addressof): Make reg a MEM before initializing it. + * integrate.c (copy_rtx_and_substitute): Copy '0' slots with + X0WINT. + * local-alloc.c (update_equiv_regs): Zap REG_NOTES before + deleting an insn, not after. + (block_alloc): Only look at PATTERN(insn) if we have to, and + only if it's format class 'i'. + * loop.c (check_dbra_loop): Check bl->biv->add_val is a + CONST_INT before using its INTVAL. + * print-rtl.c (print_rtx): Use X0STR. + * regmove.c (fixup_match_1): Don't look at PATTERN of + non-class-'i' insn chain elements. + * reload.c (loc_mentioned_in_p): Take address of + in->fld[1].rtx directly. + * reload1.c (reload): Change reg to a MEM before initializing + it. + * varasm.c (mark_constant_pool): Skip CONST_DOUBLES, which + have no names. + * config/i386/i386.md (decrement_and_branch_if_zero): Fix typo. + Fri Aug 20 13:43:41 1999 Andrew Haley <aph@cygnus.com> * config/mips/mips.c (machine_dependent_reorg): Force a diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 62dff26..547facd 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -6413,7 +6413,7 @@ byte_xor_operation: { CC_STATUS_INIT; - if (GET_CODE (operands[1]) == REG && REGNO (operands[2]) == 2 && + if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 2 && operands[2] == constm1_rtx && ix86_cpu == PROCESSOR_K6) return \"loop %l3\"; @@ -2166,7 +2166,7 @@ canon_hash (x, mode) if (GET_MODE (x) != VOIDmode) for (i = 2; i < GET_RTX_LENGTH (CONST_DOUBLE); i++) { - unsigned tem = XINT (x, i); + unsigned HOST_WIDE_INT tem = XWINT (x, i); hash += tem; } else @@ -7384,13 +7384,13 @@ cse_insn (insn, libcall_insn) the insn. */ else if (n_sets == 1 && dest == pc_rtx && src == pc_rtx) { + /* One less use of the label this insn used to jump to. */ + if (JUMP_LABEL (insn) != 0) + --LABEL_NUSES (JUMP_LABEL (insn)); PUT_CODE (insn, NOTE); NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; NOTE_SOURCE_FILE (insn) = 0; cse_jumps_altered = 1; - /* One less use of the label this insn used to jump to. */ - if (JUMP_LABEL (insn) != 0) - --LABEL_NUSES (JUMP_LABEL (insn)); /* No more processing for this set. */ sets[i].rtl = 0; } diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index fc33130..3535a23 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -217,7 +217,7 @@ gen_rtx_CONST_DOUBLE (mode, arg0, arg1, arg2) PUT_MODE (r, mode); XEXP (r, 0) = arg0; - XEXP (r, 1) = NULL_RTX; + X0EXP (r, 1) = NULL_RTX; XWINT (r, 2) = arg1; XWINT (r, 3) = arg2; diff --git a/gcc/final.c b/gcc/final.c index 58361ab..c4d4708 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -3089,6 +3089,7 @@ alter_subreg (x) if (GET_CODE (y) == REG) { + int regno; /* If the word size is larger than the size of this register, adjust the register number to compensate. */ /* ??? Note that this just catches stragglers created by/for @@ -3096,13 +3097,14 @@ alter_subreg (x) earlier, or kept _all_ subregs until now and eliminate gen_lowpart and friends. */ - PUT_CODE (x, REG); #ifdef ALTER_HARD_SUBREG - REGNO (x) = ALTER_HARD_SUBREG(GET_MODE (x), SUBREG_WORD (x), - GET_MODE (y), REGNO (y)); + regno = ALTER_HARD_SUBREG(GET_MODE (x), SUBREG_WORD (x), + GET_MODE (y), REGNO (y)); #else - REGNO (x) = REGNO (y) + SUBREG_WORD (x); + regno = REGNO (y) + SUBREG_WORD (x); #endif + PUT_CODE (x, REG); + REGNO (x) = regno; /* This field has a different meaning for REGs and SUBREGs. Make sure to clear it! */ x->used = 0; @@ -473,7 +473,7 @@ count_basic_blocks (f) if (code == CALL_INSN) { rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); - int region = (note ? XINT (XEXP (note, 0), 0) : 1); + int region = (note ? XWINT (XEXP (note, 0), 0) : 1); prev_call = insn; call_had_abnormal_edge = 0; @@ -553,7 +553,7 @@ find_basic_blocks_1 (f, bb_eh_end) { /* Record whether this call created an edge. */ rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); - int region = (note ? XINT (XEXP (note, 0), 0) : 1); + int region = (note ? XWINT (XEXP (note, 0), 0) : 1); call_has_abnormal_edge = 0; /* If there is an EH region, we have an edge. */ @@ -1613,7 +1613,7 @@ delete_eh_regions () if ((NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG) || (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)) { - int num = CODE_LABEL_NUMBER (insn); + int num = NOTE_EH_HANDLER (insn); /* A NULL handler indicates a region is no longer needed, as long as it isn't the target of a rethrow. */ if (get_first_handler (num) == NULL && ! rethrow_used (num)) diff --git a/gcc/function.c b/gcc/function.c index 074252c..6fb5368 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -1341,11 +1341,11 @@ put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p, new = assign_stack_local (decl_mode, GET_MODE_SIZE (decl_mode), 0); } + PUT_CODE (reg, MEM); PUT_MODE (reg, decl_mode); XEXP (reg, 0) = XEXP (new, 0); /* `volatil' bit means one thing for MEMs, another entirely for REGs. */ MEM_VOLATILE_P (reg) = volatile_p; - PUT_CODE (reg, MEM); /* If this is a memory ref that contains aggregate components, mark it as such for cse and loop optimize. If we are reusing a @@ -1495,6 +1495,9 @@ fixup_var_refs_insns (var, promoted_mode, unsignedp, insn, toplevel, ht) if (GET_RTX_CLASS (GET_CODE (insn)) == 'i') { + /* Remember the notes in case we delete the insn. */ + note = REG_NOTES (insn); + /* If this is a CLOBBER of VAR, delete it. If it has a REG_LIBCALL note, delete the REG_LIBCALL @@ -1653,10 +1656,13 @@ fixup_var_refs_insns (var, promoted_mode, unsignedp, insn, toplevel, ht) /* Also fix up any invalid exprs in the REG_NOTES of this insn. But don't touch other insns referred to by reg-notes; we will get them elsewhere. */ - for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) - if (GET_CODE (note) != INSN_LIST) - XEXP (note, 0) - = walk_fixup_memory_subreg (XEXP (note, 0), insn, 1); + while (note) + { + if (GET_CODE (note) != INSN_LIST) + XEXP (note, 0) + = walk_fixup_memory_subreg (XEXP (note, 0), insn, 1); + note = XEXP (note, 1); + } } if (!ht) @@ -2631,9 +2637,9 @@ gen_mem_addressof (reg, decl) address is being taken. */ REG_USERVAR_P (XEXP (r, 0)) = REG_USERVAR_P (reg); - XEXP (reg, 0) = r; PUT_CODE (reg, MEM); PUT_MODE (reg, DECL_MODE (decl)); + XEXP (reg, 0) = r; MEM_VOLATILE_P (reg) = TREE_SIDE_EFFECTS (decl); MEM_SET_IN_STRUCT_P (reg, AGGREGATE_TYPE_P (type)); MEM_ALIAS_SET (reg) = get_alias_set (decl); diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index 5c1a3be..9fb0bf0 100644 --- a/gcc/genattrtab.c +++ b/gcc/genattrtab.c @@ -5955,6 +5955,8 @@ main (argc, argv) rtx tem; int i; + progname = "genattrtab"; + #if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT) /* Get rid of any avoidable limit on stack size. */ { diff --git a/gcc/integrate.c b/gcc/integrate.c index b3e681c..56d09c2 100644 --- a/gcc/integrate.c +++ b/gcc/integrate.c @@ -2699,7 +2699,8 @@ copy_rtx_and_substitute (orig, map) switch (*format_ptr++) { case '0': - XEXP (copy, i) = XEXP (orig, i); + /* Copy this through the wide int field; that's safest. */ + X0WINT (copy, i) = X0WINT (orig, i); break; case 'e': diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c index 89e3f49..dcee499 100644 --- a/gcc/local-alloc.c +++ b/gcc/local-alloc.c @@ -971,11 +971,11 @@ update_equiv_regs () emit_insn_before (copy_rtx (PATTERN (equiv_insn)), insn); REG_NOTES (PREV_INSN (insn)) = REG_NOTES (equiv_insn); + REG_NOTES (equiv_insn) = 0; PUT_CODE (equiv_insn, NOTE); NOTE_LINE_NUMBER (equiv_insn) = NOTE_INSN_DELETED; NOTE_SOURCE_FILE (equiv_insn) = 0; - REG_NOTES (equiv_insn) = 0; if (block < 0) REG_BASIC_BLOCK (regno) = 0; @@ -1071,8 +1071,6 @@ block_alloc (b) insn = BLOCK_HEAD (b); while (1) { - register rtx body = PATTERN (insn); - if (GET_CODE (insn) != NOTE) insn_number++; @@ -1083,6 +1081,9 @@ block_alloc (b) register rtx r0, r1; int combined_regno = -1; int i; +#ifndef REGISTER_CONSTRAINTS + register rtx body = PATTERN (insn); +#endif this_insn_number = insn_number; this_insn = insn; @@ -1184,11 +1185,11 @@ block_alloc (b) can only be in the same register as the output, give priority to an equivalence found from that insn. */ int may_save_copy - = ((SET_DEST (body) == r0 && SET_SRC (body) == r1) #ifdef REGISTER_CONSTRAINTS - || (r1 == recog_operand[i] && must_match_0 >= 0) + = (r1 == recog_operand[i] && must_match_0 >= 0); +#else + = (SET_DEST (body) == r0 && SET_SRC (body) == r1); #endif - ); if (GET_CODE (r1) == REG || GET_CODE (r1) == SUBREG) win = combine_regs (r1, r0, may_save_copy, @@ -7797,7 +7797,8 @@ check_dbra_loop (loop_end, insn_count, loop_start, loop_info) } } } - else if (INTVAL (bl->biv->add_val) > 0) + else if (GET_CODE (bl->biv->add_val) == CONST_INT + && INTVAL (bl->biv->add_val) > 0) { /* Try to change inc to dec, so can apply above optimization. */ /* Can do this if: diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c index 0d23a51..52c92f3 100644 --- a/gcc/print-rtl.c +++ b/gcc/print-rtl.c @@ -185,8 +185,7 @@ print_rtx (in_rtx) } else { - /* Can't use XSTR because of type checking. */ - char *str = in_rtx->fld[i].rtstr; + char *str = X0STR (in_rtx, i); if (str == 0) fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile); else @@ -452,7 +452,7 @@ union real_extract #define CONST_DOUBLE_HIGH(r) XWINT (r, 3) /* Link for chain of all CONST_DOUBLEs in use in current function. */ -#define CONST_DOUBLE_CHAIN(r) XEXP (r, 1) +#define CONST_DOUBLE_CHAIN(r) X0EXP (r, 1) /* The MEM which represents this CONST_DOUBLE's value in memory, or const0_rtx if no MEM has been made for it yet, or cc0_rtx if it is not on the chain. */ diff --git a/gcc/regmove.c b/gcc/regmove.c index bff689e..c0e5f7e 100644 --- a/gcc/regmove.c +++ b/gcc/regmove.c @@ -1905,7 +1905,9 @@ fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number, NOTE_SOURCE_FILE (insn) = 0; /* emit_insn_after_with_line_notes has no return value, so search for the new insn. */ - for (insn = p; PATTERN (insn) != pat; ) + insn = p; + while (GET_RTX_CLASS (GET_CODE (insn)) != 'i' + || PATTERN (insn) != pat) insn = PREV_INSN (insn); REG_NOTES (insn) = notes; diff --git a/gcc/reload.c b/gcc/reload.c index 7d96884..46479ac 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -1631,7 +1631,7 @@ loc_mentioned_in_p (loc, in) for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { - if (loc == &XEXP (in, i)) + if (loc == &in->fld[i].rtx) return 1; if (fmt[i] == 'e') { diff --git a/gcc/reload1.c b/gcc/reload1.c index 28ddd86..83ebad3 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -1110,6 +1110,7 @@ reload (first, global, dumpfile) if (reg_renumber[i] < 0) { rtx reg = regno_reg_rtx[i]; + PUT_CODE (reg, MEM); XEXP (reg, 0) = addr; REG_USERVAR_P (reg) = 0; RTX_UNCHANGING_P (reg) = is_readonly; @@ -1118,7 +1119,6 @@ reload (first, global, dumpfile) /* We have no alias information about this newly created MEM. */ MEM_ALIAS_SET (reg) = 0; - PUT_CODE (reg, MEM); } else if (reg_equiv_mem[i]) XEXP (reg_equiv_mem[i], 0) = addr; @@ -387,7 +387,6 @@ copy_rtx (orig) XEXP (copy, i) = copy_rtx (XEXP (orig, i)); break; - case '0': case 'u': XEXP (copy, i) = XEXP (orig, i); break; @@ -428,6 +427,11 @@ copy_rtx (orig) XSTR (copy, i) = XSTR (orig, i); break; + case '0': + /* Copy this through the wide int field; that's safest. */ + X0WINT (copy, i) = X0WINT (orig, i); + break; + default: abort (); } @@ -487,7 +491,6 @@ copy_most_rtx (orig, may_share) XEXP (copy, i) = copy_most_rtx (XEXP (orig, i), may_share); break; - case '0': case 'u': XEXP (copy, i) = XEXP (orig, i); break; @@ -522,6 +525,11 @@ copy_most_rtx (orig, may_share) XSTR (copy, i) = XSTR (orig, i); break; + case '0': + /* Copy this through the wide int field; that's safest. */ + X0WINT (copy, i) = X0WINT (orig, i); + break; + default: abort (); } @@ -934,6 +942,65 @@ read_rtx (infile) return return_rtx; } +#if defined ENABLE_CHECKING && (__GNUC__ > 2 || __GNUC_MINOR__ > 6) +void +rtl_check_failed_bounds (r, n, file, line, func) + rtx r; + int n; + const char *file; + int line; + const char *func; +{ + error ("RTL check: access of elt %d of `%s' with last elt %d", + n, GET_RTX_NAME (GET_CODE (r)), GET_RTX_LENGTH (GET_CODE (r))-1); + fancy_abort (file, line, func); +} + +void +rtl_check_failed_type1 (r, n, c1, file, line, func) + rtx r; + int n; + int c1; + const char *file; + int line; + const char *func; +{ + error ("RTL check: expected elt %d type '%c', have '%c' (rtx %s)", + n, c1, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r))); + fancy_abort (file, line, func); +} + +void +rtl_check_failed_type2 (r, n, c1, c2, file, line, func) + rtx r; + int n; + int c1; + int c2; + const char *file; + int line; + const char *func; +{ + error ("RTL check: expected elt %d type '%c' or '%c', have '%c' (rtx %s)", + n, c1, c2, + GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE(r))); + fancy_abort (file, line, func); +} + +/* XXX Maybe print the vector? */ +void +rtvec_check_failed_bounds (r, n, file, line, func) + rtvec r; + int n; + const char *file; + int line; + const char *func; +{ + error ("RTL check: access of elt %d of vector with last elt %d", + n, GET_NUM_ELEM (r)-1); + fancy_abort (file, line, func); +} +#endif /* ENABLE_CHECKING */ + /* These are utility functions used by fatal-error functions all over the code. rtl.c happens to be linked by all the programs that need them, so these are here. In the future we want to break out all error handling @@ -962,11 +1029,10 @@ trim_filename (name) } /* Report an internal compiler error in a friendly manner and without - dumping core. There are two versions because __FUNCTION__ isn't - available except in gcc 2.7 and later. */ + dumping core. */ extern void fatal PVPROTO ((const char *, ...)) - ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; + ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; void fancy_abort (file, line, function) @@ -222,19 +222,86 @@ typedef struct rtvec_def{ /* General accessor macros for accessing the fields of an rtx. */ -#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) +#if defined ENABLE_CHECKING && (__GNUC__ > 2 || __GNUC_MINOR__ > 6) +/* The bit with a star outside the statement expr and an & inside is + so that N can be evaluated only once. */ +#define RTL_CHECK1(RTX, N, C1) \ +(*({ rtx _rtx = RTX; int _n = N; \ + enum rtx_code _code = GET_CODE (_rtx); \ + if (_n < 0 || _n >= GET_RTX_LENGTH (_code)) \ + rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__, \ + __PRETTY_FUNCTION__); \ + if (GET_RTX_FORMAT(_code)[_n] != C1) \ + rtl_check_failed_type1 (_rtx, _n, C1, __FILE__, __LINE__, \ + __PRETTY_FUNCTION__); \ + &_rtx->fld[_n]; })) + +#define RTL_CHECK2(RTX, N, C1, C2) \ +(*({ rtx _rtx = RTX; int _n = N; \ + enum rtx_code _code = GET_CODE (_rtx); \ + if (_n < 0 || _n >= GET_RTX_LENGTH (_code)) \ + rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__, \ + __PRETTY_FUNCTION__); \ + if (GET_RTX_FORMAT(_code)[_n] != C1 \ + && GET_RTX_FORMAT(_code)[_n] != C2) \ + rtl_check_failed_type2 (_rtx, _n, C1, C2, __FILE__, __LINE__, \ + __PRETTY_FUNCTION__); \ + &_rtx->fld[_n]; })) + +#define RTVEC_ELT(RTVEC, I) \ +(*({ rtvec _rtvec = RTVEC; int _i = I; \ + if (_i < 0 || _i >= GET_NUM_ELEM (_rtvec)) \ + rtvec_check_failed_bounds (_rtvec, _i, __FILE__, __LINE__, \ + __PRETTY_FUNCTION__); \ + &_rtvec->elem[_i]; })) + +extern void rtl_check_failed_bounds PROTO((rtx, int, + const char *, int, const char *)) + ATTRIBUTE_NORETURN; +extern void rtl_check_failed_type1 PROTO((rtx, int, int, + const char *, int, const char *)) + ATTRIBUTE_NORETURN; +extern void rtl_check_failed_type2 PROTO((rtx, int, int, int, + const char *, int, const char *)) + ATTRIBUTE_NORETURN; +extern void rtvec_check_failed_bounds PROTO((rtvec, int, + const char *, int, const char *)) + ATTRIBUTE_NORETURN; + +#else /* not ENABLE_CHECKING */ + +#define RTL_CHECK1(RTX, N, C1) ((RTX)->fld[N]) +#define RTL_CHECK2(RTX, N, C1, C2) ((RTX)->fld[N]) +#define RTVEC_ELT(RTVEC, I) ((RTVEC)->elem[I]) + +#endif + +#define XWINT(RTX, N) (RTL_CHECK1(RTX, N, 'w').rtwint) +#define XINT(RTX, N) (RTL_CHECK2(RTX, N, 'i', 'n').rtint) +#define XSTR(RTX, N) (RTL_CHECK2(RTX, N, 's', 'S').rtstr) +#define XEXP(RTX, N) (RTL_CHECK2(RTX, N, 'e', 'u').rtx) +#define XVEC(RTX, N) (RTL_CHECK2(RTX, N, 'E', 'V').rtvec) +#define XMODE(RTX, N) (RTL_CHECK1(RTX, N, 'M').rttype) +#define XBITMAP(RTX, N) (RTL_CHECK1(RTX, N, 'b').rtbit) +#define XTREE(RTX, N) (RTL_CHECK1(RTX, N, 't').rttree) +#define XBBDEF(RTX, N) (RTL_CHECK1(RTX, N, 'B').bb) + +#define XVECEXP(RTX, N, M) RTVEC_ELT (XVEC (RTX, N), M) +#define XVECLEN(RTX, N) GET_NUM_ELEM (XVEC (RTX, N)) + +/* These are like XWINT, etc. except that they expect a '0' field instead + of the normal type code. */ + +#define X0WINT(RTX, N) (RTL_CHECK1(RTX, N, '0').rtwint) +#define X0INT(RTX, N) (RTL_CHECK1(RTX, N, '0').rtint) +#define X0STR(RTX, N) (RTL_CHECK1(RTX, N, '0').rtstr) +#define X0EXP(RTX, N) (RTL_CHECK1(RTX, N, '0').rtx) +#define X0VEC(RTX, N) (RTL_CHECK1(RTX, N, '0').rtvec) +#define X0MODE(RTX, N) (RTL_CHECK1(RTX, N, '0').rttype) +#define X0BITMAP(RTX, N) (RTL_CHECK1(RTX, N, '0').rtbit) +#define X0TREE(RTX, N) (RTL_CHECK1(RTX, N, '0').rttree) +#define X0BBDEF(RTX, N) (RTL_CHECK1(RTX, N, '0').bb) +#define X0ADVFLAGS(RTX, N) (RTL_CHECK1(RTX, N, '0').rt_addr_diff_vec_flags) /* ACCESS MACROS for particular fields of insns. */ @@ -357,7 +424,7 @@ typedef struct rtvec_def{ #define REG_NOTES(INSN) XEXP(INSN, 6) -#define ADDR_DIFF_VEC_FLAGS(RTX) ((RTX)->fld[4].rt_addr_diff_vec_flags) +#define ADDR_DIFF_VEC_FLAGS(RTX) X0ADVFLAGS(RTX, 4) /* Don't forget to change reg_note_name in rtl.c. */ enum reg_note { REG_DEAD = 1, REG_INC = 2, REG_EQUIV = 3, REG_WAS_0 = 4, @@ -404,11 +471,12 @@ extern const char * const reg_note_name[]; The NOTE_INSN_RANGE_{START,END} and NOTE_INSN_LIVE notes record their information as a rtx in the field. */ -#define NOTE_SOURCE_FILE(INSN) ((INSN)->fld[3].rtstr) -#define NOTE_BLOCK_NUMBER(INSN) ((INSN)->fld[3].rtint) -#define NOTE_RANGE_INFO(INSN) ((INSN)->fld[3].rtx) -#define NOTE_LIVE_INFO(INSN) ((INSN)->fld[3].rtx) -#define NOTE_BASIC_BLOCK(INSN) ((INSN)->fld[3].bb) +#define NOTE_SOURCE_FILE(INSN) X0STR(INSN, 3) +#define NOTE_BLOCK_NUMBER(INSN) X0INT(INSN, 3) +#define NOTE_EH_HANDLER(INSN) X0INT(INSN, 3) +#define NOTE_RANGE_INFO(INSN) X0EXP(INSN, 3) +#define NOTE_LIVE_INFO(INSN) X0EXP(INSN, 3) +#define NOTE_BASIC_BLOCK(INSN) X0EXP(INSN, 3) /* If the NOTE_BLOCK_NUMBER field gets a -1, it means create a new block node for a live range block. */ @@ -488,7 +556,7 @@ extern const char * const note_insn_name[]; /* 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) +#define LABEL_NUSES(LABEL) X0INT(LABEL, 5) /* The original regno this ADDRESSOF was built for. */ #define ADDRESSOF_REGNO(RTX) XINT(RTX, 1) @@ -499,24 +567,24 @@ extern const char * const note_insn_name[]; /* 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 be decremented and possibly the label can be deleted. */ -#define JUMP_LABEL(INSN) ((INSN)->fld[7].rtx) +#define JUMP_LABEL(INSN) X0EXP(INSN, 7) /* Once basic blocks are found in flow.c, each CODE_LABEL starts a chain that goes through all the LABEL_REFs that jump to that label. The chain eventually winds up at the CODE_LABEL; it is circular. */ -#define LABEL_REFS(LABEL) ((LABEL)->fld[6].rtx) +#define LABEL_REFS(LABEL) X0EXP(LABEL, 6) /* This is the field in the LABEL_REF through which the circular chain of references to a particular label is linked. This chain is set up in flow.c. */ -#define LABEL_NEXTREF(REF) ((REF)->fld[1].rtx) +#define LABEL_NEXTREF(REF) X0EXP(REF, 1) /* Once basic blocks are found in flow.c, Each LABEL_REF points to its containing instruction with this field. */ -#define CONTAINING_INSN(RTX) ((RTX)->fld[2].rtx) +#define CONTAINING_INSN(RTX) X0EXP(RTX, 2) /* For a REG rtx, REGNO extracts the register number. */ @@ -601,7 +669,7 @@ extern const char * const note_insn_name[]; some front-ends, these numbers may correspond in some way to types, or other language-level entities, but they need not, and the back-end makes no such assumptions. */ -#define MEM_ALIAS_SET(RTX) (XINT (RTX, 1)) +#define MEM_ALIAS_SET(RTX) X0INT(RTX, 1) /* For a LABEL_REF, 1 means that this reference is to a label outside the loop containing the reference. */ diff --git a/gcc/varasm.c b/gcc/varasm.c index 3413eed..944d1bb 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -3745,6 +3745,9 @@ mark_constant_pool () if (!pool->mark) continue; + /* skip CONST_DOUBLEs too - correct? */ + if (GET_CODE (pool->constant) == CONST_DOUBLE) + continue; label = XSTR (pool->constant, 0); /* Be sure the symbol's value is marked. */ |