summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-05-14 14:39:09 +0200
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-05-14 14:46:22 +0200
commita22362346872039fa01a22fc8dc2c26de16d24a0 (patch)
tree3664b3d38594018b18af0643cebe2ea88b47f432
parent2b7d6678eed25ade1351c12fe5919dd7120f37b2 (diff)
Adds globals
-rw-r--r--gcc/collect-types.c258
-rw-r--r--gcc/collect-types.h14
-rw-r--r--gcc/ipa-escape-analysis.c148
3 files changed, 322 insertions, 98 deletions
diff --git a/gcc/collect-types.c b/gcc/collect-types.c
index fd25ff81be3..0ce6cccb025 100644
--- a/gcc/collect-types.c
+++ b/gcc/collect-types.c
@@ -30,46 +30,193 @@
#include "compare-types.h"
#include "types-inlines.h"
+#include "name-types.h"
#include <set>
#include "collect-types.h"
+static bool filter_boring_types(const_tree type, ptrset_t &);
+
static bool
-filter_out_simple_types(const_tree type)
+filter_boring_types_wrapper(const_tree type, ptrset_t &types)
{
gcc_assert(type);
+ const_tree inner_type = TREE_TYPE(type);
+ gcc_assert(inner_type);
+ return filter_boring_types(inner_type, types);
+}
+
+static bool
+filter_boring_types_array(const_tree type, ptrset_t &types)
+{
+ assert_is_type(type, ARRAY_TYPE);
+ return filter_boring_types_wrapper(type, types);
+}
+
+static bool
+filter_boring_types_reference(const_tree type, ptrset_t &types)
+{
+ assert_is_type(type, REFERENCE_TYPE);
+ return filter_boring_types_wrapper(type, types);
+}
+
+static bool
+filter_boring_types_pointer(const_tree type, ptrset_t &types)
+{
+ assert_is_type(type, POINTER_TYPE);
+ return filter_boring_types_wrapper(type, types);
+}
+
+static bool
+filter_boring_types_record(const_tree type, ptrset_t &types)
+{
+ assert_is_type(type, RECORD_TYPE);
+ return false;
+}
+
+static bool
+filter_boring_types_unions(const_tree type, ptrset_t &types)
+{
+ const enum tree_code code = TREE_CODE(type);
+ const bool is_union = UNION_TYPE == code;
+ const bool is_qual_union = QUAL_UNION_TYPE == code;
+ const bool is_valid_input = is_union || is_qual_union;
+ gcc_assert(is_valid_input);
+
+ for (tree field = TYPE_FIELDS(type) ; field ; field = DECL_CHAIN(field))
+ {
+ const_tree field_type = TREE_TYPE(field);
+ gcc_assert(field_type);
+ const bool is_boring = filter_boring_types(field_type, types);
+ if (!is_boring) return is_boring;
+ }
+
+ return true;
+}
+
+static bool
+filter_boring_types_union(const_tree type, ptrset_t &types)
+{
+ assert_is_type(type, UNION_TYPE);
+ return filter_boring_types_unions(type, types);
+}
+
+static bool
+filter_boring_types_qual_union(const_tree type, ptrset_t &types)
+{
+ assert_is_type(type, QUAL_UNION_TYPE);
+ return filter_boring_types_unions(type, types);
+}
+
+static bool
+filter_boring_types_function_or_method(const_tree type, ptrset_t &types)
+{
const enum tree_code code = TREE_CODE(type);
+ const bool is_function = FUNCTION_TYPE == code;
+ const bool is_method = METHOD_TYPE == code;
+ const bool is_valid_input = is_function || is_method;
+ gcc_assert(is_valid_input);
+
+ const_tree ret_type = TREE_TYPE(type);
+ gcc_assert(ret_type);
+ const bool retval_is_boring = filter_boring_types(ret_type, types);
+ if (!retval_is_boring) return retval_is_boring;
+
+ tree arg_node = TYPE_ARG_TYPES(type);
+ while (NULL_TREE != arg_node)
+ {
+ tree arg_node_type = TREE_VALUE(arg_node);
+ gcc_assert(arg_node_type);
+ const bool arg_is_boring = filter_boring_types(arg_node_type, types);
+ arg_node = TREE_CHAIN(arg_node);
+ if (!arg_is_boring) return arg_is_boring;
+ }
+
+ return true;
+}
+static bool
+filter_boring_types_function(const_tree type, ptrset_t &types)
+{
+ assert_is_type(type, FUNCTION_TYPE);
+ return filter_boring_types_function_or_method(type, types);
+}
+
+static bool
+filter_boring_types_method(const_tree type, ptrset_t &types)
+{
+ assert_is_type(type, METHOD_TYPE);
+ return filter_boring_types_function_or_method(type, types);
+}
+
+static bool
+filter_boring_types(const_tree type, ptrset_t &types)
+{
+ // boring types are those that do not point to
+ // a struct
+ gcc_assert(type);
+
+ // Optimization to speed up the filter.
+ // Memoization
+ const bool seen_before = types.in_universe(type);
+ if (seen_before)
+ {
+ const bool in_points_to_record = types.in_points_to_record(type);
+ const bool in_complement = types.in_complement(type);
+ const bool _xor = in_points_to_record != in_complement;
+ gcc_assert(_xor);
+ return in_complement;
+ }
+
+
+ bool is_boring = true;
+ enum tree_code code = TREE_CODE(type);
switch (code)
{
- case VOID_TYPE:
- case INTEGER_TYPE:
- case REAL_TYPE:
- case FIXED_POINT_TYPE:
- case COMPLEX_TYPE:
- case ENUMERAL_TYPE:
- case BOOLEAN_TYPE:
- case OFFSET_TYPE:
- return false;
+ case ARRAY_TYPE:
+ is_boring = filter_boring_types_array(type, types);
+ break;
+ case RECORD_TYPE:
+ is_boring = filter_boring_types_record(type, types);
+ break;
+ case UNION_TYPE:
+ is_boring = filter_boring_types_union(type, types);
+ break;
+ case QUAL_UNION_TYPE:
+ is_boring = filter_boring_types_qual_union(type, types);
+ break;
+ case REFERENCE_TYPE:
+ is_boring = filter_boring_types_reference(type, types);
+ break;
+ case POINTER_TYPE:
+ is_boring = filter_boring_types_pointer(type, types);
+ break;
+ case FUNCTION_TYPE:
+ is_boring = filter_boring_types_function(type, types);
+ break;
+ case METHOD_TYPE:
+ is_boring = filter_boring_types_method(type, types);
break;
default:
- return false;
+ // I will probably need to fuzz.
break;
}
- gcc_unreachable();
- return false;
+ // This should be one the two only times we call insert!
+ types.insert(type, !is_boring);
+
+ return is_boring;
}
static const unsigned filter_buffer_size = 1;
-typedef bool (*filter_t)(const_tree);
+typedef bool (*filter_t)(const_tree, ptrset_t&);
const extern filter_t filter[filter_buffer_size] =
{
- filter_out_simple_types,
+ filter_boring_types,
};
static void
-collect_types_from_record_or_union_type(const_tree type, typeset &types)
+collect_types_from_record_or_union_type(const_tree type, ptrset_t &types)
{
gcc_assert(type);
const enum tree_code code = TREE_CODE(type);
@@ -81,26 +228,27 @@ collect_types_from_record_or_union_type(const_tree type, typeset &types)
for (tree field = TYPE_FIELDS(type) ; field ; field = DECL_CHAIN(field))
{
const_tree field_type = TREE_TYPE(field);
+ gcc_assert(field_type);
collect_types(field_type, types);
}
}
static void
-collect_types_from_record_type(const_tree type, typeset &types)
+collect_types_from_record_type(const_tree type, ptrset_t &types)
{
assert_is_type(type, RECORD_TYPE);
collect_types_from_record_or_union_type(type, types);
}
static void
-collect_types_from_union_type(const_tree type, typeset &types)
+collect_types_from_union_type(const_tree type, ptrset_t &types)
{
assert_is_type(type, UNION_TYPE);
collect_types_from_record_or_union_type(type, types);
}
static void
-collect_types_from_wrapper_type(const_tree type, typeset &types)
+collect_types_from_wrapper_type(const_tree type, ptrset_t &types)
{
gcc_assert(type);
const_tree inner_type = TREE_TYPE(type);
@@ -109,28 +257,28 @@ collect_types_from_wrapper_type(const_tree type, typeset &types)
}
static void
-collect_types_from_pointer_type(const_tree type, typeset &types)
+collect_types_from_pointer_type(const_tree type, ptrset_t &types)
{
assert_is_type(type, POINTER_TYPE);
collect_types_from_wrapper_type(type, types);
}
static void
-collect_types_from_reference_type(const_tree type, typeset &types)
+collect_types_from_reference_type(const_tree type, ptrset_t &types)
{
assert_is_type(type, REFERENCE_TYPE);
collect_types_from_wrapper_type(type, types);
}
static void
-collect_types_from_array_type(const_tree type, typeset &types)
+collect_types_from_array_type(const_tree type, ptrset_t &types)
{
assert_is_type(type, ARRAY_TYPE);
collect_types_from_wrapper_type(type, types);
}
static void
-collect_types_from_function_or_method_type(const_tree type, typeset &types)
+collect_types_from_function_or_method_type(const_tree type, ptrset_t &types)
{
gcc_assert(type);
const enum tree_code code = TREE_CODE(type);
@@ -147,31 +295,71 @@ collect_types_from_function_or_method_type(const_tree type, typeset &types)
while (NULL_TREE != arg_node)
{
tree arg_node_type = TREE_VALUE(arg_node);
+ gcc_assert(arg_node_type);
collect_types(arg_node_type, types);
arg_node = TREE_CHAIN(arg_node);
}
}
static void
-collect_types_from_function_type(const_tree type, typeset &types)
+collect_types_from_function_type(const_tree type, ptrset_t &types)
{
assert_is_type(type, FUNCTION_TYPE);
collect_types_from_function_or_method_type(type, types);
}
static void
-collect_types_from_method_type(const_tree type, typeset &types)
+collect_types_from_method_type(const_tree type, ptrset_t &types)
{
assert_is_type(type, METHOD_TYPE);
collect_types_from_function_or_method_type(type, types);
}
void
-collect_types(const_tree type, typeset &types)
+points_to_record_sets_s::insert(const_tree type, bool in_points_to_record)
+{
+ gcc_assert(type);
+ this->universe.insert(type);
+ in_points_to_record ? this->points_to_record.insert(type) : this->complement.insert(type);
+ // let's just double check...
+ const bool in_points_to_set = this->in_points_to_record(type);
+ const bool in_complement = this->in_complement(type);
+ const bool _xor = in_points_to_set != in_complement;
+ gcc_assert(_xor);
+}
+
+bool
+points_to_record_sets_s::in_universe(const_tree type) const
+{
+ gcc_assert(type);
+ const bool seen_before = this->universe.find(type) != this->universe.end();
+ return seen_before;
+}
+
+bool
+points_to_record_sets_s::in_points_to_record(const_tree type) const
+{
+ gcc_assert(type);
+ const bool seen_before = this->points_to_record.find(type) != this->points_to_record.end();
+ return seen_before;
+}
+
+bool
+points_to_record_sets_s::in_complement(const_tree type) const
+{
+ gcc_assert(type);
+ const bool seen_before = this->complement.find(type) != this->complement.end();
+ return seen_before;
+}
+
+void
+collect_types(const_tree type, ptrset_t &types)
{
if (!type) return;
- const bool in_set = types.find(type) != types.end();
+ // This should be the only case we call to find if
+ // we have seen the type before!
+ const bool in_set = types.in_universe(type);
// memoized.
if (in_set) return;
@@ -181,10 +369,10 @@ collect_types(const_tree type, typeset &types)
// then we just return immediately.
// maybe even add it to a set of blacklisted types so that we
// memoize and do things faster...
+ bool is_boring = false;
for (unsigned i = 0; i < filter_buffer_size; i++)
{
- const bool filter_out = filter[i](type);
- if (filter_out) return;
+ is_boring |= filter[i](type, types);
}
const enum tree_code code = TREE_CODE(type);
@@ -198,15 +386,8 @@ collect_types(const_tree type, typeset &types)
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
case OFFSET_TYPE:
- types.insert(type);
- return;
- break;
- default:
+ // simple cases and we want to allow them
break;
- }
-
- switch (code)
- {
case RECORD_TYPE:
collect_types_from_record_type(type, types);
break;
@@ -236,5 +417,6 @@ collect_types(const_tree type, typeset &types)
break;
}
- types.insert(type);
+ // This should be one the two only times we call insert!
+ types.insert(type, !is_boring);
}
diff --git a/gcc/collect-types.h b/gcc/collect-types.h
index 315c19abfd7..883c08d36dc 100644
--- a/gcc/collect-types.h
+++ b/gcc/collect-types.h
@@ -4,4 +4,16 @@
#include <set>
typedef std::set<const_tree> typeset;
-extern void collect_types(const_tree type, typeset &types);
+struct points_to_record_sets_s {
+ typeset universe;
+ typeset points_to_record;
+ typeset complement;
+ bool in_universe(const_tree) const;
+ bool in_points_to_record(const_tree) const;
+ bool in_complement(const_tree) const;
+ void insert(const_tree, bool);
+};
+
+typedef struct points_to_record_sets_s ptrset_t;
+
+extern void collect_types(const_tree type, ptrset_t &ptrset_t);
diff --git a/gcc/ipa-escape-analysis.c b/gcc/ipa-escape-analysis.c
index ba0ae26c88e..04023a406a5 100644
--- a/gcc/ipa-escape-analysis.c
+++ b/gcc/ipa-escape-analysis.c
@@ -36,7 +36,7 @@
#include "collect-types.h"
#include "name-types.h"
-#define FUZZ_MODE 0
+//#define FUZZ_MODE 1
namespace type_playground {
enum type_comparison_func_enum {
@@ -70,7 +70,7 @@ static type_comparison_func_t comparisons[type_comparisons] = {
eq_type_compare
};
}
-static void collect_types_from_expr(const_tree expr, typeset &types);
+static void collect_types_from_expr(const_tree expr, ptrset_t &types);
inline void
is_gimple_code(gimple *stmt, const enum gimple_code ex_code)
@@ -92,7 +92,7 @@ is_gimple_rhs_class(gimple *stmt, const enum gimple_rhs_class ex_class)
}
static void
-collect_types_from_op(const_tree expr, typeset &types, unsigned n)
+collect_types_from_op(const_tree expr, ptrset_t &types, unsigned n)
{
gcc_assert(expr);
const_tree op_n = TREE_OPERAND(expr, n);
@@ -101,14 +101,14 @@ collect_types_from_op(const_tree expr, typeset &types, unsigned n)
}
static void
-collect_types_from_op0(const_tree expr, typeset &types, const enum tree_code ex_code)
+collect_types_from_op0(const_tree expr, ptrset_t &types, const enum tree_code ex_code)
{
assert_is_type(expr, ex_code);
collect_types_from_op(expr, types, 0);
}
static void
-collect_types_from_op1(const_tree expr, typeset &types, const enum tree_code ex_code)
+collect_types_from_op1(const_tree expr, ptrset_t &types, const enum tree_code ex_code)
{
assert_is_type(expr, ex_code);
collect_types_from_op(expr, types, 0);
@@ -116,31 +116,31 @@ collect_types_from_op1(const_tree expr, typeset &types, const enum tree_code ex_
}
static void
-collect_types_from_addr_expr(const_tree expr, typeset &types)
+collect_types_from_addr_expr(const_tree expr, ptrset_t &types)
{
collect_types_from_op0(expr, types, ADDR_EXPR);
}
static void
-collect_types_from_component_ref(const_tree expr, typeset &types)
+collect_types_from_component_ref(const_tree expr, ptrset_t &types)
{
collect_types_from_op1(expr, types, COMPONENT_REF);
}
static void
-collect_types_from_mem_ref(const_tree expr, typeset &types)
+collect_types_from_mem_ref(const_tree expr, ptrset_t &types)
{
collect_types_from_op1(expr, types, MEM_REF);
}
static void
-collect_types_from_array_ref(const_tree expr, typeset &types)
+collect_types_from_array_ref(const_tree expr, ptrset_t &types)
{
collect_types_from_op1(expr, types, ARRAY_REF);
}
static void
-collect_types_from_leaf_expr(const_tree expr, typeset &types, const enum tree_code ex_code)
+collect_types_from_leaf_expr(const_tree expr, ptrset_t &types, const enum tree_code ex_code)
{
assert_is_type(expr, ex_code);
const_tree type = TREE_TYPE(expr);
@@ -149,31 +149,31 @@ collect_types_from_leaf_expr(const_tree expr, typeset &types, const enum tree_co
}
static void
-collect_types_from_ssa_name(const_tree expr, typeset &types)
+collect_types_from_ssa_name(const_tree expr, ptrset_t &types)
{
collect_types_from_leaf_expr(expr, types, SSA_NAME);
}
static void
-collect_types_from_var_decl(const_tree expr, typeset &types)
+collect_types_from_var_decl(const_tree expr, ptrset_t &types)
{
collect_types_from_leaf_expr(expr, types, VAR_DECL);
}
static void
-collect_types_from_field_decl(const_tree expr, typeset &types)
+collect_types_from_field_decl(const_tree expr, ptrset_t &types)
{
collect_types_from_leaf_expr(expr, types, FIELD_DECL);
}
static void
-collect_types_from_integer_cst(const_tree expr, typeset &types)
+collect_types_from_integer_cst(const_tree expr, ptrset_t &types)
{
collect_types_from_leaf_expr(expr, types, INTEGER_CST);
}
static void
-collect_types_from_constructor_array(const_tree expr, typeset &types)
+collect_types_from_constructor_array(const_tree expr, ptrset_t &types)
{
assert_is_type(expr, CONSTRUCTOR);
const_tree type = TREE_TYPE(expr);
@@ -185,7 +185,7 @@ collect_types_from_constructor_array(const_tree expr, typeset &types)
}
static void
-collect_types_from_constructor_record_or_union(const_tree expr, typeset &types)
+collect_types_from_constructor_record_or_union(const_tree expr, ptrset_t &types)
{
assert_is_type(expr, CONSTRUCTOR);
const_tree type = TREE_TYPE(expr);
@@ -202,7 +202,7 @@ collect_types_from_constructor_record_or_union(const_tree expr, typeset &types)
}
static void
-collect_types_from_constructor(const_tree expr, typeset &types)
+collect_types_from_constructor(const_tree expr, ptrset_t &types)
{
// https://gcc.gnu.org/onlinedocs/gccint/Unary-and-Binary-Expressions.html#Unary-and-Binary-Expressions
// These nodes represent the brace-enclosed initializers for a structure or an array.
@@ -242,25 +242,25 @@ collect_types_from_constructor(const_tree expr, typeset &types)
}
static void
-collect_types_from_parm_decl(const_tree expr, typeset &types)
+collect_types_from_parm_decl(const_tree expr, ptrset_t &types)
{
collect_types_from_leaf_expr(expr, types, PARM_DECL);
}
static void
-collect_types_from_real_cst(const_tree expr, typeset &types)
+collect_types_from_real_cst(const_tree expr, ptrset_t &types)
{
collect_types_from_leaf_expr(expr, types, REAL_CST);
}
static void
-collect_types_from_string_cst(const_tree expr, typeset &types)
+collect_types_from_string_cst(const_tree expr, ptrset_t &types)
{
collect_types_from_leaf_expr(expr, types, STRING_CST);
}
static void
-collect_types_from_bit_field_ref(const_tree expr, typeset &types)
+collect_types_from_bit_field_ref(const_tree expr, ptrset_t &types)
{
// TODO: How to collect types from bit_field_ref?
#ifdef FUZZ_MODE
@@ -269,7 +269,7 @@ collect_types_from_bit_field_ref(const_tree expr, typeset &types)
}
static void
-collect_types_from_view_convert_expr(const_tree expr, typeset &types)
+collect_types_from_view_convert_expr(const_tree expr, ptrset_t &types)
{
// VIEW_CONVERT_EXPR is used to interpret the bit representation
// of a register as a register of a different type.
@@ -284,13 +284,13 @@ collect_types_from_view_convert_expr(const_tree expr, typeset &types)
}
static void
-collect_types_from_result_decl(const_tree expr, typeset &types)
+collect_types_from_result_decl(const_tree expr, ptrset_t &types)
{
collect_types_from_leaf_expr(expr, types, RESULT_DECL);
}
static void
-collect_types_from_expr(const_tree expr, typeset &types)
+collect_types_from_expr(const_tree expr, ptrset_t &types)
{
// These are the codes I saw using csmith to fuzz.
gcc_assert(expr);
@@ -353,7 +353,7 @@ collect_types_from_expr(const_tree expr, typeset &types)
}
static void
-collect_types_from_stmt_assign_lhs(gimple *stmt, typeset &types)
+collect_types_from_stmt_assign_lhs(gimple *stmt, ptrset_t &types)
{
is_gimple_code(stmt, GIMPLE_ASSIGN);
const_tree lhs = gimple_assign_lhs(stmt);
@@ -362,7 +362,7 @@ collect_types_from_stmt_assign_lhs(gimple *stmt, typeset &types)
}
static void
-collect_types_from_stmt_assign_rhs3(gimple *stmt, typeset &types)
+collect_types_from_stmt_assign_rhs3(gimple *stmt, ptrset_t &types)
{
is_gimple_rhs_class(stmt, GIMPLE_TERNARY_RHS);
const_tree rhs = gimple_assign_rhs3(stmt);
@@ -371,7 +371,7 @@ collect_types_from_stmt_assign_rhs3(gimple *stmt, typeset &types)
}
static void
-collect_types_from_stmt_assign_rhs2(gimple *stmt, typeset &types)
+collect_types_from_stmt_assign_rhs2(gimple *stmt, ptrset_t &types)
{
is_gimple_code(stmt, GIMPLE_ASSIGN);
const enum gimple_rhs_class gclass = gimple_assign_rhs_class(stmt);
@@ -385,7 +385,7 @@ collect_types_from_stmt_assign_rhs2(gimple *stmt, typeset &types)
}
static void
-collect_types_from_stmt_assign_rhs1(gimple *stmt, typeset &types)
+collect_types_from_stmt_assign_rhs1(gimple *stmt, ptrset_t &types)
{
is_gimple_code(stmt, GIMPLE_ASSIGN);
const enum gimple_rhs_class gclass = gimple_assign_rhs_class(stmt);
@@ -401,7 +401,7 @@ collect_types_from_stmt_assign_rhs1(gimple *stmt, typeset &types)
}
static void
-collect_types_from_stmt_assign_rhs(gimple *stmt, typeset &types)
+collect_types_from_stmt_assign_rhs(gimple *stmt, ptrset_t &types)
{
is_gimple_code(stmt, GIMPLE_ASSIGN);
const enum gimple_rhs_class gclass = gimple_assign_rhs_class(stmt);
@@ -424,7 +424,7 @@ collect_types_from_stmt_assign_rhs(gimple *stmt, typeset &types)
}
static void
-collect_types_from_stmt_assign(gimple *stmt, typeset &types)
+collect_types_from_stmt_assign(gimple *stmt, ptrset_t &types)
{
is_gimple_code(stmt, GIMPLE_ASSIGN);
collect_types_from_stmt_assign_lhs(stmt, types);
@@ -432,7 +432,7 @@ collect_types_from_stmt_assign(gimple *stmt, typeset &types)
}
static void
-collect_types_from_stmt_call_lhs(gimple *stmt, typeset &types)
+collect_types_from_stmt_call_lhs(gimple *stmt, ptrset_t &types)
{
is_gimple_code(stmt, GIMPLE_CALL);
const_tree lhs = gimple_call_lhs(stmt);
@@ -441,7 +441,7 @@ collect_types_from_stmt_call_lhs(gimple *stmt, typeset &types)
}
static void
-collect_types_from_stmt_call_rhs(gimple *stmt, typeset &types)
+collect_types_from_stmt_call_rhs(gimple *stmt, ptrset_t &types)
{
is_gimple_code(stmt, GIMPLE_CALL);
unsigned num_args = gimple_call_num_args(stmt);
@@ -453,7 +453,7 @@ collect_types_from_stmt_call_rhs(gimple *stmt, typeset &types)
}
static void
-collect_types_from_stmt_call(gimple *stmt, typeset &types)
+collect_types_from_stmt_call(gimple *stmt, ptrset_t &types)
{
is_gimple_code(stmt, GIMPLE_CALL);
collect_types_from_stmt_call_lhs(stmt, types);
@@ -461,7 +461,7 @@ collect_types_from_stmt_call(gimple *stmt, typeset &types)
}
static void
-collect_types_from_stmt_cond_lhs(gimple *stmt, typeset &types)
+collect_types_from_stmt_cond_lhs(gimple *stmt, ptrset_t &types)
{
is_gimple_code(stmt, GIMPLE_COND);
const_tree lhs = gimple_cond_lhs(stmt);
@@ -470,7 +470,7 @@ collect_types_from_stmt_cond_lhs(gimple *stmt, typeset &types)
}
static void
-collect_types_from_stmt_cond_rhs(gimple *stmt, typeset &types)
+collect_types_from_stmt_cond_rhs(gimple *stmt, ptrset_t &types)
{
is_gimple_code(stmt, GIMPLE_COND);
const_tree rhs = gimple_cond_rhs(stmt);
@@ -479,7 +479,7 @@ collect_types_from_stmt_cond_rhs(gimple *stmt, typeset &types)
}
static void
-collect_types_from_stmt_cond(gimple *stmt, typeset &types)
+collect_types_from_stmt_cond(gimple *stmt, ptrset_t &types)
{
is_gimple_code(stmt, GIMPLE_COND);
collect_types_from_stmt_cond_lhs(stmt, types);
@@ -487,7 +487,7 @@ collect_types_from_stmt_cond(gimple *stmt, typeset &types)
}
static void
-collect_types_from_stmt_return(gimple *stmt, typeset &types)
+collect_types_from_stmt_return(gimple *stmt, ptrset_t &types)
{
is_gimple_code(stmt, GIMPLE_RETURN);
const_tree retval = gimple_return_retval(stmt);
@@ -496,7 +496,7 @@ collect_types_from_stmt_return(gimple *stmt, typeset &types)
}
static void
-collect_types_from_stmt(gimple *stmt, typeset &types)
+collect_types_from_stmt(gimple *stmt, ptrset_t &types)
{
gcc_assert(stmt);
const enum gimple_code code = gimple_code(stmt);
@@ -530,7 +530,7 @@ collect_types_from_stmt(gimple *stmt, typeset &types)
}
static void
-collect_types_from_cnode_decl(cgraph_node *cnode, typeset &types)
+collect_types_from_cnode_decl(cgraph_node *cnode, ptrset_t &types)
{
gcc_assert(cnode);
const_tree decl = cnode->decl;
@@ -546,7 +546,7 @@ collect_types_from_cnode_decl(cgraph_node *cnode, typeset &types)
}
static void
-collect_types_from_cnode_locals(cgraph_node *cnode, typeset &types)
+collect_types_from_cnode_locals(cgraph_node *cnode, ptrset_t &types)
{
gcc_assert(cnode);
const_tree decl = cnode->decl;
@@ -564,7 +564,7 @@ collect_types_from_cnode_locals(cgraph_node *cnode, typeset &types)
}
static void
-collect_types_from_cnode_ssa_names(cgraph_node *cnode, typeset &types)
+collect_types_from_cnode_ssa_names(cgraph_node *cnode, ptrset_t &types)
{
gcc_assert(cnode);
const_tree decl = cnode->decl;
@@ -584,7 +584,7 @@ collect_types_from_cnode_ssa_names(cgraph_node *cnode, typeset &types)
}
static void
-collect_types_from_bb(basic_block bb, typeset &types)
+collect_types_from_bb(basic_block bb, ptrset_t &types)
{
gcc_assert(bb);
for (auto gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi))
@@ -596,7 +596,7 @@ collect_types_from_bb(basic_block bb, typeset &types)
}
static void
-collect_types_from_cnode_bb(cgraph_node *cnode, typeset &types)
+collect_types_from_cnode_bb(cgraph_node *cnode, ptrset_t &types)
{
gcc_assert(cnode);
cnode->get_untransformed_body();
@@ -615,7 +615,30 @@ collect_types_from_cnode_bb(cgraph_node *cnode, typeset &types)
}
static void
-collect_types_from_functions_with_gimple_body(cgraph_node *cnode, typeset &types)
+collect_types_from_global(varpool_node *vnode, ptrset_t &types)
+{
+ gcc_assert(vnode);
+ struct ipa_ref *ref = NULL;
+ for (unsigned i = 0; vnode->iterate_referring(i, ref); i++)
+ {
+ tree decl = vnode->decl;
+ gcc_assert(decl);
+ collect_types_from_var_decl(decl, types);
+ }
+}
+
+static void
+collect_types_from_globals(ptrset_t &types)
+{
+ varpool_node *vnode = NULL;
+ FOR_EACH_VARIABLE (vnode)
+ {
+ collect_types_from_global(vnode, types);
+ }
+}
+
+static void
+collect_types_from_functions_with_gimple_body(cgraph_node *cnode, ptrset_t &types)
{
gcc_assert(cnode);
collect_types_from_cnode_decl(cnode, types);
@@ -625,9 +648,9 @@ collect_types_from_functions_with_gimple_body(cgraph_node *cnode, typeset &types
}
static void
-print_types_in_set(typeset &types)
+print_types_in_set(ptrset_t &types)
{
- for (auto it = types.cbegin(); it != types.cend(); ++it)
+ for (auto it = types.points_to_record.cbegin(); it != types.points_to_record.cend(); ++it)
{
const_tree type = *it;
std::string name = type_to_string(type);
@@ -685,11 +708,11 @@ filter_comparisons_functions(type_playground::type_comparison_func_t func)
static void
-compare_types_in_set(typeset &types)
+compare_types_in_set(ptrset_t &types)
{
- for (auto i = types.cbegin(); i != types.cend(); ++i)
+ for (auto i = types.points_to_record.cbegin(); i != types.points_to_record.cend(); ++i)
{
- for (auto j = types.cbegin(); j != types.cend(); ++j)
+ for (auto j = types.points_to_record.cbegin(); j != types.points_to_record.cend(); ++j)
{
const_tree a = *i;
const_tree b = *j;
@@ -709,7 +732,7 @@ compare_types_in_set(typeset &types)
}
static void
-filter_out_types_in_set(typeset &types)
+filter_out_types_in_set(ptrset_t &types)
{
// compare everything
if (!flag_tp_types_compared) return;
@@ -721,7 +744,7 @@ filter_out_types_in_set(typeset &types)
strcpy(whitelist, flag_tp_types_compared);
bool name_allowed = false;
- for (auto it = types.cbegin(); it != types.cend(); name_allowed ? ++it : it = types.erase(it))
+ for (auto it = types.points_to_record.cbegin(); it != types.points_to_record.cend(); name_allowed ? ++it : it = types.points_to_record.erase(it))
{
const_tree type = *it;
std::string observed_name = get_type_identifier(type);
@@ -737,22 +760,29 @@ filter_out_types_in_set(typeset &types)
}
-static unsigned int
-iphw_execute()
+static void
+collect_types(ptrset_t &types)
{
- //test_type_equality::run_tests();
- //test_naming_types::run_tests();
- cgraph_node *node = NULL;
- typeset types;
+ collect_types_from_globals(types);
+ cgraph_node *node = NULL;
FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node)
{
node->get_untransformed_body();
collect_types_from_functions_with_gimple_body(node, types);
+ // We still need to collect types from
+ // the function signatures of functions without gimple bodies...
}
+}
+
+static unsigned int
+iphw_execute()
+{
+ //test_type_equality::run_tests();
+ //test_naming_types::run_tests();
+ ptrset_t types;
- // We still need to collect types from
- // the function signatures of functions without gimple bodies...
+ collect_types(types);
filter_out_types_in_set(types);
compare_types_in_set(types);
return 0;