summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Oblock <gary@amperecomputing.com>2020-11-30 14:38:53 -0800
committerGary Oblock <gary@amperecomputing.com>2020-11-30 14:38:53 -0800
commit911fb110bad713ffbaf424fc45d8b1aa9677a810 (patch)
treeaab4ba74b36bcd872f065e191a9fb7328e99b74d
parent4de36bd5d35fd3dce4566f318ee86cf8f4d5f3cb (diff)
Changes to determine what types need to be modified and what the
modification is. This is with regard to the fact that some pointer types change into what amounts to indices and this change can percolate through the structure types.
-rw-r--r--gcc/ipa-str-reorg-instance-interleave.c556
-rw-r--r--gcc/ipa-structure-reorg.c946
-rw-r--r--gcc/ipa-structure-reorg.h36
3 files changed, 1365 insertions, 173 deletions
diff --git a/gcc/ipa-str-reorg-instance-interleave.c b/gcc/ipa-str-reorg-instance-interleave.c
index 03817a4a709..35271e11cde 100644
--- a/gcc/ipa-str-reorg-instance-interleave.c
+++ b/gcc/ipa-str-reorg-instance-interleave.c
@@ -73,8 +73,14 @@ static double cut_off_eq_single_pool( double);
static double alignment_effect( unsigned HOST_WIDE_INT);
static void tell_me_about_ssa_name ( tree, int);
static void analyze_access ( tree , acc_info_t *);
+static void create_pointer_reps ( Info_t *);
+static void create_base_vars ( Info_t *);
+static void create_a_pointer_rep ( Info_t *, tree);
+static void create_a_base_var ( Info_t *, tree);
+#if 0
static void create_new_types ( Info_t *);
static void create_a_new_type ( Info_t *, tree);
+#endif
static unsigned int reorg_perf_qual ( Info *);
static tree find_coresponding_field ( tree, tree);
static void remove_default_def ( tree, struct function *);
@@ -191,6 +197,11 @@ str_reorg_instance_interleave_trans ( Info *info)
{
//DEBUG_L("No Transfrom on: ");
//DEBUG_F( print_gimple_stmt, stderr, stmt, 4, TDF_SLIM);
+
+ // NEW STUFF
+ // Find assigns that are basically element assigns.
+ // If their type is modified then adjust the gimple.
+
}
else
{
@@ -1174,16 +1185,16 @@ str_reorg_instance_interleave_trans ( Info *info)
tree base_field =
find_coresponding_field ( base, field);
- //DEBUG_L("base_field: %p\n", base_field);
- //DEBUG_A(" : ");
- //DEBUG_F(print_generic_expr, stderr, base_field, (dump_flags_t)0);
- //DEBUG("\n");
+ DEBUG_L("base_field: %p\n", base_field);
+ DEBUG_A(" : ");
+ DEBUG_F(print_generic_expr, stderr, base_field, (dump_flags_t)0);
+ DEBUG("\n");
tree base_field_type = TREE_TYPE( base_field);
- //DEBUG_L("base_field_type: %p\n", base_field_type);
- //DEBUG_A(" : ");
- //DEBUG_F(print_generic_expr, stderr, base_field_type, (dump_flags_t)0);
- //DEBUG("\n");
+ DEBUG_L("base_field_type: %p\n", base_field_type);
+ DEBUG_A(" : ");
+ DEBUG_F(print_generic_expr, stderr, base_field_type, (dump_flags_t)0);
+ DEBUG("\n");
gimple_stmt_iterator gsi = gsi_start_bb ( new_bb);
// Note, switching the order of edge creation and
@@ -2031,8 +2042,8 @@ str_reorg_instance_interleave_trans ( Info *info)
DEBUG_F( print_program, info->reorg_dump_file, PRINT_FORMAT, 4, info);
- //DEBUG ("INTERNALS PRINT\n");
- //DEBUG_F (apply_to_all_gimple, print_internals, true, (void *)info);
+ DEBUG ("INTERNALS PRINT\n");
+ DEBUG_F (apply_to_all_gimple, print_internals, true, (void *)info);
// A mini-pass to fixup dangling SSA temps.
@@ -2252,7 +2263,8 @@ str_reorg_instance_interleave_trans ( Info *info)
bool no_defining_stmt = defining_stmt == NULL;
bool defined_by_nop = defining_stmt && gimple_code ( defining_stmt) == GIMPLE_NOP;
tree type = TREE_TYPE ( ssa_name);
- tree bottom_type = base_type_of ( type);
+ int levels;
+ tree bottom_type = base_type_with_levels ( type, &levels);
ReorgType_t *ri = get_reorgtype_info ( bottom_type, info);
DEBUG_L("ssa_name = ");
DEBUG_F(print_generic_expr, stderr, ssa_name, (dump_flags_t)0);
@@ -2279,6 +2291,14 @@ str_reorg_instance_interleave_trans ( Info *info)
continue;
}
+ // TBD CHECK FOR pointer to record.
+
+ if ( levels != 1 )
+ {
+ DEBUG_L("Skip not one level pointer to record\n");
+ continue;
+ }
+
gcc_assert ( !no_defining_stmt);
gcc_assert ( !defined_by_nop);
@@ -2392,8 +2412,8 @@ str_reorg_instance_interleave_trans ( Info *info)
//DEBUG_F ( print_program, info->reorg_dump_file, PRINT_FORMAT, 4, info);
// TBD Should this be a diagnostic or not?
- //DEBUG ("INTERNALS PRINT\n");
- //DEBUG_F (apply_to_all_gimple, print_internals, true, (void *)info);
+ DEBUG ("INTERNALS PRINT\n");
+ DEBUG_F (apply_to_all_gimple, print_internals, true, (void *)info);
// NOTE, spinning through all the functions and recomputing all the
// dominace info here is a really bad idea.
@@ -2436,7 +2456,10 @@ element_assign_transformation ( gimple *stmt, ReorgType_t *ri, Info_t *info)
make_transformed_ref ( ro_side, ri, &ref_expr, &ref_seq, &field_val_temp, info);
gimple *temp_set;
+ gimple *middle_set;
gimple *final_set;
+
+ bool middle = false;
if ( ro_on_left )
{
@@ -2444,8 +2467,30 @@ element_assign_transformation ( gimple *stmt, ReorgType_t *ri, Info_t *info)
// Generate:
// temp = rhs
- temp_set = gimple_build_assign( field_val_temp, rhs);
- SSA_NAME_DEF_STMT ( field_val_temp) = temp_set;
+ tree field_type = TREE_TYPE ( lhs);
+ int level;
+ tree base_type = base_type_with_levels ( field_type, &level);
+ if ( integer_zerop ( rhs)
+ && is_reorg_type ( base_type, info)
+ && level == 1 )
+ {
+ // Detected a zero value set to a pointer.
+ middle = true;
+ tree mid_temp =
+ make_temp_ssa_name( ri->pointer_rep, NULL, "mid_temp");
+ tree new_rhs = TYPE_MAX_VALUE ( ri->pointer_rep);
+ temp_set = gimple_build_assign ( mid_temp, new_rhs);
+ SSA_NAME_DEF_STMT ( mid_temp) = temp_set;
+ middle_set =
+ gimple_build_assign ( field_val_temp, CONVERT_EXPR, mid_temp);
+ SSA_NAME_DEF_STMT ( field_val_temp) = middle_set;
+ }
+ else
+ {
+ temp_set = gimple_build_assign( field_val_temp, rhs);
+ SSA_NAME_DEF_STMT ( field_val_temp) = temp_set;
+ }
+ //SSA_NAME_DEF_STMT ( field_val_temp) = temp_set;
//// field_array[index] = temp
//tree elem_to_set =
@@ -2497,6 +2542,7 @@ element_assign_transformation ( gimple *stmt, ReorgType_t *ri, Info_t *info)
gsi_insert_seq_before ( &gsi, ref_seq, GSI_SAME_STMT);
gsi_insert_before( &gsi, temp_set, GSI_SAME_STMT);
+ if ( middle ) gsi_insert_before( &gsi, middle_set, GSI_SAME_STMT);
gsi_insert_before( &gsi, final_set, GSI_SAME_STMT);
//delete stmt
@@ -2885,7 +2931,15 @@ str_reorg_instance_interleave_qual_part ( Info *info)
static void
str_reorg_instance_interleave_type_part ( Info *info)
{
+ #if 0
create_new_types ( info);
+ #endif
+
+ create_pointer_reps ( info); // TBD
+
+ find_and_create_all_modified_types ( info); // Modify
+
+ create_base_vars ( info); // TBD
}
// Typse for performance qualification
@@ -4108,7 +4162,45 @@ analyze_access ( tree access, acc_info_t *acc_info)
an_ac_helper ( access, 4, &already, acc_info);
}
+static void
+create_pointer_reps ( Info_t *info)
+{
+ DEBUG_L("create_pointer_reps:\n");
+ std::map < tree, BoolPair_t>::iterator tmi;
+ for( tmi = info->struct_types->begin ();
+ tmi != info->struct_types->end ();
+ tmi++ ) {
+ if ( !tmi->second.processed )
+ {
+ create_a_pointer_rep ( info, tmi->first);
+ }
+ else
+ {
+ DEBUG_A("processed\n");
+ }
+ }
+}
+
+static void
+create_base_vars ( Info_t *info)
+{
+ DEBUG_L("create_base_vars:\n");
+ std::map < tree, BoolPair_t>::iterator tmi;
+ for( tmi = info->struct_types->begin ();
+ tmi != info->struct_types->end ();
+ tmi++ ) {
+ if ( !tmi->second.processed )
+ {
+ create_a_base_var ( info, tmi->first);
+ }
+ else
+ {
+ DEBUG_A("processed\n");
+ }
+ }
+}
+#if 0
// create_new_types has to crawl "all" the
// types, create new types and transform
// other types that must be changed.
@@ -4133,6 +4225,440 @@ create_new_types ( Info_t *info)
}
}
}
+#endif
+
+static void
+create_a_pointer_rep ( Info_t *info, tree type)
+{
+ bool layout_changed = false;
+ // skip if already processed
+ if ( ( *( info->struct_types))[type].processed ) return;
+
+ DEBUG_L("create_a_pointer_rep: ");
+ DEBUG_F(flexible_print, stderr, type, 1, (dump_flags_t)0);
+
+ #if 0
+ // Implementation note: Check this for infinite recursion.
+ // I don't think it's possible in a sane universe but
+ // pointers to reorganized types can occur, so does that
+ // an issue (not necessarily here.)
+ // Also, is this even necessary? Singletons don't expand
+ // and static arrays are not allowed "yet."
+ tree field;
+ tree new_fields = NULL;
+ for ( field = TYPE_FIELDS ( type); // ??? I speced reorg_type_prime here???
+ field;
+ field = DECL_CHAIN ( field))
+ {
+ // make sure all the interior types are processed
+ // before processing this type
+ if ( TREE_CODE ( field) == RECORD_TYPE )
+ {
+ create_a_new_type ( info, field);
+ }
+ }
+ #endif
+
+ ReorgType_t *ri = get_reorgtype_info ( type, info);
+ if ( ri != NULL ) {
+ // Create the new record type of the reorg type
+ tree reorg_type_prime = lang_hooks.types.make_type (RECORD_TYPE);
+
+ ri->reorg_ver_type = reorg_type_prime;
+ DEBUG_L("TYPE_SIZE(reorg_type_prime): %p, ", TYPE_SIZE(reorg_type_prime));
+ DEBUG_F( print_generic_expr, stderr, TYPE_SIZE(reorg_type_prime), (dump_flags_t)-1);
+ DEBUG("\n");
+
+ /* Multi-pool only
+ // Create pointer_rep
+ // this will be a long and a pointer to the
+ // reorg_type_prime
+ tree pointer_rep =
+ lang_hooks.types.make_type( RECORD_TYPE);
+
+ tree index_name = get_identifier("index");
+ tree index_field = build_decl( BUILTINS_LOCATION,
+ FIELD_DECL,
+ index_name,
+ long_integer_type_node);
+ tree base_name = get_identifier("base");
+ tree base_field = build_decl( BUILTINS_LOCATION,
+ FIELD_DECL,
+ base_name,
+ reorg_type_prime);
+ insert_field_into_struct( pointer_rep, index_field);
+ insert_field_into_struct( pointer_rep, base);
+
+ reorg_type->pointer_rep = pointer_rep;
+ */
+
+ tree pointer_rep = make_signed_type ( TYPE_PRECISION ( pointer_sized_int_node));
+ TYPE_MAIN_VARIANT ( pointer_rep) = TYPE_MAIN_VARIANT ( pointer_sized_int_node);
+ DEBUG("Issue with gcc_ of reorg\n");
+ DEBUG_F(print_reorg, stderr, 2, ri);
+ const char *gcc_name =
+ identifier_to_locale ( IDENTIFIER_POINTER ( TYPE_NAME ( ri->gcc_type)));
+ size_t len =
+ strlen ( REORG_SP_PTR_PREFIX) + strlen ( gcc_name);
+ char *name = ( char *)alloca(len + 1);
+ strcpy ( name, REORG_SP_PTR_PREFIX);
+ strcat ( name, gcc_name);
+ TYPE_NAME ( pointer_rep) = get_identifier ( name);
+ ri->pointer_rep = pointer_rep;
+ DEBUG_L("pointer_rep = ");
+ DEBUG_F(flexible_print, stderr, pointer_rep, 1, (dump_flags_t)-1);
+ DEBUG_A("TYPE_MAIN_VARIANT ( pointer_rep) = ");
+ DEBUG_F(flexible_print, stderr, TYPE_MAIN_VARIANT (pointer_rep), 1, (dump_flags_t)-1);
+
+ #if 0
+ // Note, we also declare a base type variable (globally.)
+ // This variable also belong in the ReorgType.
+
+ // Set name of reorg_type_prime
+ const char *base_type_name =
+ identifier_to_locale ( IDENTIFIER_POINTER ( TYPE_NAME ( ri->gcc_type)));
+ len = strlen ( REORG_SP_PREFIX) + strlen ( base_type_name);
+ char *rec_name = ( char*)alloca ( len + 1);
+ strcpy ( rec_name, REORG_SP_PREFIX);
+ strcat ( rec_name, base_type_name);
+
+ //DEBUG_L("TYPE_SIZE(reorg_type_prime): %p\n", TYPE_SIZE(reorg_type_prime));
+
+ // Build the new pointer type fields
+ TYPE_NAME ( reorg_type_prime) = get_identifier ( rec_name);
+ tree field;
+ tree new_fields = NULL;
+ for ( field = TYPE_FIELDS ( type); field; field = DECL_CHAIN ( field))
+ {
+ //DEBUG_F( print_generic_decl, stderr, field, TDF_DETAILS); // example
+ tree tree_type = TREE_TYPE ( field);
+ tree new_fld_type = build_pointer_type ( tree_type);
+ tree new_decl =
+ build_decl ( DECL_SOURCE_LOCATION (field),
+ FIELD_DECL, DECL_NAME (field), new_fld_type);
+ DECL_CONTEXT ( new_decl) = reorg_type_prime;
+ layout_decl ( new_decl, 0);
+
+ // We might be missing a bunch of attributes (see
+ // tree-nested.c:899) But we seem without without them!
+
+ DECL_CHAIN ( new_decl) = new_fields; // <- bug: need decl, not type
+ new_fields = new_decl;
+ //DEBUG( "built new pointer type field:");
+ //DEBUG_F( print_generic_decl, stderr, new_decl, TDF_DETAILS);
+ //DEBUG( "\n");
+ }
+
+ //DEBUG_L("TYPE_SIZE(reorg_type_prime): %p\n", TYPE_SIZE(reorg_type_prime));
+
+ // store reversed fields into reorg_type_prime
+ TYPE_FIELDS ( reorg_type_prime) = NULL;
+ tree next_fld;
+ for ( field = new_fields;
+ field;
+ field = next_fld )
+ {
+ next_fld = DECL_CHAIN ( field);
+ DECL_CHAIN ( field) = TYPE_FIELDS ( reorg_type_prime);
+ TYPE_FIELDS ( reorg_type_prime) = field;
+ }
+ //DEBUG_L("TYPE_SIZE(reorg_type_prime): %p\n", TYPE_SIZE(reorg_type_prime));
+ // Fix-up the layout
+ layout_type ( reorg_type_prime);
+
+ // HERE
+ // Create the base element for a reorg type. This is for the single
+ // pool case only.
+ tree base_var =
+ build_decl ( UNKNOWN_LOCATION, VAR_DECL, NULL_TREE, ri->reorg_ver_type);
+ // We don't want to manually set DECL_INITIAL here!
+
+ const char *type_name =
+ identifier_to_locale ( IDENTIFIER_POINTER ( TYPE_NAME ( ri->gcc_type)));
+ size_t tlen = strlen ( REORG_SP_BASE_PREFIX) + strlen ( type_name);
+ char *base_name = ( char*)alloca ( tlen + 1);
+ strcpy ( base_name, REORG_SP_BASE_PREFIX);
+ //DECL_NAME ( base_var) = get_identifier ( base_name);
+
+ strcat ( base_name, type_name);
+
+ DECL_NAME ( base_var) = get_identifier ( base_name); // wrong spot above???
+
+ TREE_STATIC ( base_var) = 1;
+ TREE_ADDRESSABLE ( base_var) = 1;
+ DECL_NONALIASED ( base_var) = 1;
+ SET_DECL_ALIGN ( base_var, TYPE_ALIGN ( ri->reorg_ver_type));
+
+ varpool_node::finalize_decl ( base_var);
+
+ relayout_decl ( base_var);
+
+ ri->instance_interleave.base = base_var;
+ #endif
+ }
+
+ #if 0
+ // Mess with the original type too because it might
+ // have base_type_fld interior elements that are modified.
+ for ( field = TYPE_FIELDS ( type);
+ field;
+ field = DECL_CHAIN ( field))
+ {
+ if ( TREE_CODE ( field) == RECORD_TYPE )
+ {
+ layout_changed =
+ layout_changed || ( *( info->struct_types)) [ field].layout_changed;
+ }
+ else
+ {
+ // process pointers to reorg types
+ if ( POINTER_TYPE_P ( field) )
+ {
+ tree field_type = TREE_TYPE ( field);
+ if ( is_reorg_type ( field_type, info) )
+ {
+ // Change field type.
+
+ // If multi-pool then set layout_changed to true.
+
+ // The type pointed to changes for single-pool.
+ ReorgType_t *ri =
+ get_reorgtype_info ( field_type, info);
+ gcc_assert ( ri->pointer_rep);
+ TREE_TYPE ( field) = ri->pointer_rep;
+ }
+ tree base = base_type_of ( field);
+ if ( is_reorg_type ( base, info) )
+ {
+ // strip off a layer of pointers
+ gcc_assert ( TREE_TYPE ( TREE_TYPE( field)));
+ TREE_TYPE ( field) = TREE_TYPE ( TREE_TYPE( field));
+ }
+ }
+ }
+ }
+
+ // Mark the type as processed
+ ( *( info->struct_types)) [ type] = { true, layout_changed};
+ #endif
+}
+
+
+static void
+create_a_base_var ( Info_t *info, tree type)
+{
+ bool layout_changed = false;
+ // skip if already processed
+ if ( ( *( info->struct_types))[type].processed ) return;
+
+ DEBUG_L("create_a_base_var: ");
+ DEBUG_F(flexible_print, stderr, type, 1, (dump_flags_t)0);
+
+ // I think the type modification stuff should catch this
+ #if 0
+ // Implementation note: Check this for infinite recursion.
+ // I don't think it's possible in a sane universe but
+ // pointers to reorganized types can occur, so does that
+ // an issue (not necessarily here.)
+ // Also, is this even necessary? Singletons don't expand
+ // and static arrays are not allowed "yet."
+ tree field;
+ tree new_fields = NULL;
+ for ( field = TYPE_FIELDS ( type); // ??? I speced reorg_type_prime here???
+ field;
+ field = DECL_CHAIN ( field))
+ {
+ // make sure all the interior types are processed
+ // before processing this type
+ if ( TREE_CODE ( field) == RECORD_TYPE )
+ {
+ create_a_new_type ( info, field);
+ }
+ }
+ #endif
+
+ ReorgType_t *ri = get_reorgtype_info ( type, info);
+ if ( ri != NULL ) {
+ // Create the new record type of the reorg type
+ tree reorg_type_prime = lang_hooks.types.make_type (RECORD_TYPE);
+
+ ri->reorg_ver_type = reorg_type_prime;
+ #if 0
+ DEBUG_L("TYPE_SIZE(reorg_type_prime): %p, ", TYPE_SIZE(reorg_type_prime));
+ DEBUG_F( print_generic_expr, stderr, TYPE_SIZE(reorg_type_prime), (dump_flags_t)-1);
+ DEBUG("\n");
+
+ /* Multi-pool only
+ // Create pointer_rep
+ // this will be a long and a pointer to the
+ // reorg_type_prime
+ tree pointer_rep =
+ lang_hooks.types.make_type( RECORD_TYPE);
+
+ tree index_name = get_identifier("index");
+ tree index_field = build_decl( BUILTINS_LOCATION,
+ FIELD_DECL,
+ index_name,
+ long_integer_type_node);
+ tree base_name = get_identifier("base");
+ tree base_field = build_decl( BUILTINS_LOCATION,
+ FIELD_DECL,
+ base_name,
+ reorg_type_prime);
+ insert_field_into_struct( pointer_rep, index_field);
+ insert_field_into_struct( pointer_rep, base);
+
+ reorg_type->pointer_rep = pointer_rep;
+ */
+
+ tree pointer_rep = make_signed_type ( TYPE_PRECISION ( pointer_sized_int_node));
+ TYPE_MAIN_VARIANT ( pointer_rep) = TYPE_MAIN_VARIANT ( pointer_sized_int_node);
+ DEBUG("Issue with gcc_ of reorg\n");
+ DEBUG_F(print_reorg, stderr, 2, ri);
+ const char *gcc_name =
+ identifier_to_locale ( IDENTIFIER_POINTER ( TYPE_NAME ( ri->gcc_type)));
+ size_t len =
+ strlen ( REORG_SP_PTR_PREFIX) + strlen ( gcc_name);
+ char *name = ( char *)alloca(len + 1);
+ strcpy ( name, REORG_SP_PTR_PREFIX);
+ strcat ( name, gcc_name);
+ TYPE_NAME ( pointer_rep) = get_identifier ( name);
+ ri->pointer_rep = pointer_rep;
+ DEBUG_L("pointer_rep = ");
+ DEBUG_F(flexible_print, stderr, pointer_rep, 1, (dump_flags_t)-1);
+ DEBUG_A("TYPE_MAIN_VARIANT ( pointer_rep) = ");
+ DEBUG_F(flexible_print, stderr, TYPE_MAIN_VARIANT (pointer_rep), 1, (dump_flags_t)-1);
+ #endif
+
+ // Note, we also declare a base type variable (globally.)
+ // This variable also belong in the ReorgType.
+
+ // Set name of reorg_type_prime
+ const char *base_type_name =
+ identifier_to_locale ( IDENTIFIER_POINTER ( TYPE_NAME ( ri->gcc_type)));
+ size_t len = strlen ( REORG_SP_PREFIX) + strlen ( base_type_name);
+ char *rec_name = ( char*)alloca ( len + 1);
+ strcpy ( rec_name, REORG_SP_PREFIX);
+ strcat ( rec_name, base_type_name);
+
+ //DEBUG_L("TYPE_SIZE(reorg_type_prime): %p\n", TYPE_SIZE(reorg_type_prime));
+
+ // Build the new pointer type fields
+ TYPE_NAME ( reorg_type_prime) = get_identifier ( rec_name);
+ tree field;
+ tree new_fields = NULL;
+ for ( field = TYPE_FIELDS ( type); field; field = DECL_CHAIN ( field))
+ {
+ //DEBUG_F( print_generic_decl, stderr, field, TDF_DETAILS); // example
+ tree tree_type = TREE_TYPE ( field);
+ tree new_fld_type = build_pointer_type ( tree_type);
+ tree new_decl =
+ build_decl ( DECL_SOURCE_LOCATION (field),
+ FIELD_DECL, DECL_NAME (field), new_fld_type);
+ DECL_CONTEXT ( new_decl) = reorg_type_prime;
+ layout_decl ( new_decl, 0);
+
+ // We might be missing a bunch of attributes (see
+ // tree-nested.c:899) But we seem without without them!
+
+ DECL_CHAIN ( new_decl) = new_fields; // <- bug: need decl, not type
+ new_fields = new_decl;
+ //DEBUG( "built new pointer type field:");
+ //DEBUG_F( print_generic_decl, stderr, new_decl, TDF_DETAILS);
+ //DEBUG( "\n");
+ }
+
+ //DEBUG_L("TYPE_SIZE(reorg_type_prime): %p\n", TYPE_SIZE(reorg_type_prime));
+
+ // store reversed fields into reorg_type_prime
+ TYPE_FIELDS ( reorg_type_prime) = NULL;
+ tree next_fld;
+ for ( field = new_fields;
+ field;
+ field = next_fld )
+ {
+ next_fld = DECL_CHAIN ( field);
+ DECL_CHAIN ( field) = TYPE_FIELDS ( reorg_type_prime);
+ TYPE_FIELDS ( reorg_type_prime) = field;
+ }
+ //DEBUG_L("TYPE_SIZE(reorg_type_prime): %p\n", TYPE_SIZE(reorg_type_prime));
+ // Fix-up the layout
+ layout_type ( reorg_type_prime);
+
+ // HERE
+ // Create the base element for a reorg type. This is for the single
+ // pool case only.
+ tree base_var =
+ build_decl ( UNKNOWN_LOCATION, VAR_DECL, NULL_TREE, ri->reorg_ver_type);
+ // We don't want to manually set DECL_INITIAL here!
+
+ const char *type_name =
+ identifier_to_locale ( IDENTIFIER_POINTER ( TYPE_NAME ( ri->gcc_type)));
+ size_t tlen = strlen ( REORG_SP_BASE_PREFIX) + strlen ( type_name);
+ char *base_name = ( char*)alloca ( tlen + 1);
+ strcpy ( base_name, REORG_SP_BASE_PREFIX);
+ //DECL_NAME ( base_var) = get_identifier ( base_name);
+
+ strcat ( base_name, type_name);
+
+ DECL_NAME ( base_var) = get_identifier ( base_name); // wrong spot above???
+
+ TREE_STATIC ( base_var) = 1;
+ TREE_ADDRESSABLE ( base_var) = 1;
+ DECL_NONALIASED ( base_var) = 1;
+ SET_DECL_ALIGN ( base_var, TYPE_ALIGN ( ri->reorg_ver_type));
+
+ varpool_node::finalize_decl ( base_var);
+
+ relayout_decl ( base_var);
+
+ ri->instance_interleave.base = base_var;
+ }
+
+ // Mess with the original type too because it might
+ // have base_type_fldinterior elements that are modified.
+ tree field;
+ for ( field = TYPE_FIELDS ( type);
+ field;
+ field = DECL_CHAIN ( field))
+ {
+ if ( TREE_CODE ( field) == RECORD_TYPE )
+ {
+ layout_changed =
+ layout_changed || ( *( info->struct_types)) [ field].layout_changed;
+ }
+ else
+ {
+ // process pointers to reorg types
+ if ( POINTER_TYPE_P ( field) )
+ {
+ tree field_type = TREE_TYPE ( field);
+ if ( is_reorg_type ( field_type, info) )
+ {
+ // Change field type.
+
+ // If multi-pool then set layout_changed to true.
+
+ // The type pointed to changes for single-pool.
+ ReorgType_t *ri =
+ get_reorgtype_info ( field_type, info);
+ gcc_assert ( ri->pointer_rep);
+ TREE_TYPE ( field) = ri->pointer_rep;
+ }
+ tree base = base_type_of ( field);
+ if ( is_reorg_type ( base, info) )
+ {
+ // strip off a layer of pointers
+ gcc_assert ( TREE_TYPE ( TREE_TYPE( field)));
+ TREE_TYPE ( field) = TREE_TYPE ( TREE_TYPE( field));
+ }
+ }
+ }
+ }
+
+ // Mark the type as processed
+ ( *( info->struct_types)) [ type] = { true, layout_changed};
+}
static void
create_a_new_type ( Info_t *info, tree type)
diff --git a/gcc/ipa-structure-reorg.c b/gcc/ipa-structure-reorg.c
index f82256c178e..d7c18503221 100644
--- a/gcc/ipa-structure-reorg.c
+++ b/gcc/ipa-structure-reorg.c
@@ -52,6 +52,16 @@ along with GCC; see the file COPYING3. If not see
#include "stringpool.h"
#include "tree-ssanames.h"
+#if 0
+typedef struct type_holder TypeHolder;
+
+struct type_holder
+{
+ std::vector <tree> refed_types;
+ std::vector <tree> rec_types;
+};
+#endif
+
static void setup_debug_flags ( Info *);
static void initial_debug_info ( Info *);
static void final_debug_info ( Info *);
@@ -59,6 +69,17 @@ static unsigned int reorg_analysis ( Info *);
static unsigned number_of_executions ( gimple *, struct cgraph_node *);
static void reorg_analysis_debug ( Info *, ReorgType *);
static bool find_decls_and_types ( Info *);
+#if 1
+static void find_all_record_types ( tree type, Info_t *);
+#if 0
+static void find_all_record_types ( std::map <tree,TypeHolder> *, tree type, Info_t *);
+static void find_and_create_all_modified_types ( std::map <tree,TypeHolder> *, Info_t *);
+#endif
+static std::vector<tree>::iterator find_in_type_vec ( std::vector<tree> *, tree);
+static void dump_modified_types ( FILE *, Info_t *);
+#else
+static bool possibly_modify_pointer_types ( tree, Info_t *);
+#endif
#if USE_REORG_TYPES
static void add_reorg_type( tree, bool, Info *);
#endif
@@ -127,7 +148,9 @@ ipa_structure_reorg ( void)
std::vector <ReorgType_t> Saved_Reorg_Type;
std::vector <ProgDecl_t> Prog_Decl;
std::map <tree,BoolPair_t> StructTypes; // TBD horrible type name
-
+ std::vector <two_trees_t> Modified_Types;
+ std::set <tree> Dont_Modify;
+ std::map <tree,TypeHolder> Type_Mod_Info;
DEBUG("SAMPLE DEGUG\n");
//DEBUG_L( "Running ipa_structure_reorg\n");
//INDENT(2);
@@ -140,7 +163,13 @@ ipa_structure_reorg ( void)
// Why not make this a class and avoid having all these parameters
// to initialize?
// Also, all functions should be references and not pointers...
- Info info(&Reorg_Type, &Saved_Reorg_Type, &Prog_Decl, &StructTypes);
+ Info info ( &Reorg_Type,
+ &Saved_Reorg_Type,
+ &Prog_Decl,
+ &StructTypes,
+ &Modified_Types,
+ &Dont_Modify,
+ &Type_Mod_Info);
//DEBUG_L("At init dum_deleted %d\n",info.num_deleted);
cgraph_node* node;
@@ -557,17 +586,28 @@ find_decls_and_types ( Info *info)
return false;
}
std::set<tree> typeset; // ???
+ std::map <tree,TypeHolder> type_mod_info;
for ( auto typei = escaping_nonescaping_sets.points_to_record.begin ();
typei != escaping_nonescaping_sets.points_to_record.end (); typei++ )
{
tree type = *typei;
+ tree canonical = TYPE_MAIN_VARIANT ( base_type_of ( type));
+
+ // This is here as a convenience.
+ #if 1
+ #if 0
+ find_all_record_types( &type_mod_info, canonical, info);
+ #endif
+ find_all_record_types( canonical, info);
+ #else
+ possibly_modify_pointer_types ( canonical, info);
+ #endif
+
if ( escaping_nonescaping_sets.non_escaping.find ( type)
!=
escaping_nonescaping_sets.non_escaping.end ())
{
- tree canonical = TYPE_MAIN_VARIANT ( base_type_of ( type));
-
// Check for incomplete types and ignore them.
if ( TYPE_SIZE ( canonical) == NULL ) continue;
if ( TYPE_FIELDS ( canonical) == NULL ) continue;
@@ -581,6 +621,38 @@ find_decls_and_types ( Info *info)
}
}
+ // We are have to look at the globals because we created some new types
+ // for them
+ varpool_node *var;
+ FOR_EACH_VARIABLE ( var)
+ {
+ tree decl = var->decl;
+ tree canonical = TYPE_MAIN_VARIANT ( base_type_of ( decl));
+
+ #if 0
+ find_all_record_types( &type_mod_info, canonical, info);
+ #endif
+ find_all_record_types( canonical, info);
+
+ if ( escaping_nonescaping_sets.non_escaping.find ( decl)
+ !=
+ escaping_nonescaping_sets.non_escaping.end ())
+ {
+ // Check for incomplete types and ignore them.
+ if ( TYPE_SIZE ( canonical) == NULL ) continue;
+ if ( TYPE_FIELDS ( canonical) == NULL ) continue;
+
+ // The types here are highly redundant so ignore
+ // the duplicates.
+ if ( get_reorgtype_info ( canonical, info) ) continue;
+
+ add_reorg_type ( canonical, false, info);
+ typeset.insert ( canonical);
+ }
+ }
+
+
+
// Don't keep any structure types if they aren't
// used in an array or have a pointer type (which
// hopefully will have an associated allocation.)
@@ -617,19 +689,21 @@ find_decls_and_types ( Info *info)
print_reorgs ( info->reorg_dump_file, 2, info);
}
- // Scan all types in ReorgTypes for structure fields
- // and if they are pointers to a type Q in ReorgTypes
- // then clear the deletion mark of Q. Note, at this
- // point in the execution ReorgTypes is all the structure
- // types.
+ // Scan all types in ReorgTypes for structure fields and if they are
+ // pointers to a type Q in ReorgTypes then clear the deletion mark
+ // of Q. Note, at this point in the execution ReorgTypes is all the
+ // structure types.
//
- // It would be a bit nuts to allocate memory and hang it
- // off of pointer in a structure, but it's still possible.
- // Note, if there are no pointers to a structure of a type
- // then it is impossible to dynamically allocate memory of
- // that type. This of course assumes sane programming
- // practices and if they violate those structure reorg has
- // every right to punt.
+ // It would be a bit nuts to allocate memory and hang it off of
+ // pointer in a structure, but it's still possible. More, likely is
+ // just that they are simply pointers into the array of reorg types
+ // but the other bit is what counts here.
+ //
+ // Note, if there are no pointers to a structure of a type then it
+ // is impossible to dynamically allocate memory of that type. This
+ // of course assumes sane programming practices and if they violate
+ // those structure reorg has every right to punt.
+
//DEBUG_L( "Examine imbedded pointers\n");
//INDENT(2);
for ( std::vector<ReorgType_t>::iterator ri = info->reorg_type->begin ();
@@ -689,7 +763,6 @@ find_decls_and_types ( Info *info)
// so use FOR_EACH_VARIABLE instead. I'm not 100% this is the thing
// actuall do here... but...
//DEBUG_L( "ProgDecl global declarations:\n");
- varpool_node *var;
FOR_EACH_VARIABLE ( var)
{
tree decl = var->decl;
@@ -717,6 +790,10 @@ find_decls_and_types ( Info *info)
print_progdecls ( info->reorg_dump_file, 2, info);
}
+ #if 0
+ find_and_create_all_modified_types ( &type_mod_info, info);
+ #endif
+
return true;
}
@@ -1009,6 +1086,563 @@ find_decls_and_types ( Info *info)
}
#endif
+// Note, these replace possibly_modify_pointer_types.
+#if 0
+static void
+find_all_record_types ( std::map <tree,TypeHolder> *types, tree type, Info_t *info){}
+#endif
+static void
+find_all_record_types ( tree type, Info_t *info)
+{
+ std::map <tree,TypeHolder> *types = info->type_mod_info;
+ // Get cannonical form of record type
+ tree base = base_type_of ( type);
+
+ if( TREE_CODE ( base) != RECORD_TYPE ) return;
+
+ tree canonocal = TYPE_MAIN_VARIANT ( base);
+
+ // Add it to the set if need be
+ if( types->find ( canonocal) == types->end () )
+ {
+ TypeHolder holder;
+ (*types)[ canonocal] = holder;
+ }
+}
+
+#if 0
+static void
+find_and_create_all_modified_types ( std::map <tree,TypeHolder> *types, Info_t *info) {}
+#endif
+void
+find_and_create_all_modified_types ( Info_t *info)
+{
+ std::map <tree,TypeHolder> *types = info->type_mod_info;
+ std::deque <tree> rec_types_work_list;
+ DEBUG_L("find_and_create_all_modified_types:\n");
+
+ DEBUG_A("At start:\n");
+ DEBUG_F( dump_modified_types, stderr, info);
+ INDENT(4);
+
+ // Fill out the references to each type from each type
+ for ( auto typei = types->begin (); typei != types->end (); typei++ )
+ {
+ tree type = typei->first;
+ TypeHolder *holder = &(typei->second);
+ tree canonical_type = TYPE_MAIN_VARIANT ( base_type_of ( type));
+ DEBUG_A( "canonical_type = ");
+ DEBUG_F(flexible_print, stderr, canonical_type, 1, (dump_flags_t)0);
+ INDENT(4);
+
+ // For each record type create an entry
+ for ( tree field = TYPE_FIELDS ( canonical_type);
+ field;
+ field = DECL_CHAIN ( field) )
+ {
+ tree field_type = TREE_TYPE ( field);
+ tree canonical_field_type = TYPE_MAIN_VARIANT ( base_type_of (field_type));
+ DEBUG_A( "canonical_field_type = ");
+ DEBUG_F(flexible_print, stderr, canonical_field_type, 1, (dump_flags_t)0);
+
+ rec_types_work_list.push_back ( canonical_type);
+
+ if ( TREE_CODE ( canonical_field_type) == RECORD_TYPE)
+ {
+ DEBUG_A("TREE_CODE ( canonical_field_type) == RECORD_TYPE\n");
+ auto referenced = types->find ( canonical_field_type);
+ gcc_assert ( referenced != types->end ());
+
+ auto foundi =
+ find_in_type_vec ( &referenced->second.refed_types, canonical_type);
+ if ( foundi == referenced->second.refed_types.end () )
+ {
+ DEBUG_A("referenced->second.refed_types.push_back ( canonical_type)\n");
+ referenced->second.refed_types.push_back ( canonical_type);
+ }
+ }
+ if ( TREE_CODE ( field_type) == RECORD_TYPE )
+ {
+ DEBUG_A("TREE_CODE ( field_type) == RECORD_TYPE\n");
+ auto foundi = find_in_type_vec ( &holder->rec_types, canonical_type);
+ if ( foundi == holder->rec_types.end () )
+ {
+ DEBUG_A("holder->rec_types.push_back ( field_type)\n");
+ holder->rec_types.push_back ( field_type);
+ }
+ }
+ }
+ INDENT(-4);
+ // Having an interior record means it can't be processed initally.
+ // That is because this is done bottom up starting with types
+ // that have no modified interior records.
+ if ( holder->rec_types.empty () )
+ {
+ DEBUG_A( "rec_types_work_list <- ");
+ DEBUG_F(flexible_print, stderr, canonical_type, 1, (dump_flags_t)0);
+ rec_types_work_list.push_back ( canonical_type);
+ }
+ }
+ INDENT(-4);
+
+ DEBUG_A("Before modification setup:\n");
+ DEBUG_F( dump_modified_types, stderr, info);
+
+ //
+ // Propagate The Modifications
+ //
+ std::vector <tree> needs_modification;
+ std::deque <tree> work_list;
+
+ // setup up initial modifications
+ for ( auto typei = types->begin (); typei != types->end (); typei++ )
+ {
+ tree type = typei->first;
+ for ( tree field = TYPE_FIELDS ( type);
+ field;
+ field = DECL_CHAIN ( field) )
+ {
+ tree field_type = TREE_TYPE ( field);
+ tree canonical_field_type = TYPE_MAIN_VARIANT ( base_type_of (field_type));
+ if ( TREE_CODE ( canonical_field_type) == RECORD_TYPE
+ && is_reorg_type ( canonical_field_type, info) )
+ {
+ // Need to replace the type if found and the one found is incomplete.
+ // But then we probably don't also need to mess with the work list.
+ auto foundtype = find_in_type_vec ( &needs_modification, canonical_field_type);
+ if( foundtype == needs_modification.end () )
+ {
+ DEBUG_L("needs_modification, insert canonical_field_type %p = ", canonical_field_type);
+ DEBUG_F(flexible_print, stderr, canonical_field_type, 1, (dump_flags_t)0);
+ DEBUG_A(" TYPE_FIELDS = %p\n", TYPE_FIELDS(canonical_field_type));
+ needs_modification.push_back ( canonical_field_type);
+ work_list.push_back ( canonical_field_type);
+ }
+ else
+ {
+ // If the found type is incomplete repalce it.
+ if ( TYPE_FIELDS ( *foundtype) == NULL )
+ {
+ *foundtype = canonical_field_type;
+ }
+ }
+ }
+ }
+ }
+
+ DEBUG_A("Before propogation:\n");
+ DEBUG_F( dump_modified_types, stderr, info);
+
+ // propigate
+ while ( !work_list.empty () )
+ {
+ tree item = work_list.front ();
+ work_list.pop_front ();
+
+ TypeHolder *holder = &(types->find (item)->second);
+ for ( auto ref_typei = holder->refed_types.begin ();
+ ref_typei != holder->refed_types.end ();
+ ref_typei++ )
+ {
+ tree ref_type = *ref_typei;
+ tree canonical_ref_type = TYPE_MAIN_VARIANT ( base_type_of (ref_type));
+ DEBUG_A("ref_type %p = ", canonical_ref_type);
+ DEBUG_F(flexible_print, stderr, canonical_ref_type, 1, (dump_flags_t)0);
+ DEBUG_A(" TYPE_FIELDS = %p\n", TYPE_FIELDS(canonical_ref_type));
+ auto foundtype = find_in_type_vec ( &needs_modification, canonical_ref_type);
+ if ( foundtype == needs_modification.end () )
+ {
+ DEBUG_A(" Inserted\n");
+ needs_modification.push_back ( canonical_ref_type);
+ work_list.push_back ( canonical_ref_type);
+ }
+ else
+ {
+ // If the found type is incomplete repalce it.
+ if ( TYPE_FIELDS ( *foundtype) == NULL )
+ {
+ *foundtype = canonical_ref_type;
+ }
+ }
+ }
+ }
+
+ // Create The Modifications
+
+ DEBUG_A("Before doing the modifications:\n");
+ DEBUG_F( dump_modified_types, stderr, info);
+
+ // Just create the type, the fields are created afterwards
+ for ( auto type2modi = needs_modification.begin ();
+ type2modi != needs_modification.end (); type2modi++ )
+ {
+ tree type_to_modify = *type2modi;
+ DEBUG_A("type_to_modify (from needs_modification) = ");
+ DEBUG_F(flexible_print, stderr, type_to_modify, 1, (dump_flags_t)0);
+ // Create new record type
+ tree modified_type = lang_hooks.types.make_type (RECORD_TYPE);
+ //(*(info->modified_types))[ type_to_modify] = modified_type;
+ two_trees_t entry = { type_to_modify, modified_type};
+ info->modified_types->push_back ( entry);
+
+ const char *old_type_name =
+ identifier_to_locale ( IDENTIFIER_POINTER ( TYPE_NAME ( type_to_modify)));
+ size_t len = strlen ( "_modif_") + strlen ( old_type_name);
+ char *rec_name = ( char*)alloca ( len + 1);
+ strcpy ( rec_name, "_modif_");
+ strcat ( rec_name, old_type_name);
+
+ // Build the new pointer type fields
+ TYPE_NAME ( modified_type) = get_identifier ( rec_name);
+ }
+ DEBUG_A("Before field creation:\n");
+ DEBUG_F( dump_modified_types, stderr, info);
+
+ // Create the fields but the types must be created in a bottom up
+ // manner where the types include types as elements that are below
+ // them.
+ while ( !rec_types_work_list.empty () )
+ {
+ tree type = rec_types_work_list.front ();
+ rec_types_work_list.pop_front ();
+ DEBUG_A("type (rec_types_work_list.front) = ");
+ DEBUG_F(flexible_print, stderr, type, 1, (dump_flags_t)0);
+ //auto pairi = info->modified_types->find (type);
+ auto peari = find_in_vec_of_two_types ( info->modified_types, type);
+ //gcc_assert( peari != info->modified_types->end ());
+ // The is a possibility the type on the work list does need to
+ // be modified. If found skip this type.
+ // This situtaion can likely be avoided but it might not be worth
+ // the effort.
+ if ( peari == info->modified_types->end ()) continue;
+
+ // The sane type should be complete! (I hope)
+ tree sane_type = peari->first;
+ gcc_assert( TYPE_FIELDS ( sane_type) != NULL );
+ DEBUG_A("sane_type (TYPE_FIELDS %p) = ", TYPE_FIELDS ( sane_type));
+ DEBUG_F(flexible_print, stderr, sane_type, 1, (dump_flags_t)0);
+ tree modified_type = peari->second;
+
+ tree field;
+ tree new_fields = NULL;
+ for ( field = TYPE_FIELDS ( sane_type); field; field = DECL_CHAIN ( field))
+ {
+ tree field_type = TREE_TYPE ( field);
+ tree new_fld_type;
+ DEBUG_A("transforming field = ");
+ DEBUG_F(flexible_print, stderr, field, 1, (dump_flags_t)0);
+ tree canoncl_fld_type = TYPE_MAIN_VARIANT ( base_type_of (field_type));
+
+ // TBD Do I need a canonical type here instead?
+ //auto is_modified = info->modified_types->find ( type);
+ //auto is_modified = find_in_vec_of_two_types ( info->modified_types, sane_type); // ???
+ auto is_modified = find_in_vec_of_two_types ( info->modified_types, canoncl_fld_type);
+ DEBUG_A("is_modified = %s\n", is_modified != info->modified_types->end () ? "T" : "F");
+ if ( is_modified != info->modified_types->end () )
+ {
+ if ( POINTER_TYPE_P ( field_type))
+ {
+ ReorgType_t *ri = get_reorgtype_info ( canoncl_fld_type, info);
+ int levels = number_of_levels ( field_type);
+ DEBUG_A("ri = %p, levels = %d\n", ri, levels);
+ if ( ri == NULL )
+ {
+ new_fld_type = make_multilevel ( is_modified->second, levels);
+ }
+ else
+ {
+ new_fld_type = make_multilevel ( ri->pointer_rep, levels - 1);
+ }
+ }
+ else
+ {
+ new_fld_type = is_modified->second;
+ }
+ }
+ else
+ {
+ // This field doesn't need to be modified.
+ new_fld_type = field_type;
+ }
+ tree new_decl =
+ build_decl ( DECL_SOURCE_LOCATION (field),
+ FIELD_DECL, DECL_NAME (field), new_fld_type);
+ DECL_CONTEXT ( new_decl) = modified_type;
+
+ DEBUG_A("new_fld_type = ");
+ DEBUG_F(flexible_print, stderr, new_fld_type, 1, (dump_flags_t)0);
+ DEBUG_A("new_decl = ");
+ DEBUG_F(flexible_print, stderr, new_decl, 1, (dump_flags_t)0);
+
+ layout_decl ( new_decl, 0);
+
+ // We might be missing a bunch of attributes (see
+ // tree-nested.c:899) But we seem without without them!
+
+ DECL_CHAIN ( new_decl) = new_fields; // <- bug: need decl, not type
+ new_fields = new_decl;
+ }
+
+ // Reverse fields. Note, a some point try nreverse here instead.
+ TYPE_FIELDS ( modified_type) = NULL;
+ tree next_fld;
+ for ( field = new_fields;
+ field;
+ field = next_fld )
+ {
+ next_fld = DECL_CHAIN ( field);
+ DECL_CHAIN ( field) = TYPE_FIELDS ( modified_type);
+ TYPE_FIELDS ( modified_type) = field;
+ }
+
+ DEBUG_A("Before lay_type:\n");
+ DEBUG_F( dump_modified_types, stderr, info);
+
+ // Lay it out
+ layout_type ( modified_type);
+
+ TypeHolder *holder = &(types->find ( sane_type)->second);
+ // Add new types to the work list if possible
+ for ( auto refingi = holder->refed_types.begin ();
+ refingi != holder->refed_types.end ();
+ refingi++ )
+ {
+ tree refing_type = *refingi;
+ TypeHolder *refing_holder = &(types->find ( sane_type)->second);
+ for ( auto record_typei = refing_holder->rec_types.begin ();
+ record_typei != refing_holder->rec_types.end ();
+ record_typei++ )
+ {
+ tree record_type = *record_typei;
+ if ( TYPE_FIELDS (record_type) == NULL ) goto dont_add;
+ }
+ // Only add to the work list if all the necessary
+ // structure ypes have already been processed.
+ // Note, this is only added once when the last
+ // structure type necessary has its fields created
+ // above.
+ rec_types_work_list.push_back (refing_type);
+
+ dont_add:
+ ;
+ }
+ }
+ DEBUG_A("End results:\n");
+ DEBUG_F( dump_modified_types, stderr, info);
+}
+
+static std::vector<tree>::iterator
+find_in_type_vec ( std::vector<tree> *types, tree type)
+{
+ for ( auto looki = types->begin (); looki != types->end (); looki++)
+ {
+ tree look = *looki;
+ if ( same_type_p ( look, type) ) return looki;
+ }
+ return types->end ();
+}
+
+static void
+dump_modified_types (FILE *file, Info_t *info)
+{
+ DEBUG_A("");
+ fprintf ( file, "dump_modified_types:%s\n",
+ info->modified_types->begin () == info->modified_types->end ()
+ ? " (empty)" : "");
+ for ( auto modifi = info->modified_types->begin ();
+ modifi != info->modified_types->end (); modifi++ )
+ {
+ tree field;
+ tree orig_type = modifi->first;
+ tree new_type = modifi->second;
+ DEBUG_A("");
+ fprintf ( file, " %p, ", TYPE_FIELDS ( orig_type));
+ flexible_print ( file, orig_type, 1, (dump_flags_t)0);
+ for ( field = TYPE_FIELDS ( orig_type);
+ field; field = DECL_CHAIN ( field))
+ {
+ DEBUG_A("");
+ fprintf ( file, " ", TYPE_FIELDS ( new_type));
+ flexible_print ( file, field, 1, (dump_flags_t)0);
+ }
+ DEBUG_A("");
+ fprintf ( file, " %p, ", TYPE_FIELDS ( new_type));
+ flexible_print ( file, new_type, 1, (dump_flags_t)0);
+ for ( field = TYPE_FIELDS ( new_type);
+ field; field = DECL_CHAIN ( field))
+ {
+ DEBUG_A("");
+ fprintf ( file, " ");
+ flexible_print ( file, field, 1, (dump_flags_t)0);
+ }
+ }
+}
+
+#if 0
+// A type needs to be in modified_types iff one or more fields is a
+// reorg pointer or a modified record and should involve creating the
+// modified types. The process is recursive and natural in that
+// attempting to classify the type results in the creation of the
+// modified types and also create and note any interior types that
+// must be modified. This returns true if modified.
+static bool
+possibly_modify_pointer_types ( tree type, Info_t *info)
+{
+ bool modified = false;
+
+ if ( TREE_CODE( type) != RECORD_TYPE )
+ return false;
+
+ DEBUG_L("possibly_modify_pointer_types: ");
+ DEBUG_F(flexible_print, stderr, type, 1, (dump_flags_t)0);
+ INDENT(4);
+
+ if ( TYPE_SIZE ( type) == NULL || TYPE_FIELDS ( type) == NULL)
+ {
+ DEBUG_A("Incomplete type\n");
+ INDENT(-4);
+ return false;
+ }
+
+ // NOPE
+ if ( info->modified_types->find ( type) != info->modified_types->end () )
+ {
+ DEBUG_A("Already modified\n");
+ INDENT(-4);
+ return true;
+ }
+ if ( info->dont_modify->find ( type) != info->dont_modify->end () )
+ {
+ DEBUG_A("Marked to not modify\n");
+ INDENT(-4);
+ return false;
+ }
+ for ( tree field = TYPE_FIELDS ( type);
+ field;
+ field = DECL_CHAIN ( field) )
+ {
+ tree field_type = TREE_TYPE ( field);
+ tree canonical_field_type = TYPE_MAIN_VARIANT ( base_type_of (field_type));
+ bool pointer = POINTER_TYPE_P ( field_type);
+ bool record = TREE_CODE( canonical_field_type) == RECORD_TYPE;
+ DEBUG_A("Field: ");
+ DEBUG_F(flexible_print, stderr, field, 1, (dump_flags_t)0);
+ DEBUG_A(" pointer %s, record %s\n", pointer ? "T" : "F", record ? "T" :"F");
+ if ( pointer && record )
+ {
+ bool is_reorg = is_reorg_type ( canonical_field_type, info);
+ if ( is_reorg )
+ {
+ modified = true;
+ }
+ else
+ if ( possibly_modify_pointer_types ( canonical_field_type, info) )
+ {
+ modified = true;
+ }
+ }
+ else
+ {
+ // ??? non record types?
+ if ( possibly_modify_pointer_types ( canonical_field_type, info) )
+ {
+ modified = true;
+ }
+ }
+ }
+
+ if ( modified )
+ {
+ // Create new record type
+ tree modified_type = lang_hooks.types.make_type (RECORD_TYPE);
+ //(*(info->modified_types))[ type] = modified_type;
+ two_trees_t entry = { type, modified_type};
+ info->modified_types->push_back ( entry);
+
+ const char *old_type_name =
+ identifier_to_locale ( IDENTIFIER_POINTER ( TYPE_NAME ( type)));
+ size_t len = strlen ( "_modif_") + strlen ( old_type_name);
+ char *rec_name = ( char*)alloca ( len + 1);
+ strcpy ( rec_name, "_modif_");
+ strcat ( rec_name, old_type_name);
+
+ // Build the new pointer type fields
+ TYPE_NAME ( modified_type) = get_identifier ( rec_name);
+
+ // TBD Create its fields by walking the old type.
+ tree field;
+ tree new_fields = NULL;
+ for ( field = TYPE_FIELDS ( type); field; field = DECL_CHAIN ( field))
+ {
+ tree field_type = TREE_TYPE ( field);
+ tree new_fld_type;
+
+ // TBD Do I need a canonical type here instead?
+ //auto is_modified = info->modified_types->find ( type);
+ auto is_modified = find_in_vec_of_two_types ( info->modified_types, type);
+ if ( is_modified != info->modified_types->end () )
+ {
+ if ( POINTER_TYPE_P ( field_type))
+ {
+ ReorgType_t *ri = get_reorgtype_info ( field_type, info);
+ int levels = number_of_levels ( field_type);
+ if ( ri == NULL )
+ {
+ new_fld_type = make_multilevel ( is_modified->second, levels);
+ }
+ else
+ {
+ new_fld_type = make_multilevel ( ri->pointer_rep, levels - 1);
+ }
+ }
+ else
+ {
+ new_fld_type = is_modified->second;
+ }
+ }
+ else
+ {
+ // This field doesn't need to be modified.
+ new_fld_type = field_type;
+ }
+ tree new_decl =
+ build_decl ( DECL_SOURCE_LOCATION (field),
+ FIELD_DECL, DECL_NAME (field), new_fld_type);
+ DECL_CONTEXT ( new_decl) = modified_type;
+ layout_decl ( new_decl, 0);
+
+ // We might be missing a bunch of attributes (see
+ // tree-nested.c:899) But we seem without without them!
+
+ DECL_CHAIN ( new_decl) = new_fields; // <- bug: need decl, not type
+ new_fields = new_decl;
+ }
+
+ // Reverse fields. Note, a some point try nreverse here instead.
+ TYPE_FIELDS ( modified_type) = NULL;
+ tree next_fld;
+ for ( field = new_fields;
+ field;
+ field = next_fld )
+ {
+ next_fld = DECL_CHAIN ( field);
+ DECL_CHAIN ( field) = TYPE_FIELDS ( modified_type);
+ TYPE_FIELDS ( modified_type) = field;
+ }
+
+ // Lay it out
+ layout_type ( modified_type);
+ }
+ else
+ {
+ info->dont_modify->insert ( type);
+ }
+ DEBUG_A("Was %smodidied\n", modified ? "" : "not ");
+ INDENT(-4);
+ return modified;
+}
+#endif
+
#if USE_REORG_TYPES
static void
add_reorg_type (
@@ -1024,8 +1658,8 @@ add_reorg_type (
{ 0, del, tmv_type, NULL, NULL, false, false, false,
{ 0}, { 0}, { 0, 0, 0, NULL, 0.0, 0.0, false}};
- DEBUG_L("add_reorg_type: ");
- DEBUG_F(flexible_print, stderr, base, 1, (dump_flags_t)0);
+ //DEBUG_L("add_reorg_type: ");
+ //DEBUG_F(flexible_print, stderr, base, 1, (dump_flags_t)0);
info->reorg_type->push_back ( rt);
#if !USE_ESCAPE_ANALYSIS
// Remember the intial assumption is the type added will be deleted
@@ -1588,9 +2222,16 @@ reverse_args( tree args )
return reveresed;
}
-
-
-
+std::vector<two_trees_t>::iterator
+find_in_vec_of_two_types ( std::vector<two_trees_t> *types, tree type)
+{
+ for ( auto looki = types->begin (); looki != types->end (); looki++)
+ {
+ tree look = looki->first;
+ if ( same_type_p ( look, type) ) return looki;
+ }
+ return types->end ();
+}
int
number_of_levels ( tree type)
@@ -1608,25 +2249,25 @@ tree prev_type;
}
tree
-make_multilevel( tree base_type, int levels_indirection)
+make_multilevel ( tree base_type, int levels_indirection)
{
- //DEBUG_A("make_multilevel %d levels of ", levels_indirection);
- //DEBUG_F( flexible_print, stderr, base_type, 1, (dump_flags_t)0);
- //INDENT(4);
+ DEBUG_A("make_multilevel %d levels of ", levels_indirection);
+ DEBUG_F( flexible_print, stderr, base_type, 1, (dump_flags_t)0);
+ INDENT(4);
if ( levels_indirection == 0 )
{
- //INDENT(-4);
- //DEBUG_A("returns: ");
- //DEBUG_F( flexible_print, stderr, base_type, 1, (dump_flags_t)0);
+ INDENT(-4);
+ DEBUG_A("returns: ");
+ DEBUG_F( flexible_print, stderr, base_type, 1, (dump_flags_t)0);
return base_type;
}
else
{
tree lower = make_multilevel ( base_type, levels_indirection - 1);
tree returns = build_pointer_type ( lower);
- //INDENT(-4);
- //DEBUG_A("returns: ");
- //DEBUG_F( flexible_print, stderr, returns, 1, (dump_flags_t)0);
+ INDENT(-4);
+ DEBUG_A("returns: ");
+ DEBUG_F( flexible_print, stderr, returns, 1, (dump_flags_t)0);
return returns;
}
}
@@ -1654,10 +2295,10 @@ modify_func_decl_core ( struct function *func, Info *info)
//INDENT(-4);
return false;
}
- DEBUG_A("pointer_rep = ");
- DEBUG_F( flexible_print, stderr, ri->pointer_rep, 1, (dump_flags_t)0);
- DEBUG_A("TYPE_MAIN_VARIANT( pointer_rep) = ");
- DEBUG_F( flexible_print, stderr, TYPE_MAIN_VARIANT( ri->pointer_rep), 1, (dump_flags_t)0);
+ //DEBUG_A("pointer_rep = ");
+ //DEBUG_F( flexible_print, stderr, ri->pointer_rep, 1, (dump_flags_t)0);
+ //DEBUG_A("TYPE_MAIN_VARIANT( pointer_rep) = ");
+ //DEBUG_F( flexible_print, stderr, TYPE_MAIN_VARIANT( ri->pointer_rep), 1, (dump_flags_t)0);
int levels = number_of_levels ( func_type);
@@ -1764,17 +2405,17 @@ modify_decl_core ( tree *location, Info *info)
bool
modify_decl_core ( tree *location, Info *info)
{
- DEBUG_L("before modify_decl_core: ");
- DEBUG_F( flexible_print, stderr, *location, 1, (dump_flags_t)0);
+ //DEBUG_L("before modify_decl_core: ");
+ //DEBUG_F( flexible_print, stderr, *location, 1, (dump_flags_t)0);
//tree type = *location;
tree type = TREE_TYPE ( *location);
- DEBUG_A("type = ");
- DEBUG_F( flexible_print, stderr, type, 0, (dump_flags_t)0);
+ //DEBUG_A("type = ");
+ //DEBUG_F( flexible_print, stderr, type, 0, (dump_flags_t)0);
tree base = base_type_of ( type);
- DEBUG_A(", base = ");
- DEBUG_F( flexible_print, stderr, base, 1, (dump_flags_t)0);
+ //DEBUG_A(", base = ");
+ //DEBUG_F( flexible_print, stderr, base, 1, (dump_flags_t)0);
ReorgType_t *ri = get_reorgtype_info ( base, info);
if ( ri == NULL )
{
@@ -1870,7 +2511,7 @@ undelete_reorgtype ( ReorgType_t *rt, Info *info )
static ReorgTransformation
reorg_recognize_ret_action( ReorgTransformation val, unsigned ln)
{
- #if DEBUGGING
+ #if DEBUGGING && 0
fprintf ( stderr, "L# %4d: %*s returns %s\n",
ln, debug_indenting, "", reorgtrans_to_str (val));
#endif
@@ -1880,28 +2521,28 @@ reorg_recognize_ret_action( ReorgTransformation val, unsigned ln)
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:
@@ -1935,8 +2576,8 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info )
return REORG_RECOG_RET_ACT ( 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"
@@ -1952,8 +2593,8 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info )
return REORG_RECOG_RET_ACT ( 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"
@@ -1964,8 +2605,8 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info )
return REORG_RECOG_RET_ACT ( 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"
@@ -1978,8 +2619,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"
@@ -2002,8 +2643,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
@@ -2032,24 +2673,24 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info )
return REORG_RECOG_RET_ACT ( 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 REORG_RECOG_RET_ACT ( 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 REORG_RECOG_RET_ACT ( Not_Supported);
}
@@ -2059,8 +2700,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:
@@ -2086,8 +2727,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);
@@ -2118,17 +2759,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 REORG_RECOG_RET_ACT ( ReorgT_Calloc);
if ( gimple_call_builtin_p( stmt, BUILT_IN_MALLOC ) ) return REORG_RECOG_RET_ACT ( ReorgT_Malloc);
if ( gimple_call_builtin_p( stmt, BUILT_IN_REALLOC) ) return REORG_RECOG_RET_ACT ( ReorgT_Realloc);
@@ -2141,7 +2782,7 @@ 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 REORG_RECOG_RET_ACT ( ReorgT_UserFunc);
}
//DEBUG_A(" Not_supported\n");
@@ -2150,15 +2791,15 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info )
}
break;
case GIMPLE_RETURN:
- DEBUG_L("GIMPLE_RETURN:\n");
- INDENT(-2);
+ //DEBUG_L("GIMPLE_RETURN:\n");
+ //INDENT(-2);
return REORG_RECOG_RET_ACT ( 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 REORG_RECOG_RET_ACT ( Not_Supported);
}
}
@@ -2272,10 +2913,10 @@ recognize_op_ret_action ( enum ReorgOpTrans 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 INTEGER_CST:
@@ -2302,8 +2943,8 @@ 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);
+ //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.
@@ -2405,20 +3046,20 @@ recognize_op ( tree op, bool lie, Info *info)
}
case COMPONENT_REF:
{
- DEBUG_L("process: 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);
- 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));
+ //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));
// Note, a reorg type can only occurr at the bottom or
// the top, that is "rt.a.b..." or "a.b...z.rt".
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);
+ //DEBUG_L("Is multilevel component ref: deep_type is ");
+ //DEBUG_F(flexible_print, stderr, deep_type, 1, (dump_flags_t)0);
bool a_deep_reorg = is_reorg_type ( base_type_of ( deep_type), info);
if ( a_deep_reorg || !lie )
@@ -2430,12 +3071,12 @@ recognize_op ( tree op, bool lie, Info *info)
}
if ( tree_contains_a_reorgtype_p ( op, info))
{
- DEBUG_A("POINTER_TYPE_P ( type) : %s\n",
- POINTER_TYPE_P ( type) ? "true" : "false");
+ //DEBUG_A("POINTER_TYPE_P ( type) : %s\n",
+ // POINTER_TYPE_P ( type) ? "true" : "false");
if ( POINTER_TYPE_P ( type))
{
- DEBUG_A("TREE_CODE ( TREE_TYPE( type)) == RECORD_TYPE : %s\n",
- TREE_CODE ( TREE_TYPE( type)) == RECORD_TYPE ? "true" : "false");
+ //DEBUG_A("TREE_CODE ( TREE_TYPE( type)) == RECORD_TYPE : %s\n",
+ // TREE_CODE ( TREE_TYPE( type)) == RECORD_TYPE ? "true" : "false");
}
}
if ( tree_contains_a_reorgtype_p ( op, info)
@@ -2447,7 +3088,7 @@ recognize_op ( tree op, bool lie, Info *info)
}
if ( inner_op0_code == INDIRECT_REF )
{
- DEBUG_L("TREE_CODE( inner_op) == INDIRECT_REF\n");
+ //DEBUG_L("TREE_CODE( inner_op) == INDIRECT_REF\n");
bool a_base_reorg = is_reorg_type ( base_type_of ( type), info);
if ( a_base_reorg || !lie )
{
@@ -2457,7 +3098,7 @@ recognize_op ( tree op, bool lie, Info *info)
return recognize_op_ret_action ( ReorgOpT_Scalar);
}
if ( inner_op0_code == MEM_REF ) {
- DEBUG_L("TREE_CODE( inner_op) == MEM_REF\n");
+ //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 )
{
@@ -2468,14 +3109,14 @@ recognize_op ( tree op, bool lie, Info *info)
}
if ( inner_op0_code == COMPONENT_REF )
{
- DEBUG_L("TREE_CODE( inner_op) == COMPONENT_REF\n");
+ //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));
+ //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 )
@@ -2485,7 +3126,7 @@ 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, component or mem ref\n");
+ //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.
@@ -2501,20 +3142,20 @@ recognize_op ( tree op, bool lie, Info *info)
}
case ARRAY_REF:
{
- DEBUG_L("process: 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_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);
+ //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");
+ //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 )
{
@@ -2533,7 +3174,7 @@ recognize_op ( tree op, bool lie, Info *info)
}
case INDIRECT_REF:
{
- DEBUG_L("process: 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.)
@@ -2546,10 +3187,10 @@ recognize_op ( tree op, bool lie, Info *info)
}
case MEM_REF:
{
- 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);
+ //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 )
{
@@ -2565,16 +3206,16 @@ recognize_op ( tree op, bool lie, Info *info)
tree
multilevel_component_ref ( tree op)
{
- DEBUG_A("multilevel_component_ref: ");
- DEBUG_F(flexible_print, stderr, op, 1, (dump_flags_t)0);
- INDENT(2);
+ //DEBUG_A("multilevel_component_ref: ");
+ //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 )
{
tree ret = multilevel_component_ref ( inner_op0);
- INDENT(-2);
+ //INDENT(-2);
return ret;
}
else
@@ -2583,14 +3224,14 @@ 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);
- INDENT(-2);
+ //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;
}
}
- DEBUG_A(" found: no deep type\n");
- INDENT(-2);
+ //DEBUG_A(" found: no deep type\n");
+ //INDENT(-2);
return NULL;
}
@@ -2712,16 +3353,15 @@ apply_to_all_gimple ( bool (*function)(gimple *, void *), bool phis_too, void *d
// What's dicey about this is it may sort of work but then I
// can see places where it wouldn't... The language has a say
// in what types are equal so maybe language hooks are involved???
-bool same_type_p(
- tree a, tree b
- )
+bool
+same_type_p ( tree a, tree b )
{
- DEBUG( "same_type_p:\n");
- DEBUG( " a: TREE_CODE = %s, name = %p\n ",code_str(TREE_CODE(a)),TYPE_NAME(a));
- DEBUG_F( print_generic_expr, stderr, a, (dump_flags_t)-1);
- DEBUG( "\n b TREE_CODE = %s, name = %p\n ",code_str(TREE_CODE(b)),TYPE_NAME(b));
- DEBUG_F( print_generic_expr, stderr, b, (dump_flags_t)-1);
- DEBUG( "\n");
+ //DEBUG( "same_type_p:\n");
+ //DEBUG( " a: TREE_CODE = %s, name = %p\n ",code_str(TREE_CODE(a)),TYPE_NAME(a));
+ //DEBUG_F( print_generic_expr, stderr, a, (dump_flags_t)-1);
+ //DEBUG( "\n b TREE_CODE = %s, name = %p\n ",code_str(TREE_CODE(b)),TYPE_NAME(b));
+ //DEBUG_F( print_generic_expr, stderr, b, (dump_flags_t)-1);
+ //DEBUG( "\n");
// This replaces part of the below
bool a_rec = TREE_CODE ( a ) == RECORD_TYPE;
@@ -2742,7 +3382,7 @@ bool same_type_p(
bool ret = TYPE_NAME ( a) == TYPE_NAME ( b);
- DEBUG( "returns %s\n", ret ? "true" : "false");
+ //DEBUG( "returns %s\n", ret ? "true" : "false");
return ret;
}
@@ -2753,8 +3393,8 @@ bool same_type_p(
ReorgType_t *
get_reorgtype_info ( tree type, Info* info)
{
- DEBUG_L( "get_reorgtype_info: type = ");
- DEBUG_F( flexible_print, stderr, type, 1, (dump_flags_t)0);
+ //DEBUG_L( "get_reorgtype_info: type = ");
+ //DEBUG_F( flexible_print, stderr, type, 1, (dump_flags_t)0);
// Note, I'm going to use the most stupid and slowest possible way
// to do this. The advanage is it will be super easy and almost
@@ -2772,9 +3412,9 @@ get_reorgtype_info ( tree type, Info* info)
// so this is just a place holder until I can get an answer
// from the gcc community. Note, this is a big issue.
// Remember, the same_type_p here is my own temporary hack.
- DEBUG_L("");
- DEBUG_F( print_generic_expr, stderr, type, TDF_DETAILS);
- DEBUG("\n");
+ //DEBUG_L("");
+ //DEBUG_F( print_generic_expr, stderr, type, TDF_DETAILS);
+ //DEBUG("\n");
if ( same_type_p ( ri->gcc_type, type2check ) )
{
//DEBUG_A( " returns %p\n", &(*ri));
@@ -2782,7 +3422,7 @@ get_reorgtype_info ( tree type, Info* info)
return &(*ri);
}
}
- DEBUG_A( " returns NULL\n");
+ //DEBUG_A( " returns NULL\n");
return NULL;
}
@@ -2955,13 +3595,13 @@ print_base_reorg ( FILE *file, int leading_space, ReorgType_t *reorg, bool detai
fprintf ( file, "no interleave, ");
}
- DEBUG_L("reorg->reorg_ver_type = %p\n", reorg->reorg_ver_type);
+ //DEBUG_L("reorg->reorg_ver_type = %p\n", reorg->reorg_ver_type);
if ( reorg->reorg_ver_type != NULL && TYPE_NAME ( reorg->reorg_ver_type) != NULL )
{
// TBD does this belong here? How will the clone be done with elim and
// reorder
- DEBUG_A("%p, %p\n", reorg->reorg_ver_type, TYPE_NAME ( reorg->reorg_ver_type));
+ //DEBUG_A("%p, %p\n", reorg->reorg_ver_type, TYPE_NAME ( reorg->reorg_ver_type));
const char *clone_name =
identifier_to_locale ( IDENTIFIER_POINTER ( TYPE_NAME ( reorg->reorg_ver_type)));
fprintf ( file, "%s%s", clone_name, reorg->pointer_rep ? ", " : "");
diff --git a/gcc/ipa-structure-reorg.h b/gcc/ipa-structure-reorg.h
index bf8843b46ec..77b979fa058 100644
--- a/gcc/ipa-structure-reorg.h
+++ b/gcc/ipa-structure-reorg.h
@@ -162,6 +162,20 @@ struct BoolPair {
bool layout_changed;
};
+typedef struct two_trees two_trees_t;
+struct two_trees {
+ tree first;
+ tree second;
+};
+
+typedef struct type_holder TypeHolder;
+
+struct type_holder
+{
+ std::vector <tree> refed_types;
+ std::vector <tree> rec_types;
+};
+
typedef struct Info Info_t;
struct Info {
// TODO: What is the meaning of reorg type?
@@ -175,9 +189,13 @@ struct Info {
// Gcc doesn't have global decls readily available
// so this holds them
std::map <tree,BoolPair_t> *struct_types; // desing bug fix
+ // For pointer modification
+ std::vector <two_trees_t> *modified_types;
+ std::set <tree> *dont_modify;
int num_deleted;
double total_cache_accesses;
FILE *reorg_dump_file;
+ std::map <tree,TypeHolder> *type_mod_info;
// Debug flags
bool show_all_reorg_cands;
bool show_all_reorg_cands_in_detail;
@@ -189,14 +207,20 @@ struct Info {
bool show_bounds;
bool is_non_escaping_set_empty();
- Info (std::vector <ReorgType_t> *v1,
- std::vector <ReorgType_t> *v2,
- std::vector <ProgDecl_t> *v3,
- std::map <tree, BoolPair_t> *v4)
+ Info (std::vector <ReorgType_t> *v1,
+ std::vector <ReorgType_t> *v2,
+ std::vector <ProgDecl_t> *v3,
+ std::map <tree,BoolPair_t> *v4,
+ std::vector <two_trees_t> *v5,
+ std::set <tree> *v6,
+ std::map <tree,TypeHolder> *v7)
: reorg_type(v1)
, saved_reorg_type(v2)
, prog_decl(v3)
, struct_types(v4)
+ , modified_types(v5)
+ , dont_modify(v6)
+ , type_mod_info(v7)
, num_deleted(0)
, total_cache_accesses(0)
, reorg_dump_file(NULL)
@@ -227,7 +251,8 @@ extern int str_reorg_dead_field_eliminate ( Info *);
extern int str_reorg_field_reorder ( Info *);
extern int str_reorg_instance_interleave ( Info *);
#endif
-
+extern void find_and_create_all_modified_types ( Info_t *);
+extern std::vector<two_trees_t>::iterator find_in_vec_of_two_types ( std::vector<two_trees_t> *, tree);
extern int number_of_levels ( tree);
extern tree make_multilevel( tree, int);
extern bool modify_decl_core ( tree *, Info *);
@@ -241,6 +266,7 @@ extern ReorgTransformation reorg_recognize ( gimple *,
cgraph_node *,
Info_t *);
extern void apply_to_all_gimple ( bool (*)(gimple *, void *), bool, void *);
+extern bool same_type_p( tree, tree);
extern ReorgType_t *get_reorgtype_info ( tree, Info_t *);
extern void print_reorg_with_msg ( FILE *, ReorgType_t *, int, const char *);
extern ReorgType_t *contains_a_reorgtype ( gimple *, Info *);