diff options
author | Gary Oblock <gary@amperecomputing.com> | 2020-10-25 23:54:37 -0700 |
---|---|---|
committer | Gary Oblock <gary@amperecomputing.com> | 2020-10-25 23:54:37 -0700 |
commit | 186053dd50d98e1592dcf65f9bde24717fd7e766 (patch) | |
tree | 127a3d18a97576405fc4c83bfa0bc77fd9f2f7d2 /gcc | |
parent | 604882c68ef1d9db7d3a67b285568d80124b7fa3 (diff) |
Added structure assignment transformation.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ipa-str-reorg-instance-interleave.c | 383 | ||||
-rw-r--r-- | gcc/ipa-structure-reorg.c | 385 |
2 files changed, 497 insertions, 271 deletions
diff --git a/gcc/ipa-str-reorg-instance-interleave.c b/gcc/ipa-str-reorg-instance-interleave.c index 0e53ed3d8fa..1e282749396 100644 --- a/gcc/ipa-str-reorg-instance-interleave.c +++ b/gcc/ipa-str-reorg-instance-interleave.c @@ -78,6 +78,7 @@ 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 void element_assign_transformation ( gimple *, ReorgType_t *, Info_t *); static void make_transformed_ref ( tree, ReorgType_t *, tree *, gimple_seq *, tree *, Info_t *); static tree find_deepest_comp_ref ( tree); static tree create_deep_ref ( tree, tree, tree); @@ -265,15 +266,104 @@ str_reorg_instance_interleave_trans ( Info *info) } } */ - break; - case ReorgT_ElemAssign: { - //break; gimple_stmt_iterator gsi = gsi_for_stmt( stmt); + tree lhs = gimple_assign_lhs( stmt); + tree rhs = gimple_assign_rhs1( stmt); + enum ReorgOpTrans left_op_trans = + recognize_op ( lhs, true, info); + enum ReorgOpTrans right_op_trans = + recognize_op ( rhs, true, info); + + // TBD lets rethink these + #if 0 + // Ignore meaningless case + if ( right_op_trans == ReorgOpT_Scalar + && left_op_trans == ReorgOpT_Scalar ) + break; + + // TBD Do these make sense? + if ( ( left_op_trans != ReorgOpT_Scalar + && + left_op_trans != ReorgOpT_Indirect ) + || + ( right_op_trans != ReorgOpT_Scalar + && + right_op_trans != ReorgOpT_Indirect )) + { + if ( left_op_trans == ReorgOpT_AryDir || + right_op_trans == ReorgOpT_AryDir ) + { + // Not implemented in single pool + internal_error ( "ReorgOpT_AryDir not possible"); + } + else + { + internal_error ( + "Reached tree operand default for " + "ReorgT_StrAssign"); + } + } + #endif + + bool ro_on_left = tree_contains_a_reorgtype_p ( lhs, info); + bool ro_on_right = tree_contains_a_reorgtype_p ( rhs, info); + + gcc_assert ( ro_on_left || ro_on_right); + + tree reorg_type = ri->gcc_type; + tree field; + for( field = TYPE_FIELDS( reorg_type); + field; + field = DECL_CHAIN( field)) + { + tree field_type = TREE_TYPE ( field); + + tree left_ref = + build3 ( COMPONENT_REF, + field_type, + lhs, + field, + NULL_TREE); + + tree right_ref = + build3 ( COMPONENT_REF, + field_type, + rhs, + field, + NULL_TREE); + + tree field_temp = + make_temp_ssa_name( field_type, NULL, "field_temp"); + + gimple *do_rhs = gimple_build_assign ( field_temp, right_ref); + SSA_NAME_DEF_STMT ( field_temp) = do_rhs; + + gimple *do_lhs = gimple_build_assign ( left_ref, field_temp); + + gsi_insert_before( &gsi, do_rhs, GSI_SAME_STMT); + + element_assign_transformation ( do_rhs, ri, info); + + gsi_insert_before( &gsi, do_lhs, GSI_SAME_STMT); + + element_assign_transformation ( do_lhs, ri, info); + } + gsi_remove ( &gsi, true); + } + break; + case ReorgT_ElemAssign: + { DEBUG_L("ReorgT_ElemAssign: "); DEBUG_F( print_gimple_stmt, stderr, stmt, 0); INDENT(2); + + #if 1 + element_assign_transformation (stmt, ri, info); + #else + gimple_stmt_iterator gsi = gsi_for_stmt( stmt); + // Needed for helloworld tree lhs = gimple_assign_lhs( stmt); tree rhs = gimple_assign_rhs1( stmt); @@ -366,10 +456,11 @@ str_reorg_instance_interleave_trans ( Info *info) internal_error ( "ReorgOpT_AryDir not possible"); default: internal_error ( - "Reached operand default for ReorgOpT_Indirect"); - - } // end recognize_op ( rhs, info) switch + "Reached tree operand default for " + "ReorgT_ElemAssign"); + } // end recognize_op ( rhs, info) switch + #endif INDENT(-2); } // end ReorgT_ElemAssign case break; @@ -1656,6 +1747,114 @@ str_reorg_instance_interleave_trans ( Info *info) return 0; } +static void +element_assign_transformation ( gimple *stmt, ReorgType_t *ri, Info_t *info) +{ + gimple_stmt_iterator gsi = gsi_for_stmt( stmt); + + DEBUG_L("element_assign_transformation: "); + DEBUG_F( print_gimple_stmt, stderr, stmt, 0); + INDENT(2); + // Needed for helloworld + 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, true, info) ) // "a->f" + { + case ReorgOpT_Indirect: + { + tree ref_expr; + tree field_val_temp; + gimple_seq ref_seq = NULL; + + make_transformed_ref ( ro_side, ri, &ref_expr, &ref_seq, &field_val_temp, info); + + gimple *temp_set; + gimple *final_set; + + if ( ro_on_left ) + { + // With: a->f = rhs + // Generate: + + // temp = rhs + temp_set = gimple_build_assign( field_val_temp, rhs); + SSA_NAME_DEF_STMT ( field_val_temp) = temp_set; + + //// field_array[index] = temp + //tree elem_to_set = + // build4 ( ARRAY_REF, field_type, field_arry_addr, index, + // NULL_TREE, NULL_TREE); + //final_set = + // gimple_build_assign( elem_to_set, field_val_temp); + + // *field_addr = temp + tree lhs_ref = ref_expr; + + final_set = + gimple_build_assign( lhs_ref, field_val_temp); + } + else + { + // With: lhs = a->f + // Generate: + + 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)); + tree op1type_type = TREE_TYPE ( op1type); + + temp_set = + gimple_build_assign( field_val_temp, rhs_ref); + SSA_NAME_DEF_STMT ( field_val_temp) = temp_set; + + // lhs = temp + final_set = gimple_build_assign( lhs, field_val_temp); + SSA_NAME_DEF_STMT ( lhs) = final_set; + } + + //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"); + + gsi_insert_seq_before ( &gsi, ref_seq, GSI_SAME_STMT); + gsi_insert_before( &gsi, temp_set, GSI_SAME_STMT); + gsi_insert_before( &gsi, final_set, GSI_SAME_STMT); + + //delete stmt + gsi_remove ( &gsi, true); + } // end ReorgOpT_Indirect case + break; + case ReorgOpT_AryDir: // "x[i].f" + // Not implemented in single pool + internal_error ( "ReorgOpT_AryDir not possible"); + default: + internal_error ( + "Reached tree operand default for " + "ReorgT_ElemAssign"); + + } // end recognize_op ( rhs, info) switch + + INDENT(-2); +} + // For ref_in which is a ReorgOpT_Indirect, create gimple // sequence to setup a transformed ref and the ref itself. static void @@ -2171,14 +2370,14 @@ reorg_perf_qual ( Info *info) for ( unsigned i = 0; i < loop->num_nodes; i++) { basic_block bb = bbs [i]; - //DEBUG_A("BB %i:\n", bb->index); - //INDENT(4); + DEBUG_A("BB %i:\n", bb->index); + INDENT(4); for ( auto gsi = gsi_start_bb ( bb); !gsi_end_p ( gsi); gsi_next ( &gsi) ) { gimple *stmt = gsi_stmt ( gsi); - //DEBUG_A("examine: "); - //DEBUG_F ( print_gimple_stmt, stderr, stmt, TDF_DETAILS); - //INDENT(4); + DEBUG_A("examine: "); + DEBUG_F ( print_gimple_stmt, stderr, stmt, TDF_DETAILS); + INDENT(4); if ( gimple_code ( stmt) == GIMPLE_LABEL || gimple_code ( stmt) == GIMPLE_SWITCH ) continue; @@ -2191,8 +2390,8 @@ reorg_perf_qual ( Info *info) op = gimple_op ( stmt, ith_op); // It's lieing about the number of operands... so... if ( op == NULL ) continue; - //DEBUG_A("op[%d]: %p, ", ith_op, op); - //DEBUG_F(flexible_print, stderr, op, 1, (dump_flags_t)0); + DEBUG_A("op[%d]: %p, ", ith_op, op); + DEBUG_F(flexible_print, stderr, op, 1, (dump_flags_t)0); ReorgType_t *tri = tree_contains_a_reorgtype ( op, info); enum ReorgOpTrans optran = recognize_op ( op, false, info); // TBD This is where we need to remember @@ -2200,15 +2399,15 @@ reorg_perf_qual ( Info *info) const char *s = optrans_to_str( optran); // Commenting out these 3 debug commands causes a // regression - //DEBUG_A(", %s\n", s); + DEBUG_A(", %s\n", s); if ( tri != NULL ) { - //DEBUG(", "); - //DEBUG_F(print_reorg, stderr, 0, tri); + DEBUG(", "); + DEBUG_F(print_reorg, stderr, 0, tri); } else { - //DEBUG("\n"); + DEBUG("\n"); ; } switch ( optran) @@ -2249,36 +2448,36 @@ reorg_perf_qual ( Info *info) missing_cases = true; } } - //INDENT(-4); + INDENT(-4); } - //INDENT(-4); + INDENT(-4); } - //DEBUG_L("Dumping acc_info:\n"); + DEBUG_L("Dumping acc_info:\n"); for ( auto aci = acc_info.begin (); aci != acc_info.end (); aci++ ) { - //DEBUG_A("variable:\n"); - //DEBUG_F( tell_me_about_ssa_name, (*aci).access, debug_indenting + 4); - //DEBUG_A("field: "); - //DEBUG_F( flexible_print, stderr, (*aci).field, 1, (dump_flags_t)0); + DEBUG_A("variable:\n"); + DEBUG_F( tell_me_about_ssa_name, (*aci).access, debug_indenting + 4); + DEBUG_A("field: "); + DEBUG_F( flexible_print, stderr, (*aci).field, 1, (dump_flags_t)0); } - //DEBUG_A("before sort: \n"); - //DEBUG_F(print_acc_infos, stderr, acc_info ); + DEBUG_A("before sort: \n"); + DEBUG_F(print_acc_infos, stderr, acc_info ); // Sort and compact the access infos. stable_sort ( acc_info.begin (), acc_info.end (), acc_lt); - //DEBUG_A("before compress: \n"); - //DEBUG_F(print_acc_infos, stderr, acc_info ); + DEBUG_A("before compress: \n"); + DEBUG_F(print_acc_infos, stderr, acc_info ); // Sort and compact the access infos. std::stable_sort ( acc_info.begin (), acc_info.end (), acc_lt); compress_acc_infos ( acc_info ); - //DEBUG_A("after compress: \n"); - //DEBUG_F(print_acc_infos, stderr, acc_info ); + DEBUG_A("after compress: \n"); + DEBUG_F(print_acc_infos, stderr, acc_info ); // Obtain loop count by looking at all the block counts. unsigned loop_count = 0; @@ -2287,8 +2486,8 @@ reorg_perf_qual ( Info *info) basic_block bb = bbs [i]; loop_count = MAX( loop_count, bb->count.value ()); } - //DEBUG_L("loop_count = %d, nb_iterations_estimate = %ld\n", - // loop_count, loop->nb_iterations_estimate); + DEBUG_L("loop_count = %d, nb_iterations_estimate = %ld\n", + loop_count, loop->nb_iterations_estimate); // Create the variable infos varInfo_t var_entry; @@ -2325,12 +2524,12 @@ reorg_perf_qual ( Info *info) { fprintf ( stderr, "%d VarInfos\n", var_info.size ()); } - //DEBUG_F(print_var_infos, stderr, var_info); + DEBUG_F(print_var_infos, stderr, var_info); // // Model the performance // - //DEBUG_A("Model The Performance\n"); + DEBUG_A("Model The Performance\n"); // Originally this was done per bb but now it has to be per // loop. TBD But perf_bb is per loop so we need something similar @@ -2342,16 +2541,16 @@ reorg_perf_qual ( Info *info) ReorgType_t *ri = pvi->rep_access->reorg; // Reorg accounting - //DEBUG_L("\n"); - //DEBUG_A("Reorg Accounting\n"); + DEBUG_L("\n"); + DEBUG_A("Reorg Accounting\n"); if( ri != NULL ) { double reorg_nca = 0.0; - //DEBUG_A(" for: "); - //DEBUG_F( flexible_print, stderr, ri->gcc_type, 1, (dump_flags_t)0); - //INDENT(4); + DEBUG_A(" for: "); + DEBUG_F( flexible_print, stderr, ri->gcc_type, 1, (dump_flags_t)0); + INDENT(4); for ( auto fldi = pvi->fields.begin (); fldi != pvi->fields.end (); fldi++ ) { unsigned HOST_WIDE_INT fld_width = @@ -2359,18 +2558,18 @@ reorg_perf_qual ( Info *info) double effect = alignment_effect ( fld_width); double product = loop_count * effect; reorg_nca += product; - //DEBUG_A("Add loop_count * effect (%d * %f = %f) to reorg_nca (now %f)\n", - // loop_count, effect, product, reorg_nca); + DEBUG_A("Add loop_count * effect (%d * %f = %f) to reorg_nca (now %f)\n", + loop_count, effect, product, reorg_nca); } - //INDENT(-4); + INDENT(-4); ri->instance_interleave.reorg_perf += reorg_nca; - //DEBUG_A("Add reorg_nca (%f) to reorg_perf (now %e)\n", - // reorg_nca, ri->instance_interleave.reorg_perf); + DEBUG_A("Add reorg_nca (%f) to reorg_perf (now %e)\n", + reorg_nca, ri->instance_interleave.reorg_perf); } // 699 // regular accounting - //DEBUG_L("\n"); - //DEBUG_A("Regular Accounting\n"); + DEBUG_L("\n"); + DEBUG_A("Regular Accounting\n"); double regular_nca = 0.0; sbitmap cache_model = sbitmap_alloc(1); @@ -2381,12 +2580,12 @@ reorg_perf_qual ( Info *info) tree base_type; // = base_type_of ( access); if ( pv2i->rep_access->reorg != NULL ) { - //DEBUG_A("Base type from reorg: "); + DEBUG_A("Base type from reorg: "); base_type = pv2i->rep_access->reorg->gcc_type; } else { - //DEBUG_A("Base type from access: "); + DEBUG_A("Base type from access: "); if ( TREE_TYPE ( access ) != NULL ) { base_type = base_type_of ( access); @@ -2396,7 +2595,7 @@ reorg_perf_qual ( Info *info) gcc_assert (0); } } - //DEBUG_F( flexible_print, stderr, base_type, 1, (dump_flags_t)0); + DEBUG_F( flexible_print, stderr, base_type, 1, (dump_flags_t)0); bool base_type_isa_decl = DECL_P ( base_type ); @@ -2406,31 +2605,31 @@ reorg_perf_qual ( Info *info) tree base_type_size; if ( base_type_isa_decl ) { - //DEBUG_A("decl\n"); + DEBUG_A("decl\n"); switch ( TREE_CODE (base_type) ) { case VAR_DECL: { - //DEBUG_A("VAR_DECL\n"); + DEBUG_A("VAR_DECL\n"); base_type_size = TYPE_SIZE_UNIT ( base_type); break; } case FIELD_DECL: { - //DEBUG_A("VAR_DECL\n"); + DEBUG_A("VAR_DECL\n"); base_type_size = TYPE_SIZE_UNIT ( TREE_TYPE ( base_type)); break; } default: { - //DEBUG_A("other decl %s\n", code_str(TREE_CODE (base_type))); + DEBUG_A("other decl %s\n", code_str(TREE_CODE (base_type))); gcc_assert(0); } } } else { - //DEBUG_A("nondecl %s\n", code_str(TREE_CODE (base_type))); + DEBUG_A("nondecl %s\n", code_str(TREE_CODE (base_type))); if ( TREE_CODE ( base_type) == SSA_NAME ) { base_type_size = TYPE_SIZE_UNIT ( TREE_TYPE( base_type)); @@ -2449,10 +2648,10 @@ reorg_perf_qual ( Info *info) param_l1_cache_line_size) + 1; - //DEBUG_L("\n"); - //DEBUG_A("cache len = %d (lines), for: ", len); - //DEBUG_F( flexible_print, stderr, base_type, 0, (dump_flags_t)0); - //DEBUG("%sstruct\n") + DEBUG_L("\n"); + DEBUG_A("cache len = %d (lines), for: ", len); + DEBUG_F( flexible_print, stderr, base_type, 0, (dump_flags_t)0); + DEBUG("%sstruct\n") // TBD Does this clear the bits??? It needs to. // Each bit represents a cache line. @@ -2474,14 +2673,14 @@ reorg_perf_qual ( Info *info) // why this is here and what it does. Sigh... unsigned HOST_WIDE_INT base_offset = tree_to_uhwi ( DECL_FIELD_OFFSET( field_ex)); - //DEBUG_L("\n"); - //DEBUG_A("For field_ex: "); - //DEBUG_F( flexible_print, stderr, field_ex, 0, (dump_flags_t)0); - //DEBUG(", nrbo %d, base_offset %d\n", nrbo, base_offset); + DEBUG_L("\n"); + DEBUG_A("For field_ex: "); + DEBUG_F( flexible_print, stderr, field_ex, 0, (dump_flags_t)0); + DEBUG(", nrbo %d, base_offset %d\n", nrbo, base_offset); // Access accounting - //INDENT(4); + INDENT(4); for ( auto fldi = pv2i->fields.begin (); fldi != pv2i->fields.end (); fldi++ ) { @@ -2489,27 +2688,27 @@ reorg_perf_qual ( Info *info) unsigned HOST_WIDE_INT fld_width, fld_offset; fld_width = tree_to_uhwi ( DECL_SIZE ( field)); fld_offset = tree_to_uhwi ( DECL_FIELD_OFFSET ( field)); - //DEBUG_A("Field: "); - //DEBUG_F( flexible_print, stderr, field, 0, (dump_flags_t)0); - //DEBUG(", width = %d, offset = %d\n", fld_width, fld_offset); + DEBUG_A("Field: "); + DEBUG_F( flexible_print, stderr, field, 0, (dump_flags_t)0); + DEBUG(", width = %d, offset = %d\n", fld_width, fld_offset); + INDENT(4); int chari; - //INDENT(4); for ( chari = 0; chari < fld_width; chari++ ) { int loc = (chari + fld_offset + base_offset) / param_l1_cache_line_size; - //DEBUG_A("loc: %d\n", loc); + DEBUG_A("loc: %d\n", loc); bitmap_set_bit ( cache_model, loc); } - //INDENT(-4); + INDENT(-4); } - //INDENT(-4); + INDENT(-4); unsigned bcount = bitmap_count_bits ( cache_model); accum += bcount; - //DEBUG_L("\n"); - //DEBUG_A("Add popcount of cache (%d) to accum (now %f)\n", - // bcount, accum); + DEBUG_L("\n"); + DEBUG_A("Add popcount of cache (%d) to accum (now %f)\n", + bcount, accum); bitmap_clear ( cache_model); } } @@ -2517,22 +2716,22 @@ reorg_perf_qual ( Info *info) { nrbo = 1; accum++; - //DEBUG_L("\n"); - //DEBUG_A("nrbo = 1, increment accum to %f\n", accum); + DEBUG_L("\n"); + DEBUG_A("nrbo = 1, increment accum to %f\n", accum); } #if 1 double amount = accum / nrbo; double product = amount * loop_count; regular_nca += product; - //DEBUG_L("\n"); - //DEBUG_A("Add loop_count*accum/nrbo (%f*%f/%d = %f) to regular_nca (now %e)\n", - // loop_count, accum, nrbo, product, regular_nca); + DEBUG_L("\n"); + DEBUG_A("Add loop_count*accum/nrbo (%f*%f/%d = %f) to regular_nca (now %e)\n", + loop_count, accum, nrbo, product, regular_nca); #else double amount = accum / nrbo; regular_nca += amount; - //DEBUG_L("\n"); - //DEBUG_A("Add accum/nrbo (%f/%d = %f) to regular_nca (now %e)\n", - // accum, nrbo, amount, regular_nca); + DEBUG_L("\n"); + DEBUG_A("Add accum/nrbo (%f/%d = %f) to regular_nca (now %e)\n", + accum, nrbo, amount, regular_nca); #endif } // 739 sbitmap_free ( cache_model); @@ -2540,11 +2739,11 @@ reorg_perf_qual ( Info *info) if( ri != NULL ) { ri->instance_interleave.regular_perf += regular_nca; cache_accesses_noreorg += regular_nca; - //DEBUG_L("\n"); - //DEBUG_A("Add regular_nca (%f) to regular_perf (now %e)", - // regular_nca, ri->instance_interleave.regular_perf); - //DEBUG_A(" and to cache_accesses_noreorg (now %e)\n", - // cache_accesses_noreorg); + DEBUG_L("\n"); + DEBUG_A("Add regular_nca (%f) to regular_perf (now %e)", + regular_nca, ri->instance_interleave.regular_perf); + DEBUG_A(" and to cache_accesses_noreorg (now %e)\n", + cache_accesses_noreorg); } else { cache_accesses += regular_nca; } @@ -2991,7 +3190,7 @@ account_for_access ( tree access, tree field, std::vector <acc_info_t> *acc_info static void tmasn_helper ( tree t, int indent, std::set<tree> *already ) { - //DEBUG_A(""); + DEBUG_A(""); fprintf( stderr, "%*s", indent, " "); indent += 4; flexible_print ( stderr, t, 0, (dump_flags_t)0); @@ -3004,7 +3203,7 @@ tmasn_helper ( tree t, int indent, std::set<tree> *already ) { fprintf( stderr, "\n"); } - //DEBUG_L("code: %s\n", code_str(TREE_CODE (t))); + DEBUG_L("code: %s\n", code_str(TREE_CODE (t))); if ( TREE_CODE (t) == SSA_NAME ) { already->insert (t); @@ -3057,6 +3256,14 @@ tmasn_helper ( tree t, int indent, std::set<tree> *already ) tmasn_helper ( t_0 , indent, already); return; } + if ( TREE_CODE ( t) == COMPONENT_REF ) + { + tree t_0 = TREE_OPERAND ( t, 0); + fprintf ( stderr, "%*sCOMPONENT_REF t_0: ", indent, " "); + flexible_print ( stderr, t_0, 1, (dump_flags_t)0); + tmasn_helper ( t_0 , indent, already); + return; + } if ( TREE_CODE ( t) == INTEGER_CST ) return; fprintf ( stderr, "unanticipated TREE_CODE\n"); gcc_assert ( 0); diff --git a/gcc/ipa-structure-reorg.c b/gcc/ipa-structure-reorg.c index 7f692933a41..70b3d385053 100644 --- a/gcc/ipa-structure-reorg.c +++ b/gcc/ipa-structure-reorg.c @@ -1707,28 +1707,28 @@ undelete_reorgtype ( ReorgType_t *rt, Info *info ) ReorgTransformation reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info ) { - //DEBUG_L ( "ReorgTransformation reorg_recognize for: "); - //DEBUG_F ( print_gimple_stmt, stderr, stmt, 0); - //INDENT(2); + DEBUG_L ( "ReorgTransformation reorg_recognize for: "); + DEBUG_F ( print_gimple_stmt, stderr, stmt, 0); + INDENT(2); switch ( gimple_code( stmt) ) { case GIMPLE_ASSIGN: { - //DEBUG_L("GIMPLE_ASSIGN:\n"); + DEBUG_L("GIMPLE_ASSIGN:\n"); tree lhs = gimple_assign_lhs ( stmt); enum tree_code rhs_code = gimple_assign_rhs_code ( stmt); if ( gimple_assign_single_p ( stmt) ) { - //DEBUG_L("gimple_assign_single_p() = true\n"); - //INDENT(2); + DEBUG_L("gimple_assign_single_p() = true\n"); + INDENT(2); tree rhs = gimple_assign_rhs1 ( stmt); enum ReorgOpTrans lhs_op = recognize_op ( lhs, true, info); switch ( lhs_op ) { case ReorgOpT_Pointer: // "a" - //DEBUG_L("case ReorgOpT_Pointer\n"); - //INDENT(-4); + DEBUG_L("case ReorgOpT_Pointer\n"); + INDENT(-4); switch ( recognize_op ( rhs, true, info) ) { case ReorgOpT_Scalar: @@ -1749,8 +1749,8 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info ) return Not_Supported; } case ReorgOpT_Struct: // "s" - //DEBUG_L("case ReorgOpT_Struct\n"); - //INDENT(-4); + DEBUG_L("case ReorgOpT_Struct\n"); + INDENT(-4); switch ( recognize_op ( rhs, true, info) ) { case ReorgOpT_Deref: // "*a" @@ -1766,8 +1766,8 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info ) return Not_Supported; } case ReorgOpT_Deref: // "*a" - //DEBUG_L("case ReorgOpT_Deref\n"); - //INDENT(-4); + DEBUG_L("case ReorgOpT_Deref\n"); + INDENT(-4); switch ( recognize_op ( rhs, true, info) ) { case ReorgOpT_Deref: // "*a" @@ -1778,8 +1778,8 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info ) return Not_Supported; } case ReorgOpT_Array: // "x[i]" - //DEBUG_L("case ReorgOpT_Array\n"); - //INDENT(-4); + DEBUG_L("case ReorgOpT_Array\n"); + INDENT(-4); switch ( recognize_op ( rhs, true, info) ) { case ReorgOpT_Struct: // "s" @@ -1792,8 +1792,8 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info ) case ReorgOpT_Temp: // t case ReorgOpT_Scalar: // "z" { - //DEBUG_L("case ReorgOpT_%s\n", lhs_op == ReorgOpT_Temp ? "Temp" : "Scalar"); - //INDENT(-4); + DEBUG_L("case ReorgOpT_%s\n", lhs_op == ReorgOpT_Temp ? "Temp" : "Scalar"); + INDENT(-4); switch ( recognize_op( rhs, true, info) ) { case ReorgOpT_Scalar: // "z" @@ -1809,8 +1809,8 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info ) case ReorgOpT_Indirect: // "a->f" case ReorgOpT_AryDir: // "x[i].f" { - //DEBUG_L("case ReorgOpT_%s\n", lhs_op == ReorgOpT_Indirect ? "Indirect" : "AryDir"); - //INDENT(-4); + DEBUG_L("case ReorgOpT_%s\n", lhs_op == ReorgOpT_Indirect ? "Indirect" : "AryDir"); + INDENT(-4); switch ( recognize_op ( rhs, true, info) ) { case ReorgOpT_Cst: // k @@ -1838,24 +1838,24 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info ) return Not_Supported; } // switch ( recognize_op ( lhs, true, info) ) } else { - //DEBUG_L("gimple_assign_single_p() = false\n"); - //INDENT(2); + DEBUG_L("gimple_assign_single_p() = false\n"); + INDENT(2); tree op1 = gimple_assign_rhs1 ( stmt); tree op2 = gimple_assign_rhs2 ( stmt); - //DEBUG_L("op1 = %p, op2 = %p\n", op1, op2); - //DEBUG_A(""); - //DEBUG_F( flexible_print, stderr, op1, 1, TDF_DETAILS); + DEBUG_L("op1 = %p, op2 = %p\n", op1, op2); + DEBUG_A(""); + DEBUG_F( flexible_print, stderr, op1, 1, TDF_DETAILS); if ( CONVERT_EXPR_CODE_P ( gimple_assign_rhs_code ( stmt))) { - //DEBUG_L("CONVERT_EXPR_CODE_P (...)\n"); - //INDENT(-4); + DEBUG_L("CONVERT_EXPR_CODE_P (...)\n"); + INDENT(-4); return ReorgT_Convert; } if ( gimple_assign_rhs3 ( stmt) != NULL ) { - //DEBUG_L("gimple_assign_rhs3 ( stmt) != NULL\n"); - //INDENT(-4); + DEBUG_L("gimple_assign_rhs3 ( stmt) != NULL\n"); + INDENT(-4); return Not_Supported; } @@ -1865,8 +1865,8 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info ) ( (POINTER_TYPE_P ( TREE_TYPE( op1)) && integer_zerop ( op2)) || (POINTER_TYPE_P ( TREE_TYPE( op2)) && integer_zerop ( op1))) && ( integer_zerop ( op1) || integer_zerop ( op2) ); - //DEBUG_L("zero_case = %s\n", zero_case ? "true" : "false" ); - //INDENT(-4); + DEBUG_L("zero_case = %s\n", zero_case ? "true" : "false" ); + INDENT(-4); switch ( rhs_code ) { case POINTER_PLUS_EXPR: @@ -1892,8 +1892,8 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info ) } case GIMPLE_COND: // Similar to assign cases { - //DEBUG_L("GIMPLE_COND:\n"); - //INDENT(-2); + DEBUG_L("GIMPLE_COND:\n"); + INDENT(-2); //tree op1 = gimple_assign_rhs1 ( stmt); //tree op2 = gimple_assign_rhs2( stmt); tree op1 = gimple_cond_lhs ( stmt); @@ -1924,17 +1924,17 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info ) } case GIMPLE_CALL: { - //DEBUG_L("GIMPLE_CALL:\n"); + DEBUG_L("GIMPLE_CALL:\n"); struct cgraph_edge *edge = node->get_edge ( stmt); gcc_assert( edge); - //DEBUG_L("called function %s gimple_body\n", - // edge->callee->has_gimple_body_p() ? "has a" : "has no"); - //DEBUG_L("called function inline_to %s\n", - // edge->callee->inlined_to ? "true" : "false"); - //DEBUG_L("called function external %s\n", - // edge->callee->get_partitioning_class() == SYMBOL_EXTERNAL ? "true" : "false"); + DEBUG_L("called function %s gimple_body\n", + edge->callee->has_gimple_body_p() ? "has a" : "has no"); + DEBUG_L("called function inline_to %s\n", + edge->callee->inlined_to ? "true" : "false"); + DEBUG_L("called function external %s\n", + edge->callee->get_partitioning_class() == SYMBOL_EXTERNAL ? "true" : "false"); - //INDENT(-2); + INDENT(-2); if ( gimple_call_builtin_p( stmt, BUILT_IN_CALLOC ) ) return ReorgT_Calloc; if ( gimple_call_builtin_p( stmt, BUILT_IN_MALLOC ) ) return ReorgT_Malloc; if ( gimple_call_builtin_p( stmt, BUILT_IN_REALLOC) ) return ReorgT_Realloc; @@ -1947,23 +1947,24 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info ) if ( is_user_function ( stmt, node, info) ) { - //DEBUG_A(" ReorgT_UserFunc\n"); + DEBUG_A(" ReorgT_UserFunc\n"); return ReorgT_UserFunc; } //DEBUG_A(" Not_supported\n"); + // TBD Why is this commented out? //return Not_Supported; } break; case GIMPLE_RETURN: - //DEBUG_L("GIMPLE_RETURN:\n"); - //INDENT(-2); + DEBUG_L("GIMPLE_RETURN:\n"); + INDENT(-2); return ReorgT_Return; break; default: - //DEBUG_L ( "didn't support: "); - //DEBUG_F ( print_gimple_stmt, stderr, stmt, 0); - //DEBUG( "\n"); - //INDENT(-2); + DEBUG_L ( "didn't support: "); + DEBUG_F ( print_gimple_stmt, stderr, stmt, 0); + DEBUG( "\n"); + INDENT(-2); return Not_Supported; } } @@ -2070,17 +2071,17 @@ remove_deleted_types ( Info *info, ReorgFn reorg_fn) static enum ReorgOpTrans recognize_op_ret_action ( enum ReorgOpTrans e ) { - //DEBUG_A(" returns %s\n", optrans_to_str ( e)); + DEBUG_A(" returns %s\n", optrans_to_str ( e)); return e; } enum ReorgOpTrans recognize_op ( tree op, bool lie, Info *info) { - //DEBUG_L("recognize_op: "); - //DEBUG_F( flexible_print, stderr, op, 1, TDF_DETAILS); + DEBUG_L("recognize_op: "); + DEBUG_F( flexible_print, stderr, op, 1, TDF_DETAILS); enum tree_code op_code = TREE_CODE ( op); - //DEBUG_A("opcode = %s\n", code_str( op_code)); + DEBUG_A("opcode = %s\n", code_str( op_code)); switch ( op_code ) { case SSA_NAME: @@ -2106,6 +2107,9 @@ recognize_op ( tree op, bool lie, Info *info) } tree type = TREE_TYPE ( op); + DEBUG_A("type: "); + DEBUG_F(flexible_print, stderr, type, 1, (dump_flags_t)0); + // This type bases approach seems like crap. // I'm turning it off to see what breaks. #if 0 @@ -2157,161 +2161,184 @@ recognize_op ( tree op, bool lie, Info *info) 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 ) + switch ( op_code ) { - //DEBUG_L("op_code == ADDR_EXPR\n"); - if ( inner_op0_code == ARRAY_REF ) - { - bool a_reorg = is_reorg_type ( inner_op0, info); + case ADDR_EXPR: + { + //DEBUG_L("op_code == ADDR_EXPR\n"); + if ( inner_op0_code == ARRAY_REF ) + { + 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_op0_code == VAR_DECL ) - { - tree var_type = TREE_TYPE ( inner_op0 ); - bool a_reorg = is_reorg_type ( var_type, info); + } + // TBD shouldn't we be testing for a reorg??? + if ( inner_op0_code == VAR_DECL ) + { + tree var_type = TREE_TYPE ( inner_op0 ); + bool a_reorg = is_reorg_type ( var_type, info); + if ( a_reorg || !lie ) + { + return recognize_op_ret_action ( ReorgOpT_Address); + } + } + return recognize_op_ret_action ( ReorgOpT_Scalar); + } + case COMPONENT_REF: + { + DEBUG_L("process: COMPONENT_REF\n"); + tree inner_op1 = TREE_OPERAND( op, 1); + enum tree_code inner_op1_code = TREE_CODE ( inner_op1); + + 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: deep_type is "); + DEBUG_F(flexible_print, stderr, deep_type, 1, (dump_flags_t)0); + + 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); + 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 == MEM_REF ) { + DEBUG_L("TREE_CODE( inner_op) == MEM_REF\n"); + bool a_reorg = is_reorg_type ( base_type_of ( inner_op0_type), info); if ( a_reorg || !lie ) { - return recognize_op_ret_action ( ReorgOpT_Address); + return recognize_op_ret_action ( ReorgOpT_Indirect); } + // Just normal field reference otherwise... + return recognize_op_ret_action ( ReorgOpT_Scalar); } - } - if ( op_code == COMPONENT_REF ) - { - //DEBUG_L("process: COMPONENT_REF\n"); - tree inner_op1 = TREE_OPERAND( op, 1); - enum tree_code inner_op1_code = TREE_CODE ( inner_op1); - - //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 ( 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_op0_type), info); if ( a_reorg || !lie ) { - return recognize_op_ret_action ( ReorgOpT_Indirect); + return recognize_op_ret_action ( ReorgOpT_AryDir); } // 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); - 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 == MEM_REF ) { - //DEBUG_L("TREE_CODE( inner_op) == MEM_REF\n"); - bool a_reorg = is_reorg_type ( base_type_of ( inner_op0_type), info); - if ( a_reorg || !lie ) + case ARRAY_REF: { - return recognize_op_ret_action ( ReorgOpT_Indirect); - } - // Just normal field reference otherwise... - return recognize_op_ret_action ( ReorgOpT_Scalar); - } - 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); + 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 ) + { + return recognize_op_ret_action ( ReorgOpT_Array); + } + return recognize_op_ret_action ( ReorgOpT_Scalar); } - // 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_op0_type), info); - if ( a_reorg || !lie ) + case INDIRECT_REF: { - return recognize_op_ret_action ( ReorgOpT_AryDir); + 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.) + bool a_reorg = is_reorg_type ( type, info); + if( a_reorg || !lie ) + { + return recognize_op_ret_action ( ReorgOpT_Deref); + } + return recognize_op_ret_action ( ReorgOpT_Scalar); } - // Just normal field reference otherwise... - return recognize_op_ret_action ( ReorgOpT_Scalar); - } - if ( op_code == ARRAY_REF ) - { - //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) ) + case MEM_REF: { - //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 ) + DEBUG_L("process: MEF_REF\n"); + DEBUG_A("inner_op0, inner_op0_type = "); + DEBUG_F( flexible_print, stderr, inner_op0, 0, TDF_DETAILS); + DEBUG_F( flexible_print, stderr, inner_op0_type, 1, TDF_DETAILS); + bool a_reorg = is_reorg_type ( type, info); + if( a_reorg || !lie ) { - return recognize_op_ret_action ( ReorgOpT_Indirect); + return recognize_op_ret_action ( ReorgOpT_Struct); } - // 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 ) - { - return recognize_op_ret_action ( ReorgOpT_Array); - } - return recognize_op_ret_action ( ReorgOpT_Scalar); - } - if( op_code == INDIRECT_REF ) - { - //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.) - bool a_reorg = is_reorg_type ( type, info); - if( a_reorg || !lie ) - { - return recognize_op_ret_action ( ReorgOpT_Deref); + default: + return recognize_op_ret_action ( ReorgOpT_Scalar); } - return recognize_op_ret_action ( ReorgOpT_Scalar); - } - 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); + 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); + INDENT(2); 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); + tree ret = multilevel_component_ref ( inner_op0); + INDENT(-2); + return ret; } else if ( inner_op0_code == MEM_REF ) @@ -2319,8 +2346,9 @@ multilevel_component_ref ( tree op) 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); + DEBUG_A(" found: %s, type: \n", code_str (inner_op0_code)); + DEBUG_F(flexible_print, stderr, type, 1, (dump_flags_t)0); + INDENT(-2); return type; } } @@ -3078,19 +3106,10 @@ code_str( enum tree_code tc) return "COMPONENT_REF"; case INDIRECT_REF: return "INDIRECT_REF"; + case MEM_REF: + return "MEM_REF"; default: return get_tree_code_name ( tc); - switch( TREE_CODE_CLASS( tc) ) - { - case tcc_type: - return "class type"; - case tcc_declaration: - return "class declaration"; - case tcc_reference: - return "class reference"; - default: - return "unknown class"; - } } } #endif |