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.

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