jit: use deep unsharing of trees [PR 95314]
PR jit/95314 reports a internal error inside verify_gimple, which turned out to be due to reusing the result of gcc_jit_lvalue_get_address in several functions, leading to tree nodes shared between multiple function bodies. This patch fixes the issue by adopting the "Deep unsharing" strategy described in the comment in gimplify.c preceding mostly_copy_tree_r: to mark all of the jit "frontend"'s expression tree nodes with TREE_VISITED, and to set LANG_HOOKS_DEEP_UNSHARING, so that "they are unshared on the first reference within functions when the regular unsharing algorithm runs". gcc/jit/ChangeLog: PR jit/95314 * dummy-frontend.c (LANG_HOOKS_DEEP_UNSHARING): Define to be true. * jit-playback.h (gcc::jit::playback::rvalue): Mark tree node with TREE_VISITED. gcc/testsuite/ChangeLog: PR jit/95314 * jit.dg/all-non-failing-tests.h: Add test-pr95314-rvalue-reuse.c. * jit.dg/test-pr95314-rvalue-reuse.c: New test.
This commit is contained in:
parent
ac43b32ce2
commit
c98bd673ef
@ -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"
|
||||
|
@ -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; }
|
||||
|
@ -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 },
|
||||
|
56
gcc/testsuite/jit.dg/test-pr95314-rvalue-reuse.c
Normal file
56
gcc/testsuite/jit.dg/test-pr95314-rvalue-reuse.c
Normal file
@ -0,0 +1,56 @@
|
||||
#include <libgccjit.h>
|
||||
#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");
|
||||
}
|
Loading…
Reference in New Issue
Block a user