mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-17 18:00:55 +08:00
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
This commit is contained in:
parent
e807aeaae3
commit
e09abfa408
@ -1,3 +1,10 @@
|
||||
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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,10 @@
|
||||
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
|
||||
|
@ -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 },
|
||||
|
109
gcc/testsuite/jit.dg/test-pr66700-observing-write-through-ptr.c
Normal file
109
gcc/testsuite/jit.dg/test-pr66700-observing-write-through-ptr.c
Normal file
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user