diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-12-08 17:12:55 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-12-08 17:12:55 +0000 |
commit | 342ad2d6a6167f3f9626947ac8affa9e0c92f611 (patch) | |
tree | 485096f4613a7860b4f1694cbf454cc8dbba8614 /gcc/stor-layout.c | |
parent | e3faad8ab6338078c58c2832315fc487fdc4b944 (diff) | |
download | gcc-342ad2d6a6167f3f9626947ac8affa9e0c92f611.tar.gz |
PR 38240
* tree.h (TYPE_MODE): Invoke vector_type_mode when needed.
(SET_TYPE_MODE): New.
* c-decl.c (parser_xref_tag): Use it.
(finish_enum): Likewise.
* tree.c (build_pointer_type_for_mode): Likewise.
(build_reference_type_for_mode, build_index_type): Likewise.
(build_range_type, make_vector_type): Likewise.
(build_common_tree_nodes_2): Likewise.
* stor-layout.c (compute_record_mode): Likewise.
(finalize_type_size, layout_type, make_fract_type): Likewise.
(make_accum_type, initialize_sizetypes): Likewise.
(vector_type_mode): New.
* function.c (allocate_struct_function): Call
invoke_set_current_function_hook before querying anything else.
* config/i386/i386.c (ix86_valid_target_attribute_inner_p): Add avx.
cp/
* class.c (finish_struct_bits): Use SET_TYPE_MODE.
* decl.c (record_unknown_type): Likewise.
(start_enum, finish_enum): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@142556 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/stor-layout.c')
-rw-r--r-- | gcc/stor-layout.c | 106 |
1 files changed, 74 insertions, 32 deletions
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 17654611e1a..0e7caa5450b 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -1316,7 +1316,7 @@ compute_record_mode (tree type) However, if possible, we use a mode that fits in a register instead, in order to allow for better optimization down the line. */ - TYPE_MODE (type) = BLKmode; + SET_TYPE_MODE (type, BLKmode); if (! host_integerp (TYPE_SIZE (type), 1)) return; @@ -1360,9 +1360,9 @@ compute_record_mode (tree type) if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode && host_integerp (TYPE_SIZE (type), 1) && GET_MODE_BITSIZE (mode) == TREE_INT_CST_LOW (TYPE_SIZE (type))) - TYPE_MODE (type) = mode; + SET_TYPE_MODE (type, mode); else - TYPE_MODE (type) = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1); + SET_TYPE_MODE (type, mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1)); /* If structure's known alignment is less than what the scalar mode would need, and it matters, then stick with BLKmode. */ @@ -1374,7 +1374,7 @@ compute_record_mode (tree type) /* If this is the only reason this type is BLKmode, then don't force containing types to be BLKmode. */ TYPE_NO_FORCE_BLK (type) = 1; - TYPE_MODE (type) = BLKmode; + SET_TYPE_MODE (type, BLKmode); } } @@ -1458,7 +1458,7 @@ finalize_type_size (tree type) TYPE_SIZE_UNIT (variant) = size_unit; TYPE_ALIGN (variant) = align; TYPE_USER_ALIGN (variant) = user_align; - TYPE_MODE (variant) = mode; + SET_TYPE_MODE (variant, mode); } } } @@ -1580,14 +1580,15 @@ layout_type (tree type) && tree_int_cst_sgn (TYPE_MIN_VALUE (type)) >= 0) TYPE_UNSIGNED (type) = 1; - TYPE_MODE (type) = smallest_mode_for_size (TYPE_PRECISION (type), - MODE_INT); + SET_TYPE_MODE (type, + smallest_mode_for_size (TYPE_PRECISION (type), MODE_INT)); TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type))); TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type))); break; case REAL_TYPE: - TYPE_MODE (type) = mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0); + SET_TYPE_MODE (type, + mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0)); TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type))); TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type))); break; @@ -1600,11 +1601,11 @@ layout_type (tree type) case COMPLEX_TYPE: TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type)); - TYPE_MODE (type) - = mode_for_size (2 * TYPE_PRECISION (TREE_TYPE (type)), - (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE - ? MODE_COMPLEX_FLOAT : MODE_COMPLEX_INT), - 0); + SET_TYPE_MODE (type, + mode_for_size (2 * TYPE_PRECISION (TREE_TYPE (type)), + (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE + ? MODE_COMPLEX_FLOAT : MODE_COMPLEX_INT), + 0)); TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type))); TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type))); break; @@ -1636,10 +1637,11 @@ layout_type (tree type) else mode = MIN_MODE_VECTOR_INT; + /* Do not check vector_mode_supported_p here. We'll do that + later in vector_type_mode. */ for (; mode != VOIDmode ; mode = GET_MODE_WIDER_MODE (mode)) if (GET_MODE_NUNITS (mode) == nunits - && GET_MODE_INNER (mode) == innermode - && targetm.vector_mode_supported_p (mode)) + && GET_MODE_INNER (mode) == innermode) break; /* For integers, try mapping it to a same-sized scalar mode. */ @@ -1648,10 +1650,12 @@ layout_type (tree type) mode = mode_for_size (nunits * GET_MODE_BITSIZE (innermode), MODE_INT, 0); - if (mode == VOIDmode || !have_regs_of_mode[mode]) - TYPE_MODE (type) = BLKmode; + if (mode == VOIDmode || + (GET_MODE_CLASS (mode) == MODE_INT + && !have_regs_of_mode[mode])) + SET_TYPE_MODE (type, BLKmode); else - TYPE_MODE (type) = mode; + SET_TYPE_MODE (type, mode); } TYPE_SATURATING (type) = TYPE_SATURATING (TREE_TYPE (type)); @@ -1672,7 +1676,7 @@ layout_type (tree type) /* This is an incomplete type and so doesn't have a size. */ TYPE_ALIGN (type) = 1; TYPE_USER_ALIGN (type) = 0; - TYPE_MODE (type) = VOIDmode; + SET_TYPE_MODE (type, VOIDmode); break; case OFFSET_TYPE: @@ -1680,7 +1684,7 @@ layout_type (tree type) TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE / BITS_PER_UNIT); /* A pointer might be MODE_PARTIAL_INT, but ptrdiff_t must be integral. */ - TYPE_MODE (type) = mode_for_size (POINTER_SIZE, MODE_INT, 0); + SET_TYPE_MODE (type, mode_for_size (POINTER_SIZE, MODE_INT, 0)); break; case FUNCTION_TYPE: @@ -1688,7 +1692,7 @@ layout_type (tree type) /* It's hard to see what the mode and size of a function ought to be, but we do know the alignment is FUNCTION_BOUNDARY, so make it consistent with that. */ - TYPE_MODE (type) = mode_for_size (FUNCTION_BOUNDARY, MODE_INT, 0); + SET_TYPE_MODE (type, mode_for_size (FUNCTION_BOUNDARY, MODE_INT, 0)); TYPE_SIZE (type) = bitsize_int (FUNCTION_BOUNDARY); TYPE_SIZE_UNIT (type) = size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT); break; @@ -1696,7 +1700,6 @@ layout_type (tree type) case POINTER_TYPE: case REFERENCE_TYPE: { - enum machine_mode mode = ((TREE_CODE (type) == REFERENCE_TYPE && reference_types_internal) ? Pmode : TYPE_MODE (type)); @@ -1792,7 +1795,7 @@ layout_type (tree type) fall back on structural equality. */ SET_TYPE_STRUCTURAL_EQUALITY (type); TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element); - TYPE_MODE (type) = BLKmode; + SET_TYPE_MODE (type, BLKmode); if (TYPE_SIZE (type) != 0 #ifdef MEMBER_TYPE_FORCES_BLK && ! MEMBER_TYPE_FORCES_BLK (type, VOIDmode) @@ -1805,17 +1808,17 @@ layout_type (tree type) /* One-element arrays get the component type's mode. */ if (simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (type)))) - TYPE_MODE (type) = TYPE_MODE (TREE_TYPE (type)); + SET_TYPE_MODE (type, TYPE_MODE (TREE_TYPE (type))); else - TYPE_MODE (type) - = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1); + SET_TYPE_MODE (type, mode_for_size_tree (TYPE_SIZE (type), + MODE_INT, 1)); if (TYPE_MODE (type) != BLKmode && STRICT_ALIGNMENT && TYPE_ALIGN (type) < BIGGEST_ALIGNMENT && TYPE_ALIGN (type) < GET_MODE_ALIGNMENT (TYPE_MODE (type))) { TYPE_NO_FORCE_BLK (type) = 1; - TYPE_MODE (type) = BLKmode; + SET_TYPE_MODE (type, BLKmode); } } /* When the element size is constant, check that it is at least as @@ -1877,6 +1880,45 @@ layout_type (tree type) if (AGGREGATE_TYPE_P (type)) gcc_assert (!TYPE_ALIAS_SET_KNOWN_P (type)); } + +/* Vector types need to re-check the target flags each time we report + the machine mode. We need to do this because attribute target can + change the result of vector_mode_supported_p and have_regs_of_mode + on a per-function basis. Thus the TYPE_MODE of a VECTOR_TYPE can + change on a per-function basis. */ +/* ??? Possibly a better solution is to run through all the types + referenced by a function and re-compute the TYPE_MODE once, rather + than make the TYPE_MODE macro call a function. */ + +enum machine_mode +vector_type_mode (const_tree t) +{ + enum machine_mode mode; + + gcc_assert (TREE_CODE (t) == VECTOR_TYPE); + + mode = t->type.mode; + if (VECTOR_MODE_P (mode) + && (!targetm.vector_mode_supported_p (mode) + || !have_regs_of_mode[mode])) + { + enum machine_mode innermode = TREE_TYPE (t)->type.mode; + + /* For integers, try mapping it to a same-sized scalar mode. */ + if (GET_MODE_CLASS (innermode) == MODE_INT) + { + mode = mode_for_size (TYPE_VECTOR_SUBPARTS (t) + * GET_MODE_BITSIZE (innermode), MODE_INT, 0); + + if (mode != VOIDmode && have_regs_of_mode[mode]) + return mode; + } + + return BLKmode; + } + + return mode; +} /* Create and return a type for signed integers of PRECISION bits. */ @@ -1921,10 +1963,10 @@ make_fract_type (int precision, int unsignedp, int satp) if (unsignedp) { TYPE_UNSIGNED (type) = 1; - TYPE_MODE (type) = mode_for_size (precision, MODE_UFRACT, 0); + SET_TYPE_MODE (type, mode_for_size (precision, MODE_UFRACT, 0)); } else - TYPE_MODE (type) = mode_for_size (precision, MODE_FRACT, 0); + SET_TYPE_MODE (type, mode_for_size (precision, MODE_FRACT, 0)); layout_type (type); return type; @@ -1947,10 +1989,10 @@ make_accum_type (int precision, int unsignedp, int satp) if (unsignedp) { TYPE_UNSIGNED (type) = 1; - TYPE_MODE (type) = mode_for_size (precision, MODE_UACCUM, 0); + SET_TYPE_MODE (type, mode_for_size (precision, MODE_UACCUM, 0)); } else - TYPE_MODE (type) = mode_for_size (precision, MODE_ACCUM, 0); + SET_TYPE_MODE (type, mode_for_size (precision, MODE_ACCUM, 0)); layout_type (type); return type; @@ -1965,7 +2007,7 @@ initialize_sizetypes (bool signed_p) tree t = make_node (INTEGER_TYPE); int precision = GET_MODE_BITSIZE (SImode); - TYPE_MODE (t) = SImode; + SET_TYPE_MODE (t, SImode); TYPE_ALIGN (t) = GET_MODE_ALIGNMENT (SImode); TYPE_USER_ALIGN (t) = 0; TYPE_IS_SIZETYPE (t) = 1; |