diff options
author | Gary Oblock <gary@amperecomputing.com> | 2020-09-07 20:53:31 -0700 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-09-08 09:05:47 +0200 |
commit | c96e3117465c401e7ef846f2f488fdfd78b045d3 (patch) | |
tree | 0fe25b2029b599f9559263e07a8038db922ca2e5 | |
parent | e0ced00aecaaa7996922b374d3a8ebec89fa98bb (diff) |
The phi case for setting a pointer to zero.
-rw-r--r-- | gcc/ipa-str-reorg-instance-interleave.c | 36 | ||||
-rw-r--r-- | gcc/ipa-structure-reorg.c | 136 | ||||
-rw-r--r-- | gcc/ipa-structure-reorg.h | 2 |
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); |