Committed to branch dmalcolm/jit: The following commit adds a way to create an array type from an existing type:
/* Given type "T", get type "T[N]" (for a constant N). */ extern gcc_jit_type * gcc_jit_context_new_array_type (gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_type *element_type, int num_elements); and renames the array access API from: gcc_jit_context_new_array_lookup to: gcc_jit_context_new_array_access changing it to return an lvalue rather than an rvalue. It also adds a helper function: extern gcc_jit_loop * gcc_jit_function_new_loop_over_range (gcc_jit_function *func, gcc_jit_location *loc, gcc_jit_lvalue *iteration_var, gcc_jit_rvalue *start_of_range, gcc_jit_rvalue *upper_bound_of_range, gcc_jit_rvalue *step); for creating loops of this form more easily: for (i = start_of_range; i < upper_bound_of_range; i += step) { BODY; } "start_of_range" can be NULL, in which case 0 is used. "upper_bound_of_range" must be non-NULL. "step" can be NULL, in which case 1 is used. gcc/jit/ * libgccjit.h (gcc_jit_context_new_array_type): New. (gcc_jit_context_new_array_lookup): Rename to... (gcc_jit_context_new_array_access): ...this, and change return type from rvalue to lvalue. (gcc_jit_function_new_loop_over_range): New. * libgccjit.map (gcc_jit_context_new_array_lookup): Rename to... (gcc_jit_context_new_array_access): ..this. (gcc_jit_context_new_array_type): New. (gcc_jit_function_new_loop_over_range): New. * libgccjit++.h (gccjit::context::new_array_type): New methods. (gccjit::context::new_array_access): New methods. * libgccjit.c (gcc_jit_context_new_array_type): New. (gcc_jit_context_new_array_lookup): Rename to... (gcc_jit_context_new_array_access): ...this, and change return type from rvalue to lvalue. (gcc_jit_function_new_loop): Provide NULL for the added arguments for the underlying API. (gcc_jit_function_new_loop_over_range): New. * internal-api.h (gcc::jit::recording::context:: new_array_type): New. (gcc::jit::recording::context::new_array_lookup): Rename to... (gcc::jit::recording::context::new_array_access): ...this, and change return type from an rvalue to an lvalue. (gcc::jit::recording::array_type): New subclass of type. (gcc::jit::recording::function::new_loop): Add iteration_var and step params, so that we can add a += when the loop ends. (gcc::jit::recording::array_lookup): Rename to... (gcc::jit::recording::array_access): ...this, and subclass from lvalue rathern than rvalue. (gcc::jit::recording::loop): Add optional iteration_var and step fields, for use by gcc_jit_function_new_loop_over_range so that, if present, we can add a += when the loop ends. (gcc::jit::playback::context::new_array_type): New. (gcc::jit::playback::context::new_array_lookup): Rename to... (gcc::jit::playback::context::new_array_access): ...this, and change return type from an rvalue to an lvalue. * internal-api.c (gcc::jit::recording::context::new_array_type): New. (gcc::jit::recording::context::new_array_lookup): Rename to... (gcc::jit::recording::context::new_array_access): ...this, and change return type from an rvalue to an lvalue. (gcc::jit::recording::array_type::dereference): New. (gcc::jit::recording::array_type::replay_into): New. (gcc::jit::recording::array_type::make_debug_string): New. (gcc::jit::recording::function::new_loop): Add iteration_var and step params. (gcc::jit::recording::array_lookup): Rename to... (gcc::jit::recording::array_access): ...this. (gcc::jit::recording::loop::end): If we have an iteration_var, and thus a step, inject a += operation immediately before the loop end. (gcc::jit::playback::context::new_array_type): New. (gcc::jit::playback::context::new_array_lookup): Rename to... (gcc::jit::playback::context::new_array_access): ...this, and change return type from an rvalue to an lvalue. gcc/testsuite/ * jit.dg/test-arrays.c: New test case, verifying that array types work as expected (and using the the new gcc_jit_function_new_loop_over_range API call). * jit.dg/test-dot-product.c (create_code): Update for API changes to array access. --- gcc/jit/internal-api.c | 90 +++++++++++++++++--- gcc/jit/internal-api.h | 72 +++++++++++++--- gcc/jit/libgccjit++.h | 43 ++++++++++ gcc/jit/libgccjit.c | 62 +++++++++++++- gcc/jit/libgccjit.h | 33 +++++++- gcc/jit/libgccjit.map | 4 +- gcc/testsuite/jit.dg/test-arrays.c | 144 ++++++++++++++++++++++++++++++++ gcc/testsuite/jit.dg/test-dot-product.c | 21 +++-- 8 files changed, 430 insertions(+), 39 deletions(-) create mode 100644 gcc/testsuite/jit.dg/test-arrays.c diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c index e061ebd..85d8fd1 100644 --- a/gcc/jit/internal-api.c +++ b/gcc/jit/internal-api.c @@ -214,6 +214,17 @@ recording::context::get_type (enum gcc_jit_types kind) return m_basic_types[kind]; } +recording::type * +recording::context::new_array_type (recording::location *loc, + recording::type *element_type, + int num_elements) +{ + recording::type *result = + new recording::array_type (this, loc, element_type, num_elements); + record (result); + return result; +} + recording::field * recording::context::new_field (recording::location *loc, recording::type *type, @@ -366,12 +377,12 @@ recording::context::new_call (recording::location *loc, return result; } -recording::rvalue * -recording::context::new_array_lookup (recording::location *loc, +recording::lvalue * +recording::context::new_array_access (recording::location *loc, recording::rvalue *ptr, recording::rvalue *index) { - recording::rvalue *result = new array_lookup (this, loc, ptr, index); + recording::lvalue *result = new array_access (this, loc, ptr, index); record (result); return result; } @@ -717,6 +728,31 @@ recording::memento_of_get_const::make_debug_string () "const %s", m_other_type->get_debug_string ()); } +/* gcc::jit::recording::array_type */ + +recording::type * +recording::array_type::dereference () +{ + return m_element_type; +} + +void +recording::array_type::replay_into (replayer *r) +{ + set_playback_obj (r->new_array_type (playback_location (m_loc), + m_element_type->playback_type (), + m_num_elements)); +} + +recording::string * +recording::array_type::make_debug_string () +{ + return string::from_printf (m_ctxt, + "%s[%d]", + m_element_type->get_debug_string (), + m_num_elements); +} + /* gcc::jit::recording::field:: */ void recording::field::replay_into (replayer *r) @@ -979,9 +1015,12 @@ recording::function::add_return (recording::location *loc, recording::loop * recording::function::new_loop (recording::location *loc, - recording::rvalue *boolval) + recording::rvalue *boolval, + recording::lvalue *iteration_var, + recording::rvalue *step) { - recording::loop *result = new recording::loop (this, loc, boolval); + recording::loop *result = new recording::loop (this, loc, boolval, + iteration_var, step); m_ctxt->record (result); return result; } @@ -1250,16 +1289,16 @@ recording::call::make_debug_string () } void -recording::array_lookup::replay_into (replayer *r) +recording::array_access::replay_into (replayer *r) { set_playback_obj ( - r->new_array_lookup (playback_location (m_loc), + r->new_array_access (playback_location (m_loc), m_ptr->playback_rvalue (), m_index->playback_rvalue ())); } recording::string * -recording::array_lookup::make_debug_string () +recording::array_access::make_debug_string () { return string::from_printf (m_ctxt, "%s[%s]", @@ -1553,6 +1592,15 @@ recording::loop::make_debug_string () void recording::loop::end (location *loc) { + if (m_iteration_var) + m_func->add_assignment ( + loc, + m_iteration_var, + m_ctxt->new_binary_op (loc, + GCC_JIT_BINARY_OP_PLUS, + m_iteration_var->get_type (), + m_iteration_var, + m_step)); recording::loop_end *m = new loop_end (this, loc); m_ctxt->record (m); } @@ -1697,6 +1745,24 @@ get_type (enum gcc_jit_types type_) return new type (type_node); } +playback::type * +playback::context:: +new_array_type (playback::location *loc, + playback::type *element_type, + int num_elements) +{ + gcc_assert (element_type); + + tree t = build_array_type_nelts (element_type->as_tree (), + num_elements); + layout_type (t); + + if (loc) + set_tree_location (t, loc); + + return new type (t); +} + playback::field * playback::context:: new_field (location *loc, @@ -2166,9 +2232,9 @@ new_call (location *loc, */ } -playback::rvalue * +playback::lvalue * playback::context:: -new_array_lookup (location *loc, +new_array_access (location *loc, rvalue *ptr, rvalue *index) { @@ -2190,7 +2256,7 @@ new_array_lookup (location *loc, NULL_TREE, NULL_TREE); if (loc) set_tree_location (t_result, loc); - return new rvalue (this, t_result); + return new lvalue (this, t_result); } else { @@ -2211,7 +2277,7 @@ new_array_lookup (location *loc, set_tree_location (t_indirection, loc); } - return new rvalue (this, t_indirection); + return new lvalue (this, t_indirection); } } diff --git a/gcc/jit/internal-api.h b/gcc/jit/internal-api.h index ce46433..aa98728 100644 --- a/gcc/jit/internal-api.h +++ b/gcc/jit/internal-api.h @@ -142,6 +142,11 @@ public: type * get_type (enum gcc_jit_types type); + type * + new_array_type (location *loc, + type *element_type, + int num_elements); + field * new_field (location *loc, type *type, @@ -210,8 +215,8 @@ public: function *func, int numargs, rvalue **args); - rvalue * - new_array_lookup (location *loc, + lvalue * + new_array_access (location *loc, rvalue *ptr, rvalue *index); @@ -504,6 +509,31 @@ private: type *m_other_type; }; +class array_type : public type +{ + public: + array_type (context *ctxt, + location *loc, + type *element_type, + int num_elements) + : type (ctxt), + m_loc (loc), + m_element_type (element_type), + m_num_elements (num_elements) + {} + + type *dereference (); + void replay_into (replayer *); + + private: + string * make_debug_string (); + + private: + location *m_loc; + type *m_element_type; + int m_num_elements; +}; + class field : public memento { public: @@ -724,7 +754,8 @@ public: loop * new_loop (location *loc, - rvalue *boolval); + rvalue *boolval, + lvalue *iteration_var, rvalue *step); type *get_return_type () const { return m_return_type; } string * get_name () const { return m_name; } @@ -963,14 +994,14 @@ private: vec<rvalue *> m_args; }; -class array_lookup : public rvalue +class array_access : public lvalue { public: - array_lookup (context *ctxt, + array_access (context *ctxt, location *loc, rvalue *ptr, rvalue *index) - : rvalue (ctxt, loc, ptr->get_type ()->dereference ()), + : lvalue (ctxt, loc, ptr->get_type ()->dereference ()), m_ptr (ptr), m_index (index) {} @@ -1293,11 +1324,15 @@ class loop : public memento public: loop (function *func, location *loc, - rvalue *boolval) + rvalue *boolval, + lvalue *iteration_var, rvalue *step) : memento (func->m_ctxt), m_func (func), m_loc (loc), - m_boolval (boolval) {} + m_boolval (boolval), + m_iteration_var (iteration_var), + m_step (step) + {} void replay_into (replayer *r); @@ -1316,6 +1351,18 @@ private: function *m_func; location *m_loc; rvalue *m_boolval; + + /* The following fields are for handling + gcc_jit_function_new_loop_over_range and are NULL for other loops. + + We preserve these from "_over_range" calls so that we can inject a + += assignment in the correct place immediately before the loop ends. + This is done within the recording::loop::end () method. + The corresponding playback::loop class has no special handling for + this, with the += operation having become a regular assignment by + that time. */ + lvalue *m_iteration_var; + rvalue *m_step; }; class loop_end : public memento @@ -1379,6 +1426,11 @@ public: type * get_type (enum gcc_jit_types type); + type * + new_array_type (location *loc, + type *element_type, + int num_elements); + field * new_field (location *loc, type *type, @@ -1444,8 +1496,8 @@ public: function *func, vec<rvalue *> args); - rvalue * - new_array_lookup (location *loc, + lvalue * + new_array_access (location *loc, rvalue *ptr, rvalue *index); diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h index be2f9ed..79abcd1 100644 --- a/gcc/jit/libgccjit++.h +++ b/gcc/jit/libgccjit++.h @@ -38,6 +38,9 @@ namespace gccjit type get_type (enum gcc_jit_types kind); + type new_array_type (type element_type, int num_elements); + type new_array_type (location loc, type element_type, int num_elements); + field new_field (type type_, const char *name); field new_field (location loc, type type_, const char *name); @@ -103,6 +106,12 @@ namespace gccjit function func, std::vector<rvalue> args); + lvalue new_array_access (rvalue ptr, + rvalue index); + lvalue new_array_access (location loc, + rvalue ptr, + rvalue index); + public: gcc_jit_context *m_inner_ctxt; }; @@ -303,6 +312,22 @@ context::get_type (enum gcc_jit_types kind) return type (gcc_jit_context_get_type (m_inner_ctxt, kind)); } +inline type +context::new_array_type (type element_type, int num_elements) +{ + return new_array_type (location (), element_type, num_elements); +} + +inline type +context::new_array_type (location loc, type element_type, int num_elements) +{ + return type (gcc_jit_context_new_array_type ( + m_inner_ctxt, + loc.get_inner_location (), + element_type.get_inner_type (), + num_elements)); +} + inline field context::new_field (type type_, const char *name) { @@ -550,6 +575,24 @@ context::new_call (location loc, as_array_of_ptrs); } +inline lvalue +context::new_array_access (rvalue ptr, + rvalue index) +{ + return new_array_access (location (), ptr, index); +} + +inline lvalue +context::new_array_access (location loc, + rvalue ptr, + rvalue index) +{ + return lvalue (gcc_jit_context_new_array_access (m_inner_ctxt, + loc.get_inner_location (), + ptr.get_inner_rvalue (), + index.get_inner_rvalue ())); +} + // class object inline std::string object::get_debug_string () const diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c index 67d09ea..181954d 100644 --- a/gcc/jit/libgccjit.c +++ b/gcc/jit/libgccjit.c @@ -261,6 +261,20 @@ gcc_jit_type_get_const (gcc_jit_type *type) return (gcc_jit_type *)type->get_const (); } +gcc_jit_type * +gcc_jit_context_new_array_type (gcc_jit_context *ctxt, + gcc_jit_location *loc, + gcc_jit_type *element_type, + int num_elements) +{ + RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context"); + RETURN_NULL_IF_FAIL (element_type, ctxt, "NULL type"); + + return (gcc_jit_type *)ctxt->new_array_type (loc, + element_type, + num_elements); +} + gcc_jit_field * gcc_jit_context_new_field (gcc_jit_context *ctxt, gcc_jit_location *loc, @@ -601,8 +615,8 @@ gcc_jit_context_new_call (gcc_jit_context *ctxt, (gcc::jit::recording::rvalue **)args); } -extern gcc_jit_rvalue * -gcc_jit_context_new_array_lookup (gcc_jit_context *ctxt, +extern gcc_jit_lvalue * +gcc_jit_context_new_array_access (gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_rvalue *ptr, gcc_jit_rvalue *index) @@ -611,7 +625,7 @@ gcc_jit_context_new_array_lookup (gcc_jit_context *ctxt, RETURN_NULL_IF_FAIL (ptr, ctxt, "NULL ptr"); RETURN_NULL_IF_FAIL (index, ctxt, "NULL index"); - return (gcc_jit_rvalue *)ctxt->new_array_lookup (loc, ptr, index); + return (gcc_jit_lvalue *)ctxt->new_array_access (loc, ptr, index); } gcc_jit_context * @@ -861,7 +875,47 @@ gcc_jit_function_new_loop (gcc_jit_function *func, RETURN_NULL_IF_NOT_FUNC_DEFINITION (func); RETURN_NULL_IF_FAIL (boolval, NULL, "NULL boolval"); - return (gcc_jit_loop *)func->new_loop (loc, boolval); + return (gcc_jit_loop *)func->new_loop (loc, boolval, NULL, NULL); +} + +gcc_jit_loop * +gcc_jit_function_new_loop_over_range (gcc_jit_function *func, + gcc_jit_location *loc, + gcc_jit_lvalue *iteration_var, + gcc_jit_rvalue *start_of_range, + gcc_jit_rvalue *upper_bound_of_range, + gcc_jit_rvalue *step) +{ + RETURN_NULL_IF_NOT_FUNC_DEFINITION (func); + gcc_jit_context *ctxt = static_cast <gcc_jit_context *> (func->m_ctxt); + RETURN_NULL_IF_FAIL (iteration_var, ctxt, "NULL iteration_var"); + RETURN_NULL_IF_FAIL (upper_bound_of_range, ctxt, + "NULL upper_bound_of_range"); + if (!start_of_range) + start_of_range = + gcc_jit_context_zero (ctxt, + static_cast <gcc_jit_type *> (iteration_var->get_type ())); + + if (!step) + step = gcc_jit_context_one (ctxt, + static_cast <gcc_jit_type *> (iteration_var->get_type ())); + + /* "iteration_var = start_of_range;" */ + gcc_jit_function_add_assignment (func, + loc, + iteration_var, + start_of_range); + + /* "(iteration_var < upper_bound_of_range)" */ + gcc_jit_rvalue *boolval = + gcc_jit_context_new_comparison (ctxt, + loc, + GCC_JIT_COMPARISON_LT, + gcc_jit_lvalue_as_rvalue (iteration_var), + upper_bound_of_range); + + /* the += is added when loop_end is called. */ + return (gcc_jit_loop *)func->new_loop (loc, boolval, iteration_var, step); } gcc_jit_object * diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h index f408baf..1ef55d0 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -359,6 +359,13 @@ gcc_jit_type_get_pointer (gcc_jit_type *type); extern gcc_jit_type * gcc_jit_type_get_const (gcc_jit_type *type); +/* Given type "T", get type "T[N]" (for a constant N). */ +extern gcc_jit_type * +gcc_jit_context_new_array_type (gcc_jit_context *ctxt, + gcc_jit_location *loc, + gcc_jit_type *element_type, + int num_elements); + /* Struct-handling. */ extern gcc_jit_field * gcc_jit_context_new_field (gcc_jit_context *ctxt, @@ -522,7 +529,7 @@ enum gcc_jit_binary_op /* Addition of arithmetic values; analogous to: (EXPR_A) + (EXPR_B) in C. - For pointer addition, use gcc_jit_context_new_array_lookup. */ + For pointer addition, use gcc_jit_context_new_array_access. */ GCC_JIT_BINARY_OP_PLUS, /* Subtraction of arithmetic values; analogous to: @@ -617,8 +624,8 @@ gcc_jit_context_new_call (gcc_jit_context *ctxt, gcc_jit_function *func, int numargs , gcc_jit_rvalue **args); -extern gcc_jit_rvalue * -gcc_jit_context_new_array_lookup (gcc_jit_context *ctxt, +extern gcc_jit_lvalue * +gcc_jit_context_new_array_access (gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_rvalue *ptr, gcc_jit_rvalue *index); @@ -812,6 +819,26 @@ gcc_jit_function_new_loop (gcc_jit_function *func, gcc_jit_location *loc, gcc_jit_rvalue *boolval); +/* Helper function for creating a loop of this form: + for (i = start_of_range; i < upper_bound_of_range; i += step) + { + BODY; + } + + Statements will be added to the body of the loop until + gcc_jit_loop_end is called. + + "start_of_range" can be NULL, in which case 0 is used. + "upper_bound_of_range" must be non-NULL. + "step" can be NULL, in which case 1 is used. */ +extern gcc_jit_loop * +gcc_jit_function_new_loop_over_range (gcc_jit_function *func, + gcc_jit_location *loc, + gcc_jit_lvalue *iteration_var, + gcc_jit_rvalue *start_of_range, + gcc_jit_rvalue *upper_bound_of_range, + gcc_jit_rvalue *step); + /* Upcasting from loop to object. */ extern gcc_jit_object * gcc_jit_loop_as_object (gcc_jit_loop *loop); diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map index 88cec7b..cbf9b33 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -6,7 +6,8 @@ gcc_jit_context_compile; gcc_jit_context_get_first_error; gcc_jit_context_get_type; - gcc_jit_context_new_array_lookup; + gcc_jit_context_new_array_access; + gcc_jit_context_new_array_type; gcc_jit_context_new_binary_op; gcc_jit_context_new_call; gcc_jit_context_new_child_context; @@ -41,6 +42,7 @@ gcc_jit_function_new_forward_label; gcc_jit_function_new_local; gcc_jit_function_new_loop; + gcc_jit_function_new_loop_over_range; gcc_jit_function_place_forward_label; gcc_jit_label_as_object; gcc_jit_location_as_object; diff --git a/gcc/testsuite/jit.dg/test-arrays.c b/gcc/testsuite/jit.dg/test-arrays.c new file mode 100644 index 0000000..2cff561 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-arrays.c @@ -0,0 +1,144 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stddef.h> + +#include "libgccjit.h" + +#include "harness.h" + +#define ARRAY_SIZE (4) + +/* Verify that struct layout works properly when adding an array field. */ +struct array_holder +{ + float m_before; + int m_ints[ARRAY_SIZE]; + float m_after; +}; + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + + void + test_array (struct array_holder *ah) + { + ah->m_before = 4.0f; + for i in 0 to (ARRAY_SIZE - 1): + ah->m_ints[i] = (i * i); + ah->m_after = 2.0f; + } + */ + gcc_jit_type *void_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); + gcc_jit_type *float_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT); + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + + gcc_jit_field *field_m_before = + gcc_jit_context_new_field (ctxt, NULL, float_type, "m_before"); + gcc_jit_field *field_m_ints = + gcc_jit_context_new_field ( + ctxt, NULL, + gcc_jit_context_new_array_type (ctxt, NULL, int_type, ARRAY_SIZE), + "m_ints"); + gcc_jit_field *field_m_after = + gcc_jit_context_new_field (ctxt, NULL, float_type, "m_after"); + + gcc_jit_field *fields[] = { + field_m_before, + field_m_ints, + field_m_after, + }; + + gcc_jit_type *struct_type = + gcc_jit_context_new_struct_type ( + ctxt, + NULL, + "array_holder", + 3, fields); + + gcc_jit_type *struct_ptr_type = + gcc_jit_type_get_pointer (struct_type); + + /* Build the test_fn. */ + gcc_jit_param *param_ah = + gcc_jit_context_new_param (ctxt, NULL, struct_ptr_type, "ah"); + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + void_type, + "test_array", + 1, ¶m_ah, + 0); + + /* "ah->m_before = 4.0f;" */ + gcc_jit_function_add_assignment ( + func, NULL, + gcc_jit_rvalue_dereference_field ( + gcc_jit_param_as_rvalue (param_ah), NULL, field_m_before), + gcc_jit_context_new_rvalue_from_int (ctxt, float_type, 4)); + + gcc_jit_function_add_comment (func, NULL, + "for i in 0 to (ARRAY_SIZE - 1):"); + gcc_jit_lvalue *i = + gcc_jit_function_new_local (func, NULL, int_type, "i"); + gcc_jit_loop *loop = + gcc_jit_function_new_loop_over_range ( + func, NULL, i, + NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, ARRAY_SIZE), + NULL); + + gcc_jit_function_add_comment (func, NULL, "ah->m_ints[i] = (i * i);"); + gcc_jit_function_add_assignment ( + func, NULL, + gcc_jit_context_new_array_access ( + ctxt, NULL, + gcc_jit_lvalue_as_rvalue (gcc_jit_rvalue_dereference_field ( + gcc_jit_param_as_rvalue (param_ah), + NULL, + field_m_ints)), + gcc_jit_lvalue_as_rvalue (i)), + gcc_jit_context_new_binary_op ( + ctxt, NULL, + GCC_JIT_BINARY_OP_MULT, + int_type, + gcc_jit_lvalue_as_rvalue (i), + gcc_jit_lvalue_as_rvalue (i))); + + gcc_jit_loop_end (loop, NULL); + + /* ah->m_after = 2.0f; */ + gcc_jit_function_add_assignment ( + func, NULL, + gcc_jit_rvalue_dereference_field ( + gcc_jit_param_as_rvalue (param_ah), NULL, field_m_after), + gcc_jit_context_new_rvalue_from_int (ctxt, float_type, 2)); + +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + typedef void (*fn_type) (struct array_holder *ah); + + CHECK_NON_NULL (result); + fn_type test_array = + (fn_type)gcc_jit_result_get_code (result, "test_array"); + CHECK_NON_NULL (test_array); + + struct array_holder ah; + memset (&ah, 0xf0, sizeof (ah)); + + test_array (&ah); + CHECK_VALUE (ah.m_before, 4.0f); + CHECK_VALUE (ah.m_ints[0], 0); + CHECK_VALUE (ah.m_ints[1], 1); + CHECK_VALUE (ah.m_ints[2], 4); + CHECK_VALUE (ah.m_ints[3], 9); + CHECK_VALUE (ah.m_after, 2.0f); + +} diff --git a/gcc/testsuite/jit.dg/test-dot-product.c b/gcc/testsuite/jit.dg/test-dot-product.c index 0cc6282..e78546c 100644 --- a/gcc/testsuite/jit.dg/test-dot-product.c +++ b/gcc/testsuite/jit.dg/test-dot-product.c @@ -68,17 +68,20 @@ create_code (gcc_jit_context *ctxt, void *user_data) func, NULL, result, GCC_JIT_BINARY_OP_PLUS, - gcc_jit_context_new_binary_op (ctxt, NULL, + gcc_jit_context_new_binary_op ( + ctxt, NULL, GCC_JIT_BINARY_OP_MULT, val_type, - gcc_jit_context_new_array_lookup( - ctxt, NULL, - gcc_jit_param_as_rvalue (param_a), - gcc_jit_lvalue_as_rvalue (i)), - gcc_jit_context_new_array_lookup( - ctxt, NULL, - gcc_jit_param_as_rvalue (param_b), - gcc_jit_lvalue_as_rvalue (i)))); + gcc_jit_lvalue_as_rvalue ( + gcc_jit_context_new_array_access ( + ctxt, NULL, + gcc_jit_param_as_rvalue (param_a), + gcc_jit_lvalue_as_rvalue (i))), + gcc_jit_lvalue_as_rvalue ( + gcc_jit_context_new_array_access ( + ctxt, NULL, + gcc_jit_param_as_rvalue (param_b), + gcc_jit_lvalue_as_rvalue (i))))); /* Build: "i++" */ gcc_jit_function_add_assignment_op ( -- 1.7.11.7