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.

Reply via email to