Skip to content

Commit f2a6769

Browse files
committed
Add function to set the initial value of a global variable [PR96089]
2021-05-20 Antoni Boucher <[email protected]> gcc/jit/ PR target/96089 * docs/topics/compatibility.rst (LIBGCCJIT_ABI_19): New ABI tag. * docs/topics/expressions.rst: Add documentation for the function gcc_jit_global_set_initializer_value. * jit-playback.c: New function (new_global_with_value). * jit-playback.h: New function (new_global_with_value). * jit-recording.c: Add support for setting a value to a global variable. * jit-recording.h: New function (set_initializer_value) and new field m_initializer_value. * libgccjit.c: New macro RETURN_IF_FAIL_PRINTF5 and new function (gcc_jit_global_set_initializer_value). * libgccjit.h: New function (gcc_jit_global_set_initializer_value). * libgccjit.map (LIBGCCJIT_ABI_19): New ABI tag. gcc/testsuite/ PR target/96089 * jit.dg/test-global-set-initializer.c: Add test for the new function (gcc_jit_global_set_initializer_value). Signed-off-by: Antoni Boucher <[email protected]>
1 parent 079c23c commit f2a6769

10 files changed

+160
-6
lines changed

gcc/jit/docs/topics/compatibility.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,12 @@ embedding assembler instructions:
243243
* :func:`gcc_jit_extended_asm_add_input_operand`
244244
* :func:`gcc_jit_extended_asm_add_clobber`
245245
* :func:`gcc_jit_context_add_top_level_asm`
246+
247+
.. _LIBGCCJIT_ABI_19:
248+
249+
``LIBGCCJIT_ABI_19``
250+
-----------------------
251+
``LIBGCCJIT_ABI_19`` covers the addition of an API entrypoint to set the value
252+
of a global variable:
253+
254+
* :func:`gcc_jit_global_set_initializer_value`

gcc/jit/docs/topics/expressions.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,20 @@ Global variables
603603
604604
#ifdef LIBGCCJIT_HAVE_gcc_jit_global_set_initializer
605605
606+
.. function:: void
607+
gcc_jit_global_set_initializer_value (gcc_jit_lvalue *global,\
608+
gcc_jit_rvalue *value)
609+
610+
Set an initializer for ``global`` using the specified value.
611+
``global`` must be the same type as ``value``.
612+
613+
This entrypoint was added in :ref:`LIBGCCJIT_ABI_19`; you can test for
614+
its presence using
615+
616+
.. code-block:: c
617+
618+
#ifdef LIBGCCJIT_HAVE_gcc_jit_global_set_initializer_value
619+
606620
Working with pointers, structs and unions
607621
-----------------------------------------
608622

gcc/jit/jit-playback.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,24 @@ new_global_initialized (location *loc,
664664
return global_finalize_lvalue (inner);
665665
}
666666

667+
playback::lvalue *
668+
playback::context::
669+
new_global_with_value (location *loc,
670+
enum gcc_jit_global_kind kind,
671+
type *type,
672+
playback::rvalue *value,
673+
const char *name)
674+
{
675+
tree inner = global_new_decl (loc, kind, type, name);
676+
677+
tree inner_type = type->as_tree ();
678+
tree initial = value->as_tree ();
679+
gcc_assert (TREE_CONSTANT (initial));
680+
DECL_INITIAL (inner) = initial;
681+
682+
return global_finalize_lvalue (inner);
683+
}
684+
667685
/* Implementation of the various
668686
gcc::jit::playback::context::new_rvalue_from_const <HOST_TYPE>
669687
methods.

gcc/jit/jit-playback.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,13 @@ class context : public log_user
120120
const void *initializer,
121121
const char *name);
122122

123+
lvalue*
124+
new_global_with_value (location *loc,
125+
enum gcc_jit_global_kind kind,
126+
type *type,
127+
rvalue *value,
128+
const char *name);
129+
123130
template <typename HOST_TYPE>
124131
rvalue *
125132
new_rvalue_from_const (type *type,

gcc/jit/jit-recording.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4547,20 +4547,34 @@ recording::block::dump_edges_to_dot (pretty_printer *pp)
45474547
void
45484548
recording::global::replay_into (replayer *r)
45494549
{
4550-
set_playback_obj (
4551-
m_initializer
4552-
? r->new_global_initialized (playback_location (r, m_loc),
4550+
playback::lvalue * obj;
4551+
if (m_initializer)
4552+
{
4553+
obj = r->new_global_initialized (playback_location (r, m_loc),
45534554
m_kind,
45544555
m_type->playback_type (),
45554556
m_type->dereference ()->get_size (),
45564557
m_initializer_num_bytes
45574558
/ m_type->dereference ()->get_size (),
45584559
m_initializer,
4559-
playback_string (m_name))
4560-
: r->new_global (playback_location (r, m_loc),
4560+
playback_string (m_name));
4561+
}
4562+
else if (m_initializer_value)
4563+
{
4564+
obj = r->new_global_with_value (playback_location (r, m_loc),
4565+
m_kind,
4566+
m_type->playback_type (),
4567+
m_initializer_value->playback_rvalue (),
4568+
playback_string (m_name));
4569+
}
4570+
else
4571+
{
4572+
obj = r->new_global (playback_location (r, m_loc),
45614573
m_kind,
45624574
m_type->playback_type (),
4563-
playback_string (m_name)));
4575+
playback_string (m_name));
4576+
}
4577+
set_playback_obj (obj);
45644578
}
45654579

45664580
/* Override the default implementation of
@@ -4675,6 +4689,14 @@ recording::global::write_reproducer (reproducer &r)
46754689
r.get_identifier_as_type (get_type ()),
46764690
m_name->get_debug_string ());
46774691

4692+
if (m_initializer_value)
4693+
{
4694+
r.write (" gcc_jit_global_set_initializer_value (%s, /* gcc_jit_lvalue *global */\n"
4695+
" %s/* gcc_jit_rvalue *value */);\n",
4696+
id,
4697+
r.get_identifier_as_rvalue (m_initializer_value));
4698+
}
4699+
46784700
if (m_initializer)
46794701
switch (m_type->dereference ()->get_size ())
46804702
{

gcc/jit/jit-recording.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,6 +1360,7 @@ class global : public lvalue
13601360
m_name (name)
13611361
{
13621362
m_initializer = NULL;
1363+
m_initializer_value = NULL;
13631364
m_initializer_num_bytes = 0;
13641365
}
13651366
~global ()
@@ -1386,6 +1387,12 @@ class global : public lvalue
13861387
m_initializer_num_bytes = num_bytes;
13871388
}
13881389

1390+
void
1391+
set_initializer_value (rvalue* value)
1392+
{
1393+
m_initializer_value = value;
1394+
}
1395+
13891396
private:
13901397
string * make_debug_string () FINAL OVERRIDE { return m_name; }
13911398
template <typename T>
@@ -1400,6 +1407,7 @@ class global : public lvalue
14001407
enum gcc_jit_global_kind m_kind;
14011408
string *m_name;
14021409
void *m_initializer;
1410+
rvalue *m_initializer_value;
14031411
size_t m_initializer_num_bytes;
14041412
};
14051413

gcc/jit/libgccjit.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,17 @@ struct gcc_jit_extended_asm : public gcc::jit::recording::extended_asm
269269
} \
270270
JIT_END_STMT
271271

272+
#define RETURN_IF_FAIL_PRINTF5(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, \
273+
A4) \
274+
JIT_BEGIN_STMT \
275+
if (!(TEST_EXPR)) \
276+
{ \
277+
jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
278+
__func__, (A0), (A1), (A2), (A3), (A4)); \
279+
return; \
280+
} \
281+
JIT_END_STMT
282+
272283
/* Check that BLOCK is non-NULL, and that it's OK to add statements to
273284
it. This will fail if BLOCK has already been terminated by some
274285
kind of jump or a return. */
@@ -1161,6 +1172,38 @@ gcc_jit_global_set_initializer (gcc_jit_lvalue *global,
11611172
return global;
11621173
}
11631174

1175+
/* Public entrypoint. See description in libgccjit.h.
1176+
1177+
After error-checking, the real work is done by the
1178+
gcc::jit::recording::global::set_initializer_value method, in
1179+
jit-recording.c. */
1180+
1181+
void
1182+
gcc_jit_global_set_initializer_value (gcc_jit_lvalue *global,
1183+
gcc_jit_rvalue *value)
1184+
{
1185+
RETURN_IF_FAIL (global, NULL, NULL, "NULL global");
1186+
RETURN_IF_FAIL (value, NULL, NULL, "NULL value");
1187+
RETURN_IF_FAIL_PRINTF1 (global->is_global (), NULL, NULL,
1188+
"lvalue \"%s\" not a global",
1189+
global->get_debug_string ());
1190+
1191+
RETURN_IF_FAIL_PRINTF5 (
1192+
compatible_types (global->get_type (),
1193+
value->get_type ()),
1194+
NULL, NULL,
1195+
"mismatching types for global \"%s\":"
1196+
" assignment to global %s (type: %s) from %s (type: %s)",
1197+
global->get_debug_string (),
1198+
global->get_debug_string (),
1199+
global->get_type ()->get_debug_string (),
1200+
value->get_debug_string (),
1201+
value->get_type ()->get_debug_string ());
1202+
1203+
reinterpret_cast <gcc::jit::recording::global *> (global)
1204+
->set_initializer_value (value);
1205+
}
1206+
11641207
/* Public entrypoint. See description in libgccjit.h.
11651208
11661209
After error-checking, this calls the trivial

gcc/jit/libgccjit.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,19 @@ gcc_jit_global_set_initializer (gcc_jit_lvalue *global,
810810
const void *blob,
811811
size_t num_bytes);
812812

813+
#define LIBGCCJIT_HAVE_gcc_jit_global_set_initializer_value
814+
815+
/* Set an initial value for a global, which must be a constant.
816+
817+
This API entrypoint was added in LIBGCCJIT_ABI_19; you can test for its
818+
presence using
819+
#ifdef LIBGCCJIT_HAVE_gcc_jit_global_set_initializer_value
820+
*/
821+
822+
extern void
823+
gcc_jit_global_set_initializer_value (gcc_jit_lvalue *global,
824+
gcc_jit_rvalue *value);
825+
813826
/* Upcasting. */
814827
extern gcc_jit_object *
815828
gcc_jit_lvalue_as_object (gcc_jit_lvalue *lvalue);

gcc/jit/libgccjit.map

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,8 @@ LIBGCCJIT_ABI_15 {
205205
gcc_jit_extended_asm_add_clobber;
206206
gcc_jit_context_add_top_level_asm;
207207
} LIBGCCJIT_ABI_14;
208+
209+
LIBGCCJIT_ABI_19 {
210+
global:
211+
gcc_jit_global_set_initializer_value;
212+
} LIBGCCJIT_ABI_18;

gcc/testsuite/jit.dg/test-global-set-initializer.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ create_code (gcc_jit_context *ctxt, void *user_data)
2121
signed char bin_blob1[] = { 0xc, 0xa, 0xf, 0xf, 0xe };
2222
unsigned bin_blob2[] = { 0x3, 0x2, 0x1, 0x0, 0x1, 0x2, 0x3 };
2323
unsigned char bin_blob3[4096]...
24+
unsigned int integer = 42;
2425
*/
2526
gcc_jit_type *unsigned_char_type =
2627
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_CHAR);
@@ -56,6 +57,16 @@ create_code (gcc_jit_context *ctxt, void *user_data)
5657
sizeof (test_blob3)),
5758
"bin_blob3");
5859
gcc_jit_global_set_initializer (glob, test_blob3, sizeof (test_blob3));
60+
61+
gcc_jit_rvalue *forty_two = gcc_jit_context_new_rvalue_from_int (
62+
ctxt, unsigned_type, 42);
63+
64+
glob =
65+
gcc_jit_context_new_global (
66+
ctxt, NULL, GCC_JIT_GLOBAL_EXPORTED,
67+
unsigned_type,
68+
"integer");
69+
gcc_jit_global_set_initializer_value (glob, forty_two);
5970
}
6071

6172
void
@@ -75,4 +86,8 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
7586
CHECK_NON_NULL (glob);
7687
CHECK_VALUE (memcmp (test_blob3, glob, sizeof (test_blob3)), 0);
7788

89+
glob = gcc_jit_result_get_global (result, "integer");
90+
CHECK_NON_NULL (glob);
91+
int *value = glob;
92+
CHECK_VALUE (*value, 42);
7893
}

0 commit comments

Comments
 (0)