diff options
Diffstat (limited to 'gcc/rtl.c')
-rw-r--r-- | gcc/rtl.c | 109 |
1 files changed, 63 insertions, 46 deletions
@@ -109,7 +109,7 @@ const enum rtx_class rtx_class[NUM_RTX_CODE] = { /* Indexed by rtx code, gives the size of the rtx in bytes. */ -const unsigned char rtx_size[NUM_RTX_CODE] = { +const unsigned char rtx_code_size[NUM_RTX_CODE] = { #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) \ ((ENUM) == CONST_INT || (ENUM) == CONST_DOUBLE \ ? RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (HOST_WIDE_INT) \ @@ -170,6 +170,16 @@ rtvec_alloc (int n) return rt; } +/* Return the number of bytes occupied by rtx value X. */ + +unsigned int +rtx_size (rtx x) +{ + if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_IN_BLOCK_P (x)) + return RTX_HDR_SIZE + sizeof (struct block_symbol); + return RTX_CODE_SIZE (GET_CODE (x)); +} + /* Allocate an rtx of code CODE. The CODE is stored in the rtx; all the rest is initialized to zero. */ @@ -178,7 +188,7 @@ rtx_alloc_stat (RTX_CODE code MEM_STAT_DECL) { rtx rt; - rt = (rtx) ggc_alloc_zone_pass_stat (RTX_SIZE (code), &rtl_zone); + rt = (rtx) ggc_alloc_zone_pass_stat (RTX_CODE_SIZE (code), &rtl_zone); /* We want to clear everything up to the FLD array. Normally, this is one int, but we don't want to assume that and it isn't very @@ -189,7 +199,7 @@ rtx_alloc_stat (RTX_CODE code MEM_STAT_DECL) #ifdef GATHER_STATISTICS rtx_alloc_counts[code]++; - rtx_alloc_sizes[code] += RTX_SIZE (code); + rtx_alloc_sizes[code] += RTX_CODE_SIZE (code); #endif return rt; @@ -246,13 +256,11 @@ copy_rtx (rtx orig) break; } - copy = rtx_alloc (code); - - /* Copy the various flags, and other information. We assume that - all fields need copying, and then clear the fields that should + /* Copy the various flags, fields, and other information. We assume + that all fields need copying, and then clear the fields that should not be copied. That is the sensible default behavior, and forces us to explicitly document why we are *not* copying a flag. */ - memcpy (copy, orig, RTX_HDR_SIZE); + copy = shallow_copy_rtx (orig); /* We do not copy the USED flag, which is used as a mark bit during walks over the RTL. */ @@ -267,41 +275,38 @@ copy_rtx (rtx orig) format_ptr = GET_RTX_FORMAT (GET_CODE (copy)); for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++) - { - copy->u.fld[i] = orig->u.fld[i]; - switch (*format_ptr++) - { - case 'e': - if (XEXP (orig, i) != NULL) - XEXP (copy, i) = copy_rtx (XEXP (orig, i)); - break; - - case 'E': - case 'V': - if (XVEC (orig, i) != NULL) - { - XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i)); - for (j = 0; j < XVECLEN (copy, i); j++) - XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j)); - } - break; - - case 't': - case 'w': - case 'i': - case 's': - case 'S': - case 'T': - case 'u': - case 'B': - case '0': - /* These are left unchanged. */ - break; - - default: - gcc_unreachable (); - } - } + switch (*format_ptr++) + { + case 'e': + if (XEXP (orig, i) != NULL) + XEXP (copy, i) = copy_rtx (XEXP (orig, i)); + break; + + case 'E': + case 'V': + if (XVEC (orig, i) != NULL) + { + XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i)); + for (j = 0; j < XVECLEN (copy, i); j++) + XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j)); + } + break; + + case 't': + case 'w': + case 'i': + case 's': + case 'S': + case 'T': + case 'u': + case 'B': + case '0': + /* These are left unchanged. */ + break; + + default: + gcc_unreachable (); + } return copy; } @@ -310,11 +315,12 @@ copy_rtx (rtx orig) rtx shallow_copy_rtx_stat (rtx orig MEM_STAT_DECL) { + unsigned int size; rtx copy; - copy = (rtx) ggc_alloc_zone_pass_stat (RTX_SIZE (GET_CODE (orig)), - &rtl_zone); - memcpy (copy, orig, RTX_SIZE (GET_CODE (orig))); + size = rtx_size (orig); + copy = (rtx) ggc_alloc_zone_pass_stat (size, &rtl_zone); + memcpy (copy, orig, size); return copy; } @@ -530,6 +536,17 @@ rtl_check_failed_code_mode (rtx r, enum rtx_code code, enum machine_mode mode, func, trim_filename (file), line); } +/* Report that line LINE of FILE tried to access the block symbol fields + of a non-block symbol. FUNC is the function that contains the line. */ + +void +rtl_check_failed_block_symbol (const char *file, int line, const char *func) +{ + internal_error + ("RTL check: attempt to treat non-block symbol as a block symbol " + "in %s, at %s:%d", func, trim_filename (file), line); +} + /* XXX Maybe print the vector? */ void rtvec_check_failed_bounds (rtvec r, int n, const char *file, int line, |