diff options
author | Gary Oblock <gary@amperecomputing.com> | 2020-10-20 19:16:03 -0700 |
---|---|---|
committer | Gary Oblock <gary@amperecomputing.com> | 2020-10-20 19:16:03 -0700 |
commit | b9ead1555bd01538334670f61e17db3ac6baaafc (patch) | |
tree | bc6639be9feb0146c7569d9ad212fc5accb79f4e | |
parent | 674219861f103aafda2a2392b48cbf74617806d4 (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.c | 164 | ||||
-rw-r--r-- | gcc/ipa-structure-reorg.c | 136 | ||||
-rw-r--r-- | gcc/ipa-structure-reorg.h | 3 |
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, |