summaryrefslogtreecommitdiff
path: root/gcc/collect-types.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/collect-types.c')
-rw-r--r--gcc/collect-types.c377
1 files changed, 7 insertions, 370 deletions
diff --git a/gcc/collect-types.c b/gcc/collect-types.c
index 3ebd6ff975e..da66bb11fa2 100644
--- a/gcc/collect-types.c
+++ b/gcc/collect-types.c
@@ -30,324 +30,29 @@
#include "compare-types.h"
#include "types-inlines.h"
+#include "type-stringifier.hpp"
#include "name-types.h"
#include <set>
#include "collect-types.h"
-static bool filter_boring_types(const_tree type, ptrset_t &);
-
-static bool
-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_union_or_record(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_record = RECORD_TYPE == code;
- const bool is_valid_input = is_union || is_qual_union || is_record;
- gcc_assert(is_valid_input);
-
- bool is_interesting = is_record;
- for (tree field = TYPE_FIELDS(type) ; field ; field = DECL_CHAIN(field))
- {
- // TYPE_FIELDS contains the items contained in this type, each of which can be a FIELD_DECL, VAR_DECL, CONST_DECL, or TYPE_DECL
- const_tree field_type = TREE_TYPE(field);
- gcc_assert(field_type);
- is_interesting |= filter_boring_types(field_type, types);
- }
-
- return !is_interesting;
-}
-
-static bool
-filter_boring_types_record(const_tree type, ptrset_t &types)
-{
- return filter_boring_types_union_or_record(type, types);
-}
-
-static bool
-filter_boring_types_unions(const_tree type, ptrset_t &types)
-{
- return filter_boring_types_union_or_record(type, types);
-}
-
-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:
- is_boring = true;
- break;
- case ARRAY_TYPE:
- is_boring = filter_boring_types_array(type, types);
- break;
- case RECORD_TYPE:
- is_boring = filter_boring_types_record(type, types);
- is_boring = false;
- 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:
- log("tree_code: %s\n", get_tree_code_name(code));
- gcc_unreachable();
- break;
- }
-
- // 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, ptrset_t&);
-const extern filter_t filter[filter_buffer_size] =
-{
- filter_boring_types,
-};
-
-static void
-collect_types_from_record_or_union_type(const_tree type, ptrset_t &types)
-{
- gcc_assert(type);
- const enum tree_code code = TREE_CODE(type);
- const bool is_union = UNION_TYPE == code;
- const bool is_record = RECORD_TYPE == code;
- const bool is_qual_union = QUAL_UNION_TYPE == code;
- const bool is_valid_input = is_record || 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);
- collect_types(field_type, types);
- }
-}
-
-static void
-collect_types_from_record_type(const_tree type, ptrset_t &types)
-{
- assert_is_complete_type(type, RECORD_TYPE);
- collect_types_from_record_or_union_type(type, types);
-}
-
-static void
-collect_types_from_union_type(const_tree type, ptrset_t &types)
-{
- assert_is_complete_type(type, UNION_TYPE);
- collect_types_from_record_or_union_type(type, types);
-}
-
-static void
-collect_types_from_wrapper_type(const_tree type, ptrset_t &types)
-{
- gcc_assert(type);
- //assert_is_complete(type);
- const_tree inner_type = TREE_TYPE(type);
- gcc_assert(inner_type);
- collect_types(inner_type, types);
-}
-
-static void
-collect_types_from_pointer_type(const_tree type, ptrset_t &types)
-{
- assert_is_type(type, POINTER_TYPE);
- assert_is_complete(type);
- collect_types_from_wrapper_type(type, types);
-}
-
-static void
-collect_types_from_reference_type(const_tree type, ptrset_t &types)
-{
- assert_is_complete_type(type, REFERENCE_TYPE);
- collect_types_from_wrapper_type(type, types);
-}
-
-static void
-collect_types_from_array_type(const_tree type, ptrset_t &types)
-{
- assert_is_complete_type(type, ARRAY_TYPE);
- collect_types_from_wrapper_type(type, types);
-}
-
-static void
-collect_types_from_function_or_method_type(const_tree type, ptrset_t &types)
-{
- gcc_assert(type);
- assert_is_complete(type);
- 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);
- collect_types(ret_type, types);
-
- 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);
- collect_types(arg_node_type, types);
- arg_node = TREE_CHAIN(arg_node);
- }
-}
-
-static void
-collect_types_from_function_type(const_tree type, ptrset_t &types)
-{
- assert_is_complete_type(type, FUNCTION_TYPE);
- collect_types_from_function_or_method_type(type, types);
-}
-
-static void
-collect_types_from_method_type(const_tree type, ptrset_t &types)
-{
- assert_is_complete_type(type, METHOD_TYPE);
- collect_types_from_function_or_method_type(type, types);
-}
void
points_to_record_sets_s::insert(const_tree type, bool in_points_to_record)
{
gcc_assert(type);
this->universe.insert(type);
+ TypeStringifier stringifier;
+ std::string name = stringifier.stringify(type);
+ log("points_to_record %s type %s\n", in_points_to_record ? "t" : "f", name.c_str());
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;
+ if (!_xor) {
+ log("points_to_record %s type %s != %s %s\n", in_points_to_record ? "t" : "f", in_points_to_set ? "t" : "f", in_complement ? "t": "f", name.c_str());
+ }
gcc_assert(_xor);
}
@@ -375,71 +80,3 @@ points_to_record_sets_s::in_complement(const_tree type) const
return seen_before;
}
-void
-collect_types(const_tree type, ptrset_t &types)
-{
- if (!type) return;
-
- // 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;
-
- // we should have filters here
- // such that if we are processing a type
- // which we know somehow that it is not a type we are interested
- // 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++)
- {
- is_boring |= filter[i](type, types);
- }
-
- const 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:
- // simple cases and we want to allow them
- break;
- case RECORD_TYPE:
- collect_types_from_record_type(type, types);
- break;
- case POINTER_TYPE:
- collect_types_from_pointer_type(type, types);
- break;
- case REFERENCE_TYPE:
- collect_types_from_reference_type(type, types);
- break;
- case ARRAY_TYPE:
- collect_types_from_array_type(type, types);
- break;
- case UNION_TYPE:
- collect_types_from_union_type(type, types);
- break;
- case FUNCTION_TYPE:
- collect_types_from_function_type(type, types);
- break;
- case METHOD_TYPE:
- collect_types_from_method_type(type, types);
- break;
- case QUAL_UNION_TYPE:
- case LANG_TYPE:
- default:
- log("%s\n", get_tree_code_name(code));
- gcc_unreachable();
- break;
- }
-
- // This should be one the two only times we call insert!
- types.insert(type, !is_boring);
-}