summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-05-07 14:49:41 +0200
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-09-08 08:55:23 +0200
commit52b9adf126367a5d1bec100a4bb54226b23202cb (patch)
tree05debc3a58a5f93c64c73eb866acc29a0eda3e83
parent8c6f1afdb762cb4635074c415712f2e2adf1b1b9 (diff)
wip
-rwxr-xr-xbuild.sh9
-rw-r--r--gcc/Makefile.in1
-rw-r--r--gcc/ipa-hello-world.c334
3 files changed, 301 insertions, 43 deletions
diff --git a/build.sh b/build.sh
index 97158b0cf59..bde67e5232a 100755
--- a/build.sh
+++ b/build.sh
@@ -3,16 +3,11 @@
set -e
set -u
-installdir=${1:-"gcc-inst"}
+installdir=${1:-"gcc-inst2"}
mkdir -p $HOME/code/gcc-build/
mkdir -p $HOME/code/${installdir}/
pushd $HOME/code/gcc-build/
-if find . -mindepth 1 -print -quit 2>/dev/null | grep -q . ; then
- echo "not empty?"
-else
- $OLDPWD/configure --disable-bootstrap --disable-libsanitizer --enable-__cxa_atexit --enable-shared --disable-libsanitizer --enable-languages=c,c++,fortran --enable-lto --enable-gold --enable-linker-build-id --with-cpu-emag --prefix="$HOME/code/${installdir}/"
-fi
-
+$OLDPWD/configure --disable-bootstrap --disable-libsanitizer --enable-__cxa_atexit --enable-shared --disable-libsanitizer --enable-languages=c,c++,fortran --enable-lto --enable-gold --enable-linker-build-id --with-cpu-emag --prefix="$HOME/code/${installdir}/"
make -j `nproc`
make install -j `nproc`
make check-gcc RUNTESTFLAGS="ipa.exp"
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index c55204ab129..5f5d41c49b7 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1410,6 +1410,7 @@ OBJS = \
internal-fn.o \
ipa-type-escape-analysis.o \
ipa-hello-world.o \
+ compare-types.o \
ipa-cp.o \
ipa-sra.o \
ipa-devirt.o \
diff --git a/gcc/ipa-hello-world.c b/gcc/ipa-hello-world.c
index 00e276a4bd7..d9af11cfb41 100644
--- a/gcc/ipa-hello-world.c
+++ b/gcc/ipa-hello-world.c
@@ -28,6 +28,9 @@
#include "gimple-iterator.h"
#include "gimple-ssa.h"
+#include "compare-types.h"
+#include <set>
+
void inline
log(const char* const fmt, ...)
{
@@ -39,57 +42,316 @@ log(const char* const fmt, ...)
va_end(args);
}
+typedef std::set<const_tree> typeset;
+
+static const bool contains_record_types(const_tree type);
+
+static const bool
+inner_type_contains_record_types(const_tree type)
+{
+ gcc_assert(type);
+ const_tree inner = TREE_TYPE(type);
+ return contains_record_types(inner);
+}
+
+static const bool
+pointer_contains_record_types(const_tree type)
+{
+ assert_is_type(type, POINTER_TYPE);
+ return inner_type_contains_record_types(type);
+}
+
+static const bool
+reference_contains_record_types(const_tree type)
+{
+ assert_is_type(type, REFERENCE_TYPE);
+ return inner_type_contains_record_types(type);
+}
+
+static const bool
+array_contains_record_types(const_tree type)
+{
+ assert_is_type(type, ARRAY_TYPE);
+ return inner_type_contains_record_types(type);
+}
+
+static const bool
+union_contains_record_types(const_tree type)
+{
+ assert_is_type(type, UNION_TYPE);
+ tree field = TYPE_FIELDS(type);
+ while (field)
+ {
+ const_tree field_type = TREE_TYPE(field);
+ gcc_assert(field_type);
+ const bool contains_record = contains_record_types(field_type);
+ if (contains_record) return true;
+
+ field = DECL_CHAIN(field);
+ }
+
+ return false;
+}
+
+static const bool
+function_or_method_contains_record_types(const_tree type)
+{
+ gcc_assert(type);
+ const_tree ret_type = TREE_TYPE(type);
+ const bool return_type_contains_record = contains_record_types(ret_type);
+ if (return_type_contains_record) return true;
+
+ tree parm = TYPE_ARG_TYPES(type);
+
+ while (parm)
+ {
+ const_tree parm_type = TREE_TYPE(parm);
+ const bool parm_type_contains_record = contains_record_types(parm_type);
+ if (parm_type) return true;
+
+ parm = TREE_CHAIN(parm);
+ }
+
+ return false;
+}
+
+static const bool
+function_contains_record_types(const_tree type)
+{
+ assert_is_type(type, FUNCTION_TYPE);
+ return function_or_method_contains_record_types(type);
+}
+
+static const bool
+method_contains_record_types(const_tree type)
+{
+ assert_is_type(type, FUNCTION_TYPE);
+ const_tree base_type = TYPE_METHOD_BASETYPE(type);
+ const bool base_type_contains_record_types = contains_record_types(base_type);
+ return base_type_contains_record_types && function_or_method_contains_record_types(type);
+}
+
+static const bool
+contains_record_types(const_tree type)
+{
+ gcc_assert(type);
+ const enum tree_code code = TREE_CODE(type);
+ if (code == RECORD_TYPE) return true;
+
+ switch (code)
+ {
+ case VOID_TYPE:
+ case INTEGER_TYPE:
+ case REAL_TYPE:
+ case FIXED_POINT_TYPE:
+ case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
+ case OFFSET_TYPE:
+ return false;
+ break;
+ default:
+ break;
+ }
+
+ switch (code)
+ {
+ case POINTER_TYPE:
+ return pointer_contains_record_types(type);
+ break;
+ case REFERENCE_TYPE:
+ return reference_contains_record_types(type);
+ break;
+ case ARRAY_TYPE:
+ return array_contains_record_types(type);
+ break;
+ case UNION_TYPE:
+ return union_contains_record_types(type);
+ break;
+ case FUNCTION_TYPE:
+ return function_contains_record_types(type);
+ break;
+ case METHOD_TYPE:
+ return method_contains_record_types(type);
+ break;
+ case QUAL_UNION_TYPE:
+ case LANG_TYPE:
+ default:
+ gcc_unreachable();
+ break;
+ }
+
+ gcc_unreachable();
+ return false;
+}
+
static void
-alias_experiment_gimple_body(const cgraph_node *cnode)
+get_non_escaping_locals(const cgraph_node *cnode, typeset &escaping_types, typeset &non_escaping_types)
{
gcc_assert(cnode);
-
- function *func = DECL_STRUCT_FUNCTION(cnode->decl);
-
- // We are looking first into SSA becaues of
- // this documentation...
- // Points-to and escape analysis.
- // Points-to analysis builds a set of constraints from the GIMPLE SSA IL
- // representing all pointer operations and facts we do or do not know
- // about pointers. Solving this set of constraints yields a conservatively
- // correct solution for each pointer variable in the program (though we are
- // only interested in SSA name pointers) as to what it may possibly point to.
- // https://gcc.gnu.org/onlinedocs/gccint/Alias-analysis.html
-
- size_t j = 0;
+ function *func = DECL_STRUCT_FUNCTION (cnode->decl);
+ int i = 0;
tree var_decl = NULL;
- FOR_EACH_LOCAL_DECL(func, j, var_decl)
+ FOR_EACH_LOCAL_DECL(func, i, var_decl)
{
- const_tree identifier_node = DECL_NAME(var_decl);
- if (!identifier_node) continue;
- const char* const identifier_pointer = IDENTIFIER_POINTER(identifier_node);
- log("var_decl = %s\n", identifier_pointer);
- if (POINTER_TYPE_P(TREE_TYPE(var_decl))) break;
+
}
+}
+
+static void
+get_non_escaping_types(const cgraph_node *cnode, typeset &escaping_types, typeset &non_escaping_types)
+{
+ gcc_assert(cnode);
+ get_non_escaping_locals(cnode, escaping_types, non_escaping_types);
+}
- size_t i = 0;
- tree ssa_name = NULL;
- push_cfun(func);
- FOR_EACH_SSA_NAME(i, ssa_name, cfun)
+// So, have a set with TYPE_MAIN_VARIANTS...
+typeset
+get_non_escaping_types()
+{
+ cgraph_node *cnode = NULL;
+ typeset non_escaping_types;
+ typeset escaping_types;
+ FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(cnode)
{
- struct ptr_info_def *pi = SSA_NAME_PTR_INFO(ssa_name);
- if (!pi) continue;
- log("i have a pi");
- pt_solution_includes(&pi->pt, var_decl);
+ cnode->get_untransformed_body();
+ get_non_escaping_types(cnode, escaping_types, non_escaping_types);
}
- pop_cfun();
+ return non_escaping_types;
+}
+
+namespace test_type_equality {
+
+static void
+test_main_variant()
+{
+ tree void_a = make_node(VOID_TYPE);
+ tree void_b = build_variant_type_copy(void_a);
+ const bool expected = true;
+ const bool observed = eq_types(void_a, void_b);
+ const bool success = expected == observed;
+ gcc_assert(success);
+}
+
+static void
+test_pointer_types_eq()
+{
+ tree pointer_a = make_node(POINTER_TYPE);
+ tree inner_type = make_node(INTEGER_TYPE);
+ TREE_TYPE(pointer_a) = inner_type;
+ tree pointer_b = build_variant_type_copy(pointer_a);
+ const bool expected = true;
+ const bool observed = eq_types(pointer_a, pointer_b);
+ const bool success = expected == observed;
+ gcc_assert(success);
+}
+
+static void
+test_pointer_types_ne()
+{
+ tree pointer_a = make_node(POINTER_TYPE);
+ tree inner_type_a = make_node(INTEGER_TYPE);
+ TREE_TYPE(pointer_a) = inner_type_a;
+ tree pointer_b = make_node(POINTER_TYPE);
+ tree inner_type_b = make_node(VOID_TYPE);
+ TREE_TYPE(pointer_b) = inner_type_b;
+ const bool expected = false;
+ const bool observed = eq_types(pointer_a, pointer_b, true);
+ const bool success = expected == observed;
+ gcc_assert(success);
+}
+static void
+test_pointer_types_eq_structurally()
+{
+ tree pointer_a = make_node(POINTER_TYPE);
+ tree inner_type_a = make_node(INTEGER_TYPE);
+ TREE_TYPE(pointer_a) = inner_type_a;
+ tree pointer_b = make_node(POINTER_TYPE);
+ tree inner_type_b = make_node(INTEGER_TYPE);
+ TREE_TYPE(pointer_b) = inner_type_b;
+ const bool expected = true;
+ const bool observed = eq_types(pointer_a, pointer_b, true);
+ const bool success = expected == observed;
+ gcc_assert(success);
+}
+
+static void
+test_void_eq()
+{
+ tree void_a = make_node(VOID_TYPE);
+ tree void_b = build_variant_type_copy(void_a);
+ const bool expected = true;
+ const bool observed = eq_types(void_a, void_b, true);
+ const bool success = expected == observed;
+ gcc_assert(success);
+}
+static void
+test_structural_equality_different_types()
+{
+ tree type_a = make_node(VOID_TYPE);
+ tree type_b = make_node(RECORD_TYPE);
+ const bool expected = false;
+ const bool observed = eq_types(type_a, type_b, true);
+ const bool success = expected == observed;
+ gcc_assert(success);
+}
+
+static void
+test_different_record_types()
+{
+ tree type_a = make_node(RECORD_TYPE);
+ tree type_b = make_node(RECORD_TYPE);
+ tree field_a = make_node(FIELD_DECL);
+ tree field_b = make_node(FIELD_DECL);
+ tree type_field_a = make_node(VOID_TYPE);
+ tree type_field_b = make_node(RECORD_TYPE);
+ TREE_TYPE(field_a) = type_field_a;
+ TREE_TYPE(field_b) = type_field_b;
+ TYPE_FIELDS(type_a) = field_a;
+ TYPE_FIELDS(type_b) = field_b;
+ const bool expected = false;
+ const bool observed = eq_types(type_a, type_b, true);
+ const bool success = expected == observed;
+ gcc_assert(success);
}
+static void
+test_same_record_types()
+{
+ tree type_a = make_node(RECORD_TYPE);
+ tree field_a = make_node(FIELD_DECL);
+ tree type_field_a = make_node(VOID_TYPE);
+ TREE_TYPE(field_a) = type_field_a;
+ TYPE_FIELDS(type_a) = field_a;
+ tree type_b = build_variant_type_copy(type_a);
+ const bool expected = true;
+ const bool observed = eq_types(type_a, type_b, true);
+ const bool success = expected == observed;
+ gcc_assert(success);
+}
+
+static void
+run_tests()
+{
+ log("running tests...\n");
+ test_main_variant();
+ test_void_eq();
+ test_structural_equality_different_types();
+ test_different_record_types();
+ test_same_record_types();
+ test_pointer_types_eq_structurally();
+ test_pointer_types_ne();
+ test_pointer_types_eq();
+
+}
+} // test_type_equality
+
static unsigned int
iphw_execute()
{
- cgraph_node *node = NULL;
- FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node)
- {
- alias_experiment_gimple_body (node);
- }
+ //test_type_equality::run_tests();
+ typeset non_escaping = get_non_escaping_types();
return 0;
}
@@ -114,7 +376,7 @@ public:
: simple_ipa_opt_pass(pass_data_ipa_hello_world, ctx)
{}
- virtual bool gate(function*) { return flag_ipa_hello_world; }
+ virtual bool gate(function*) { return false; }
virtual unsigned execute (function*) { return iphw_execute(); }
};
} // anon namespace