Re: [PATCH] Fix arrays in rtx.u + add minor rtx verification
On July 4, 2014 10:50:01 PM CEST, Jakub Jelinek ja...@redhat.com wrote: On Mon, Jun 23, 2014 at 04:40:43PM +0200, Richard Biener wrote: Can we instead refactor expmed.c to avoid allocating rtx_def directly? Like by using rtx in init_expmed_rtl and allocating from an obstack (or not care and GC-allocate anyway). So like this? Bootstrapped/regtested on x86_64-linux and i686-linux, haven't seen any measurable difference in 1000x invocations of null .c file compilations. It is just 18 GC allocations + I ggc_free all of them. Yes. Thanks, Richard. 2014-07-04 Jakub Jelinek ja...@redhat.com * expmed.c (struct init_expmed_rtl): Change all fields but pow2 and cint from struct rtx_def to rtx. (init_expmed_one_conv, init_expmed_one_mode): Adjust for that change. (init_expmed): Likewise. Allocate all the 18 rtxes and ggc_free them at the end again. --- gcc/expmed.c.jj2014-07-03 16:37:50.0 +0200 +++ gcc/expmed.c 2014-07-04 17:23:54.229174101 +0200 @@ -88,24 +88,24 @@ mask_rtx (enum machine_mode mode, int bi struct init_expmed_rtl { - struct rtx_def reg; - struct rtx_def plus; - struct rtx_def neg; - struct rtx_def mult; - struct rtx_def sdiv; - struct rtx_def udiv; - struct rtx_def sdiv_32; - struct rtx_def smod_32; - struct rtx_def wide_mult; - struct rtx_def wide_lshr; - struct rtx_def wide_trunc; - struct rtx_def shift; - struct rtx_def shift_mult; - struct rtx_def shift_add; - struct rtx_def shift_sub0; - struct rtx_def shift_sub1; - struct rtx_def zext; - struct rtx_def trunc; + rtx reg; + rtx plus; + rtx neg; + rtx mult; + rtx sdiv; + rtx udiv; + rtx sdiv_32; + rtx smod_32; + rtx wide_mult; + rtx wide_lshr; + rtx wide_trunc; + rtx shift; + rtx shift_mult; + rtx shift_add; + rtx shift_sub0; + rtx shift_sub1; + rtx zext; + rtx trunc; rtx pow2[MAX_BITS_PER_WORD]; rtx cint[MAX_BITS_PER_WORD]; @@ -127,9 +127,9 @@ init_expmed_one_conv (struct init_expmed - (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)); /* Assume cost of zero-extend and sign-extend is the same. */ - which = (to_size from_size ? all-trunc : all-zext); + which = (to_size from_size ? all-trunc : all-zext); - PUT_MODE (all-reg, from_mode); + PUT_MODE (all-reg, from_mode); set_convert_cost (to_mode, from_mode, speed, set_src_cost (which, speed)); } @@ -142,32 +142,32 @@ init_expmed_one_mode (struct init_expmed mode_bitsize = GET_MODE_UNIT_BITSIZE (mode); - PUT_MODE (all-reg, mode); - PUT_MODE (all-plus, mode); - PUT_MODE (all-neg, mode); - PUT_MODE (all-mult, mode); - PUT_MODE (all-sdiv, mode); - PUT_MODE (all-udiv, mode); - PUT_MODE (all-sdiv_32, mode); - PUT_MODE (all-smod_32, mode); - PUT_MODE (all-wide_trunc, mode); - PUT_MODE (all-shift, mode); - PUT_MODE (all-shift_mult, mode); - PUT_MODE (all-shift_add, mode); - PUT_MODE (all-shift_sub0, mode); - PUT_MODE (all-shift_sub1, mode); - PUT_MODE (all-zext, mode); - PUT_MODE (all-trunc, mode); - - set_add_cost (speed, mode, set_src_cost (all-plus, speed)); - set_neg_cost (speed, mode, set_src_cost (all-neg, speed)); - set_mul_cost (speed, mode, set_src_cost (all-mult, speed)); - set_sdiv_cost (speed, mode, set_src_cost (all-sdiv, speed)); - set_udiv_cost (speed, mode, set_src_cost (all-udiv, speed)); + PUT_MODE (all-reg, mode); + PUT_MODE (all-plus, mode); + PUT_MODE (all-neg, mode); + PUT_MODE (all-mult, mode); + PUT_MODE (all-sdiv, mode); + PUT_MODE (all-udiv, mode); + PUT_MODE (all-sdiv_32, mode); + PUT_MODE (all-smod_32, mode); + PUT_MODE (all-wide_trunc, mode); + PUT_MODE (all-shift, mode); + PUT_MODE (all-shift_mult, mode); + PUT_MODE (all-shift_add, mode); + PUT_MODE (all-shift_sub0, mode); + PUT_MODE (all-shift_sub1, mode); + PUT_MODE (all-zext, mode); + PUT_MODE (all-trunc, mode); + + set_add_cost (speed, mode, set_src_cost (all-plus, speed)); + set_neg_cost (speed, mode, set_src_cost (all-neg, speed)); + set_mul_cost (speed, mode, set_src_cost (all-mult, speed)); + set_sdiv_cost (speed, mode, set_src_cost (all-sdiv, speed)); + set_udiv_cost (speed, mode, set_src_cost (all-udiv, speed)); - set_sdiv_pow2_cheap (speed, mode, (set_src_cost (all-sdiv_32, speed) + set_sdiv_pow2_cheap (speed, mode, (set_src_cost (all-sdiv_32, speed) = 2 * add_cost (speed, mode))); - set_smod_pow2_cheap (speed, mode, (set_src_cost (all-smod_32, speed) + set_smod_pow2_cheap (speed, mode, (set_src_cost (all-smod_32, speed) = 4 * add_cost (speed, mode))); set_shift_cost (speed, mode, 0, 0); @@ -181,13 +181,13 @@ init_expmed_one_mode (struct init_expmed n = MIN (MAX_BITS_PER_WORD, mode_bitsize); for (m = 1; m n; m++) { - XEXP (all-shift, 1) = all-cint[m]; - XEXP (all-shift_mult, 1) = all-pow2[m]; + XEXP (all-shift, 1) = all-cint[m]; + XEXP (all-shift_mult, 1) = all-pow2[m]; - set_shift_cost (speed, mode, m,
Re: [PATCH] Fix arrays in rtx.u + add minor rtx verification
On Mon, Jun 23, 2014 at 04:40:43PM +0200, Richard Biener wrote: Can we instead refactor expmed.c to avoid allocating rtx_def directly? Like by using rtx in init_expmed_rtl and allocating from an obstack (or not care and GC-allocate anyway). So like this? Bootstrapped/regtested on x86_64-linux and i686-linux, haven't seen any measurable difference in 1000x invocations of null .c file compilations. It is just 18 GC allocations + I ggc_free all of them. 2014-07-04 Jakub Jelinek ja...@redhat.com * expmed.c (struct init_expmed_rtl): Change all fields but pow2 and cint from struct rtx_def to rtx. (init_expmed_one_conv, init_expmed_one_mode): Adjust for that change. (init_expmed): Likewise. Allocate all the 18 rtxes and ggc_free them at the end again. --- gcc/expmed.c.jj 2014-07-03 16:37:50.0 +0200 +++ gcc/expmed.c2014-07-04 17:23:54.229174101 +0200 @@ -88,24 +88,24 @@ mask_rtx (enum machine_mode mode, int bi struct init_expmed_rtl { - struct rtx_def reg; - struct rtx_def plus; - struct rtx_def neg; - struct rtx_def mult; - struct rtx_def sdiv; - struct rtx_def udiv; - struct rtx_def sdiv_32; - struct rtx_def smod_32; - struct rtx_def wide_mult; - struct rtx_def wide_lshr; - struct rtx_def wide_trunc; - struct rtx_def shift; - struct rtx_def shift_mult; - struct rtx_def shift_add; - struct rtx_def shift_sub0; - struct rtx_def shift_sub1; - struct rtx_def zext; - struct rtx_def trunc; + rtx reg; + rtx plus; + rtx neg; + rtx mult; + rtx sdiv; + rtx udiv; + rtx sdiv_32; + rtx smod_32; + rtx wide_mult; + rtx wide_lshr; + rtx wide_trunc; + rtx shift; + rtx shift_mult; + rtx shift_add; + rtx shift_sub0; + rtx shift_sub1; + rtx zext; + rtx trunc; rtx pow2[MAX_BITS_PER_WORD]; rtx cint[MAX_BITS_PER_WORD]; @@ -127,9 +127,9 @@ init_expmed_one_conv (struct init_expmed - (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)); /* Assume cost of zero-extend and sign-extend is the same. */ - which = (to_size from_size ? all-trunc : all-zext); + which = (to_size from_size ? all-trunc : all-zext); - PUT_MODE (all-reg, from_mode); + PUT_MODE (all-reg, from_mode); set_convert_cost (to_mode, from_mode, speed, set_src_cost (which, speed)); } @@ -142,32 +142,32 @@ init_expmed_one_mode (struct init_expmed mode_bitsize = GET_MODE_UNIT_BITSIZE (mode); - PUT_MODE (all-reg, mode); - PUT_MODE (all-plus, mode); - PUT_MODE (all-neg, mode); - PUT_MODE (all-mult, mode); - PUT_MODE (all-sdiv, mode); - PUT_MODE (all-udiv, mode); - PUT_MODE (all-sdiv_32, mode); - PUT_MODE (all-smod_32, mode); - PUT_MODE (all-wide_trunc, mode); - PUT_MODE (all-shift, mode); - PUT_MODE (all-shift_mult, mode); - PUT_MODE (all-shift_add, mode); - PUT_MODE (all-shift_sub0, mode); - PUT_MODE (all-shift_sub1, mode); - PUT_MODE (all-zext, mode); - PUT_MODE (all-trunc, mode); - - set_add_cost (speed, mode, set_src_cost (all-plus, speed)); - set_neg_cost (speed, mode, set_src_cost (all-neg, speed)); - set_mul_cost (speed, mode, set_src_cost (all-mult, speed)); - set_sdiv_cost (speed, mode, set_src_cost (all-sdiv, speed)); - set_udiv_cost (speed, mode, set_src_cost (all-udiv, speed)); + PUT_MODE (all-reg, mode); + PUT_MODE (all-plus, mode); + PUT_MODE (all-neg, mode); + PUT_MODE (all-mult, mode); + PUT_MODE (all-sdiv, mode); + PUT_MODE (all-udiv, mode); + PUT_MODE (all-sdiv_32, mode); + PUT_MODE (all-smod_32, mode); + PUT_MODE (all-wide_trunc, mode); + PUT_MODE (all-shift, mode); + PUT_MODE (all-shift_mult, mode); + PUT_MODE (all-shift_add, mode); + PUT_MODE (all-shift_sub0, mode); + PUT_MODE (all-shift_sub1, mode); + PUT_MODE (all-zext, mode); + PUT_MODE (all-trunc, mode); + + set_add_cost (speed, mode, set_src_cost (all-plus, speed)); + set_neg_cost (speed, mode, set_src_cost (all-neg, speed)); + set_mul_cost (speed, mode, set_src_cost (all-mult, speed)); + set_sdiv_cost (speed, mode, set_src_cost (all-sdiv, speed)); + set_udiv_cost (speed, mode, set_src_cost (all-udiv, speed)); - set_sdiv_pow2_cheap (speed, mode, (set_src_cost (all-sdiv_32, speed) + set_sdiv_pow2_cheap (speed, mode, (set_src_cost (all-sdiv_32, speed) = 2 * add_cost (speed, mode))); - set_smod_pow2_cheap (speed, mode, (set_src_cost (all-smod_32, speed) + set_smod_pow2_cheap (speed, mode, (set_src_cost (all-smod_32, speed) = 4 * add_cost (speed, mode))); set_shift_cost (speed, mode, 0, 0); @@ -181,13 +181,13 @@ init_expmed_one_mode (struct init_expmed n = MIN (MAX_BITS_PER_WORD, mode_bitsize); for (m = 1; m n; m++) { - XEXP (all-shift, 1) = all-cint[m]; - XEXP (all-shift_mult, 1) = all-pow2[m]; + XEXP (all-shift, 1) = all-cint[m]; + XEXP (all-shift_mult, 1) = all-pow2[m]; - set_shift_cost (speed, mode, m, set_src_cost (all-shift, speed)); - set_shiftadd_cost (speed, mode, m,
Re: [PATCH] Fix arrays in rtx.u + add minor rtx verification
On 06/20/2014 01:42 PM, Marek Polacek wrote: 2014-06-20 Marek Polacek pola...@redhat.com * genpreds.c (verify_rtx_codes): New function. (main): Call it. * rtl.h (RTX_FLD_WIDTH, RTX_HWINT_WIDTH): Define. (struct rtx_def): Use them. Looks pretty good. Just a few nits. +static void +verify_rtx_codes (void) +{ + unsigned int i, j; + + for (i = 0; i NUM_RTX_CODE; i++) +if (strchr (GET_RTX_FORMAT (i), 'w') == NULL) + { + if (strlen (GET_RTX_FORMAT (i)) RTX_FLD_WIDTH) + internal_error (%s format %s longer than RTX_FLD_WIDTH %d\n, + GET_RTX_NAME (i), GET_RTX_FORMAT (i), + (int) RTX_FLD_WIDTH); + } +else + { + const size_t len = strlen (GET_RTX_FORMAT (i)); The strlen result is used in both arms of the if. Tidier to hoist it, I think. + for (j = 0; j len; j++) + if (GET_RTX_FORMAT (i)[j] != 'w') + internal_error (%s format %s should contain only w, but + has %c\n, GET_RTX_NAME (i), GET_RTX_FORMAT (i), + GET_RTX_FORMAT (i)[j]); The loop is strspn. Perhaps tidier as const size_t spn = strspn(GET_RTX_FORMAT (i), w); if (spn != len) internal_error (...); r~
Re: [PATCH] Fix arrays in rtx.u + add minor rtx verification
On Mon, Jun 23, 2014 at 4:25 PM, Richard Henderson r...@redhat.com wrote: On 06/20/2014 01:42 PM, Marek Polacek wrote: 2014-06-20 Marek Polacek pola...@redhat.com * genpreds.c (verify_rtx_codes): New function. (main): Call it. * rtl.h (RTX_FLD_WIDTH, RTX_HWINT_WIDTH): Define. (struct rtx_def): Use them. Looks pretty good. Just a few nits. +static void +verify_rtx_codes (void) +{ + unsigned int i, j; + + for (i = 0; i NUM_RTX_CODE; i++) +if (strchr (GET_RTX_FORMAT (i), 'w') == NULL) + { + if (strlen (GET_RTX_FORMAT (i)) RTX_FLD_WIDTH) + internal_error (%s format %s longer than RTX_FLD_WIDTH %d\n, + GET_RTX_NAME (i), GET_RTX_FORMAT (i), + (int) RTX_FLD_WIDTH); + } +else + { + const size_t len = strlen (GET_RTX_FORMAT (i)); The strlen result is used in both arms of the if. Tidier to hoist it, I think. + for (j = 0; j len; j++) + if (GET_RTX_FORMAT (i)[j] != 'w') + internal_error (%s format %s should contain only w, but + has %c\n, GET_RTX_NAME (i), GET_RTX_FORMAT (i), + GET_RTX_FORMAT (i)[j]); The loop is strspn. Perhaps tidier as const size_t spn = strspn(GET_RTX_FORMAT (i), w); if (spn != len) internal_error (...); Note that RTX_HWINT_WIDTH is wrong because of CONST_WIDE_INT. Also I don't like increasing the array sizes - this is wrong in the same way as [1] is. Can we instead refactor expmed.c to avoid allocating rtx_def directly? Like by using rtx in init_expmed_rtl and allocating from an obstack (or not care and GC-allocate anyway). Richard. r~
Re: [PATCH] Fix arrays in rtx.u + add minor rtx verification
On Fri, Jun 20, 2014 at 07:36:41PM +0200, Marek Polacek wrote: 2014-06-20 Marek Polacek pola...@redhat.com * genpreds.c (verify_rtx_codes): New function. (main): Call it. * rtl.h (RTX_FLD_WIDTH, RTX_HWINT_WIDTH): Define. (struct rtx_def): Use them. Note, e.g. Coverity also complains about this stuff loudly too, apparently not just in the problematic case where rtx_def is used in a middle of structure, but also when used in flexible array like spot. Most RTLs are allocated through rtx_alloc and the size is determined from RTX_HDR_SIZE (i.e. offsetof) and/or RTX_CODE_SIZE, so your rtl.h change IMHO shouldn't affect anything but make the expmed.c init_expmed_rtl structure somewhat longer. --- gcc/genpreds.c +++ gcc/genpreds.c @@ -1471,6 +1471,40 @@ parse_option (const char *opt) return 0; } +/* Verify RTX codes. We can't call fatal_error here, so call + gcc_unreachable after error to really abort. */ + +static void +verify_rtx_codes (void) +{ + unsigned int i, j; + + for (i = 0; i NUM_RTX_CODE; i++) +if (strchr (GET_RTX_FORMAT (i), 'w') == NULL) + { + if (strlen (GET_RTX_FORMAT (i)) RTX_FLD_WIDTH) + { + error (insufficient size of RTX_FLD_WIDTH); + gcc_unreachable (); I think it would be nice to be more verbose, i.e. say which rtx has longer format string than RTX_FLD_WIDTH, and perhaps also the size and RTX_FLD_WIDTH value. Also, can't you use internal_error instead of error + gcc_unreachable ? So perhaps internal_error (%s format %s longer than RTX_FLD_WIDTH %d\n, GET_RTX_NAME (i), GET_RTX_FORMAT (i), (int) RTX_FLD_WIDTH); ? + } + } +else + { + const size_t len = strlen (GET_RTX_FORMAT (i)); + for (j = 0; j len; j++) + if (GET_RTX_FORMAT (i)[j] != 'w') + { + error (rtx format does not contain only hwint entries); + gcc_unreachable (); + } + if (len RTX_HWINT_WIDTH) + { + error (insufficient size of RTL_MAX_HWINT_WIDTH); + gcc_unreachable (); + } + } And similarly here. Otherwise, LGTM, but as I've been discussing this with Marek, I'd prefer somebody else to review it. Jakub
Re: [PATCH] Fix arrays in rtx.u + add minor rtx verification
On 06/20/14 13:01, Jakub Jelinek wrote: On Fri, Jun 20, 2014 at 07:36:41PM +0200, Marek Polacek wrote: 2014-06-20 Marek Polacek pola...@redhat.com * genpreds.c (verify_rtx_codes): New function. (main): Call it. * rtl.h (RTX_FLD_WIDTH, RTX_HWINT_WIDTH): Define. (struct rtx_def): Use them. Note, e.g. Coverity also complains about this stuff loudly too, Yes it does. IIRC, these warnings from Coverity were the cause of GCC reaching the #1 or #2 position across Red Hat's packages in terms of Coverity warnings. Not a good position to be in. like spot. Most RTLs are allocated through rtx_alloc and the size is determined from RTX_HDR_SIZE (i.e. offsetof) and/or RTX_CODE_SIZE, so your rtl.h change IMHO shouldn't affect anything but make the expmed.c init_expmed_rtl structure somewhat longer. Right. This comment was actually very helpful in that I wasn't aware of precisely which cases Marek was trying to address. Presumably the [1] sizing is what prevents any compile-time checking of this? No strong opinion on the internal_error vs error+unreachable. --- gcc/genpreds.c +++ gcc/genpreds.c @@ -1471,6 +1471,40 @@ parse_option (const char *opt) return 0; } +/* Verify RTX codes. We can't call fatal_error here, so call + gcc_unreachable after error to really abort. */ + +static void +verify_rtx_codes (void) +{ + unsigned int i, j; + + for (i = 0; i NUM_RTX_CODE; i++) +if (strchr (GET_RTX_FORMAT (i), 'w') == NULL) + { + if (strlen (GET_RTX_FORMAT (i)) RTX_FLD_WIDTH) + { + error (insufficient size of RTX_FLD_WIDTH); + gcc_unreachable (); I think it would be nice to be more verbose, i.e. say which rtx has longer format string than RTX_FLD_WIDTH, and perhaps also the size and RTX_FLD_WIDTH value. Also, can't you use internal_error instead of error + gcc_unreachable ? Agreed, definitely indicate which RTX code is problematical. Jeff
Re: [PATCH] Fix arrays in rtx.u + add minor rtx verification
On Fri, Jun 20, 2014 at 09:01:14PM +0200, Jakub Jelinek wrote: On Fri, Jun 20, 2014 at 07:36:41PM +0200, Marek Polacek wrote: 2014-06-20 Marek Polacek pola...@redhat.com * genpreds.c (verify_rtx_codes): New function. (main): Call it. * rtl.h (RTX_FLD_WIDTH, RTX_HWINT_WIDTH): Define. (struct rtx_def): Use them. Note, e.g. Coverity also complains about this stuff loudly too, apparently not just in the problematic case where rtx_def is used in a middle of structure, but also when used in flexible array like spot. Most RTLs are allocated through rtx_alloc and the size is determined from RTX_HDR_SIZE (i.e. offsetof) and/or RTX_CODE_SIZE, so your rtl.h change IMHO shouldn't affect anything but make the expmed.c init_expmed_rtl structure somewhat longer. --- gcc/genpreds.c +++ gcc/genpreds.c @@ -1471,6 +1471,40 @@ parse_option (const char *opt) return 0; } +/* Verify RTX codes. We can't call fatal_error here, so call + gcc_unreachable after error to really abort. */ + +static void +verify_rtx_codes (void) +{ + unsigned int i, j; + + for (i = 0; i NUM_RTX_CODE; i++) +if (strchr (GET_RTX_FORMAT (i), 'w') == NULL) + { + if (strlen (GET_RTX_FORMAT (i)) RTX_FLD_WIDTH) + { + error (insufficient size of RTX_FLD_WIDTH); + gcc_unreachable (); I think it would be nice to be more verbose, i.e. say which rtx has longer format string than RTX_FLD_WIDTH, and perhaps also the size and RTX_FLD_WIDTH value. Also, can't you use internal_error instead of error + gcc_unreachable ? So perhaps internal_error (%s format %s longer than RTX_FLD_WIDTH %d\n, GET_RTX_NAME (i), GET_RTX_FORMAT (i), (int) RTX_FLD_WIDTH); ? Ok, that's much better. I actually can use internal_error - we have that function in both diagnostic.c and errors.c, while fatal_error is only in diagnostic.c. + } + } +else + { + const size_t len = strlen (GET_RTX_FORMAT (i)); + for (j = 0; j len; j++) + if (GET_RTX_FORMAT (i)[j] != 'w') + { + error (rtx format does not contain only hwint entries); + gcc_unreachable (); + } + if (len RTX_HWINT_WIDTH) + { + error (insufficient size of RTL_MAX_HWINT_WIDTH); + gcc_unreachable (); + } + } And similarly here. Fixed. Otherwise, LGTM, but as I've been discussing this with Marek, I'd prefer somebody else to review it. Sure. So can anybody look at this, please? 2014-06-20 Marek Polacek pola...@redhat.com * genpreds.c (verify_rtx_codes): New function. (main): Call it. * rtl.h (RTX_FLD_WIDTH, RTX_HWINT_WIDTH): Define. (struct rtx_def): Use them. diff --git gcc/genpreds.c gcc/genpreds.c index b14a4ac..7e62124 100644 --- gcc/genpreds.c +++ gcc/genpreds.c @@ -1471,6 +1471,36 @@ parse_option (const char *opt) return 0; } +/* Verify RTX codes. */ + +static void +verify_rtx_codes (void) +{ + unsigned int i, j; + + for (i = 0; i NUM_RTX_CODE; i++) +if (strchr (GET_RTX_FORMAT (i), 'w') == NULL) + { + if (strlen (GET_RTX_FORMAT (i)) RTX_FLD_WIDTH) + internal_error (%s format %s longer than RTX_FLD_WIDTH %d\n, + GET_RTX_NAME (i), GET_RTX_FORMAT (i), + (int) RTX_FLD_WIDTH); + } +else + { + const size_t len = strlen (GET_RTX_FORMAT (i)); + for (j = 0; j len; j++) + if (GET_RTX_FORMAT (i)[j] != 'w') + internal_error (%s format %s should contain only w, but + has %c\n, GET_RTX_NAME (i), GET_RTX_FORMAT (i), + GET_RTX_FORMAT (i)[j]); + if (len RTX_HWINT_WIDTH) + internal_error (%s format %s longer than RTX_HWINT_WIDTH %d\n, + GET_RTX_NAME (i), GET_RTX_FORMAT (i), + (int) RTX_HWINT_WIDTH); + } +} + /* Master control. */ int main (int argc, char **argv) @@ -1518,5 +1548,7 @@ main (int argc, char **argv) if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout)) return FATAL_EXIT_CODE; + verify_rtx_codes (); + return SUCCESS_EXIT_CODE; } diff --git gcc/rtl.h gcc/rtl.h index 6ec91a8..3f2e774 100644 --- gcc/rtl.h +++ gcc/rtl.h @@ -264,6 +264,12 @@ struct GTY((variable_size)) hwivec_def { #define CWI_PUT_NUM_ELEM(RTX, NUM) \ (RTL_FLAG_CHECK1(CWI_PUT_NUM_ELEM, (RTX), CONST_WIDE_INT)-u2.num_elem = (NUM)) +/* The maximum number of entries in the FLD array in rtx. */ +#define RTX_FLD_WIDTH 8 + +/* The maximum number of entries in the HWINT array in rtx. */ +#define RTX_HWINT_WIDTH (MAX (REAL_WIDTH, 3)) + /* RTL expression (rtx). */ struct GTY((chain_next (RTX_NEXT (%h)), @@ -378,8 +384,8 @@ struct GTY((chain_next (RTX_NEXT (%h)), The number of operands and
Re: [PATCH] Fix arrays in rtx.u + add minor rtx verification
On Fri, Jun 20, 2014 at 01:55:41PM -0600, Jeff Law wrote: like spot. Most RTLs are allocated through rtx_alloc and the size is determined from RTX_HDR_SIZE (i.e. offsetof) and/or RTX_CODE_SIZE, so your rtl.h change IMHO shouldn't affect anything but make the expmed.c init_expmed_rtl structure somewhat longer. Right. This comment was actually very helpful in that I wasn't aware of precisely which cases Marek was trying to address. Presumably the [1] sizing is what prevents any compile-time checking of this? First version of Marek's patch did that (never instrumented [], [0] and [1] arrays, no matter where they appeared, and instrumented everything else). Latest patch only never instruments [] (which, by definition can only appear at the end of structure), other arrays (no matter what size) aren't instrumented if they aren't followed by any fields, or if the base of the handled components is not INDIRECT_REF/MEM_REF (so, typically is a decl). u.fld[1] array is the last field, so we don't warn for that, but when rtx_def appears in another structure (in expmed.c) or if e.g. even some code had a rtx_def typed variable and accessed say u.fld[1] in there, it would be instrumented. Whether we should have a strict array bounds mode where we would instrument even arrays at the end of structures (with the exception of []) is something to be discussed. Jakub
Re: [PATCH] Fix arrays in rtx.u + add minor rtx verification
On Fri, Jun 20, 2014 at 11:10:18PM +0200, Jakub Jelinek wrote: On Fri, Jun 20, 2014 at 01:55:41PM -0600, Jeff Law wrote: like spot. Most RTLs are allocated through rtx_alloc and the size is determined from RTX_HDR_SIZE (i.e. offsetof) and/or RTX_CODE_SIZE, so your rtl.h change IMHO shouldn't affect anything but make the expmed.c init_expmed_rtl structure somewhat longer. Right. This comment was actually very helpful in that I wasn't aware of precisely which cases Marek was trying to address. Presumably the [1] sizing is what prevents any compile-time checking of this? First version of Marek's patch did that (never instrumented [], [0] and [1] arrays, no matter where they appeared, and instrumented everything else). Latest patch only never instruments [] (which, by definition can only appear at the end of structure), other arrays (no matter what size) aren't instrumented if they aren't followed by any fields, or if the base of the handled components is not INDIRECT_REF/MEM_REF (so, typically is a decl). u.fld[1] array is the last field, so we don't warn for that, but when rtx_def appears in another structure (in expmed.c) or if e.g. even some code had a rtx_def typed variable and accessed say u.fld[1] in there, it would be instrumented. Yeah - init_expmed in expmed.c has XEXP (all.plus, 1) = all.reg; which is expanded to (((all.plus)-u.fld[1]).rt_rtx) = all.reg; but since the expression (A)-B is the same as A.B (if A is a valid pointer expression), the above was turned into all.plus.u.fld[1].rt_rtx) = all.reg; and that doesn't contain any INDIRECT_REF/MEM_REFs - it's being instrumented. With this patch I don't see any -fsanitize=bounds errors when doing bootstrap-ubsan. Whether we should have a strict array bounds mode where we would instrument even arrays at the end of structures (with the exception of []) is something to be discussed. This should be basically just about adding a new option - e.g. -fsanitize=bounds-strict. Marek