Commit 491527af by Eric Botcazou Committed by Eric Botcazou

utils.c (fold_bit_position): New function.

	* gcc-interface/utils.c (fold_bit_position): New function.
	(rest_of_record_type_compilation): Call it instead of bit_position to
	compute the field position and remove the call to remove_conversions.
	(compute_related_constant): Factor out the multiplication in both
	operands, if any, and streamline the final test.

From-SVN: r245704
parent 0b9cdb9a
2017-02-24 Eric Botcazou <ebotcazou@adacore.com> 2017-02-24 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/utils.c (fold_bit_position): New function.
(rest_of_record_type_compilation): Call it instead of bit_position to
compute the field position and remove the call to remove_conversions.
(compute_related_constant): Factor out the multiplication in both
operands, if any, and streamline the final test.
2017-02-24 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/trans.c (return_value_ok_for_nrv_p): Add sanity check. * gcc-interface/trans.c (return_value_ok_for_nrv_p): Add sanity check.
2017-02-24 Eric Botcazou <ebotcazou@adacore.com> 2017-02-24 Eric Botcazou <ebotcazou@adacore.com>
......
...@@ -238,6 +238,7 @@ static GTY ((cache)) ...@@ -238,6 +238,7 @@ static GTY ((cache))
hash_table<pad_type_hasher> *pad_type_hash_table; hash_table<pad_type_hasher> *pad_type_hash_table;
static tree merge_sizes (tree, tree, tree, bool, bool); static tree merge_sizes (tree, tree, tree, bool, bool);
static tree fold_bit_position (const_tree);
static tree compute_related_constant (tree, tree); static tree compute_related_constant (tree, tree);
static tree split_plus (tree, tree *); static tree split_plus (tree, tree *);
static tree float_type_for_precision (int, machine_mode); static tree float_type_for_precision (int, machine_mode);
...@@ -2041,15 +2042,11 @@ rest_of_record_type_compilation (tree record_type) ...@@ -2041,15 +2042,11 @@ rest_of_record_type_compilation (tree record_type)
{ {
tree field_type = TREE_TYPE (old_field); tree field_type = TREE_TYPE (old_field);
tree field_name = DECL_NAME (old_field); tree field_name = DECL_NAME (old_field);
tree curpos = bit_position (old_field); tree curpos = fold_bit_position (old_field);
tree pos, new_field; tree pos, new_field;
bool var = false; bool var = false;
unsigned int align = 0; unsigned int align = 0;
/* We're going to do some pattern matching below so remove as many
conversions as possible. */
curpos = remove_conversions (curpos, true);
/* See how the position was modified from the last position. /* See how the position was modified from the last position.
There are two basic cases we support: a value was added There are two basic cases we support: a value was added
...@@ -2146,7 +2143,7 @@ rest_of_record_type_compilation (tree record_type) ...@@ -2146,7 +2143,7 @@ rest_of_record_type_compilation (tree record_type)
is when there are other components at fixed positions after is when there are other components at fixed positions after
it (meaning there was a rep clause for every field) and we it (meaning there was a rep clause for every field) and we
want to be able to encode them. */ want to be able to encode them. */
last_pos = size_binop (PLUS_EXPR, bit_position (old_field), last_pos = size_binop (PLUS_EXPR, curpos,
(TREE_CODE (TREE_TYPE (old_field)) (TREE_CODE (TREE_TYPE (old_field))
== QUAL_UNION_TYPE) == QUAL_UNION_TYPE)
? bitsize_zero_node ? bitsize_zero_node
...@@ -2201,23 +2198,51 @@ merge_sizes (tree last_size, tree first_bit, tree size, bool special, ...@@ -2201,23 +2198,51 @@ merge_sizes (tree last_size, tree first_bit, tree size, bool special,
return new_size; return new_size;
} }
/* Return the bit position of FIELD, in bits from the start of the record,
and fold it as much as possible. This is a tree of type bitsizetype. */
static tree
fold_bit_position (const_tree field)
{
tree offset = DECL_FIELD_OFFSET (field);
if (TREE_CODE (offset) == MULT_EXPR || TREE_CODE (offset) == PLUS_EXPR)
offset = size_binop (TREE_CODE (offset),
fold_convert (bitsizetype, TREE_OPERAND (offset, 0)),
fold_convert (bitsizetype, TREE_OPERAND (offset, 1)));
else
offset = fold_convert (bitsizetype, offset);
return size_binop (PLUS_EXPR, DECL_FIELD_BIT_OFFSET (field),
size_binop (MULT_EXPR, offset, bitsize_unit_node));
}
/* Utility function of above to see if OP0 and OP1, both of SIZETYPE, are /* Utility function of above to see if OP0 and OP1, both of SIZETYPE, are
related by the addition of a constant. Return that constant if so. */ related by the addition of a constant. Return that constant if so. */
static tree static tree
compute_related_constant (tree op0, tree op1) compute_related_constant (tree op0, tree op1)
{ {
tree op0_var, op1_var; tree factor, op0_var, op1_var, op0_cst, op1_cst, result;
tree op0_con = split_plus (op0, &op0_var);
tree op1_con = split_plus (op1, &op1_var);
tree result = size_binop (MINUS_EXPR, op0_con, op1_con);
if (operand_equal_p (op0_var, op1_var, 0)) if (TREE_CODE (op0) == MULT_EXPR
return result; && TREE_CODE (op1) == MULT_EXPR
else if (operand_equal_p (op0, size_binop (PLUS_EXPR, op1_var, result), 0)) && TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST
return result; && TREE_OPERAND (op1, 1) == TREE_OPERAND (op0, 1))
{
factor = TREE_OPERAND (op0, 1);
op0 = TREE_OPERAND (op0, 0);
op1 = TREE_OPERAND (op1, 0);
}
else else
return 0; factor = NULL_TREE;
op0_cst = split_plus (op0, &op0_var);
op1_cst = split_plus (op1, &op1_var);
result = size_binop (MINUS_EXPR, op0_cst, op1_cst);
if (operand_equal_p (op0_var, op1_var, 0))
return factor ? size_binop (MULT_EXPR, factor, result) : result;
return NULL_TREE;
} }
/* Utility function of above to split a tree OP which may be a sum, into a /* Utility function of above to split a tree OP which may be a sum, into a
......
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