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
This commit is contained in:
parent
e590690ef2
commit
8974754f6f
|
@ -1,3 +1,22 @@
|
|||
2015-05-27 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* 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 <gregor.richards@uwaterloo.ca>
|
||||
Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||
|
||||
|
|
133
gcc/expr.c
133
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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
137
gcc/tree.c
137
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. */
|
||||
|
|
39
gcc/tree.h
39
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 */
|
||||
|
|
Loading…
Reference in New Issue