From a22362346872039fa01a22fc8dc2c26de16d24a0 Mon Sep 17 00:00:00 2001 From: Erick Ochoa Date: Thu, 14 May 2020 14:39:09 +0200 Subject: Adds globals --- gcc/collect-types.c | 258 +++++++++++++++++++++++++++++++++++++++------- gcc/collect-types.h | 14 ++- gcc/ipa-escape-analysis.c | 148 +++++++++++++++----------- 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 #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 typedef std::set 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; -- cgit v1.2.3