Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to get the alignment of a type #48

Merged
merged 1 commit into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions gcc/jit/docs/topics/expressions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,20 @@ Simple expressions

sizeof (type)

.. function:: gcc_jit_rvalue *\
gcc_jit_context_new_alignof (gcc_jit_context *ctxt, \
gcc_jit_type *type)

Generate an rvalue that is equal to the alignment of ``type``.

The parameter ``type`` must be non-NULL.

This is equivalent to this C code:

.. code-block:: c

_Alignof (type)

Constructor expressions
***********************

Expand Down
11 changes: 11 additions & 0 deletions gcc/jit/jit-playback.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,17 @@ new_sizeof (type *type)

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

playback::rvalue *
playback::context::
new_alignof (type *type)
{
int alignment = TYPE_ALIGN (type->as_tree ()) / BITS_PER_UNIT;
tree inner = build_int_cst (integer_type_node, alignment);
return new rvalue (this, inner);
}

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

playback::rvalue *
playback::context::
new_string_literal (const char *value)
Expand Down
3 changes: 3 additions & 0 deletions gcc/jit/jit-playback.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ class context : public log_user
rvalue *
new_sizeof (type *type);

rvalue *
new_alignof (type *type);

rvalue *
new_string_literal (const char *value);

Expand Down
67 changes: 56 additions & 11 deletions gcc/jit/jit-recording.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1134,7 +1134,7 @@ recording::context::new_global_init_rvalue (lvalue *variable,
gbl->set_rvalue_init (init); /* Needed by the global for write dump. */
}

/* Create a recording::memento_of_sizeof instance and add it
/* Create a recording::memento_of_typeinfo instance and add it
to this context's list of mementos.

Implements the post-error-checking part of
Expand All @@ -1144,7 +1144,22 @@ recording::rvalue *
recording::context::new_sizeof (recording::type *type)
{
recording::rvalue *result =
new memento_of_sizeof (this, NULL, type);
new memento_of_typeinfo (this, NULL, type, TYPE_INFO_SIZE_OF);
record (result);
return result;
}

/* Create a recording::memento_of_typeinfo instance and add it
to this context's list of mementos.

Implements the post-error-checking part of
gcc_jit_context_new_alignof. */

recording::rvalue *
recording::context::new_alignof (recording::type *type)
{
recording::rvalue *result =
new memento_of_typeinfo (this, NULL, type, TYPE_INFO_ALIGN_OF);
record (result);
return result;
}
Expand Down Expand Up @@ -5805,39 +5820,69 @@ memento_of_new_rvalue_from_const <void *>::write_reproducer (reproducer &r)

} // namespace recording

/* The implementation of class gcc::jit::recording::memento_of_sizeof. */
/* The implementation of class gcc::jit::recording::memento_of_typeinfo. */

/* Implementation of pure virtual hook recording::memento::replay_into
for recording::memento_of_sizeof. */
for recording::memento_of_typeinfo. */

void
recording::memento_of_sizeof::replay_into (replayer *r)
recording::memento_of_typeinfo::replay_into (replayer *r)
{
set_playback_obj (r->new_sizeof (m_type->playback_type ()));
switch (m_info_type)
{
case TYPE_INFO_ALIGN_OF:
set_playback_obj (r->new_alignof (m_type->playback_type ()));
break;
case TYPE_INFO_SIZE_OF:
set_playback_obj (r->new_sizeof (m_type->playback_type ()));
break;
}
}

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

recording::string *
recording::memento_of_sizeof::make_debug_string ()
recording::memento_of_typeinfo::make_debug_string ()
{
const char* ident;
switch (m_info_type)
{
case TYPE_INFO_ALIGN_OF:
ident = "_Alignof";
break;
case TYPE_INFO_SIZE_OF:
ident = "sizeof";
break;
}
return string::from_printf (m_ctxt,
"sizeof (%s)",
"%s (%s)",
ident,
m_type->get_debug_string ());
}

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

void
recording::memento_of_sizeof::write_reproducer (reproducer &r)
recording::memento_of_typeinfo::write_reproducer (reproducer &r)
{
const char* type;
switch (m_info_type)
{
case TYPE_INFO_ALIGN_OF:
type = "align";
break;
case TYPE_INFO_SIZE_OF:
type = "size";
break;
}
const char *id = r.make_identifier (this, "rvalue");
r.write (" gcc_jit_rvalue *%s =\n"
" gcc_jit_context_new_sizeof (%s, /* gcc_jit_context *ctxt */\n"
" %s); /* gcc_jit_type *type */\n",
" gcc_jit_context_new_%sof (%s, /* gcc_jit_context *ctxt */\n"
" (gcc_jit_type *) %s); /* gcc_jit_type *type */\n",
id,
type,
r.get_identifier (get_context ()),
r.get_identifier (m_type));
}
Expand Down
19 changes: 15 additions & 4 deletions gcc/jit/jit-recording.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ class reproducer;

namespace recording {

enum type_info_type {
TYPE_INFO_ALIGN_OF,
TYPE_INFO_SIZE_OF,
};

playback::location *
playback_location (replayer *r, location *loc);

Expand Down Expand Up @@ -181,6 +186,9 @@ class context : public log_user
rvalue *
new_sizeof (type *type);

rvalue *
new_alignof (type *type);

rvalue *
new_string_literal (const char *value);

Expand Down Expand Up @@ -1814,14 +1822,16 @@ class memento_of_new_rvalue_from_const : public rvalue
HOST_TYPE m_value;
};

class memento_of_sizeof : public rvalue
class memento_of_typeinfo : public rvalue
{
public:
memento_of_sizeof (context *ctxt,
memento_of_typeinfo (context *ctxt,
location *loc,
type *type)
type *type,
type_info_type type_info)
: rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_INT)),
m_type (type) {}
m_type (type),
m_info_type (type_info) {}

void replay_into (replayer *r) final override;

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

private:
type *m_type;
type_info_type m_info_type;
};

class memento_of_new_string_literal : public rvalue
Expand Down
18 changes: 18 additions & 0 deletions gcc/jit/libgccjit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2158,6 +2158,24 @@ gcc_jit_context_new_sizeof (gcc_jit_context *ctxt,
->new_sizeof (type));
}

/* Public entrypoint. See description in libgccjit.h.

After error-checking, the real work is done by the
gcc::jit::recording::context::new_alignof method in
jit-recording.cc. */

gcc_jit_rvalue *
gcc_jit_context_new_alignof (gcc_jit_context *ctxt,
gcc_jit_type *type)
{
RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
RETURN_NULL_IF_FAIL (type, ctxt, NULL, "NULL type");
JIT_LOG_FUNC (ctxt->get_logger ());

return ((gcc_jit_rvalue *)ctxt
->new_alignof (type));
}

/* Public entrypoint. See description in libgccjit.h.

After error-checking, the real work is done by the
Expand Down
13 changes: 13 additions & 0 deletions gcc/jit/libgccjit.h
Original file line number Diff line number Diff line change
Expand Up @@ -1122,6 +1122,19 @@ extern gcc_jit_rvalue *
gcc_jit_context_new_sizeof (gcc_jit_context *ctxt,
gcc_jit_type *type);

#define LIBGCCJIT_HAVE_gcc_jit_context_new_alignof

/* Generates an rvalue that is equal to the alignment of type.

This API entrypoint was added in LIBGCCJIT_ABI_38; you can test for its
presence using
#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_alignof */

extern gcc_jit_rvalue *
gcc_jit_context_new_alignof (gcc_jit_context *ctxt,
gcc_jit_type *type);


/* String literals. */
extern gcc_jit_rvalue *
gcc_jit_context_new_string_literal (gcc_jit_context *ctxt,
Expand Down
5 changes: 5 additions & 0 deletions gcc/jit/libgccjit.map
Original file line number Diff line number Diff line change
Expand Up @@ -347,3 +347,8 @@ LIBGCCJIT_ABI_37 {
gcc_jit_function_set_location;
gcc_jit_rvalue_set_location;
} LIBGCCJIT_ABI_36;

LIBGCCJIT_ABI_38 {
global:
gcc_jit_context_new_alignof;
} LIBGCCJIT_ABI_37;
10 changes: 10 additions & 0 deletions gcc/testsuite/jit.dg/all-non-failing-tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@
#undef create_code
#undef verify_code

/* test-alignof.c */
#define create_code create_code_alignof
#define verify_code verify_code_alignof
#include "test-alignof.c"
#undef create_code
#undef verify_code

/* test-always_inline-attribute.c: This can't be in the testcases array as it needs
the `-O0` flag. */

Expand Down Expand Up @@ -455,6 +462,9 @@ const struct testcase testcases[] = {
{"accessing_union",
create_code_accessing_union,
verify_code_accessing_union},
{"alignof",
create_code_alignof,
verify_code_alignof},
{"alignment",
create_code_alignment,
verify_code_alignment},
Expand Down
69 changes: 69 additions & 0 deletions gcc/testsuite/jit.dg/test-alignof.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>

#include "libgccjit.h"

#include "harness.h"

void
create_code (gcc_jit_context *ctxt, void *user_data)
{
/* Let's try to inject the equivalent of:
int
my_alignof ()
{
return _Alignof(int32_t);
}
*/
gcc_jit_type *int32 =
gcc_jit_context_get_int_type (ctxt, 4, 1);
gcc_jit_type *int64 =
gcc_jit_context_get_int_type (ctxt, 8, 1);
gcc_jit_type *int_type =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);

gcc_jit_function *func =
gcc_jit_context_new_function (ctxt,
NULL,
GCC_JIT_FUNCTION_EXPORTED,
int_type,
"my_alignof",
0, NULL, 0);

gcc_jit_block *initial =
gcc_jit_function_new_block (func, "initial");

gcc_jit_field *field1 =
gcc_jit_context_new_field (ctxt, NULL, int32, "int32");
gcc_jit_field *field2 =
gcc_jit_context_new_field (ctxt, NULL, int64, "int64");

gcc_jit_field *fields[] = {
field1,
field2,
};

gcc_jit_struct *struct_type =
gcc_jit_context_new_struct_type (
ctxt,
NULL,
"ints",
2, fields);

gcc_jit_block_end_with_return(initial, NULL,
gcc_jit_context_new_alignof(ctxt, gcc_jit_struct_as_type (struct_type)));
}

void
verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
{
typedef int (*my_alignof_type) ();
CHECK_NON_NULL (result);
my_alignof_type my_alignof =
(my_alignof_type)gcc_jit_result_get_code (result, "my_alignof");
CHECK_NON_NULL (my_alignof);
int val = my_alignof ();
CHECK_VALUE (val, 8);
}
Loading