summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Oblock <gary@amperecomputing.com>2020-10-20 19:16:03 -0700
committerGary Oblock <gary@amperecomputing.com>2020-10-20 19:16:03 -0700
commitb9ead1555bd01538334670f61e17db3ac6baaafc (patch)
treebc6639be9feb0146c7569d9ad212fc5accb79f4e
parent674219861f103aafda2a2392b48cbf74617806d4 (diff)
Almost every unit test is working now. Added changes
(recursive functions) to deal with tree operands like "_5->stuff.t.c[0]" and fixed other smaller issues.
-rw-r--r--gcc/ipa-str-reorg-instance-interleave.c164
-rw-r--r--gcc/ipa-structure-reorg.c136
-rw-r--r--gcc/ipa-structure-reorg.h3
3 files changed, 252 insertions, 51 deletions
diff --git a/gcc/ipa-str-reorg-instance-interleave.c b/gcc/ipa-str-reorg-instance-interleave.c
index e42e8a9dac8..e18b299b458 100644
--- a/gcc/ipa-str-reorg-instance-interleave.c
+++ b/gcc/ipa-str-reorg-instance-interleave.c
@@ -77,6 +77,8 @@ static void create_a_new_type ( Info_t *, tree);
static unsigned int reorg_perf_qual ( Info *);
static tree find_coresponding_field ( tree, tree);
static void remove_default_def ( tree, struct function *);
+static tree find_deepest_comp_ref ( tree);
+static tree create_deep_ref ( tree, tree, tree);
static void set_lhs_for ( gimple *, tree);
static basic_block make_bb ( char *, basic_block);
@@ -283,20 +285,34 @@ str_reorg_instance_interleave_trans ( Info *info)
{
case ReorgOpT_Indirect:
{
- tree orig_field = TREE_OPERAND( ro_side, 1);
- tree field_type = TREE_TYPE( orig_field);
+ // For deeply nested case we need the lowest.
+ tree lowest_comp_ref = find_deepest_comp_ref ( ro_side);
+ DEBUG_A("lowest_comp_ref = ");
+ DEBUG_F(flexible_print, stderr, lowest_comp_ref, 1, (dump_flags_t)0);
+ tree orig_field = TREE_OPERAND ( lowest_comp_ref, 1);
+ tree field_type = TREE_TYPE ( orig_field);
tree base = ri->instance_interleave.base;
+ DEBUG_A("orig_field, field_type, base = ");
+ DEBUG_F(flexible_print, stderr, orig_field, 2, (dump_flags_t)0);
+ DEBUG_F(flexible_print, stderr, field_type, 2, (dump_flags_t)0);
+ DEBUG_F(flexible_print, stderr, base, 1, (dump_flags_t)0);
tree base_field =
find_coresponding_field ( base, orig_field);
tree base_field_type = TREE_TYPE( base_field);
- gcc_assert ( field_type);
+ // The this changes because it the lowest field now
+ //gcc_assert ( field_type);
+ //tree field_val_temp =
+ // make_temp_ssa_name( field_type, NULL, "field_val_temp");
+ //tree top_field = TREE_OPERAND ( ro_side, 1);
+ //tree top_field_type = TREE_TYPE ( top_field);
+ tree top_field_type = TREE_TYPE ( ro_side);
tree field_val_temp =
- make_temp_ssa_name( field_type, NULL, "field_val_temp");
+ make_temp_ssa_name( top_field_type, NULL, "field_val_temp");
- tree inner_op = TREE_OPERAND( ro_side, 0);
+ tree inner_op = TREE_OPERAND( lowest_comp_ref, 0);
inner_op = TREE_OPERAND( inner_op, 0);
//DEBUG_L("inner_op: ");
//DEBUG_F( print_generic_expr, stderr, inner_op, (dump_flags_t)0);
@@ -306,6 +322,9 @@ str_reorg_instance_interleave_trans ( Info *info)
// field_array = _base.f
gcc_assert ( base_field_type);
+ // Note, this looks like trouble because this is a structure
+ // type for a deeply nested type. Maybe wrap it it in a
+ // pointer if deeply nested???
tree field_arry_addr =
make_temp_ssa_name( base_field_type, NULL, "field_arry_addr");
@@ -354,6 +373,14 @@ str_reorg_instance_interleave_trans ( Info *info)
gimple_build_assign ( field_addr, POINTER_PLUS_EXPR, field_arry_addr, offset);
SSA_NAME_DEF_STMT ( field_addr) = get_field_addr;
+ #if 0
+ // Tried other idioms here (tricky)
+ tree ref_expr = build2 ( MEM_REF, field_type, field_addr,
+ build_int_cst (ptr_type_node, 0));
+ #else
+ tree ref_expr = create_deep_ref ( ro_side, field_type, field_addr);
+ #endif
+
if ( ro_on_left )
{
// With: a->f = rhs
@@ -371,8 +398,7 @@ str_reorg_instance_interleave_trans ( Info *info)
// gimple_build_assign( elem_to_set, field_val_temp);
// *field_addr = temp
- tree lhs_ref = build2 ( MEM_REF, field_type, field_addr,
- build_int_cst (ptr_type_node, 0));
+ tree lhs_ref = ref_expr;
final_set =
gimple_build_assign( lhs_ref, field_val_temp);
@@ -382,16 +408,14 @@ str_reorg_instance_interleave_trans ( Info *info)
// With: lhs = a->f
// Generate:
- // Tried other idioms here (tricky)
- tree rhs_ref = build2 ( MEM_REF, field_type, field_addr,
- build_int_cst (ptr_type_node, 0));
-
+ tree rhs_ref = ref_expr;
// If these will actually print then things are likely sane
//DEBUG_L("rhs_ref: ");
//DEBUG_F(print_generic_expr, stderr, rhs_ref, (dump_flags_t)0);
//DEBUG("\n");
-
+
+ // These are here for debugging
tree op0 = TREE_OPERAND ( rhs_ref, 0);
tree op1 = TREE_OPERAND ( rhs_ref, 1);
tree op1type = TYPE_MAIN_VARIANT (TREE_TYPE (op1));
@@ -406,29 +430,29 @@ str_reorg_instance_interleave_trans ( Info *info)
SSA_NAME_DEF_STMT ( lhs) = final_set;
}
- //DEBUG_L("get_field_arry_addr: ");
- //DEBUG_F( print_gimple_stmt, stderr, get_field_arry_addr, 0);
- //DEBUG("\n");
+ DEBUG_L("get_field_arry_addr: ");
+ DEBUG_F( print_gimple_stmt, stderr, get_field_arry_addr, 0);
+ DEBUG("\n");
- //DEBUG_L("get_index: ");
- //DEBUG_F( print_gimple_stmt, stderr, get_index, 0);
- //DEBUG("\n");
+ DEBUG_L("get_index: ");
+ DEBUG_F( print_gimple_stmt, stderr, get_index, 0);
+ DEBUG("\n");
- //DEBUG_L("get_offset: ");
- //DEBUG_F( print_gimple_stmt, stderr, get_offset, 0);
- //DEBUG("\n");
+ DEBUG_L("get_offset: ");
+ DEBUG_F( print_gimple_stmt, stderr, get_offset, 0);
+ DEBUG("\n");
- //DEBUG_L("get_field_addr: ");
- //DEBUG_F( print_gimple_stmt, stderr, get_field_addr, 0);
- //DEBUG("\n");
+ DEBUG_L("get_field_addr: ");
+ DEBUG_F( print_gimple_stmt, stderr, get_field_addr, 0);
+ DEBUG("\n");
- //DEBUG_L("temp_set: ");
- //DEBUG_F( print_gimple_stmt, stderr, temp_set, 0);
- //DEBUG("\n");
+ DEBUG_L("temp_set: ");
+ DEBUG_F( print_gimple_stmt, stderr, temp_set, 0);
+ DEBUG("\n");
- //DEBUG_L("final_set: ");
- //DEBUG_F( print_gimple_stmt, stderr, final_set, 0);
- //DEBUG("\n");
+ DEBUG_L("final_set: ");
+ DEBUG_F( print_gimple_stmt, stderr, final_set, 0);
+ DEBUG("\n");
gsi_insert_before( &gsi, get_field_arry_addr, GSI_SAME_STMT);
gsi_insert_before( &gsi, get_index, GSI_SAME_STMT);
@@ -1724,6 +1748,86 @@ str_reorg_instance_interleave_trans ( Info *info)
return 0;
}
+static tree
+find_deepest_comp_ref ( tree comp_ref_expr )
+{
+ tree inner_op0 = TREE_OPERAND( comp_ref_expr, 0);
+ enum tree_code inner_op0_code = TREE_CODE ( inner_op0);
+ if ( inner_op0_code == COMPONENT_REF )
+ {
+ return find_deepest_comp_ref ( inner_op0);
+ }
+ else if ( inner_op0_code == MEM_REF )
+ {
+ return comp_ref_expr;
+ }
+ gcc_assert (0);
+}
+
+static tree
+create_deep_ref ( tree old_ref, tree field_type, tree field_addr )
+{
+ DEBUG_A("create_deep_ref: ");
+ DEBUG_F(flexible_print, stderr, old_ref, 1, (dump_flags_t)0);
+ INDENT(4);
+ tree inner_op0 = TREE_OPERAND( old_ref, 0);
+ enum tree_code inner_op0_code = TREE_CODE ( inner_op0);
+ enum tree_code top_code = TREE_CODE ( old_ref);
+ if ( inner_op0_code == MEM_REF )
+ {
+ tree deepest =
+ build2 ( MEM_REF, field_type, field_addr,
+ build_int_cst (ptr_type_node, 0));
+
+ INDENT(-4);
+ DEBUG_A("returns deepest: ");
+ DEBUG_F(flexible_print, stderr, deepest, 1, (dump_flags_t)0);
+
+ return deepest;
+ }
+ else if ( top_code == COMPONENT_REF )
+ {
+ tree lower_comp_part =
+ create_deep_ref ( inner_op0, field_type, field_addr);
+ tree level_field = TREE_OPERAND( old_ref, 1);;
+ tree level_field_type = TREE_TYPE ( level_field);
+ tree component_layer =
+ build3 ( COMPONENT_REF,
+ level_field_type,
+ lower_comp_part,
+ level_field,
+ NULL_TREE);
+
+ INDENT(-4);
+ DEBUG_A("returns component_layer: ");
+ DEBUG_F(flexible_print, stderr, component_layer, 1, (dump_flags_t)0);
+
+ return component_layer;
+ }
+ else if ( top_code == ARRAY_REF )
+ {
+ tree lower_array_part =
+ create_deep_ref ( inner_op0, field_type, field_addr);
+
+ tree array_index = TREE_OPERAND( old_ref, 1);
+ tree elem_type = TREE_TYPE ( old_ref);
+
+ tree array_layer =
+ build4 ( ARRAY_REF,
+ elem_type,
+ lower_array_part,
+ array_index,
+ NULL_TREE, NULL_TREE);
+
+ INDENT(-4);
+ DEBUG_A("returns array_layer: ");
+ DEBUG_F(flexible_print, stderr, array_layer, 1, (dump_flags_t)0);
+
+ return array_layer;
+ }
+ gcc_assert (0);
+}
+
// Note, the following code might be a bit overly simplistic.
static void
set_lhs_for ( gimple *stmt, tree ssa_name)
diff --git a/gcc/ipa-structure-reorg.c b/gcc/ipa-structure-reorg.c
index 85790039111..72131dc203f 100644
--- a/gcc/ipa-structure-reorg.c
+++ b/gcc/ipa-structure-reorg.c
@@ -1791,7 +1791,16 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info )
case ReorgOpT_AryDir: // "x[i].f"
return ReorgT_ElemAssign;
case ReorgOpT_Cst0:
- return ReorgT_Ptr2Zero;
+ {
+ if ( is_reorg_type ( TREE_TYPE (lhs), info) )
+ {
+ return ReorgT_Ptr2Zero;
+ }
+ else
+ {
+ return ReorgT_ElemAssign;
+ }
+ }
default:
return Not_Supported;
}
@@ -2115,27 +2124,24 @@ recognize_op ( tree op, bool lie, Info *info)
}
return recognize_op_ret_action ( ReorgOpT_Scalar);
}
- tree inner_op = TREE_OPERAND( op, 0);
- tree inner_type = TREE_TYPE ( inner_op);
- enum tree_code inner_op_code = TREE_CODE ( inner_op);
- DEBUG_L("inner_op = ");
- DEBUG_F(flexible_print, stderr, inner_op, 0, (dump_flags_t)0);
- DEBUG(", TREE_CODE = %s\n", code_str( inner_op_code));
+ tree inner_op0 = TREE_OPERAND( op, 0);
+ tree inner_op0_type = TREE_TYPE ( inner_op0);
+ enum tree_code inner_op0_code = TREE_CODE ( inner_op0);
if ( op_code == ADDR_EXPR )
{
DEBUG_L("op_code == ADDR_EXPR\n");
- if ( inner_op_code == ARRAY_REF )
+ if ( inner_op0_code == ARRAY_REF )
{
- bool a_reorg = is_reorg_type ( inner_op, info);
+ bool a_reorg = is_reorg_type ( inner_op0, info);
if ( a_reorg || !lie )
{
return recognize_op_ret_action ( ReorgOpT_Address);
}
}
// TBD shouldn't we be testing for a reorg???
- if ( inner_op_code == VAR_DECL )
+ if ( inner_op0_code == VAR_DECL )
{
- tree var_type = TREE_TYPE ( inner_op );
+ tree var_type = TREE_TYPE ( inner_op0 );
bool a_reorg = is_reorg_type ( var_type, info);
if ( a_reorg || !lie )
{
@@ -2145,9 +2151,26 @@ recognize_op ( tree op, bool lie, Info *info)
}
if ( op_code == COMPONENT_REF )
{
- DEBUG_L("op_code == COMPONENT_REF\n");
+ DEBUG_L("process: COMPONENT_REF\n");
+ tree inner_op1 = TREE_OPERAND( op, 1);
+ enum tree_code inner_op1_code = TREE_CODE ( inner_op1);
- if ( inner_op_code == INDIRECT_REF )
+ DEBUG_L("inner_op1 = ");
+ DEBUG_F(flexible_print, stderr, inner_op1, 0, (dump_flags_t)0);
+ DEBUG(", TREE_CODE = %s\n", code_str( inner_op1_code));
+
+ if ( tree deep_type = multilevel_component_ref ( op) )
+ {
+ DEBUG_L("Is multilevel component ref\n");
+ bool a_reorg = is_reorg_type ( base_type_of ( deep_type), info);
+ if ( a_reorg || !lie )
+ {
+ return recognize_op_ret_action ( ReorgOpT_Indirect);
+ }
+ // Just normal field reference otherwise...
+ return recognize_op_ret_action ( ReorgOpT_Scalar);
+ }
+ if ( inner_op0_code == INDIRECT_REF )
{
DEBUG_L("TREE_CODE( inner_op) == INDIRECT_REF\n");
bool a_reorg = is_reorg_type ( base_type_of ( type), info);
@@ -2158,9 +2181,9 @@ recognize_op ( tree op, bool lie, Info *info)
// Just normal field reference otherwise...
return recognize_op_ret_action ( ReorgOpT_Scalar);
}
- if ( inner_op_code == MEM_REF ) {
+ if ( inner_op0_code == MEM_REF ) {
DEBUG_L("TREE_CODE( inner_op) == MEM_REF\n");
- bool a_reorg = is_reorg_type ( base_type_of ( inner_type), info);
+ bool a_reorg = is_reorg_type ( base_type_of ( inner_op0_type), info);
if ( a_reorg || !lie )
{
return recognize_op_ret_action ( ReorgOpT_Indirect);
@@ -2168,11 +2191,30 @@ recognize_op ( tree op, bool lie, Info *info)
// Just normal field reference otherwise...
return recognize_op_ret_action ( ReorgOpT_Scalar);
}
- DEBUG_L("TREE_CODE( inner_op) not INDIRECT_REF or MEM_REF\n");
+ if ( inner_op0_code == COMPONENT_REF ) {
+ DEBUG_L("TREE_CODE( inner_op) == COMPONENT_REF\n");
+ tree inner_op0_0 = TREE_OPERAND ( inner_op0, 0);
+ tree inner_op0_0_type = TREE_TYPE ( inner_op0_0);
+ DEBUG_L("inner_op0_0 = ");
+ DEBUG_F(flexible_print, stderr, inner_op0_0, 0, (dump_flags_t)0);
+ DEBUG(" type = ");
+ DEBUG_F(flexible_print, stderr, inner_op0_0_type, 0, (dump_flags_t)0);
+ DEBUG(", TREE_CODE = %s\n", code_str( inner_op0_code));
+
+
+ bool a_reorg = is_reorg_type ( base_type_of ( inner_op0_0_type), info);
+ if ( a_reorg || !lie )
+ {
+ return recognize_op_ret_action ( ReorgOpT_Indirect);
+ }
+ // Just normal field reference otherwise...
+ return recognize_op_ret_action ( ReorgOpT_Scalar);
+ }
+ DEBUG_L("TREE_CODE( inner_op) not indirect, component or mem ref\n");
// Note, doesn't this ignore ARRAY_REF of this?
// I think it's OK at least until we start supporting
// multi-pools.
- bool a_reorg = is_reorg_type ( base_type_of ( inner_type), info);
+ bool a_reorg = is_reorg_type ( base_type_of ( inner_op0_type), info);
if ( a_reorg || !lie )
{
return recognize_op_ret_action ( ReorgOpT_AryDir);
@@ -2182,7 +2224,29 @@ recognize_op ( tree op, bool lie, Info *info)
}
if ( op_code == ARRAY_REF )
{
- DEBUG_L("op_code == ARRAY_REF\n");
+ DEBUG_L("process: ARRAY_REF\n");
+ tree inner_op1 = TREE_OPERAND( op, 1);
+ tree inner_op1_type = TREE_TYPE ( inner_op1);
+ DEBUG_A("inner_op0, inner_op0_type = ");
+ DEBUG_F(flexible_print, stderr, inner_op0, 2, (dump_flags_t)0);
+ DEBUG_F(flexible_print, stderr, inner_op0_type, 1, (dump_flags_t)0);
+
+ DEBUG_A("inner_op1, inner_op1_type = ");
+ DEBUG_F(flexible_print, stderr, inner_op1, 2, (dump_flags_t)0);
+ DEBUG_F(flexible_print, stderr, inner_op1_type, 1, (dump_flags_t)0);
+
+ if ( tree deep_type = multilevel_component_ref ( op) )
+ {
+ DEBUG_L("Is multilevel component ref (with array)\n");
+ bool a_reorg = is_reorg_type ( base_type_of ( deep_type), info);
+ if ( a_reorg || !lie )
+ {
+ return recognize_op_ret_action ( ReorgOpT_Indirect);
+ }
+ // Just normal field reference otherwise...
+ return recognize_op_ret_action ( ReorgOpT_Scalar);
+ }
+
bool a_reorg = is_reorg_type( base_type_of ( type), info);
if ( a_reorg || !lie )
{
@@ -2192,7 +2256,7 @@ recognize_op ( tree op, bool lie, Info *info)
}
if( op_code == INDIRECT_REF )
{
- DEBUG_L("op_code == INDIRECT_REF\n");
+ DEBUG_L("process: INDIRECT_REF\n");
// Do we want to chase the base type?
// No, we care about (and transform) just
// *r and not **...r (where r is a ReorgType.)
@@ -2206,6 +2270,33 @@ recognize_op ( tree op, bool lie, Info *info)
return recognize_op_ret_action ( ReorgOpT_Scalar);
}
+tree
+multilevel_component_ref ( tree op)
+{
+ DEBUG_A("multilevel_component_ref: ");
+ DEBUG_F(flexible_print, stderr, op, 1, (dump_flags_t)0);
+ DEBUG_F(flexible_print, stderr, op, 1, (dump_flags_t)0);
+ tree inner_op0 = TREE_OPERAND( op, 0);
+ //tree inner_op1 = TREE_OPERAND( op, 1);
+ enum tree_code inner_op0_code = TREE_CODE ( inner_op0);
+ if ( inner_op0_code == COMPONENT_REF || inner_op0_code == ARRAY_REF )
+ {
+ return multilevel_component_ref ( inner_op0);
+ }
+ else
+ if ( inner_op0_code == MEM_REF )
+ {
+ if ( TREE_CODE ( op) == COMPONENT_REF )
+ {
+ tree type = TREE_TYPE (inner_op0);
+ DEBUG_A(" found: %s, type: \n", code_str (inner_op0_code));
+ DEBUG_F(flexible_print, stderr, type, 1, (dump_flags_t)0);
+ return type;
+ }
+ }
+ return NULL;
+}
+
bool
is_reorg_type( tree rt, Info *info )
{
@@ -2953,6 +3044,10 @@ code_str( enum tree_code tc)
return "FUNCTION_DECL";
case RESULT_DECL:
return "RESULT_DECL";
+ case COMPONENT_REF:
+ return "COMPONENT_REF";
+ case INDIRECT_REF:
+ return "INDIRECT_REF";
default:
return get_tree_code_name ( tc);
switch( TREE_CODE_CLASS( tc) )
@@ -3174,7 +3269,8 @@ flexible_print( FILE *f, tree t, int nl, dump_flags_t d)
{
print_generic_expr(f,t,d);
}
- if ( nl ) fprintf ( f, "\n");
+ if ( nl == 1 ) fprintf ( f, "\n");
+ if ( nl == 2 ) fprintf ( f, ", ");
}
//---------------- Pass Control Follows ----------------
diff --git a/gcc/ipa-structure-reorg.h b/gcc/ipa-structure-reorg.h
index 43f6639fa8e..c44e785ef40 100644
--- a/gcc/ipa-structure-reorg.h
+++ b/gcc/ipa-structure-reorg.h
@@ -247,6 +247,7 @@ extern void print_reorg_with_msg ( FILE *, ReorgType_t *, int, const char *);
extern ReorgType_t *contains_a_reorgtype ( gimple *, Info *);
extern bool tree_contains_a_reorgtype_p ( tree, Info *);
extern ReorgType_t *tree_contains_a_reorgtype ( tree, Info *);
+extern tree multilevel_component_ref ( tree);
extern bool is_reorg_type ( tree, Info_t *);
extern tree base_type_of ( tree);
extern tree base_type_with_levels ( tree, int *);
@@ -264,7 +265,7 @@ extern bool is_assign_from_ssa ( gimple *);
// them in the code. However, some of the uses should obviously be
// converted to dump file information.
-#define DEBUGGING 0
+#define DEBUGGING 1
#if DEBUGGING
enum Display {
Show_nothing,