summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Oblock <gary@amperecomputing.com>2020-05-14 12:08:28 -0700
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-09-08 08:50:21 +0200
commita1624e8337fe6a70fd8b6c7da6fd6569a38294a8 (patch)
tree392de831410cf29923d49a917cee287b8f081c3c
parentc6f774f496351e5ad7bad61dcfb292c6481bfae7 (diff)
Back to the Marvell orginal code
-rw-r--r--gcc/ipa-structure-reorg.c1753
-rw-r--r--gcc/ipa-structure-reorg.h187
2 files changed, 1307 insertions, 633 deletions
diff --git a/gcc/ipa-structure-reorg.c b/gcc/ipa-structure-reorg.c
index 10e092b664d..5629cd7724d 100644
--- a/gcc/ipa-structure-reorg.c
+++ b/gcc/ipa-structure-reorg.c
@@ -34,225 +34,277 @@ along with GCC; see the file COPYING3. If not see
#include <set>
#include "ipa-structure-reorg.h"
#include "dumpfile.h"
+#include "pretty-print.h"
#include "tree-pretty-print.h"
#include "gimple-pretty-print.h"
#include "langhooks.h"
// TBD more includes go here
-static void
-setup_debug_flags (Info *);
-static void
-final_debug_info (Info *);
-static unsigned int
-reorg_analysis (Info_t *);
-static void
-reorg_analysis_debug (Info *, ReorgType *);
-static bool
-find_decls_and_types (Info_t *);
-static void
-disqualify_struct_in_struct_or_union (Info_t *);
-static void
-initial_reorg_debug (Info *info, ReorgType *reorg);
-static void
-disqualify_struct_in_struct_or_union_debug (Info *, ReorgType *);
-static void
-disq_str_in_str_or_union_helper (tree, std::set<tree> *, Info_t *);
-static unsigned int
-reorg_qualification (Info_t *);
+
+static void setup_debug_flags ( Info *);
+static void final_debug_info ( Info *);
+static unsigned int reorg_analysis ( Info_t *);
+static void reorg_analysis_debug ( Info *, ReorgType *);
+static bool find_decls_and_types ( Info_t *);
+static void add_reorg_type( Info *, ReorgType *);
+static void disqualify_struct_in_struct_or_union ( Info_t *);
+static void initial_reorg_debug ( Info *info, ReorgType *reorg );
+static void disqualify_struct_in_struct_or_union_debug ( Info *,
+ ReorgType *);
+static void disq_str_in_str_or_union_helper ( tree,
+ std::set<tree> *,
+ Info_t *);
+static unsigned int reorg_qualification ( Info_t *);
+static bool transformation_legality( Info_t *);
+static void transformation_legality_debug ( Info *, ReorgType *);
+static bool reorg_legality ( Info_t *);
+static void reorg_forbidden ( gimple *, Info_t *);
// Name changed and moved to its own file
-// static void reorg_transformation ( Info_t *);
+//static void reorg_transformation ( Info_t *);
// made extern
-// static void delete_reorgtype ( ReorgType_t *, Info_t *);
-// static void undelete_reorgtype ( ReorgType_t *, Info_t *);
-// static void remove_deleted_types ( Info *, ReorgFn);
-static tree base_type_of (tree);
-static bool
-is_reorg_alloc_trigger (gimple *);
-static ReorgType_t *
-find_struct_type_ptr_to_struct (tree, Info *);
-static ReorgType_t *
-get_reorgtype_info (tree type, Info_t *info);
-static void
-print_reorg_with_msg (FILE *, ReorgType_t *, int, const char *);
-static void
-dump_reorg (ReorgType_t *reorg);
-static void
-print_reorgs (FILE *, int, Info *);
-static void
-print_reorg (FILE *, int, ReorgType_t *);
-//-- debugging only --
-static const char *code_str (enum tree_code);
+//static void delete_reorgtype ( ReorgType_t *, Info_t *);
+//static void undelete_reorgtype ( ReorgType_t *, Info_t *);
+//static void remove_deleted_types ( Info *, ReorgFn);
+static enum ReorgOpTrans recognize_op ( tree, Info_t *);
+static ReorgTransformation reorg_recognize ( gimple *, Info_t *);
+static bool is_reorg_type ( tree, Info_t *);
+static tree base_type_of ( tree);
+static bool is_reorg_alloc_trigger ( gimple *);
+static ReorgType_t *find_struct_type_ptr_to_struct ( tree, Info_t *);
+static ReorgType_t *get_reorgtype_info ( tree, Info_t *);
+static void print_reorg_with_msg ( FILE *, ReorgType_t *, int, const char *);
+static void dump_reorg ( ReorgType_t *reorg);
+static void print_reorgs ( FILE *, int, Info_t *);
+static void print_reorg ( FILE *, int, ReorgType_t *);
+static void print_progdecls ( FILE *, int, Info_t *);
+static void print_progdecl ( FILE *, int, ProgDecl_t *);
+static void print_program ( FILE *, int);
+static void print_function ( FILE *, int, function *);
+static ReorgType_t *get_reorgtype( gimple *stmt, Info_t *, int);
+static int num_reorgtypes( gimple *, Info_t *);
+static bool points_to_escape_analysis( Info_t *);
+static bool uses_field_of_reorgtypes( gimple *, Info_t *);
+//-- debugging only --
+#if DEBUGGING
+static const char *code_str( enum tree_code);
+static const char *type_name_to_str( tree);
+static void handle_debug_indenting( int);
+static int debug_indenting = 0;
+#endif
//---------------- Code Follows ----------------
-
+
static unsigned int
-ipa_structure_reorg (void)
+ipa_structure_reorg ( void)
{
- std::vector<ReorgType_t> Reorg_Type;
- 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 <ReorgType_t> Reorg_Type;
+ std::vector <ReorgType_t> Saved_Reorg_Type;
+ std::vector <ProgDecl_t> Prog_Decl;
+ std::map <tree,BoolPair_t> StructTypes; // TBD horrible type name
- // DEBUG( "Running ipa_structure_reorg\n");
+ //DEBUG_L( "Running ipa_structure_reorg\n");
+ //INDENT(2);
// TBD we must have run the IPA points-to analysis and
// be running in a single LTRANS partition. Sanity check
// these here.
- Info_t info = {&Reorg_Type, &Saved_Reorg_Type,
- &Prog_Decl, &StructTypes,
- 0, 0.0,
- false, false,
- false, false,
- false, false};
-
- setup_debug_flags (&info);
+ Info_t info = { &Reorg_Type,
+ &Saved_Reorg_Type,
+ &Prog_Decl,
+ &StructTypes,
+ 0,
+ 0.0,
+ NULL,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false};
+
+ setup_debug_flags ( &info);
+
+ if ( !reorg_analysis ( &info) )
+ {
+ return true;
+ }
- if (flag_ipa_dead_field_eliminate)
- {
- str_reorg_dead_field_eliminate (&info);
+ if ( reorg_qualification ( &info) )
+ {
+ // Each of these do their own performance qualification and
+ // if they delete any types they must invoke restore_deleted_types
+ // so the next subpass has all the types to consider.
+ // Also, if they change the shape of a type the must create my
+ // type and update the ReorgTypes to reflect this.
+
+ if ( flag_ipa_structure_reorg || flag_ipa_dead_field_eliminate ) {
+ str_reorg_dead_field_eliminate ( &info);
}
-
- return true;
-
- if (reorg_qualification (&info))
- {
- // Each of these do their own performance qualification and
- // if they delete any types they must invoke restore_deleted_types
- // so the next subpass has all the types to consider.
- // Also, if they change the shape of a type the must create my
- // type and update the ReorgTypes to reflect this.
-
- if (flag_ipa_structure_reorg || flag_ipa_field_reorder)
- {
- str_reorg_field_reorder (&info);
- }
- if (flag_ipa_structure_reorg || flag_ipa_instance_interleave)
- {
- str_reorg_instance_interleave (&info);
- }
+ if ( flag_ipa_structure_reorg || flag_ipa_field_reorder ) {
+ str_reorg_field_reorder ( &info);
+ }
+ if ( flag_ipa_structure_reorg || flag_ipa_instance_interleave ) {
+ str_reorg_instance_interleave ( &info);
}
+ }
- final_debug_info (&info);
+ final_debug_info ( &info);
return true;
}
static void
-setup_debug_flags (Info *info)
+setup_debug_flags ( Info *info)
{
// The normal way of doing this would be to
// set the flags with dump_file && (dump_flags & TDF_XXX
// where XXX is some level of dump control but
// I think the code here would work better
// (where each flag is set off the dump_flags.)
-
- if (dump_file)
- {
- info->show_all_reorg_cands = true;
- info->show_all_reorg_cands_in_detail = dump_flags & TDF_DETAILS;
- info->show_delete = dump_flags & TDF_DETAILS;
- info->show_new_BBs = dump_flags & TDF_DETAILS;
- info->show_transforms = dump_flags & TDF_DETAILS;
- info->show_bounds = dump_flags & TDF_DETAILS;
- }
+
+ if ( dump_file )
+ {
+ info->show_all_reorg_cands = true;
+ info->show_all_reorg_cands_in_detail = dump_flags & TDF_DETAILS;
+ info->show_prog_decls = true;
+ info->show_delete = dump_flags & TDF_DETAILS;
+ info->show_new_BBs = dump_flags & TDF_DETAILS;
+ info->show_transforms = dump_flags & TDF_DETAILS;
+ info->show_bounds = dump_flags & TDF_DETAILS;
+ info->reorg_dump_file = dump_file;
+ #if DEBUGGING
+ info->reorg_dump_file = stderr;
+ #endif
+ }
}
static void
-final_debug_info (Info *info)
+final_debug_info ( Info *info)
{
// TBD
+ if ( info->reorg_dump_file )
+ {
+ print_program ( info->reorg_dump_file, 0);
+ }
}
static unsigned int
-reorg_analysis (Info_t *info)
+reorg_analysis ( Info_t *info)
{
struct cgraph_node *node;
- find_decls_and_types (info);
+ find_decls_and_types ( info);
// Skip computing numbOfGlobalArrays initially.
// Skip computing numbOfLocalArrays initially.
// Compute numbOfDynmAllocs per type in regtype
- FOR_EACH_FUNCTION (node)
- {
- basic_block bb;
+ FOR_EACH_FUNCTION ( node) {
+ basic_block bb;
- struct function *func = DECL_STRUCT_FUNCTION (node->decl);
+ struct function *func = DECL_STRUCT_FUNCTION ( node->decl);
- // This is a work around
- if (func == NULL)
- {
- continue;
- }
+ // This is a work around
+ if ( func == NULL )
+ {
+ continue;
+ }
- FOR_EACH_BB_FN (bb, func)
+ // Note,there is a major design issue with the design of this code.
+ // This can stand as is for now but it must be fixed relatively soon.
+ FOR_EACH_BB_FN ( bb, func)
+ {
+ gimple_stmt_iterator gsi;
+ for ( gsi = gsi_start_bb ( bb);
+ !gsi_end_p ( gsi);
+ gsi_next ( &gsi) )
+ {
+ gimple *stmt = gsi_stmt ( gsi);
+ //DEBUG_L ( "");
+ //DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
+ //INDENT(2);
+ if ( is_gimple_call ( stmt) )
{
- gimple_stmt_iterator gsi;
- for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ // next line has issues but the mechanism is sound
+ tree t = *gimple_call_lhs_ptr ( stmt);
+ //DEBUG_A( "t %p\n", t);
+ // Calls to a function returning void are skipped.
+ if ( t != NULL )
+ {
+ tree type = TREE_TYPE( t);
+ //tree bt = base_type_of ( t);
+ tree bt = base_type_of ( type);
+ if ( TREE_CODE( bt) != RECORD_TYPE )
{
- gimple *stmt = gsi_stmt (gsi);
- // DEBUG_F ( print_gimple_stmt, stderr, stmt, (dump_flags_t)-1);
- // DEBUG ( "\n");
- if (is_gimple_call (stmt))
- {
- // next line has issues but the mechanism is sound
- tree t = *gimple_call_lhs_ptr (stmt);
- // DEBUG( "t %p\n", t);
- // Calls to a function returning void are skipped.
- if (t != NULL)
- {
- tree bt = base_type_of (t);
- if (TREE_CODE (bt) != RECORD_TYPE)
- {
- continue;
- }
- // find if in reorgtypes and get the info (in one call)
- ReorgType_t *ri = get_reorgtype_info (bt, info);
- if (ri != NULL && is_reorg_alloc_trigger (stmt))
- {
- ri->numbOfDynmAllocs++;
- }
- }
- }
+ //DEBUG_A( "TREE_CODE( bt) == %s\n", code_str( TREE_CODE ( bt)));
+ //DEBUG_A("");
+ //DEBUG_F( print_generic_expr, stderr, bt, (dump_flags_t)-1);
+ //INDENT(-2);
+ continue;
+ }
+ // find if in reorgtypes and get the info (in one call)
+ ReorgType_t *ri = get_reorgtype_info ( bt, info);
+ if ( ri != NULL && is_reorg_alloc_trigger ( stmt) )
+ {
+ //DEBUG_L( "Found allocaion: \n");
+ //DEBUG_A( " Reorg: ");
+ //DEBUG_F( print_reorg, stderr, 0, ri);
+ //DEBUG("\n");
+ ri->numbOfDynmAllocs++;
}
+ }
}
+ INDENT(-2);
+ }
}
+ }
+ //DEBUG_L( "possible deletes:\n");
+ //INDENT(2);
// It's LOT clear to use an iterator here TBD
- for (int i = 0; i < info->reorg_type->size (); i++)
+ for ( int i = 0; i < info->reorg_type->size (); i++ )
+ {
+ int n = (*(info->reorg_type))[i].numbOfGlobalArrays
+ + (*(info->reorg_type))[i].numbOfLocalArrays
+ + (*(info->reorg_type))[i].numbOfDynmAllocs;
+ if ( n > 1 )
{
- int n = (*(info->reorg_type))[i].numbOfGlobalArrays
- + (*(info->reorg_type))[i].numbOfLocalArrays
- + (*(info->reorg_type))[i].numbOfDynmAllocs;
- if (n > 1)
- {
- (*(info->reorg_type))[i].multi_pool = true;
- }
- if (n == 0)
- {
- delete_reorgtype (&(*(info->reorg_type))[i], info);
- }
+ (*(info->reorg_type))[i].multi_pool = true;
+ }
+ // Note when multi-pools are enabled the test should be
+ // "n == 0" but until then...
+ if ( n != 1 )
+ {
+ delete_reorgtype ( &(*(info->reorg_type))[i], info);
}
+ }
+ //INDENT(-2);
- remove_deleted_types (info, &reorg_analysis_debug);
+ remove_deleted_types ( info, &reorg_analysis_debug);
+
+ if ( info->show_all_reorg_cands )
+ {
+ fprintf ( info->reorg_dump_file, "All Reorg Analysis ReorgTypes:\n");
+ print_reorgs ( info->reorg_dump_file, 2, info);
+ }
return !info->reorg_type->empty ();
}
void
-reorg_analysis_debug (Info *info, ReorgType *reorg)
+reorg_analysis_debug ( Info *info, ReorgType *reorg )
{
- if (info->show_delete)
- {
- print_reorg_with_msg (dump_file, reorg, 2, "Was not allocated");
- }
+ if ( info->show_delete )
+ {
+ print_reorg_with_msg ( info->reorg_dump_file, reorg, 2,
+ "Was not allocated");
+ }
}
-static bool
-find_decls_and_types (Info_t *info)
+static bool find_decls_and_types ( Info_t *info)
{
// Don't keep any structure types if they aren't
// used in an array or have a pointer type (which
@@ -261,101 +313,104 @@ find_decls_and_types (Info_t *info)
// allocated arrays.
//
// This initializes them too of course.
-
+
// Find all struct types for initial ReorgTypes
// marking them all to initially be deleted.
// This is done by walking all variables.
std::set<tree> typeset;
varpool_node *var;
- FOR_EACH_VARIABLE (var)
+ FOR_EACH_VARIABLE ( var)
+ {
+ tree decl = var->decl;
+ //DEBUG_L( "Consider var->decl\n");
+ //DEBUG_L( "");
+ //DEBUG_F( print_generic_decl, stderr, decl, (dump_flags_t)-1);
+ tree base = base_type_of ( decl);
+ //DEBUG( "\n");
+ //DEBUG_A(Base\n");
+ //DEBUG_A( "TREE_CODE = %s, ", code_str( TREE_CODE ( base)));
+ //DEBUG_F( print_generic_expr, stderr, base, (dump_flags_t)-1);
+ //DEBUG( "\n");
+
+ if ( TREE_CODE ( base) == RECORD_TYPE )
{
- tree decl = var->decl;
- // DEBUG( "L# %d Consider var->decl\n", __LINE__);
- // DEBUG_F( print_generic_decl, stderr, decl, (dump_flags_t)-1);
- tree base = base_type_of (decl);
- // DEBUG( "\nBase\n");
- // DEBUG( "TREE_CODE = %s\n", code_str( TREE_CODE ( base)));
- // DEBUG_F( print_generic_expr, stderr, base, (dump_flags_t)-1);
- // DEBUG( "\n");
-
- if (TREE_CODE (base) == RECORD_TYPE)
- {
- // skip if found before
- if (typeset.find (base) != typeset.end ())
- {
- // DEBUG( "not found\n");
- continue;
- }
- else
- {
- // DEBUG( "found\n")
- ;
- }
- ReorgType_t rt
- = {0, base, 0, 0, 0, 0.0, 0.0, false, true, NULL, NULL};
- info->reorg_type->push_back (rt);
- typeset.insert (base); // ???
- }
+ // skip if found before
+ if ( typeset.find ( base) != typeset.end () )
+ {
+ //DEBUG_L( " not found\n");
+ continue;
+ } else {
+ //DEBUG_L( " found\n")
+ ;
+ }
+ ReorgType_t rt =
+ { 0, base, 0, 0, 0, 0.0, 0.0, false, true, NULL, NULL };
+ add_reorg_type ( info, &rt);
+ typeset.insert ( base); // ???
}
-
+ }
+
// NOTE, the scheme above leaves out local variables so
// I'll repeat the for the local variable of functions.
// TBD Am I doing something actually, after this, that
// is actually done here or above... it seems likely.
- cgraph_node *node;
- FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
+ cgraph_node* node;
+ FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node)
+ {
+ tree decl;
+ unsigned i;
+
+ node->get_untransformed_body ();
+
+ struct function *fn = DECL_STRUCT_FUNCTION ( node->decl);
+ // enable this to see error in test_1_8
+ //DEBUG_L( "function name = %s\n", lang_hooks.decl_printable_name ( node->decl, 2));
+ if ( fn == NULL )
{
- tree decl;
- unsigned i;
-
- node->get_untransformed_body ();
+ //DEBUG( " EMPTY\n");
+ continue;
+ }
- struct function *fn = DECL_STRUCT_FUNCTION (node->decl);
+ //INDENT(2);
+ FOR_EACH_LOCAL_DECL ( fn, i, decl)
+ {
+ tree base = base_type_of ( decl);
// enable this to see error in test_1_8
- // DEBUG( "L# %d, function name = %s\n",
- //__LINE__, lang_hooks.decl_printable_name ( node->decl, 2));
- if (fn == NULL)
- {
- // DEBUG( " EMPTY\n");
+ //DEBUG_L( "Consider local var decl\n");
+ //DEBUG_F( print_generic_decl, stderr, decl, (dump_flags_t)-1);
+ //DEBUG( "\n");
+
+ if ( TREE_CODE ( base) == RECORD_TYPE)
+ {
+ if ( typeset.find ( base) != typeset.end () )
+ {
+ //INDENT(-2)
continue;
}
- FOR_EACH_LOCAL_DECL (fn, i, decl)
- {
- tree base = base_type_of (decl);
- // enable this to see error in test_1_8
- // DEBUG( "L# %d Consider local var decl\n", __LINE__);
- // DEBUG_F( print_generic_decl, stderr, decl, (dump_flags_t)-1);
- // DEBUG( "\n");
-
- if (TREE_CODE (base) == RECORD_TYPE)
- {
- if (typeset.find (base) != typeset.end ())
- {
- continue;
- }
-
- ReorgType_t rt
- = {0, base, 0, 0, 0, 0.0, 0.0, false, true, NULL, NULL};
- info->reorg_type->push_back (rt);
- typeset.insert (base); // ???
- }
- }
+ ReorgType_t rt =
+ { 0, base, 0, 0, 0, 0.0, 0.0, false, true, NULL, NULL };
+ add_reorg_type ( info, &rt);
+ typeset.insert ( base); // ???
+ }
}
-
+ //INDENT(-2)
+ }
+
// We need this later for creating new types
- for (std::set<tree>::iterator ti = typeset.begin (); ti != typeset.end ();
- ti++)
- {
- (*(info->struct_types))[*ti] = {false, false};
- }
+ for ( std::set<tree>::iterator ti = typeset.begin ();
+ ti != typeset.end ();
+ ti++ )
+ {
+ (*(info->struct_types))[*ti] = { false, false };
+ }
- if (info->show_all_reorg_cands_in_detail)
- {
- fprintf (dump_file, "All possible candidates:\n");
- print_reorgs (dump_file, 2, info);
- }
+ if ( info->show_all_reorg_cands_in_detail )
+ {
+ fprintf ( info->reorg_dump_file, "All possible candidates:\n");
+ print_reorgs ( info->reorg_dump_file, 2, info);
+ }
// Scan all declarations for pointers to ReorgTypes
// and in a later version array of them. When found
@@ -363,54 +418,70 @@ find_decls_and_types (Info_t *info)
// Note, there is no mechanism for looking at global declarations
// so use FOR_EACH_VARIABLE instead. I'm not 100% this is the thing
// actuall do here... but...
- FOR_EACH_VARIABLE (var)
+
+ //DEBUG_L( "Scan all global decls for pointers to ReorgTypes (possible deletes)\n");
+ //INDENT(2);
+
+ FOR_EACH_VARIABLE ( var)
+ {
+ tree decl = var->decl;
+
+ //DEBUG_A( "look at each global var for undelete: ");
+ //DEBUG_F( print_generic_decl, stderr, decl, (dump_flags_t)-1);
+ //DEBUG( "\n");
+
+ tree type = TREE_TYPE ( decl);
+ ReorgType_t *rtype = find_struct_type_ptr_to_struct ( type, info);
+ if ( rtype != NULL )
{
- tree decl = var->decl;
- ReorgType_t *rtype = find_struct_type_ptr_to_struct (decl, info);
- if (rtype != NULL)
- {
- undelete_reorgtype (rtype, info);
- }
+ undelete_reorgtype ( rtype, info);
}
+ }
+ //INDENT(-2);
- FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
+ FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node)
+ {
+ tree decl;
+ unsigned i;
+
+ // Only need to do this once in the program and it was done
+ // above!
+ //Node->get_untransformed_body ();
+
+ struct function *fn = DECL_STRUCT_FUNCTION ( node->decl);
+
+ //DEBUG_L( "fn %p\n", fn);
+ //DEBUG_A("");
+ //DEBUG_F( print_generic_decl, stderr, node->decl, (dump_flags_t)-1);
+ //DEBUG( "\n");
+ // I don't know why this is coming up null.... but I'll
+ // skip it for now.
+ if ( fn == NULL )
{
- tree decl;
- unsigned i;
-
- // Only need to do this once in the program and it was done
- // above!
- // Node->get_untransformed_body ();
-
- struct function *fn = DECL_STRUCT_FUNCTION (node->decl);
-
- // DEBUG( "fn %p\n", fn);
- // DEBUG_F( print_generic_decl, stderr, node->decl, (dump_flags_t)-1);
- // DEBUG( "\n");
- // I don't know why this is coming up null.... but I'll
- // skip it for now.
- if (fn == NULL)
- {
- continue;
- }
-
- FOR_EACH_LOCAL_DECL (fn, i, decl)
- {
- // Does this work... see tree.c:6132
- ReorgType_t *rtype = find_struct_type_ptr_to_struct (decl, info);
- if (rtype != NULL)
- {
- undelete_reorgtype (rtype, info);
- }
- }
+ continue;
}
- if (info->show_all_reorg_cands)
+ //DEBUG_L( "possible deletes:\n");
+ //INDENT(2);
+ FOR_EACH_LOCAL_DECL ( fn, i, decl)
{
- fprintf (dump_file, "All preliminary ReorgTypes:\n");
- // print_reorgs ( dump_file, 2, info);
+ // Does this work... see tree.c:6132
+ tree type = TREE_TYPE ( decl);
+ ReorgType_t *rtype = find_struct_type_ptr_to_struct ( type, info);
+ if ( rtype != NULL )
+ {
+ undelete_reorgtype ( rtype, info);
+ }
}
+ //INDENT(-2);
+ }
+ if ( info->show_all_reorg_cands )
+ {
+ fprintf ( info->reorg_dump_file, "All preliminary ReorgTypes:\n");
+ 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
@@ -424,267 +495,729 @@ find_decls_and_types (Info_t *info)
// that type. This of course assumes sane programming
// practices and if they violate those structure reorg has
// every right to punt.
- for (std::vector<ReorgType_t>::iterator ri = info->reorg_type->begin ();
- ri != info->reorg_type->end (); ri++)
+ //DEBUG_L( "Examine imbedded pointers\n");
+ //INDENT(2);
+ for ( std::vector<ReorgType_t>::iterator ri = info->reorg_type->begin ();
+ ri != info->reorg_type->end ();
+ ri++ )
+ {
+ //DEBUG_A("");
+ //DEBUG_F( dump_reorg, &(*ri));
+ //DEBUG("\n");
+ //INDENT(2);
+ for ( tree fld = TYPE_FIELDS ( ri->gcc_type);
+ fld;
+ fld = DECL_CHAIN ( fld) )
{
- for (tree fld = TYPE_FIELDS (ri->gcc_type); fld; fld = DECL_CHAIN (fld))
- {
- ReorgType_t *rtype = find_struct_type_ptr_to_struct (fld, info);
- if (rtype != NULL)
- {
- undelete_reorgtype (rtype, info);
- }
- }
+ tree field_type = TREE_TYPE( fld);
+ ReorgType_t *rtype =
+ find_struct_type_ptr_to_struct ( field_type, info);
+ if ( rtype != NULL )
+ {
+ undelete_reorgtype ( rtype, info);
+ }
}
+ //INDENT(-2);
+ }
+ //INDENT(-2);
- remove_deleted_types (info, &initial_reorg_debug);
+ remove_deleted_types ( info, &initial_reorg_debug);
// Disqualifying structures in interior to structures is optional
- // (see comment at end of type escape section) but if it's not
+ // (see comment at end of type escape section) but if it's not
// done it commits the optimization to do something a little too
// involved for the initial version.
- disqualify_struct_in_struct_or_union (info);
-
- if (info->reorg_type->empty ())
+ disqualify_struct_in_struct_or_union ( info);
+
+ if ( info->reorg_type->empty () )
+ {
+ if ( info->show_all_reorg_cands_in_detail )
{
- if (info->show_all_reorg_cands_in_detail)
- {
- fprintf (dump_file, "find_decls_and_types: Found no types\n");
- }
- return false;
+ fprintf ( info->reorg_dump_file, "find_decls_and_types: Found no types\n");
}
+ return false;
+ }
// initialize ids of ReorgTypes
int id = 0;
- for (std::vector<ReorgType_t>::iterator ri = info->reorg_type->begin ();
- ri != info->reorg_type->end (); ri++)
- {
- ri->id = id;
- id++;
- }
+ for ( std::vector<ReorgType_t>::iterator ri = info->reorg_type->begin ();
+ ri != info->reorg_type->end ();
+ ri++ )
+ {
+ ri->id = id;
+ id++;
+ }
// Scan all declarations. If their type is in ReorgTypes
// add them to ProgDecl.
// Note, there is no mechanism for looking at global declarations
// so use FOR_EACH_VARIABLE instead. I'm not 100% this is the thing
// actuall do here... but...
- FOR_EACH_VARIABLE (var)
+ //DEBUG_L( "ProgDecl global declarations:\n");
+ FOR_EACH_VARIABLE ( var)
+ {
+ tree decl = var->decl;
+ tree type = base_type_of ( decl);
+ if ( TREE_CODE ( type ) == RECORD_TYPE &&
+ get_reorgtype_info ( type, info) != NULL )
{
- tree decl = var->decl;
- tree type = base_type_of (decl);
- if (TREE_CODE (type) == RECORD_TYPE
- && get_reorgtype_info (type, info) != NULL)
- {
- ProgDecl_t decl_info;
- decl_info.gcc_decl = decl;
- info->prog_decl->push_back (decl_info);
- }
+ ProgDecl_t decl_info;
+ decl_info.gcc_decl = decl;
+ info->prog_decl->push_back ( decl_info);
+ //DEBUG_A("");
+ //DEBUG_F( print_progdecl, stderr, 2, &decl_info);
}
-
- FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
+ }
+
+ //DEBUG_L( "ProgDecl per function:\n");
+ //INDENT(2);
+ FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node)
+ {
+ //DEBUG_L( "function: %s\n", lang_hooks.decl_printable_name ( node->decl, 2));
+ //INDENT(2);
+ // local declarations
+ unsigned i;
+ tree decl;
+ struct function *fn = DECL_STRUCT_FUNCTION ( node->decl);
+ //DEBUG_L( "ProgDecl local declarations:\n");
+ FOR_EACH_LOCAL_DECL ( fn, i, decl)
{
- // local declarations
- unsigned i;
- tree decl;
- struct function *fn = DECL_STRUCT_FUNCTION (node->decl);
- FOR_EACH_LOCAL_DECL (fn, i, decl)
- {
- tree type = base_type_of (decl);
- if (TREE_CODE (type) == RECORD_TYPE
- && get_reorgtype_info (type, info) != NULL)
- {
- ProgDecl_t decl_info;
- decl_info.gcc_decl = decl;
- info->prog_decl->push_back (decl_info);
- }
- }
-
- // parameter declarations
- tree parm;
- for (parm = DECL_ARGUMENTS (fn->decl); parm; parm = DECL_CHAIN (parm))
- {
- tree decl = TREE_TYPE (parm);
- tree type = base_type_of (decl);
- if (TREE_CODE (type) == RECORD_TYPE
- && get_reorgtype_info (type, info) != NULL)
- {
- ProgDecl_t decl_info;
- decl_info.gcc_decl = decl;
- info->prog_decl->push_back (decl_info);
- }
- }
+ tree type = base_type_of ( decl);
+ if ( TREE_CODE ( type ) == RECORD_TYPE &&
+ get_reorgtype_info ( type, info) != NULL ) {
+ ProgDecl_t decl_info;
+ decl_info.gcc_decl = decl;
+ info->prog_decl->push_back ( decl_info);
+ //DEBUG_A("");
+ //DEBUG_F( print_progdecl, stderr, 2, &decl_info);
+ }
}
-
- if (info->show_all_reorg_cands_in_detail)
+
+ // parameter declarations
+ //DEBUG_L( "ProgDecl parameter declarations:\n");
+ tree parm;
+ for ( parm = DECL_ARGUMENTS ( fn->decl);
+ parm;
+ parm = DECL_CHAIN ( parm) )
{
- fprintf (dump_file, "find_decls_and_types: Found the following types:\n");
- print_reorgs (dump_file, 2, info);
+ //tree decl = TREE_TYPE ( parm);
+ tree decl = parm;
+ tree type = base_type_of ( decl);
+ ProgDecl_t decl_info;
+ decl_info.gcc_decl = decl;
+ //DEBUG_A("");
+ //DEBUG_F( print_progdecl, stderr, 2, &decl_info);
+ //DEBUG_A("TREE_CODE(type) == %s\n", code_str( TREE_CODE( type)));
+ if ( TREE_CODE ( type ) == RECORD_TYPE &&
+ get_reorgtype_info ( type, info) != NULL )
+ {
+ info->prog_decl->push_back ( decl_info);
+ //DEBUG_A(" -- Added to ProgDecls\n");
+ }
}
+ //INDENT(-2);
+ }
+ //INDENT(-2);
+
+ if ( info->show_all_reorg_cands_in_detail )
+ {
+ fprintf ( info->reorg_dump_file, "find_decls_and_types: Found the following types:\n");
+ print_reorgs ( info->reorg_dump_file, 2, info);
+ }
+
+ if ( info->show_prog_decls )
+ {
+ fprintf ( info->reorg_dump_file, "ProgDecls:\n");
+ print_progdecls ( info->reorg_dump_file, 2, info);
+ }
return true;
}
+static void
+add_reorg_type ( Info *info, ReorgType_t *rt)
+{
+ info->reorg_type->push_back ( *rt);
+ // Remember the intial assumption is the type added will be deleted
+ // and is marked to be deleted.
+ info->num_deleted++;
+}
+
void
-disqualify_struct_in_struct_or_union (Info_t *info)
+disqualify_struct_in_struct_or_union ( Info_t *info)
{
varpool_node *var;
std::set<tree> typeset;
- FOR_EACH_VARIABLE (var)
+
+ //DEBUG_L( "In disqualify_struct_in_struct_or_union\n");
+ //INDENT(2);
+
+ FOR_EACH_VARIABLE ( var)
+ {
+ tree decl = var->decl;
+
+ //DEBUG( "type %s\n", TYPE_NAME( TREE_TYPE( decl)));
+
+ tree base = base_type_of ( decl);
+ if ( TREE_CODE ( base) == RECORD_TYPE
+ || TREE_CODE ( base) == UNION_TYPE )
{
- tree decl = var->decl;
- tree base = base_type_of (decl);
- if (TREE_CODE (base) == RECORD_TYPE || TREE_CODE (base) == UNION_TYPE)
- {
- disq_str_in_str_or_union_helper (base, &typeset, info);
- typeset.insert (base);
- }
+ disq_str_in_str_or_union_helper ( base, &typeset, info);
+ typeset.insert ( base);
+ }
+ }
+ //INDENT(-2);
+
+ // Repeating the above for local variables
+ cgraph_node* node;
+ FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node)
+ {
+ tree decl;
+ unsigned i;
+
+ node->get_untransformed_body ();
+
+ struct function *fn = DECL_STRUCT_FUNCTION ( node->decl);
+ //DEBUG_L( "function name = %s\n",
+ // lang_hooks.decl_printable_name ( node->decl, 2));
+ if ( fn == NULL )
+ {
+ continue;
}
- remove_deleted_types (info, &disqualify_struct_in_struct_or_union_debug);
+ //INDENT(2);
+ FOR_EACH_LOCAL_DECL ( fn, i, decl)
+ {
+ tree base = base_type_of ( decl);
+
+ //DEBUG_L( "local var decl: ");
+ //DEBUG_F( print_generic_decl, stderr, decl, (dump_flags_t)-1);
+ //DEBUG( "TREE_CODE( base) = %s\n", code_str( TREE_CODE ( base)));
+
+ if ( TREE_CODE ( base) == RECORD_TYPE
+ || TREE_CODE ( base) == UNION_TYPE )
+ {
+ disq_str_in_str_or_union_helper ( base, &typeset, info);
+ typeset.insert ( base);
+ }
+ }
+ //INDENT(-2);
+ }
+
+ remove_deleted_types ( info,
+ &disqualify_struct_in_struct_or_union_debug);
}
static void
-initial_reorg_debug (Info *info, ReorgType *reorg)
+initial_reorg_debug ( Info *info, ReorgType *reorg )
{
- if (info->show_delete)
- {
- print_reorg_with_msg (dump_file, reorg, 2, "No Pointer to Structure");
- }
+ if ( info->show_delete )
+ {
+ print_reorg_with_msg ( info->reorg_dump_file, reorg, 2,
+ "No Pointer to Structure");
+ }
}
+
+static void
+disqualify_struct_in_struct_or_union_debug ( Info *info,
+ ReorgType *reorg )
+{
+ if ( info->show_delete )
+ {
+ print_reorg_with_msg ( info->reorg_dump_file, reorg, 2,
+ "Interior Struct or Union");
+ }
+}
+
static void
-disqualify_struct_in_struct_or_union_debug (Info *info, ReorgType *reorg)
+disq_str_in_str_or_union_helper ( tree type,
+ std::set<tree> *typeset,
+ Info_t *info )
{
- if (info->show_delete)
+ //DEBUG_L( "In disq_str_in_str_or_union_helper (possibele deletes)\n");
+ //INDENT(2);
+
+ if ( typeset->find ( type) != typeset->end ()) return;
+ tree fld;
+ for ( tree fld = TYPE_FIELDS( type); fld; fld = DECL_CHAIN ( fld) )
+ {
+ //DEBUG_A( ": ", DECL_NAME( fld));
+ //DEBUG_F( print_generic_decl, stderr, fld, (dump_flags_t)-1);
+ //DEBUG( " -- ");
+ //INDENT(2);
+
+ // If we go to the base we end up disqualifying pointer to reorganizable
+ // structure. That's not what we want!
+ tree field_type = TREE_TYPE( fld);
+ //tree base = base_type_of ( field_type);
+ if ( TREE_CODE ( field_type) == RECORD_TYPE ) // base to field type
{
- print_reorg_with_msg (dump_file, reorg, 2, "Interior Struct or Union");
+ //DEBUG( "RECORD\n");
+
+ ReorgType_t *rinfo = get_reorgtype_info ( field_type, info); // base to field type
+ if ( rinfo != NULL )
+ {
+ delete_reorgtype ( rinfo, info);
+ } else {
+ disq_str_in_str_or_union_helper ( field_type, typeset, info ); // base to field type
+ typeset->insert ( field_type); // might be bug here -- base to field type
+ }
+ } else {
+ if ( TREE_CODE ( field_type) == UNION_TYPE ) { // base to field type
+ //DEBUG( "UNION\n");
+
+ disq_str_in_str_or_union_helper ( field_type, typeset, info ); // base to field type
+ typeset->insert ( field_type); // might be bug here -- base to field type
+ } else {
+ //DEBUG( "%s\n", code_str( TREE_CODE ( field_type)) ); // base to field type
+ }
}
+ //INDENT(-2);
+ }
+ //INDENT(-2);
+
+ return;
+}
+
+static unsigned int
+reorg_qualification ( Info_t *info)
+{
+ // TBD
+ // This only does a generic legality qualification and each
+ // subpass does its own performance qualification.
+ return reorg_legality( info);
+
}
-static void
-disq_str_in_str_or_union_helper (tree type, std::set<tree> *typeset,
- Info_t *info)
+// Return false if nothing qualified
+bool
+reorg_legality( Info_t *info) {
+ // NOTE, the following line does nothing unless
+ // we actually do our own points-to analysis
+ if( !points_to_escape_analysis( info) ) return false;
+
+ return transformation_legality( info);
+}
+
+// Return false if nothing qualified
+bool
+transformation_legality ( Info_t *info)
{
- if (typeset->find (type) != typeset->end ())
- return;
- tree fld;
- for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
+ cgraph_node* node;
+
+ FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node)
+ {
+ struct function *func = DECL_STRUCT_FUNCTION ( node->decl);
+ basic_block bb;
+
+ FOR_EACH_BB_FN ( bb, func)
{
- if (TREE_CODE (fld) == RECORD_TYPE)
+ gimple_stmt_iterator gsi;
+ for ( gsi = gsi_start_bb ( bb);
+ !gsi_end_p ( gsi);
+ gsi_next ( &gsi) )
+ {
+ gimple *stmt = gsi_stmt ( gsi);
+ int num = num_reorgtypes ( stmt, info);
+ if ( num != 0 )
{
- ReorgType_t *rinfo = get_reorgtype_info (fld, info);
- if (rinfo != NULL)
- {
- delete_reorgtype (rinfo, info);
- }
- else
+ if ( reorg_recognize( stmt, info) == Not_Supported )
+ {
+ int i;
+ for ( i = 0; i < num; i++ )
{
- disq_str_in_str_or_union_helper (fld, typeset, info);
- typeset->insert (fld); // might be bug here
+ ReorgType_t *reorg_type =
+ get_reorgtype( stmt, info, i);
+ delete_reorgtype( reorg_type, info);
}
+ }
}
- else
+ if ( uses_field_of_reorgtypes( stmt, info) )
{
- if (TREE_CODE (fld) == UNION_TYPE)
- {
- disq_str_in_str_or_union_helper (fld, typeset, info);
- typeset->insert (fld); // might be bug here
- }
+ // This will mark types to be deleted if need be.
+ reorg_forbidden ( stmt, info );
}
+ }
}
- return;
+ }
+
+ remove_deleted_types ( info, &transformation_legality_debug);
+
+ return !info->reorg_type->empty ();
}
-static unsigned int
-reorg_qualification (Info_t *info)
+void
+transformation_legality_debug ( Info *info, ReorgType *reorg )
{
- // TBD
- // This only does a generic legality qualification and each
- // subpass does its own performance qualification.
+ if ( info->show_delete )
+ {
+ print_reorg_with_msg ( info->reorg_dump_file, reorg, 2,
+ "Unallowed transformation");
+ }
}
void
-delete_reorgtype (ReorgType_t *rt, Info_t *info)
+delete_reorgtype ( ReorgType_t *rt, Info_t *info )
{
- if (!rt->delete_me)
- {
- info->num_deleted++;
- rt->delete_me = true;
- }
+ //DEBUG_L( "delete_reorgtype( %s ):", type_name_to_str( TYPE_NAME( rt->gcc_type)));
+ if ( !rt->delete_me )
+ {
+ //DEBUG( "TO DELETE\n");
+ info->num_deleted++;
+ rt->delete_me = true;
+ } else {
+ //DEBUG( "SKIP\n");
+ }
}
void
-undelete_reorgtype (ReorgType_t *rt, Info_t *info)
+undelete_reorgtype ( ReorgType_t *rt, Info_t *info )
{
- if (rt->delete_me)
+ //DEBUG_L( "undelete_reorgtype( %s ): ", type_name_to_str( TYPE_NAME( rt->gcc_type)));
+ if ( rt->delete_me )
+ {
+ //DEBUG( "UNDELETE\n");
+ info->num_deleted--;
+ rt->delete_me = false;
+ } else {
+ //DEBUG( "SKIP\n");
+ }
+}
+
+ReorgTransformation
+reorg_recognize ( gimple *stmt, Info_t *info )
+{
+ switch ( gimple_code( stmt) )
+ {
+ case GIMPLE_ASSIGN:
+ {
+ tree lhs = gimple_assign_lhs ( stmt);
+ enum tree_code rhs_code = gimple_assign_rhs_code ( stmt);
+
+ if ( gimple_assign_single_p ( stmt) )
+ {
+ tree rhs = gimple_assign_rhs1 ( stmt);
+ switch ( recognize_op ( lhs, info) )
+ {
+ case ReorgT_Pointer: // "a"
+ switch ( recognize_op ( rhs, info) )
+ {
+ case ReorgT_Scalar:
+ if ( integer_zerop ( rhs) )
+ {
+ return ReorgT_Ptr2Zero;
+ }
+ case ReorgT_Address: // "&x[i]"
+ return ReorgT_Adr2Ptr;
+ default:
+ return Not_Supported;
+ }
+ case ReorgT_Struct: // "s"
+ switch ( recognize_op ( rhs, info) )
+ {
+ case ReorgT_Deref: // "*a"
+ case ReorgT_Array: // "x[i]"
+ return ReorgT_StrAssign;
+ default:
+ return Not_Supported;
+ }
+ case ReorgT_Deref: // "*a"
+ switch ( recognize_op ( rhs, info) )
+ {
+ case ReorgT_Deref: // "*a"
+ case ReorgT_Struct: // "s"
+ case ReorgT_Array: // "x[i]"
+ return ReorgT_StrAssign;
+ default:
+ return Not_Supported;
+ }
+ case ReorgT_Array: // "x[i]"
+ switch ( recognize_op ( rhs, info) )
+ {
+ case ReorgT_Struct: // "s"
+ case ReorgT_Deref: // "*a"
+ case ReorgT_Array: // "x[i]"
+ return ReorgT_StrAssign;
+ default:
+ return Not_Supported;
+ }
+ case ReorgT_Scalar: // "z"
+ switch ( recognize_op( rhs, info) )
+ {
+ case ReorgT_Indirect: // "a->f"
+ case ReorgT_AryDir: // "x[i].f"
+ return ReorgT_ElemAssign;
+ default:
+ return Not_Supported;
+ }
+ case ReorgT_Indirect: // "a->f"
+ case ReorgT_AryDir: // "x[i].f"
+ switch ( recognize_op ( rhs, info) )
+ {
+ case ReorgT_Scalar: // "z"
+ case ReorgT_Indirect: // "a->f"
+ case ReorgT_AryDir: // "x[i].f"
+ return ReorgT_ElemAssign;
+ default:
+ return Not_Supported;
+ }
+ default:
+ return Not_Supported;
+ } // switch ( recognize_op ( lhs, info) )
+ } else {
+ tree op1 = gimple_assign_rhs1 ( stmt);
+ tree op2 = gimple_assign_rhs2 ( stmt);
+
+ if ( gimple_assign_rhs3 ( stmt) != NULL )
+ {
+ return Not_Supported;
+ }
+
+ // TBD The parenthesis where a disaster here in the HL Design so
+ // double check this!
+ bool zero_case =
+ ( (POINTER_TYPE_P ( TREE_TYPE( op1)) && integer_zerop ( op2))
+ || (POINTER_TYPE_P ( TREE_TYPE( op2)) && integer_zerop ( op1)))
+ && ( integer_zerop ( op1) || integer_zerop ( op2) );
+ switch ( rhs_code )
+ {
+ case POINTER_PLUS_EXPR:
+ return ReorgT_PtrPlusInt;
+ case POINTER_DIFF_EXPR:
+ return ReorgT_PtrDiff;
+ case EQ_EXPR:
+ return zero_case ? ReorgT_PtrNull : ReorgT_PtrEQ;
+ case NE_EXPR:
+ return zero_case ? ReorgT_PtrNotNull : ReorgT_PtrNE;
+ case LE_EXPR:
+ return ReorgT_PtrLE;
+ case LT_EXPR:
+ return ReorgT_PtrLT;
+ case GE_EXPR:
+ return ReorgT_PtrGE;
+ case GT_EXPR:
+ return ReorgT_PtrGT;
+ default:
+ return Not_Supported;
+ }
+ } // } else {
+ }
+ case GIMPLE_COND: // Similar to assign cases
{
- info->num_deleted--;
- rt->delete_me = false;
+ tree op1 = gimple_assign_rhs1 ( stmt);
+ tree op2 = gimple_assign_rhs2( stmt);
+ enum tree_code cond_code = gimple_cond_code (stmt);
+ // TBD The parenthesis where a disaster here in the HL Design so
+ // double check this!
+ bool zero_case =
+ ( POINTER_TYPE_P ( TREE_TYPE ( op1)) && integer_zerop ( op2))
+ || ( POINTER_TYPE_P ( TREE_TYPE ( op2)) && integer_zerop ( op1));
+ switch ( cond_code )
+ {
+ case EQ_EXPR:
+ return zero_case ? ReorgT_If_Null : ReorgT_IfPtrEQ;
+ case NE_EXPR:
+ return zero_case ? ReorgT_If_NotNull : ReorgT_IfPtrNE;
+ case LE_EXPR:
+ return ReorgT_IfPtrLE;
+ case LT_EXPR:
+ return ReorgT_IfPtrLT;
+ case GE_EXPR:
+ return ReorgT_IfPtrGE;
+ case GT_EXPR:
+ return ReorgT_IfPtrGT;
+ default:
+ return Not_Supported;
+ }
}
+ case GIMPLE_CALL:
+ 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;
+ if ( gimple_call_builtin_p( stmt, BUILT_IN_FREE ) ) return ReorgT_Free;
+ return Not_Supported;
+ default:
+ return Not_Supported;
+ }
}
void
-clear_deleted_types (Info *info)
+clear_deleted_types( Info *info)
{
info->saved_reorg_type->clear ();
}
void
-restore_deleted_types (Info *info)
+restore_deleted_types ( Info *info)
{
- while (!info->saved_reorg_type->empty ())
- {
- info->reorg_type->push_back (info->saved_reorg_type->back ());
- info->saved_reorg_type->pop_back ();
- }
+ while ( !info->saved_reorg_type->empty () )
+ {
+ info->reorg_type->push_back ( info->saved_reorg_type->back () );
+ info->saved_reorg_type->pop_back ();
+ }
}
+// This routine disqualifies any and all reorg
+// types in it that deserve disqualification.
+// There are bizarre circumstances that could disqualify
+// many types in a single statement.
void
-remove_deleted_types (Info *info, ReorgFn reorg_fn)
+reorg_forbidden ( gimple *stmt, Info *info )
{
- if (info->show_delete)
- {
- fprintf (dump_file, "DELETING REORG TYPES:\n");
- }
+ // The recognition of forbidden patterns must include casting a
+ // pointer (i.e. a pointer into a Reorg field) to something of a
+ // larger size (e.g. ints to longs) or doing arithmetic with them
+ // (e.g. bar->foo + k) since the later assumes the structure
+ // layout has not changed.
+#if 0
+ // TBD
+ switch( gimple_code( stmt) ) {
+ case :
+ }
+#endif
+}
- if (info->num_deleted > 0)
+void
+remove_deleted_types ( Info *info, ReorgFn reorg_fn)
+{
+ //DEBUG_L( "remove_deleted_types: %d to delete of %d types\n", info->num_deleted, info->reorg_type->size ());
+ if ( info->show_delete )
+ {
+ fprintf ( info->reorg_dump_file, "DELETING REORG TYPES:\n");
+ }
+
+ if ( info->num_deleted > 0 )
+ {
+ // Do delete here and run reorg_fn on each
+ // deleted type
+ int n = info->reorg_type->size ();
+ int to = 0;
+ //INDENT(2);
+ for ( int from = 0; from < n; from++ )
{
- // Do delete here and run reorg_fn on each
- // deleted type
- int n = info->reorg_type->size ();
- int to = 0;
- for (int from = 0; from < n; from++)
+ //DEBUG_L( "%s ", type_name_to_str( TYPE_NAME( (*(info->reorg_type))[from].gcc_type)));
+ //DEBUG( "< from %d, to %d > - ", from, to);
+
+ if ( !(*(info->reorg_type))[from].delete_me )
+ {
+ //DEBUG( "NOT DELETED %d\n", from);
+
+ // Save copy of removed entry
+ (*(info->reorg_type))[from].delete_me = false;
+ info->saved_reorg_type->push_back ( (*(info->reorg_type))[from]);
+
+ // Delete by not copying deleted elements
+ if ( from != to )
{
- if (!(*(info->reorg_type))[from].delete_me)
- {
- // Save copy of removed entry
- (*(info->reorg_type))[from].delete_me = false;
- info->saved_reorg_type->push_back ((*(info->reorg_type))[from]);
-
- // Delete by not copying deleted elements
- if (from != to)
- {
- if (reorg_fn != NULL)
- {
- (*reorg_fn) (info, &(*(info->reorg_type))[from]);
- }
- (*(info->reorg_type))[to] = (*(info->reorg_type))[from];
- }
- to++;
- }
+ if ( reorg_fn != NULL )
+ {
+ (*reorg_fn)( info, &(*(info->reorg_type))[ from]);
+ }
+ (*(info->reorg_type))[ to] = (*(info->reorg_type))[ from];
+ //DEBUG_A( " move from -> to\n");
}
- info->reorg_type->resize (n - info->num_deleted);
- info->num_deleted = 0;
+
+ to++;
+ } else {
+ //DEBUG( "DELETE %d\n", from);
+ }
+ }
+ //INDENT(-2);
+ info->reorg_type->resize ( n - info->num_deleted);
+ info->num_deleted = 0;
+ }
+}
+
+enum ReorgOpTrans
+recognize_op ( tree op, Info *info)
+{
+ enum tree_code op_code = TREE_CODE ( op);
+ tree type = TREE_TYPE ( op);
+ if ( POINTER_TYPE_P (type) )
+ {
+ if ( is_reorg_type ( type, info) )
+ {
+ return ReorgT_Pointer;
+ } else {
+ // This would be for when
+ // the field of a struct element
+ // is a pointer that's not a reorg
+ // point. I.e. ReorgT_ElemAssign.
+ return ReorgT_Scalar;
+ }
+ }
+ if ( op_code == RECORD_TYPE )
+ {
+ // The assumption here is that this
+ // is a reorg type.
+ return ReorgT_Struct;
+ }
+ tree inter_op = TREE_OPERAND( op, 0);
+ if ( op_code == ADDR_EXPR
+ && TREE_CODE ( inter_op) == ARRAY_REF
+ && is_reorg_type ( inter_op, info) )
+ {
+ return ReorgT_Address;
+ }
+ if ( op_code == COMPONENT_REF )
+ {
+ if ( TREE_CODE( inter_op) == INDIRECT_REF )
+ {
+ if ( is_reorg_type ( base_type_of ( type), info) )
+ {
+ return ReorgT_Indirect;
+ }
+ // Just normal field reference otherwise...
+ return ReorgT_Scalar;
+ } else {
+ // Note, doesn't this ignore ARRAY_REF of this?
+ // I think it's OK at least until we start supporting
+ // multi-pools.
+ if ( is_reorg_type ( base_type_of ( type), info) )
+ {
+ return ReorgT_AryDir;
+ }
+ // Just normal field reference otherwise...
+ return ReorgT_Scalar;
+ }
+ }
+ if ( op_code == ARRAY_REF )
+ {
+ if ( is_reorg_type( base_type_of ( type), info) )
+ {
+ return ReorgT_Array;
}
+ return ReorgT_Scalar;
+ }
+ if( op_code == INDIRECT_REF )
+ {
+ // Do we want to chase the base type?
+ // No, we care about (and transform) just
+ // *r and not **...r (where r is a ReorgType.)
+ if( is_reorg_type ( type, info) )
+ {
+ return ReorgT_Deref;
+ }
+ return ReorgT_Scalar;
+ }
+ return ReorgT_Scalar;
+}
+
+bool
+is_reorg_type( tree rt, Info_t *info )
+{
+ return get_reorgtype_info ( rt, info) != NULL;
}
static tree
-base_type_of (tree type)
+base_type_of ( tree type)
{
- for (; POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE
- || TREE_CODE (type) == VAR_DECL;
- type = TREE_TYPE (type))
- ;
+ for ( ; POINTER_TYPE_P ( type) ||
+ TREE_CODE ( type) == ARRAY_TYPE ||
+ TREE_CODE ( type) == VAR_DECL ||
+ TREE_CODE ( type) == PARM_DECL
+ ; type = TREE_TYPE ( type) );
return type;
}
@@ -694,26 +1227,30 @@ base_type_of (tree type)
// Also, we do handle realloc but it doesn't
// create a new pool of memory so we ignore it here.
static bool
-is_reorg_alloc_trigger (gimple *stmt)
+is_reorg_alloc_trigger ( gimple *stmt)
{
- return gimple_call_builtin_p (stmt, BUILT_IN_MALLOC)
- || gimple_call_builtin_p (stmt, BUILT_IN_CALLOC);
+ return gimple_call_builtin_p ( stmt, BUILT_IN_MALLOC)
+ || gimple_call_builtin_p ( stmt, BUILT_IN_CALLOC);
}
-static ReorgType_t *
-find_struct_type_ptr_to_struct (tree type, Info *info)
+static ReorgType_t *
+find_struct_type_ptr_to_struct ( tree type, Info *info)
{
- if (!POINTER_TYPE_P (type))
- {
- return NULL;
- }
- for (; POINTER_TYPE_P (type); type = TREE_TYPE (type))
- ;
-
- if (TREE_CODE (type) == RECORD_TYPE)
- {
- return get_reorgtype_info (type, info);
- }
+ //DEBUG_L( "find_struct_type_ptr_to_struct: ");
+ if ( !POINTER_TYPE_P ( type) ) {
+ //DEBUG(" bail\n");
+
+ return NULL;
+ }
+ for ( ; POINTER_TYPE_P ( type); type = TREE_TYPE ( type) );
+
+ if ( TREE_CODE ( type) == RECORD_TYPE ) {
+ //DEBUG( " look for info\n");
+
+ return get_reorgtype_info ( type, info);
+ }
+ //DEBUG(" fell through\n");
+
return NULL;
}
@@ -721,159 +1258,297 @@ find_struct_type_ptr_to_struct (tree type, Info *info)
// 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");
- gcc_assert (TREE_CODE (a) == RECORD_TYPE && TYPE_NAME (a) != 0);
- gcc_assert (TREE_CODE (b) == RECORD_TYPE && TYPE_NAME (b) != 0);
- return TYPE_NAME (a) == TYPE_NAME (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");
+
+ gcc_assert ( TREE_CODE ( a ) == RECORD_TYPE && TYPE_NAME ( a) != 0);
+ gcc_assert ( TREE_CODE ( b ) == RECORD_TYPE && TYPE_NAME ( b) != 0);
+
+ bool ret = TYPE_NAME ( a) == TYPE_NAME ( b);
+
+ //DEBUG( "returns %s\n", ret ? "true" : "false");
+
+ return ret;
}
// May need to add secondary map container to
// look them up or even modify the container
// type of ReorgType
static ReorgType_t *
-get_reorgtype_info (tree type, Info_t *info)
+get_reorgtype_info ( tree type, Info_t* info)
{
+ //DEBUG_L( "get_reorgtype_info\n");
+
// 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
// certainly correct. It will also almost certainly need to be
// improved but I get something out there now.
- for (std::vector<ReorgType_t>::iterator ri = info->reorg_type->begin ();
- ri != info->reorg_type->end (); ri++)
+ for ( std::vector<ReorgType_t>::iterator ri = info->reorg_type->begin ();
+ ri != info->reorg_type->end ();
+ ri++ )
+ {
+ // TBD the internal docs lie and same_type_p doesn't exist
+ // (at least it's not available here at LTO time)
+ // 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.
+ if ( same_type_p ( ri->gcc_type, type) )
{
- // TBD the internal docs lie and same_type_p doesn't exist
- // (at least it's not available here at LTO time)
- // 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.
- if (same_type_p (ri->gcc_type, type))
- {
- return &(*ri);
- }
+ //DEBUG_A( " returns %p\n", &(*ri));
+
+ return &(*ri);
}
+ }
return NULL;
}
static void
-print_reorg_with_msg (FILE *file, ReorgType_t *reorg, int leading_space,
- const char *msg)
+print_reorg_with_msg ( FILE *file,
+ ReorgType_t *reorg,
+ int leading_space,
+ const char *msg )
{
- fprintf (file, "%*s%s:\n", leading_space, "", msg);
- print_reorg (file, leading_space + 2, reorg);
+ fprintf ( file, "%*s%s:\n", leading_space, "", msg);
+ print_reorg ( file, leading_space + 2, reorg);
}
static void
-dump_reorg (ReorgType_t *reorg)
+dump_reorg ( ReorgType_t *reorg)
{
- print_reorg (stderr, 0, reorg);
+ print_reorg ( stderr, 0, reorg);
}
static void
-print_reorgs (FILE *file, int leading_space, Info *info)
+print_reorgs ( FILE *file, int leading_space, Info *info)
{
- for (int i = 0; i < info->reorg_type->size (); i++)
- {
- print_reorg (file, leading_space, &(*(info->reorg_type))[i]);
- }
+ for ( int i = 0; i < info->reorg_type->size (); i++ ) {
+ print_reorg ( file, leading_space, &(*(info->reorg_type))[i]);
+ }
}
static void
-print_reorg (FILE *file, int leading_space, ReorgType_t *reorg)
+print_reorg ( FILE *file, int leading_space, ReorgType_t *reorg )
{
// TBD
// note if reorg_perf & regular_perf are nonzero
// synthesize and display absolute_effect & raw_effect
-
+
// Note, the following is a stub.
const char *text
- = identifier_to_locale (IDENTIFIER_POINTER (TYPE_NAME (reorg->gcc_type)));
- fprintf (file, "%*s{ type:%s, id:%d, ... }\n", leading_space, "", text,
- reorg->id);
+ = identifier_to_locale ( IDENTIFIER_POINTER ( TYPE_NAME ( reorg->gcc_type)));
+ fprintf ( file, "%*s{ type:%s, id:%d, %s, ... }\n",
+ leading_space, "",
+ text,
+ reorg->id,
+ reorg->multi_pool ? "multi" : "single" );
+}
+
+static void
+print_progdecls ( FILE *file, int leading_space, Info * info)
+{
+ for ( int i = 0; i < info->prog_decl->size (); i++ ) {
+ print_progdecl ( file, leading_space, &(*(info->prog_decl))[i]);
+ }
+}
+
+static void
+print_progdecl ( FILE *file, int leading_space, ProgDecl_t *progdecl )
+{
+ //INDENT(leading_space);
+ //DEBUG_L( "print_progdecl check TREE_CODE = %s\n", code_str( TREE_CODE( progdecl->gcc_decl)));
+ //INDENT(-leading_space);
+ //DEBUG_A("");
+ fprintf ( file, "%*s", leading_space, "");
+ print_generic_decl ( file, progdecl->gcc_decl, (dump_flags_t)-1);
+ fprintf ( file, "\n");
+}
+
+static void
+print_program ( FILE *file, int leading_space )
+{
+ struct cgraph_node *node;
+ fprintf ( file, "%*sProgram:\n", leading_space, "");
+ FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node)
+ {
+ struct function *func = DECL_STRUCT_FUNCTION ( node->decl);
+ // print func name
+ fprintf ( file, "%*sFunc: %s\n", leading_space + 2, "", lang_hooks.decl_printable_name ( node->decl, 2));
+ print_function ( file, leading_space + 4, func);
+ }
+}
+
+static void
+print_function ( FILE *file, int leading_space, struct function *func)
+{
+ basic_block bb;
+
+ FOR_EACH_BB_FN ( bb, func)
+ {
+ // print bb num
+ fprintf ( file, "%*sBB %d:\n", leading_space, "", bb->index );
+
+ // Tried to use function gimple_dump_bb is here instead of
+ // the following loop but it's worthless.
+
+ gimple_stmt_iterator gsi;
+ for ( gsi = gsi_start_bb ( bb);
+ !gsi_end_p ( gsi);
+ gsi_next ( &gsi) )
+ {
+ gimple *stmt = gsi_stmt ( gsi);
+ fprintf ( file, "%*s", leading_space + 2, "" );
+ // Issue: for "if" this does not print the gotos.
+ print_gimple_stmt ( file, stmt, 0, (dump_flags_t)0);
+ }
+ }
+}
+
+ReorgType_t *
+get_reorgtype( gimple *stmt, Info_t *info, int i)
+{
+ // TBD - Straight forward
+ NULL;
+}
+
+int
+num_reorgtypes( gimple *stmt, Info_t *info)
+{
+ // TBD - Straight forward
+ 0;
+}
+
+// Does there really need to be here?
+// I suspect not. Perhaps if needed
+// to run our own points-to analysis
+// routine.... it would be invoked here.
+// So, just to maintain a point to do this
+// from, return true.
+// Return false if nothing qualified
+bool
+points_to_escape_analysis( Info_t *info)
+{
+ // TBD
+ return true;
+}
+
+bool
+uses_field_of_reorgtypes( gimple *stmt, Info_t * info)
+{
+ // TBD
+ return false;
}
//-- debugging only --
static const char *
-code_str (enum tree_code tc)
+code_str( enum tree_code tc)
{
- switch (tc)
+ switch ( tc )
+ {
+ case POINTER_TYPE:
+ return "POINTER_TYPE";
+ case RECORD_TYPE:
+ return "RECORD_TYPE";
+ case UNION_TYPE:
+ return "UNION_TYPE";
+ case ARRAY_TYPE:
+ return "ARRAY_TYPE";
+ case REFERENCE_TYPE:
+ return "REFERENCE_TYPE";
+ case VOID_TYPE:
+ return "VOID_TYPE";
+ case VAR_DECL:
+ return "VAR_DECL";
+ case TYPE_DECL:
+ return "TYPE_DECL";
+ case CONST_DECL:
+ return "CONST_DECL";
+ case PARM_DECL:
+ return "PARM_DECL";
+ case FIELD_DECL:
+ return "FIELD_DECL";
+ case FUNCTION_DECL:
+ return "FUNCTION_DECL";
+ case RESULT_DECL:
+ return "RESULT_DECL";
+ default:
+ switch( TREE_CODE_CLASS( tc) )
{
- case POINTER_TYPE:
- return "POINTER_TYPE";
- case RECORD_TYPE:
- return "RECORD_TYPE";
- case UNION_TYPE:
- return "UNION_TYPE";
- case ARRAY_TYPE:
- return "ARRAY_TYPE";
- case REFERENCE_TYPE:
- return "REFERENCE_TYPE";
- case VAR_DECL:
- return "VAR_DECL";
- case TYPE_DECL:
- return "TYPE_DECL";
- case CONST_DECL:
- return "CONST_DECL";
+ case tcc_type:
+ return "class type";
+ case tcc_declaration:
+ return "class declaration";
+ case tcc_reference:
+ return "class reference";
default:
- 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";
- }
+ return "unknown class";
}
+ }
+}
+
+const char *
+type_name_to_str ( tree tn)
+{
+ gcc_assert ( tn != NULL );
+ gcc_assert ( IDENTIFIER_POINTER ( tn) != NULL );
+ return identifier_to_locale ( IDENTIFIER_POINTER ( tn));
+}
+
+#if DEBUGGING
+static void
+handle_debug_indenting ( int amount )
+{
+ debug_indenting += amount;
+ debug_indenting = MAX ( debug_indenting, 0);
}
+#endif
//---------------- Pass Control Follows ----------------
-const pass_data pass_data_ipa_structure_reorg = {
- SIMPLE_IPA_PASS, /* type */
- "structure-reorg", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- // TV_IPA_SRA, /* tv_id */ // TBD
+const pass_data pass_data_ipa_structure_reorg =
+{
+ IPA_PASS, /* type */
+ "structure reorg", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ //TV_IPA_SRA, /* tv_id */ // TBD
TV_IPA_STRUCTURE_REORG, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
//( TODO_dump_symtab | TODO_remove_functions ), /* todo_flags_finish */ // ???
- (TODO_update_ssa | TODO_update_address_taken | TODO_cleanup_cfg
- | TODO_remove_unused_locals),
- /* todo_flags_finish */ // ???
+ 0, /* todo_flags_finish */ // ???
};
class pass_ipa_structure_reorg : public simple_ipa_opt_pass
{
public:
- pass_ipa_structure_reorg (gcc::context *ctxt)
- : simple_ipa_opt_pass (pass_data_ipa_structure_reorg, ctxt)
+ pass_ipa_structure_reorg ( gcc::context *ctxt)
+ : simple_ipa_opt_pass ( pass_data_ipa_structure_reorg, ctxt)
{}
/* opt_pass methods: */
- virtual bool gate (function *)
- {
- return ((flag_ipa_structure_reorg || flag_ipa_instance_interleave
- || flag_ipa_field_reorder || flag_ipa_dead_field_eliminate));
- }
+ virtual bool gate ( function *)
+ {
+ return ( ( flag_ipa_structure_reorg ||
+ flag_ipa_instance_interleave ||
+ flag_ipa_field_reorder ||
+ flag_ipa_dead_field_eliminate )
+ && optimize );
+ }
- virtual unsigned int execute (function *) { return ipa_structure_reorg (); }
+ virtual unsigned int execute ( function *) { return ipa_structure_reorg (); }
}; // class ipa_structure_reorg
-// ipa_opt_pass_d *
+//ipa_opt_pass_d *
simple_ipa_opt_pass *
-make_pass_ipa_structure_reorg (gcc::context *ctxt)
+make_pass_ipa_structure_reorg ( gcc::context *ctxt)
{
- return new pass_ipa_structure_reorg (ctxt);
+ return new pass_ipa_structure_reorg ( ctxt);
}
diff --git a/gcc/ipa-structure-reorg.h b/gcc/ipa-structure-reorg.h
index 910f066b677..9526929571a 100644
--- a/gcc/ipa-structure-reorg.h
+++ b/gcc/ipa-structure-reorg.h
@@ -20,135 +20,134 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
typedef struct ReorgType ReorgType_t;
-struct ReorgType
-{
- unsigned id;
- tree gcc_type;
- int numbOfGlobalArrays; // Statically allocated only
- int numbOfLocalArrays; // Statically allocated only
- int numbOfDynmAllocs;
- double reorg_perf;
- double regular_perf;
- bool multi_pool; // single pool if not set
- bool delete_me;
- tree clone; // the base
- tree pointer_rep; // new pointer format (multi-pool)
+struct ReorgType {
+ unsigned id;
+ tree gcc_type;
+ int numbOfGlobalArrays; // Statically allocated only
+ int numbOfLocalArrays; // Statically allocated only
+ int numbOfDynmAllocs;
+ double reorg_perf;
+ double regular_perf;
+ bool multi_pool; // single pool if not set
+ bool delete_me;
+ tree clone; // the base
+ tree pointer_rep; // new pointer format (multi-pool)
};
typedef struct ProgDecl ProgDecl_t;
-struct ProgDecl
-{
- tree gcc_decl;
+struct ProgDecl {
+ tree gcc_decl;
};
-enum ReorgOpTrans
-{
- ReorgT_Address, // "&x[i]"
- ReorgT_Pointer, // "a"
- ReorgT_Struct, // "s"
- ReorgT_Deref, // "*a"
- ReorgT_Array, // "x[i]"
- ReorgT_Scalar, // "z"
- ReorgT_Indirect, // "a->f"
- ReorgT_AryDir // "x[i].f"
+enum ReorgOpTrans {
+ ReorgT_Address, // "&x[i]"
+ ReorgT_Pointer, // "a"
+ ReorgT_Struct, // "s"
+ ReorgT_Deref, // "*a"
+ ReorgT_Array, // "x[i]"
+ ReorgT_Scalar, // "z"
+ ReorgT_Indirect, // "a->f"
+ ReorgT_AryDir // "x[i].f"
};
-enum CompressionControl
-{
+enum CompressionControl {
Initial,
Subsequent
};
-enum ReorgTransformation
-{
- ReorgT_StrAssign, // "*a = x[i]", "x[i] = y[j]", "s = *a", etc.
- ReorgT_ElemAssign, // "a->f = z", "z = x[i].f", etc.
- ReorgT_If_Null, // "if(a == 0)..."
- ReorgT_If_NotNull, // "if(a != 0)..."
- ReorgT_IfPtrEQ, // "if(a == b)..."
- ReorgT_IfPtrNE, // "if(a != b)..."
- ReorgT_IfPtrLT, // "if(a < b)..."
- ReorgT_IfPtrGT, // "if(a > b)..."
- ReorgT_IfPtrLE, // "if(a <= b)..."
- ReorgT_IfPtrGE, // "if(a >= b)..."
- ReorgT_PtrPlusInt, // "a = b + i"
- ReorgT_Ptr2Zero, // "a = 0"
- ReorgT_PtrDiff, // "i = a - b"
- ReorgT_Adr2Ptr, // "a = &x[i]"
- ReorgT_PtrNull, // "x = a == 0"
- ReorgT_PtrNotNull, // "x = a != 0"
- ReorgT_PtrEQ, // "x = a == b"
- ReorgT_PtrNE, // "x = a != b"
- ReorgT_PtrLT, // "x = a < b"
- ReorgT_PtrLE, // "x = a <= b"
- ReorgT_PtrGT, // "x = a > b"
- ReorgT_PtrGE, // "x = a >= b"
- ReorgT_Malloc, //
- ReorgT_Calloc, //
- ReorgT_Realloc, //
- ReorgT_Free, //
+enum ReorgTransformation {
+ ReorgT_StrAssign, // "*a = x[i]", "x[i] = y[j]", "s = *a", etc.
+ ReorgT_ElemAssign, // "a->f = z", "z = x[i].f", etc.
+ ReorgT_If_Null, // "if(a == 0)..."
+ ReorgT_If_NotNull, // "if(a != 0)..."
+ ReorgT_IfPtrEQ, // "if(a == b)..."
+ ReorgT_IfPtrNE, // "if(a != b)..."
+ ReorgT_IfPtrLT, // "if(a < b)..."
+ ReorgT_IfPtrGT, // "if(a > b)..."
+ ReorgT_IfPtrLE, // "if(a <= b)..."
+ ReorgT_IfPtrGE, // "if(a >= b)..."
+ ReorgT_PtrPlusInt, // "a = b + i"
+ ReorgT_Ptr2Zero, // "a = 0"
+ ReorgT_PtrDiff, // "i = a - b"
+ ReorgT_Adr2Ptr, // "a = &x[i]"
+ ReorgT_PtrNull, // "x = a == 0"
+ ReorgT_PtrNotNull, // "x = a != 0"
+ ReorgT_PtrEQ, // "x = a == b"
+ ReorgT_PtrNE, // "x = a != b"
+ ReorgT_PtrLT, // "x = a < b"
+ ReorgT_PtrLE, // "x = a <= b"
+ ReorgT_PtrGT, // "x = a > b"
+ ReorgT_PtrGE, // "x = a >= b"
+ ReorgT_Malloc, //
+ ReorgT_Calloc, //
+ ReorgT_Realloc, //
+ ReorgT_Free, //
Not_Supported
};
// Added as design bug fix
typedef struct BoolPair BoolPair_t;
-struct BoolPair
-{
+struct BoolPair {
bool processed;
bool layout_changed;
};
typedef struct Info Info_t;
-struct Info
-{
- std::vector<ReorgType_t> *reorg_type;
+struct Info {
+ std::vector <ReorgType_t> *reorg_type;
// Added to by remove_deleted_types
- std::vector<ReorgType_t> *saved_reorg_type;
- std::vector<ProgDecl_t> *prog_decl;
+ std::vector <ReorgType_t> *saved_reorg_type;
+ std::vector <ProgDecl_t> *prog_decl;
// Gcc doesn't have global decls readily available
// so this holds them
- std::map<tree, BoolPair_t> *struct_types; // desing bug fix
- int num_deleted;
- double total_cache_accesses;
+ std::map <tree,BoolPair_t> *struct_types; // desing bug fix
+ int num_deleted;
+ double total_cache_accesses;
+ FILE *reorg_dump_file;
// Debug flags
- bool show_all_reorg_cands;
- bool show_all_reorg_cands_in_detail;
- bool show_delete;
- bool show_new_BBs;
- bool show_transforms;
- bool show_bounds;
+ bool show_all_reorg_cands;
+ bool show_all_reorg_cands_in_detail;
+ bool show_prog_decls;
+ bool show_delete;
+ bool show_new_BBs;
+ bool show_transforms;
+ bool show_bounds;
};
// This will perform a function on the supplied
// reorg type. It's primarily to support debugging.
-typedef void (*ReorgFn) (Info *, ReorgType_t *);
-
-extern int
-str_reorg_dead_field_eliminate (Info *);
-extern int
-str_reorg_field_reorder (Info *);
-extern int
-str_reorg_instance_interleave (Info *);
-
-extern void
-delete_reorgtype (ReorgType_t *, Info_t *);
-extern void
-undelete_reorgtype (ReorgType_t *, Info_t *);
-extern void
-clear_deleted_types (Info *);
-extern void
-restore_deleted_types (Info *);
-extern void
-remove_deleted_types (Info *, ReorgFn reorg_fn);
+typedef void (*ReorgFn)( Info *, ReorgType_t *);
+
+extern int str_reorg_dead_field_eliminate ( Info *);
+extern int str_reorg_field_reorder ( Info *);
+extern int str_reorg_instance_interleave ( Info *);
+
+extern void delete_reorgtype ( ReorgType_t *, Info_t *);
+extern void undelete_reorgtype ( ReorgType_t *, Info_t *);
+extern void clear_deleted_types( Info *);
+extern void restore_deleted_types ( Info *);
+extern void remove_deleted_types ( Info *, ReorgFn reorg_fn);
+
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
// I have no intention of leaving this or uses of the
// defined marcos in the code. However, some of uses
// should obviously be converted to dump file information.
-#if 1
-#define DEBUG(...) fprintf (stderr, __VA_ARGS__)
-#define DEBUG_F(f, ...) f (__VA_ARGS__)
+#define DEBUGGING 1
+#if DEBUGGING
+// Line numbered
+#define DEBUG_L(...) { fprintf( stderr, "L# %4d: %*s", __LINE__, debug_indenting, ""); fprintf( stderr, __VA_ARGS__); }
+// Alinged with line numbered
+#define DEBUG_A(...) { fprintf( stderr, "%*s", debug_indenting + 7, ""); fprintf( stderr, __VA_ARGS__); }
+//With no indenting
+#define DEBUG(...) { fprintf( stderr, __VA_ARGS__); }
+#define DEBUG_F(f,...) f( __VA_ARGS__)
+#define INDENT(a) handle_debug_indenting(a)
#else
+#define DEBUG_L(...)
+#define DEBUG_A(...)
#define DEBUG(...)
#define DEBUG_F(...)
+#define INDENT(a)
#endif