PING: [PATCH][gcc] libgccjit: add bitfield support
Andrea Corallo
Andrea.Corallo@arm.com
Tue Jun 18 08:22:00 GMT 2019
Just wanted to politely ping to have have a status on that.
Bests
Andrea
Andrea Corallo writes:
> Hi all,
> I would like to submit this patch that aims to introduce bitfields support into libgccjit.
>
> A new entry point gcc_jit_context_new_bitfield is added plus relative testcase.
>
> Checked with make check-jit does not introduce regressions.
>
> Feedbacks are very welcome.
>
> Bests
>
> Andrea
>
> 2019-06-01 Andrea Corallo andrea.corallo@arm.com
>
> * docs/topics/compatibility.rst (LIBGCCJIT_ABI_12): New ABI tag.
> * docs/topics/types.rst: Add gcc_jit_context_new_bitfield.
> * jit-common.h (namespace recording): Add class bitfield.
> * jit-playback.c: Include "c-family/c-common.h"
> (playback::context::new_bitfield): New method.
> (playback::compound_type::set_fields): Add bitfield support.
> (playback::lvalue::jit_mark_addressable): Make this a method of lvalue
> plus return a bool to communicate success.
> (playback::lvalue::get_address): Check for jit_mark_addressable return
> value.
> * jit-playback.h (new_bitfield): New method.
> (class bitfield): New class.
> (class lvalue): Add jit_mark_addressable method.
> * jit-recording.c (recording::context::new_bitfield): New method.
> (recording::bitfield::replay_into): New method.
> (recording::bitfield::write_to_dump): Likewise.
> (recording::bitfield::make_debug_string): Likewise.
> (recording::bitfield::write_reproducer): Likewise.
> * jit-recording.h (class context): Add new_bitfield method.
> (class field): Make it derivable by class bitfield.
> (class bitfield): Add new class.
> * libgccjit++.h (class context): Add new_bitfield method.
> * libgccjit.c (struct gcc_jit_bitfield): New structure.
> (gcc_jit_context_new_bitfield): New function.
> * libgccjit.h
> (LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield) New macro.
> (gcc_jit_context_new_bitfield): New function.
> * libgccjit.map (LIBGCCJIT_ABI_12) New ABI tag.
>
>
> 2019-06-01 Andrea Corallo andrea.corallo@arm.com
>
> * jit.dg/all-non-failing-tests.h: Add test-accessing-bitfield.c.
> * jit.dg/test-accessing-bitfield.c: New testcase.
> diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst
> index abefa56..da64920 100644
> --- a/gcc/jit/docs/topics/compatibility.rst
> +++ b/gcc/jit/docs/topics/compatibility.rst
> @@ -177,3 +177,8 @@ entrypoints:
> --------------------
> ``LIBGCCJIT_ABI_11`` covers the addition of
> :func:`gcc_jit_context_add_driver_option`
> +
> +``LIBGCCJIT_ABI_12``
> +--------------------
> +``LIBGCCJIT_ABI_12`` covers the addition of
> +:func:`gcc_jit_context_new_bitfield`
> diff --git a/gcc/jit/docs/topics/types.rst b/gcc/jit/docs/topics/types.rst
> index 1d2dcd4..094f9fd 100644
> --- a/gcc/jit/docs/topics/types.rst
> +++ b/gcc/jit/docs/topics/types.rst
> @@ -247,6 +247,30 @@ You can model C `struct` types by creating :c:type:`gcc_jit_struct *` and
> underlying string, so it is valid to pass in a pointer to an on-stack
> buffer.
>
> +.. function:: gcc_jit_field *\
> + gcc_jit_context_new_bitfield (gcc_jit_context *ctxt,\
> + gcc_jit_location *loc,\
> + gcc_jit_type *type,\
> + int width,\
> + const char *name)
> +
> + Construct a new bit field, with the given type width and name.
> +
> + The parameter ``name`` must be non-NULL. The call takes a copy of the
> + underlying string, so it is valid to pass in a pointer to an on-stack
> + buffer.
> +
> + The parameter ``type`` must be an integer type.
> +
> + The parameter ``width`` must be a positive integer that does not exceed the
> + size of ``type``.
> +
> + This API entrypoint was added in :ref:`LIBGCCJIT_ABI_12`; you can test
> + for its presence using
> + .. code-block:: c
> +
> + #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield
> +
> .. function:: gcc_jit_object *\
> gcc_jit_field_as_object (gcc_jit_field *field)
>
> diff --git a/gcc/jit/jit-common.h b/gcc/jit/jit-common.h
> index 1d96cc3..e747d96 100644
> --- a/gcc/jit/jit-common.h
> +++ b/gcc/jit/jit-common.h
> @@ -119,6 +119,7 @@ namespace recording {
> class union_;
> class vector_type;
> class field;
> + class bitfield;
> class fields;
> class function;
> class block;
> diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
> index b74495c..7676e55 100644
> --- a/gcc/jit/jit-playback.c
> +++ b/gcc/jit/jit-playback.c
> @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
> #include "convert.h"
> #include "stor-layout.h"
> #include "print-tree.h"
> +#include "c-family/c-common.h"
> #include "gimplify.h"
> #include "gcc-driver-name.h"
> #include "attribs.h"
> @@ -263,6 +264,48 @@ new_field (location *loc,
> return new field (decl);
> }
>
> +/* Construct a playback::bitfield instance (wrapping a tree). */
> +
> +playback::field *
> +playback::context::
> +new_bitfield (location *loc,
> + type *type,
> + int width,
> + const char *name)
> +{
> + gcc_assert (type);
> + gcc_assert (name);
> + gcc_assert (width);
> +
> + /* compare with c/c-decl.c:grokfield, grokdeclarator and
> + check_bitfield_type_and_width. */
> +
> + tree tree_type = type->as_tree ();
> + if (TREE_CODE (tree_type) != INTEGER_TYPE
> + && TREE_CODE (tree_type) != BOOLEAN_TYPE)
> + {
> + add_error (loc, "bit-field %s has invalid type", name);
> + return NULL;
> + }
> + tree tree_width = build_int_cst (integer_type_node, width);
> + if (compare_tree_int (tree_width, TYPE_PRECISION (tree_type)) > 0)
> + {
> + add_error (loc, "bit-field %s exceeds its type", name);
> + return NULL;
> + }
> +
> + tree decl = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
> + get_identifier (name), type->as_tree ());
> + DECL_NONADDRESSABLE_P (decl) = true;
> + DECL_INITIAL (decl) = tree_width;
> + SET_DECL_C_BIT_FIELD (decl);
> +
> + if (loc)
> + set_tree_location (decl, loc);
> +
> + return new field (decl);
> +}
> +
> /* Construct a playback::compound_type instance (wrapping a tree). */
>
> playback::compound_type *
> @@ -295,8 +338,15 @@ playback::compound_type::set_fields (const auto_vec<playback::field *> *fields)
> for (unsigned i = 0; i < fields->length (); i++)
> {
> field *f = (*fields)[i];
> - DECL_CONTEXT (f->as_tree ()) = t;
> - fieldlist = chainon (f->as_tree (), fieldlist);
> + tree x = f->as_tree ();
> + DECL_CONTEXT (x) = t;
> + if (DECL_C_BIT_FIELD (x))
> + {
> + unsigned HOST_WIDE_INT width = tree_to_uhwi (DECL_INITIAL (x));
> + DECL_SIZE (x) = bitsize_int (width);
> + DECL_BIT_FIELD (x) = 1;
> + }
> + fieldlist = chainon (x, fieldlist);
> }
> fieldlist = nreverse (fieldlist);
> TYPE_FIELDS (t) = fieldlist;
> @@ -1197,20 +1247,30 @@ dereference (location *loc)
> return new lvalue (get_context (), datum);
> }
>
> -/* Mark EXP saying that we need to be able to take the
> +/* Mark the lvalue saying that we need to be able to take the
> address of it; it should not be allocated in a register.
> - Compare with e.g. c/c-typeck.c: c_mark_addressable. */
> + Compare with e.g. c/c-typeck.c: c_mark_addressable really_atomic_lvalue.
> + Returns true if successful. */
>
> -static void
> -jit_mark_addressable (tree exp)
> +bool
> +playback::lvalue::
> +jit_mark_addressable (location *loc)
> {
> - tree x = exp;
> + tree x = as_tree ();;
>
> while (1)
> switch (TREE_CODE (x))
> {
> case COMPONENT_REF:
> - /* (we don't yet support bitfields) */
> + if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1)))
> + {
> + gcc_assert (gcc::jit::active_playback_ctxt);
> + gcc::jit::
> + active_playback_ctxt->add_error (loc,
> + "cannot take address of "
> + "bit-field");
> + return false;
> + }
> /* fallthrough */
> case ADDR_EXPR:
> case ARRAY_REF:
> @@ -1222,7 +1282,7 @@ jit_mark_addressable (tree exp)
> case COMPOUND_LITERAL_EXPR:
> case CONSTRUCTOR:
> TREE_ADDRESSABLE (x) = 1;
> - return;
> + return true;
>
> case VAR_DECL:
> case CONST_DECL:
> @@ -1234,7 +1294,7 @@ jit_mark_addressable (tree exp)
> TREE_ADDRESSABLE (x) = 1;
> /* fallthrough */
> default:
> - return;
> + return true;
> }
> }
>
> @@ -1251,8 +1311,10 @@ get_address (location *loc)
> tree ptr = build1 (ADDR_EXPR, t_ptrtype, t_lvalue);
> if (loc)
> get_context ()->set_tree_location (ptr, loc);
> - jit_mark_addressable (t_lvalue);
> - return new rvalue (get_context (), ptr);
> + if (jit_mark_addressable (loc))
> + return new rvalue (get_context (), ptr);
> + else
> + return NULL;
> }
>
> /* The wrapper subclasses are GC-managed, but can own non-GC memory.
> diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
> index bc4de9c..c59f614 100644
> --- a/gcc/jit/jit-playback.h
> +++ b/gcc/jit/jit-playback.h
> @@ -75,6 +75,12 @@ public:
> type *type,
> const char *name);
>
> + field *
> + new_bitfield (location *loc,
> + type *type,
> + int width,
> + const char *name);
> +
> compound_type *
> new_compound_type (location *loc,
> const char *name,
> @@ -426,6 +432,8 @@ private:
> tree m_inner;
> };
>
> +class bitfield : public field {};
> +
> class function : public wrapper
> {
> public:
> @@ -614,6 +622,8 @@ public:
> rvalue *
> get_address (location *loc);
>
> +private:
> + bool jit_mark_addressable (location *loc);
> };
>
> class param : public lvalue
> @@ -703,4 +713,3 @@ extern playback::context *active_playback_ctxt;
> } // namespace gcc
>
> #endif /* JIT_PLAYBACK_H */
> -
> diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c
> index a332fe8..0678d07 100644
> --- a/gcc/jit/jit-recording.c
> +++ b/gcc/jit/jit-recording.c
> @@ -872,6 +872,24 @@ recording::context::new_field (recording::location *loc,
> return result;
> }
>
> +/* Create a recording::bitfield instance and add it to this context's list
> + of mementos.
> +
> + Implements the post-error-checking part of
> + gcc_jit_context_new_bitfield. */
> +
> +recording::field *
> +recording::context::new_bitfield (recording::location *loc,
> + recording::type *type,
> + int width,
> + const char *name)
> +{
> + recording::field *result =
> + new recording::bitfield (this, loc, type, width, new_string (name));
> + record (result);
> + return result;
> +}
> +
> /* Create a recording::struct_ instance and add it to this context's
> list of mementos and list of compound types.
>
> @@ -2999,6 +3017,66 @@ recording::field::write_reproducer (reproducer &r)
> m_name->get_debug_string ());
> }
>
> +/* The implementation of class gcc::jit::recording::bitfield. */
> +
> +/* Implementation of pure virtual hook recording::memento::replay_into
> + for recording::bitfield. */
> +
> +void
> +recording::bitfield::replay_into (replayer *r)
> +{
> + set_playback_obj (r->new_bitfield (playback_location (r, m_loc),
> + m_type->playback_type (),
> + m_width,
> + playback_string (m_name)));
> +}
> +
> +/* Override the default implementation of
> + recording::memento::write_to_dump. Dump each bit field
> + by dumping a line of the form:
> + TYPE NAME:WIDTH;
> + so that we can build up a struct/union field-byfield. */
> +
> +void
> +recording::bitfield::write_to_dump (dump &d)
> +{
> + d.write (" %s %s:%d;\n",
> + m_type->get_debug_string (),
> + m_name->c_str (),
> + m_width);
> +}
> +
> +/* Implementation of recording::memento::make_debug_string for
> + results of new_bitfield. */
> +
> +recording::string *
> +recording::bitfield::make_debug_string ()
> +{
> + return string::from_printf (m_ctxt,
> + "%s:%d",
> + m_name->c_str (), m_width);
> +}
> +
> +/* Implementation of recording::memento::write_reproducer for bitfields. */
> +
> +void
> +recording::bitfield::write_reproducer (reproducer &r)
> +{
> + const char *id = r.make_identifier (this, "bitfield");
> + r.write (" gcc_jit_field *%s =\n"
> + " gcc_jit_context_new_bitfield (%s,\n"
> + " %s, /* gcc_jit_location *loc */\n"
> + " %s, /* gcc_jit_type *type, */\n"
> + " %d, /* int *width, */\n"
> + " %s); /* const char *name */\n",
> + id,
> + r.get_identifier (get_context ()),
> + r.get_identifier (m_loc),
> + r.get_identifier_as_type (m_type),
> + m_width,
> + m_name->get_debug_string ());
> +}
> +
> /* The implementation of class gcc::jit::recording::compound_type */
>
> /* The constructor for gcc::jit::recording::compound_type. */
> diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
> index b9f2250..5e2d64e 100644
> --- a/gcc/jit/jit-recording.h
> +++ b/gcc/jit/jit-recording.h
> @@ -95,6 +95,12 @@ public:
> type *type,
> const char *name);
>
> + field *
> + new_bitfield (location *loc,
> + type *type,
> + int width,
> + const char *name);
> +
> struct_ *
> new_struct_type (location *loc,
> const char *name);
> @@ -822,9 +828,9 @@ public:
> compound_type * get_container () const { return m_container; }
> void set_container (compound_type *c) { m_container = c; }
>
> - void replay_into (replayer *) FINAL OVERRIDE;
> + void replay_into (replayer *);
>
> - void write_to_dump (dump &d) FINAL OVERRIDE;
> + void write_to_dump (dump &d);
>
> playback::field *
> playback_field () const
> @@ -833,16 +839,40 @@ public:
> }
>
> private:
> - string * make_debug_string () FINAL OVERRIDE;
> - void write_reproducer (reproducer &r) FINAL OVERRIDE;
> + string * make_debug_string ();
> + void write_reproducer (reproducer &r);
>
> -private:
> +protected:
> location *m_loc;
> type *m_type;
> string *m_name;
> compound_type *m_container;
> };
>
> +
> +class bitfield : public field
> +{
> +public:
> + bitfield (context *ctxt,
> + location *loc,
> + type *type,
> + int width,
> + string *name)
> + : field (ctxt, loc, type, name)
> + { m_width = width; }
> +
> + void replay_into (replayer *) FINAL OVERRIDE;
> +
> + void write_to_dump (dump &d) FINAL OVERRIDE;
> +
> +private:
> + string * make_debug_string () FINAL OVERRIDE;
> + void write_reproducer (reproducer &r) FINAL OVERRIDE;
> +
> +private:
> + int m_width;
> +};
> +
> /* Base class for struct_ and union_ */
> class compound_type : public type
> {
> diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h
> index 55aebca..e5a769a 100644
> --- a/gcc/jit/libgccjit++.h
> +++ b/gcc/jit/libgccjit++.h
> @@ -152,6 +152,9 @@ namespace gccjit
> field new_field (type type_, const std::string &name,
> location loc = location ());
>
> + field new_bitfield (type type_, int width, const std::string &name,
> + location loc = location ());
> +
> struct_ new_struct_type (const std::string &name,
> std::vector<field> &fields,
> location loc = location ());
> @@ -757,6 +760,17 @@ context::new_field (type type_, const std::string &name, location loc)
> name.c_str ()));
> }
>
> +inline field
> +context::new_bitfield (type type_, int width, const std::string &name,
> + location loc)
> +{
> + return field (gcc_jit_context_new_bitfield (m_inner_ctxt,
> + loc.get_inner_location (),
> + type_.get_inner_type (),
> + width,
> + name.c_str ()));
> +}
> +
> inline struct_
> context::new_struct_type (const std::string &name,
> std::vector<field> &fields,
> diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
> index e4f17f8..f1265a5 100644
> --- a/gcc/jit/libgccjit.c
> +++ b/gcc/jit/libgccjit.c
> @@ -62,6 +62,10 @@ struct gcc_jit_field : public gcc::jit::recording::field
> {
> };
>
> +struct gcc_jit_bitfield : public gcc::jit::recording::bitfield
> +{
> +};
> +
> struct gcc_jit_function : public gcc::jit::recording::function
> {
> };
> @@ -556,6 +560,35 @@ gcc_jit_context_new_field (gcc_jit_context *ctxt,
>
> /* Public entrypoint. See description in libgccjit.h.
>
> + After error-checking, the real work is done by the
> + gcc::jit::recording::context::new_bitfield method, in
> + jit-recording.c. */
> +
> +gcc_jit_field *
> +gcc_jit_context_new_bitfield (gcc_jit_context *ctxt,
> + gcc_jit_location *loc,
> + gcc_jit_type *type,
> + int width,
> + const char *name)
> +{
> + RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
> + JIT_LOG_FUNC (ctxt->get_logger ());
> + /* LOC can be NULL. */
> + RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
> + RETURN_NULL_IF_FAIL (width > 0, ctxt, NULL, "invalid width");
> + RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
> + RETURN_NULL_IF_FAIL_PRINTF2 (
> + type->has_known_size (),
> + ctxt, loc,
> + "unknown size for field \"%s\" (type: %s)",
> + name,
> + type->get_debug_string ());
> +
> + return (gcc_jit_field *)ctxt->new_bitfield (loc, type, width, name);
> +}
> +
> +/* Public entrypoint. See description in libgccjit.h.
> +
> After error-checking, this calls the trivial
> gcc::jit::recording::memento::as_object method (a field is a
> memento), in jit-recording.h. */
> diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
> index beeb747..9c5f23b 100644
> --- a/gcc/jit/libgccjit.h
> +++ b/gcc/jit/libgccjit.h
> @@ -602,6 +602,21 @@ gcc_jit_context_new_field (gcc_jit_context *ctxt,
> gcc_jit_type *type,
> const char *name);
>
> +#define LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield
> +
> +/* Create a bit field, for use within a struct or union.
> +
> + This API entrypoint was added in LIBGCCJIT_ABI_12; you can test for its
> + presence using
> + #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield
> +*/
> +extern gcc_jit_field *
> +gcc_jit_context_new_bitfield (gcc_jit_context *ctxt,
> + gcc_jit_location *loc,
> + gcc_jit_type *type,
> + int width,
> + const char *name);
> +
> /* Upcasting from field to object. */
> extern gcc_jit_object *
> gcc_jit_field_as_object (gcc_jit_field *field);
> diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
> index 16f5253..40e1c78 100644
> --- a/gcc/jit/libgccjit.map
> +++ b/gcc/jit/libgccjit.map
> @@ -174,4 +174,9 @@ LIBGCCJIT_ABI_10 {
> LIBGCCJIT_ABI_11 {
> global:
> gcc_jit_context_add_driver_option;
> -} LIBGCCJIT_ABI_10;
> \ No newline at end of file
> +} LIBGCCJIT_ABI_10;
> +
> +LIBGCCJIT_ABI_12 {
> + global:
> + gcc_jit_context_new_bitfield;
> +} LIBGCCJIT_ABI_11;
> \ No newline at end of file
> diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
> index 9a10418..f7af8e9 100644
> --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
> +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
> @@ -8,6 +8,13 @@
> hooks provided by each test case. */
> #define COMBINED_TEST
>
> +/* test-accessing-bitfield.c */
> +#define create_code create_code_accessing_bitfield
> +#define verify_code verify_code_accessing_bitfield
> +#include "test-accessing-bitfield.c"
> +#undef create_code
> +#undef verify_code
> +
> /* test-accessing-struct.c */
> #define create_code create_code_accessing_struct
> #define verify_code verify_code_accessing_struct
> diff --git a/gcc/testsuite/jit.dg/test-accessing-bitfield.c b/gcc/testsuite/jit.dg/test-accessing-bitfield.c
> new file mode 100644
> index 0000000..6ca8b24
> --- /dev/null
> +++ b/gcc/testsuite/jit.dg/test-accessing-bitfield.c
> @@ -0,0 +1,130 @@
> +#include <stdlib.h>
> +#include <stdio.h>
> +
> +#include "libgccjit.h"
> +
> +#include "harness.h"
> +
> +struct bit_foo
> +{
> + int i:3;
> + int x:5;
> + int y:5;
> + int z:10;
> + int j:3;
> +};
> +
> +void
> +create_code (gcc_jit_context *ctxt, void *user_data)
> +{
> + /* Let's try to inject the equivalent of:
> + void
> + test_access (struct bit_foo *f)
> + {
> + f->z = f->x + f->y;
> + }
> + */
> + gcc_jit_type *void_type =
> + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
> + gcc_jit_type *int_type =
> + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
> + gcc_jit_field *i =
> + gcc_jit_context_new_bitfield (ctxt,
> + NULL,
> + int_type,
> + 3,
> + "i");
> + gcc_jit_field *x =
> + gcc_jit_context_new_bitfield (ctxt,
> + NULL,
> + int_type,
> + 5,
> + "x");
> + gcc_jit_field *y =
> + gcc_jit_context_new_bitfield (ctxt,
> + NULL,
> + int_type,
> + 5,
> + "y");
> + gcc_jit_field *z =
> + gcc_jit_context_new_bitfield (ctxt,
> + NULL,
> + int_type,
> + 10,
> + "z");
> + gcc_jit_field *j =
> + gcc_jit_context_new_bitfield (ctxt,
> + NULL,
> + int_type,
> + 3,
> + "j");
> + gcc_jit_field *fields[] = {i, x, y, z, j};
> + gcc_jit_struct *struct_type =
> + gcc_jit_context_new_struct_type (ctxt, NULL, "bit_foo", 5, fields);
> + gcc_jit_type *ptr_type =
> + gcc_jit_type_get_pointer (gcc_jit_struct_as_type (struct_type));
> +
> + /* Build the test function. */
> + gcc_jit_param *param_f =
> + gcc_jit_context_new_param (ctxt, NULL, ptr_type, "f");
> + gcc_jit_function *test_fn =
> + gcc_jit_context_new_function (ctxt, NULL,
> + GCC_JIT_FUNCTION_EXPORTED,
> + void_type,
> + "test_access",
> + 1, ¶m_f,
> + 0);
> +
> + /* f->x + f->y */
> + gcc_jit_rvalue *sum =
> + gcc_jit_context_new_binary_op (
> + ctxt, NULL,
> + GCC_JIT_BINARY_OP_PLUS,
> + int_type,
> + gcc_jit_lvalue_as_rvalue (
> + gcc_jit_rvalue_dereference_field (
> + gcc_jit_param_as_rvalue (param_f),
> + NULL,
> + x)),
> + gcc_jit_lvalue_as_rvalue (
> + gcc_jit_rvalue_dereference_field (
> + gcc_jit_param_as_rvalue (param_f),
> + NULL,
> + y)));
> +
> + /* f->z = ... */
> + gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
> + gcc_jit_block_add_assignment (
> + block,
> + NULL,
> + gcc_jit_rvalue_dereference_field (
> + gcc_jit_param_as_rvalue (param_f),
> + NULL,
> + z),
> + sum);
> + gcc_jit_block_end_with_void_return (block, NULL);
> +}
> +
> +void
> +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
> +{
> + typedef void (*fn_type) (struct bit_foo *);
> + CHECK_NON_NULL (result);
> +
> + fn_type test_access =
> + (fn_type)gcc_jit_result_get_code (result, "test_access");
> + CHECK_NON_NULL (test_access);
> +
> + struct bit_foo tmp;
> + tmp.i = 3;
> + tmp.x = 5;
> + tmp.y = 7;
> + tmp.z = 0;
> + tmp.j = 3;
> +
> + /* Call the JIT-generated function. */
> + test_access (&tmp);
> +
> + /* Verify that the code correctly modified the field "z". */
> + CHECK_VALUE (tmp.z, 12);
> +}
More information about the Gcc-patches
mailing list