summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-08 11:22:16 +0200
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-08 11:22:16 +0200
commit095fb75003c2ba67f9b1088dde507ab5bc0d41a9 (patch)
tree7da0eef4fa4abf648c4b7b0a380c4a8cf2d94e5b
parent6beaedd06185b45231beb1433d4a401ffc4ef68c (diff)
Putting code into ipa-structure-reorg
-rw-r--r--gcc/expr-escaper.hpp1
-rw-r--r--gcc/gimple-escaper.c1
-rw-r--r--gcc/gimple-escaper.hpp2
-rw-r--r--gcc/ipa-prototype.c10
-rw-r--r--gcc/ipa-structure-reorg.c136
-rw-r--r--gcc/ipa-structure-reorg.h23
-rw-r--r--gcc/type-escaper.c35
-rw-r--r--gcc/type-escaper.hpp3
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();
};