On Wed, Jun 24, 2020 at 1:36 AM Gary Oblock via Gcc <[email protected]> wrote:
>
> I'm somehow misusing GIMPLE (probably in multiple ways) and I need
> some help in straightening out this little mess I've made.
>
> I'm trying to do the following:
>
> In an attempt at structure reorganization (instance interleaving) an
> array of structures is being transformed into a structure of arrays.
>
> for the simple example I'm using
> typedef struct type type_t;
> struct type {
> double x;
> double y;
> };
> .
> .
> type_t *data = (type_t *)malloc( len * sizeof(type_t));
> .
> .
> result = data[i].y;
>
> Is transformed into this or something close to it
>
> typedef long _reorg_SP_ptr_type_type_t
> typedef struct _reorg_base_type_type_t _reorg_base_type_type_t
>
> struct _reorg_base_type_type_t {
> double *x;
> double *y;
> };
>
> _reorg_SP_ptr_type_type_t data;
>
> _reorg_base_type_type_t _reorg_base_var_type_t;
>
> // Note I'm ignoring a bunch of stuff that needs to happen
> // when a malloc fails..
> _reorg_base_var_type_t.x = (double*)malloc( len*sizeof(double));
> _reorg_base_var_type_t.y = (double*)malloc( len*sizeof(double));
>
> data = 0;
> .
> .
> double *temp = _reorg_base_var_type_t.y;
> result = temp[i];
>
> Now, believe it or not the the whole bit above, except for "result =
> data[i].y",
> seems to work just fine.
>
> I attempted to do this (result = data[i].y) via basically two different
> ways. One is using ARRAY_REF and in the other faking an array access with
> INDIRECT_REF. The first approach chokes on the fact that temp is a pointer
> and the second dies in ssa operand scanning because it doesn't have a case
> for INDIRECT_REF.
On GIMPLE there's no INDIRECT_REF but you have to use a MEM_REF
instead. I'd use an ARRAY_REF and what you need to build is, in
-fdump-tree-XYZ-gimple (aka GIMPLE frontend) syntax:
temp_2 = _reorg_base_var_type_t.y;
result_3 = __MEM <double[]> (temp_2)[i_4];
so for the ARRAY_REF you have to dereference temp but view it as
array type double[]. That is, the TREE_TYPE of the MEM_REF you
build should be the array type. You can build an array type from
the component type via build_array_type (component_type, NULL_TREE)/
> The code below shows both ways. What have I done wrong here and what to
> I need to do differently to get it to work?
>
> Thanks,
>
> Gary
>
> PS Please ignore the then case below.
>
> --------------------------------------------------------------------------------
> gimple_stmt_iterator gsi = gsi_for_stmt( stmt);
>
> // Dump for debugging
> print_gimple_stmt ( stderr, stmt, 0);
>
> tree lhs = gimple_assign_lhs( stmt);
> tree rhs = gimple_assign_rhs1( stmt);
>
> bool ro_on_left = tree_contains_a_reorgtype_p ( lhs, info);
>
> tree ro_side = ro_on_left ? lhs : rhs;
> tree nonro_side = ro_on_left ? rhs : lhs;
>
> switch ( recognize_op ( ro_side, info) ) // "a->f"
> {
> case ReorgOpT_Indirect:
> {
> tree orig_field = TREE_OPERAND( ro_side, 1);
> tree field_type = TREE_TYPE( orig_field);
> tree base = ri->instance_interleave.base;
>
> tree base_field =
> find_coresponding_field ( base, orig_field);
>
> tree base_field_type = TREE_TYPE( base_field);
>
> tree field_val_temp =
> make_temp_ssa_name( field_type, NULL, "field_val_temp");
>
> tree inner_op = TREE_OPERAND( ro_side, 0);
>
> // For either case generate common code:
>
> // field_array = _base.f
> tree field_arry_addr =
> make_temp_ssa_name( base_field_type, NULL, "field_arry_addr");
>
> tree rhs_faa = build3 ( COMPONENT_REF,
> //base_field_type, // This doesn't work
> ptr_type_node, // This seems bogus
> base,
> //base_field, // This doesn't work
> orig_field, // This seems bogus
> NULL_TREE);
>
> // Use this to access the array of element.
> gimple *get_field_arry_addr =
> gimple_build_assign( field_arry_addr, rhs_faa);
>
> // index = a
> tree index =
> make_temp_ssa_name( ri->pointer_rep, NULL, "index");
> gimple *get_index =
> gimple_build_assign( index, inner_op);
>
> gimple *temp_set;
> gimple *final_set;
>
> #if WITH_INDIRECT
> // offset = index * size_of_field
> tree size_of_field = TYPE_SIZE_UNIT ( base_field_type);
> tree offset = make_temp_ssa_name( sizetype, NULL, "offset");
>
> gimple *get_offset =
> gimple_build_assign ( offset, MULT_EXPR, index, size_of_field);
>
> // field_addr = field_array + offset
> // bug fix here (TBD) type must be *double not double
> tree field_addr =
> make_temp_ssa_name( base_field_type, NULL, "field_addr");
>
> gimple *get_field_addr =
> gimple_build_assign ( field_addr, PLUS_EXPR, field_arry_addr,
> offset);
> #endif
>
> if ( ro_on_left )
> {
> // With: a->f = rhs
> // Generate:
>
> // temp = rhs
> temp_set = gimple_build_assign( field_val_temp, rhs);
>
> #if WITH_INDIRECT
> // NOTE, THIS (MEM_REF) SHOULD NOT WORK (IGNORE THIS PLEASE!)
> // not tested yet! I know THIS bit won't work.
> // *field_addr = temp
> tree lhs_ref = build1 ( MEM_REF, field_type, field_addr);
> #else
> // field_arry_addr[index]
> tree lhs_ref =
> build4 ( ARRAY_REF, field_type, field_arry_addr, index,
> NULL_TREE, NULL_TREE);
> #endif
>
> // lhs = temp
> final_set =
> gimple_build_assign( lhs_ref, field_val_temp);
> }
> else
> {
> // With: lhs = a->f
> // Generate:
> // temp = *field_addr
> #if WITH_INDIRECT
> // I tried MEM_REF here and build1 had an internal error
> tree rhs_ref = build1 ( INDIRECT_REF, field_type, field_addr);
> #else
> tree rhs_ref =
> build4 ( ARRAY_REF, field_type, field_arry_addr, index,
> NULL_TREE, NULL_TREE);
> #endif
>
> temp_set =
> gimple_build_assign( field_val_temp, rhs_ref);
>
> // lhs = temp
> final_set = gimple_build_assign( lhs, field_val_temp);
> }
>
> // Dump for debugging
> print_gimple_stmt ( stderr, get_field_arry_addr, 0);
> print_gimple_stmt ( stderr, get_index, 0);
>
> #if WITH_INDIRECT
> print_gimple_stmt ( stderr, get_offset, 0);
> print_gimple_stmt ( stderr, get_field_addr, 0);
> #endif
>
> print_gimple_stmt ( stderr, temp_set, 0);
> print_gimple_stmt ( stderr, final_set, 0);
>
>
> gsi_insert_before( &gsi, get_field_arry_addr, GSI_SAME_STMT);
> gsi_insert_before( &gsi, get_index, GSI_SAME_STMT);
> #if WITH_INDIRECT
> gsi_insert_before( &gsi, get_offset, GSI_SAME_STMT);
> gsi_insert_before( &gsi, get_field_addr, GSI_SAME_STMT);
> #endif
> gsi_insert_before( &gsi, temp_set, GSI_SAME_STMT); // <<
> malformed???
> gsi_insert_before( &gsi, final_set, GSI_SAME_STMT);
>
>
> //delete stmt
> gsi_remove ( &gsi, true);
> } // end ReorgOpT_Indirect case
>
> break;
> } // end ReorgOpT_Indirect case
>
>
> case ReorgOpT_AryDir: // "x[i].f"
> // Not implemented in single pool
> internal_error ( "ReorgOpT_AryDir not possible");
> default:
> internal_error (
> "Reached operand default for ReorgOpT_Indirect");
>
> }
>
>
>
> CONFIDENTIALITY NOTICE: This e-mail message, including any attachments, is
> for the sole use of the intended recipient(s) and contains information that
> is confidential and proprietary to Ampere Computing or its subsidiaries. It
> is to be used solely for the purpose of furthering the parties' business
> relationship. Any review, copying, or distribution of this email (or any
> attachments thereto) is strictly prohibited. If you are not the intended
> recipient, please contact the sender immediately and permanently delete the
> original and any copies of this email and any attachments thereto.