public inbox for jit@gcc.gnu.org
 help / color / mirror / Atom feed
From: Andrea Corallo <Andrea.Corallo@arm.com>
To: Andrea Corallo <Andrea.Corallo@arm.com>
Cc: "gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>,
	"jit@gcc.gnu.org"	<jit@gcc.gnu.org>, nd <nd@arm.com>,
	David Malcolm <dmalcolm@redhat.com>
Subject: PING: [PATCH][gcc] libgccjit: add bitfield support
Date: Tue, 01 Jan 2019 00:00:00 -0000	[thread overview]
Message-ID: <gkry31zjoch.fsf@arm.com> (raw)
In-Reply-To: <gkrd0jvvvx2.fsf@arm.com>

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, &param_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);
> +}

  reply	other threads:[~2019-06-18  8:22 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-01  0:00 Andrea Corallo
2019-01-01  0:00 ` Andrea Corallo [this message]
2019-01-01  0:00 ` David Malcolm
2019-01-01  0:00   ` Andrea Corallo
2019-01-01  0:00   ` Andrea Corallo
2019-01-01  0:00     ` David Malcolm
2019-01-01  0:00       ` Andrea Corallo
2019-01-01  0:00         ` David Malcolm
2019-01-01  0:00           ` Andrea Corallo
2019-01-01  0:00             ` Andrea Corallo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=gkry31zjoch.fsf@arm.com \
    --to=andrea.corallo@arm.com \
    --cc=dmalcolm@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jit@gcc.gnu.org \
    --cc=nd@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).