aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2015-07-01 12:50:50 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2015-07-01 12:50:50 +0000
commite09abfa408597ec644621b6318d735eb0a2d299d (patch)
treec3c7765d81997c4efc52f8fad6f56a8d17eb693c /gcc
parente807aeaae32697a203928a7900426d011c98dedc (diff)
downloadgcc-e09abfa408597ec644621b6318d735eb0a2d299d.zip
gcc-e09abfa408597ec644621b6318d735eb0a2d299d.tar.gz
gcc-e09abfa408597ec644621b6318d735eb0a2d299d.tar.bz2
PR jit/66700: set TREE_ADDRESSABLE when building an ADDR_EXPR
gcc/jit/ChangeLog: PR jit/66700 * jit-playback.c (jit_mark_addressable): New function. (gcc::jit::playback::lvalue::get_address): Call jit_mark_addressable on the underlying tree. gcc/testsuite/ChangeLog: PR jit/66700 * jit.dg/all-non-failing-tests.h: Add test-pr66700-observing-write-through-ptr.c. * jit.dg/test-pr66700-observing-write-through-ptr.c: New testcase. From-SVN: r225248
Diffstat (limited to 'gcc')
-rw-r--r--gcc/jit/ChangeLog7
-rw-r--r--gcc/jit/jit-playback.c42
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/jit.dg/all-non-failing-tests.h10
-rw-r--r--gcc/testsuite/jit.dg/test-pr66700-observing-write-through-ptr.c109
5 files changed, 175 insertions, 0 deletions
diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog
index 8a89370..baa7b83 100644
--- a/gcc/jit/ChangeLog
+++ b/gcc/jit/ChangeLog
@@ -1,5 +1,12 @@
2015-07-01 David Malcolm <dmalcolm@redhat.com>
+ PR jit/66700
+ * jit-playback.c (jit_mark_addressable): New function.
+ (gcc::jit::playback::lvalue::get_address): Call
+ jit_mark_addressable on the underlying tree.
+
+2015-07-01 David Malcolm <dmalcolm@redhat.com>
+
* docs/topics/types.rst (gcc_jit_context_new_union_type): Add
documentation.
* docs/_build/texinfo/libgccjit.texi: Regenerate.
diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
index c9d7c8c..1fe1091 100644
--- a/gcc/jit/jit-playback.c
+++ b/gcc/jit/jit-playback.c
@@ -1164,6 +1164,47 @@ dereference (location *loc)
return new lvalue (get_context (), datum);
}
+/* Mark EXP saying that we need to be able to take the
+ address of it; it should not be allocated in a register.
+ Compare with e.g. c/c-typeck.c: c_mark_addressable. */
+
+static void
+jit_mark_addressable (tree exp)
+{
+ tree x = exp;
+
+ while (1)
+ switch (TREE_CODE (x))
+ {
+ case COMPONENT_REF:
+ /* (we don't yet support bitfields) */
+ /* fallthrough */
+ case ADDR_EXPR:
+ case ARRAY_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ x = TREE_OPERAND (x, 0);
+ break;
+
+ case COMPOUND_LITERAL_EXPR:
+ case CONSTRUCTOR:
+ TREE_ADDRESSABLE (x) = 1;
+ return;
+
+ case VAR_DECL:
+ case CONST_DECL:
+ case PARM_DECL:
+ case RESULT_DECL:
+ /* (we don't have a concept of a "register" declaration) */
+ /* fallthrough */
+ case FUNCTION_DECL:
+ TREE_ADDRESSABLE (x) = 1;
+ /* fallthrough */
+ default:
+ return;
+ }
+}
+
/* Construct a playback::rvalue instance (wrapping a tree) for an
address-lookup. */
@@ -1177,6 +1218,7 @@ get_address (location *loc)
tree ptr = build1 (ADDR_EXPR, t_ptrtype, t_lvalue);
if (loc)
get_context ()->set_tree_location (ptr, loc);
+ jit_mark_addressable (t_lvalue);
return new rvalue (get_context (), ptr);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ad2cb51..1ff34ca 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,12 @@
2015-07-01 David Malcolm <dmalcolm@redhat.com>
+ PR jit/66700
+ * jit.dg/all-non-failing-tests.h: Add
+ test-pr66700-observing-write-through-ptr.c.
+ * jit.dg/test-pr66700-observing-write-through-ptr.c: New testcase.
+
+2015-07-01 David Malcolm <dmalcolm@redhat.com>
+
* jit.dg/test-accessing-union.c: Add comments for use by
gcc/jit/docs/topics/types.rst.
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index 36a6160..21ff428 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -154,6 +154,13 @@
#undef create_code
#undef verify_code
+/* test-pr66700-observing-write-through-ptr.c */
+#define create_code create_code_pr66700_observing_write_through_ptr
+#define verify_code verify_code_pr66700_observing_write_through_ptr
+#include "test-pr66700-observing-write-through-ptr.c"
+#undef create_code
+#undef verify_code
+
/* test-reading-struct.c */
#define create_code create_code_reading_struct
#define verify_code verify_code_reading_struct
@@ -279,6 +286,9 @@ const struct testcase testcases[] = {
{"nested_loop",
create_code_nested_loop,
verify_code_nested_loop},
+ {"pr66700_observing_write_through_ptr",
+ create_code_pr66700_observing_write_through_ptr,
+ verify_code_pr66700_observing_write_through_ptr},
{"reading_struct ",
create_code_reading_struct ,
verify_code_reading_struct },
diff --git a/gcc/testsuite/jit.dg/test-pr66700-observing-write-through-ptr.c b/gcc/testsuite/jit.dg/test-pr66700-observing-write-through-ptr.c
new file mode 100644
index 0000000..4ffbfac
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-pr66700-observing-write-through-ptr.c
@@ -0,0 +1,109 @@
+/* Test of PR jit/66700. */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ extern void
+ write_back_through_ptr (double *d);
+
+#ifdef __cplusplus
+}
+#endif
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+
+ double
+ test_caller_of_write_back_through_ptr (void)
+ {
+ double d;
+ d = 4.0;
+ write_back_through_ptr (&d);
+ return d;
+ }
+ */
+ gcc_jit_type *t_void =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
+ gcc_jit_type *t_double =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE);
+ gcc_jit_type *t_ptr_to_double =
+ gcc_jit_type_get_pointer (t_double);
+
+ /* Declare the imported function. */
+ gcc_jit_param *params[1];
+ params[0] =
+ gcc_jit_context_new_param (ctxt, NULL, t_ptr_to_double, "d");
+ gcc_jit_function *called_fn =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_IMPORTED,
+ t_void,
+ "write_back_through_ptr",
+ 1, params,
+ 0);
+
+ /* Build the test_fn. */
+ gcc_jit_function *test_fn =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ t_double,
+ "test_caller_of_write_back_through_ptr",
+ 0, NULL,
+ 0);
+ gcc_jit_lvalue *d =
+ gcc_jit_function_new_local (test_fn, NULL, t_double, "d");
+
+ gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
+
+ /* "d = 0.0" */
+ gcc_jit_block_add_assignment (
+ block, NULL, d,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_double, 4));
+
+ /* "write_back_through_ptr (&d);" */
+ gcc_jit_rvalue *args[1];
+ args[0] = gcc_jit_lvalue_get_address (d, NULL);
+ gcc_jit_block_add_eval (
+ block, NULL,
+ gcc_jit_context_new_call (ctxt,
+ NULL,
+ called_fn,
+ 1, args));
+ gcc_jit_block_end_with_return (block,
+ NULL,
+ gcc_jit_lvalue_as_rvalue (d));
+}
+
+extern void
+write_back_through_ptr (double *d)
+{
+ *d = 5.600000;
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ typedef double (*fn_type) (void);
+ CHECK_NON_NULL (result);
+
+ fn_type test_caller_of_write_back_through_ptr =
+ (fn_type)gcc_jit_result_get_code (result,
+ "test_caller_of_write_back_through_ptr");
+ CHECK_NON_NULL (test_caller_of_write_back_through_ptr);
+
+ /* Call the JIT-generated function. */
+ double d = test_caller_of_write_back_through_ptr ();
+
+ /* Verify that it correctly called "write_back_through_ptr". */
+ CHECK_VALUE (d, 5.600000);
+}
+