diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-05-12 14:31:03 +0200 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-05-12 14:31:03 +0200 |
commit | f72812666c3f2b4f0762cfca060c3b54ac4722a5 (patch) | |
tree | eab70451406c97c62c358872350165d5e213c6ef | |
parent | ff0bfd0e2a7e92132660aa2527878aa84e974edd (diff) |
Adds ability to use only specified comparison functions
-rwxr-xr-x | build.sh | 2 | ||||
-rw-r--r-- | gcc/collect-types.c | 2 | ||||
-rw-r--r-- | gcc/common.opt | 6 | ||||
-rw-r--r-- | gcc/compare-types.c | 15 | ||||
-rw-r--r-- | gcc/compare-types.h | 2 | ||||
-rw-r--r-- | gcc/ipa-hello-world.c | 73 | ||||
-rw-r--r-- | gcc/name-types.c | 18 | ||||
-rw-r--r-- | gcc/name-types.h | 1 |
8 files changed, 116 insertions, 3 deletions
@@ -3,7 +3,7 @@ set -e set -u -installdir=${1:-"gcc-inst2"} +installdir=${1:-"gcc-inst"} mkdir -p $HOME/code/gcc-build/ mkdir -p $HOME/code/${installdir}/ pushd $HOME/code/gcc-build/ diff --git a/gcc/collect-types.c b/gcc/collect-types.c index 0d05c7bdb4d..3f04e0f8d45 100644 --- a/gcc/collect-types.c +++ b/gcc/collect-types.c @@ -50,7 +50,7 @@ filter_out_simple_types(const_tree type) case ENUMERAL_TYPE: case BOOLEAN_TYPE: case OFFSET_TYPE: - return true; + return false; break; default: return false; diff --git a/gcc/common.opt b/gcc/common.opt index 09cabeb114d..dd505be948c 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -3412,4 +3412,10 @@ fipa-hello-world Common Report Var(flag_ipa_hello_world) Optimization TBD +ftp-types-compared= +Common Joined Report Var(flag_tp_types_compared) Init(0) + +ftp-comparison-functions= +Common Joined Report Var(flag_tp_comparison_functions) Init(0) + ; This comment is to ensure we retain the blank line above. diff --git a/gcc/compare-types.c b/gcc/compare-types.c index 752f4cfbd0d..33021d5feb0 100644 --- a/gcc/compare-types.c +++ b/gcc/compare-types.c @@ -30,6 +30,7 @@ #include "compare-types.h" #include "types-inlines.h" +#include "name-types.h" bool eq_main_variant(const_tree a, const_tree b) @@ -187,6 +188,20 @@ eq_method_types(const_tree a, const_tree b, const bool force_structural) static bool eq_structural(const_tree a, const_tree b, const bool force_structural = false); +bool +eq_pointer(const_tree a, const_tree b) +{ + return a == b; +} + +bool +eq_identifier(const_tree a, const_tree b) +{ + std::string name_a = get_type_identifier(a); + std::string name_b = get_type_identifier(b); + return name_a.compare(name_b) == 0; +} + static bool eq_structural(const_tree a, const_tree b, const bool force_structural) { diff --git a/gcc/compare-types.h b/gcc/compare-types.h index 68a79ce4c0a..7f33684e927 100644 --- a/gcc/compare-types.h +++ b/gcc/compare-types.h @@ -1,6 +1,8 @@ #pragma once namespace test_type_equality { void run_tests(); }; +extern bool eq_identifier(const_tree a, const_tree b); +extern bool eq_pointer(const_tree a, const_tree b); extern bool eq_main_variant(const_tree a, const_tree b); extern bool eq_canonical(const_tree a, const_tree b); extern bool eq_type_compare(const_tree a, const_tree b); diff --git a/gcc/ipa-hello-world.c b/gcc/ipa-hello-world.c index e7cd5400282..b3f85d2e85c 100644 --- a/gcc/ipa-hello-world.c +++ b/gcc/ipa-hello-world.c @@ -37,9 +37,28 @@ #include "name-types.h" namespace type_playground { -static unsigned const type_comparisons = 4; +enum type_comparison_func_enum { + EQ_POINTER = 0, + EQ_IDENTIFIER, + EQ_MAIN_VARIANT, + EQ_CANONICAL, + EQ_STRUCTURAL, + EQ_COMPARE, + EQ_END +}; +static unsigned const type_comparisons = EQ_END; +static const char* names[type_comparisons] = { + "EQ_POINTER", + "EQ_IDENTIFIER", + "EQ_MAIN_VARIANT", + "EQ_CANONICAL", + "EQ_STRUCTURAL", + "EQ_COMPARE" +}; typedef bool (*type_comparison_func_t)(const_tree, const_tree); static type_comparison_func_t comparisons[type_comparisons] = { + eq_pointer, + eq_identifier, eq_main_variant, eq_canonical, eq_type_structural, @@ -132,6 +151,55 @@ print_types_in_set(typeset &types) } } +static const bool +filter_comparisons_functions_char(const char* function_name) +{ + // Everything should run + if (!flag_tp_comparison_functions) return true; + + const size_t buffer_size = 1024; + const size_t cli_length = strlen(flag_tp_comparison_functions); + gcc_assert(buffer_size > cli_length); + char whitelist[buffer_size]; + strcpy(whitelist, flag_tp_comparison_functions); + + + char* saveptr = whitelist; + char* token = NULL; + while (token = strtok_r(saveptr, ",", &saveptr)) + { + const bool name_allowed = strcmp(token, function_name) == 0; + if (name_allowed) return true; + } + + return false; +} + +static const bool +filter_comparisons_functions_int(unsigned function_id) +{ + if (!flag_tp_comparison_functions) return true; + + const char* function_name = type_playground::names[function_id]; + return filter_comparisons_functions_char(function_name); +} + +static const bool +filter_comparisons_functions(type_playground::type_comparison_func_t func) +{ + if (!flag_tp_comparison_functions) return true; + + for (unsigned i = 0; i < type_playground::type_comparisons; i++) + { + if (func != type_playground::comparisons[i]) continue; + + return filter_comparisons_functions_int(i); + } + + return false; +} + + static void compare_types_in_set(typeset &types) { @@ -145,6 +213,9 @@ compare_types_in_set(typeset &types) for (unsigned k = 0; k < type_playground::type_comparisons; k++) { type_playground::type_comparison_func_t comparison = type_playground::comparisons[k]; + const bool allowed_to_run = filter_comparisons_functions(comparison); + if (!allowed_to_run) continue; + const bool result = comparison(a, b); log("%s, ", result ? "t" : "f"); } diff --git a/gcc/name-types.c b/gcc/name-types.c index 693ebf28400..44ff4021153 100644 --- a/gcc/name-types.c +++ b/gcc/name-types.c @@ -105,6 +105,24 @@ type_to_string_get_type_size(const_tree type) return 0; } +const std::string +get_type_identifier(const_tree type) +{ + tree name = TYPE_NAME(type); + // The TYPE_NAME will be NULL_TREE for a type + // that is not a built-in type, the result of a typedef + // or a named class type. + const bool no_name = NULL_TREE == name; + if (no_name) return std::string(""); + + const enum tree_code name_code = TREE_CODE(name); + const bool is_name_type_decl = TYPE_DECL == name_code; + name = is_name_type_decl ? DECL_NAME(name) : name; + const char* identifier_ptr = IDENTIFIER_POINTER(name); + gcc_assert(identifier_ptr); + return std::string(identifier_ptr); +} + static const std::string type_to_string_get_record_name(const_tree type) { diff --git a/gcc/name-types.h b/gcc/name-types.h index a56b459b87f..538956fdd5d 100644 --- a/gcc/name-types.h +++ b/gcc/name-types.h @@ -4,6 +4,7 @@ #include <string> const std::string type_to_string(const_tree type, const unsigned field_offset=0, const bool add_prelude=true); +const std::string get_type_identifier(const_tree type); namespace test_naming_types { void run_tests(); |