On Sun, Nov 3, 2024 at 11:27 PM Lewis Hyatt <lhy...@gmail.com> wrote:
>
> Some RTL objects need to store a location_t. Currently, they store it in the
> rt_int field of union rtunion, but in a world where location_t could be
> 64-bit, they need to store it in a larger variable. Unfortunately, rtunion
> does not currently have a 64-bit int type for that purpose, so add one. In
> order to avoid increasing any overhead when 64-bit locations are not in use,
> the new field is dedicated for location_t storage only and has type
> "location_t" so it will only be 64-bit if necessary. This necessitates
> adding a new RTX format code 'L' for locations. There are very many switch
> statements in the codebase that inspect the RTX format code. I took the
> approach of finding all of them that handle code 'i' or 'n' and making sure
> they handle 'L' too. I am sure that some of these call sites can never see
> an 'L' code, but I thought it would be safer and more future-proof to handle
> as many as possible, given it's just a line or two to add in most cases.

That sounds like a reasonable approach.

> While testing this with --enable-checking=rtl, I came across one place in
> final.cc that seems to be a (currently) harmless misuse of RTL:
>
>     set_cur_block_to_this_block:
>       if (! this_block)
>         {
>           if (INSN_LOCATION (insn) == UNKNOWN_LOCATION)
>             continue;
>           else
>             this_block = DECL_INITIAL (cfun->decl);
>         }
>
> In this part of reemit_insn_block_notes(), the insn variable could actually
> be a NOTE and not an INSN. In that case, INSN_LOCATION() shouldn't be
> called on it. It works fine currently because the field is properly accessed
> by XINT() either way. (For an INSN, it is a location, but for a NOTE, it is
> the note type enum). Currently, if insn is a NOTE, the comparison must
> always be false because the note type is not equal to
> 0==UNKNOWN_LOCATION. Once locations and ints are differentiated, this line
> leads to a checking failure, which I resolved by checking for the NOTE_P
> case before calling INSN_LOCATION.

>        if (! this_block)
>         {
> -         if (INSN_LOCATION (insn) == UNKNOWN_LOCATION)
> +         if (!NOTE_P (insn) && INSN_LOCATION (insn) == UNKNOWN_LOCATION)
>             continue;
>           else

I think you instead want

           if (NOTE_P (insn)
               || INSN_LOCATION (insn) == UNKNOWN_LOCATION)
             continue;

but the whole if (! this_block) block doesn't make sense to me ... I think
we only get here for NOTE_P via

          case NOTE_INSN_BEGIN_STMT:
          case NOTE_INSN_INLINE_ENTRY:
            this_block = LOCATION_BLOCK (NOTE_MARKER_LOCATION (insn));
            goto set_cur_block_to_this_block;

so possibly a !this_block case should be made explicit there, by checking
NOTE_MARKER_LOCATION for UNKNOWN_LOCATION.  CCing Alex who
might know.

The rest of the patch is OK absent comments from others.  I would suggest to
split out the above hunk for further review.

Richard.


> gcc/ChangeLog:
>
>         * rtl.def (DEBUG_INSN): Use new format code 'L' for location_t fields.
>         (INSN): Likewise.
>         (JUMP_INSN): Likewise.
>         (CALL_INSN): Likewise.
>         (ASM_INPUT): Likewise.
>         (ASM_OPERANDS): Likewise.
>         * rtl.h (union rtunion): Add new location_t RT_LOC member for use by
>         the 'L' format.
>         (struct rtx_debug_insn): Adjust comment.
>         (struct rtx_nonjump_insn): Adjust comment.
>         (struct rtx_call_insn): Adjust comment.
>         (XLOC): New accessor macro for rtunion::rt_loc.
>         (X0LOC): Likewise.
>         (XCLOC): Likewise.
>         (INSN_LOCATION): Use XLOC instead of XUINT to retrieve a location_t.
>         (NOTE_MARKER_LOCATION): Likewise for XCUINT -> XCLOC.
>         (ASM_OPERANDS_SOURCE_LOCATION): Likewise.
>         (ASM_INPUT_SOURCE_LOCATION):Likewise.
>         (gen_rtx_ASM_INPUT): Adjust to use sL format instead of si.
>         (gen_rtx_INSN): Adjust prototype to use location_r rather than int
>         for the location.
>         * cfgrtl.cc (force_nonfallthru_and_redirect): Change type of LOC
>         local variable from int to location_t.
>         * rtlhash.cc (add_rtx): Support 'L' format in the switch statement.
>         * var-tracking.cc (loc_cmp): Likewise.
>         * alias.cc (rtx_equal_for_memref_p): Likewise.
>         * config/alpha/alpha.cc (summarize_insn): Likewise.
>         * config/ia64/ia64.cc (rtx_needs_barrier): Likewise.
>         * config/rs6000/rs6000.cc (rs6000_hash_constant): Likewise.
>         * cse.cc (hash_rtx): Likewise.
>         (exp_equiv_p): Likewise.
>         * cselib.cc (rtx_equal_for_cselib_1): Likewise.
>         (cselib_hash_rtx): Likewise.
>         (cselib_expand_value_rtx_1): Likewise.
>         * emit-rtl.cc (copy_insn_1): Likewise.
>         (gen_rtx_INSN): Change the location argument from int to location_t,
>         and call the corresponding gen_rtf_fmt_* function.
>         * final.cc (reemit_insn_block_notes): Don't call INSN_LOCATION if
>         NOTE_P; the field being accessed is not a location in this case.
>         (leaf_renumber_regs_insn): Support 'L' format in the switch statement.
>         * genattrtab.cc (attr_rtx_1): Likewise.
>         * genemit.cc (gen_exp): Likewise.
>         * gengenrtl.cc (type_from_format): Likewise.
>         (accessor_from_format): Likewise.
>         * gengtype.cc (adjust_field_rtx_def): Likewise.
>         * genpeep.cc (match_rtx): Likewise; just mark gcc_unreachable() for
>         now.
>         * genrecog.cc (find_operand): Support 'L' format in the switch 
> statement.
>         (find_matching_operand): Likewise.
>         (validate_pattern): Likewise.
>         * gensupport.cc (subst_pattern_match): Likewise.
>         (get_alternatives_number): Likewise.
>         (collect_insn_data): Likewise.
>         (alter_predicate_for_insn): Likewise.
>         (alter_constraints): Likewise.
>         (subst_dup): Likewise.
>         * jump.cc (rtx_renumbered_equal_p): Likewise.
>         * loop-invariant.cc (hash_invariant_expr_1): Likewise.
>         * lra-constraints.cc (operands_match_p): Likewise.
>         * lra.cc (lra_rtx_hash): Likewise.
>         * print-rtl.cc (rtx_writer::print_rtx_operand_code_i): Refactor
>         location_t-relevant code to...
>         (rtx_writer::print_rtx_operand_code_L): ...new function here.
>         (rtx_writer::print_rtx_operand): Support 'L' format in the switch 
> statement.
>         * print-rtl.h (rtx_writer::print_rtx_operand_code_L): Add prototype
>         for new function.
>         * read-rtl-function.cc (function_reader::read_rtx_operand): Support
>         'L' format in the switch statement.
>         (function_reader::read_rtx_operand_i_or_n): Rename to...
>         (function_reader::read_rtx_operand_inL): ...this, and support 'L' as
>         well.
>         * read-rtl.cc (apply_int_iterator): Support 'L' format in the switch
>         statement.
>         (rtx_reader::read_rtx_operand): Likewise.
>         * reload.cc (operands_match_p): Likewise.
>         * rtl.cc (rtx_format): Add new code 'L'.
>         (rtx_equal_p): Support 'L' in the switch statement. Remove dead code
>         in the handling for 'i' and 'n'.
> ---
>  gcc/alias.cc                |  5 +++++
>  gcc/cfgrtl.cc               |  3 +--
>  gcc/config/alpha/alpha.cc   |  1 +
>  gcc/config/ia64/ia64.cc     |  1 +
>  gcc/config/rs6000/rs6000.cc | 25 +++++++++++++++----------
>  gcc/cse.cc                  |  9 +++++++++
>  gcc/cselib.cc               | 10 ++++++++++
>  gcc/emit-rtl.cc             |  5 +++--
>  gcc/final.cc                |  3 ++-
>  gcc/genattrtab.cc           |  4 ++++
>  gcc/genemit.cc              |  4 ++++
>  gcc/gengenrtl.cc            |  6 ++++++
>  gcc/gengtype.cc             |  5 +++++
>  gcc/genpeep.cc              |  2 ++
>  gcc/genrecog.cc             |  6 +++---
>  gcc/gensupport.cc           |  9 ++++++---
>  gcc/jump.cc                 |  5 +++++
>  gcc/loop-invariant.cc       |  2 ++
>  gcc/lra-constraints.cc      |  5 +++++
>  gcc/lra.cc                  |  4 ++++
>  gcc/print-rtl.cc            | 19 ++++++++++++++++---
>  gcc/print-rtl.h             |  1 +
>  gcc/read-rtl-function.cc    | 13 ++++++++-----
>  gcc/read-rtl.cc             |  4 ++++
>  gcc/reload.cc               |  5 +++++
>  gcc/rtl.cc                  | 18 +++++++++---------
>  gcc/rtl.def                 | 12 ++++++------
>  gcc/rtl.h                   | 32 ++++++++++++++++++--------------
>  gcc/rtlhash.cc              |  3 +++
>  gcc/var-tracking.cc         |  8 ++++++++
>  30 files changed, 171 insertions(+), 58 deletions(-)
>
> diff --git a/gcc/alias.cc b/gcc/alias.cc
> index 7c1c07d0284..a354c14cdbf 100644
> --- a/gcc/alias.cc
> +++ b/gcc/alias.cc
> @@ -1861,6 +1861,11 @@ rtx_equal_for_memref_p (const_rtx x, const_rtx y)
>             return false;
>           break;
>
> +       case 'L':
> +         if (XLOC (x, i) != XLOC (y, i))
> +           return false;
> +         break;
> +
>         case 'p':
>           if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
>             return false;
> diff --git a/gcc/cfgrtl.cc b/gcc/cfgrtl.cc
> index d9c851f72ff..516316c7ad1 100644
> --- a/gcc/cfgrtl.cc
> +++ b/gcc/cfgrtl.cc
> @@ -1512,7 +1512,6 @@ force_nonfallthru_and_redirect (edge e, basic_block 
> target, rtx jump_label)
>    edge new_edge;
>    int abnormal_edge_flags = 0;
>    bool asm_goto_edge = false;
> -  int loc;
>
>    /* In the case the last instruction is conditional jump to the next
>       instruction, first redirect the jump itself and then continue
> @@ -1697,7 +1696,7 @@ force_nonfallthru_and_redirect (edge e, basic_block 
> target, rtx jump_label)
>    else
>      jump_block = e->src;
>
> -  loc = e->goto_locus;
> +  const location_t loc = e->goto_locus;
>    e->flags &= ~EDGE_FALLTHRU;
>    if (target == EXIT_BLOCK_PTR_FOR_FN (cfun))
>      {
> diff --git a/gcc/config/alpha/alpha.cc b/gcc/config/alpha/alpha.cc
> index d7f5e3b8751..f196524dfa1 100644
> --- a/gcc/config/alpha/alpha.cc
> +++ b/gcc/config/alpha/alpha.cc
> @@ -8642,6 +8642,7 @@ summarize_insn (rtx x, struct shadow_summary *sum, int 
> set)
>             break;
>
>           case 'i':
> +         case 'L':
>             break;
>
>           default:
> diff --git a/gcc/config/ia64/ia64.cc b/gcc/config/ia64/ia64.cc
> index 4acbd82bc65..daec32bb49f 100644
> --- a/gcc/config/ia64/ia64.cc
> +++ b/gcc/config/ia64/ia64.cc
> @@ -6902,6 +6902,7 @@ rtx_needs_barrier (rtx x, struct reg_flags flags, int 
> pred)
>           case '0':     /* unused field */
>           case 'i':     /* integer */
>           case 'n':     /* note */
> +         case 'L':     /* location_t */
>           case 'w':     /* wide integer */
>           case 's':     /* pointer to string */
>           case 'S':     /* optional pointer to string */
> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
> index 950fd947fda..2d7a6aa3c9c 100644
> --- a/gcc/config/rs6000/rs6000.cc
> +++ b/gcc/config/rs6000/rs6000.cc
> @@ -17425,16 +17425,21 @@ rs6000_hash_constant (rtx k)
>         result = result * 613 + (unsigned) XINT (k, fidx);
>         break;
>        case 'w':
> -       if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
> -         result = result * 613 + (unsigned) XWINT (k, fidx);
> -       else
> -         {
> -           size_t i;
> -           for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
> -             result = result * 613 + (unsigned) (XWINT (k, fidx)
> -                                                 >> CHAR_BIT * i);
> -         }
> -       break;
> +      case 'L':
> +       {
> +         const HOST_WIDE_INT val
> +           = (format[fidx] == 'L' ? XLOC (k, fidx) : XWINT (k, fidx));
> +         if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
> +           result = result * 613 + (unsigned) val;
> +         else
> +           {
> +             size_t i;
> +             for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
> +               result = result * 613 + (unsigned) (val
> +                                                   >> CHAR_BIT * i);
> +           }
> +         break;
> +       }
>        case '0':
>         break;
>        default:
> diff --git a/gcc/cse.cc b/gcc/cse.cc
> index 6a5fe236bb0..c60a4bca3e3 100644
> --- a/gcc/cse.cc
> +++ b/gcc/cse.cc
> @@ -2534,6 +2534,10 @@ hash_rtx (const_rtx x, machine_mode mode,
>           hash += (unsigned int) XINT (x, i);
>           break;
>
> +       case 'L':
> +         hash += (unsigned int) XLOC (x, i);
> +         break;
> +
>         case 'p':
>           hash += constant_lower_bound (SUBREG_BYTE (x));
>           break;
> @@ -2766,6 +2770,11 @@ exp_equiv_p (const_rtx x, const_rtx y, int validate, 
> bool for_gcse)
>             return false;
>           break;
>
> +       case 'L':
> +         if (XLOC (x, i) != XLOC (y, i))
> +           return false;
> +         break;
> +
>         case 'w':
>           if (XWINT (x, i) != XWINT (y, i))
>             return false;
> diff --git a/gcc/cselib.cc b/gcc/cselib.cc
> index e6a36e892bb..947782b6f6b 100644
> --- a/gcc/cselib.cc
> +++ b/gcc/cselib.cc
> @@ -1122,6 +1122,11 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode 
> memmode, int depth)
>             return false;
>           break;
>
> +       case 'L':
> +         if (XLOC (x, i) != XLOC (y, i))
> +           return false;
> +         break;
> +
>         case 'p':
>           if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
>             return false;
> @@ -1565,6 +1570,10 @@ cselib_hash_rtx (rtx x, int create, machine_mode 
> memmode)
>           hash.add_hwi (XINT (x, i));
>           break;
>
> +       case 'L':
> +         hash.add_hwi (XLOC (x, i));
> +         break;
> +
>         case 'p':
>           hash.add_int (constant_lower_bound (SUBREG_BYTE (x)));
>           break;
> @@ -2079,6 +2088,7 @@ cselib_expand_value_rtx_1 (rtx orig, struct 
> expand_value_data *evd,
>        case 't':
>        case 'w':
>        case 'i':
> +      case 'L':
>        case 's':
>        case 'S':
>        case 'T':
> diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc
> index 9ad0c56f96f..a556692e8a0 100644
> --- a/gcc/emit-rtl.cc
> +++ b/gcc/emit-rtl.cc
> @@ -511,10 +511,10 @@ gen_rtx_INSN_LIST (machine_mode mode, rtx insn, rtx 
> insn_list)
>
>  rtx_insn *
>  gen_rtx_INSN (machine_mode mode, rtx_insn *prev_insn, rtx_insn *next_insn,
> -             basic_block bb, rtx pattern, int location, int code,
> +             basic_block bb, rtx pattern, location_t location, int code,
>               rtx reg_notes)
>  {
> -  return as_a <rtx_insn *> (gen_rtx_fmt_uuBeiie (INSN, mode,
> +  return as_a <rtx_insn *> (gen_rtx_fmt_uuBeLie (INSN, mode,
>                                                  prev_insn, next_insn,
>                                                  bb, pattern, location, code,
>                                                  reg_notes));
> @@ -5892,6 +5892,7 @@ copy_insn_1 (rtx orig)
>        case 't':
>        case 'w':
>        case 'i':
> +      case 'L':
>        case 'p':
>        case 's':
>        case 'S':
> diff --git a/gcc/final.cc b/gcc/final.cc
> index 11141f2b56c..a721622904c 100644
> --- a/gcc/final.cc
> +++ b/gcc/final.cc
> @@ -1542,7 +1542,7 @@ reemit_insn_block_notes (void)
>      set_cur_block_to_this_block:
>        if (! this_block)
>         {
> -         if (INSN_LOCATION (insn) == UNKNOWN_LOCATION)
> +         if (!NOTE_P (insn) && INSN_LOCATION (insn) == UNKNOWN_LOCATION)
>             continue;
>           else
>             this_block = DECL_INITIAL (cfun->decl);
> @@ -4211,6 +4211,7 @@ leaf_renumber_regs_insn (rtx in_rtx)
>        case 's':
>        case '0':
>        case 'i':
> +      case 'L':
>        case 'w':
>        case 'p':
>        case 'n':
> diff --git a/gcc/genattrtab.cc b/gcc/genattrtab.cc
> index 931e06957f2..d67fae627e2 100644
> --- a/gcc/genattrtab.cc
> +++ b/gcc/genattrtab.cc
> @@ -551,6 +551,10 @@ attr_rtx_1 (enum rtx_code code, va_list p)
>               XINT (rt_val, i) = va_arg (p, int);
>               break;
>
> +           case 'L':           /* A location_t?  */
> +             XLOC (rt_val, i) = va_arg (p, location_t);
> +             break;
> +
>             case 'w':           /* A wide integer? */
>               XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
>               break;
> diff --git a/gcc/genemit.cc b/gcc/genemit.cc
> index 5d3d10f5061..82c39e9b59a 100644
> --- a/gcc/genemit.cc
> +++ b/gcc/genemit.cc
> @@ -238,6 +238,10 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char 
> *used, md_rtx_info *info,
>           fprintf (file, "%u", XINT (x, i));
>           break;
>
> +       case 'L':
> +         fprintf (file, "%llu", (unsigned long long) XLOC (x, i));
> +         break;
> +
>         case 'r':
>           fprintf (file, "%u", REGNO (x));
>           break;
> diff --git a/gcc/gengenrtl.cc b/gcc/gengenrtl.cc
> index c9ba471ac20..3da48e7dca9 100644
> --- a/gcc/gengenrtl.cc
> +++ b/gcc/gengenrtl.cc
> @@ -51,6 +51,9 @@ type_from_format (int c)
>      case 'i':
>        return "int ";
>
> +    case 'L':
> +      return "location_t ";
> +
>      case 'w':
>        return "HOST_WIDE_INT ";
>
> @@ -84,6 +87,9 @@ accessor_from_format (int c)
>      case 'i':
>        return "XINT";
>
> +    case 'L':
> +      return "XLOC";
> +
>      case 'w':
>        return "XWINT";
>
> diff --git a/gcc/gengtype.cc b/gcc/gengtype.cc
> index 29f91e30826..25a955fe538 100644
> --- a/gcc/gengtype.cc
> +++ b/gcc/gengtype.cc
> @@ -1254,6 +1254,11 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED 
> (opt))
>               subname = "rt_int";
>               break;
>
> +           case 'L':
> +             t = scalar_tp;
> +             subname = "rt_loc";
> +             break;
> +
>             case 'p':
>               t = scalar_tp;
>               subname = "rt_subreg";
> diff --git a/gcc/genpeep.cc b/gcc/genpeep.cc
> index 9d9e5eb2e8b..ec459616ddd 100644
> --- a/gcc/genpeep.cc
> +++ b/gcc/genpeep.cc
> @@ -273,6 +273,8 @@ match_rtx (rtx x, struct link *path, int fail_label)
>           printf ("  if (XINT (x, %d) != %d) goto L%d;\n",
>                   i, XINT (x, i), fail_label);
>         }
> +      else if (fmt[i] == 'L')
> +       gcc_unreachable ();
>        else if (fmt[i] == 'r')
>         {
>           gcc_assert (i == 0);
> diff --git a/gcc/genrecog.cc b/gcc/genrecog.cc
> index ba09ec3b600..719b1d44387 100644
> --- a/gcc/genrecog.cc
> +++ b/gcc/genrecog.cc
> @@ -388,7 +388,7 @@ find_operand (rtx pattern, int n, rtx stop)
>               return r;
>           break;
>
> -       case 'r': case 'p': case 'i': case 'w': case '0': case 's':
> +       case 'r': case 'p': case 'i': case 'w': case '0': case 's': case 'L':
>           break;
>
>         default:
> @@ -439,7 +439,7 @@ find_matching_operand (rtx pattern, int n)
>               return r;
>           break;
>
> -       case 'r': case 'p': case 'i': case 'w': case '0': case 's':
> +       case 'r': case 'p': case 'i': case 'w': case '0': case 's': case 'L':
>           break;
>
>         default:
> @@ -801,7 +801,7 @@ validate_pattern (rtx pattern, md_rtx_info *info, rtx 
> set, int set_code)
>             validate_pattern (XVECEXP (pattern, i, j), info, NULL_RTX, 0);
>           break;
>
> -       case 'r': case 'p': case 'i': case 'w': case '0': case 's':
> +       case 'r': case 'p': case 'i': case 'w': case '0': case 's': case 'L':
>           break;
>
>         default:
> diff --git a/gcc/gensupport.cc b/gcc/gensupport.cc
> index 3a02132c876..79e45d46217 100644
> --- a/gcc/gensupport.cc
> +++ b/gcc/gensupport.cc
> @@ -1496,7 +1496,7 @@ subst_pattern_match (rtx x, rtx pt, file_location loc)
>
>        switch (fmt[i])
>         {
> -       case 'r': case 'p': case 'i': case 'w': case 's':
> +       case 'r': case 'p': case 'i': case 'w': case 's': case 'L':
>           continue;
>
>         case 'e': case 'u':
> @@ -1662,6 +1662,7 @@ get_alternatives_number (rtx pattern, int *n_alt, 
> file_location loc)
>
>         case 'r': case 'p': case 'i': case 'w':
>         case '0': case 's': case 'S': case 'T':
> +       case 'L':
>           break;
>
>         default:
> @@ -1722,6 +1723,7 @@ collect_insn_data (rtx pattern, int *palt, int *pmax)
>
>         case 'r': case 'p': case 'i': case 'w':
>         case '0': case 's': case 'S': case 'T':
> +       case 'L':
>           break;
>
>         default:
> @@ -1806,7 +1808,7 @@ alter_predicate_for_insn (rtx pattern, int alt, int 
> max_op,
>             }
>           break;
>
> -       case 'r': case 'p': case 'i': case 'w': case '0': case 's':
> +       case 'r': case 'p': case 'i': case 'w': case '0': case 's': case 'L':
>           break;
>
>         default:
> @@ -1867,7 +1869,7 @@ alter_constraints (rtx pattern, int n_dup, 
> constraints_handler_t alter)
>             }
>           break;
>
> -       case 'r': case 'p': case 'i': case 'w': case '0': case 's':
> +       case 'r': case 'p': case 'i': case 'w': case '0': case 's': case 'L':
>           break;
>
>         default:
> @@ -2785,6 +2787,7 @@ subst_dup (rtx pattern, int n_alt, int n_subst_alt)
>
>         case 'r': case 'p': case 'i': case 'w':
>         case '0': case 's': case 'S': case 'T':
> +       case 'L':
>           break;
>
>         default:
> diff --git a/gcc/jump.cc b/gcc/jump.cc
> index 5b9e9ac4722..643c8a07cba 100644
> --- a/gcc/jump.cc
> +++ b/gcc/jump.cc
> @@ -1801,6 +1801,11 @@ rtx_renumbered_equal_p (const_rtx x, const_rtx y)
>
>         case 'i':
>           if (XINT (x, i) != XINT (y, i))
> +           return false;
> +         break;
> +
> +       case 'L':
> +         if (XLOC (x, i) != XLOC (y, i))
>             {
>               if (((code == ASM_OPERANDS && i == 6)
>                    || (code == ASM_INPUT && i == 1)))
> diff --git a/gcc/loop-invariant.cc b/gcc/loop-invariant.cc
> index 4f2bcd158b0..f4347a6f973 100644
> --- a/gcc/loop-invariant.cc
> +++ b/gcc/loop-invariant.cc
> @@ -334,6 +334,8 @@ hash_invariant_expr_1 (rtx_insn *insn, rtx x)
>         }
>        else if (fmt[i] == 'i' || fmt[i] == 'n')
>         val ^= XINT (x, i);
> +      else if (fmt[i] == 'L')
> +       val ^= XLOC (x, i);
>        else if (fmt[i] == 'p')
>         val ^= constant_lower_bound (SUBREG_BYTE (x));
>      }
> diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
> index 61bbb930b7f..319be74b1c9 100644
> --- a/gcc/lra-constraints.cc
> +++ b/gcc/lra-constraints.cc
> @@ -898,6 +898,11 @@ operands_match_p (rtx x, rtx y, int y_hard_regno)
>             return false;
>           break;
>
> +       case 'L':
> +         if (XLOC (x, i) != XLOC (y, i))
> +           return false;
> +         break;
> +
>         case 'p':
>           if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
>             return false;
> diff --git a/gcc/lra.cc b/gcc/lra.cc
> index bc46f56cf20..a84e321519d 100644
> --- a/gcc/lra.cc
> +++ b/gcc/lra.cc
> @@ -1749,6 +1749,10 @@ lra_rtx_hash (rtx x)
>           val += XINT (x, i);
>           break;
>
> +       case 'L':
> +         val += XLOC (x, i);
> +         break;
> +
>         case 'V':
>         case 'E':
>           val += XVECLEN (x, i);
> diff --git a/gcc/print-rtl.cc b/gcc/print-rtl.cc
> index 1688d4ec5c8..7ff737e98ed 100644
> --- a/gcc/print-rtl.cc
> +++ b/gcc/print-rtl.cc
> @@ -436,10 +436,10 @@ rtx_writer::print_rtx_operand_codes_E_and_V (const_rtx 
> in_rtx, int idx)
>    m_indent -= 2;
>  }
>
> -/* Subroutine of print_rtx_operand for handling code 'i'.  */
> +/* Subroutine of print_rtx_operand for handling code 'L'.  */
>
>  void
> -rtx_writer::print_rtx_operand_code_i (const_rtx in_rtx, int idx)
> +rtx_writer::print_rtx_operand_code_L (const_rtx in_rtx, int idx)
>  {
>    if (idx == 4 && INSN_P (in_rtx))
>      {
> @@ -479,7 +479,16 @@ rtx_writer::print_rtx_operand_code_i (const_rtx in_rtx, 
> int idx)
>                  LOCATION_LINE (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
>  #endif
>      }
> -  else if (idx == 5 && NOTE_P (in_rtx))
> +  else
> +    gcc_unreachable ();
> +}
> +
> +/* Subroutine of print_rtx_operand for handling code 'i'.  */
> +
> +void
> +rtx_writer::print_rtx_operand_code_i (const_rtx in_rtx, int idx)
> +{
> +  if (idx == 5 && NOTE_P (in_rtx))
>      {
>        /* This field is only used for NOTE_INSN_DELETED_LABEL, and
>          other times often contains garbage from INSN->NOTE death.  */
> @@ -697,6 +706,10 @@ rtx_writer::print_rtx_operand (const_rtx in_rtx, int idx)
>        print_rtx_operand_code_i (in_rtx, idx);
>        break;
>
> +    case 'L':
> +      print_rtx_operand_code_L (in_rtx, idx);
> +      break;
> +
>      case 'p':
>        fprintf (m_outfile, " ");
>        print_poly_int (m_outfile, SUBREG_BYTE (in_rtx));
> diff --git a/gcc/print-rtl.h b/gcc/print-rtl.h
> index 820f8a5c2bc..f56a452706c 100644
> --- a/gcc/print-rtl.h
> +++ b/gcc/print-rtl.h
> @@ -45,6 +45,7 @@ class rtx_writer
>    void print_rtx_operand_code_e (const_rtx in_rtx, int idx);
>    void print_rtx_operand_codes_E_and_V (const_rtx in_rtx, int idx);
>    void print_rtx_operand_code_i (const_rtx in_rtx, int idx);
> +  void print_rtx_operand_code_L (const_rtx in_rtx, int idx);
>    void print_rtx_operand_code_r (const_rtx in_rtx);
>    void print_rtx_operand_code_u (const_rtx in_rtx, int idx);
>    void print_rtx_operand (const_rtx in_rtx, int idx);
> diff --git a/gcc/read-rtl-function.cc b/gcc/read-rtl-function.cc
> index 51dc11928d0..855fb540b11 100644
> --- a/gcc/read-rtl-function.cc
> +++ b/gcc/read-rtl-function.cc
> @@ -105,7 +105,7 @@ class function_reader : public rtx_reader
>    int parse_enum_value (int num_values, const char *const *strings);
>
>    void read_rtx_operand_u (rtx x, int idx);
> -  void read_rtx_operand_i_or_n (rtx x, int idx, char format_char);
> +  void read_rtx_operand_inL (rtx x, int idx, char format_char);
>    rtx read_rtx_operand_r (rtx x);
>    rtx extra_parsing_for_operand_code_0 (rtx x, int idx);
>
> @@ -903,7 +903,8 @@ function_reader::read_rtx_operand (rtx x, int idx)
>
>      case 'i':
>      case 'n':
> -      read_rtx_operand_i_or_n (x, idx, format_char);
> +    case 'L':
> +      read_rtx_operand_inL (x, idx, format_char);
>        /* Don't run regular parser for these codes.  */
>        return x;
>
> @@ -992,8 +993,7 @@ function_reader::parse_enum_value (int num_values, const 
> char *const *strings)
>     Special-cased handling of these, for reading function dumps.  */
>
>  void
> -function_reader::read_rtx_operand_i_or_n (rtx x, int idx,
> -                                         char format_char)
> +function_reader::read_rtx_operand_inL (rtx x, int idx, char format_char)
>  {
>    /* Handle some of the extra information that print_rtx
>       can write out for these cases.  */
> @@ -1046,7 +1046,10 @@ function_reader::read_rtx_operand_i_or_n (rtx x, int 
> idx,
>    if (format_char == 'n')
>      value = parse_note_insn_name (name.string);
>    else
> -    value = atoi (name.string);
> +    {
> +      gcc_checking_assert (format_char == 'i');
> +      value = atoi (name.string);
> +    }
>    XINT (x, idx) = value;
>  }
>
> diff --git a/gcc/read-rtl.cc b/gcc/read-rtl.cc
> index bfce806f9d6..e6e5c9ecb7e 100644
> --- a/gcc/read-rtl.cc
> +++ b/gcc/read-rtl.cc
> @@ -327,6 +327,9 @@ apply_int_iterator (rtx x, unsigned int index, 
> HOST_WIDE_INT value)
>      case 'n':
>        XINT (x, index) = value;
>        break;
> +    case 'L':
> +      XLOC (x, index) = value;
> +      break;
>      case 'w':
>        XWINT (x, index) = value;
>        break;
> @@ -2048,6 +2051,7 @@ rtx_reader::read_rtx_operand (rtx return_rtx, int idx)
>      case 'n':
>      case 'w':
>      case 'p':
> +    case 'L':
>        {
>         /* Can be an iterator or an integer constant.  */
>         file_location loc = read_name (&name);
> diff --git a/gcc/reload.cc b/gcc/reload.cc
> index 27ca8a57f3c..5707b7fce59 100644
> --- a/gcc/reload.cc
> +++ b/gcc/reload.cc
> @@ -2332,6 +2332,11 @@ operands_match_p (rtx x, rtx y)
>             return 0;
>           break;
>
> +       case 'L':
> +         if (XLOC (x, i) != XLOC (y, i))
> +           return 0;
> +         break;
> +
>         case 'p':
>           if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
>             return 0;
> diff --git a/gcc/rtl.cc b/gcc/rtl.cc
> index dc2c8e02755..cda7a44319c 100644
> --- a/gcc/rtl.cc
> +++ b/gcc/rtl.cc
> @@ -70,6 +70,8 @@ const char * const rtx_format[NUM_RTX_CODE] = {
>       "i" an integer
>           prints the integer
>       "n" like "i", but prints entries from `note_insn_name'
> +     "L" like "i", but correctly sized to hold a location_t,
> +        which may be configured as 32- or 64-bit.
>       "w" an integer of width HOST_BITS_PER_WIDE_INT
>           prints the integer
>       "s" a pointer to a string
> @@ -355,6 +357,7 @@ copy_rtx (rtx orig)
>        case 't':
>        case 'w':
>        case 'i':
> +      case 'L':
>        case 'p':
>        case 's':
>        case 'S':
> @@ -506,15 +509,12 @@ rtx_equal_p (const_rtx x, const_rtx y, 
> rtx_equal_p_callback_function cb)
>         case 'n':
>         case 'i':
>           if (XINT (x, i) != XINT (y, i))
> -           {
> -#ifndef GENERATOR_FILE
> -             if (((code == ASM_OPERANDS && i == 6)
> -                  || (code == ASM_INPUT && i == 1))
> -                 && XINT (x, i) == XINT (y, i))
> -               break;
> -#endif
> -             return false;
> -           }
> +           return false;
> +         break;
> +
> +       case 'L':
> +         if (XLOC (x, i) != XLOC (y, i))
> +           return false;
>           break;
>
>         case 'p':
> diff --git a/gcc/rtl.def b/gcc/rtl.def
> index 6eec284d281..5c0af957942 100644
> --- a/gcc/rtl.def
> +++ b/gcc/rtl.def
> @@ -139,21 +139,21 @@ DEF_RTL_EXPR(ADDRESS, "address", "i", RTX_EXTRA)
>     ---------------------------------------------------------------------- */
>
>  /* An annotation for variable assignment tracking.  */
> -DEF_RTL_EXPR(DEBUG_INSN, "debug_insn", "uuBeiie", RTX_INSN)
> +DEF_RTL_EXPR(DEBUG_INSN, "debug_insn", "uuBeLie", RTX_INSN)
>
>  /* An instruction that cannot jump.  */
> -DEF_RTL_EXPR(INSN, "insn", "uuBeiie", RTX_INSN)
> +DEF_RTL_EXPR(INSN, "insn", "uuBeLie", RTX_INSN)
>
>  /* An instruction that can possibly jump.
>     Fields ( rtx->u.fld[] ) have exact same meaning as INSN's.  */
> -DEF_RTL_EXPR(JUMP_INSN, "jump_insn", "uuBeiie0", RTX_INSN)
> +DEF_RTL_EXPR(JUMP_INSN, "jump_insn", "uuBeLie0", RTX_INSN)
>
>  /* An instruction that can possibly call a subroutine
>     but which will not change which instruction comes next
>     in the current function.
>     Field ( rtx->u.fld[8] ) is CALL_INSN_FUNCTION_USAGE.
>     All other fields ( rtx->u.fld[] ) have exact same meaning as INSN's.  */
> -DEF_RTL_EXPR(CALL_INSN, "call_insn", "uuBeiiee", RTX_INSN)
> +DEF_RTL_EXPR(CALL_INSN, "call_insn", "uuBeLiee", RTX_INSN)
>
>  /* Placeholder for tablejump JUMP_INSNs.  The pattern of this kind
>     of rtx is always either an ADDR_VEC or an ADDR_DIFF_VEC.  These
> @@ -202,7 +202,7 @@ DEF_RTL_EXPR(PARALLEL, "parallel", "E", RTX_EXTRA)
>       These occur in an insn all by themselves as the PATTERN.
>       They also appear inside an ASM_OPERANDS
>       as a convenient way to hold a string.  */
> -DEF_RTL_EXPR(ASM_INPUT, "asm_input", "si", RTX_EXTRA)
> +DEF_RTL_EXPR(ASM_INPUT, "asm_input", "sL", RTX_EXTRA)
>
>  /* An assembler instruction with operands.
>     1st operand is the instruction template.
> @@ -216,7 +216,7 @@ DEF_RTL_EXPR(ASM_INPUT, "asm_input", "si", RTX_EXTRA)
>       and whose mode indicates the mode of the input operand.
>     6th is a vector of labels that may be branched to by the asm.
>     7th is the source line number.  */
> -DEF_RTL_EXPR(ASM_OPERANDS, "asm_operands", "ssiEEEi", RTX_EXTRA)
> +DEF_RTL_EXPR(ASM_OPERANDS, "asm_operands", "ssiEEEL", RTX_EXTRA)
>
>  /* A machine-specific operation.
>     1st operand is a vector of operands being used by the operation so that
> diff --git a/gcc/rtl.h b/gcc/rtl.h
> index f298096a5a6..0369e550573 100644
> --- a/gcc/rtl.h
> +++ b/gcc/rtl.h
> @@ -204,6 +204,7 @@ union rtunion
>  {
>    int rt_int;
>    unsigned int rt_uint;
> +  location_t rt_loc;
>    poly_uint16 rt_subreg;
>    const char *rt_str;
>    rtx rt_rtx;
> @@ -584,7 +585,7 @@ struct GTY(()) rtx_debug_insn : public rtx_insn
>       i.e. an annotation for tracking variable assignments.
>
>       This is an instance of:
> -       DEF_RTL_EXPR(DEBUG_INSN, "debug_insn", "uuBeiie", RTX_INSN)
> +       DEF_RTL_EXPR(DEBUG_INSN, "debug_insn", "uuBeLie", RTX_INSN)
>       from rtl.def.  */
>  };
>
> @@ -595,7 +596,7 @@ struct GTY(()) rtx_nonjump_insn : public rtx_insn
>       i.e an instruction that cannot jump.
>
>       This is an instance of:
> -       DEF_RTL_EXPR(INSN, "insn", "uuBeiie", RTX_INSN)
> +       DEF_RTL_EXPR(INSN, "insn", "uuBeLie", RTX_INSN)
>       from rtl.def.  */
>  };
>
> @@ -607,7 +608,7 @@ public:
>       i.e. an instruction that can possibly jump.
>
>       This is an instance of:
> -       DEF_RTL_EXPR(JUMP_INSN, "jump_insn", "uuBeiie0", RTX_INSN)
> +       DEF_RTL_EXPR(JUMP_INSN, "jump_insn", "uuBeLie0", RTX_INSN)
>       from rtl.def.  */
>
>    /* Returns jump target of this instruction.  The returned value is not
> @@ -635,7 +636,7 @@ struct GTY(()) rtx_call_insn : public rtx_insn
>       in the current function.
>
>       This is an instance of:
> -       DEF_RTL_EXPR(CALL_INSN, "call_insn", "uuBeiiee", RTX_INSN)
> +       DEF_RTL_EXPR(CALL_INSN, "call_insn", "uuBeLiee", RTX_INSN)
>       from rtl.def.  */
>  };
>
> @@ -1347,6 +1348,7 @@ extern void rtl_check_failed_flag (const char *, 
> const_rtx, const char *,
>
>  #define XINT(RTX, N)   (RTL_CHECK2 (RTX, N, 'i', 'n').rt_int)
>  #define XUINT(RTX, N)   (RTL_CHECK2 (RTX, N, 'i', 'n').rt_uint)
> +#define XLOC(RTX, N)    (RTL_CHECK1 (RTX, N, 'L').rt_loc)
>  #define XSTR(RTX, N)   (RTL_CHECK2 (RTX, N, 's', 'S').rt_str)
>  #define XEXP(RTX, N)   (RTL_CHECK2 (RTX, N, 'e', 'u').rt_rtx)
>  #define XVEC(RTX, N)   (RTL_CHECK2 (RTX, N, 'E', 'V').rt_rtvec)
> @@ -1364,6 +1366,7 @@ extern void rtl_check_failed_flag (const char *, 
> const_rtx, const char *,
>
>  #define X0INT(RTX, N)     (RTL_CHECK1 (RTX, N, '0').rt_int)
>  #define X0UINT(RTX, N)    (RTL_CHECK1 (RTX, N, '0').rt_uint)
> +#define X0LOC(RTX, N)     (RTL_CHECK1 (RTX, N, '0').rt_loc)
>  #define X0STR(RTX, N)     (RTL_CHECK1 (RTX, N, '0').rt_str)
>  #define X0EXP(RTX, N)     (RTL_CHECK1 (RTX, N, '0').rt_rtx)
>  #define X0VEC(RTX, N)     (RTL_CHECK1 (RTX, N, '0').rt_rtvec)
> @@ -1380,6 +1383,7 @@ extern void rtl_check_failed_flag (const char *, 
> const_rtx, const char *,
>
>  #define XCINT(RTX, N, C)      (RTL_CHECKC1 (RTX, N, C).rt_int)
>  #define XCUINT(RTX, N, C)     (RTL_CHECKC1 (RTX, N, C).rt_uint)
> +#define XCLOC(RTX, N, C)      (RTL_CHECKC1 (RTX, N, C).rt_loc)
>  #define XCSUBREG(RTX, N, C)   (RTL_CHECKC1 (RTX, N, C).rt_subreg)
>  #define XCSTR(RTX, N, C)      (RTL_CHECKC1 (RTX, N, C).rt_str)
>  #define XCEXP(RTX, N, C)      (RTL_CHECKC1 (RTX, N, C).rt_rtx)
> @@ -1511,14 +1515,14 @@ inline rtx& PATTERN (rtx insn)
>    return XEXP (insn, 3);
>  }
>
> -inline unsigned int INSN_LOCATION (const rtx_insn *insn)
> +inline location_t INSN_LOCATION (const rtx_insn *insn)
>  {
> -  return XUINT (insn, 4);
> +  return XLOC (insn, 4);
>  }
>
> -inline unsigned int& INSN_LOCATION (rtx_insn *insn)
> +inline location_t& INSN_LOCATION (rtx_insn *insn)
>  {
> -  return XUINT (insn, 4);
> +  return XLOC (insn, 4);
>  }
>
>  inline bool INSN_HAS_LOCATION (const rtx_insn *insn)
> @@ -1676,7 +1680,7 @@ extern const char * const reg_note_name[];
>  #define NOTE_EH_HANDLER(INSN)  XCINT (INSN, 3, NOTE)
>  #define NOTE_BASIC_BLOCK(INSN) XCBBDEF (INSN, 3, NOTE)
>  #define NOTE_VAR_LOCATION(INSN)        XCEXP (INSN, 3, NOTE)
> -#define NOTE_MARKER_LOCATION(INSN) XCUINT (INSN, 3, NOTE)
> +#define NOTE_MARKER_LOCATION(INSN) XCLOC (INSN, 3, NOTE)
>  #define NOTE_CFI(INSN)         XCCFI (INSN, 3, NOTE)
>  #define NOTE_LABEL_NUMBER(INSN)        XCINT (INSN, 3, NOTE)
>
> @@ -2610,8 +2614,8 @@ do {                                                    
>                   \
>  #define ASM_OPERANDS_LABEL_VEC(RTX) XCVEC (RTX, 5, ASM_OPERANDS)
>  #define ASM_OPERANDS_LABEL_LENGTH(RTX) XCVECLEN (RTX, 5, ASM_OPERANDS)
>  #define ASM_OPERANDS_LABEL(RTX, N) XCVECEXP (RTX, 5, N, ASM_OPERANDS)
> -#define ASM_OPERANDS_SOURCE_LOCATION(RTX) XCUINT (RTX, 6, ASM_OPERANDS)
> -#define ASM_INPUT_SOURCE_LOCATION(RTX) XCUINT (RTX, 1, ASM_INPUT)
> +#define ASM_OPERANDS_SOURCE_LOCATION(RTX) XCLOC (RTX, 6, ASM_OPERANDS)
> +#define ASM_INPUT_SOURCE_LOCATION(RTX) XCLOC (RTX, 1, ASM_INPUT)
>
>  /* 1 if RTX is a mem that is statically allocated in read-only memory.  */
>  #define MEM_READONLY_P(RTX) \
> @@ -3983,9 +3987,9 @@ get_mem_attrs (const_rtx x)
>  #include "genrtl.h"
>  #undef gen_rtx_ASM_INPUT
>  #define gen_rtx_ASM_INPUT(MODE, ARG0)                          \
> -  gen_rtx_fmt_si (ASM_INPUT, (MODE), (ARG0), 0)
> +  gen_rtx_fmt_sL (ASM_INPUT, (MODE), (ARG0), 0)
>  #define gen_rtx_ASM_INPUT_loc(MODE, ARG0, LOC)                 \
> -  gen_rtx_fmt_si (ASM_INPUT, (MODE), (ARG0), (LOC))
> +  gen_rtx_fmt_sL (ASM_INPUT, (MODE), (ARG0), (LOC))
>  #endif
>
>  /* There are some RTL codes that require special attention; the
> @@ -3996,7 +4000,7 @@ extern rtx_expr_list *gen_rtx_EXPR_LIST (machine_mode, 
> rtx, rtx);
>  extern rtx_insn_list *gen_rtx_INSN_LIST (machine_mode, rtx, rtx);
>  extern rtx_insn *
>  gen_rtx_INSN (machine_mode mode, rtx_insn *prev_insn, rtx_insn *next_insn,
> -             basic_block bb, rtx pattern, int location, int code,
> +             basic_block bb, rtx pattern, location_t location, int code,
>               rtx reg_notes);
>  extern rtx gen_rtx_CONST_INT (machine_mode, HOST_WIDE_INT);
>  extern rtx gen_rtx_CONST_VECTOR (machine_mode, rtvec);
> diff --git a/gcc/rtlhash.cc b/gcc/rtlhash.cc
> index 7d6910f4486..240e56e5ab3 100644
> --- a/gcc/rtlhash.cc
> +++ b/gcc/rtlhash.cc
> @@ -87,6 +87,9 @@ add_rtx (const_rtx x, hash &hstate)
>        case 'i':
>         hstate.add_int (XINT (x, i));
>         break;
> +      case 'L':
> +       hstate.add_hwi (XLOC (x, i));
> +       break;
>        case 'p':
>         hstate.add_poly_int (SUBREG_BYTE (x));
>         break;
> diff --git a/gcc/var-tracking.cc b/gcc/var-tracking.cc
> index 5f1358c1ac2..f07fe723b62 100644
> --- a/gcc/var-tracking.cc
> +++ b/gcc/var-tracking.cc
> @@ -3536,6 +3536,14 @@ loc_cmp (rtx x, rtx y)
>         else
>           return 1;
>
> +      case 'L':
> +       if (XLOC (x, i) == XLOC (y, i))
> +         break;
> +       else if (XLOC (x, i) < XLOC (y, i))
> +         return -1;
> +       else
> +         return 1;
> +
>        case 'p':
>         r = compare_sizes_for_sort (SUBREG_BYTE (x), SUBREG_BYTE (y));
>         if (r != 0)

Reply via email to