On Wed, 4 Apr 2012, Martin Jambor wrote:
> Hi everyone, especially Richi and Eric,
>
> I'd like to know what is your attitude to changing SRA's
> build_ref_for_model to what it once looked like, so that it produces
> COMPONENT_REFs only for bit-fields. The non-bit field handling was
> added in order to work-around problems when expanding non-aligned
> MEM_REFs on strict-alignment targets but that should not be a problem
> now and my experiments confirm that. Last week I successfully
> bootstrapped and tested this patch on sparc64-linux (with the
> temporary MEM_EXPR patch, not including Java), ia64-linux (without
> Ada), x86_64-linux, i686-linux and tested it on hppa-linux (only C and
> C++).
>
> The main downside of this change I see is that dumps would be a bit
> more difficult to read and understand when the fields disappear from
> them.
>
> The upsides are:
>
> - the expr field of SRA access was originally intended only for
> debugging (meaning both for compiler-produced debug info and
> debugging SRA). It was never intended to influence the memory
> accesses produced by SRA and when we create them artificially, the
> effects of the particular form are hard to reason about. If we
> ever lower bit-field accesses on gimple level, build_ref_for_model
> could go away completely (yeah, I know I'm getting carried way
> here).
>
> - If something like PR 51528 creeps up again and we need to create
> replacements of type returned by lang_hooks.types.type_for_mode,
> the produced MEM_REFs could simply have this type. OTOH, the
> current COMPONENT_REFs would require to be encapsulated in V_C_Es
> and that is quite a nightmare. I tried it in December, even made
> it work, but it was particularly ugly and needed some quite
> questionable uses of V_C_Es.
>
> - Well, it does the same thing and is much simpler, is it not?
>
> The patch fulfills the criteria to be committed and I can do it soon.
> OTOH, keeping it so on a number of platforms takes quite a lot of time
> (and has uncovered some non-related bugs) so I'd like to know whether
> it's worth it.
>
> Thanks,
>
> Martin
>
>
>
> 2012-03-20 Martin Jambor <[email protected]>
>
> * tree-sra.c (build_ref_for_model): Create COMPONENT_REFs only for
> bit-fields.
>
> Index: src/gcc/tree-sra.c
> ===================================================================
> *** src.orig/gcc/tree-sra.c
> --- src/gcc/tree-sra.c
> *************** build_ref_for_offset (location_t loc, tr
> *** 1489,1558 ****
> return fold_build2_loc (loc, MEM_REF, exp_type, base, off);
> }
>
> - DEF_VEC_ALLOC_P_STACK (tree);
> - #define VEC_tree_stack_alloc(alloc) VEC_stack_alloc (tree, alloc)
> -
> /* Construct a memory reference to a part of an aggregate BASE at the given
> ! OFFSET and of the type of MODEL. In case this is a chain of references
> ! to component, the function will replicate the chain of COMPONENT_REFs of
> ! the expression of MODEL to access it. GSI and INSERT_AFTER have the same
> ! meaning as in build_ref_for_offset. */
>
> static tree
> build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
> struct access *model, gimple_stmt_iterator *gsi,
> bool insert_after)
> {
> ! tree type = model->type, t;
> ! VEC(tree,stack) *cr_stack = NULL;
> !
> ! if (TREE_CODE (model->expr) == COMPONENT_REF)
> {
> ! tree expr = model->expr;
> !
> ! /* Create a stack of the COMPONENT_REFs so later we can walk them in
> ! order from inner to outer. */
> ! cr_stack = VEC_alloc (tree, stack, 6);
> !
> ! do {
> ! tree field = TREE_OPERAND (expr, 1);
> ! tree cr_offset = component_ref_field_offset (expr);
> ! HOST_WIDE_INT bit_pos
> ! = tree_low_cst (cr_offset, 1) * BITS_PER_UNIT
> ! + TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field));
>
> ! /* We can be called with a model different from the one associated
> ! with BASE so we need to avoid going up the chain too far. */
> ! if (offset - bit_pos < 0)
> ! break;
> !
> ! offset -= bit_pos;
> ! VEC_safe_push (tree, stack, cr_stack, expr);
> !
> ! expr = TREE_OPERAND (expr, 0);
> ! type = TREE_TYPE (expr);
> ! } while (TREE_CODE (expr) == COMPONENT_REF);
> }
> !
> ! t = build_ref_for_offset (loc, base, offset, type, gsi, insert_after);
> !
> ! if (TREE_CODE (model->expr) == COMPONENT_REF)
> ! {
> ! unsigned i;
> ! tree expr;
> !
> ! /* Now replicate the chain of COMPONENT_REFs from inner to outer. */
> ! FOR_EACH_VEC_ELT_REVERSE (tree, cr_stack, i, expr)
> ! {
> ! tree field = TREE_OPERAND (expr, 1);
> ! t = fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (field), t, field,
> ! TREE_OPERAND (expr, 2));
> ! }
> !
> ! VEC_free (tree, stack, cr_stack);
> ! }
> !
> ! return t;
> }
>
> /* Construct a memory reference consisting of component_refs and array_refs
> to
> --- 1489,1520 ----
> return fold_build2_loc (loc, MEM_REF, exp_type, base, off);
> }
>
> /* 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
> ! expr to access it. GSI and INSERT_AFTER have the same meaning as in
> ! build_ref_for_offset. */
>
> static tree
> build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT 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)))
I think you need to test DECL_BIT_FIELD_TYPE here
> {
> ! /* This access represents a bit-field. */
> ! tree t, exp_type;
>
> ! offset -= int_bit_position (TREE_OPERAND (model->expr, 1));
I'm not sure that offset is now byte-aligned for all the funny Ada
bit-layouted records. But maybe we don't even try to SRA those?
> ! exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
> ! t = build_ref_for_offset (loc, base, offset, exp_type, gsi,
> insert_after);
> ! return fold_build3_loc (loc, COMPONENT_REF, model->type, t,
> ! TREE_OPERAND (model->expr, 1), NULL_TREE);
> }
> ! else
> ! return build_ref_for_offset (loc, base, offset, model->type,
> ! gsi, insert_after);
> }
>
> /* Construct a memory reference consisting of component_refs and array_refs
> to
Otherwise I'm all for doing this change. I'd even go one step further
and lower bitfield accesses here in SRA - if the FIELD_DECL of the
bitfield COMPONENT_REF has a DECL_BIT_FIELD_REPRESENTATIVE access
that and extract the requested bits via a BIT_FIELD_REF on the RHS
(or do a RMW cycle for stores).
That would have been my first place to "lower" bitfield accesses anyway,
and maybe get rid of some restrictions of SRA that way.
Thanks,
Richard.