On Aug 29, 2013, at 12:36 AM, Richard Biener <rguent...@suse.de> wrote: > On Wed, 28 Aug 2013, Mike Stump wrote: > >> On Aug 28, 2013, at 3:22 AM, Richard Biener <rguent...@suse.de> wrote: >>> Btw, rtl.h still wastes space with >>> >>> struct GTY((variable_size)) hwivec_def { >>> int num_elem; /* number of elements */ >>> HOST_WIDE_INT elem[1]; >>> }; >>> >>> struct GTY((chain_next ("RTX_NEXT (&%h)"), >>> chain_prev ("RTX_PREV (&%h)"), variable_size)) rtx_def { >>> ... >>> /* The first element of the operands of this rtx. >>> The number of operands and their types are controlled >>> by the `code' field, according to rtl.def. */ >>> union u { >>> rtunion fld[1]; >>> HOST_WIDE_INT hwint[1]; >>> struct block_symbol block_sym; >>> struct real_value rv; >>> struct fixed_value fv; >>> struct hwivec_def hwiv; >>> } GTY ((special ("rtx_def"), desc ("GET_CODE (&%0)"))) u; >>> }; >>> >>> there are 32bits available before the union. If you don't use >>> those for num_elem then all wide-ints will at least take as >>> much space as DOUBLE_INTs originally took - and large ints >>> that would have required DOUBLE_INTs in the past will now >>> require more space than before. Which means your math >>> motivating the 'num_elem' encoding stuff is wrong. With >>> moving 'num_elem' before u you can even re-use the hwint >>> field in the union as the existing double-int code does >>> (which in fact could simply do the encoding trick in the >>> old CONST_DOUBLE scheme, similar for the tree INTEGER_CST >>> container). >> >> So, HOST_WIDE_INT is likely 64 bits, and likely is 64 bit aligned. The >> base (stuff before the union) is 32 bits. There is a 32 bit gap, even >> if not used before the HOST_WIDE_INT elem. We place the num_elem is >> this gap. > > No, you don't. You place num_elem 64bit aligned _after_ the gap. > And you have another 32bit gap, as you say, before elem.
Ah, ok, I get it, thanks for the explanation. This removes the second gap creator and puts the field into the gap before the u union.
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index ce40347..143f298 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -594,7 +594,7 @@ immed_wide_int_const (const wide_int &v, enum machine_mode mode) /* It is so tempting to just put the mode in here. Must control myself ... */ PUT_MODE (value, VOIDmode); - HWI_PUT_NUM_ELEM (CONST_WIDE_INT_VEC (value), len); + CWI_PUT_NUM_ELEM (value, len); for (i = 0; i < len; i++) CONST_WIDE_INT_ELT (value, i) = v.elt (i); diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c index 3620bd6..8dad9f6 100644 --- a/gcc/print-rtl.c +++ b/gcc/print-rtl.c @@ -616,7 +616,7 @@ print_rtx (const_rtx in_rtx) case CONST_WIDE_INT: if (! flag_simple) fprintf (outfile, " "); - hwivec_output_hex (outfile, CONST_WIDE_INT_VEC (in_rtx)); + cwi_output_hex (outfile, in_rtx); break; #endif diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c index 707ef3f..c198b5b 100644 --- a/gcc/read-rtl.c +++ b/gcc/read-rtl.c @@ -1352,7 +1352,6 @@ read_rtx_code (const char *code_name) read_name (&name); validate_const_wide_int (name.string); { - hwivec hwiv; const char *s = name.string; int len; int index = 0; @@ -1377,7 +1376,6 @@ read_rtx_code (const char *code_name) return_rtx = const_wide_int_alloc (wlen); - hwiv = CONST_WIDE_INT_VEC (return_rtx); while (pos > 0) { #if HOST_BITS_PER_WIDE_INT == 64 @@ -1385,13 +1383,13 @@ read_rtx_code (const char *code_name) #else sscanf (s + pos, "%8" HOST_WIDE_INT_PRINT "x", &wi); #endif - XHWIVEC_ELT (hwiv, index++) = wi; + CWI_ELT (return_rtx, index++) = wi; pos -= gs; } strncpy (buf, s, gs - pos); buf [gs - pos] = 0; sscanf (buf, "%" HOST_WIDE_INT_PRINT "x", &wi); - XHWIVEC_ELT (hwiv, index++) = wi; + CWI_ELT (return_rtx, index++) = wi; /* TODO: After reading, do we want to canonicalize with: value = lookup_const_wide_int (value); ? */ } diff --git a/gcc/rtl.c b/gcc/rtl.c index 074e425..b913d0d 100644 --- a/gcc/rtl.c +++ b/gcc/rtl.c @@ -225,18 +225,18 @@ rtx_alloc_stat (RTX_CODE code MEM_STAT_DECL) return rtx_alloc_stat_v (code PASS_MEM_STAT, 0); } -/* Write the wide constant OP0 to OUTFILE. */ +/* Write the wide constant X to OUTFILE. */ void -hwivec_output_hex (FILE *outfile, const_hwivec op0) +cwi_output_hex (FILE *outfile, const_rtx x) { - int i = HWI_GET_NUM_ELEM (op0); + int i = CWI_GET_NUM_ELEM (x); gcc_assert (i > 0); - if (XHWIVEC_ELT (op0, i-1) == 0) + if (CWI_ELT (x, i-1) == 0) fprintf (outfile, "0x"); - fprintf (outfile, HOST_WIDE_INT_PRINT_HEX, XHWIVEC_ELT (op0, --i)); + fprintf (outfile, HOST_WIDE_INT_PRINT_HEX, CWI_ELT (x, --i)); while (--i >= 0) - fprintf (outfile, HOST_WIDE_INT_PRINT_PADDED_HEX, XHWIVEC_ELT (op0, i)); + fprintf (outfile, HOST_WIDE_INT_PRINT_PADDED_HEX, CWI_ELT (x, i)); } @@ -843,12 +843,12 @@ rtl_check_failed_block_symbol (const char *file, int line, const char *func) /* XXX Maybe print the vector? */ void -hwivec_check_failed_bounds (const_hwivec r, int n, const char *file, int line, - const char *func) +cwi_check_failed_bounds (const_rtx x, int n, const char *file, int line, + const char *func) { internal_error ("RTL check: access of hwi elt %d of vector with last elt %d in %s, at %s:%d", - n, GET_NUM_ELEM (r) - 1, func, trim_filename (file), line); + n, CWI_GET_NUM_ELEM (x) - 1, func, trim_filename (file), line); } /* XXX Maybe print the vector? */ diff --git a/gcc/rtl.h b/gcc/rtl.h index 6b45b41..a218ee9 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -252,12 +252,14 @@ struct GTY(()) object_block { }; struct GTY((variable_size)) hwivec_def { - int num_elem; /* number of elements */ HOST_WIDE_INT elem[1]; }; -#define HWI_GET_NUM_ELEM(HWIVEC) ((HWIVEC)->num_elem) -#define HWI_PUT_NUM_ELEM(HWIVEC, NUM) ((HWIVEC)->num_elem = (NUM)) +/* Number of elements of the HWIVEC if RTX is a CONST_WIDE_INT. */ +#define CWI_GET_NUM_ELEM(RTX) \ + ((int)RTL_FLAG_CHECK1("CWI_GET_NUM_ELEM", (RTX), CONST_WIDE_INT)->u2.num_elem) +#define CWI_PUT_NUM_ELEM(RTX, NUM) \ + (RTL_FLAG_CHECK1("CWI_PUT_NUM_ELEM", (RTX), CONST_WIDE_INT)->u2.num_elem = (NUM)) /* RTL expression ("rtx"). */ @@ -345,6 +347,14 @@ struct GTY((chain_next ("RTX_NEXT (&%h)"), 1 in a VALUE or DEBUG_EXPR is NO_LOC_P in var-tracking.c. */ unsigned return_val : 1; + union { + /* RTXs are free to use up to 32 bit from here. */ + + /* In a CONST_WIDE_INT (aka hwivec_def), this is the number of HOST_WIDE_INTs + in the hwivec_def. */ + unsigned GTY ((tag ("CONST_WIDE_INT"))) num_elem:32; + } GTY ((desc ("GET_CODE (&%0)"))) u2; + /* The first element of the operands of this rtx. The number of operands and their types are controlled by the `code' field, according to rtl.def. */ @@ -643,12 +653,14 @@ equality. */ __FUNCTION__); \ &_rtx->u.hwint[_n]; })) -#define XHWIVEC_ELT(HWIVEC, I) __extension__ \ -(*({ __typeof (HWIVEC) const _hwivec = (HWIVEC); const int _i = (I); \ - if (_i < 0 || _i >= HWI_GET_NUM_ELEM (_hwivec)) \ - hwivec_check_failed_bounds (_hwivec, _i, __FILE__, __LINE__, \ - __FUNCTION__); \ - &_hwivec->elem[_i]; })) +#define CWI_ELT(RTX, I) __extension__ \ +(*({ __typeof (RTX) const _rtx = (RTX); \ + int _max = CWI_GET_NUM_ELEM (_rtx); \ + const int _i = (I); \ + if (_i < 0 || _i >= _max) \ + cwi_check_failed_bounds (_rtx, _i, __FILE__, __LINE__, \ + __FUNCTION__); \ + &_rtx->u.hwiv.elem[_i]; })) #define XCWINT(RTX, N, C) __extension__ \ (*({ __typeof (RTX) const _rtx = (RTX); \ @@ -711,8 +723,8 @@ extern void rtl_check_failed_code_mode (const_rtx, enum rtx_code, enum machine_m ATTRIBUTE_NORETURN; extern void rtl_check_failed_block_symbol (const char *, int, const char *) ATTRIBUTE_NORETURN; -extern void hwivec_check_failed_bounds (const_hwivec, int, const char *, int, - const char *) +extern void cwi_check_failed_bounds (const_rtx, int, const char *, int, + const char *) ATTRIBUTE_NORETURN; extern void rtvec_check_failed_bounds (const_rtvec, int, const char *, int, const char *) @@ -726,7 +738,7 @@ extern void rtvec_check_failed_bounds (const_rtvec, int, const char *, int, #define RTL_CHECKC2(RTX, N, C1, C2) ((RTX)->u.fld[N]) #define RTVEC_ELT(RTVEC, I) ((RTVEC)->elem[I]) #define XWINT(RTX, N) ((RTX)->u.hwint[N]) -#define XHWIVEC_ELT(HWIVEC, I) ((HWIVEC)->elem[I]) +#define CWI_ELT(RTX, I) ((RTX)->u.hwiv.elem[I]) #define XCWINT(RTX, N, C) ((RTX)->u.hwint[N]) #define XCMWINT(RTX, N, C, M) ((RTX)->u.hwint[N]) #define XCNMWINT(RTX, N, C, M) ((RTX)->u.hwint[N]) @@ -1223,8 +1235,8 @@ rhs_regno (const_rtx x) CONST_WIDE_INT_ELT gets one of the elements. 0 is the least significant HOST_WIDE_INT. */ #define CONST_WIDE_INT_VEC(RTX) HWIVEC_CHECK (RTX, CONST_WIDE_INT) -#define CONST_WIDE_INT_NUNITS(RTX) HWI_GET_NUM_ELEM (CONST_WIDE_INT_VEC (RTX)) -#define CONST_WIDE_INT_ELT(RTX, N) XHWIVEC_ELT (CONST_WIDE_INT_VEC (RTX), N) +#define CONST_WIDE_INT_NUNITS(RTX) CWI_GET_NUM_ELEM (RTX) +#define CONST_WIDE_INT_ELT(RTX, N) CWI_ELT (RTX, N) /* For a CONST_DOUBLE: #if TARGET_SUPPORTS_WIDE_INT == 0 @@ -1982,7 +1994,7 @@ extern void end_sequence (void); #if TARGET_SUPPORTS_WIDE_INT == 0 extern double_int rtx_to_double_int (const_rtx); #endif -extern void hwivec_output_hex (FILE *, const_hwivec); +extern void cwi_output_hex (FILE *, const_rtx); #ifndef GENERATOR_FILE extern rtx immed_wide_int_const (const wide_int &cst, enum machine_mode mode); #endif