diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-06-08 11:22:16 +0200 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-06-08 11:22:16 +0200 |
commit | 095fb75003c2ba67f9b1088dde507ab5bc0d41a9 (patch) | |
tree | 7da0eef4fa4abf648c4b7b0a380c4a8cf2d94e5b | |
parent | 6beaedd06185b45231beb1433d4a401ffc4ef68c (diff) |
Putting code into ipa-structure-reorg
-rw-r--r-- | gcc/expr-escaper.hpp | 1 | ||||
-rw-r--r-- | gcc/gimple-escaper.c | 1 | ||||
-rw-r--r-- | gcc/gimple-escaper.hpp | 2 | ||||
-rw-r--r-- | gcc/ipa-prototype.c | 10 | ||||
-rw-r--r-- | gcc/ipa-structure-reorg.c | 136 | ||||
-rw-r--r-- | gcc/ipa-structure-reorg.h | 23 | ||||
-rw-r--r-- | gcc/type-escaper.c | 35 | ||||
-rw-r--r-- | gcc/type-escaper.hpp | 3 |
8 files changed, 155 insertions, 56 deletions
diff --git a/gcc/expr-escaper.hpp b/gcc/expr-escaper.hpp index 75e4de23196..6498f9e3dd4 100644 --- a/gcc/expr-escaper.hpp +++ b/gcc/expr-escaper.hpp @@ -10,6 +10,7 @@ class ExprEscaper : public ExprWalker public: TypeEscaper typeEscaper; ExprEscaper(ptrset_t &types) : typeEscaper(types) {}; + ptrset_t get_sets() { return typeEscaper.get_sets(); }; void update(const_tree t, Reason r); private: Reason _r; diff --git a/gcc/gimple-escaper.c b/gcc/gimple-escaper.c index a3cd880c281..625235e0b8d 100644 --- a/gcc/gimple-escaper.c +++ b/gcc/gimple-escaper.c @@ -31,6 +31,7 @@ #include "gimple-escaper.hpp" + void GimpleEscaper::_init() { diff --git a/gcc/gimple-escaper.hpp b/gcc/gimple-escaper.hpp index 447a4f83bee..45cdd70ab4a 100644 --- a/gcc/gimple-escaper.hpp +++ b/gcc/gimple-escaper.hpp @@ -2,12 +2,14 @@ #include "gimple-walker.hpp" #include "expr-escaper.hpp" +#include "collect-types.h" class GimpleEscaper : public GimpleWalker { public: GimpleEscaper(ptrset_t &types) : exprEscaper(types) { _init(); }; ExprEscaper exprEscaper; + ptrset_t get_sets() { return exprEscaper.get_sets(); }; private: typedef std::set<const_tree> undefset; undefset undefined; diff --git a/gcc/ipa-prototype.c b/gcc/ipa-prototype.c index 51f0eafea6f..c718e5bb57e 100644 --- a/gcc/ipa-prototype.c +++ b/gcc/ipa-prototype.c @@ -85,23 +85,23 @@ Reason::operator|=(const Reason &other) } + static inline void -assert_type_is_in_universe(const_tree type, ptrset_t &types) +assert_type_is_in_ptrset(const_tree type, ptrset_t &types) { #ifdef SANITY_CHECKS - gcc_assert(types.in_universe(type)); + gcc_assert(types.in_points_to_record(type)); #endif } static inline void -assert_type_is_in_ptrset(const_tree type, ptrset_t &types) +assert_type_is_in_universe(const_tree type, ptrset_t &types) { #ifdef SANITY_CHECKS - gcc_assert(types.in_points_to_record(type)); + gcc_assert(types.in_universe(type)); #endif } - static bool is_variable_escaping(varpool_node *vnode) { diff --git a/gcc/ipa-structure-reorg.c b/gcc/ipa-structure-reorg.c index f2c25b588cf..5df74ba139e 100644 --- a/gcc/ipa-structure-reorg.c +++ b/gcc/ipa-structure-reorg.c @@ -40,55 +40,58 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "gimple-walk.h" // TBD more includes go here +#include "gimple-collector.hpp" +#include "gimple-escaper.hpp" +#include "collect-types.h" static void setup_debug_flags ( Info *); static void final_debug_info ( Info *); -static unsigned int reorg_analysis ( Info_t *); +static unsigned int reorg_analysis ( Info *); static void reorg_analysis_debug ( Info *, ReorgType *); -static bool find_decls_and_types ( Info_t *); -static void add_reorg_type( tree, Info *); -static void disqualify_struct_in_struct_or_union ( Info_t *); -static void initial_reorg_debug ( Info *info, ReorgType *reorg ); +static bool find_decls_and_types ( Info *); +//static void add_reorg_type( tree, Info *); +static void disqualify_struct_in_struct_or_union ( Info *); +static void initial_reorg_debug ( Info *, ReorgType *reorg ); static void disqualify_struct_in_struct_or_union_debug ( Info *, ReorgType *); static void disq_str_in_str_or_union_helper ( tree, std::set<tree> *, - Info_t *); -static unsigned int reorg_qualification ( Info_t *); -static bool transformation_legality ( Info_t *); + Info *); +static unsigned int reorg_qualification ( Info *); +static bool transformation_legality ( Info *); static void transformation_legality_debug ( Info *, ReorgType *); -static bool reorg_legality ( Info_t *); -static void reorg_common_middle_code ( Info_t *); -static void modify_declarations ( Info_t *); -static void modify_decl_core ( tree *, Info_t *); -static void reorg_forbidden ( gimple *, Info_t *); +static bool reorg_legality ( Info *); +static void reorg_common_middle_code ( Info *); +static void modify_declarations ( Info *); +static void modify_decl_core ( tree *, Info *); +static void reorg_forbidden ( gimple *, Info *); // Name changed and moved to its own file -//static void reorg_transformation ( Info_t *); +//static void reorg_transformation ( Info *); // made extern -//static void delete_reorgtype ( ReorgType_t *, Info_t *); -//static void undelete_reorgtype ( ReorgType_t *, Info_t *); +//static void delete_reorgtype ( ReorgType_t *, Info *); +//static void undelete_reorgtype ( ReorgType_t *, Info *); //static void remove_deleted_types ( Info *, ReorgFn); -//static enum ReorgOpTrans recognize_op ( tree, Info_t *); -//static ReorgTransformation reorg_recognize ( gimple *, Info_t *); -//static bool is_reorg_type ( tree, Info_t *); +//static enum ReorgOpTrans recognize_op ( tree, Info *); +//static ReorgTransformation reorg_recognize ( gimple *, Info *); +//static bool is_reorg_type ( tree, Info *); //static tree base_type_of ( tree); static bool is_user_function ( gimple *, Info *); static bool is_reorg_alloc_trigger ( gimple *); -static ReorgType_t *find_struct_type_ptr_to_struct ( tree, Info_t *); -//static ReorgType_t *get_reorgtype_info ( tree, Info_t *); +static ReorgType_t *find_struct_type_ptr_to_struct ( tree, Info *); +//static ReorgType_t *get_reorgtype_info ( tree, Info *); static void print_reorg_with_msg ( FILE *, ReorgType_t *, int, const char *); static void dump_reorg ( ReorgType_t *reorg); -static void print_reorgs ( FILE *, int, Info_t *); +static void print_reorgs ( FILE *, int, Info *); //static void print_reorg ( FILE *, int, ReorgType_t *); -static void print_progdecls ( FILE *, int, Info_t *); +static void print_progdecls ( FILE *, int, Info *); static void print_progdecl ( FILE *, int, ProgDecl_t *); static void print_program ( FILE *, int); static void print_function ( FILE *, int, function *); -static ReorgType_t *get_reorgtype( gimple *stmt, Info_t *, int); -static int num_reorgtypes( gimple *, Info_t *); -static bool points_to_escape_analysis( Info_t *); -static bool uses_field_of_reorgtypes( gimple *, Info_t *); +static ReorgType_t *get_reorgtype( gimple *stmt, Info *, int); +static int num_reorgtypes( gimple *, Info *); +static bool points_to_escape_analysis( Info *); +static bool uses_field_of_reorgtypes( gimple *, Info *); //-- debugging only -- #if DEBUGGING @@ -114,7 +117,11 @@ ipa_structure_reorg ( void) // be running in a single LTRANS partition. Sanity check // these here. - Info_t info = { &Reorg_Type, + // TODO: + // Why not make this a class and avoid having all these parameters + // to initialize? + // Also, all functions should be references and not pointers... + Info info = { &Reorg_Type, &Saved_Reorg_Type, &Prog_Decl, &StructTypes, @@ -133,6 +140,7 @@ ipa_structure_reorg ( void) if ( !reorg_analysis ( &info) ) { + gcc_unreachable(); return true; } @@ -232,8 +240,32 @@ final_debug_info ( Info *info) } static unsigned int -reorg_analysis ( Info_t *info) +reorg_analysis ( Info *info) { + + // TODO: + // Gary, this main "analysis" method seems to have a lot of + // instance interleave specific code. Shouldn't this method + // concretely be just the escape analysis? + + + // TODO: + // Gary, this is me adding a way to run the escape analysis... + // It is only triggered when flag_ipa_structure_reorg is + // specified since I am not sure what this function should + // concretely do. + const bool run_escape_analysis = flag_ipa_dead_field_eliminate && !flag_ipa_instance_interleave && !flag_ipa_field_reorder; + if (run_escape_analysis) + { + GimpleTypeCollector collector; + collector.walk(); + ptrset_t types = collector.get_pointer_set(); + GimpleEscaper gimpleEscaper(types); + gimpleEscaper.walk(); + types = gimpleEscaper.get_sets(); + gcc_unreachable(); + return true; + } struct cgraph_node *node; find_decls_and_types ( info); @@ -348,7 +380,7 @@ reorg_analysis_debug ( Info *info, ReorgType *reorg ) } } -static bool find_decls_and_types ( Info_t *info) +static bool find_decls_and_types ( Info *info) { // Don't keep any structure types if they aren't // used in an array or have a pointer type (which @@ -388,7 +420,7 @@ static bool find_decls_and_types ( Info_t *info) ; } - add_reorg_type ( base, info); + //add_reorg_type ( base, info); typeset.insert ( base); // ??? } } @@ -432,7 +464,7 @@ static bool find_decls_and_types ( Info_t *info) continue; } - add_reorg_type ( base, info); + //add_reorg_type ( base, info); typeset.insert ( base); // ??? } } @@ -675,6 +707,7 @@ static bool find_decls_and_types ( Info_t *info) return true; } +/* static void add_reorg_type ( tree base, Info *info) { @@ -687,9 +720,10 @@ add_reorg_type ( tree base, Info *info) // and is marked to be deleted. info->num_deleted++; } +*/ void -disqualify_struct_in_struct_or_union ( Info_t *info) +disqualify_struct_in_struct_or_union ( Info *info) { varpool_node *var; std::set<tree> typeset; @@ -778,7 +812,7 @@ disqualify_struct_in_struct_or_union_debug ( Info *info, static void disq_str_in_str_or_union_helper ( tree type, std::set<tree> *typeset, - Info_t *info ) + Info *info ) { //DEBUG_L( "In disq_str_in_str_or_union_helper (possibele deletes)\n"); //INDENT(2); @@ -827,7 +861,7 @@ disq_str_in_str_or_union_helper ( tree type, } static unsigned int -reorg_qualification ( Info_t *info) +reorg_qualification ( Info *info) { // TBD // This only does a generic legality qualification and each @@ -838,7 +872,7 @@ reorg_qualification ( Info_t *info) // Return false if nothing qualified bool -reorg_legality( Info_t *info) { +reorg_legality( Info *info) { // NOTE, the following line does nothing unless // we actually do our own points-to analysis if( !points_to_escape_analysis( info) ) return false; @@ -848,7 +882,7 @@ reorg_legality( Info_t *info) { // Return false if nothing qualified bool -transformation_legality ( Info_t *info) +transformation_legality ( Info *info) { cgraph_node* node; @@ -904,13 +938,13 @@ transformation_legality_debug ( Info *info, ReorgType *reorg ) } static void -reorg_common_middle_code ( Info_t *info) +reorg_common_middle_code ( Info *info) { modify_declarations( info); } static void -modify_declarations ( Info_t *info) +modify_declarations ( Info *info) { // For the moment we ignore initializations assuming // all potential reorg types that had initialized @@ -932,7 +966,7 @@ modify_declarations ( Info_t *info) } static void -modify_decl_core ( tree *location, Info_t *info) +modify_decl_core ( tree *location, Info *info) { tree type = *location; tree base = base_type_of ( type); @@ -957,7 +991,7 @@ modify_decl_core ( tree *location, Info_t *info) } void -delete_reorgtype ( ReorgType_t *rt, Info_t *info ) +delete_reorgtype ( ReorgType_t *rt, Info *info ) { //DEBUG_L( "delete_reorgtype( %s ):", type_name_to_str( TYPE_NAME( rt->gcc_type))); if ( !rt->delete_me ) @@ -971,7 +1005,7 @@ delete_reorgtype ( ReorgType_t *rt, Info_t *info ) } void -undelete_reorgtype ( ReorgType_t *rt, Info_t *info ) +undelete_reorgtype ( ReorgType_t *rt, Info *info ) { //DEBUG_L( "undelete_reorgtype( %s ): ", type_name_to_str( TYPE_NAME( rt->gcc_type))); if ( rt->delete_me ) @@ -985,7 +1019,7 @@ undelete_reorgtype ( ReorgType_t *rt, Info_t *info ) } ReorgTransformation -reorg_recognize ( gimple *stmt, Info_t *info ) +reorg_recognize ( gimple *stmt, Info *info ) { DEBUG_L ( "ReorgTransformation reorg_recognize for: "); DEBUG_F ( print_gimple_stmt, stderr, stmt, 0); @@ -1447,7 +1481,7 @@ recognize_op ( tree op, Info *info) } bool -is_reorg_type( tree rt, Info_t *info ) +is_reorg_type( tree rt, Info *info ) { return get_reorgtype_info ( rt, info) != NULL; } @@ -1537,7 +1571,7 @@ bool same_type_p( tree a, tree b ) // look them up or even modify the container // type of ReorgType ReorgType_t * -get_reorgtype_info ( tree type, Info_t* info) +get_reorgtype_info ( tree type, Info* info) { DEBUG_L( "get_reorgtype_info\n"); @@ -1744,14 +1778,14 @@ print_function ( FILE *file, int leading_space, struct function *func) } ReorgType_t * -get_reorgtype( gimple *stmt, Info_t *info, int i) +get_reorgtype( gimple *stmt, Info *info, int i) { // TBD - Straight forward NULL; } int -num_reorgtypes( gimple *stmt, Info_t *info) +num_reorgtypes( gimple *stmt, Info *info) { // TBD - Straight forward 0; @@ -1773,14 +1807,14 @@ print_type ( FILE *file, tree type) // from, return true. // Return false if nothing qualified bool -points_to_escape_analysis( Info_t *info) +points_to_escape_analysis( Info *info) { // TBD return true; } bool -uses_field_of_reorgtypes( gimple *stmt, Info_t * info) +uses_field_of_reorgtypes( gimple *stmt, Info * info) { // TBD return false; @@ -1856,7 +1890,7 @@ handle_debug_indenting ( int amount ) const pass_data pass_data_ipa_structure_reorg = { IPA_PASS, /* type */ - "structure reorg", /* name */ + "structure-reorg", /* name */ OPTGROUP_NONE, /* optinfo_flags */ //TV_IPA_SRA, /* tv_id */ // TBD TV_IPA_STRUCTURE_REORG, /* tv_id */ @@ -1882,7 +1916,7 @@ public: flag_ipa_instance_interleave || flag_ipa_field_reorder || flag_ipa_dead_field_eliminate ) - && optimize ); + && in_lto_p ); } virtual unsigned int execute ( function *) { return ipa_structure_reorg (); } diff --git a/gcc/ipa-structure-reorg.h b/gcc/ipa-structure-reorg.h index a379943c05f..3861efa0be0 100644 --- a/gcc/ipa-structure-reorg.h +++ b/gcc/ipa-structure-reorg.h @@ -25,6 +25,9 @@ typedef struct RT_Elim RT_Elim; typedef struct RT_Reorder RT_Reorder; typedef struct RT_Interleave RT_Interleave; +#include <set> +#include "collect-types.h" + struct RT_Elim { int dummy; }; @@ -44,6 +47,12 @@ struct RT_Interleave { }; typedef struct ReorgType ReorgType_t; +// TODO: Gary, is there supposed to be +// 1 ReorgType_t for every tree? +// Don't we need something that also is global? +// I have a set of trees that do not escape +// and I would like to use that for the moment. +// Not sure how it will evolve in the future... struct ReorgType { unsigned id; tree gcc_type; @@ -66,6 +75,7 @@ struct ProgDecl { }; enum ReorgOpTrans { + // TODO: What is the purpose of this enum? // Let's try to use scalar insead of this... nope! ReorgOpT_Temp, // SSA temp ReorgOpT_Address, // "&x[i]" @@ -84,6 +94,14 @@ enum CompressionControl { }; enum ReorgTransformation { + // TODO: Gary, if these are transformation, shouldn't they have + // a pre-state and a post-state? + // Here I am only seeing statements. Not sure why + // a reorg transformation has statements / expressions. + // + // Also, why aren't we using the expressions already + // defined by GCC? For example EQ_EXPR? + // Ultimately what is the purpose of these? ReorgT_StrAssign, // "*a = x[i]", "x[i] = y[j]", "s = *a", etc. ReorgT_ElemAssign, // "a->f = z", "z = x[i].f", etc. ReorgT_If_Null, // "if(a == 0)..." @@ -124,6 +142,9 @@ struct BoolPair { typedef struct Info Info_t; 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? std::vector <ReorgType_t> *reorg_type; // Added to by remove_deleted_types std::vector <ReorgType_t> *saved_reorg_type; @@ -131,6 +152,8 @@ struct Info { // Gcc doesn't have global decls readily available // so this holds them std::map <tree,BoolPair_t> *struct_types; // desing bug fix + // ptrset_t holds types which point to records + // and types which escape int num_deleted; double total_cache_accesses; FILE *reorg_dump_file; diff --git a/gcc/type-escaper.c b/gcc/type-escaper.c index c72ee785980..977a8af795c 100644 --- a/gcc/type-escaper.c +++ b/gcc/type-escaper.c @@ -47,6 +47,41 @@ TypeEscaper::is_memoized(const_tree t) return false; } +static inline void +assert_type_is_in_universe(const_tree type, ptrset_t &types) +{ +#ifdef SANITY_CHECKS + gcc_assert(types.in_universe(type)); +#endif +} + +ptrset_t +TypeEscaper::get_sets() +{ + place_escaping_types_in_set(); + return _ptrset; +} + +void +TypeEscaper::place_escaping_types_in_set() +{ + for (auto i = calc.cbegin(), e = calc.cend(); i != e; ++i) + { + const_tree type = i->first; + // We should have seen it before + assert_type_is_in_universe(type, _ptrset); + + // We should only track interesting types + // Types which are not in points_to_record are the ones + // that are pointed to by records. + // I think it is possible to prune them ahead of time... + if (!_ptrset.in_points_to_record(type)) continue; + + const Reason reason = i->second; + reason.is_escaping ? _ptrset.escaping.insert(type) : _ptrset.non_escaping.insert(type); + } +} + void TypeEscaper::update(const_tree t, Reason r) { diff --git a/gcc/type-escaper.hpp b/gcc/type-escaper.hpp index c35c6cc5f5f..3bda74aa297 100644 --- a/gcc/type-escaper.hpp +++ b/gcc/type-escaper.hpp @@ -3,12 +3,14 @@ #include "type-walker.hpp" #include "ipa-prototype.h" #include "collect-types.h" +#include <map> class TypeEscaper : public TypeWalker { public: TypeEscaper(ptrset_t &p) : _ptrset(p), _inside_union(0) {}; void update(const_tree t, Reason r); + ptrset_t get_sets(); ptrset_t &_ptrset; typemap calc; private: @@ -24,5 +26,6 @@ private: unsigned _inside_union; Reason _reason; void _update(const_tree t); + void place_escaping_types_in_set(); }; |