On Wed, Jun 24, 2020 at 1:36 AM Gary Oblock via Gcc <gcc@gcc.gnu.org> 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.