rtl.h (RTL_CHECK1, RTL_CHECK2): New macros which type- and bounds- check RTL accesses...
authorZack Weinberg <zack@bitmover.com>
Tue, 31 Aug 1999 19:39:10 +0000 (19:39 +0000)
committerZack Weinberg <zack@gcc.gnu.org>
Tue, 31 Aug 1999 19:39:10 +0000 (19:39 +0000)
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

19 files changed:
gcc/ChangeLog
gcc/config/i386/i386.md
gcc/cse.c
gcc/emit-rtl.c
gcc/final.c
gcc/flow.c
gcc/function.c
gcc/genattrtab.c
gcc/integrate.c
gcc/local-alloc.c
gcc/loop.c
gcc/print-rtl.c
gcc/real.h
gcc/regmove.c
gcc/reload.c
gcc/reload1.c
gcc/rtl.c
gcc/rtl.h
gcc/varasm.c

index 417a342ede38eb816dc8926d7e5af09887870568..d84191d92285bc066fb94a83f3653fea3959b38c 100644 (file)
@@ -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
index 62dff2633fb19f747300f21ce76924f5edf0635f..547facd171cfc42aa5b0cd0002801334ea049075 100644 (file)
@@ -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\";
 
index baa42365c7783605e23c0c2a4205d9bf828cb9a1..6c7aef31ecd3b89ce884b0d22f4a5f93694579fa 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -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;
        }
index fc33130df3ed48f9eb4b0ac5900722105373e209..3535a23239dcf86805bbfc190b2b870cfece2e43 100644 (file)
@@ -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;
 
index 58361ab69ff26c214b8edea0de81f2815254a124..c4d470820461eb67591a62e2b2d42c08b7effc00 100644 (file)
@@ -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;
index 2c05fe7d5906bbf23f4fce9c75cac9b29691f1d1..a813d943e690f4c14bb3d71b26350752ce20028d 100644 (file)
@@ -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))
index 074252c5b583264449fdbd9c9e2d77656fea824a..6fb5368a3a3cd086e097342a40943742d1708696 100644 (file)
@@ -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);
index 5c1a3be73ecc13c9764f2f912f6582ef7d0afbcc..9fb0bf0d6d2c313ca66be1d140fa0fe19700915b 100644 (file)
@@ -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.  */
   {
index b3e681c6b62777ed87a388a3179a1dbc90ea741d..56d09c2010e7813ff0258858da94dc4d817a5baf 100644 (file)
@@ -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':
index 89e3f495d26ff679d83f078d87b412bffa099f6d..dcee4992c5acac731e498519e3f88f13bf1770fc 100644 (file)
@@ -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,
index a3b2bb0271ec5494b859b7c933b014bbd899078e..59628fd4f74d928137bf495cdaa6026a8f217539 100644 (file)
@@ -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:
index 0d23a5104e982a4b362514ed4b7644e8ed9498aa..52c92f3022f4e6503ecf6c7bc723705478a76d3b 100644 (file)
@@ -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
index f289379efd8329fd0784f571abb56e00eacb113a..a1e85b16c84d4798522940c17f3eccded8c1afb1 100644 (file)
@@ -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.  */
index bff689e60cb8382f2fddaf02b4158dc72771027e..c0e5f7e75676ebdc307139bfcdba6c23d6dd02d9 100644 (file)
@@ -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;
index 7d96884b782ca7ee8653c4e6deac2584a635ad2e..46479ac53e1abdf77c7765dfb81a034ac01b4418 100644 (file)
@@ -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')
         {
index 28ddd860434a275bc85b515d889f4874dc6a7f41..83ebad3c6bc0f533e59a788a60b55ff06d347545 100644 (file)
@@ -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;
index e13e4d2bfb00ab95e3cb19abfb16afafd4a6c398..e183b0503542693c8947f6c650cc6e9bae07d75d 100644 (file)
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -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)
index 837dad1af6d5902a106687e45dc1582285d1d515..ec0b73829debc3e8f5e08014b124c7be93405f25 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -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)
 
 \f
 /* 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)
 \f
 /* 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.  */
index 3413eed05f9d2bc154cfd0253c1427df4be3a344..944d1bb47f3faff8a355d4f05e0260c8338613be 100644 (file)
@@ -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. */