From 8974754f6f12f2f032d4122b06d26319545ced00 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 27 May 2015 18:00:15 +0000 Subject: [PATCH] expr.h (array_at_struct_end_p): Move to... * expr.h (array_at_struct_end_p): Move to... (array_ref_element_size): Likewise. (component_ref_field_offset): Likewise. * tree.h (array_ref_element_size): ...here. (array_at_struct_end_p): Likewise. (component_ref_field_offset): Likewise. * expr.c (array_ref_element_size): Move to... (array_ref_low_bound): Likewise. (array_at_struct_end_p): Likewise. (array_ref_up_bound): Likewise. (component_ref_field_offset): Likewise. * tree.c (array_ref_element_size): ...here. (array_ref_low_bound): Likewise. (array_ref_up_bound): Likewise. (array_at_struct_end_p): Likewise. (component_ref_field_offset): Likewise. From-SVN: r223768 --- gcc/ChangeLog | 19 +++++++ gcc/expr.c | 133 ------------------------------------------------ gcc/expr.h | 9 ---- gcc/tree.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++- gcc/tree.h | 39 ++++++++++---- 5 files changed, 182 insertions(+), 155 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b0145285aae..6920846f50c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2015-05-27 Eric Botcazou + + * expr.h (array_at_struct_end_p): Move to... + (array_ref_element_size): Likewise. + (component_ref_field_offset): Likewise. + * tree.h (array_ref_element_size): ...here. + (array_at_struct_end_p): Likewise. + (component_ref_field_offset): Likewise. + * expr.c (array_ref_element_size): Move to... + (array_ref_low_bound): Likewise. + (array_at_struct_end_p): Likewise. + (array_ref_up_bound): Likewise. + (component_ref_field_offset): Likewise. + * tree.c (array_ref_element_size): ...here. + (array_ref_low_bound): Likewise. + (array_ref_up_bound): Likewise. + (array_at_struct_end_p): Likewise. + (component_ref_field_offset): Likewise. + 2015-05-27 Gregor Richards Szabolcs Nagy diff --git a/gcc/expr.c b/gcc/expr.c index 1dd1cf301f2..5a931dc35ae 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -7025,139 +7025,6 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, return exp; } -/* Return a tree of sizetype representing the size, in bytes, of the element - of EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ - -tree -array_ref_element_size (tree exp) -{ - tree aligned_size = TREE_OPERAND (exp, 3); - tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))); - location_t loc = EXPR_LOCATION (exp); - - /* If a size was specified in the ARRAY_REF, it's the size measured - in alignment units of the element type. So multiply by that value. */ - if (aligned_size) - { - /* ??? tree_ssa_useless_type_conversion will eliminate casts to - sizetype from another type of the same width and signedness. */ - if (TREE_TYPE (aligned_size) != sizetype) - aligned_size = fold_convert_loc (loc, sizetype, aligned_size); - return size_binop_loc (loc, MULT_EXPR, aligned_size, - size_int (TYPE_ALIGN_UNIT (elmt_type))); - } - - /* Otherwise, take the size from that of the element type. Substitute - any PLACEHOLDER_EXPR that we have. */ - else - return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (elmt_type), exp); -} - -/* Return a tree representing the lower bound of the array mentioned in - EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ - -tree -array_ref_low_bound (tree exp) -{ - tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0))); - - /* If a lower bound is specified in EXP, use it. */ - if (TREE_OPERAND (exp, 2)) - return TREE_OPERAND (exp, 2); - - /* Otherwise, if there is a domain type and it has a lower bound, use it, - substituting for a PLACEHOLDER_EXPR as needed. */ - if (domain_type && TYPE_MIN_VALUE (domain_type)) - return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MIN_VALUE (domain_type), exp); - - /* Otherwise, return a zero of the appropriate type. */ - return build_int_cst (TREE_TYPE (TREE_OPERAND (exp, 1)), 0); -} - -/* Returns true if REF is an array reference to an array at the end of - a structure. If this is the case, the array may be allocated larger - than its upper bound implies. */ - -bool -array_at_struct_end_p (tree ref) -{ - if (TREE_CODE (ref) != ARRAY_REF - && TREE_CODE (ref) != ARRAY_RANGE_REF) - return false; - - while (handled_component_p (ref)) - { - /* If the reference chain contains a component reference to a - non-union type and there follows another field the reference - is not at the end of a structure. */ - if (TREE_CODE (ref) == COMPONENT_REF - && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE) - { - tree nextf = DECL_CHAIN (TREE_OPERAND (ref, 1)); - while (nextf && TREE_CODE (nextf) != FIELD_DECL) - nextf = DECL_CHAIN (nextf); - if (nextf) - return false; - } - - ref = TREE_OPERAND (ref, 0); - } - - /* If the reference is based on a declared entity, the size of the array - is constrained by its given domain. */ - if (DECL_P (ref)) - return false; - - return true; -} - -/* Return a tree representing the upper bound of the array mentioned in - EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ - -tree -array_ref_up_bound (tree exp) -{ - tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0))); - - /* If there is a domain type and it has an upper bound, use it, substituting - for a PLACEHOLDER_EXPR as needed. */ - if (domain_type && TYPE_MAX_VALUE (domain_type)) - return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MAX_VALUE (domain_type), exp); - - /* Otherwise fail. */ - return NULL_TREE; -} - -/* Return a tree representing the offset, in bytes, of the field referenced - by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */ - -tree -component_ref_field_offset (tree exp) -{ - tree aligned_offset = TREE_OPERAND (exp, 2); - tree field = TREE_OPERAND (exp, 1); - location_t loc = EXPR_LOCATION (exp); - - /* If an offset was specified in the COMPONENT_REF, it's the offset measured - in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT. So multiply by that - value. */ - if (aligned_offset) - { - /* ??? tree_ssa_useless_type_conversion will eliminate casts to - sizetype from another type of the same width and signedness. */ - if (TREE_TYPE (aligned_offset) != sizetype) - aligned_offset = fold_convert_loc (loc, sizetype, aligned_offset); - return size_binop_loc (loc, MULT_EXPR, aligned_offset, - size_int (DECL_OFFSET_ALIGN (field) - / BITS_PER_UNIT)); - } - - /* Otherwise, take the offset from that of the field. Substitute - any PLACEHOLDER_EXPR that we have. */ - else - return SUBSTITUTE_PLACEHOLDER_IN_EXPR (DECL_FIELD_OFFSET (field), exp); -} - /* Alignment in bits the TARGET of an assignment may be assumed to have. */ static unsigned HOST_WIDE_INT diff --git a/gcc/expr.h b/gcc/expr.h index 7b28ffd8d39..8cf9720484a 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -281,19 +281,10 @@ rtx get_personality_function (tree); extern int can_move_by_pieces (unsigned HOST_WIDE_INT, unsigned int); extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree); -bool array_at_struct_end_p (tree); - -/* Return a tree of sizetype representing the size, in bytes, of the element - of EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ -extern tree array_ref_element_size (tree); extern bool categorize_ctor_elements (const_tree, HOST_WIDE_INT *, HOST_WIDE_INT *, bool *); -/* Return a tree representing the offset, in bytes, of the field referenced - by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */ -extern tree component_ref_field_offset (tree); - extern void expand_operands (tree, tree, rtx, rtx*, rtx*, enum expand_modifier); diff --git a/gcc/tree.c b/gcc/tree.c index 60d45099217..c22fa765f4c 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -24,8 +24,8 @@ along with GCC; see the file COPYING3. If not see tables index by tree code that describe how to take apart nodes of that code. - It is intended to be language-independent, but occasionally - calls language-dependent routines defined (for C) in typecheck.c. */ + It is intended to be language-independent but can occasionally + calls language-dependent routines. */ #include "config.h" #include "system.h" @@ -12453,6 +12453,139 @@ get_base_address (tree t) return t; } +/* Return a tree of sizetype representing the size, in bytes, of the element + of EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ + +tree +array_ref_element_size (tree exp) +{ + tree aligned_size = TREE_OPERAND (exp, 3); + tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))); + location_t loc = EXPR_LOCATION (exp); + + /* If a size was specified in the ARRAY_REF, it's the size measured + in alignment units of the element type. So multiply by that value. */ + if (aligned_size) + { + /* ??? tree_ssa_useless_type_conversion will eliminate casts to + sizetype from another type of the same width and signedness. */ + if (TREE_TYPE (aligned_size) != sizetype) + aligned_size = fold_convert_loc (loc, sizetype, aligned_size); + return size_binop_loc (loc, MULT_EXPR, aligned_size, + size_int (TYPE_ALIGN_UNIT (elmt_type))); + } + + /* Otherwise, take the size from that of the element type. Substitute + any PLACEHOLDER_EXPR that we have. */ + else + return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (elmt_type), exp); +} + +/* Return a tree representing the lower bound of the array mentioned in + EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ + +tree +array_ref_low_bound (tree exp) +{ + tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0))); + + /* If a lower bound is specified in EXP, use it. */ + if (TREE_OPERAND (exp, 2)) + return TREE_OPERAND (exp, 2); + + /* Otherwise, if there is a domain type and it has a lower bound, use it, + substituting for a PLACEHOLDER_EXPR as needed. */ + if (domain_type && TYPE_MIN_VALUE (domain_type)) + return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MIN_VALUE (domain_type), exp); + + /* Otherwise, return a zero of the appropriate type. */ + return build_int_cst (TREE_TYPE (TREE_OPERAND (exp, 1)), 0); +} + +/* Return a tree representing the upper bound of the array mentioned in + EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ + +tree +array_ref_up_bound (tree exp) +{ + tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0))); + + /* If there is a domain type and it has an upper bound, use it, substituting + for a PLACEHOLDER_EXPR as needed. */ + if (domain_type && TYPE_MAX_VALUE (domain_type)) + return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MAX_VALUE (domain_type), exp); + + /* Otherwise fail. */ + return NULL_TREE; +} + +/* Returns true if REF is an array reference to an array at the end of + a structure. If this is the case, the array may be allocated larger + than its upper bound implies. */ + +bool +array_at_struct_end_p (tree ref) +{ + if (TREE_CODE (ref) != ARRAY_REF + && TREE_CODE (ref) != ARRAY_RANGE_REF) + return false; + + while (handled_component_p (ref)) + { + /* If the reference chain contains a component reference to a + non-union type and there follows another field the reference + is not at the end of a structure. */ + if (TREE_CODE (ref) == COMPONENT_REF + && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE) + { + tree nextf = DECL_CHAIN (TREE_OPERAND (ref, 1)); + while (nextf && TREE_CODE (nextf) != FIELD_DECL) + nextf = DECL_CHAIN (nextf); + if (nextf) + return false; + } + + ref = TREE_OPERAND (ref, 0); + } + + /* If the reference is based on a declared entity, the size of the array + is constrained by its given domain. */ + if (DECL_P (ref)) + return false; + + return true; +} + +/* Return a tree representing the offset, in bytes, of the field referenced + by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */ + +tree +component_ref_field_offset (tree exp) +{ + tree aligned_offset = TREE_OPERAND (exp, 2); + tree field = TREE_OPERAND (exp, 1); + location_t loc = EXPR_LOCATION (exp); + + /* If an offset was specified in the COMPONENT_REF, it's the offset measured + in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT. So multiply by that + value. */ + if (aligned_offset) + { + /* ??? tree_ssa_useless_type_conversion will eliminate casts to + sizetype from another type of the same width and signedness. */ + if (TREE_TYPE (aligned_offset) != sizetype) + aligned_offset = fold_convert_loc (loc, sizetype, aligned_offset); + return size_binop_loc (loc, MULT_EXPR, aligned_offset, + size_int (DECL_OFFSET_ALIGN (field) + / BITS_PER_UNIT)); + } + + /* Otherwise, take the offset from that of the field. Substitute + any PLACEHOLDER_EXPR that we have. */ + else + return SUBSTITUTE_PLACEHOLDER_IN_EXPR (DECL_FIELD_OFFSET (field), exp); +} + /* Return the machine mode of T. For vectors, returns the mode of the inner type. The main use case is to feed the result to HONOR_NANS, avoiding the BLKmode that a direct TYPE_MODE (T) might return. */ diff --git a/gcc/tree.h b/gcc/tree.h index 58d2e9b8858..732a61c2131 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -4564,8 +4564,34 @@ extern tree walk_tree_without_duplicates_1 (tree*, walk_tree_fn, void*, #define walk_tree_without_duplicates(a,b,c) \ walk_tree_without_duplicates_1 (a, b, c, NULL) -extern tree get_base_address (tree t); extern tree drop_tree_overflow (tree); + +/* Given a memory reference expression T, return its base address. + The base address of a memory reference expression is the main + object being referenced. */ +extern tree get_base_address (tree t); + +/* Return a tree of sizetype representing the size, in bytes, of the element + of EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ +extern tree array_ref_element_size (tree); + +/* Return a tree representing the upper bound of the array mentioned in + EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ +extern tree array_ref_up_bound (tree); + +/* Return a tree representing the lower bound of the array mentioned in + EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ +extern tree array_ref_low_bound (tree); + +/* Returns true if REF is an array reference to an array at the end of + a structure. If this is the case, the array may be allocated larger + than its upper bound implies. */ +extern bool array_at_struct_end_p (tree); + +/* Return a tree representing the offset, in bytes, of the field referenced + by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */ +extern tree component_ref_field_offset (tree); + extern int tree_map_base_eq (const void *, const void *); extern unsigned int tree_map_base_hash (const void *); extern int tree_map_base_marked_p (const void *); @@ -5052,12 +5078,6 @@ tree_int_cst_compare (const_tree t1, const_tree t2) extern void set_decl_rtl (tree, rtx); extern bool complete_ctor_at_level_p (const_tree, HOST_WIDE_INT, const_tree); -/* Return a tree representing the upper bound of the array mentioned in - EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ -extern tree array_ref_up_bound (tree); - -extern tree build_personality_function (const char *); - /* Given an expression EXP that is a handled_component_p, look for the ultimate containing object, which is returned and specify the access position and size. */ @@ -5065,10 +5085,7 @@ extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *, tree *, machine_mode *, int *, int *, bool); -/* Return a tree representing the lower bound of the array mentioned in - EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ -extern tree array_ref_low_bound (tree); - +extern tree build_personality_function (const char *); struct GTY(()) int_n_trees_t { /* These parts are initialized at runtime */ -- 2.30.2