summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Oblock <gary@amperecomputing.com>2020-10-09 21:29:21 -0700
committerGary Oblock <gary@amperecomputing.com>2020-10-09 21:29:21 -0700
commitdd65938d74e9c97246013ff06040d9dd3904d46b (patch)
tree9c6fd05788481d99dbfa3db4c61fe6dd6ece70be
parent30ba851880f2a6fd9e082d628199ed3a8ac95a62 (diff)
The changes fro v1. They were to performance qualification
and allowed it to qualify the node structure for transformation.
-rw-r--r--gcc/ipa-str-reorg-instance-interleave.c1375
-rw-r--r--gcc/ipa-structure-reorg.c597
-rw-r--r--gcc/ipa-structure-reorg.h22
3 files changed, 1551 insertions, 443 deletions
diff --git a/gcc/ipa-str-reorg-instance-interleave.c b/gcc/ipa-str-reorg-instance-interleave.c
index 1d0213f1427..7073c9fc1d2 100644
--- a/gcc/ipa-str-reorg-instance-interleave.c
+++ b/gcc/ipa-str-reorg-instance-interleave.c
@@ -19,21 +19,24 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#include <vector>
+#include <map>
+#include <set>
+#include <list>
+#include <algorithm>
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "tree-ssa.h"
+#include "tree-ssa-loop-ivopts.h"
#include "tree-dfa.h"
#include "gimple.h"
#include "tree-pass.h"
#include "cgraph.h"
#include "gimple-iterator.h"
#include "pretty-print.h"
-#include <vector>
-#include <map>
-#include <set>
#include "ipa-structure-reorg.h"
#include "dumpfile.h"
#include "tree-pretty-print.h"
@@ -49,13 +52,26 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h"
#include "wide-int.h"
+typedef struct acc_base_info acc_base_info_t;
+typedef struct acc_info acc_info_t;
+typedef struct varInfo varInfo_t;
+
static void wrangle_ssa_type( tree, Info_t*);
//static bool print_internals (gimple *, void *);
static void str_reorg_instance_interleave_qual_part ( Info *);
static void str_reorg_instance_interleave_type_part ( Info *);
static void header ( bool);
+static void print_var_infos ( FILE *, std::vector<varInfo_t> &);
+static void compress_acc_infos ( std::vector <acc_info_t>);
+static void print_acc_info ( FILE *, acc_info_t *);
+static void print_acc_infos ( FILE *, std::vector <acc_info_t>);
+static bool acc_lt ( const acc_info_t&, const acc_info_t&);
+static bool acc_eq ( const acc_info_t&, const acc_info_t&);
+static bool all_but_field_eq ( const acc_info_t&, const acc_info_t&);
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_new_types ( Info_t *);
static void create_a_new_type ( Info_t *, tree);
static unsigned int reorg_perf_qual ( Info *);
@@ -93,10 +109,10 @@ static basic_block make_bb ( char *, basic_block);
*/
// These are dummy values tha alway result the reorganization
-#define SINGLE_POOL_RAW_SKIP_IT 0.0
-#define SINGLE_POOL_RAW_DO_IT_ALWAYS 0.0
-#define SINGLE_POOL_ABS_SKIP_IT 0.0
-#define SINGLE_POOL_ABS_DO_IT_ALWAYS 0.0
+#define SINGLE_POOL_RAW_SKIP_IT 0.05
+#define SINGLE_POOL_RAW_DO_IT_ALWAYS 0.90
+#define SINGLE_POOL_ABS_SKIP_IT 0.02
+#define SINGLE_POOL_ABS_DO_IT_ALWAYS 0.10
int
str_reorg_instance_interleave_qual ( Info *info)
@@ -105,6 +121,7 @@ str_reorg_instance_interleave_qual ( Info *info)
//
str_reorg_instance_interleave_qual_part ( info);
+ //if ( BYPASS_TRANSFORM ) return 0;
// this modifiies the qualified types.
//
str_reorg_instance_interleave_type_part ( info);
@@ -114,14 +131,21 @@ str_reorg_instance_interleave_qual ( Info *info)
int
str_reorg_instance_interleave_trans ( Info *info)
{
+ if ( BYPASS_TRANSFORM )
+ {
+
+ fprintf ( stderr, "Bypassing str_reorg_instance_interleave_trans for experiment\n");
+ return 0;
+ }
+
if ( info->show_all_reorg_cands )
{
fprintf ( info->reorg_dump_file, "Start of str_reorg_instance_interleave_trans:\n");
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);
struct cgraph_node *node;
FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node) {
@@ -245,7 +269,7 @@ str_reorg_instance_interleave_trans ( Info *info)
DEBUG_L("ReorgT_ElemAssign: ");
DEBUG_F( print_gimple_stmt, stderr, stmt, 0);
- INDENT(2);
+ //INDENT(2);
// Needed for helloworld
tree lhs = gimple_assign_lhs( stmt);
tree rhs = gimple_assign_rhs1( stmt);
@@ -255,7 +279,7 @@ str_reorg_instance_interleave_trans ( Info *info)
tree ro_side = ro_on_left ? lhs : rhs;
tree nonro_side = ro_on_left ? rhs : lhs;
- switch ( recognize_op ( ro_side, info) ) // "a->f"
+ switch ( recognize_op ( ro_side, true, info) ) // "a->f"
{
case ReorgOpT_Indirect:
{
@@ -427,14 +451,14 @@ str_reorg_instance_interleave_trans ( Info *info)
} // end recognize_op ( rhs, info) switch
- INDENT(-2);
+ //INDENT(-2);
} // end ReorgT_ElemAssign case
break;
case ReorgT_If_Null:
case ReorgT_If_NotNull:
{
- DEBUG_L("ReorgT_If_(Not)Null: ");
- DEBUG_F( print_gimple_stmt, stderr, stmt, 0);
+ //DEBUG_L("ReorgT_If_(Not)Null: ");
+ //DEBUG_F( print_gimple_stmt, stderr, stmt, 0);
/*
gimple_cond_set_rhs( stmt,
TYPE_MAX_VALUE( pointer_sized_int_node));
@@ -449,14 +473,14 @@ str_reorg_instance_interleave_trans ( Info *info)
//tree max = TYPE_MAX_VALUE ( TREE_TYPE ( ri->pointer_rep));
tree max = TYPE_MAX_VALUE ( ri->pointer_rep);
- DEBUG_L("max: ");
- DEBUG_F(print_generic_expr, stderr, max, (dump_flags_t)0);
- DEBUG("\n");
+ //DEBUG_L("max: ");
+ //DEBUG_F(print_generic_expr, stderr, max, (dump_flags_t)0);
+ //DEBUG("\n");
gimple_cond_set_rhs( cond_stmt, max);
- DEBUG_L("after: ");
- DEBUG_F( print_gimple_stmt, stderr, stmt, 0);
+ //DEBUG_L("after: ");
+ //DEBUG_F( print_gimple_stmt, stderr, stmt, 0);
}
break;
case ReorgT_IfPtrEQ:
@@ -465,13 +489,13 @@ str_reorg_instance_interleave_trans ( Info *info)
case ReorgT_IfPtrGT:
case ReorgT_IfPtrLE:
case ReorgT_IfPtrGE:
- DEBUG_L("ReorgT_IfPtr*\n");
+ //DEBUG_L("ReorgT_IfPtr*\n");
// Not needed for single pool. TBD test this
break;
case ReorgT_PtrPlusInt: // "a = b + i"
{
- DEBUG_L("ReorgT_PtrPlusInt: ");
- DEBUG_F( print_gimple_stmt, stderr, stmt, 0);
+ //DEBUG_L("ReorgT_PtrPlusInt: ");
+ //DEBUG_F( print_gimple_stmt, stderr, stmt, 0);
// Needed for hellowotrld
// Does the type of stmt need to be adjusted? I assume so.
@@ -526,14 +550,14 @@ str_reorg_instance_interleave_trans ( Info *info)
gsi_remove ( &gsi, true);
- DEBUG_L("");
- DEBUG_F( print_gimple_stmt, stderr, gPPI_rhs2_cast, 0);
- DEBUG_L("");
- DEBUG_F( print_gimple_stmt, stderr, gPPI_adj, 0);
- DEBUG_L("");
- DEBUG_F( print_gimple_stmt, stderr, gPPI, 0);
- DEBUG_L("");
- DEBUG_F( print_gimple_stmt, stderr, gPPI_cast, 0);
+ //DEBUG_L("");
+ //DEBUG_F( print_gimple_stmt, stderr, gPPI_rhs2_cast, 0);
+ //DEBUG_L("");
+ //DEBUG_F( print_gimple_stmt, stderr, gPPI_adj, 0);
+ //DEBUG_L("");
+ //DEBUG_F( print_gimple_stmt, stderr, gPPI, 0);
+ //DEBUG_L("");
+ //DEBUG_F( print_gimple_stmt, stderr, gPPI_cast, 0);
}
break;
case ReorgT_Ptr2Zero: // "a = 0"
@@ -587,14 +611,14 @@ str_reorg_instance_interleave_trans ( Info *info)
gsi_remove ( &gsi, true);
- DEBUG_L("");
- DEBUG_F( print_gimple_stmt, stderr, gPD_rhs1_cast, 0);
- DEBUG_L("");
- DEBUG_F( print_gimple_stmt, stderr, gPD_rhs2_cast, 0);
- DEBUG_L("");
- DEBUG_F( print_gimple_stmt, stderr, gPD, 0);
- DEBUG_L("");
- DEBUG_F( print_gimple_stmt, stderr, gPD_cast, 0);
+ //DEBUG_L("");
+ //DEBUG_F( print_gimple_stmt, stderr, gPD_rhs1_cast, 0);
+ //DEBUG_L("");
+ //DEBUG_F( print_gimple_stmt, stderr, gPD_rhs2_cast, 0);
+ //DEBUG_L("");
+ //DEBUG_F( print_gimple_stmt, stderr, gPD, 0);
+ //DEBUG_L("");
+ //DEBUG_F( print_gimple_stmt, stderr, gPD_cast, 0);
}
break;
case ReorgT_Adr2Ptr: // "a = &x[i]"
@@ -616,7 +640,7 @@ str_reorg_instance_interleave_trans ( Info *info)
break;
case ReorgT_PtrNull: // "x = a == 0"
case ReorgT_PtrNotNull: // "x = a != 0"
- DEBUG_L("ReorgT_Ptr(Not)Null\n");\
+ DEBUG_L("ReorgT_Ptr(Not)Null\n"); \
// TBD
/*
gimple_set_op( stmt, 2,
@@ -635,7 +659,7 @@ str_reorg_instance_interleave_trans ( Info *info)
case ReorgT_Malloc:
{
DEBUG_L("Transform ReorgT_Malloc\n");
- INDENT(2);
+ //INDENT(2);
// We need to use the user malloc function
// declaration rather than the builtin!!!
@@ -1082,7 +1106,7 @@ str_reorg_instance_interleave_trans ( Info *info)
//DEBUG_L("End of malloc:\n");
//DEBUG_F( print_program, PRINT_FORMAT, stderr, 4);
}
- INDENT(-2);
+ //INDENT(-2);
break;
case ReorgT_Calloc:
// TBD
@@ -1301,8 +1325,8 @@ str_reorg_instance_interleave_trans ( Info *info)
// transform any constant zero into it's new repersentation.
// OR MAYBE... use FOR_EACH_PHI_ARG for the iterator...
- DEBUG_L("Phis with constant operands:\n");
- INDENT(4);
+ //DEBUG_L("Phis with constant operands:\n");
+ //INDENT(4);
gphi_iterator pi;
for ( pi = gsi_start_phis (bb); !gsi_end_p (pi); gsi_next (&pi))
{
@@ -1319,30 +1343,30 @@ str_reorg_instance_interleave_trans ( Info *info)
for (int i = 0; i < gimple_phi_num_args (phi); i++)
{
tree *arg = gimple_phi_arg_def_ptr (phi, i);
- DEBUG_A("arg[%d] = ",i);
- DEBUG_F(flexible_print, stderr, *arg, 1, (dump_flags_t)0);
+ //DEBUG_A("arg[%d] = ",i);
+ //DEBUG_F(flexible_print, stderr, *arg, 1, (dump_flags_t)0);
bool int_cst = TREE_CODE ( *arg) == INTEGER_CST;
- DEBUG_A("is %sinteger constant\n", int_cst ? "" : "not ");
+ //DEBUG_A("is %sinteger constant\n", int_cst ? "" : "not ");
if ( int_cst && integer_zerop ( *arg) )
{
*arg = TYPE_MAX_VALUE ( ri->pointer_rep);
- DEBUG_L("arg after = ");
- DEBUG_F(flexible_print, stderr, *arg, 1, (dump_flags_t)0);
+ //DEBUG_L("arg after = ");
+ //DEBUG_F(flexible_print, stderr, *arg, 1, (dump_flags_t)0);
}
}
}
}
- INDENT(-4);
+ //INDENT(-4);
}
pop_cfun ();
}
- DEBUG_L("after bulk of transformations\n");
+ //DEBUG_L("after bulk of transformations\n");
- DEBUG_F( print_program, info->reorg_dump_file, PRINT_FORMAT, 4, 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.
@@ -1353,7 +1377,7 @@ str_reorg_instance_interleave_trans ( Info *info)
std::vector <tree> ssa_to_delete;
- DEBUG_L("Mini-Pass on Function %s:\n", lang_hooks.decl_printable_name ( func->decl, 2));
+ //DEBUG_L("Mini-Pass on Function %s:\n", lang_hooks.decl_printable_name ( func->decl, 2));
//DEBUG_L("\n");
//DEBUG_F( wolf_fence, info);
@@ -1385,21 +1409,21 @@ str_reorg_instance_interleave_trans ( Info *info)
// of many functions mapping onto one declaration (which I
// even doubt is possible in thi case) can't be a problem.
- DEBUG_L("Dangling Types for Function Params (default defs).\n");
- INDENT(4);
+ //DEBUG_L("Dangling Types for Function Params (default defs).\n");
+ //INDENT(4);
tree parm;
for ( parm = DECL_ARGUMENTS ( func->decl);
parm;
parm = DECL_CHAIN ( parm) )
{
- DEBUG_A("param: ");
- DEBUG_F( print_generic_decl, stderr, parm, (dump_flags_t)0);
- DEBUG("\n");
- INDENT(2);
+ //DEBUG_A("param: ");
+ //DEBUG_F( print_generic_decl, stderr, parm, (dump_flags_t)0);
+ //DEBUG("\n");
+ //INDENT(2);
tree old_default_def = ssa_default_def ( func, parm);
- DEBUG_A("old_default_def: ");
- DEBUG_F( print_generic_expr, stderr, old_default_def, (dump_flags_t)0);
- DEBUG("\n");
+ //DEBUG_A("old_default_def: ");
+ //DEBUG_F( print_generic_expr, stderr, old_default_def, (dump_flags_t)0);
+ //DEBUG("\n");
tree new_default_def;
// Modify prameter and do the default def stuff
@@ -1409,9 +1433,9 @@ str_reorg_instance_interleave_trans ( Info *info)
if ( modify_decl_core ( &parm, info) )
{
- DEBUG_A("double check new param: ");
- DEBUG_F( print_generic_decl, stderr, parm, (dump_flags_t)0);
- DEBUG("\n");
+ //DEBUG_A("double check new param: ");
+ //DEBUG_F( print_generic_decl, stderr, parm, (dump_flags_t)0);
+ //DEBUG("\n");
// New default def here
@@ -1438,11 +1462,11 @@ str_reorg_instance_interleave_trans ( Info *info)
new_default_def = make_ssa_name_fn ( func, parm, gimple_build_nop ());
set_ssa_default_def ( func, parm, new_default_def);
- DEBUG_A("new_default_def: ");
- DEBUG_F(print_generic_expr, stderr, new_default_def, (dump_flags_t)0);
- DEBUG(", TYPE: ");
- DEBUG_F(print_generic_expr, stderr, TREE_TYPE(new_default_def), (dump_flags_t)0);
- DEBUG("\n");
+ //DEBUG_A("new_default_def: ");
+ //DEBUG_F(print_generic_expr, stderr, new_default_def, (dump_flags_t)0);
+ //DEBUG(", TYPE: ");
+ //DEBUG_F(print_generic_expr, stderr, TREE_TYPE(new_default_def), (dump_flags_t)0);
+ //DEBUG("\n");
// TBD REMOVE DUPLICATE!
// Replace old one (not really totally hence the
@@ -1456,8 +1480,8 @@ str_reorg_instance_interleave_trans ( Info *info)
// new default def
FOR_EACH_IMM_USE_STMT ( stmt, iter, old_default_def) // <== use other form??? Not
{
- DEBUG_A("before: ");
- DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
+ //DEBUG_A("before: ");
+ //DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
use_operand_p use_p;
ssa_op_iter ssa_iter;
// The F_E_S_U_O macro was blowing up on a phi
@@ -1466,14 +1490,14 @@ str_reorg_instance_interleave_trans ( Info *info)
{
if ( use_p == NULL ) continue;
tree use = USE_FROM_PTR (use_p);
- DEBUG_A("use to replace: ");
- DEBUG_F( print_generic_expr, stderr, use, (dump_flags_t)0);
- DEBUG("\n");
+ //DEBUG_A("use to replace: ");
+ //DEBUG_F( print_generic_expr, stderr, use, (dump_flags_t)0);
+ //DEBUG("\n");
if (use == old_default_def)
SET_USE ( use_p, new_default_def);
}
- DEBUG_A("after: ");
- DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
+ //DEBUG_A("after: ");
+ //DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
}
// Get rid of the old default def because it confuses
//
@@ -1482,12 +1506,12 @@ str_reorg_instance_interleave_trans ( Info *info)
release_ssa_name_fn ( func, old_default_def);
}
}
- INDENT(-2);
+ //INDENT(-2);
}
- INDENT(-4);
+ //INDENT(-4);
- DEBUG_L("Dangling Types for Function Local (default defs).\n");
- INDENT(4);
+ //DEBUG_L("Dangling Types for Function Local (default defs).\n");
+ //INDENT(4);
//DEBUG_L("\n");
//DEBUG_F( wolf_fence, info);
@@ -1502,9 +1526,9 @@ str_reorg_instance_interleave_trans ( Info *info)
tree decl;
FOR_EACH_LOCAL_DECL ( func, i, decl)
{
- DEBUG_A("local: ");
- DEBUG_F( print_generic_decl, stderr, decl, (dump_flags_t)0);
- DEBUG("\n");
+ //DEBUG_A("local: ");
+ //DEBUG_F( print_generic_decl, stderr, decl, (dump_flags_t)0);
+ //DEBUG("\n");
tree old_default_def = ssa_default_def ( func, decl);
tree new_default_def;
@@ -1544,28 +1568,28 @@ str_reorg_instance_interleave_trans ( Info *info)
}
}
}
- INDENT(-4);
+ //INDENT(-4);
// Normal ssa name case
- DEBUG_L("Dangling Types for Normal SSA Names:\n");
+ //DEBUG_L("Dangling Types for Normal SSA Names:\n");
//DEBUG_L("\n");
//DEBUG_F( wolf_fence, info);
- INDENT(4);
+ //INDENT(4);
// We use len instead of using func->length() in the for loop test
// because new ssa names are created in the loop body and we
// shouldn't process them.
unsigned int len = SSANAMES ( func)->length ();
- DEBUG_L("len = %d\n",len);
+ //DEBUG_L("len = %d\n",len);
for ( unsigned int i = 0; i < len; i++)
{
- DEBUG_L("SSANAMES(func)[%d]\n",i);
+ //DEBUG_L("SSANAMES(func)[%d]\n",i);
tree ssa_name = (*SSANAMES ( func))[i];
if( ssa_name == NULL )
{
- DEBUG_L("Skip, ssa_name == NULL\n");
+ //DEBUG_L("Skip, ssa_name == NULL\n");
continue;
}
@@ -1576,42 +1600,42 @@ str_reorg_instance_interleave_trans ( Info *info)
tree type = TREE_TYPE ( ssa_name);
tree bottom_type = base_type_of ( type);
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);
- DEBUG(" %s", a_default_def ? "is default_def" : "");
- DEBUG(" %s", no_defining_stmt ? "has no defining stmt" : "");
- DEBUG(" %s", defined_by_nop ? "defined by a nop" : "");
- DEBUG(", type = ");
- DEBUG_F(print_generic_expr, stderr, type, (dump_flags_t)0);
- DEBUG(", bottom_type = ");
- DEBUG_F(print_generic_expr, stderr, bottom_type, (dump_flags_t)0);
- DEBUG(", ri = %p\n",ri);
+ //DEBUG_L("ssa_name = ");
+ //DEBUG_F(print_generic_expr, stderr, ssa_name, (dump_flags_t)0);
+ //DEBUG(" %s", a_default_def ? "is default_def" : "");
+ //DEBUG(" %s", no_defining_stmt ? "has no defining stmt" : "");
+ //DEBUG(" %s", defined_by_nop ? "defined by a nop" : "");
+ //DEBUG(", type = ");
+ //DEBUG_F(print_generic_expr, stderr, type, (dump_flags_t)0);
+ //DEBUG(", bottom_type = ");
+ //DEBUG_F(print_generic_expr, stderr, bottom_type, (dump_flags_t)0);
+ //DEBUG(", ri = %p\n",ri);
// If it's not a dangling type we don't care
if ( ri == NULL )
{
- DEBUG_L("Skip, ri == NULL\n");
+ //DEBUG_L("Skip, ri == NULL\n");
continue;
}
// A default def is processed seperately
if ( a_default_def )
{
- DEBUG_L("Skip default_def\n");
+ //DEBUG_L("Skip default_def\n");
continue;
}
gcc_assert ( !no_defining_stmt);
gcc_assert ( !defined_by_nop);
- DEBUG_L("Defining stmt: ");
- DEBUG_F ( print_gimple_stmt, stderr, defining_stmt, 0);
+ //DEBUG_L("Defining stmt: ");
+ //DEBUG_F ( print_gimple_stmt, stderr, defining_stmt, 0);
tree new_type = ri->pointer_rep;
tree new_ssa_name = make_temp_ssa_name( new_type, NULL, "dedangled");
- DEBUG_L("new_ssa_name = ");
- DEBUG_F(print_generic_expr, stderr, new_ssa_name, (dump_flags_t)0);
- DEBUG("\n");
+ //DEBUG_L("new_ssa_name = ");
+ //DEBUG_F(print_generic_expr, stderr, new_ssa_name, (dump_flags_t)0);
+ //DEBUG("\n");
#if DEBUGGING
for ( unsigned int j = 0; j < SSANAMES ( func)->length (); j++)
{
@@ -1627,8 +1651,8 @@ str_reorg_instance_interleave_trans ( Info *info)
imm_use_iterator iter;
FOR_EACH_IMM_USE_STMT ( use_stmt, iter, ssa_name)
{
- DEBUG_L("use_stmt before: ");
- DEBUG_F ( print_gimple_stmt, stderr, use_stmt, 0);
+ //DEBUG_L("use_stmt before: ");
+ //DEBUG_F ( print_gimple_stmt, stderr, use_stmt, 0);
// Deal with the uses
use_operand_p use_p;
@@ -1637,14 +1661,14 @@ str_reorg_instance_interleave_trans ( Info *info)
//FOR_EACH_SSA_USE_OPERAND( use_p, use_stmt, ssa_iter, SSA_OP_USE )
FOR_EACH_PHI_OR_STMT_USE ( use_p, use_stmt, ssa_iter, SSA_OP_USE )
{
- DEBUG_L("use_p = %p\n",use_p);
+ //DEBUG_L("use_p = %p\n",use_p);
if ( use_p == NULL ) continue;
tree use = USE_FROM_PTR (use_p);
if (use == ssa_name)
SET_USE ( use_p, new_ssa_name);
}
- DEBUG_L("use_stmt after: ");
- DEBUG_F ( print_gimple_stmt, stderr, use_stmt, 0);
+ //DEBUG_L("use_stmt after: ");
+ //DEBUG_F ( print_gimple_stmt, stderr, use_stmt, 0);
// Should update_stmt be called here?
// It does not seem either harm or help so I'll
@@ -1653,12 +1677,12 @@ str_reorg_instance_interleave_trans ( Info *info)
}
// Modify the LHS too
// TBD This code needs to be more general.
- DEBUG_L("What is ssa_name? ");
- DEBUG_F(flexible_print, stderr, ssa_name, 1, (dump_flags_t)0);
+ //DEBUG_L("What is ssa_name? ");
+ //DEBUG_F(flexible_print, stderr, ssa_name, 1, (dump_flags_t)0);
gimple *def = SSA_NAME_DEF_STMT ( ssa_name);
- DEBUG_L("def: ");
- DEBUG_F ( print_gimple_stmt, stderr, def, 0);
+ //DEBUG_L("def: ");
+ //DEBUG_F ( print_gimple_stmt, stderr, def, 0);
set_lhs_for ( def, new_ssa_name);
@@ -1668,7 +1692,7 @@ str_reorg_instance_interleave_trans ( Info *info)
release_ssa_name_fn ( func, ssa_name);
}
- INDENT(-4);
+ //INDENT(-4);
// Might be a bad idea.
#if 0
@@ -1681,17 +1705,20 @@ str_reorg_instance_interleave_trans ( Info *info)
pop_cfun ();
}
- DEBUG_L("after mini-passes\n");
+ // This used to be off of.. "if ( info->show_all_reorg_cands ) { ..."
+ // I'm leaning towards deleting this as redundnt.
+ //DEBUG ( info->reorg_dump_file,
+ // "\nEnd of str_reorg_instance_interleave_trans (after mini-psasses):\n\n");
+ //DEBUG_F ( print_program, info->reorg_dump_file, PRINT_FORMAT, 4, info);
- if ( info->show_all_reorg_cands )
- {
- fprintf ( info->reorg_dump_file, "End of str_reorg_instance_interleave_trans:\n");
- 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.
+
+ return 0;
}
// Note, the following code might be a bit overly simplistic.
@@ -1888,32 +1915,64 @@ struct reorg_bb_info {
};
typedef struct perf_bb_info perf_bb_info_t;
-typedef struct acc_info acc_info_t;
-typedef struct var_info var_info_t;
-struct var_info {
- varpool_node *var;
- sbitmap *bits;
- double count;
+struct acc_base_info {
+ bool a_def_def;
+ bool a_decl;
+ bool a_func;
+ bool has_induct_var_acc;
+ bool multi_induct;
+ bool complicated;
+ // TBD Note could look at sign of operation for the
+ // induction. Variables moving forward are different (cache access
+ // wise) that those moving backward do the sort/compress shouldn't
+ // lump them together.
+ tree acc_base;
+ tree induct_base;
+ gimple *function;
};
-struct acc_info {
- varpool_node *v;
- int field_num;
+struct varInfo {
+ // Varpool_nodes are a pain to get at so I'll just
+ // use the first entry in a run of access info enties
+ // where all of the information but the field is the
+ // same.
+ //varpool_node *var;
+ acc_info_t *rep_access;
+ // This seems bit map scheme seems tedious and unnecessay.
+ // just use the fields
+ // sbitmap *bits;
+ std::list<tree> fields;
+ // The count doesn't vary in the simplified scheme
+ //double count;
};
-struct perf_loop_info {
- std::vector <var_info_t*> *vari;
- class loop *gcc_loop;
+struct acc_info {
+ // trying to get to the varpool seems too hard
+ // so I'll try for he decl
+ //varpool_node *v;
+ tree access;
+ tree field; // int field_num;
+ acc_base_info_t base_info;
+ ReorgType_t *reorg;
};
-static void account_for_use( tree, std::vector <acc_info_t> *);
+//struct perf_loop_info {
+// std::vector <varInfo_t*> *vari;
+// class loop *gcc_loop;
+//};
+
+static void account_for_access( tree, tree, std::vector <acc_info_t> *, Info_t *);
static bool is_array_access( tree);
static unsigned int
reorg_perf_qual ( Info *info)
{
- DEBUG_L("reorg_perf_qual:\n");
+ if ( info->show_perf_qualify )
+ {
+ fprintf ( info->reorg_dump_file, "Doing Performance Qualification\n");
+ }
+ //DEBUG_L("reorg_perf_qual:\n");
#if 1
// TBD use design in doc but mark ReorgTypes
// (do_instance_interleave) that qualify instead of deleting them
@@ -1926,7 +1985,8 @@ reorg_perf_qual ( Info *info)
{
(*(info->reorg_type))[i].do_instance_interleave = true;
}
- #else
+ #endif
+ #if 1
// We are doing a quick and dirty version of performance
// qualification for testing purposes and possibly the
// initial version of for the main branch.
@@ -1949,167 +2009,451 @@ reorg_perf_qual ( Info *info)
// Perf Analysis
struct cgraph_node *node;
+
FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node) {
struct function *func = DECL_STRUCT_FUNCTION ( node->decl);
+
+ if ( info->show_perf_qualify )
+ {
+ fprintf ( info->reorg_dump_file, "Function: ");
+ print_generic_expr ( info->reorg_dump_file,
+ TREE_TYPE(TREE_TYPE( func->decl)),
+ (dump_flags_t)0);
+ }
+
// Ulgy GCC idiom with global pointer to current function.
// However, the dominace calculations other things need it.
push_cfun ( func);
+ #if 1
if ( dom_info_available_p ( CDI_DOMINATORS) )
{
free_dominance_info ( CDI_DOMINATORS);
}
calculate_dominance_info (CDI_DOMINATORS);
-
+ #endif
+
+ if ( info->show_perf_qualify )
+ {
+ fprintf ( info->reorg_dump_file," Function: %s\n",
+ lang_hooks.decl_printable_name ( func->decl, 2));
+ }
+
+
// TBD
- std::vector<perf_loop_info> loop_perf;
- loop_perf.reserve ( number_of_loops ( func));
+ //std::vector<perf_loop_info> loop_perf;
+ //loop_perf.reserve ( number_of_loops ( func));
class loop *loop;
+ bool missing_cases = false;
FOR_EACH_LOOP_FN ( func, loop, LI_ONLY_INNERMOST )
{
- loop_perf [ loop->num ].vari = new std::vector<var_info_t*>; // ???
- loop_perf [ loop->num ].gcc_loop = loop;
+ //We don't need these
+ //loop_perf [ loop->num ].vari = new std::vector<varInfo_t*>; // ???
+ //loop_perf [ loop->num ].gcc_loop = loop;
+
+ std::vector<acc_info_t> acc_info;
+ std::vector<varInfo_t> var_info;
+
size_t num_bbs = loop->num_nodes;
basic_block *bbs = get_loop_body ( loop);
- // TBD Stuff here
+ // For the basic blocks in the the loop
for ( unsigned i = 0; i < loop->num_nodes; i++)
{
basic_block bb = bbs [i];
+ //DEBUG_A("BB %i:\n", bb->index);
+ //INDENT(4);
for ( auto gsi = gsi_start_bb ( bb); !gsi_end_p ( gsi); gsi_next ( &gsi) )
{
gimple *stmt = gsi_stmt ( gsi);
- if ( contains_a_reorgtype ( stmt, info) != NULL )
+ //DEBUG_A("examine: ");
+ //DEBUG_F ( print_gimple_stmt, stderr, stmt, TDF_DETAILS);
+ //INDENT(4);
+
+ if ( gimple_code ( stmt) == GIMPLE_LABEL ||
+ gimple_code ( stmt) == GIMPLE_SWITCH ) continue;
+
+ unsigned n_ops = gimple_num_ops( stmt);
+ tree op;
+ unsigned ith_op;
+ for ( ith_op = 0; ith_op < n_ops; ith_op++ )
{
- DEBUG_A("examine: ");
- DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
- INDENT(4);
- unsigned n_ops = gimple_num_ops( stmt);
- tree op;
- unsigned ith_op;
- for ( ith_op = 0; i < n_ops; i++ )
+ op = gimple_op ( stmt, ith_op);
+ // It's lieing about the number of operands... so...
+ if ( op == NULL ) continue;
+ //DEBUG_A("op[%d]: %p, ", ith_op, op);
+ //DEBUG_F(flexible_print, stderr, op, 1, (dump_flags_t)0);
+ ReorgType_t *tri = tree_contains_a_reorgtype ( op, info);
+ enum ReorgOpTrans optran = recognize_op ( op, false, info);
+ // TBD This is where we need to remember
+ // each germane access
+ const char *s = optrans_to_str( optran);
+ // Commenting out these 3 debug commands causes a
+ // regression
+ //DEBUG_A(", %s\n", s);
+ if ( tri != NULL )
{
- op = gimple_op ( stmt, ith_op);
- ReorgType_t *tri = tree_contains_a_reorgtype (op, info);
- if ( tri != NULL )
- {
- DEBUG_A("");
- DEBUG_F(print_reorg, stderr, 0, tri);
- DEBUG(", ");
- DEBUG_F(flexible_print, stderr, op, 1, (dump_flags_t)0);
- }
+ //DEBUG(", ");
+ //DEBUG_F(print_reorg, stderr, 0, tri);
+ }
+ else
+ {
+ //DEBUG("\n");
+ ;
+ }
+ switch ( optran)
+ {
+ case ReorgOpT_Indirect:
+ {
+ // TBD
+ // Is the var an induction variable for this loop?
+ // If so find the assocaite varpool_node and push
+ // it and the field onto var_acc_info;
+ tree op_var = TREE_OPERAND( op, 0);
+ tree op_field = TREE_OPERAND( op, 1);
+ // Since doesn't have an easily exposed mechanism
+ // for induction variable I'm hand waving here.
+ if ( !expr_invariant_in_loop_p ( loop, op_var) )
+ {
+ account_for_access ( op_var, op_field, &acc_info, info);
+ }
+ }
+ break;
+ case ReorgOpT_Array:
+ {
+ // TBD
+ // Is the var an induction variable for this loop?
+ // If so find the assocaite varpool_node and push
+ // it and the field onto var_acc_info;
+ tree op_var = TREE_OPERAND( op, 0);
+ tree op_field = TREE_OPERAND( op, 1);
+ // Since doesn't have an easily exposed mechanism
+ // for induction variable I'm hand waving here.
+ if ( !expr_invariant_in_loop_p ( loop, op_var) )
+ {
+ account_for_access ( op_var, op_field, &acc_info, info);
+ }
+ }
+ case ReorgOpT_AryDir:
+ case ReorgOpT_Deref: // ??
+ missing_cases = true;
}
- INDENT(-4);
-
}
+ //INDENT(-4);
}
- }continue; // Testing above here
+ //INDENT(-4);
+ }
+ //DEBUG_L("Dumping acc_info:\n");
+ for ( auto aci = acc_info.begin (); aci != acc_info.end (); aci++ )
+ {
+ //DEBUG_A("variable:\n");
+ //DEBUG_F( tell_me_about_ssa_name, (*aci).access, debug_indenting + 4);
+ //DEBUG_A("field: ");
+ //DEBUG_F( flexible_print, stderr, (*aci).field, 1, (dump_flags_t)0);
+ }
+
+ //DEBUG_A("before sort: \n");
+ //DEBUG_F(print_acc_infos, stderr, acc_info );
+
+ // Sort and compact the access infos.
+ stable_sort ( acc_info.begin (), acc_info.end (), acc_lt);
+
+ //DEBUG_A("before compress: \n");
+ //DEBUG_F(print_acc_infos, stderr, acc_info );
+
+ // Sort and compact the access infos.
+ std::stable_sort ( acc_info.begin (), acc_info.end (), acc_lt);
+
+ compress_acc_infos ( acc_info );
+
+ //DEBUG_A("after compress: \n");
+ //DEBUG_F(print_acc_infos, stderr, acc_info );
+
// Obtain loop count by looking at all the block counts.
- unsigned max_count = 0;
+ unsigned loop_count = 0;
for ( unsigned i = 0; i < loop->num_nodes; i++)
{
basic_block bb = bbs [i];
- max_count = MAX( max_count, bb->count.value ());
+ loop_count = MAX( loop_count, bb->count.value ());
+ }
+ //DEBUG_L("loop_count = %d, nb_iterations_estimate = %ld\n",
+ // loop_count, loop->nb_iterations_estimate);
+
+ // Create the variable infos
+ varInfo_t var_entry;
+ var_entry.rep_access = &acc_info[0];
+ unsigned len = acc_info.size ();
+
+ // If no accesses detected, never for this loop.
+ if ( len == 0 ) continue;
+
+ if ( len == 1 )
+ {
+ var_entry.fields.push_front ( acc_info[0].field);
+ }
+ else
+ {
+ unsigned i, j;
+ for ( i = 0, j = 1; j < len; j++ )
+ {
+ acc_info_t *a_of_i = &acc_info[i];
+ acc_info_t *a_of_j = &acc_info[j];
+ var_entry.fields.push_front ( a_of_i->field);
+ if ( !all_but_field_eq ( *a_of_i, *a_of_j ) )
+ {
+ var_info.push_back( var_entry);
+ var_entry.rep_access = a_of_j;
+ var_entry.fields.clear ();
+ a_of_i = a_of_j;
+ }
+ }
}
- DEBUG_L("max_count = %d, nb_iterations_estimate = %ld\n",
- max_count, loop->nb_iterations_estimate);
+ var_info.push_back( var_entry);
+
+ if ( info->show_perf_qualify )
+ {
+ fprintf ( stderr, "%d VarInfos\n", var_info.size ());
+ }
+ //DEBUG_F(print_var_infos, stderr, var_info);
+
+ //
+ // Model the performance
+ //
+ //DEBUG_A("Model The Performance\n");
// Originally this was done per bb but now it has to be per
// loop. TBD But perf_bb is per loop so we need something similar
// per loop.
- std::vector <var_info_t*> *pv = loop_perf [ loop->num].vari;
- for ( auto pvi = pv->begin (); pvi != pv->end (); pvi++ )
+ for ( auto pvi = var_info.begin (); pvi != var_info.end (); pvi++ )
{ // 676
- tree base_type = base_type_of( ( *pvi)->var->decl);
- ReorgType_t *ri = get_reorgtype_info ( base_type, info);
+ //tree base_type = base_type_of( pvi->rep_access.access);
+ ReorgType_t *ri = pvi->rep_access->reorg;
+
// Reorg accounting
+ //DEBUG_L("\n");
+ //DEBUG_A("Reorg Accounting\n");
+
if( ri != NULL )
{
double reorg_nca = 0.0;
- int fi;
- tree field;
- for( field = TYPE_FIELDS ( ri->gcc_type), fi = 0;
- field;
- field = DECL_CHAIN ( field), fi++ ) // 684
+
+ //DEBUG_A(" for: ");
+ //DEBUG_F( flexible_print, stderr, ri->gcc_type, 1, (dump_flags_t)0);
+ //INDENT(4);
+ for ( auto fldi = pvi->fields.begin (); fldi != pvi->fields.end (); fldi++ )
{
- if ( bitmap_bit_p ( *(*pvi)->bits, fi) )
- {
- unsigned HOST_WIDE_INT fld_width =
- tree_to_uhwi ( DECL_SIZE ( field));
- reorg_nca += max_count * alignment_effect ( fld_width);
- }
+ unsigned HOST_WIDE_INT fld_width =
+ tree_to_uhwi ( DECL_SIZE ( *fldi));
+ double effect = alignment_effect ( fld_width);
+ double product = loop_count * effect;
+ reorg_nca += product;
+ //DEBUG_A("Add loop_count * effect (%d * %f = %f) to reorg_nca (now %f)\n",
+ // loop_count, effect, product, reorg_nca);
}
+ //INDENT(-4);
ri->instance_interleave.reorg_perf += reorg_nca;
- } // 699
-
+ //DEBUG_A("Add reorg_nca (%f) to reorg_perf (now %e)\n",
+ // reorg_nca, ri->instance_interleave.reorg_perf);
+ } // 699
+
// regular accounting
+ //DEBUG_L("\n");
+ //DEBUG_A("Regular Accounting\n");
+
double regular_nca = 0.0;
sbitmap cache_model = sbitmap_alloc(1);
- // TBD NOTE, pv steps on the pv above.
- std::vector <var_info_t*> *pv2 = loop_perf[ loop->num].vari;
- for( auto pv2i = pv2->begin (); pv2i != pv2->end (); pv2i++ ) { // 704
- tree base_type = base_type_of ( (*pv2i)->var->decl);
- // create a tiny model of the cache big
- // enough for this record.
- unsigned HOST_WIDE_INT len =
- (( tree_to_uhwi ( DECL_SIZE ( base_type))
- +
- param_l1_cache_line_size -1)
- /
- param_l1_cache_line_size)
- +
- 1;
- cache_model = sbitmap_resize( cache_model, (unsigned) len, 0);
- double accum = 0.0;
- int nrbo = 0;
- for ( auto field_ex = TYPE_FIELDS ( base_type);
- field_ex;
- field_ex = DECL_CHAIN ( field_ex) )
- {
- nrbo++;
- unsigned HOST_WIDE_INT base_offset =
- tree_to_uhwi ( DECL_FIELD_OFFSET( field_ex));
- // Access accounting
- int fi = 0;
- for ( auto field = TYPE_FIELDS ( base_type);
- field;
- field = DECL_CHAIN ( field), fi++)
- {
- if ( bitmap_bit_p ( *(*pv2i)->bits, fi) )
+
+ for( auto pv2i = var_info.begin (); pv2i != var_info.end (); pv2i++ )
+ { // 704
+ tree access = pv2i->rep_access->base_info.acc_base;
+ tree base_type; // = base_type_of ( access);
+ if ( pv2i->rep_access->reorg != NULL )
+ {
+ //DEBUG_A("Base type from reorg: ");
+ base_type = pv2i->rep_access->reorg->gcc_type;
+ }
+ else
+ {
+ //DEBUG_A("Base type from access: ");
+ if ( TREE_TYPE ( access ) != NULL )
+ {
+ base_type = base_type_of ( access);
+ }
+ else
+ {
+ gcc_assert (0);
+ }
+ }
+ //DEBUG_F( flexible_print, stderr, base_type, 1, (dump_flags_t)0);
+
+ bool base_type_isa_decl = DECL_P ( base_type );
+
+ // create a tiny model of the cache big
+ // enough for this record.
+ #if 0
+ tree base_type_size = base_type_isa_decl ?
+ DECL_SIZE ( base_type )
+ :
+ TYPE_SIZE ( base_type);
+ #else
+ tree base_type_size;
+ if ( base_type_isa_decl )
+ {
+ //DEBUG_A("decl\n");
+ switch ( TREE_CODE (base_type) )
+ {
+ case VAR_DECL:
{
- unsigned HOST_WIDE_INT fld_width, fld_offset;
- fld_width = tree_to_uhwi ( DECL_SIZE ( field));
- fld_offset = tree_to_uhwi ( DECL_FIELD_OFFSET ( field));
- int chari;
- for ( chari = 0; chari < fld_width; chari++ )
- {
- int loc = (chari + fld_offset + base_offset)
- /
- param_l1_cache_line_size;
- bitmap_set_bit ( cache_model, loc);
- }
+ //DEBUG_A("VAR_DECL\n");
+ base_type_size = TYPE_SIZE ( base_type);
+ break;
}
- }
- accum += bitmap_count_bits ( cache_model);
- bitmap_clear ( cache_model);
- }
- regular_nca += accum / nrbo;
+ case FIELD_DECL:
+ {
+ //DEBUG_A("VAR_DECL\n");
+ base_type_size = TYPE_SIZE ( TREE_TYPE ( base_type));
+ break;
+ }
+ default:
+ {
+ //DEBUG_A("other decl %s\n", code_str(TREE_CODE (base_type)));
+ gcc_assert(0);
+ }
+ }
+ }
+ else
+ {
+ //DEBUG_A("nondecl %s\n", code_str(TREE_CODE (base_type)));
+ if ( TREE_CODE ( base_type) == SSA_NAME )
+ {
+ base_type_size = TYPE_SIZE ( TREE_TYPE( base_type));
+ }
+ else
+ {
+ base_type_size = TYPE_SIZE ( base_type);
+ }
+ }
+ #endif
+
+ unsigned HOST_WIDE_INT len =
+ (( tree_to_uhwi ( base_type_size)
+ +
+ param_l1_cache_line_size -1)
+ /
+ param_l1_cache_line_size)
+ +
+ 1;
+ //DEBUG_L("\n");
+ //DEBUG_A("cache len = %d (lines), for: ", len);
+ //DEBUG_F( flexible_print, stderr, base_type, 0, (dump_flags_t)0);
+ //DEBUG("%sstruct\n")
- } // 739
+ // TBD Does this clear the bits??? It needs to.
+ // Each bit represents a cache line.
+ cache_model = sbitmap_resize( cache_model, (unsigned) len, 0);
+ double accum = 0.0;
+ int nrbo = 0;
+ tree type = TREE_TYPE ( base_type);
+
+ //bool a_record = type == NULL && TREE_CODE ( type) == RECORD_TYPE;
+ bool a_record = type != NULL && TREE_CODE ( type) == RECORD_TYPE;
+ if ( base_type_isa_decl && a_record )
+ {
+ for ( auto field_ex = TYPE_FIELDS ( base_type);
+ field_ex;
+ field_ex = DECL_CHAIN ( field_ex) )
+ {
+ nrbo++;
+ // Looking back on my design I don't have a clue
+ // why this is here and what it does. Sigh...
+ unsigned HOST_WIDE_INT base_offset =
+ tree_to_uhwi ( DECL_FIELD_OFFSET( field_ex));
+ //DEBUG_L("\n");
+ //DEBUG_A("For field_ex: ");
+ //DEBUG_F( flexible_print, stderr, field_ex, 0, (dump_flags_t)0);
+ //DEBUG(", nrbo %d, base_offset %d\n", nrbo, base_offset);
+
+ // Access accounting
+
+ //INDENT(4);
+ for ( auto fldi = pv2i->fields.begin ();
+ fldi != pv2i->fields.end (); fldi++ )
+ {
+ tree field = *fldi;
+ unsigned HOST_WIDE_INT fld_width, fld_offset;
+ fld_width = tree_to_uhwi ( DECL_SIZE ( field));
+ fld_offset = tree_to_uhwi ( DECL_FIELD_OFFSET ( field));
+ //DEBUG_A("Field: ");
+ //DEBUG_F( flexible_print, stderr, field, 0, (dump_flags_t)0);
+ //DEBUG(", width = %d, offset = %d\n", fld_width, fld_offset);
+ int chari;
+ //INDENT(4);
+ for ( chari = 0; chari < fld_width; chari++ )
+ {
+ int loc = (chari + fld_offset + base_offset)
+ /
+ param_l1_cache_line_size;
+ //DEBUG_A("loc: %d\n", loc);
+ bitmap_set_bit ( cache_model, loc);
+ }
+ //INDENT(-4);
+ }
+ //INDENT(-4);
+ unsigned bcount = bitmap_count_bits ( cache_model);
+ accum += bcount;
+ //DEBUG_L("\n");
+ //DEBUG_A("Add popcount of cache (%d) to accum (now %f)\n",
+ // bcount, accum);
+ bitmap_clear ( cache_model);
+ }
+ }
+ else
+ {
+ nrbo = 1;
+ accum++;
+ //DEBUG_L("\n");
+ //DEBUG_A("nrbo = 1, increment accum to %f\n", accum);
+ }
+ #if 1
+ double amount = accum / nrbo;
+ double product = amount * loop_count;
+ regular_nca += product;
+ //DEBUG_L("\n");
+ //DEBUG_A("Add loop_count*accum/nrbo (%f*%f/%d = %f) to regular_nca (now %e)\n",
+ // loop_count, accum, nrbo, product, regular_nca);
+ #else
+ double amount = accum / nrbo;
+ regular_nca += amount;
+ //DEBUG_L("\n");
+ //DEBUG_A("Add accum/nrbo (%f/%d = %f) to regular_nca (now %e)\n",
+ // accum, nrbo, amount, regular_nca);
+ #endif
+ } // 739
sbitmap_free ( cache_model);
if( ri != NULL ) {
ri->instance_interleave.regular_perf += regular_nca;
- cache_accesses_noreorg += regular_nca;
- } else {
- cache_accesses += regular_nca;
- }
- } // end for each prop_var 748
-
-
- } //
+ cache_accesses_noreorg += regular_nca;
+ //DEBUG_L("\n");
+ //DEBUG_A("Add regular_nca (%f) to regular_perf (now %e)",
+ // regular_nca, ri->instance_interleave.regular_perf);
+ //DEBUG_A(" and to cache_accesses_noreorg (now %e)\n",
+ // cache_accesses_noreorg);
+ } else {
+ cache_accesses += regular_nca;
+ }
+ } // end for prop_var
+ } //
+
+ if ( info->show_perf_qualify && missing_cases )
+ {
+ fprintf ( info->reorg_dump_file,
+ " Ignored unimplemented cases when finding accesses.\n");
+ }
+
+ free_dominance_info ( CDI_DOMINATORS);
pop_cfun ();
}
@@ -2124,6 +2468,17 @@ reorg_perf_qual ( Info *info)
info->total_cache_accesses = total_cache_accesses;
+ if ( info->show_perf_qualify )
+ {
+ fprintf ( info->reorg_dump_file, "total_cache_accesses: %e\n\n",
+ total_cache_accesses);
+ }
+
+ if ( info->show_perf_qualify )
+ {
+ fprintf ( info->reorg_dump_file,
+ "Decide which reorgTypes fail performance qualification\n");
+ }
//
// Decide which reorgTypes fail performance qualification
//
@@ -2134,10 +2489,16 @@ reorg_perf_qual ( Info *info)
reorgi != reorg_types->end (); reorgi++ )
{
double with_opt = reorgi->instance_interleave.reorg_perf;
- double wihtout_opt = reorgi->instance_interleave.regular_perf;
- double raw_effect = with_opt/wihtout_opt;
+ double without_opt = reorgi->instance_interleave.regular_perf;
+ double raw_effect = with_opt/without_opt;
double absolute_effect =
- (wihtout_opt - with_opt) / total_cache_accesses;
+ (without_opt - with_opt) / total_cache_accesses;
+ //DEBUG_A("For ");
+ //DEBUG_F(flexible_print, stderr, reorgi->gcc_type, 0, (dump_flags_t)0);
+ //DEBUG(" with_opt: %e, without_opt %e, total_cache_accesses %e\n",
+ // with_opt, without_opt, total_cache_accesses);
+ //DEBUG_A(" Raw Effect: %5.4f, Absolute Effect %5.4f\n",
+ // raw_effect, absolute_effect);
// Note, there would need to be a multi-pool case here if
// that is every done.
@@ -2145,6 +2506,16 @@ reorg_perf_qual ( Info *info)
// If the relative effect is small enough don't bother.
if ( raw_effect < SINGLE_POOL_RAW_SKIP_IT )
{
+ if ( info->show_perf_qualify )
+ {
+ fprintf ( info->reorg_dump_file, " Disqualified: ");
+ flexible_print ( info->reorg_dump_file, reorgi->gcc_type, 0,
+ (dump_flags_t)0);
+ fprintf ( info->reorg_dump_file, ": Very small effect:\n");
+ fprintf ( info->reorg_dump_file,
+ " raw_effect %5.4f < SINGLE_POOL_RAW_SKIP_IT %5.4f\n",
+ raw_effect, SINGLE_POOL_RAW_SKIP_IT);
+ }
reorgi->do_instance_interleave = false;
continue;
}
@@ -2152,16 +2523,51 @@ reorg_perf_qual ( Info *info)
// otherwise look at the absolute effect.
if ( raw_effect >= SINGLE_POOL_RAW_DO_IT_ALWAYS )
{
+
+ if ( info->show_perf_qualify )
+ {
+ fprintf ( info->reorg_dump_file, " Qualified: ");
+ flexible_print ( info->reorg_dump_file, reorgi->gcc_type, 0,
+ (dump_flags_t)0);
+ fprintf ( info->reorg_dump_file, ": Large raw effect:\n");
+ fprintf ( info->reorg_dump_file,
+ " raw_effect %5.4f >= SINGLE_POOL_RAW_DO_IT_ALWAYS %5.4f\n",
+ raw_effect, SINGLE_POOL_RAW_DO_IT_ALWAYS);
+ }
+
reorgi->do_instance_interleave = true;
continue;
}
if ( absolute_effect < SINGLE_POOL_ABS_SKIP_IT )
{
+ if ( info->show_perf_qualify )
+ {
+ fprintf ( info->reorg_dump_file, " Disqualified: ");
+ flexible_print ( info->reorg_dump_file, reorgi->gcc_type, 0,
+ (dump_flags_t)0);
+ fprintf ( info->reorg_dump_file, ": Very small absolute effect:\n");
+ fprintf ( info->reorg_dump_file,
+ " absolute_effect %5.4f < SINGLE_POOL_ABS_SKIP_IT %5.4f\n",
+ absolute_effect, SINGLE_POOL_ABS_SKIP_IT);
+ }
+
reorgi->do_instance_interleave = false;
continue;
}
if ( absolute_effect >= SINGLE_POOL_ABS_DO_IT_ALWAYS )
{
+
+ if ( info->show_perf_qualify )
+ {
+ fprintf ( info->reorg_dump_file, " Qualified: ");
+ flexible_print ( info->reorg_dump_file, reorgi->gcc_type, 0,
+ (dump_flags_t)0);
+ fprintf ( info->reorg_dump_file, ": Large absolute effect:\n");
+ fprintf ( info->reorg_dump_file,
+ " absolute_effect %5.4f >= SINGLE_POOL_ABS_DO_IT_ALWAYS %5.4f\n",
+ absolute_effect, SINGLE_POOL_ABS_DO_IT_ALWAYS);
+ }
+
reorgi->do_instance_interleave = true;
continue;
}
@@ -2172,13 +2578,224 @@ reorg_perf_qual ( Info *info)
double cut_off = cut_off_eq_single_pool ( absolute_effect);
if ( raw_effect < cut_off )
{
+
+ if ( info->show_perf_qualify )
+ {
+ fprintf ( info->reorg_dump_file, " Disqualified: ");
+ flexible_print ( info->reorg_dump_file, reorgi->gcc_type, 0,
+ (dump_flags_t)0);
+ fprintf ( info->reorg_dump_file, ": Failed cut off equations:\n");
+ fprintf ( info->reorg_dump_file,
+ " raw_effect %5.4f < cut_off %5.4f\n",
+ raw_effect, cut_off);
+ }
+
reorgi->do_instance_interleave = false;
- }
+ continue;
+ }
+
+ if ( info->show_perf_qualify )
+ {
+ fprintf ( info->reorg_dump_file, " Qualified: ");
+ flexible_print ( info->reorg_dump_file, reorgi->gcc_type, 0,
+ (dump_flags_t)0);
+ fprintf ( info->reorg_dump_file, ": Passed cut off equations:\n");
+ fprintf ( info->reorg_dump_file,
+ " raw_effect %5.4f >= cut_off %5.4f\n",
+ raw_effect, cut_off);
+ }
+
}
+ #endif
+}
- free_dominance_info ( CDI_DOMINATORS);
+static void
+print_var_info ( FILE *file, varInfo_t &vinfo)
+{
+ print_acc_info ( file, vinfo.rep_access );
+ for ( auto fi = vinfo.fields.begin (); fi != vinfo.fields.end (); fi++ )
+ {
+ if ( fi != vinfo.fields.begin () ) fprintf ( stderr,", ");
+ flexible_print ( stderr, *fi, 0, (dump_flags_t)0);
+ }
+ fprintf ( stderr,"\n");
+}
- #endif
+static void
+print_var_infos ( FILE *file, std::vector<varInfo_t> &vinfo)
+{
+ fprintf( stderr, "print_var_infos:\n");
+ for ( auto vi = vinfo.begin (); vi != vinfo.end (); vi++ )
+ {
+ print_var_info ( file, *vi);
+ }
+}
+
+static void
+compress_acc_infos ( std::vector <acc_info_t> ainfo )
+{
+ unsigned len = ainfo.size ();
+ //DEBUG_L("compress_acc_infos: len in %d, ",len);
+ if ( len <= 1 ) return;
+ unsigned i, j;
+ for ( i = j = 1; j < len; j++ )
+ {
+ ainfo[i] = ainfo[j];
+ if ( !acc_eq ( ainfo[i], ainfo[i - 1]) ) i++;
+ }
+ if ( i == j ) return;
+ ainfo.resize ( len - (j -i));
+ //DEBUG_L("len out %d, ", ainfo.size ());
+}
+
+static void
+print_acc_info ( FILE *file, acc_info_t *ainfo )
+{
+ //DEBUG_L("print_acc_info: ainfo %p\n", ainfo);
+ fprintf ( file, "%s%s%s%s%s%s\n",
+ ainfo->base_info.a_def_def ? ", deflt_def" : "",
+ ainfo->base_info.a_decl ? ", decl" : "",
+ ainfo->base_info.a_func ? ", a_func" : "",
+ ainfo->base_info.has_induct_var_acc ? ", induct" : "",
+ ainfo->base_info.multi_induct ? ", multi" : "",
+ ainfo->base_info.complicated ? ", complicated" : "");
+ fprintf ( file, " base var ");
+ flexible_print ( stderr, ainfo->base_info.acc_base, 0, (dump_flags_t)0);
+ if ( ainfo->base_info.has_induct_var_acc )
+ {
+ fprintf ( file, ", induc var ");
+ flexible_print ( stderr, ainfo->base_info.acc_base,
+ 0, (dump_flags_t)0);
+ }
+ fprintf ( file, ", field ");
+ flexible_print ( stderr, ainfo->field, 0, (dump_flags_t)0);
+ if ( ainfo->reorg )
+ {
+ fprintf ( file, ", reorg of ");
+ flexible_print ( stderr, ainfo->reorg->gcc_type,
+ 0, (dump_flags_t)0);
+ }
+ fprintf ( file, "\n");
+}
+
+static void
+print_acc_infos ( FILE *file, std::vector <acc_info_t> ainfo )
+{
+ fprintf ( file, "print_acc_infos:\n");
+ unsigned i;
+ unsigned len = ainfo.size ();
+
+ for ( i = 0; i < len; i++ )
+ {
+ fprintf ( file, "[%d] ", i);
+ print_acc_info ( file, &ainfo[i]);
+ }
+}
+
+
+// decls < default defs < defined by function
+static bool
+acc_lt_acc_category ( const acc_info_t& a, const acc_info_t& b )
+{
+ int ord_a = a.base_info.a_decl ? 1 : a.base_info.a_def_def ? 2 : 3;
+ int ord_b = b.base_info.a_decl ? 1 : b.base_info.a_def_def ? 2 : 3;
+ if ( ord_a < ord_b ) return true;
+ if ( ord_a > ord_b ) return false;
+ switch ( ord_a ) {
+ case 1:
+ // The field isn't there for decls, it's the index. Ignoring the
+ // index is harmless. This is becauseif if we take an arbitary
+ // small number of iterations of a loop, then all the permutations
+ // of the accesses in those iterations touch the same number of
+ // cache lines (just in a different order.)
+ return false;
+ case 2:
+ {
+ if ( a.access < b.access ) return true;
+ if ( a.access > b.access ) return false;
+ return a.field < b.field;
+ }
+ case 3:
+ {
+ if ( a.base_info.function < b.base_info.function ) return true;
+ if ( a.base_info.function > b.base_info.function ) return false;
+ return a.field < b.field;
+ }
+ }
+}
+
+// Complicated is less than noncomplicated and null reorgs are less than non
+// null reorgs.
+static bool
+acc_lt ( const acc_info_t& a, const acc_info_t& b )
+{
+ if ( a.base_info.complicated && !b.base_info.complicated ) return true;
+ if ( !a.base_info.complicated && !b.base_info.complicated ) return false;
+ if ( a.reorg == NULL )
+ {
+ if ( b.reorg != NULL ) return true;
+ // compare non_reorg_bit
+ return acc_lt_acc_category ( a, b);
+ }
+ else
+ {
+ if ( b.reorg == NULL ) return false;
+ if ( a.reorg < b.reorg ) return true;
+ if ( a.reorg > b.reorg ) return false;
+ // compare non_reorg_bit
+ return acc_lt_acc_category ( a, b);
+ }
+}
+
+static bool
+acc_eq ( const acc_info_t& a, const acc_info_t& b )
+{
+ // nothing complicated is equal to anything else. Being complicated
+ // is basically saying that little is really know about it and it's
+ // difficult if not meaningless to analyze in depth given this
+ // framework.
+ if ( a.base_info.complicated || b.base_info.complicated ) return false;
+ if ( a.reorg != b.reorg ) return false;
+ int ord_a = a.base_info.a_decl ? 1 : a.base_info.a_def_def ? 2 : 3;
+ int ord_b = b.base_info.a_decl ? 1 : b.base_info.a_def_def ? 2 : 3;
+ if ( ord_a != ord_b ) return false;
+ switch ( ord_a ) {
+ case 1:
+ case 2:
+ {
+ if ( a.access != b.access ) return false;
+ }
+ case 3:
+ {
+ if ( a.base_info.function != b.base_info.function ) return false;
+ }
+ }
+ return a.field == b.field;
+}
+
+static bool
+all_but_field_eq ( const acc_info_t& a, const acc_info_t& b )
+{
+ // nothing complicated is equal to anything else. Being complicated
+ // is basically saying that little is really know about it and it's
+ // difficult if not meaningless to analyze in depth given this
+ // framework.
+ if ( a.base_info.complicated || b.base_info.complicated ) return false;
+ if ( a.reorg != b.reorg ) return false;
+ int ord_a = a.base_info.a_decl ? 1 : a.base_info.a_def_def ? 2 : 3;
+ int ord_b = b.base_info.a_decl ? 1 : b.base_info.a_def_def ? 2 : 3;
+ if ( ord_a != ord_b ) return false;
+ switch ( ord_a ) {
+ case 1:
+ case 2:
+ {
+ return a.access == b.access;
+ }
+ case 3:
+ {
+ return a.base_info.function == b.base_info.function;
+ }
+ }
}
#define SINGLE_POOL_SLOPE \
@@ -2246,18 +2863,248 @@ is_array_access( tree acc)
}
static void
-account_for_use( tree acc, std::vector <acc_info_t> *acc_info)
+account_for_access ( tree access, tree field, std::vector <acc_info_t> *acc_info, Info_t *info)
{
- // determine element of access
- // find field access number i
- // find var v
- varpool_node *v;
- int i;
- // TBD
- acc_info_t ai = { v, i};
+ //DEBUG_A("account_for_use var: ");
+ //DEBUG_F(flexible_print, stderr, access, 0, (dump_flags_t)0);
+ //DEBUG(", field: ");
+ //DEBUG_F(flexible_print, stderr, field, 1, (dump_flags_t)0);
+
+ // assert might eventually make sense but not yet
+ //gcc_assert ( TREE_CODE ( ssa_var) == SSA_NAME);
+ acc_info_t ai;
+ //ai.v = SSA_NAME_VAR ( ssa_var);
+ ai.access = access; // TBD We need to see if we can find the decl
+ ai.field = field;
+ ai.reorg = tree_contains_a_reorgtype ( access, info);
+ analyze_access ( access, &ai);
+ // don't count this acces if there is no associated induction variable
+ if ( !ai.base_info.has_induct_var_acc ) return;
+ // Otherwise add the access
acc_info->push_back( ai);
}
+static void
+tmasn_helper ( tree t, int indent, std::set<tree> *already )
+{
+ //DEBUG_A("");
+ fprintf( stderr, "%*s", indent, " ");
+ indent += 4;
+ flexible_print ( stderr, t, 0, (dump_flags_t)0);
+ if ( already->find (t) != already->end () )
+ {
+ fprintf( stderr, " <Induction>\n");
+ return;
+ }
+ else
+ {
+ fprintf( stderr, "\n");
+ }
+ //DEBUG_L("code: %s\n", code_str(TREE_CODE (t)));
+ if ( TREE_CODE (t) == SSA_NAME )
+ {
+ already->insert (t);
+ gimple *stmt = SSA_NAME_DEF_STMT (t);
+ fprintf( stderr, "%*sSSA_NAME defined in: ", indent - 4, " ");
+ print_gimple_stmt( stderr, stmt, TDF_DETAILS);
+ if ( gimple_code ( stmt) == GIMPLE_PHI )
+ {
+ gphi *phi_stmt = dyn_cast <gphi *> ( stmt);
+ for (int i = 0; i < gimple_phi_num_args (phi_stmt); i++)
+ {
+ tree *arg = gimple_phi_arg_def_ptr (phi_stmt, i);
+ tmasn_helper ( *arg, indent, already);
+ }
+ }
+ else
+ {
+ bool a_ass = gimple_code ( stmt) == GIMPLE_ASSIGN;
+ bool a_call = gimple_code ( stmt) == GIMPLE_CALL;
+ // This was being triggered an add: op = op + op
+ //gcc_assert ( a_ass || a_call );
+
+ if ( a_call )
+ {
+ for ( int i = 0; i < gimple_call_num_args ( stmt); i++ )
+ {
+ tmasn_helper ( gimple_call_arg ( stmt, i) , indent, already);
+ }
+ }
+ else
+ {
+ // Note, start with one to skip lhs op.
+ for ( int i = 1; i < gimple_num_ops ( stmt); i++ )
+ {
+ tmasn_helper ( gimple_op ( stmt, i) , indent, already);
+ }
+ }
+ }
+ return;
+ }
+ if ( DECL_P ( t) )
+ {
+ return;
+ }
+ if ( TREE_CODE ( t) == MEM_REF )
+ {
+ tree t_0 = TREE_OPERAND ( t, 0);
+ fprintf( stderr, "%*sMEM_REF t_0: ", indent - 4, " ");
+ flexible_print ( stderr, t_0, 1, (dump_flags_t)0);
+ tmasn_helper ( t_0 , indent, already);
+ return;
+ }
+ if ( TREE_CODE ( t) == INTEGER_CST ) return;
+ fprintf ( stderr, "unanticipated TREE_CODE\n");
+ gcc_assert ( 0);
+}
+
+static void
+tell_me_about_ssa_name ( tree ssa_name, int indent)
+{
+ fprintf(stderr,"about:\n");
+ std::set<tree> already;
+ tmasn_helper ( ssa_name, indent, &already);
+}
+
+static unsigned insane_helper;
+
+static void
+an_ac_helper ( tree t, int indent, std::set<tree> *already, acc_info_t *ainfo )
+{
+ gcc_assert ( insane_helper < 100 );
+ insane_helper++;
+ acc_base_info_t *binfo = &ainfo->base_info;
+ //DEBUG_A("%*s", indent, " ");
+ indent += 4;
+ //DEBUG_F( flexible_print, stderr, t, 0, (dump_flags_t)0);
+ if ( already->find (t) != already->end () )
+ {
+ //DEBUG(" <Induction>\n");
+ binfo->multi_induct =
+ binfo->multi_induct || binfo->has_induct_var_acc;
+ binfo->induct_base = t;
+ binfo->has_induct_var_acc = true;
+ return;
+ }
+ else
+ {
+ //DEBUG("\n");
+
+ }
+ //DEBUG_A("%*scode: %s\n", indent, " ", code_str(TREE_CODE (t)));
+ if ( TREE_CODE (t) == SSA_NAME )
+ {
+ already->insert (t);
+ gimple *stmt = SSA_NAME_DEF_STMT (t);
+ //DEBUG_A("%*sSSA_NAME defined in: ", indent, " ");
+ //DEBUG_F(print_gimple_stmt, stderr, stmt, TDF_DETAILS);
+ if ( SSA_NAME_IS_DEFAULT_DEF ( t ) )
+ {
+ binfo->acc_base = t;
+ binfo->complicated =
+ binfo->complicated || binfo->a_def_def || binfo->a_decl || binfo->a_func;
+ binfo->a_def_def = true;
+ }
+ if ( gimple_code ( stmt) == GIMPLE_PHI )
+ {
+ gphi *phi_stmt = dyn_cast <gphi *> ( stmt);
+ for (int i = 0; i < gimple_phi_num_args (phi_stmt); i++)
+ {
+ tree *arg = gimple_phi_arg_def_ptr (phi_stmt, i);
+ an_ac_helper ( *arg, indent, already, ainfo);
+ }
+ }
+ else
+ {
+ bool a_ass = gimple_code ( stmt) == GIMPLE_ASSIGN;
+ bool a_call = gimple_code ( stmt) == GIMPLE_CALL;
+ // This was being triggered an add: op = op + op
+ //gcc_assert ( a_ass || a_call );
+
+ if ( a_call )
+ {
+ binfo->acc_base = t;
+ binfo->complicated =
+ binfo->complicated || binfo->a_def_def || binfo->a_decl || binfo->a_func;
+ binfo->a_func = true;
+ binfo->function = stmt;
+ // Question, do we want to walk the call arguements???
+ // Because how do the arguments effect the return value?
+ // It's basically unknow so we shouldn't walk the
+ // arguemets.
+ //
+ for ( int i = 0; i < gimple_call_num_args ( stmt); i++ )
+ {
+ an_ac_helper ( gimple_call_arg ( stmt, i), indent, already, ainfo);
+ }
+ }
+ else
+ {
+ // Note, start with one to skip lhs op.
+ for ( int i = 1; i < gimple_num_ops ( stmt); i++ )
+ {
+ an_ac_helper ( gimple_op ( stmt, i), indent, already, ainfo);
+ }
+ }
+ }
+ return;
+ }
+ if ( DECL_P ( t) )
+ {
+ binfo->acc_base = t;
+ binfo->complicated =
+ binfo->complicated || binfo->a_def_def || binfo->a_decl || binfo->a_func;
+ binfo->a_decl = true;
+
+ //DEBUG_A("field (index) for a_decl: ");
+ //DEBUG_F(flexible_print, stderr, ainfo->field, 1, (dump_flags_t)0);
+
+ if ( TREE_CODE ( t) != FIELD_DECL )
+ {
+ an_ac_helper ( ainfo->field, indent, already, ainfo);
+ }
+ return;
+ }
+ if ( TREE_CODE ( t) == MEM_REF )
+ {
+ tree t_0 = TREE_OPERAND ( t, 0);
+ //DEBUG_A("%*sMEM_REF t_0: ", indent, " ");
+ //DEBUG_F(flexible_print, stderr, t_0, 1, (dump_flags_t)0);
+ an_ac_helper ( t_0 , indent, already, ainfo);
+ return;
+ }
+ if ( TREE_CODE ( t) == COMPONENT_REF )
+ {
+ tree t_0 = TREE_OPERAND ( t, 0);
+ //DEBUG_A("%*sCOMPONENT_REF t_0: ", indent, " ");
+ //DEBUG_F(flexible_print, stderr, t_0, 1, (dump_flags_t)0);
+ an_ac_helper ( t_0 , indent, already, ainfo);
+ return;
+ }
+ if ( TREE_CODE ( t) == INTEGER_CST ) return;
+ if ( TREE_CODE ( t) == ADDR_EXPR ) return;
+ fprintf ( stderr, "Unanticipated TREE_CODE\n");
+ gcc_assert ( 0);
+}
+
+static void
+analyze_access ( tree access, acc_info_t *acc_info)
+{
+ insane_helper = 0;
+ acc_base_info_t *base_info = &acc_info->base_info;
+ //DEBUG_A("analyze_access:\n");
+ base_info->a_def_def = false;
+ base_info->a_decl = false;
+ base_info->a_func = false;
+ base_info->has_induct_var_acc = false;
+ base_info->multi_induct = false;
+ base_info->complicated = false;
+ base_info->acc_base = NULL;
+ base_info->induct_base = NULL;
+ std::set<tree> already;
+ an_ac_helper ( access, 4, &already, acc_info);
+}
+
// create_new_types has to crawl "all" the
// types, create new types and transform
@@ -2527,10 +3374,10 @@ static basic_block
make_bb ( char *msg, basic_block prev_bb )
{
basic_block ret = create_empty_bb ( prev_bb);
- DEBUG_A( "make_bb ( %s, <bb %d>/%p ): <bb %d>/%p, prev: <bb %d>/%p, next: <bb %d>/%p\n",
- msg, prev_bb->index, prev_bb,
- ret->index, ret,
- ret->prev_bb->index, ret->prev_bb,
- ret->next_bb->index, ret->next_bb);
+ //DEBUG_A( "make_bb ( %s, <bb %d>/%p ): <bb %d>/%p, prev: <bb %d>/%p, next: <bb %d>/%p\n",
+ // msg, prev_bb->index, prev_bb,
+ // ret->index, ret,
+ // ret->prev_bb->index, ret->prev_bb,
+ // ret->next_bb->index, ret->next_bb);
return ret;
}
diff --git a/gcc/ipa-structure-reorg.c b/gcc/ipa-structure-reorg.c
index 639a1e876f3..96f07c11aeb 100644
--- a/gcc/ipa-structure-reorg.c
+++ b/gcc/ipa-structure-reorg.c
@@ -140,7 +140,7 @@ ipa_structure_reorg ( void)
cgraph_node* node;
FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node) node->get_untransformed_body ();
- DEBUG_F( ssa_check, stderr, Show_everything, Do_not_fail, false, true);
+ //DEBUG_F( ssa_check, stderr, Show_everything, Do_not_fail, false, true);
setup_debug_flags ( &info);
initial_debug_info ( &info);
@@ -153,10 +153,10 @@ ipa_structure_reorg ( void)
return true;
}
- DEBUG_L("after reorg_analysis\n");
+ //DEBUG_L("after reorg_analysis\n");
bool qualified = reorg_qualification(&info);
- DEBUG_L("after reorg_qualification\n");
+ //DEBUG_L("after reorg_qualification\n");
//DEBUG_L("");
//DEBUG_F(wolf_fence, &info);
@@ -186,6 +186,8 @@ ipa_structure_reorg ( void)
}
+ fprintf (stderr, "info.show_all_reorg_cands_in_detail %s\n",
+ info.show_all_reorg_cands_in_detail ? "true" : "false");
if ( info.show_all_reorg_cands_in_detail )
{
fprintf ( info.reorg_dump_file, "Qualified the following types:\n");
@@ -193,7 +195,7 @@ ipa_structure_reorg ( void)
}
reorg_common_middle_code( &info); // ??? might not amount to anything
- DEBUG_L("after reorg_common_middle_code\n");
+ //DEBUG_L("after reorg_common_middle_code\n");
//DEBUG_L("");
//DEBUG_F(wolf_fence, &info);
@@ -230,6 +232,7 @@ setup_debug_flags ( Info *info)
info->show_all_reorg_cands = true;
info->show_all_reorg_cands_in_detail = dump_flags & TDF_DETAILS;
info->show_prog_decls = true;
+ info->show_perf_qualify = true;
info->show_delete = dump_flags & TDF_DETAILS;
info->show_new_BBs = dump_flags & TDF_DETAILS;
info->show_transforms = dump_flags & TDF_DETAILS;
@@ -274,7 +277,7 @@ reorg_analysis ( Info *info)
// specified since I am not sure what this function should
// concretely do.
// Eric this is not really helping me... ;-)
- DEBUG_L("reorg_analysis: entered\n");
+ //DEBUG_L("reorg_analysis: entered\n");
#if INTEGRATION_FUNCTIONAL
const bool run_escape_analysis = flag_ipa_dead_field_eliminate && !flag_ipa_instance_interleave && !flag_ipa_field_reorder;
if (run_escape_analysis)
@@ -321,37 +324,42 @@ reorg_analysis ( Info *info)
gsi_next ( &gsi) )
{
gimple *stmt = gsi_stmt ( gsi);
- DEBUG_L ( "");
- DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
- INDENT(2);
+ //DEBUG_L ( "");
+ //DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
+ //INDENT(2);
if ( is_gimple_call ( stmt) )
{
// next line has issues but the mechanism is sound
tree t = *gimple_call_lhs_ptr ( stmt);
- DEBUG_A( "t %p\n", t);
+ //DEBUG_A( "t %p\n", t);
// Calls to a function returning void are skipped.
if ( t != NULL )
{
- DEBUG_A( "t: ");
- DEBUG_F( flexible_print, stderr, t, 1, (dump_flags_t)0);
+ //DEBUG_A( "t: ");
+ //DEBUG_F( flexible_print, stderr, t, 1, (dump_flags_t)0);
tree type = TREE_TYPE( t);
- 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);
//tree bt = base_type_of ( t);
tree bt = base_type_of ( type);
if ( TREE_CODE( bt) != RECORD_TYPE && TREE_CODE( bt) != VOID_TYPE)
{
- DEBUG_A( "TREE_CODE( bt) == %s\n", code_str( TREE_CODE ( bt)));
- DEBUG_A("");
- DEBUG_F(flexible_print, stderr, bt, 1, (dump_flags_t)0);
- INDENT(-2);
+ //DEBUG_A( "TREE_CODE( bt) == %s\n", code_str( TREE_CODE ( bt)));
+ //DEBUG_A("");
+ //DEBUG_F(flexible_print, stderr, bt, 1, (dump_flags_t)0);
+ //INDENT(-2);
continue;
}
if ( TREE_CODE( bt) == VOID_TYPE )
{
- // find the use of lhs. If is an assign
+ // Find the use of lhs. If is an assign
// get use the base type of it's lhs.
- // Otherwise never mind.
+ // Otherwise never mind. Note, there
+ // can be multiple uses but find the "one"
+ // that's a simple assignment to a typed
+ // variable.
+
+ #if 0
gimple *use_stmt;
use_operand_p immuse;
bool yup_a_use = single_imm_use ( t, &immuse, &use_stmt);
@@ -364,19 +372,58 @@ reorg_analysis ( Info *info)
{
tree use_lhs = gimple_assign_lhs ( use_stmt);
bt = base_type_of ( TREE_TYPE ( use_lhs));
+ //DEBUG_A("found bt: ");
+ //DEBUG_F(flexible_print, stderr, bt, 1, (dump_flags_t)0);
}
else
- continue;
+ {
+ //DEBUG_A("bailed on base type of complicated case\n");
+ //INDENT(-2);
+ continue;
+ }
+ #endif
+
+ tree ssa_name = gimple_call_lhs( stmt);
+ gimple *use_stmt;
+ imm_use_iterator iter;
+ int num_bt = 0;
+ FOR_EACH_IMM_USE_STMT ( use_stmt, iter, ssa_name)
+ {
+ //DEBUG_A("use_stmt: ");
+ //DEBUG_F ( print_gimple_stmt, stderr, use_stmt, 0);
+ if ( is_assign_from_ssa ( use_stmt ) )
+ {
+ //DEBUG_A("is assign from ssa\n");
+ tree lhs_assign = gimple_assign_lhs( use_stmt);
+ tree lhs_type = TREE_TYPE ( lhs_assign);
+ tree lhs_base_type = base_type_of ( lhs_type);
+ if ( TREE_CODE( lhs_base_type) != VOID_TYPE )
+ {
+ //DEBUG_A("not void\n");
+ num_bt++;
+ bt = lhs_base_type;
+ }
+ }
+ }
+ if ( num_bt != 1 )
+ {
+ //DEBUG_L("bailed on base type of complicated case\n");
+ //INDENT(-2);
+ continue;
+ }
}
+
+
+ bool alloc_trigger = is_reorg_alloc_trigger ( stmt);
// 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) )
+ if ( ri != NULL && alloc_trigger )
{
- DEBUG_L( "Found allocaion: \n");
- DEBUG_A( " Reorg: ");
- DEBUG_F( print_reorg, stderr, 0, ri);
- DEBUG("\n");
+ //DEBUG_L( "Found allocaion: \n");
+ //DEBUG_A( " Reorg: ");
+ //DEBUG_F( print_reorg, stderr, 0, ri);
+ //DEBUG("\n");
// TBD this needs to increment with the execution count
// instead of one. I hope the build-in block count estimation
// will work or a DIY solution might be called for.
@@ -384,13 +431,13 @@ reorg_analysis ( Info *info)
}
}
}
- INDENT(-2);
+ //INDENT(-2);
}
}
}
- DEBUG_L( "possible deletes:\n");
- INDENT(2);
+ //DEBUG_L( "possible deletes:\n");
+ //INDENT(2);
// It's LOT more clear to use an iterator here TBD
for ( int i = 0; i < info->reorg_type->size (); i++ )
{
@@ -403,13 +450,21 @@ reorg_analysis ( Info *info)
}
// Note when multi-pools are enabled the test should be
// "n == 0" but until then...
- DEBUG_A("%d pools\n",n)
+ //DEBUG_A("%d pools\n",n)
if ( n != 1 )
{
+ if ( info->show_all_reorg_cands_in_detail )
+ {
+ fprintf ( info->reorg_dump_file, "Delete ReorgType: ");
+ flexible_print ( info->reorg_dump_file,
+ (*(info->reorg_type))[i].gcc_type,
+ 0, (dump_flags_t)0);
+ fprintf ( info->reorg_dump_file, ", it has %d pools\n", n);
+ }
delete_reorgtype ( &(*(info->reorg_type))[i], info);
}
}
- INDENT(-2);
+ //INDENT(-2);
//DEBUG_L("after reorg_analysis\n");
remove_deleted_types ( info, &reorg_analysis_debug);
@@ -468,7 +523,9 @@ find_decls_and_types ( Info *info)
if ( TREE_CODE ( base) == RECORD_TYPE )
{
// skip if found before
- if ( typeset.find ( base) != typeset.end () )
+ tree tmv_type = TYPE_MAIN_VARIANT ( base);
+ tree tmv_base = tmv_type ? tmv_type : base;
+ if ( typeset.find ( tmv_base) != typeset.end () )
{
//DEBUG_L( " not found\n");
continue;
@@ -478,9 +535,9 @@ find_decls_and_types ( Info *info)
}
#if USE_REORG_TYPES
- add_reorg_type ( base, info);
+ add_reorg_type ( tmv_base, info);
#endif
- typeset.insert ( base); // ???
+ typeset.insert ( tmv_base); // ???
}
}
@@ -515,16 +572,18 @@ find_decls_and_types ( Info *info)
if ( TREE_CODE ( base) == RECORD_TYPE)
{
- if ( typeset.find ( base) != typeset.end () )
+ tree tmv_type = TYPE_MAIN_VARIANT ( base);
+ tree tmv_base = tmv_type ? tmv_type : base;
+ if ( typeset.find ( tmv_base) != typeset.end () )
{
//INDENT(-2)
continue;
}
#if USE_REORG_TYPES
- add_reorg_type ( base, info);
+ add_reorg_type ( tmv_base, info);
#endif
- typeset.insert ( base); // ???
+ typeset.insert ( tmv_base); // ???
}
}
//INDENT(-2);
@@ -720,6 +779,8 @@ find_decls_and_types ( Info *info)
static void
add_reorg_type ( tree base, Info *info)
{
+ tree tmv_type = TYPE_MAIN_VARIANT ( base);
+ tree type2add = tmv_type ? tmv_type : base;
ReorgType_t rt =
{ 0, true, base, NULL, NULL, false, false, false,
{ 0}, { 0}, { 0, 0, 0, NULL, 0.0, 0.0, false}};
@@ -845,11 +906,19 @@ disq_str_in_str_or_union_helper ( tree type,
//tree base = base_type_of ( field_type);
if ( TREE_CODE ( field_type) == RECORD_TYPE ) // base to field type
{
- DEBUG( "RECORD\n");
+ //DEBUG( "RECORD\n");
ReorgType_t *rinfo = get_reorgtype_info ( field_type, info); // base to field type
if ( rinfo != NULL )
{
+ if ( info->show_all_reorg_cands_in_detail )
+ {
+ fprintf ( info->reorg_dump_file, "Delete ReorgType: ");
+ flexible_print ( info->reorg_dump_file,
+ rinfo->gcc_type,
+ 0, (dump_flags_t)0);
+ fprintf ( info->reorg_dump_file, ", Structure in structure.\n");
+ }
delete_reorgtype ( rinfo, info);
} else {
disq_str_in_str_or_union_helper ( field_type, typeset, info ); // base to field type
@@ -922,7 +991,11 @@ transformation_legality ( Info *info)
// GIMPLE_IL sizeof tree expr
// memmove(&astruct_1, &astruct_2, sizeof(struct astruct_s));
// memmove(&astruct_1.b, &astruct_2.b, 2*sizeof(_Bool));
- const bool run_escape_analysis = flag_ipa_dead_field_eliminate && !flag_ipa_instance_interleave && !flag_ipa_field_reorder;
+ const bool run_escape_analysis =
+ flag_ipa_dead_field_eliminate &&
+ !flag_ipa_instance_interleave &&
+ !flag_ipa_field_reorder;
+
if (run_escape_analysis)
{
bool retval = !info->is_non_escaping_set_empty();
@@ -953,7 +1026,8 @@ transformation_legality ( Info *info)
case Not_Supported:
//DEBUG_L("deleting %d reorgs for unsuported stmt: ", num);
//DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
- disqualify_all_reorgtypes_of ( stmt, num, info);
+ // TBD This is not working
+ //disqualify_all_reorgtypes_of ( stmt, num, info);
case ReorgT_UserFunc:
// TBD ReorgT_Ptr2Zero does not catch all cases of
// setting a reorg pointer to zero. One that I
@@ -1005,6 +1079,7 @@ transformation_legality_debug ( Info *info, ReorgType *reorg )
static void
reorg_common_middle_code ( Info *info)
{
+ if ( BYPASS_TRANSFORM ) return;
modify_declarations( info);
}
@@ -1098,13 +1173,26 @@ modify_declarations ( Info *info)
static void
disqualify_all_reorgtypes_of ( gimple *stmt, int num, Info *info)
{
- DEBUG_L("disqualify %d reorgtypes of: ", num);
- DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
+ //DEBUG_L("disqualify %d reorgtypes of: ", num);
+ //DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
+ if ( info->show_all_reorg_cands_in_detail )
+ {
+ print_gimple_stmt( info->reorg_dump_file, stmt, 0);
+ }
int i;
for ( i = 0; i < num; i++ )
{
ReorgType_t *reorg_type =
get_reorgtype ( stmt, info, i);
+ //DEBUG_A( "reorg_type = %p\n", reorg_type);
+ if ( info->show_all_reorg_cands_in_detail )
+ {
+ fprintf ( info->reorg_dump_file, " Delete ReorgType: ");
+ flexible_print ( info->reorg_dump_file,
+ (*(info->reorg_type))[i].gcc_type,
+ 0, (dump_flags_t)0);
+ fprintf ( info->reorg_dump_file, ", because of gimple above.\n");
+ }
delete_reorgtype ( reorg_type, info);
}
}
@@ -1128,9 +1216,9 @@ static tree
modify_func_type ( struct function *func, Info *info )
{
tree func_type = TREE_TYPE ( func->decl);
- DEBUG_L("old func_type = ");
- DEBUG_F( flexible_print, stderr, func_type, 1, (dump_flags_t)0);
- INDENT(4);
+ //DEBUG_L("old func_type = ");
+ //DEBUG_F( flexible_print, stderr, func_type, 1, (dump_flags_t)0);
+ //INDENT(4);
tree new_type;
tree func_ret_type = TREE_TYPE ( func_type);
tree base = base_type_of ( func_ret_type);
@@ -1170,13 +1258,14 @@ modify_func_type ( struct function *func, Info *info )
ri = get_reorgtype_info ( base, info);
if ( ri != NULL )
{
+ int levels = number_of_levels ( type_of_arg );
if ( number_of_levels ( type_of_arg ) == 1 )
{
new_arg_type = TYPE_MAIN_VARIANT ( ri->pointer_rep);
}
else
{
- gcc_assert(0);
+ new_arg_type = make_multilevel ( ri->pointer_rep, levels);
}
}
else
@@ -1193,13 +1282,13 @@ modify_func_type ( struct function *func, Info *info )
new_args = nreverse ( new_args);
TREE_CHAIN ( last) = void_list_node;
- DEBUG_A("new args = ");
- DEBUG_F( flexible_print, stderr, new_args, 1, (dump_flags_t)0);
- INDENT(-4);
+ //DEBUG_A("new args = ");
+ //DEBUG_F( flexible_print, stderr, new_args, 1, (dump_flags_t)0);
+ //INDENT(-4);
new_type = build_function_type ( func_ret_type, new_args);
- DEBUG_L("new_type (func) = ");
- DEBUG_F( flexible_print, stderr, new_type, 1, (dump_flags_t)0);
+ //DEBUG_L("new_type (func) = ");
+ //DEBUG_F( flexible_print, stderr, new_type, 1, (dump_flags_t)0);
TREE_TYPE ( func->decl) = new_type;
return new_type;
}
@@ -1237,6 +1326,18 @@ tree prev_type;
return levels;
}
+tree
+make_multilevel( tree base_type, int levels_indirection)
+{
+ if ( levels_indirection == 0 )
+ return base_type;
+ else
+ {
+ tree lower = make_multilevel ( base_type, levels_indirection - 1);
+ return build_pointer_type ( lower);
+ }
+}
+
static bool
modify_func_decl_core ( struct function *func, Info *info)
{
@@ -1429,14 +1530,14 @@ modify_decl_core ( tree *location, Info *info)
void
delete_reorgtype ( ReorgType_t *rt, Info *info )
{
- DEBUG_L( "delete_reorgtype( %s ):", type_name_to_str( TYPE_NAME( rt->gcc_type)));
+ //DEBUG_L( "delete_reorgtype( %s ):", type_name_to_str( TYPE_NAME( rt->gcc_type)));
if ( !rt->delete_me )
{
- DEBUG( "TO DELETE\n");
+ //DEBUG( "TO DELETE\n");
info->num_deleted++;
rt->delete_me = true;
} else {
- DEBUG( "SKIP\n");
+ //DEBUG( "SKIP\n");
}
}
@@ -1457,38 +1558,40 @@ undelete_reorgtype ( ReorgType_t *rt, Info *info )
ReorgTransformation
reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info )
{
- DEBUG_L ( "ReorgTransformation reorg_recognize for: ");
- DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
- INDENT(2);
+ //DEBUG_L ( "ReorgTransformation reorg_recognize for: ");
+ //DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
+ //INDENT(2);
switch ( gimple_code( stmt) )
{
case GIMPLE_ASSIGN:
{
- DEBUG_L("GIMPLE_ASSIGN:\n");
+ //DEBUG_L("GIMPLE_ASSIGN:\n");
tree lhs = gimple_assign_lhs ( stmt);
enum tree_code rhs_code = gimple_assign_rhs_code ( stmt);
if ( gimple_assign_single_p ( stmt) )
{
- DEBUG_L("gimple_assign_single_p() = true\n");
- INDENT(2);
+ //DEBUG_L("gimple_assign_single_p() = true\n");
+ //INDENT(2);
tree rhs = gimple_assign_rhs1 ( stmt);
- enum ReorgOpTrans lhs_op = recognize_op ( lhs, info);
+ enum ReorgOpTrans lhs_op = recognize_op ( lhs, true, info);
switch ( lhs_op )
{
case ReorgOpT_Pointer: // "a"
- DEBUG_L("case ReorgOpT_Pointer\n");
- INDENT(-4);
- switch ( recognize_op ( rhs, info) )
+ //DEBUG_L("case ReorgOpT_Pointer\n");
+ //INDENT(-4);
+ switch ( recognize_op ( rhs, true, info) )
{
case ReorgOpT_Scalar:
- if ( integer_zerop ( rhs) )
{
- return ReorgT_Ptr2Zero;
+ if ( integer_zerop ( rhs) )
+ {
+ return ReorgT_Ptr2Zero;
+ }
+ // If we get here this is clearly really odd code
+ // so we need to bail out.
+ return Not_Supported;
}
- // If we get here this is clearly really odd code
- // so we need to bail out.
- return Not_Supported;
case ReorgOpT_Temp: // t
return ReorgT_ElemAssign;
case ReorgOpT_Address: // "&x[i]"
@@ -1497,9 +1600,9 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info )
return Not_Supported;
}
case ReorgOpT_Struct: // "s"
- DEBUG_L("case ReorgOpT_Struct\n");
- INDENT(-4);
- switch ( recognize_op ( rhs, info) )
+ //DEBUG_L("case ReorgOpT_Struct\n");
+ //INDENT(-4);
+ switch ( recognize_op ( rhs, true, info) )
{
case ReorgOpT_Deref: // "*a"
case ReorgOpT_Array: // "x[i]"
@@ -1514,9 +1617,9 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info )
return Not_Supported;
}
case ReorgOpT_Deref: // "*a"
- DEBUG_L("case ReorgOpT_Deref\n");
- INDENT(-4);
- switch ( recognize_op ( rhs, info) )
+ //DEBUG_L("case ReorgOpT_Deref\n");
+ //INDENT(-4);
+ switch ( recognize_op ( rhs, true, info) )
{
case ReorgOpT_Deref: // "*a"
case ReorgOpT_Struct: // "s"
@@ -1526,9 +1629,9 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info )
return Not_Supported;
}
case ReorgOpT_Array: // "x[i]"
- DEBUG_L("case ReorgOpT_Array\n");
- INDENT(-4);
- switch ( recognize_op ( rhs, info) )
+ //DEBUG_L("case ReorgOpT_Array\n");
+ //INDENT(-4);
+ switch ( recognize_op ( rhs, true, info) )
{
case ReorgOpT_Struct: // "s"
case ReorgOpT_Deref: // "*a"
@@ -1539,9 +1642,9 @@ 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);
- switch ( recognize_op( rhs, info) )
+ //DEBUG_L("case ReorgOpT_%s\n", lhs_op == ReorgOpT_Temp ? "Temp" : "Scalar");
+ //INDENT(-4);
+ switch ( recognize_op( rhs, true, info) )
{
case ReorgOpT_Scalar: // "z"
case ReorgOpT_Temp: // "t"
@@ -1553,43 +1656,44 @@ 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);
- switch ( recognize_op ( rhs, info) )
+ //DEBUG_L("case ReorgOpT_%s\n", lhs_op == ReorgOpT_Indirect ? "Indirect" : "AryDir");
+ //INDENT(-4);
+ switch ( recognize_op ( rhs, true, info) )
{
+ case ReorgOpT_Cst: // k
case ReorgOpT_Temp: // t
case ReorgOpT_Scalar: // "z"
case ReorgOpT_Indirect: // "a->f"
case ReorgOpT_AryDir: // "x[i].f"
return ReorgT_ElemAssign;
+ case ReorgOpT_Cst0:
+ return ReorgT_Ptr2Zero;
default:
return Not_Supported;
}
default:
- INDENT(-4);
+ //INDENT(-4);
return Not_Supported;
- } // switch ( recognize_op ( lhs, info) )
+ } // 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( print_generic_expr, stderr, op1, (dump_flags_t)-1);
- DEBUG("\n");
-
+ //DEBUG_L("op1 = %p, op2 = %p\n", op1, op2);
+ //DEBUG_A("");
+ //DEBUG_F( flexible_print, stderr, op1, 1, TDF_DETAILS);
if ( CONVERT_EXPR_CODE_P ( gimple_assign_rhs_code ( stmt)))
{
- DEBUG_L("CONVERT_EXPR_CODE_P (...)\n");
- INDENT(-4);
+ //DEBUG_L("CONVERT_EXPR_CODE_P (...)\n");
+ //INDENT(-4);
return ReorgT_Convert;
}
if ( gimple_assign_rhs3 ( stmt) != NULL )
{
- DEBUG_L("gimple_assign_rhs3 ( stmt) != NULL\n");
- INDENT(-4);
+ //DEBUG_L("gimple_assign_rhs3 ( stmt) != NULL\n");
+ //INDENT(-4);
return Not_Supported;
}
@@ -1599,8 +1703,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:
@@ -1658,12 +1762,12 @@ 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");
- INDENT(-2);
+ //DEBUG_L("called function %s gimple_body\n",
+ // edge->callee->has_gimple_body_p() ? "has a" : "has no");
+ //INDENT(-2);
if ( gimple_call_builtin_p( stmt, BUILT_IN_CALLOC ) ) return ReorgT_Calloc;
if ( gimple_call_builtin_p( stmt, BUILT_IN_MALLOC ) ) return ReorgT_Malloc;
if ( gimple_call_builtin_p( stmt, BUILT_IN_REALLOC) ) return ReorgT_Realloc;
@@ -1683,15 +1787,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 ReorgT_Return;
break;
default:
- DEBUG_L ( "didn't support: ");
- DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
- DEBUG( "\n");
- INDENT(-2);
+ //DEBUG_L ( "didn't support: ");
+ //DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
+ //DEBUG( "\n");
+ //INDENT(-2);
return Not_Supported;
}
}
@@ -1796,76 +1900,133 @@ remove_deleted_types ( Info *info, ReorgFn reorg_fn)
}
enum ReorgOpTrans
-recognize_op ( tree op, Info *info)
+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));
- if ( op_code == SSA_NAME )
+ //DEBUG_A("opcode = %s\n", code_str( op_code));
+ switch ( op_code )
{
+ case SSA_NAME:
// We tried returning ReorgOpT_Scalar.
// It caused an assertion failue because
// it was incorrectly triggering the ReorgT_Ptr2Zero
// case with a bogus RHS.
- DEBUG_L(" returns: ReorgOpT_Temp\n");
+ //DEBUG_L(" returns: ReorgOpT_Temp\n");
return ReorgOpT_Temp;
+ case INTEGER_CST:
+ if ( integer_zerop ( op) )
+ {
+ //DEBUG_A(" returns: ReorgOpT_Cst0\n");
+ return ReorgOpT_Cst0;
+ }
+ case REAL_CST:
+ case FIXED_CST:
+ case STRING_CST:
+ case COMPLEX_CST:
+ case CONSTRUCTOR:
+ case VECTOR_CST:
+ {
+ //DEBUG_A(" returns: ReorgOpT_Cst\n");
+ return ReorgOpT_Cst;
+ }
}
+
tree type = TREE_TYPE ( op);
+ // This type bases approach seems like crap.
+ // I'm turning it off to see what breaks.
+ #if 0
if ( type != NULL && POINTER_TYPE_P (type) )
{
- DEBUG_L("POINTER_TYPE_P (type) = true\n");
- if ( is_reorg_type ( type, info) )
+ //DEBUG_L("POINTER_TYPE_P (type) = true\n");
+ bool a_reorg = is_reorg_type ( type, info);
+ if ( a_reorg || !lie )
{
- DEBUG_L(" returns: ReorgOpT_Pointer\n");
+ //DEBUG_L(" returns: ReorgOpT_Pointer\n");
return ReorgOpT_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.
- DEBUG_L(" returns: ReorgOpT_Scalar\n");
+ //DEBUG_L(" returns: ReorgOpT_Scalar\n");
return ReorgOpT_Scalar;
}
}
+ #endif
// This might not occur in practice
if ( op_code == RECORD_TYPE )
{
// The assumption here is that this
// is a reorg type.
- DEBUG_L(" returns: ReorgOpT_Struct\n");
+ //DEBUG_A(" returns: ReorgOpT_Struct\n");
return ReorgOpT_Struct;
}
if ( op_code == VAR_DECL )
{
tree type = TREE_TYPE ( op);
- DEBUG_L(" recursing on type :");
- DEBUG_F( flexible_print, stderr, type, 1, TDF_DETAILS);
- return recognize_op ( type, info);
+ gcc_assert ( type != NULL );
+ if ( POINTER_TYPE_P (type) )
+ {
+ bool a_reorg = is_reorg_type ( type, info);
+ if ( a_reorg || !lie )
+ {
+ //DEBUG_A(" returns: ReorgOpT_Pointer\n");
+ return ReorgOpT_Pointer;
+ }
+ else
+ {
+ // This would be for when the field of a struct
+ // element is a pointer that's not a reorg
+ // pointer. I.e. ReorgT_ElemAssign. That is
+ // this is while lie for a good purpose.
+ //DEBUG_L(" returns: ReorgOpT_Scalar\n");
+ return ReorgOpT_Scalar;
+ }
+ }
+ //DEBUG_L(" returns: ReorgOpT_Scalar\n");
+ return ReorgOpT_Scalar;
}
tree inner_op = TREE_OPERAND( op, 0);
tree inner_type = TREE_TYPE ( inner_op);
enum tree_code inner_op_code = TREE_CODE ( inner_op);
//DEBUG_L("inner_op = ");
- //DEBUG_F( print_generic_expr, stderr, inner_op, TDF_DETAILS);
- //DEBUG(", TREE_CODE = %s\n", code_str( TREE_CODE(inner_op)));
+ //DEBUG_F(flexible_print, stderr, inner_op, 0, (dump_flags_t)0);
+ //DEBUG(", TREE_CODE = %s\n", code_str( inner_op_code));
if ( op_code == ADDR_EXPR )
{
//DEBUG_L("op_code == ADDR_EXPR\n");
- if ( inner_op_code == ARRAY_REF
- && is_reorg_type ( inner_op, info) )
+ if ( inner_op_code == ARRAY_REF )
+ {
+ bool a_reorg = is_reorg_type ( inner_op, info);
+ if ( a_reorg || !lie )
+ {
+ //DEBUG_L(" returns: ReorgOpT_Address\n");
+ return ReorgOpT_Address;
+ }
+ }
+ // TBD shouldn't we be testing for a reorg???
+ if ( inner_op_code == VAR_DECL )
{
- //DEBUG_L(" returns: ReorgOpT_Address\n");
- return ReorgOpT_Address;
+ tree var_type = TREE_TYPE ( inner_op );
+ bool a_reorg = is_reorg_type ( var_type, info);
+ if ( a_reorg || !lie )
+ {
+ //DEBUG_L(" returns: ReorgOpT_Address\n");
+ return ReorgOpT_Address;
+ }
}
}
if ( op_code == COMPONENT_REF )
{
//DEBUG_L("op_code == COMPONENT_REF\n");
+
if ( inner_op_code == INDIRECT_REF )
{
//DEBUG_L("TREE_CODE( inner_op) == INDIRECT_REF\n");
- if ( is_reorg_type ( base_type_of ( type), info) ) // inner_type???
+ bool a_reorg = is_reorg_type ( base_type_of ( type), info);
+ if ( a_reorg || !lie )
{
//DEBUG_L(" returns: ReorgOpT_Indirect\n");
return ReorgOpT_Indirect;
@@ -1876,7 +2037,8 @@ recognize_op ( tree op, Info *info)
}
if ( inner_op_code == MEM_REF ) {
//DEBUG_L("TREE_CODE( inner_op) == MEM_REF\n");
- if ( is_reorg_type ( base_type_of ( inner_type), info) )
+ bool a_reorg = is_reorg_type ( base_type_of ( inner_type), info);
+ if ( a_reorg || !lie )
{
//DEBUG_L(" returns: ReorgOpT_Indirect\n");
return ReorgOpT_Indirect;
@@ -1885,13 +2047,14 @@ recognize_op ( tree op, Info *info)
//DEBUG_L(" returns: ReorgOpT_Scalar\n");
return ReorgOpT_Scalar;
}
- DEBUG_L("TREE_CODE( inner_op) not INDIRECT_REF or MEM_REF\n");
+ //DEBUG_L("TREE_CODE( inner_op) not INDIRECT_REF 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.
- if ( is_reorg_type ( base_type_of ( inner_type), info) )
+ bool a_reorg = is_reorg_type ( base_type_of ( inner_type), info);
+ if ( a_reorg || !lie )
{
- //DEBUG_L(" returns: ReorgOpT_AryDir\n");
+ //DEBUG_A(" returns: ReorgOpT_AryDir\n");
return ReorgOpT_AryDir;
}
// Just normal field reference otherwise...
@@ -1901,9 +2064,10 @@ recognize_op ( tree op, Info *info)
if ( op_code == ARRAY_REF )
{
//DEBUG_L("op_code == ARRAY_REF\n");
- if ( is_reorg_type( base_type_of ( type), info) )
+ bool a_reorg = is_reorg_type( base_type_of ( type), info);
+ if ( a_reorg || !lie )
{
- //DEBUG_L(" returns: ReorgOpT_Array\n");
+ //DEBUG_A(" returns: ReorgOpT_Array\n");
return ReorgOpT_Array;
}
//DEBUG_L(" returns: ReorgOpT_Scalar\n");
@@ -1915,9 +2079,10 @@ recognize_op ( tree op, Info *info)
// 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) )
+ bool a_reorg = is_reorg_type ( type, info);
+ if( a_reorg || !lie )
{
- //DEBUG_L(" returns: ReorgOpT_Deref\n");
+ //DEBUG_A(" returns: ReorgOpT_Deref\n");
return ReorgOpT_Deref;
}
//DEBUG_L(" returns: ReorgOpT_Scalar\n");
@@ -1930,6 +2095,8 @@ recognize_op ( tree op, Info *info)
bool
is_reorg_type( tree rt, Info *info )
{
+ tree tmv_type = TYPE_MAIN_VARIANT ( rt);
+ tree type2check = tmv_type ? tmv_type : rt;
return get_reorgtype_info ( rt, info) != NULL;
}
@@ -2082,12 +2249,16 @@ bool same_type_p( tree a, tree b )
ReorgType_t *
get_reorgtype_info ( tree type, Info* info)
{
- DEBUG_L( "get_reorgtype_info\n");
+ //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
// certainly correct. It will also almost certainly need to be
// improved but I get something out there now.
+
+ tree tmv_type = TYPE_MAIN_VARIANT ( type);
+ tree type2check = tmv_type ? tmv_type : type;
for ( std::vector<ReorgType_t>::iterator ri = info->reorg_type->begin ();
ri != info->reorg_type->end ();
ri++ )
@@ -2097,17 +2268,17 @@ 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");
- if ( same_type_p ( ri->gcc_type, type) )
+ //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));
+ //DEBUG_A( " returns %p\n", &(*ri));
return &(*ri);
}
}
- DEBUG_A( " returns NULL\n");
+ //DEBUG_A( " returns NULL\n");
return NULL;
}
@@ -2124,9 +2295,9 @@ detect_reorg ( tree *tp, int *dummy, void *data)
{
struct walk_stmt_info *walk_data = ( struct walk_stmt_info *)data;
hidden_info_t *hi = ( hidden_info_t *)walk_data->info;
- DEBUG_L( "*tp = ");
- DEBUG_F( print_generic_expr, stderr, *tp, (dump_flags_t)-1);
- DEBUG("\n");
+ //DEBUG_L( "*tp = ");
+ //DEBUG_F( print_generic_expr, stderr, *tp, (dump_flags_t)-1);
+ //DEBUG("\n");
tree operand = base_type_of ( TREE_TYPE ( *tp));
ReorgType_t *ri = get_reorgtype_info ( operand, hi->info);
if ( ri != NULL )
@@ -2140,13 +2311,13 @@ detect_reorg ( tree *tp, int *dummy, void *data)
ReorgType_t *
contains_a_reorgtype ( gimple *stmt, Info *info)
{
- DEBUG_L ( "contains_a_reorgtype: ");
- DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
- INDENT(2);
+ //DEBUG_L ( "contains_a_reorgtype: ");
+ //DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
+ //INDENT(2);
if ( gimple_code ( stmt) == GIMPLE_PHI )
{
- INDENT(-2);
+ //INDENT(-2);
tree base = base_type_of ( TREE_TYPE ( PHI_RESULT ( stmt)));
return get_reorgtype_info ( base, info);
}
@@ -2161,7 +2332,7 @@ contains_a_reorgtype ( gimple *stmt, Info *info)
walk_gimple_op ( stmt,
detect_reorg,
&walk_info);
- INDENT(-2);
+ //INDENT(-2);
return hi.found_reorg;
}
}
@@ -2176,7 +2347,8 @@ detect_reorg_in_expr ( tree *tp, int *w_s, void *data)
//DEBUG_F( flexible_print, stderr, TREE_TYPE ( *tp), 1, (dump_flags_t)0);
tree operand = base_type_of ( TREE_TYPE ( *tp));
//DEBUG_L("operand = %p, ", operand);
- DEBUG_F( flexible_print, stderr, operand, 1, (dump_flags_t)0);
+
+ //DEBUG_F( flexible_print, stderr, operand, 1, (dump_flags_t)0);
ReorgType_t *ri = get_reorgtype_info ( operand, tre_hi->info);
if ( ri != NULL )
{
@@ -2244,26 +2416,34 @@ print_base_reorg ( FILE *file, int leading_space, ReorgType_t *reorg, bool detai
= identifier_to_locale ( IDENTIFIER_POINTER ( TYPE_NAME ( reorg->gcc_type)));
fprintf ( file, "%*s{ type:%s, #%d, ", leading_space, "",text, reorg->id);
- if( reorg->do_dead_field_elim ) {
- fprintf ( file, "elim:{ ");
- // TBD
- fprintf ( file, "}, ");
- }
+ if ( reorg->do_dead_field_elim )
+ {
+ fprintf ( file, "elim:{ ");
+ // TBD
+ fprintf ( file, "}, ");
+ }
- if( reorg->do_field_reorder ) {
- fprintf ( file, "reorder:{ ");
- // TBD
- fprintf ( file, "}, ");
- }
+ if ( reorg->do_field_reorder )
+ {
+ fprintf ( file, "reorder:{ ");
+ // TBD
+ fprintf ( file, "}, ");
+ }
+
+ if ( reorg->do_instance_interleave )
+ {
+ fprintf ( file, "inter:{ ");
+ // TBD
+ fprintf ( file, "%s, ",
+ reorg->instance_interleave.multi_pool ? "multi" : "single" );
+ // TBD When multi-pool implemented (and found) emit pointer_rep.
+ fprintf ( file, "}, ");
+ }
+ else
+ {
+ fprintf ( file, "no interleave, ");
+ }
- if( reorg->do_instance_interleave ) {
- fprintf ( file, "inter:{ ");
- // TBD
- fprintf ( file, "%s, ",
- reorg->instance_interleave.multi_pool ? "multi" : "single" );
- // TBD When multi-pool implemented (and found) emit pointer_rep.
- fprintf ( file, "}, ");
- }
if ( reorg->reorg_ver_type != NULL )
{
// TBD does this belong here? How will the clone be done with elim and
@@ -2468,6 +2648,8 @@ print_function ( FILE *file, int leading_space, struct function *func)
ReorgType_t *
get_reorgtype( gimple *stmt, Info *info, int i)
{
+ //DEBUG_A("get_reorgtype: i = %d, stmt = ", i);
+ //DEBUG_F(print_gimple_stmt, stderr, stmt, 0);
// Looking at operands of statement, when we get to
// the ith one, return it.
int num_reorgs = 0;
@@ -2477,11 +2659,37 @@ get_reorgtype( gimple *stmt, Info *info, int i)
{
tree op = gimple_op ( stmt, j);
if ( tree_contains_a_reorgtype_p ( op, info) ) {
- num_reorgs++;
if ( num_reorgs == i )
{
- return get_reorgtype_info ( op, info);
+ //DEBUG_A("op = ");
+ //DEBUG_F( flexible_print, stderr, op, 1, (dump_flags_t)0);
+
+ if ( TREE_CODE ( op) == COMPONENT_REF )
+ {
+ tree field_op = TREE_OPERAND ( op, 1);
+ tree field_type = TREE_TYPE ( field_op);
+ tree base_field_type = base_type_of ( field_type);
+ //DEBUG_A("field_op = ");
+ //DEBUG_F( flexible_print, stderr, field_op, 1, (dump_flags_t)0);
+ //DEBUG_A("field_type = ");
+ //DEBUG_F( flexible_print, stderr, field_type, 1, (dump_flags_t)0);
+ //DEBUG_A("base_field_type = ");
+ //DEBUG_F( flexible_print, stderr, base_field_type, 1, (dump_flags_t)0);
+ return get_reorgtype_info ( base_field_type, info);
+ }
+ else
+ {
+ tree op_type = TREE_TYPE ( op);
+ tree op_base_type = base_type_of ( op_type);
+ //DEBUG_A("op_type = ");
+ //DEBUG_F( flexible_print, stderr, op_type, 1, (dump_flags_t)0);
+ //DEBUG_A("op_base_type = ");
+ //DEBUG_F( flexible_print, stderr, op_base_type, 1, (dump_flags_t)0);
+
+ return get_reorgtype_info ( op_base_type, info);
+ }
}
+ num_reorgs++;
}
}
gcc_assert ( 0);
@@ -2581,6 +2789,22 @@ modify_ssa_name_type ( tree ssa_name, tree type)
}
}
+bool
+is_assign_from_ssa ( gimple *stmt )
+{
+ if ( is_gimple_assign ( stmt) )
+ {
+ //DEBUG_A("is gimple assign\n");
+ if ( gimple_assign_rhs_class ( stmt) == GIMPLE_SINGLE_RHS )
+ {
+ //DEBUG_A("has single rhs\n");
+ if ( TREE_CODE ( gimple_assign_rhs1 ( stmt)) == SSA_NAME )
+ return true;
+ }
+ }
+ return false;
+}
+
//-- debugging only --
//static const char *
#if DEBUGGING
@@ -2640,6 +2864,33 @@ type_name_to_str ( tree tn)
return identifier_to_locale ( IDENTIFIER_POINTER ( tn));
}
+const char *
+optrans_to_str ( enum ReorgOpTrans e )
+{
+ switch ( e )
+ {
+ case ReorgOpT_Temp:
+ return "Temp";
+ case ReorgOpT_Address:
+ return "Address";
+ case ReorgOpT_Pointer:
+ return "Pointer";
+ case ReorgOpT_Struct:
+ return "Struct";
+ case ReorgOpT_Deref:
+ return "Deref";
+ case ReorgOpT_Array:
+ return "Array";
+ case ReorgOpT_Scalar:
+ return "Scalar";
+ case ReorgOpT_Indirect:
+ return "Indirect";
+ case ReorgOpT_AryDir:
+ return "AryDir";
+ }
+ return NULL;
+}
+
#if DEBUGGING
void
handle_debug_indenting ( int amount )
diff --git a/gcc/ipa-structure-reorg.h b/gcc/ipa-structure-reorg.h
index 8454c42dd89..0a3a87e3088 100644
--- a/gcc/ipa-structure-reorg.h
+++ b/gcc/ipa-structure-reorg.h
@@ -28,6 +28,8 @@ along with GCC; see the file COPYING3. If not see
#define USE_REORG_TYPES 1
// If PRINT_FORMAT is true use pass specific print format.
#define PRINT_FORMAT false
+// Trun off actual transformations for testing
+#define BYPASS_TRANSFORM false
typedef struct RT_Elim RT_Elim;
typedef struct RT_Reorder RT_Reorder;
@@ -99,7 +101,9 @@ enum ReorgOpTrans {
ReorgOpT_Array, // "x[i]"
ReorgOpT_Scalar, // "z"
ReorgOpT_Indirect, // "a->f"
- ReorgOpT_AryDir // "x[i].f"
+ ReorgOpT_AryDir, // "x[i].f"
+ ReorgOpT_Cst,
+ ReorgOpT_Cst0
};
enum CompressionControl {
@@ -160,6 +164,7 @@ struct Info {
// TODO: What is the meaning of reorg type?
// Hasn't this meaning changed now that we have three
// transformations roughly running at the same time?
+ // Eric: Interesting point
std::vector <ReorgType_t> *reorg_type;
// Added to by remove_deleted_types
std::vector <ReorgType_t> *saved_reorg_type;
@@ -176,6 +181,7 @@ struct Info {
// Debug flags
bool show_all_reorg_cands;
bool show_all_reorg_cands_in_detail;
+ bool show_perf_qualify;
bool show_prog_decls;
bool show_delete;
bool show_new_BBs;
@@ -196,6 +202,7 @@ struct Info {
, reorg_dump_file(NULL)
, show_all_reorg_cands(false)
, show_all_reorg_cands_in_detail(false)
+ , show_perf_qualify(false)
, show_prog_decls(false)
, show_new_BBs(false)
, show_transforms(false)
@@ -222,13 +229,14 @@ extern int str_reorg_instance_interleave ( Info *);
#endif
extern int number_of_levels ( tree);
+extern tree make_multilevel( tree, int);
extern bool modify_decl_core ( tree *, 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);
-extern enum ReorgOpTrans recognize_op ( tree, Info_t *);
+extern enum ReorgOpTrans recognize_op ( tree, bool, Info_t *);
extern ReorgTransformation reorg_recognize ( gimple *,
cgraph_node *,
Info_t *);
@@ -246,14 +254,16 @@ extern void print_program ( FILE *, bool, int, Info_t *);
extern void print_type ( FILE *, tree);
extern void modify_ssa_name_type ( tree, tree);
extern bool print_internals (gimple *, void *);
+extern const char *optrans_to_str ( enum ReorgOpTrans);
+extern bool is_assign_from_ssa ( gimple *);
-// 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.
+// I have no intention of leaving these debugging marcos or uses of
+// them in the code. However, some of the uses should obviously be
+// converted to dump file information.
-#define DEBUGGING 0
+#define DEBUGGING 1
#if DEBUGGING
enum Display {
Show_nothing,