Skip to content

Commit 79f11df

Browse files
committed
libgccjit: Implement sizeof operator
gcc/jit/ChangeLog: * docs/topics/compatibility.rst (LIBGCCJIT_ABI_26): New ABI tag. * docs/topics/expressions.rst: Document gcc_jit_context_new_sizeof. * jit-playback.cc (new_sizeof): New method. * jit-playback.h (new_sizeof): New method. * jit-recording.cc (recording::context::new_sizeof, recording::memento_of_sizeof::replay_into, recording::memento_of_sizeof::make_debug_string, recording::memento_of_sizeof::write_reproducer): New methods. * jit-recording.h (class memento_of_sizeof): New class. * libgccjit.cc (gcc_jit_context_new_sizeof): New function. * libgccjit.h (gcc_jit_context_new_sizeof): New function. * libgccjit.map: New function. gcc/testsuite/ChangeLog: * jit.dg/all-non-failing-tests.h: New test. * jit.dg/test-sizeof.c: New test.
1 parent b5a76f0 commit 79f11df

11 files changed

+209
-0
lines changed

gcc/jit/docs/topics/compatibility.rst

+7
Original file line numberDiff line numberDiff line change
@@ -399,3 +399,10 @@ on functions and variables:
399399
temporary variable:
400400

401401
* :func:`gcc_jit_function_new_temp`
402+
403+
.. _LIBGCCJIT_ABI_27:
404+
405+
``LIBGCCJIT_ABI_27``
406+
--------------------
407+
``LIBGCCJIT_ABI_27`` covers the addition of
408+
:func:`gcc_jit_context_new_sizeof`

gcc/jit/docs/topics/expressions.rst

+14
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,20 @@ Simple expressions
126126
underlying string, so it is valid to pass in a pointer to an on-stack
127127
buffer.
128128

129+
.. function:: gcc_jit_rvalue *\
130+
gcc_jit_context_new_sizeof (gcc_jit_context *ctxt, \
131+
gcc_jit_type *type)
132+
133+
Generate an rvalue that is equal to the size of ``type``.
134+
135+
The parameter ``type`` must be non-NULL.
136+
137+
This is equivalent to this C code:
138+
139+
.. code-block:: c
140+
141+
sizeof (type)
142+
129143
Constructor expressions
130144
***********************
131145

gcc/jit/jit-playback.cc

+10
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,16 @@ new_rvalue_from_const <void *> (type *type,
11381138

11391139
/* Construct a playback::rvalue instance (wrapping a tree). */
11401140

1141+
playback::rvalue *
1142+
playback::context::
1143+
new_sizeof (type *type)
1144+
{
1145+
tree inner = TYPE_SIZE_UNIT (type->as_tree ());
1146+
return new rvalue (this, inner);
1147+
}
1148+
1149+
/* Construct a playback::rvalue instance (wrapping a tree). */
1150+
11411151
playback::rvalue *
11421152
playback::context::
11431153
new_string_literal (const char *value)

gcc/jit/jit-playback.h

+3
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ class context : public log_user
170170
new_rvalue_from_const (type *type,
171171
HOST_TYPE value);
172172

173+
rvalue *
174+
new_sizeof (type *type);
175+
173176
rvalue *
174177
new_string_literal (const char *value);
175178

gcc/jit/jit-recording.cc

+52
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,21 @@ recording::context::new_global_init_rvalue (lvalue *variable,
11261126
gbl->set_rvalue_init (init); /* Needed by the global for write dump. */
11271127
}
11281128

1129+
/* Create a recording::memento_of_sizeof instance and add it
1130+
to this context's list of mementos.
1131+
1132+
Implements the post-error-checking part of
1133+
gcc_jit_context_new_sizeof. */
1134+
1135+
recording::rvalue *
1136+
recording::context::new_sizeof (recording::type *type)
1137+
{
1138+
recording::rvalue *result =
1139+
new memento_of_sizeof (this, NULL, type);
1140+
record (result);
1141+
return result;
1142+
}
1143+
11291144
/* Create a recording::memento_of_new_string_literal instance and add it
11301145
to this context's list of mementos.
11311146
@@ -5754,6 +5769,43 @@ memento_of_new_rvalue_from_const <void *>::write_reproducer (reproducer &r)
57545769

57555770
} // namespace recording
57565771

5772+
/* The implementation of class gcc::jit::recording::memento_of_sizeof. */
5773+
5774+
/* Implementation of pure virtual hook recording::memento::replay_into
5775+
for recording::memento_of_sizeof. */
5776+
5777+
void
5778+
recording::memento_of_sizeof::replay_into (replayer *r)
5779+
{
5780+
set_playback_obj (r->new_sizeof (m_type->playback_type ()));
5781+
}
5782+
5783+
/* Implementation of recording::memento::make_debug_string for
5784+
sizeof expressions. */
5785+
5786+
recording::string *
5787+
recording::memento_of_sizeof::make_debug_string ()
5788+
{
5789+
return string::from_printf (m_ctxt,
5790+
"sizeof (%s)",
5791+
m_type->get_debug_string ());
5792+
}
5793+
5794+
/* Implementation of recording::memento::write_reproducer for sizeof
5795+
expressions. */
5796+
5797+
void
5798+
recording::memento_of_sizeof::write_reproducer (reproducer &r)
5799+
{
5800+
const char *id = r.make_identifier (this, "rvalue");
5801+
r.write (" gcc_jit_rvalue *%s =\n"
5802+
" gcc_jit_context_new_sizeof (%s, /* gcc_jit_context *ctxt */\n"
5803+
" %s); /* gcc_jit_type *type */\n",
5804+
id,
5805+
r.get_identifier (get_context ()),
5806+
r.get_identifier (m_type));
5807+
}
5808+
57575809
/* The implementation of class gcc::jit::recording::memento_of_new_string_literal. */
57585810

57595811
/* Implementation of pure virtual hook recording::memento::replay_into

gcc/jit/jit-recording.h

+28
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ class context : public log_user
177177
new_rvalue_from_const (type *type,
178178
HOST_TYPE value);
179179

180+
rvalue *
181+
new_sizeof (type *type);
182+
180183
rvalue *
181184
new_string_literal (const char *value);
182185

@@ -1778,6 +1781,31 @@ class memento_of_new_rvalue_from_const : public rvalue
17781781
HOST_TYPE m_value;
17791782
};
17801783

1784+
class memento_of_sizeof : public rvalue
1785+
{
1786+
public:
1787+
memento_of_sizeof (context *ctxt,
1788+
location *loc,
1789+
type *type)
1790+
: rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_INT)),
1791+
m_type (type) {}
1792+
1793+
void replay_into (replayer *r) final override;
1794+
1795+
void visit_children (rvalue_visitor *) final override {}
1796+
1797+
private:
1798+
string * make_debug_string () final override;
1799+
void write_reproducer (reproducer &r) final override;
1800+
enum precedence get_precedence () const final override
1801+
{
1802+
return PRECEDENCE_PRIMARY;
1803+
}
1804+
1805+
private:
1806+
type *m_type;
1807+
};
1808+
17811809
class memento_of_new_string_literal : public rvalue
17821810
{
17831811
public:

gcc/jit/libgccjit.cc

+18
Original file line numberDiff line numberDiff line change
@@ -2138,6 +2138,24 @@ gcc_jit_context_null (gcc_jit_context *ctxt,
21382138
return gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL);
21392139
}
21402140

2141+
/* Public entrypoint. See description in libgccjit.h.
2142+
2143+
After error-checking, the real work is done by the
2144+
gcc::jit::recording::context::new_sizeof method in
2145+
jit-recording.cc. */
2146+
2147+
gcc_jit_rvalue *
2148+
gcc_jit_context_new_sizeof (gcc_jit_context *ctxt,
2149+
gcc_jit_type *type)
2150+
{
2151+
RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2152+
RETURN_NULL_IF_FAIL (type, ctxt, NULL, "NULL type");
2153+
JIT_LOG_FUNC (ctxt->get_logger ());
2154+
2155+
return ((gcc_jit_rvalue *)ctxt
2156+
->new_sizeof (type));
2157+
}
2158+
21412159
/* Public entrypoint. See description in libgccjit.h.
21422160
21432161
After error-checking, the real work is done by the

gcc/jit/libgccjit.h

+12
Original file line numberDiff line numberDiff line change
@@ -1107,6 +1107,18 @@ extern gcc_jit_rvalue *
11071107
gcc_jit_context_null (gcc_jit_context *ctxt,
11081108
gcc_jit_type *pointer_type);
11091109

1110+
#define LIBGCCJIT_HAVE_gcc_jit_context_new_sizeof
1111+
1112+
/* Generates an rvalue that is equal to the size of type.
1113+
1114+
This API entrypoint was added in LIBGCCJIT_ABI_26; you can test for its
1115+
presence using
1116+
#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_sizeof */
1117+
1118+
extern gcc_jit_rvalue *
1119+
gcc_jit_context_new_sizeof (gcc_jit_context *ctxt,
1120+
gcc_jit_type *type);
1121+
11101122
/* String literals. */
11111123
extern gcc_jit_rvalue *
11121124
gcc_jit_context_new_string_literal (gcc_jit_context *ctxt,

gcc/jit/libgccjit.map

+5
Original file line numberDiff line numberDiff line change
@@ -336,3 +336,8 @@ LIBGCCJIT_ABI_35 {
336336
global:
337337
gcc_jit_function_new_temp;
338338
} LIBGCCJIT_ABI_34;
339+
340+
LIBGCCJIT_ABI_36 {
341+
global:
342+
gcc_jit_context_new_sizeof;
343+
} LIBGCCJIT_ABI_35;

gcc/testsuite/jit.dg/all-non-failing-tests.h

+10
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,13 @@
359359
/* test-temp.c: This can't be in the testcases array as it
360360
is target-specific. */
361361

362+
/* test-sizeof.c */
363+
#define create_code create_code_sizeof
364+
#define verify_code verify_code_sizeof
365+
#include "test-sizeof.c"
366+
#undef create_code
367+
#undef verify_code
368+
362369
/* test-string-literal.c */
363370
#define create_code create_code_string_literal
364371
#define verify_code verify_code_string_literal
@@ -559,6 +566,9 @@ const struct testcase testcases[] = {
559566
{"reflection",
560567
create_code_reflection ,
561568
verify_code_reflection },
569+
{"sizeof",
570+
create_code_sizeof,
571+
verify_code_sizeof},
562572
{"string_literal",
563573
create_code_string_literal,
564574
verify_code_string_literal},

gcc/testsuite/jit.dg/test-sizeof.c

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include <stdlib.h>
2+
#include <stdio.h>
3+
#include <string.h>
4+
#include <stdint.h>
5+
6+
#include "libgccjit.h"
7+
8+
#include "harness.h"
9+
10+
void
11+
create_code (gcc_jit_context *ctxt, void *user_data)
12+
{
13+
/* Let's try to inject the equivalent of:
14+
int
15+
my_sizeof ()
16+
{
17+
return sizeof(int32_t);
18+
}
19+
*/
20+
gcc_jit_type *int32 =
21+
gcc_jit_context_get_int_type (ctxt, 4, 1);
22+
gcc_jit_type *int_type =
23+
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
24+
25+
gcc_jit_function *func =
26+
gcc_jit_context_new_function (ctxt,
27+
NULL,
28+
GCC_JIT_FUNCTION_EXPORTED,
29+
int_type,
30+
"my_sizeof",
31+
0, NULL, 0);
32+
33+
gcc_jit_block *initial =
34+
gcc_jit_function_new_block (func, "initial");
35+
36+
gcc_jit_block_end_with_return(initial, NULL,
37+
gcc_jit_context_new_sizeof(ctxt, int32));
38+
}
39+
40+
void
41+
verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
42+
{
43+
typedef int (*my_sizeof_type) ();
44+
CHECK_NON_NULL (result);
45+
my_sizeof_type my_sizeof =
46+
(my_sizeof_type)gcc_jit_result_get_code (result, "my_sizeof");
47+
CHECK_NON_NULL (my_sizeof);
48+
int val = my_sizeof ();
49+
CHECK_VALUE (val, 4);
50+
}

0 commit comments

Comments
 (0)