diff --git a/gcc/jit/dummy-frontend.c b/gcc/jit/dummy-frontend.c index 27fe9d3db96..6c7b7992a4d 100644 --- a/gcc/jit/dummy-frontend.c +++ b/gcc/jit/dummy-frontend.c @@ -269,6 +269,9 @@ jit_langhook_getdecls (void) #undef LANG_HOOKS_GETDECLS #define LANG_HOOKS_GETDECLS jit_langhook_getdecls +#undef LANG_HOOKS_DEEP_UNSHARING +#define LANG_HOOKS_DEEP_UNSHARING true + struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; #include "gt-jit-dummy-frontend.h" diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h index 074434a9f6b..f9b3e675368 100644 --- a/gcc/jit/jit-playback.h +++ b/gcc/jit/jit-playback.h @@ -576,7 +576,12 @@ public: rvalue (context *ctxt, tree inner) : m_ctxt (ctxt), m_inner (inner) - {} + { + /* Pre-mark tree nodes with TREE_VISITED so that they can be + deeply unshared during gimplification (including across + functions); this requires LANG_HOOKS_DEEP_UNSHARING to be true. */ + TREE_VISITED (inner) = 1; + } rvalue * as_rvalue () { return this; } diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h index babcd3979b7..ca8d3df4193 100644 --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h @@ -234,6 +234,13 @@ #undef create_code #undef verify_code +/* test-pr95314-rvalue-reuse.c. */ +#define create_code create_code_pr95314_rvalue_reuse +#define verify_code verify_code_pr95314_rvalue_reuse +#include "test-pr95314-rvalue-reuse.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 @@ -401,6 +408,9 @@ const struct testcase testcases[] = { {"pr95306_builtin_types", create_code_pr95306_builtin_types, verify_code_pr95306_builtin_types}, + {"pr95314_rvalue_reuse", + create_code_pr95314_rvalue_reuse, + verify_code_pr95314_rvalue_reuse}, {"reading_struct ", create_code_reading_struct , verify_code_reading_struct }, diff --git a/gcc/testsuite/jit.dg/test-pr95314-rvalue-reuse.c b/gcc/testsuite/jit.dg/test-pr95314-rvalue-reuse.c new file mode 100644 index 00000000000..6bed0bc52a4 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-pr95314-rvalue-reuse.c @@ -0,0 +1,56 @@ +#include +#include "harness.h" + +void create_code (gcc_jit_context *ctxt, void *user_data) +{ + gcc_jit_type *t_int = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *t_void = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); + gcc_jit_type *t_const_char_ptr + = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR); + gcc_jit_lvalue *global + = gcc_jit_context_new_global (ctxt, NULL, GCC_JIT_GLOBAL_INTERNAL, + t_const_char_ptr, "pr95314_global"); + + gcc_jit_rvalue *global_ref = gcc_jit_lvalue_get_address(global, NULL); + + gcc_jit_param *param_string + = gcc_jit_context_new_param (ctxt, NULL, t_const_char_ptr, "string"); + gcc_jit_function *puts_func + = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_IMPORTED, + t_int, "puts", 1, ¶m_string, 0); + +#define NUM_INNER_FNS 3 + gcc_jit_function *inner_fns[NUM_INNER_FNS]; + for (int i = 0; i < NUM_INNER_FNS; i++) + { + char fnname[128]; + sprintf (fnname, "pr95314_inner_%i", i); + inner_fns[i] + = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_INTERNAL, + t_void, fnname, 0, NULL, 0); + gcc_jit_block *block = gcc_jit_function_new_block (inner_fns[i], NULL); + gcc_jit_rvalue *arg + = gcc_jit_context_new_cast (ctxt, NULL, global_ref, t_const_char_ptr); + gcc_jit_block_add_eval (block, NULL, + gcc_jit_context_new_call (ctxt, NULL, puts_func, + 1, &arg)); + gcc_jit_block_end_with_void_return (block, NULL); + } + + gcc_jit_function *outer_func + = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, + t_void, "pr95314_outer", 0, NULL, 0); + gcc_jit_block *block = gcc_jit_function_new_block (outer_func, NULL); + for (int i = 0; i < NUM_INNER_FNS; i++) + gcc_jit_block_add_eval (block, NULL, + gcc_jit_context_new_call (ctxt, NULL, inner_fns[i], + 0, NULL)); + gcc_jit_block_end_with_void_return (block, NULL); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + CHECK_NON_NULL (result); + (void)gcc_jit_result_get_code (result, "pr95314_outer"); +}