summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-05-12 14:31:03 +0200
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-05-12 14:31:03 +0200
commitf72812666c3f2b4f0762cfca060c3b54ac4722a5 (patch)
treeeab70451406c97c62c358872350165d5e213c6ef
parentff0bfd0e2a7e92132660aa2527878aa84e974edd (diff)
Adds ability to use only specified comparison functions
-rwxr-xr-xbuild.sh2
-rw-r--r--gcc/collect-types.c2
-rw-r--r--gcc/common.opt6
-rw-r--r--gcc/compare-types.c15
-rw-r--r--gcc/compare-types.h2
-rw-r--r--gcc/ipa-hello-world.c73
-rw-r--r--gcc/name-types.c18
-rw-r--r--gcc/name-types.h1
8 files changed, 116 insertions, 3 deletions
diff --git a/build.sh b/build.sh
index b87c079a48c..711b8c4bd56 100755
--- a/build.sh
+++ b/build.sh
@@ -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();