Commit 8974754f by Eric Botcazou Committed by Eric Botcazou

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
parent e590690e
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> 2015-05-27 Gregor Richards <gregor.richards@uwaterloo.ca>
Szabolcs Nagy <szabolcs.nagy@arm.com> Szabolcs Nagy <szabolcs.nagy@arm.com>
......
...@@ -7025,139 +7025,6 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, ...@@ -7025,139 +7025,6 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
return exp; 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. */ /* Alignment in bits the TARGET of an assignment may be assumed to have. */
static unsigned HOST_WIDE_INT static unsigned HOST_WIDE_INT
......
...@@ -281,19 +281,10 @@ rtx get_personality_function (tree); ...@@ -281,19 +281,10 @@ rtx get_personality_function (tree);
extern int can_move_by_pieces (unsigned HOST_WIDE_INT, unsigned int); extern int can_move_by_pieces (unsigned HOST_WIDE_INT, unsigned int);
extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree); 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 *, extern bool categorize_ctor_elements (const_tree, HOST_WIDE_INT *,
HOST_WIDE_INT *, bool *); 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*, extern void expand_operands (tree, tree, rtx, rtx*, rtx*,
enum expand_modifier); enum expand_modifier);
......
...@@ -24,8 +24,8 @@ along with GCC; see the file COPYING3. If not see ...@@ -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 tables index by tree code that describe how to take apart
nodes of that code. nodes of that code.
It is intended to be language-independent, but occasionally It is intended to be language-independent but can occasionally
calls language-dependent routines defined (for C) in typecheck.c. */ calls language-dependent routines. */
#include "config.h" #include "config.h"
#include "system.h" #include "system.h"
...@@ -12453,6 +12453,139 @@ get_base_address (tree t) ...@@ -12453,6 +12453,139 @@ get_base_address (tree t)
return 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 /* 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, 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. */ avoiding the BLKmode that a direct TYPE_MODE (T) might return. */
......
...@@ -4564,8 +4564,34 @@ extern tree walk_tree_without_duplicates_1 (tree*, walk_tree_fn, void*, ...@@ -4564,8 +4564,34 @@ extern tree walk_tree_without_duplicates_1 (tree*, walk_tree_fn, void*,
#define walk_tree_without_duplicates(a,b,c) \ #define walk_tree_without_duplicates(a,b,c) \
walk_tree_without_duplicates_1 (a, b, c, NULL) walk_tree_without_duplicates_1 (a, b, c, NULL)
extern tree get_base_address (tree t);
extern tree drop_tree_overflow (tree); 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 int tree_map_base_eq (const void *, const void *);
extern unsigned int tree_map_base_hash (const void *); extern unsigned int tree_map_base_hash (const void *);
extern int tree_map_base_marked_p (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) ...@@ -5052,12 +5078,6 @@ tree_int_cst_compare (const_tree t1, const_tree t2)
extern void set_decl_rtl (tree, rtx); extern void set_decl_rtl (tree, rtx);
extern bool complete_ctor_at_level_p (const_tree, HOST_WIDE_INT, const_tree); 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, /* Given an expression EXP that is a handled_component_p,
look for the ultimate containing object, which is returned and specify look for the ultimate containing object, which is returned and specify
the access position and size. */ the access position and size. */
...@@ -5065,10 +5085,7 @@ extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *, ...@@ -5065,10 +5085,7 @@ extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
tree *, machine_mode *, int *, int *, tree *, machine_mode *, int *, int *,
bool); bool);
/* Return a tree representing the lower bound of the array mentioned in extern tree build_personality_function (const char *);
EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
extern tree array_ref_low_bound (tree);
struct GTY(()) int_n_trees_t { struct GTY(()) int_n_trees_t {
/* These parts are initialized at runtime */ /* These parts are initialized at runtime */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment