#include "coretypes.h"
#include "alloc-pool.h"
#include "tm.h"
-#include "toplev.h"
#include "tree.h"
#include "gimple.h"
#include "cgraph.h"
if (TREE_THIS_VOLATILE (fld)
|| !DECL_FIELD_OFFSET (fld) || !DECL_SIZE (fld)
|| !host_integerp (DECL_FIELD_OFFSET (fld), 1)
- || !host_integerp (DECL_SIZE (fld), 1))
+ || !host_integerp (DECL_SIZE (fld), 1)
+ || (DECL_BIT_FIELD (fld) && AGGREGATE_TYPE_P (ft)))
return true;
if (AGGREGATE_TYPE_P (ft)
/* Construct a memory reference to a part of an aggregate BASE at the given
OFFSET and of the same type as MODEL. In case this is a reference to a
- bit-field, the function will replicate the last component_ref of model's
+ component, the function will replicate the last COMPONENT_REF of model's
expr to access it. GSI and INSERT_AFTER have the same meaning as in
build_ref_for_offset. */
struct access *model, gimple_stmt_iterator *gsi,
bool insert_after)
{
- if (TREE_CODE (model->expr) == COMPONENT_REF
- && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
+ if (TREE_CODE (model->expr) == COMPONENT_REF)
{
- /* This access represents a bit-field. */
tree t, exp_type;
-
offset -= int_bit_position (TREE_OPERAND (model->expr, 1));
exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
t = build_ref_for_offset (loc, base, offset, exp_type, gsi, insert_after);
return repl;
}
+/* Return true if REF has a COMPONENT_REF with a bit-field field declaration
+ somewhere in it. */
+
+static inline bool
+contains_bitfld_comp_ref_p (const_tree ref)
+{
+ while (handled_component_p (ref))
+ {
+ if (TREE_CODE (ref) == COMPONENT_REF
+ && DECL_BIT_FIELD (TREE_OPERAND (ref, 1)))
+ return true;
+ ref = TREE_OPERAND (ref, 0);
+ }
+
+ return false;
+}
+
+/* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
+ bit-field field declaration somewhere in it. */
+
+static inline bool
+contains_vce_or_bfcref_p (const_tree ref)
+{
+ while (handled_component_p (ref))
+ {
+ if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
+ || (TREE_CODE (ref) == COMPONENT_REF
+ && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
+ return true;
+ ref = TREE_OPERAND (ref, 0);
+ }
+
+ return false;
+}
+
/* Examine both sides of the assignment statement pointed to by STMT, replace
them with a scalare replacement if there is one and generate copying of
replacements if scalarized aggregates have been used in the assignment. GSI
??? This should move to fold_stmt which we simply should
call after building a VIEW_CONVERT_EXPR here. */
if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
+ && !contains_bitfld_comp_ref_p (lhs)
&& !access_has_children_p (lacc))
{
lhs = build_ref_for_offset (loc, lhs, 0, TREE_TYPE (rhs),
gimple_assign_set_lhs (*stmt, lhs);
}
else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
- && !contains_view_convert_expr_p (rhs)
+ && !contains_vce_or_bfcref_p (rhs)
&& !access_has_children_p (racc))
rhs = build_ref_for_offset (loc, rhs, 0, TREE_TYPE (lhs),
gsi, false);
This is what the first branch does. */
if (gimple_has_volatile_ops (*stmt)
- || contains_view_convert_expr_p (rhs)
- || contains_view_convert_expr_p (lhs))
+ || contains_vce_or_bfcref_p (rhs)
+ || contains_vce_or_bfcref_p (lhs))
{
if (access_has_children_p (racc))
generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
while (i < access_count)
{
bool modification;
+ tree a1_alias_type;
access = VEC_index (access_p, access_vec, i);
modification = access->write;
if (access_precludes_ipa_sra_p (access))
return NULL;
+ a1_alias_type = reference_alias_ptr_type (access->expr);
/* Access is about to become group representative unless we find some
nasty overlap which would preclude us from breaking this parameter
else if (ac2->size != access->size)
return NULL;
- if (access_precludes_ipa_sra_p (ac2))
+ if (access_precludes_ipa_sra_p (ac2)
+ || (ac2->type != access->type
+ && (TREE_ADDRESSABLE (ac2->type)
+ || TREE_ADDRESSABLE (access->type)))
+ || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
return NULL;
modification |= ac2->write;
adj->base_index = index;
adj->base = repr->base;
adj->type = repr->type;
+ adj->alias_ptr_type = reference_alias_ptr_type (repr->expr);
adj->offset = repr->offset;
adj->by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
&& (repr->grp_maybe_modified