diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-03-06 12:08:23 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-03-06 12:08:23 +0000 |
commit | 70337474d37fdba76f7220fa92d7279e014a314d (patch) | |
tree | bebeb96faecfdcf797f71dee5229fe073b7e2e3e /gcc | |
parent | b357aba8754853cacba93de212989197f4c3d01c (diff) | |
download | gcc-70337474d37fdba76f7220fa92d7279e014a314d.tar.gz |
2008-03-06 Richard Guenther <rguenther@suse.de>
* tree.def (BIT_FIELD_REF): Constrain result type and its precision.
* tree-cfg.c (verify_expr): Verify BIT_FIELD_REF constraints on
result type and precision.
* expr.c (get_inner_reference): Set unsignedp based on the result
type of BIT_FIELD_REF.
* tree.h (BIT_FIELD_REF_UNSIGNED): Remove.
* tree-sra.c (instantiate_element): Do not set BIT_FIELD_REF_UNSIGNED.
(try_instantiate_multiple_fields): Likewise. Use the correct type
for BIT_FIELD_REF.
(sra_build_assignment): Likewise.
(sra_build_elt_assignment): Likewise.
(sra_explode_bitfield_assignment): Likewise.
* print-tree.c (print_node): Do not check BIT_FIELD_REF_UNSIGNED.
* tree-vect-transform.c (vect_create_epilog_for_reduction): Do not
set BIT_FIELD_REF_UNSIGNED.
(vectorizable_load): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@132969 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/expr.c | 3 | ||||
-rw-r--r-- | gcc/print-tree.c | 2 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 16 | ||||
-rw-r--r-- | gcc/tree-sra.c | 25 | ||||
-rw-r--r-- | gcc/tree-vect-transform.c | 5 | ||||
-rw-r--r-- | gcc/tree.def | 5 | ||||
-rw-r--r-- | gcc/tree.h | 6 |
8 files changed, 53 insertions, 28 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f87ec3b28a4..62d78221214 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2008-03-06 Richard Guenther <rguenther@suse.de> + + * tree.def (BIT_FIELD_REF): Constrain result type and its precision. + * tree-cfg.c (verify_expr): Verify BIT_FIELD_REF constraints on + result type and precision. + * expr.c (get_inner_reference): Set unsignedp based on the result + type of BIT_FIELD_REF. + * tree.h (BIT_FIELD_REF_UNSIGNED): Remove. + * tree-sra.c (instantiate_element): Do not set BIT_FIELD_REF_UNSIGNED. + (try_instantiate_multiple_fields): Likewise. Use the correct type + for BIT_FIELD_REF. + (sra_build_assignment): Likewise. + (sra_build_elt_assignment): Likewise. + (sra_explode_bitfield_assignment): Likewise. + * print-tree.c (print_node): Do not check BIT_FIELD_REF_UNSIGNED. + * tree-vect-transform.c (vect_create_epilog_for_reduction): Do not + set BIT_FIELD_REF_UNSIGNED. + (vectorizable_load): Likewise. + 2008-03-06 Andreas Krebbel <krebbel1@de.ibm.com> * cse.c (cse_extended_basic_block): Invalidate artificial defs diff --git a/gcc/expr.c b/gcc/expr.c index 79a039a529f..2cd6e627843 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -5893,7 +5893,8 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, else if (TREE_CODE (exp) == BIT_FIELD_REF) { size_tree = TREE_OPERAND (exp, 1); - *punsignedp = BIT_FIELD_REF_UNSIGNED (exp); + *punsignedp = (! INTEGRAL_TYPE_P (TREE_TYPE (exp)) + || TYPE_UNSIGNED (TREE_TYPE (exp))); /* For vector types, with the correct size of access, use the mode of inner type. */ diff --git a/gcc/print-tree.c b/gcc/print-tree.c index 7df81616d51..889f1c5f511 100644 --- a/gcc/print-tree.c +++ b/gcc/print-tree.c @@ -676,8 +676,6 @@ print_node (FILE *file, const char *prefix, tree node, int indent) case tcc_reference: case tcc_statement: case tcc_vl_exp: - if (TREE_CODE (node) == BIT_FIELD_REF && BIT_FIELD_REF_UNSIGNED (node)) - fputs (" unsigned", file); if (TREE_CODE (node) == BIND_EXPR) { print_node (file, "vars", TREE_OPERAND (node, 0), indent + 4); diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 71a6c9ad667..f98c684471e 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -3277,6 +3277,22 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) error ("invalid position or size operand to BIT_FIELD_REF"); return t; } + else if (INTEGRAL_TYPE_P (TREE_TYPE (t)) + && (TYPE_PRECISION (TREE_TYPE (t)) + != TREE_INT_CST_LOW (TREE_OPERAND (t, 1)))) + { + error ("integral result type precision does not match " + "field size of BIT_FIELD_REF"); + return t; + } + if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) + && (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (t))) + != TREE_INT_CST_LOW (TREE_OPERAND (t, 1)))) + { + error ("mode precision of non-integral result does not " + "match field size of BIT_FIELD_REF"); + return t; + } } t = TREE_OPERAND (t, 0); diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 1f2d6c25e62..45142e8e14c 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -1280,9 +1280,6 @@ instantiate_element (struct sra_elt *elt) TYPE_SIZE (elt->type), DECL_SIZE (var)) : bitsize_int (0)); - if (!INTEGRAL_TYPE_P (elt->type) - || TYPE_UNSIGNED (elt->type)) - BIT_FIELD_REF_UNSIGNED (elt->replacement) = 1; } /* For vectors, if used on the left hand side with BIT_FIELD_REF, @@ -1677,12 +1674,17 @@ try_instantiate_multiple_fields (struct sra_elt *elt, tree f) /* Create the field group as a single variable. */ - type = lang_hooks.types.type_for_mode (mode, 1); + /* We used to create a type for the mode above, but size turns + to be out not of mode-size. As we need a matching type + to build a BIT_FIELD_REF, use a nonstandard integer type as + fallback. */ + type = lang_hooks.types.type_for_size (size, 1); + if (!type || TYPE_PRECISION (type) != size) + type = build_nonstandard_integer_type (size, 1); gcc_assert (type); var = build3 (BIT_FIELD_REF, type, NULL_TREE, bitsize_int (size), bitsize_int (bit)); - BIT_FIELD_REF_UNSIGNED (var) = 1; block = instantiate_missing_elements_1 (elt, var, type); gcc_assert (block && block->is_scalar); @@ -1696,7 +1698,6 @@ try_instantiate_multiple_fields (struct sra_elt *elt, tree f) TREE_TYPE (block->element), var, bitsize_int (size), bitsize_int (bit & ~alchk)); - BIT_FIELD_REF_UNSIGNED (block->replacement) = 1; } block->in_bitfld_block = 2; @@ -1719,7 +1720,6 @@ try_instantiate_multiple_fields (struct sra_elt *elt, tree f) + (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (f)))) & ~alchk)); - BIT_FIELD_REF_UNSIGNED (fld->replacement) = TYPE_UNSIGNED (field_type); fld->in_bitfld_block = 1; } @@ -2141,7 +2141,8 @@ sra_build_assignment (tree dst, tree src) tree var, shift, width; tree utype, stype, stmp, utmp, dtmp; tree list, stmt; - bool unsignedp = BIT_FIELD_REF_UNSIGNED (src); + bool unsignedp = (INTEGRAL_TYPE_P (TREE_TYPE (src)) + ? TYPE_UNSIGNED (TREE_TYPE (src)) : true); var = TREE_OPERAND (src, 0); width = TREE_OPERAND (src, 1); @@ -2491,6 +2492,7 @@ sra_build_elt_assignment (struct sra_elt *elt, tree src) if (elt->in_bitfld_block == 2 && TREE_CODE (src) == BIT_FIELD_REF) { + tmp = src; cst = TYPE_SIZE (TREE_TYPE (var)); cst2 = size_binop (MINUS_EXPR, TREE_OPERAND (src, 2), TREE_OPERAND (dst, 2)); @@ -2536,8 +2538,7 @@ sra_build_elt_assignment (struct sra_elt *elt, tree src) } else { - src = fold_build3 (BIT_FIELD_REF, TREE_TYPE (var), src, cst, cst2); - BIT_FIELD_REF_UNSIGNED (src) = 1; + src = fold_convert (TREE_TYPE (var), tmp); } return sra_build_assignment (var, src); @@ -3014,6 +3015,8 @@ sra_explode_bitfield_assignment (tree var, tree vpos, bool to_var, type = TREE_TYPE (infld); if (TYPE_PRECISION (type) != TREE_INT_CST_LOW (flen)) type = lang_hooks.types.type_for_size (TREE_INT_CST_LOW (flen), 1); + else + type = unsigned_type_for (type); if (TREE_CODE (infld) == BIT_FIELD_REF) { @@ -3031,7 +3034,6 @@ sra_explode_bitfield_assignment (tree var, tree vpos, bool to_var, } infld = fold_build3 (BIT_FIELD_REF, type, infld, flen, fpos); - BIT_FIELD_REF_UNSIGNED (infld) = 1; invar = size_binop (MINUS_EXPR, flp.field_pos, bpos); if (flp.overlap_pos) @@ -3039,7 +3041,6 @@ sra_explode_bitfield_assignment (tree var, tree vpos, bool to_var, invar = size_binop (PLUS_EXPR, invar, vpos); invar = fold_build3 (BIT_FIELD_REF, type, var, flen, invar); - BIT_FIELD_REF_UNSIGNED (invar) = 1; if (to_var) st = sra_build_bf_assignment (invar, infld); diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c index 883d7457077..a35e963b48f 100644 --- a/gcc/tree-vect-transform.c +++ b/gcc/tree-vect-transform.c @@ -2517,7 +2517,6 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt, vec_size_in_bits = tree_low_cst (TYPE_SIZE (vectype), 1); rhs = build3 (BIT_FIELD_REF, scalar_type, vec_temp, bitsize, bitsize_zero_node); - BIT_FIELD_REF_UNSIGNED (rhs) = TYPE_UNSIGNED (scalar_type); epilog_stmt = build_gimple_modify_stmt (new_scalar_dest, rhs); new_temp = make_ssa_name (new_scalar_dest, epilog_stmt); GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_temp; @@ -2532,7 +2531,6 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt, tree rhs = build3 (BIT_FIELD_REF, scalar_type, vec_temp, bitsize, bitpos); - BIT_FIELD_REF_UNSIGNED (rhs) = TYPE_UNSIGNED (scalar_type); epilog_stmt = build_gimple_modify_stmt (new_scalar_dest, rhs); new_name = make_ssa_name (new_scalar_dest, epilog_stmt); GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_name; @@ -2568,7 +2566,6 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt, bitpos = bitsize_zero_node; rhs = build3 (BIT_FIELD_REF, scalar_type, new_temp, bitsize, bitpos); - BIT_FIELD_REF_UNSIGNED (rhs) = TYPE_UNSIGNED (scalar_type); epilog_stmt = build_gimple_modify_stmt (new_scalar_dest, rhs); new_temp = make_ssa_name (new_scalar_dest, epilog_stmt); GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_temp; @@ -5877,8 +5874,6 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt, bitpos = bitsize_zero_node; vec_inv = build3 (BIT_FIELD_REF, scalar_type, new_temp, bitsize, bitpos); - BIT_FIELD_REF_UNSIGNED (vec_inv) = - TYPE_UNSIGNED (scalar_type); vec_dest = vect_create_destination_var (scalar_dest, NULL_TREE); new_stmt = build_gimple_modify_stmt (vec_dest, vec_inv); diff --git a/gcc/tree.def b/gcc/tree.def index aac9d563c38..4a55ee0aaf9 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -391,8 +391,9 @@ DEFTREECODE (COMPONENT_REF, "component_ref", tcc_reference, 3) Operand 0 is the structure or union expression; operand 1 is a tree giving the constant number of bits being referenced; operand 2 is a tree giving the constant position of the first referenced bit. - The field can be either a signed or unsigned field; - BIT_FIELD_REF_UNSIGNED says which. */ + The result type width has to match the number of bits referenced. + If the result type is integral, its signedness specifies how it is extended + to its mode width. */ DEFTREECODE (BIT_FIELD_REF, "bit_field_ref", tcc_reference, 3) /* The ordering of the following codes is optimized for the checking diff --git a/gcc/tree.h b/gcc/tree.h index d59d3fa9a3b..de6654de80f 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -542,8 +542,6 @@ struct gimple_stmt GTY(()) all types DECL_UNSIGNED in all decls - BIT_FIELD_REF_UNSIGNED in - BIT_FIELD_REF asm_written_flag: @@ -1301,10 +1299,6 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, #define DECL_UNSIGNED(NODE) \ (DECL_COMMON_CHECK (NODE)->base.unsigned_flag) -/* In a BIT_FIELD_REF, means the bitfield is to be interpreted as unsigned. */ -#define BIT_FIELD_REF_UNSIGNED(NODE) \ - (BIT_FIELD_REF_CHECK (NODE)->base.unsigned_flag) - /* In integral and pointer types, means an unsigned type. */ #define TYPE_UNSIGNED(NODE) (TYPE_CHECK (NODE)->base.unsigned_flag) |