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 =
bu