Skip to content

Commit fd61715

Browse files
authored
Merge pull request #48 from rust-lang/feature/alignof
Add ability to get the alignment of a type
2 parents 2cf6ca7 + 8e86887 commit fd61715

10 files changed

+214
-15
lines changed

gcc/jit/docs/topics/expressions.rst

+14
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,20 @@ Simple expressions
140140
141141
sizeof (type)
142142
143+
.. function:: gcc_jit_rvalue *\
144+
gcc_jit_context_new_alignof (gcc_jit_context *ctxt, \
145+
gcc_jit_type *type)
146+
147+
Generate an rvalue that is equal to the alignment of ``type``.
148+
149+
The parameter ``type`` must be non-NULL.
150+
151+
This is equivalent to this C code:
152+
153+
.. code-block:: c
154+
155+
_Alignof (type)
156+
143157
Constructor expressions
144158
***********************
145159

gcc/jit/jit-playback.cc

+11
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,17 @@ new_sizeof (type *type)
11481148

11491149
/* Construct a playback::rvalue instance (wrapping a tree). */
11501150

1151+
playback::rvalue *
1152+
playback::context::
1153+
new_alignof (type *type)
1154+
{
1155+
int alignment = TYPE_ALIGN (type->as_tree ()) / BITS_PER_UNIT;
1156+
tree inner = build_int_cst (integer_type_node, alignment);
1157+
return new rvalue (this, inner);
1158+
}
1159+
1160+
/* Construct a playback::rvalue instance (wrapping a tree). */
1161+
11511162
playback::rvalue *
11521163
playback::context::
11531164
new_string_literal (const char *value)

gcc/jit/jit-playback.h

+3
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ class context : public log_user
173173
rvalue *
174174
new_sizeof (type *type);
175175

176+
rvalue *
177+
new_alignof (type *type);
178+
176179
rvalue *
177180
new_string_literal (const char *value);
178181

gcc/jit/jit-recording.cc

+56-11
Original file line numberDiff line numberDiff line change
@@ -1134,7 +1134,7 @@ recording::context::new_global_init_rvalue (lvalue *variable,
11341134
gbl->set_rvalue_init (init); /* Needed by the global for write dump. */
11351135
}
11361136

1137-
/* Create a recording::memento_of_sizeof instance and add it
1137+
/* Create a recording::memento_of_typeinfo instance and add it
11381138
to this context's list of mementos.
11391139
11401140
Implements the post-error-checking part of
@@ -1144,7 +1144,22 @@ recording::rvalue *
11441144
recording::context::new_sizeof (recording::type *type)
11451145
{
11461146
recording::rvalue *result =
1147-
new memento_of_sizeof (this, NULL, type);
1147+
new memento_of_typeinfo (this, NULL, type, TYPE_INFO_SIZE_OF);
1148+
record (result);
1149+
return result;
1150+
}
1151+
1152+
/* Create a recording::memento_of_typeinfo instance and add it
1153+
to this context's list of mementos.
1154+
1155+
Implements the post-error-checking part of
1156+
gcc_jit_context_new_alignof. */
1157+
1158+
recording::rvalue *
1159+
recording::context::new_alignof (recording::type *type)
1160+
{
1161+
recording::rvalue *result =
1162+
new memento_of_typeinfo (this, NULL, type, TYPE_INFO_ALIGN_OF);
11481163
record (result);
11491164
return result;
11501165
}
@@ -5805,39 +5820,69 @@ memento_of_new_rvalue_from_const <void *>::write_reproducer (reproducer &r)
58055820

58065821
} // namespace recording
58075822

5808-
/* The implementation of class gcc::jit::recording::memento_of_sizeof. */
5823+
/* The implementation of class gcc::jit::recording::memento_of_typeinfo. */
58095824

58105825
/* Implementation of pure virtual hook recording::memento::replay_into
5811-
for recording::memento_of_sizeof. */
5826+
for recording::memento_of_typeinfo. */
58125827

58135828
void
5814-
recording::memento_of_sizeof::replay_into (replayer *r)
5829+
recording::memento_of_typeinfo::replay_into (replayer *r)
58155830
{
5816-
set_playback_obj (r->new_sizeof (m_type->playback_type ()));
5831+
switch (m_info_type)
5832+
{
5833+
case TYPE_INFO_ALIGN_OF:
5834+
set_playback_obj (r->new_alignof (m_type->playback_type ()));
5835+
break;
5836+
case TYPE_INFO_SIZE_OF:
5837+
set_playback_obj (r->new_sizeof (m_type->playback_type ()));
5838+
break;
5839+
}
58175840
}
58185841

58195842
/* Implementation of recording::memento::make_debug_string for
58205843
sizeof expressions. */
58215844

58225845
recording::string *
5823-
recording::memento_of_sizeof::make_debug_string ()
5846+
recording::memento_of_typeinfo::make_debug_string ()
58245847
{
5848+
const char* ident;
5849+
switch (m_info_type)
5850+
{
5851+
case TYPE_INFO_ALIGN_OF:
5852+
ident = "_Alignof";
5853+
break;
5854+
case TYPE_INFO_SIZE_OF:
5855+
ident = "sizeof";
5856+
break;
5857+
}
58255858
return string::from_printf (m_ctxt,
5826-
"sizeof (%s)",
5859+
"%s (%s)",
5860+
ident,
58275861
m_type->get_debug_string ());
58285862
}
58295863

58305864
/* Implementation of recording::memento::write_reproducer for sizeof
58315865
expressions. */
58325866

58335867
void
5834-
recording::memento_of_sizeof::write_reproducer (reproducer &r)
5868+
recording::memento_of_typeinfo::write_reproducer (reproducer &r)
58355869
{
5870+
const char* type;
5871+
switch (m_info_type)
5872+
{
5873+
case TYPE_INFO_ALIGN_OF:
5874+
type = "align";
5875+
break;
5876+
case TYPE_INFO_SIZE_OF:
5877+
type = "size";
5878+
break;
5879+
}
58365880
const char *id = r.make_identifier (this, "rvalue");
58375881
r.write (" gcc_jit_rvalue *%s =\n"
5838-
" gcc_jit_context_new_sizeof (%s, /* gcc_jit_context *ctxt */\n"
5839-
" %s); /* gcc_jit_type *type */\n",
5882+
" gcc_jit_context_new_%sof (%s, /* gcc_jit_context *ctxt */\n"
5883+
" (gcc_jit_type *) %s); /* gcc_jit_type *type */\n",
58405884
id,
5885+
type,
58415886
r.get_identifier (get_context ()),
58425887
r.get_identifier (m_type));
58435888
}

gcc/jit/jit-recording.h

+15-4
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ class reproducer;
5252

5353
namespace recording {
5454

55+
enum type_info_type {
56+
TYPE_INFO_ALIGN_OF,
57+
TYPE_INFO_SIZE_OF,
58+
};
59+
5560
playback::location *
5661
playback_location (replayer *r, location *loc);
5762

@@ -181,6 +186,9 @@ class context : public log_user
181186
rvalue *
182187
new_sizeof (type *type);
183188

189+
rvalue *
190+
new_alignof (type *type);
191+
184192
rvalue *
185193
new_string_literal (const char *value);
186194

@@ -1814,14 +1822,16 @@ class memento_of_new_rvalue_from_const : public rvalue
18141822
HOST_TYPE m_value;
18151823
};
18161824

1817-
class memento_of_sizeof : public rvalue
1825+
class memento_of_typeinfo : public rvalue
18181826
{
18191827
public:
1820-
memento_of_sizeof (context *ctxt,
1828+
memento_of_typeinfo (context *ctxt,
18211829
location *loc,
1822-
type *type)
1830+
type *type,
1831+
type_info_type type_info)
18231832
: rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_INT)),
1824-
m_type (type) {}
1833+
m_type (type),
1834+
m_info_type (type_info) {}
18251835

18261836
void replay_into (replayer *r) final override;
18271837

@@ -1837,6 +1847,7 @@ class memento_of_sizeof : public rvalue
18371847

18381848
private:
18391849
type *m_type;
1850+
type_info_type m_info_type;
18401851
};
18411852

18421853
class memento_of_new_string_literal : public rvalue

gcc/jit/libgccjit.cc

+18
Original file line numberDiff line numberDiff line change
@@ -2158,6 +2158,24 @@ gcc_jit_context_new_sizeof (gcc_jit_context *ctxt,
21582158
->new_sizeof (type));
21592159
}
21602160

2161+
/* Public entrypoint. See description in libgccjit.h.
2162+
2163+
After error-checking, the real work is done by the
2164+
gcc::jit::recording::context::new_alignof method in
2165+
jit-recording.cc. */
2166+
2167+
gcc_jit_rvalue *
2168+
gcc_jit_context_new_alignof (gcc_jit_context *ctxt,
2169+
gcc_jit_type *type)
2170+
{
2171+
RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2172+
RETURN_NULL_IF_FAIL (type, ctxt, NULL, "NULL type");
2173+
JIT_LOG_FUNC (ctxt->get_logger ());
2174+
2175+
return ((gcc_jit_rvalue *)ctxt
2176+
->new_alignof (type));
2177+
}
2178+
21612179
/* Public entrypoint. See description in libgccjit.h.
21622180
21632181
After error-checking, the real work is done by the

gcc/jit/libgccjit.h

+13
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,19 @@ extern gcc_jit_rvalue *
11221122
gcc_jit_context_new_sizeof (gcc_jit_context *ctxt,
11231123
gcc_jit_type *type);
11241124

1125+
#define LIBGCCJIT_HAVE_gcc_jit_context_new_alignof
1126+
1127+
/* Generates an rvalue that is equal to the alignment of type.
1128+
1129+
This API entrypoint was added in LIBGCCJIT_ABI_38; you can test for its
1130+
presence using
1131+
#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_alignof */
1132+
1133+
extern gcc_jit_rvalue *
1134+
gcc_jit_context_new_alignof (gcc_jit_context *ctxt,
1135+
gcc_jit_type *type);
1136+
1137+
11251138
/* String literals. */
11261139
extern gcc_jit_rvalue *
11271140
gcc_jit_context_new_string_literal (gcc_jit_context *ctxt,

gcc/jit/libgccjit.map

+5
Original file line numberDiff line numberDiff line change
@@ -347,3 +347,8 @@ LIBGCCJIT_ABI_37 {
347347
gcc_jit_function_set_location;
348348
gcc_jit_rvalue_set_location;
349349
} LIBGCCJIT_ABI_36;
350+
351+
LIBGCCJIT_ABI_38 {
352+
global:
353+
gcc_jit_context_new_alignof;
354+
} LIBGCCJIT_ABI_37;

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

+10
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@
4242
#undef create_code
4343
#undef verify_code
4444

45+
/* test-alignof.c */
46+
#define create_code create_code_alignof
47+
#define verify_code verify_code_alignof
48+
#include "test-alignof.c"
49+
#undef create_code
50+
#undef verify_code
51+
4552
/* test-always_inline-attribute.c: This can't be in the testcases array as it needs
4653
the `-O0` flag. */
4754

@@ -455,6 +462,9 @@ const struct testcase testcases[] = {
455462
{"accessing_union",
456463
create_code_accessing_union,
457464
verify_code_accessing_union},
465+
{"alignof",
466+
create_code_alignof,
467+
verify_code_alignof},
458468
{"alignment",
459469
create_code_alignment,
460470
verify_code_alignment},

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

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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_alignof ()
16+
{
17+
return _Alignof(int32_t);
18+
}
19+
*/
20+
gcc_jit_type *int32 =
21+
gcc_jit_context_get_int_type (ctxt, 4, 1);
22+
gcc_jit_type *int64 =
23+
gcc_jit_context_get_int_type (ctxt, 8, 1);
24+
gcc_jit_type *int_type =
25+
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
26+
27+
gcc_jit_function *func =
28+
gcc_jit_context_new_function (ctxt,
29+
NULL,
30+
GCC_JIT_FUNCTION_EXPORTED,
31+
int_type,
32+
"my_alignof",
33+
0, NULL, 0);
34+
35+
gcc_jit_block *initial =
36+
gcc_jit_function_new_block (func, "initial");
37+
38+
gcc_jit_field *field1 =
39+
gcc_jit_context_new_field (ctxt, NULL, int32, "int32");
40+
gcc_jit_field *field2 =
41+
gcc_jit_context_new_field (ctxt, NULL, int64, "int64");
42+
43+
gcc_jit_field *fields[] = {
44+
field1,
45+
field2,
46+
};
47+
48+
gcc_jit_struct *struct_type =
49+
gcc_jit_context_new_struct_type (
50+
ctxt,
51+
NULL,
52+
"ints",
53+
2, fields);
54+
55+
gcc_jit_block_end_with_return(initial, NULL,
56+
gcc_jit_context_new_alignof(ctxt, gcc_jit_struct_as_type (struct_type)));
57+
}
58+
59+
void
60+
verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
61+
{
62+
typedef int (*my_alignof_type) ();
63+
CHECK_NON_NULL (result);
64+
my_alignof_type my_alignof =
65+
(my_alignof_type)gcc_jit_result_get_code (result, "my_alignof");
66+
CHECK_NON_NULL (my_alignof);
67+
int val = my_alignof ();
68+
CHECK_VALUE (val, 8);
69+
}

0 commit comments

Comments
 (0)