summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Oblock <gary@amperecomputing.com>2020-09-07 20:53:31 -0700
committerGary Oblock <gary@amperecomputing.com>2020-09-07 20:53:31 -0700
commitaaafa91d98dd64130398c992b61ec42cff160c9a (patch)
tree0031c238ebdcce23d717acc5e3fe4c740f3c7a58
parent505cb71e1db6ca699d06b4d6ba1a0a0865605fd4 (diff)
The phi case for setting a pointer to zero.
-rw-r--r--gcc/ipa-str-reorg-instance-interleave.c36
-rw-r--r--gcc/ipa-structure-reorg.c136
-rw-r--r--gcc/ipa-structure-reorg.h2
3 files changed, 136 insertions, 38 deletions
diff --git a/gcc/ipa-str-reorg-instance-interleave.c b/gcc/ipa-str-reorg-instance-interleave.c
index 82a3919100a..16633d4f87c 100644
--- a/gcc/ipa-str-reorg-instance-interleave.c
+++ b/gcc/ipa-str-reorg-instance-interleave.c
@@ -1297,6 +1297,42 @@ str_reorg_instance_interleave_trans ( Info *info)
}
}
}
+ // Iterate over the PHIs and for any PHI that is a reorgtype,
+ // 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);
+ gphi_iterator pi;
+ for ( pi = gsi_start_phis (bb); !gsi_end_p (pi); gsi_next (&pi))
+ {
+ //gimple_stmt_iterator gsi = as_a <gimple_stmt_iterator> pi;
+ gphi *phi = pi.phi ();
+ gimple *stmt = static_cast <gimple *> (phi);
+
+ DEBUG_A("phi: ");
+ DEBUG_F( print_gimple_stmt, stderr, stmt, 0);
+
+ ReorgType_t *ri = contains_a_reorgtype( stmt, info);
+ if ( ri != NULL && number_of_levels ( TREE_TYPE ( PHI_RESULT ( stmt))) == 1 )
+ {
+ 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);
+ bool int_cst = TREE_CODE ( *arg) == INTEGER_CST;
+ 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);
+ }
+ }
+ }
+ }
+ INDENT(-4);
}
pop_cfun ();
}
diff --git a/gcc/ipa-structure-reorg.c b/gcc/ipa-structure-reorg.c
index 9ef52d37921..9b3fdf95211 100644
--- a/gcc/ipa-structure-reorg.c
+++ b/gcc/ipa-structure-reorg.c
@@ -70,10 +70,11 @@ static bool reorg_legality ( Info *);
static void reorg_common_middle_code ( Info *);
static void modify_declarations ( Info *);
static bool modify_func_decl_core ( struct function *, Info *);
+static void disqualify_all_reorgtypes_of ( gimple *, int, Info *);
static void adjust_result_decl ( struct function *);
static tree modify_func_type ( struct function *, Info *);
static bool needs_modification_p ( struct function *, Info *);
-static int number_of_levels ( tree);
+//static int number_of_levels ( tree);
//static void modify_decl_core ( tree *, Info *);
static void reorg_forbidden ( gimple *, Info *);
// Name changed and moved to its own file
@@ -918,18 +919,32 @@ transformation_legality ( Info *info)
int num = num_reorgtypes ( stmt, info);
if ( num != 0 )
{
- if ( reorg_recognize( stmt, node, info) == Not_Supported )
- {
- //DEBUG_L("deleting %d reorgs for unsuported stmt: ", num);
- //DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
- int i;
- for ( i = 0; i < num; i++ )
+ ReorgTransformation trans = reorg_recognize( stmt, node, info);
+ switch ( trans )
{
- ReorgType_t *reorg_type =
- get_reorgtype( stmt, info, i);
- delete_reorgtype( reorg_type, 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);
+ case ReorgT_UserFunc:
+ // TBD ReorgT_Ptr2Zero does not catch all cases of
+ // setting a reorg pointer to zero. One that I
+ // discoivered in a dump is phis can hold constanst.
+ break;
+ case ReorgT_Return:
+ // TBD ReorgT_Ptr2Zero does not catch all cases of
+ // setting a reorg pointer to zero. One that I
+ // discoivered in a dump is phis can hold constanst.
+ break;
+ case ReorgT_Convert:
+ // TBD Note, any conversion of an integer type to a
+ // reorg pointer type can obsure the zero transformation
+ // and needs to disqualify the type.
+ break;
+ default:
+ // No problem.
+ ;
}
- }
}
if ( uses_field_of_reorgtypes( stmt, info) )
{
@@ -938,6 +953,9 @@ transformation_legality ( Info *info)
}
}
}
+
+ // TBD Walk the PHIs looking for reorg type PHIs with a
+ // nonzero constant. Disqualify any typeas this happens with.
}
//DEBUG_L("after transformation_legality\n");
@@ -1050,6 +1068,18 @@ modify_declarations ( Info *info)
}
static void
+disqualify_all_reorgtypes_of ( gimple *stmt, int num, Info *info)
+{
+ int i;
+ for ( i = 0; i < num; i++ )
+ {
+ ReorgType_t *reorg_type =
+ get_reorgtype( stmt, info, i);
+ delete_reorgtype( reorg_type, info);
+ }
+}
+
+static void
adjust_result_decl ( struct function *func)
{
tree func_decl = func->decl;
@@ -1162,7 +1192,7 @@ needs_modification_p ( struct function *func, Info *info )
return false;
}
-static int
+int
number_of_levels ( tree type)
{
tree prev_type;
@@ -1426,8 +1456,9 @@ reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info )
{
return ReorgT_Ptr2Zero;
}
- // WTF??? what if we get here
- gcc_assert(0);
+ // 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]"
@@ -1872,6 +1903,26 @@ base_type_of ( tree type)
return type;
}
+tree
+base_type_with_levels ( tree type, int *levels)
+{
+ //DEBUG_L("base_type_of: ");
+ //DEBUG_F( print_generic_expr, stderr, type, TDF_DETAILS);
+ //DEBUG("\n");
+ int lev = 0;
+ bool indir;
+ for ( ; (indir = POINTER_TYPE_P ( type)) ||
+ TREE_CODE ( type) == ARRAY_TYPE ||
+ TREE_CODE ( type) == VAR_DECL ||
+ TREE_CODE ( type) == PARM_DECL
+ ; type = TREE_TYPE ( type) )
+ {
+ if ( indir ) lev++;
+ }
+ *levels = lev;
+ return type;
+}
+
// There are other allocations such as alloca or
// aligned allocs that I'm pretty sure are not
// a good fit for structure reorg optimization.
@@ -1987,7 +2038,7 @@ 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\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
@@ -2002,17 +2053,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");
+ DEBUG_L("");
+ DEBUG_F( print_generic_expr, stderr, type, TDF_DETAILS);
+ DEBUG("\n");
if ( same_type_p ( ri->gcc_type, type) )
{
- //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;
}
@@ -2029,9 +2080,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 )
@@ -2045,21 +2096,30 @@ 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);
-
- // Note walk_stmt_info is compilcated, use it's info
- // field for hidden_info
- hidden_info_t hi = { NULL, info };
- struct walk_stmt_info walk_info; // expt
- memset ( &walk_info, 0, sizeof ( walk_info));
- walk_info.info = ( void*)&hi; //expt
- walk_gimple_op ( stmt,
- detect_reorg,
- &walk_info);
- //INDENT(-2);
- return hi.found_reorg;
+ DEBUG_L ( "contains_a_reorgtype: ");
+ DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
+ INDENT(2);
+
+ if ( gimple_code ( stmt) == GIMPLE_PHI )
+ {
+ INDENT(-2);
+ tree base = base_type_of ( TREE_TYPE ( PHI_RESULT ( stmt)));
+ return get_reorgtype_info ( base, info);
+ }
+ else
+ {
+ // Note walk_stmt_info is compilcated, use it's info
+ // field for hidden_info
+ hidden_info_t hi = { NULL, info };
+ struct walk_stmt_info walk_info; // expt
+ memset ( &walk_info, 0, sizeof ( walk_info));
+ walk_info.info = ( void*)&hi; //expt
+ walk_gimple_op ( stmt,
+ detect_reorg,
+ &walk_info);
+ INDENT(-2);
+ return hi.found_reorg;
+ }
}
static tree
diff --git a/gcc/ipa-structure-reorg.h b/gcc/ipa-structure-reorg.h
index f7644a0d71e..2abd5ddfa40 100644
--- a/gcc/ipa-structure-reorg.h
+++ b/gcc/ipa-structure-reorg.h
@@ -216,6 +216,7 @@ extern int str_reorg_field_reorder ( Info *);
extern int str_reorg_instance_interleave ( Info *);
#endif
+extern int number_of_levels ( tree);
extern bool modify_decl_core ( tree *, Info *);
extern void delete_reorgtype ( ReorgType_t *, Info_t *);
extern void undelete_reorgtype ( ReorgType_t *, Info_t *);
@@ -234,6 +235,7 @@ extern bool tree_contains_a_reorgtype_p ( tree, Info *);
extern ReorgType_t *tree_contains_a_reorgtype ( tree, Info *);
extern bool is_reorg_type ( tree, Info_t *);
extern tree base_type_of ( tree);
+extern tree base_type_with_levels ( tree, int *);
extern void print_reorg ( FILE *, int, ReorgType_t *);
extern void print_program ( FILE *, bool, int, Info_t *);
extern void print_type ( FILE *, tree);