Commit 6069fe72 by David Malcolm Committed by David Malcolm

jit: implement gcc_jit_context_new_rvalue_from_vector

This patch implements a new API entrypoint:

/* Build a vector rvalue from an array of elements.

   "vec_type" should be a vector type, created using gcc_jit_type_get_vector.

   This API entrypoint was added in LIBGCCJIT_ABI_10; you can test for its
   presence using
     #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_rvalue_from_vector
*/
extern gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt,
                                        gcc_jit_location *loc,
                                        gcc_jit_type *vec_type,
                                        size_t num_elements,
                                        gcc_jit_rvalue **elements);


gcc/jit/ChangeLog:
	* docs/cp/topics/expressions.rst (Vector expressions): New
	section.
	* docs/topics/compatibility.rst (LIBGCCJIT_ABI_10): New ABI tag.
	* docs/topics/expressions.rst (Vector expressions): New section.
	* docs/topics/types.rst (gcc_jit_type_get_vector): Add link to
	gcc_jit_context_new_rvalue_from_vector.
	* jit-common.h (gcc::jit:recording::vector_type): New forward
	decl.
	* jit-playback.c
	(gcc::jit::playback::context::new_rvalue_from_vector): New method.
	* jit-playback.h
	(gcc::jit::playback::context::new_rvalue_from_vector): New method.
	* jit-recording.c: In namespace gcc::jit::
	(class comma_separated_string): New class.
	(comma_separated_string::comma_separated_string): New ctor,
	adapted from recording::call::make_debug_string.
	(comma_separated_string::~comma_separated_string): New dtor.
	In namespace gcc::jit::recording::
	(context::new_rvalue_from_vector): New method.
	(type::get_vector): Update for renaming of memento_of_get_vector.
	(class memento_of_get_vector): Rename to...
	(class vector_type): ..this.
	(memento_of_new_rvalue_from_vector::memento_of_new_rvalue_from_vector):
	New ctor.
	(memento_of_new_rvalue_from_vector::replay_into): New method.
	(memento_of_new_rvalue_from_vector::visit_children): New method.
	(memento_of_new_rvalue_from_vector::make_debug_string): New
	method.
	(memento_of_new_rvalue_from_vector::write_reproducer): New method.
	(call::make_debug_string): Split out arg-printing code into ctor
	for comma_separated_string.
	* jit-recording.h: In namespace gcc::jit::recording::
	(context::new_rvalue_from_vector): New method.
	(type::dyn_cast_vector_type): New virtual function.
	(class memento_of_get_vector): Rename to...
	(class vector_type): ...this.
	(vector_type::unqualified): Remove this vfunc override in favor
	of...
	(vector_type::get_element_type): ...this new method.
	(vector_type::get_num_units): New method.
	(vector_type::dyn_cast_vector_type): New vfunc override.
	(class memento_of_new_rvalue_from_vector): New class.
	* libgccjit++.h (gccjit::context::new_rvalue): Add overload for
	vector of rvalue.
	* libgccjit.c (gcc_jit_context_new_binary_op): Strip off type
	qualifications when checking that both operands have same type.
	(gcc_jit_context_new_rvalue_from_vector): New API entrypoint.
	* libgccjit.h
	(LIBGCCJIT_HAVE_gcc_jit_context_new_rvalue_from_vector): New
	macro.
	(gcc_jit_context_new_rvalue_from_vector): New API entrypoint.
	* libgccjit.map (LIBGCCJIT_ABI_10): New ABI tag.

gcc/testsuite/ChangeLog:
	* jit.dg/test-expressions.c (make_test_of_vectors): New function.
	(create_code): Call it.
	* jit.dg/test-vector-rvalues.cc: New test case.

From-SVN: r253409
parent 4f15b6a2
2017-10-04 David Malcolm <dmalcolm@redhat.com>
* docs/cp/topics/expressions.rst (Vector expressions): New
section.
* docs/topics/compatibility.rst (LIBGCCJIT_ABI_10): New ABI tag.
* docs/topics/expressions.rst (Vector expressions): New section.
* docs/topics/types.rst (gcc_jit_type_get_vector): Add link to
gcc_jit_context_new_rvalue_from_vector.
* docs/_build/texinfo/libgccjit.texi: Regenerate.
* jit-common.h (gcc::jit:recording::vector_type): New forward
decl.
* jit-playback.c
(gcc::jit::playback::context::new_rvalue_from_vector): New method.
* jit-playback.h
(gcc::jit::playback::context::new_rvalue_from_vector): New method.
* jit-recording.c: In namespace gcc::jit::
(class comma_separated_string): New class.
(comma_separated_string::comma_separated_string): New ctor,
adapted from recording::call::make_debug_string.
(comma_separated_string::~comma_separated_string): New dtor.
In namespace gcc::jit::recording::
(context::new_rvalue_from_vector): New method.
(type::get_vector): Update for renaming of memento_of_get_vector.
(class memento_of_get_vector): Rename to...
(class vector_type): ..this.
(memento_of_new_rvalue_from_vector::memento_of_new_rvalue_from_vector):
New ctor.
(memento_of_new_rvalue_from_vector::replay_into): New method.
(memento_of_new_rvalue_from_vector::visit_children): New method.
(memento_of_new_rvalue_from_vector::make_debug_string): New
method.
(memento_of_new_rvalue_from_vector::write_reproducer): New method.
(call::make_debug_string): Split out arg-printing code into ctor
for comma_separated_string.
* jit-recording.h: In namespace gcc::jit::recording::
(context::new_rvalue_from_vector): New method.
(type::dyn_cast_vector_type): New virtual function.
(class memento_of_get_vector): Rename to...
(class vector_type): ...this.
(vector_type::unqualified): Remove this vfunc override in favor
of...
(vector_type::get_element_type): ...this new method.
(vector_type::get_num_units): New method.
(vector_type::dyn_cast_vector_type): New vfunc override.
(class memento_of_new_rvalue_from_vector): New class.
* libgccjit++.h (gccjit::context::new_rvalue): Add overload for
vector of rvalue.
* libgccjit.c (gcc_jit_context_new_binary_op): Strip off type
qualifications when checking that both operands have same type.
(gcc_jit_context_new_rvalue_from_vector): New API entrypoint.
* libgccjit.h
(LIBGCCJIT_HAVE_gcc_jit_context_new_rvalue_from_vector): New
macro.
(gcc_jit_context_new_rvalue_from_vector): New API entrypoint.
* libgccjit.map (LIBGCCJIT_ABI_10): New ABI tag.
2017-09-28 David Malcolm <dmalcolm@redhat.com>
* docs/topics/expressions.rst (Function calls): Add link to
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -105,6 +105,17 @@ Simple expressions
Generate an rvalue of type :c:data:`GCC_JIT_TYPE_CONST_CHAR_PTR` for
the given string. This is akin to a string literal.
Vector expressions
******************
.. function:: gccjit::rvalue \
gccjit::context::new_rvalue (gccjit::type vector_type, \
std::vector<gccjit::rvalue> elements) const
Given a vector type, and a vector of scalar rvalue elements, generate a
vector rvalue.
The number of elements needs to match that of the vector type.
Unary Operations
****************
......
......@@ -163,3 +163,11 @@ entrypoints:
-------------------
``LIBGCCJIT_ABI_9`` covers the addition of
:func:`gcc_jit_function_get_address`
.. _LIBGCCJIT_ABI_10:
``LIBGCCJIT_ABI_10``
--------------------
``LIBGCCJIT_ABI_10`` covers the addition of
:func:`gcc_jit_context_new_rvalue_from_vector`
......@@ -126,6 +126,30 @@ Simple expressions
underlying string, so it is valid to pass in a pointer to an on-stack
buffer.
Vector expressions
******************
.. function:: gcc_jit_rvalue * \
gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt, \
gcc_jit_location *loc, \
gcc_jit_type *vec_type, \
size_t num_elements, \
gcc_jit_rvalue **elements)
Build a vector rvalue from an array of elements.
"vec_type" should be a vector type, created using
:func:`gcc_jit_type_get_vector`.
"num_elements" should match that of the vector type.
This entrypoint was added in :ref:`LIBGCCJIT_ABI_10`; you can test for
its presence using
.. code-block:: c
#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_rvalue_from_vector
Unary Operations
****************
......
......@@ -177,6 +177,9 @@ Vector types
#ifdef LIBGCCJIT_HAVE_gcc_jit_type_get_vector
Vector rvalues can be generated using
:func:`gcc_jit_context_new_rvalue_from_vector`.
Structures and unions
---------------------
......
......@@ -117,6 +117,7 @@ namespace recording {
class compound_type;
class struct_;
class union_;
class vector_type;
class field;
class fields;
class function;
......
......@@ -629,6 +629,22 @@ new_string_literal (const char *value)
return new rvalue (this, t_addr);
}
/* Construct a playback::rvalue instance (wrapping a tree) for a
vector. */
playback::rvalue *
playback::context::new_rvalue_from_vector (location *,
type *type,
const auto_vec<rvalue *> &elements)
{
vec<constructor_elt, va_gc> *v;
vec_alloc (v, elements.length ());
for (unsigned i = 0; i < elements.length (); ++i)
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elements[i]->as_tree ());
tree t_ctor = build_constructor (type->as_tree (), v);
return new rvalue (this, t_ctor);
}
/* Coerce a tree expression into a boolean tree expression. */
tree
......
......@@ -114,6 +114,11 @@ public:
new_string_literal (const char *value);
rvalue *
new_rvalue_from_vector (location *loc,
type *type,
const auto_vec<rvalue *> &elements);
rvalue *
new_unary_op (location *loc,
enum gcc_jit_unary_op op,
type *result_type,
......
......@@ -447,6 +447,62 @@ reproducer::xstrdup_printf (const char *fmt, ...)
return result;
}
/* A helper class for implementing make_debug_string, for building
a temporary string from a vec of rvalues. */
class comma_separated_string
{
public:
comma_separated_string (const auto_vec<recording::rvalue *> &rvalues,
enum recording::precedence prec);
~comma_separated_string ();
const char *as_char_ptr () const { return m_buf; }
private:
char *m_buf;
};
/* comma_separated_string's ctor
Build m_buf. */
comma_separated_string::comma_separated_string
(const auto_vec<recording::rvalue *> &rvalues,
enum recording::precedence prec)
: m_buf (NULL)
{
/* Calculate length of said buffer. */
size_t sz = 1; /* nil terminator */
for (unsigned i = 0; i< rvalues.length (); i++)
{
sz += strlen (rvalues[i]->get_debug_string_parens (prec));
sz += 2; /* ", " separator */
}
/* Now allocate and populate the buffer. */
m_buf = new char[sz];
size_t len = 0;
for (unsigned i = 0; i< rvalues.length (); i++)
{
strcpy (m_buf + len, rvalues[i]->get_debug_string_parens (prec));
len += strlen (rvalues[i]->get_debug_string_parens (prec));
if (i + 1 < rvalues.length ())
{
strcpy (m_buf + len, ", ");
len += 2;
}
}
m_buf[len] = '\0';
}
/* comma_separated_string's dtor. */
comma_separated_string::~comma_separated_string ()
{
delete[] m_buf;
}
/**********************************************************************
Recording.
**********************************************************************/
......@@ -1001,6 +1057,23 @@ recording::context::new_string_literal (const char *value)
return result;
}
/* Create a recording::memento_of_new_rvalue_from_vector instance and add it
to this context's list of mementos.
Implements the post-error-checking part of
gcc_jit_context_new_rvalue_from_vector. */
recording::rvalue *
recording::context::new_rvalue_from_vector (location *loc,
vector_type *type,
rvalue **elements)
{
recording::rvalue *result
= new memento_of_new_rvalue_from_vector (this, loc, type, elements);
record (result);
return result;
}
/* Create a recording::unary_op instance and add it to this context's
list of mementos.
......@@ -2035,7 +2108,7 @@ recording::type *
recording::type::get_vector (size_t num_units)
{
recording::type *result
= new memento_of_get_vector (this, num_units);
= new vector_type (this, num_units);
m_ctxt->record (result);
return result;
}
......@@ -2523,13 +2596,13 @@ recording::memento_of_get_aligned::write_reproducer (reproducer &r)
m_alignment_in_bytes);
}
/* The implementation of class gcc::jit::recording::memento_of_get_vector. */
/* The implementation of class gcc::jit::recording::vector_type. */
/* Implementation of pure virtual hook recording::memento::replay_into
for recording::memento_of_get_vector. */
for recording::vector_type. */
void
recording::memento_of_get_vector::replay_into (replayer *)
recording::vector_type::replay_into (replayer *)
{
set_playback_obj
(m_other_type->playback_type ()->get_vector (m_num_units));
......@@ -2539,7 +2612,7 @@ recording::memento_of_get_vector::replay_into (replayer *)
results of get_vector. */
recording::string *
recording::memento_of_get_vector::make_debug_string ()
recording::vector_type::make_debug_string ()
{
return string::from_printf
(m_ctxt,
......@@ -2549,11 +2622,10 @@ recording::memento_of_get_vector::make_debug_string ()
m_num_units);
}
/* Implementation of recording::memento::write_reproducer for volatile
types. */
/* Implementation of recording::memento::write_reproducer for vector types. */
void
recording::memento_of_get_vector::write_reproducer (reproducer &r)
recording::vector_type::write_reproducer (reproducer &r)
{
const char *id = r.make_identifier (this, "type");
r.write (" gcc_jit_type *%s =\n"
......@@ -4569,6 +4641,96 @@ recording::memento_of_new_string_literal::write_reproducer (reproducer &r)
m_value->get_debug_string ());
}
/* The implementation of class
gcc::jit::recording::memento_of_new_rvalue_from_vector. */
/* The constructor for
gcc::jit::recording::memento_of_new_rvalue_from_vector. */
recording::memento_of_new_rvalue_from_vector::
memento_of_new_rvalue_from_vector (context *ctxt,
location *loc,
vector_type *type,
rvalue **elements)
: rvalue (ctxt, loc, type),
m_vector_type (type),
m_elements ()
{
for (unsigned i = 0; i < type->get_num_units (); i++)
m_elements.safe_push (elements[i]);
}
/* Implementation of pure virtual hook recording::memento::replay_into
for recording::memento_of_new_rvalue_from_vector. */
void
recording::memento_of_new_rvalue_from_vector::replay_into (replayer *r)
{
auto_vec<playback::rvalue *> playback_elements;
playback_elements.create (m_elements.length ());
for (unsigned i = 0; i< m_elements.length (); i++)
playback_elements.safe_push (m_elements[i]->playback_rvalue ());
set_playback_obj (r->new_rvalue_from_vector (playback_location (r, m_loc),
m_type->playback_type (),
playback_elements));
}
/* Implementation of pure virtual hook recording::rvalue::visit_children
for recording::memento_of_new_rvalue_from_vector. */
void
recording::memento_of_new_rvalue_from_vector::visit_children (rvalue_visitor *v)
{
for (unsigned i = 0; i< m_elements.length (); i++)
v->visit (m_elements[i]);
}
/* Implementation of recording::memento::make_debug_string for
vectors. */
recording::string *
recording::memento_of_new_rvalue_from_vector::make_debug_string ()
{
comma_separated_string elements (m_elements, get_precedence ());
/* Now build a string. */
string *result = string::from_printf (m_ctxt,
"{%s}",
elements.as_char_ptr ());
return result;
}
/* Implementation of recording::memento::write_reproducer for
vectors. */
void
recording::memento_of_new_rvalue_from_vector::write_reproducer (reproducer &r)
{
const char *id = r.make_identifier (this, "vector");
const char *elements_id = r.make_tmp_identifier ("elements_for_", this);
r.write (" gcc_jit_rvalue *%s[%i] = {\n",
elements_id,
m_elements.length ());
for (unsigned i = 0; i< m_elements.length (); i++)
r.write (" %s,\n", r.get_identifier_as_rvalue (m_elements[i]));
r.write (" };\n");
r.write (" gcc_jit_rvalue *%s =\n"
" gcc_jit_context_new_rvalue_from_vector (%s, /* gcc_jit_context *ctxt */\n"
" %s, /* gcc_jit_location *loc */\n"
" %s, /* gcc_jit_type *vec_type */\n"
" %i, /* size_t num_elements */ \n"
" %s); /* gcc_jit_rvalue **elements*/\n",
id,
r.get_identifier (get_context ()),
r.get_identifier (m_loc),
r.get_identifier (m_vector_type),
m_elements.length (),
elements_id);
}
/* The implementation of class gcc::jit::recording::unary_op. */
/* Implementation of pure virtual hook recording::memento::replay_into
......@@ -4982,39 +5144,14 @@ recording::call::visit_children (rvalue_visitor *v)
recording::string *
recording::call::make_debug_string ()
{
enum precedence prec = get_precedence ();
/* First, build a buffer for the arguments. */
/* Calculate length of said buffer. */
size_t sz = 1; /* nil terminator */
for (unsigned i = 0; i< m_args.length (); i++)
{
sz += strlen (m_args[i]->get_debug_string_parens (prec));
sz += 2; /* ", " separator */
}
/* Now allocate and populate the buffer. */
char *argbuf = new char[sz];
size_t len = 0;
for (unsigned i = 0; i< m_args.length (); i++)
{
strcpy (argbuf + len, m_args[i]->get_debug_string_parens (prec));
len += strlen (m_args[i]->get_debug_string_parens (prec));
if (i + 1 < m_args.length ())
{
strcpy (argbuf + len, ", ");
len += 2;
}
}
argbuf[len] = '\0';
comma_separated_string args (m_args, get_precedence ());
/* ...and use it to get the string for the call as a whole. */
string *result = string::from_printf (m_ctxt,
"%s (%s)",
m_func->get_debug_string (),
argbuf);
delete[] argbuf;
args.as_char_ptr ());
return result;
}
......
......@@ -149,6 +149,11 @@ public:
new_string_literal (const char *value);
rvalue *
new_rvalue_from_vector (location *loc,
vector_type *type,
rvalue **elements);
rvalue *
new_unary_op (location *loc,
enum gcc_jit_unary_op op,
type *result_type,
......@@ -486,6 +491,7 @@ public:
virtual function_type *dyn_cast_function_type () { return NULL; }
virtual function_type *as_a_function_type() { gcc_unreachable (); return NULL; }
virtual struct_ *dyn_cast_struct () { return NULL; }
virtual vector_type *dyn_cast_vector_type () { return NULL; }
/* Is it typesafe to copy to this type from rtype? */
virtual bool accepts_writes_from (type *rtype)
......@@ -690,15 +696,18 @@ private:
};
/* Result of "gcc_jit_type_get_vector". */
class memento_of_get_vector : public decorated_type
class vector_type : public decorated_type
{
public:
memento_of_get_vector (type *other_type, size_t num_units)
vector_type (type *other_type, size_t num_units)
: decorated_type (other_type),
m_num_units (num_units) {}
/* Strip off the alignment, giving the underlying type. */
type *unqualified () FINAL OVERRIDE { return m_other_type; }
size_t get_num_units () const { return m_num_units; }
vector_type *dyn_cast_vector_type () FINAL OVERRIDE { return this; }
type *get_element_type () { return m_other_type; }
void replay_into (replayer *) FINAL OVERRIDE;
......@@ -1358,6 +1367,31 @@ private:
string *m_value;
};
class memento_of_new_rvalue_from_vector : public rvalue
{
public:
memento_of_new_rvalue_from_vector (context *ctxt,
location *loc,
vector_type *type,
rvalue **elements);
void replay_into (replayer *r) FINAL OVERRIDE;
void visit_children (rvalue_visitor *) FINAL OVERRIDE;
private:
string * make_debug_string () FINAL OVERRIDE;
void write_reproducer (reproducer &r) FINAL OVERRIDE;
enum precedence get_precedence () const FINAL OVERRIDE
{
return PRECEDENCE_PRIMARY;
}
private:
vector_type *m_vector_type;
auto_vec<rvalue *> m_elements;
};
class unary_op : public rvalue
{
public:
......
......@@ -187,6 +187,8 @@ namespace gccjit
rvalue new_rvalue (type pointer_type,
void *value) const;
rvalue new_rvalue (const std::string &value) const;
rvalue new_rvalue (type vector_type,
std::vector<rvalue> elements) const;
/* Generic unary operations... */
rvalue new_unary_op (enum gcc_jit_unary_op op,
......@@ -897,6 +899,26 @@ context::new_rvalue (const std::string &value) const
}
inline rvalue
context::new_rvalue (type vector_type,
std::vector<rvalue> elements) const
{
/* Treat std::vector as an array, relying on it not being resized: */
rvalue *as_array_of_wrappers = &elements[0];
/* Treat the array as being of the underlying pointers, relying on
the wrapper type being such a pointer internally. */
gcc_jit_rvalue **as_array_of_ptrs =
reinterpret_cast<gcc_jit_rvalue **> (as_array_of_wrappers);
return rvalue (
gcc_jit_context_new_rvalue_from_vector (m_inner_ctxt,
NULL,
vector_type.get_inner_type (),
elements.size (),
as_array_of_ptrs));
}
inline rvalue
context::new_unary_op (enum gcc_jit_unary_op op,
type result_type,
rvalue a,
......
......@@ -1335,7 +1335,7 @@ gcc_jit_context_new_binary_op (gcc_jit_context *ctxt,
RETURN_NULL_IF_FAIL (a, ctxt, loc, "NULL a");
RETURN_NULL_IF_FAIL (b, ctxt, loc, "NULL b");
RETURN_NULL_IF_FAIL_PRINTF4 (
a->get_type () == b->get_type (),
a->get_type ()->unqualified () == b->get_type ()->unqualified (),
ctxt, loc,
"mismatching types for binary op:"
" a: %s (type: %s) b: %s (type: %s)",
......@@ -3042,3 +3042,61 @@ gcc_jit_function_get_address (gcc_jit_function *fn,
return (gcc_jit_rvalue *)fn->get_address (loc);
}
/* Public entrypoint. See description in libgccjit.h.
After error-checking, the real work is done by the
gcc::jit::recording::context::new_rvalue_from_vector method, in
jit-recording.c. */
extern gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt,
gcc_jit_location *loc,
gcc_jit_type *vec_type,
size_t num_elements,
gcc_jit_rvalue **elements)
{
RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL ctxt");
JIT_LOG_FUNC (ctxt->get_logger ());
/* LOC can be NULL. */
RETURN_NULL_IF_FAIL (vec_type, ctxt, loc, "NULL vec_type");
/* "vec_type" must be a vector type. */
gcc::jit::recording::vector_type *as_vec_type
= vec_type->dyn_cast_vector_type ();
RETURN_NULL_IF_FAIL_PRINTF1 (as_vec_type, ctxt, loc,
"%s is not a vector type",
vec_type->get_debug_string ());
/* "num_elements" must match. */
RETURN_NULL_IF_FAIL_PRINTF1 (
num_elements == as_vec_type->get_num_units (), ctxt, loc,
"num_elements != %zi", as_vec_type->get_num_units ());
/* "elements must be non-NULL. */
RETURN_NULL_IF_FAIL (elements, ctxt, loc, "NULL elements");
/* Each of "elements" must be non-NULL and of the correct type. */
gcc::jit::recording::type *element_type
= as_vec_type->get_element_type ();
for (size_t i = 0; i < num_elements; i++)
{
RETURN_NULL_IF_FAIL_PRINTF1 (
elements[i], ctxt, loc, "NULL elements[%zi]", i);
RETURN_NULL_IF_FAIL_PRINTF4 (
compatible_types (element_type,
elements[i]->get_type ()),
ctxt, loc,
"mismatching type for element[%zi] (expected type: %s): %s (type: %s)",
i,
element_type->get_debug_string (),
elements[i]->get_debug_string (),
elements[i]->get_type ()->get_debug_string ());
}
return (gcc_jit_rvalue *)ctxt->new_rvalue_from_vector
(loc,
as_vec_type,
(gcc::jit::recording::rvalue **)elements);
}
......@@ -1433,6 +1433,23 @@ gcc_jit_function_get_address (gcc_jit_function *fn,
gcc_jit_location *loc);
#define LIBGCCJIT_HAVE_gcc_jit_context_new_rvalue_from_vector
/* Build a vector rvalue from an array of elements.
"vec_type" should be a vector type, created using gcc_jit_type_get_vector.
This API entrypoint was added in LIBGCCJIT_ABI_10; you can test for its
presence using
#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_rvalue_from_vector
*/
extern gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt,
gcc_jit_location *loc,
gcc_jit_type *vec_type,
size_t num_elements,
gcc_jit_rvalue **elements);
#ifdef __cplusplus
}
#endif /* __cplusplus */
......
......@@ -165,3 +165,8 @@ LIBGCCJIT_ABI_9 {
global:
gcc_jit_function_get_address;
} LIBGCCJIT_ABI_8;
LIBGCCJIT_ABI_10 {
global:
gcc_jit_context_new_rvalue_from_vector;
} LIBGCCJIT_ABI_9;
2017-10-04 David Malcolm <dmalcolm@redhat.com>
* jit.dg/test-expressions.c (make_test_of_vectors): New function.
(create_code): Call it.
* jit.dg/test-vector-rvalues.cc: New test case.
2017-10-04 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* g++.dg/vect/slp-pr56812.cc: xfail for targets which don't want
......
......@@ -920,6 +920,35 @@ verify_get_address (gcc_jit_result *result)
}
/**********************************************************************
Vector values
**********************************************************************/
static void
make_test_of_vectors (gcc_jit_context *ctxt)
{
gcc_jit_type *scalar_type;
gcc_jit_type *vec_type;
gcc_jit_rvalue *elements[4];
scalar_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
vec_type = gcc_jit_type_get_vector (scalar_type, 4);
elements[0] = gcc_jit_context_new_rvalue_from_int (ctxt, scalar_type, 1);
elements[1] = gcc_jit_context_new_rvalue_from_int (ctxt, scalar_type, -2);
elements[2] = gcc_jit_context_new_rvalue_from_int (ctxt, scalar_type, 3);
elements[3] = gcc_jit_context_new_rvalue_from_int (ctxt, scalar_type, -4);
gcc_jit_rvalue *vec_rvalue
= gcc_jit_context_new_rvalue_from_vector (ctxt, NULL, vec_type,
4, elements);
CHECK_STRING_VALUE (
gcc_jit_object_get_debug_string (
gcc_jit_rvalue_as_object (vec_rvalue)),
"{(int)1, (int)-2, (int)3, (int)-4}");
}
/**********************************************************************
Code for harness
**********************************************************************/
......@@ -932,6 +961,7 @@ create_code (gcc_jit_context *ctxt, void *user_data)
make_tests_of_casts (ctxt);
make_tests_of_dereferences (ctxt);
make_test_of_get_address (ctxt);
make_test_of_vectors (ctxt);
}
void
......
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libgccjit.h"
#include "harness.h"
typedef int v4si __attribute__ ((vector_size (16)));
typedef unsigned int v4ui __attribute__ ((vector_size (16)));
typedef float v4f __attribute__ ((vector_size (16)));
static void
create_vec_fn (gcc_jit_context *ctxt, const char *fnname,
gcc_jit_type *vec_type,
gcc_jit_type *elem_type,
enum gcc_jit_binary_op op)
{
/* Create equivalent to:
static void
FNNAME (V *dst, const V *lhs, E p, E q, E r, E s)
{
V pqrs;
pqrs = {p, q, r, s};
*dst = *lhs OP pqrs;
}
where V is "vec_type" (e.g. v4si)
and E is "elem_type" (e.g. int). */
gcc_jit_type *ptr_type = gcc_jit_type_get_pointer (vec_type);
gcc_jit_type *const_type = gcc_jit_type_get_const (vec_type);
gcc_jit_type *ptr_to_const_type = gcc_jit_type_get_pointer (const_type);
gcc_jit_param *dst =
gcc_jit_context_new_param (ctxt, NULL, ptr_type, "dst");
gcc_jit_param *lhs =
gcc_jit_context_new_param (ctxt, NULL, ptr_to_const_type, "lhs");
gcc_jit_param *p =
gcc_jit_context_new_param (ctxt, NULL, elem_type, "p");
gcc_jit_param *q =
gcc_jit_context_new_param (ctxt, NULL, elem_type, "q");
gcc_jit_param *r =
gcc_jit_context_new_param (ctxt, NULL, elem_type, "r");
gcc_jit_param *s =
gcc_jit_context_new_param (ctxt, NULL, elem_type, "s");
gcc_jit_type *return_type =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
gcc_jit_param *params[6] = {dst, lhs, p, q, r, s};
gcc_jit_function *func =
gcc_jit_context_new_function (ctxt, NULL,
GCC_JIT_FUNCTION_EXPORTED,
return_type,
fnname,
6, params, 0);
gcc_jit_block *initial =
gcc_jit_function_new_block (func, "initial");
/* V pqrs; */
gcc_jit_lvalue *pqrs
= gcc_jit_function_new_local (func, NULL,
vec_type, "pqrs");
/* pqrs = {p, q, r, s}; */
gcc_jit_rvalue *elems[4];
elems[0] = gcc_jit_param_as_rvalue (p);
elems[1] = gcc_jit_param_as_rvalue (q);
elems[2] = gcc_jit_param_as_rvalue (r);
elems[3] = gcc_jit_param_as_rvalue (s);
gcc_jit_block_add_assignment (
initial, NULL,
pqrs,
gcc_jit_context_new_rvalue_from_vector (ctxt, NULL, vec_type, 4, elems));
/* (*lhs OP pqrs) */
gcc_jit_rvalue *op_result =
gcc_jit_context_new_binary_op (
ctxt, NULL,
op,
vec_type,
gcc_jit_lvalue_as_rvalue (gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (lhs),
NULL)),
gcc_jit_lvalue_as_rvalue (pqrs));
/* *dst = *lhs OP pqrs; */
gcc_jit_block_add_assignment (
initial, NULL,
gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (dst), NULL),
op_result);
gcc_jit_block_end_with_void_return (initial, NULL);
}
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
gcc_jit_type *unsigned_type
= gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_INT);
gcc_jit_type *float_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT);
gcc_jit_type *v4si_type = gcc_jit_type_get_vector (int_type, 4);
gcc_jit_type *v4ui_type = gcc_jit_type_get_vector (unsigned_type, 4);
gcc_jit_type *v4f_type = gcc_jit_type_get_vector (float_type, 4);
create_vec_fn (ctxt, "jit_v4si_add",
v4si_type, int_type, GCC_JIT_BINARY_OP_PLUS);
create_vec_fn (ctxt, "jit_v4si_sub",
v4si_type, int_type, GCC_JIT_BINARY_OP_MINUS);
create_vec_fn (ctxt, "jit_v4si_mult",
v4si_type, int_type, GCC_JIT_BINARY_OP_MULT);
create_vec_fn (ctxt, "jit_v4si_div",
v4si_type, int_type, GCC_JIT_BINARY_OP_DIVIDE);
create_vec_fn (ctxt, "jit_v4ui_add",
v4ui_type, unsigned_type, GCC_JIT_BINARY_OP_PLUS);
create_vec_fn (ctxt, "jit_v4ui_sub",
v4ui_type, unsigned_type, GCC_JIT_BINARY_OP_MINUS);
create_vec_fn (ctxt, "jit_v4ui_mult",
v4ui_type, unsigned_type, GCC_JIT_BINARY_OP_MULT);
create_vec_fn (ctxt, "jit_v4ui_div",
v4ui_type, unsigned_type, GCC_JIT_BINARY_OP_DIVIDE);
create_vec_fn (ctxt, "jit_v4f_add",
v4f_type, float_type, GCC_JIT_BINARY_OP_PLUS);
create_vec_fn (ctxt, "jit_v4f_sub",
v4f_type, float_type, GCC_JIT_BINARY_OP_MINUS);
create_vec_fn (ctxt, "jit_v4f_mult",
v4f_type, float_type, GCC_JIT_BINARY_OP_MULT);
create_vec_fn (ctxt, "jit_v4f_div",
v4f_type, float_type, GCC_JIT_BINARY_OP_DIVIDE);
}
template <typename V>
void
check_add (const V &a, const V &b, const V &c)
{
for (int i = 0; i < 4; i++)
CHECK_VALUE (c[i], a[i] + b[i]);
}
template <typename V>
void
check_sub (const V &a, const V &b, const V &c)
{
for (int i = 0; i < 4; i++)
CHECK_VALUE (c[i], a[i] - b[i]);
}
template <typename V>
void
check_mult (const V &a, const V &b, const V &c)
{
for (int i = 0; i < 4; i++)
CHECK_VALUE (c[i], a[i] * b[i]);
}
template <typename V>
void
check_div (const V &a, const V &b, const V &c)
{
for (int i = 0; i < 4; i++)
CHECK_VALUE (c[i], a[i] / b[i]);
}
template <typename V, typename E>
void
verify_vec_code (gcc_jit_context *ctxt, gcc_jit_result *result,
const char *fnname,
void (*check_cb) (const V &a, const V &b, const V &c))
{
typedef void (*binop_type) (const V *a, V *b, E p, E q, E r, E s);
CHECK_NON_NULL (result);
binop_type fn =
(binop_type)gcc_jit_result_get_code (result, fnname);
CHECK_NON_NULL (fn);
V dst, lhs, pqrs;
/* Init. */
for (int i = 0; i < 4; i++)
{
lhs[i] = i + 5;
pqrs[i] = (i + 4) * 3;
}
/* Run jit-compiled code and verify result. */
fn (&dst, &lhs, pqrs[0], pqrs[1], pqrs[2], pqrs[3]);
check_cb (lhs, pqrs, dst);
}
void
verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
{
verify_vec_code<v4si, int> (ctxt, result, "jit_v4si_add", check_add);
verify_vec_code<v4si, int> (ctxt, result, "jit_v4si_sub", check_sub);
verify_vec_code<v4si, int> (ctxt, result, "jit_v4si_mult", check_mult);
verify_vec_code<v4si, int> (ctxt, result, "jit_v4si_div", check_div);
verify_vec_code<v4ui, unsigned int> (ctxt, result, "jit_v4ui_add", check_add);
verify_vec_code<v4ui, unsigned int> (ctxt, result, "jit_v4ui_sub", check_sub);
verify_vec_code<v4ui, unsigned int> (ctxt, result, "jit_v4ui_mult", check_mult);
verify_vec_code<v4ui, unsigned int> (ctxt, result, "jit_v4ui_div", check_div);
verify_vec_code<v4f, float> (ctxt, result, "jit_v4f_add", check_add);
verify_vec_code<v4f, float> (ctxt, result, "jit_v4f_sub", check_sub);
verify_vec_code<v4f, float> (ctxt, result, "jit_v4f_mult", check_mult);
verify_vec_code<v4f, float> (ctxt, result, "jit_v4f_div", check_div);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment