10 create_code (gcc_jit_context
*ctxt
, void *user_data
)
12 /* Let's try to inject the equivalent of:
15 my_dot_product (int n, double *a, double *b)
18 for (int i = 0; i < n; i++)
19 result += a[i] * b[i];
23 and see what the optimizer can do. */
24 gcc_jit_type
*val_type
=
25 gcc_jit_context_get_type (ctxt
, GCC_JIT_TYPE_DOUBLE
);
26 gcc_jit_type
*ptr_type
= gcc_jit_type_get_pointer (val_type
);
27 gcc_jit_type
*int_type
=
28 gcc_jit_context_get_type (ctxt
, GCC_JIT_TYPE_INT
);
30 gcc_jit_type
*return_type
= val_type
;
31 gcc_jit_param
*param_n
=
32 gcc_jit_context_new_param (ctxt
, NULL
, int_type
, "n");
33 gcc_jit_param
*param_a
=
34 gcc_jit_context_new_param (ctxt
, NULL
, ptr_type
, "a");
35 gcc_jit_param
*param_b
=
36 gcc_jit_context_new_param (ctxt
, NULL
, ptr_type
, "b");
37 gcc_jit_param
*params
[3] = {param_n
, param_a
, param_b
};
38 gcc_jit_function
*func
=
39 gcc_jit_context_new_function (ctxt
, NULL
,
40 GCC_JIT_FUNCTION_EXPORTED
,
45 gcc_jit_block
*initial
= gcc_jit_function_new_block (func
, "initial");
46 gcc_jit_block
*loop_test
= gcc_jit_function_new_block (func
, "loop_test");
47 gcc_jit_block
*loop_body
= gcc_jit_function_new_block (func
, "loop_body");
48 gcc_jit_block
*final
= gcc_jit_function_new_block (func
, "final");
50 /* Build: "double result = 0.;" */
51 gcc_jit_lvalue
*result
=
52 gcc_jit_function_new_local (func
, NULL
, val_type
, "result");
54 gcc_jit_block_add_assignment (initial
, NULL
,
55 result
, gcc_jit_context_zero (ctxt
, val_type
));
57 /* Build: "for (int i = 0; i < n; i++)" */
59 gcc_jit_function_new_local (func
, NULL
, int_type
, "i");
60 gcc_jit_block_add_assignment (initial
, NULL
,
61 i
, gcc_jit_context_zero (ctxt
, int_type
));
63 gcc_jit_block_end_with_jump (initial
, NULL
, loop_test
);
65 gcc_jit_block_end_with_conditional (
69 gcc_jit_context_new_comparison (
71 GCC_JIT_COMPARISON_LT
,
72 gcc_jit_lvalue_as_rvalue (i
),
73 gcc_jit_param_as_rvalue (param_n
)),
78 /* Build: "result += a[i] * b[i];" */
79 gcc_jit_block_add_assignment_op (
82 GCC_JIT_BINARY_OP_PLUS
,
83 gcc_jit_context_new_binary_op (
85 GCC_JIT_BINARY_OP_MULT
,
87 gcc_jit_lvalue_as_rvalue (
88 gcc_jit_context_new_array_access (
90 gcc_jit_param_as_rvalue (param_a
),
91 gcc_jit_lvalue_as_rvalue (i
))),
92 gcc_jit_lvalue_as_rvalue (
93 gcc_jit_context_new_array_access (
95 gcc_jit_param_as_rvalue (param_b
),
96 gcc_jit_lvalue_as_rvalue (i
)))));
99 gcc_jit_block_add_assignment_op (
102 GCC_JIT_BINARY_OP_PLUS
,
103 gcc_jit_context_one (ctxt
, int_type
));
105 gcc_jit_block_end_with_jump (loop_body
, NULL
, loop_test
);
107 /* Build: "return result;" */
108 gcc_jit_block_end_with_return (
111 gcc_jit_lvalue_as_rvalue (result
));
115 verify_code (gcc_jit_context
*ctxt
, gcc_jit_result
*result
)
117 typedef double (*my_dot_product_fn_type
) (int n
, double *a
, double *b
);
118 CHECK_NON_NULL (result
);
120 my_dot_product_fn_type my_dot_product
=
121 (my_dot_product_fn_type
)gcc_jit_result_get_code (result
,
123 CHECK_NON_NULL (my_dot_product
);
124 double test_array
[] = {1., 2., 3., 4., 5., 6., 7., 8., 9., 10.};
125 double val
= my_dot_product (10, test_array
, test_array
);
126 note ("my_dot_product returned: %f", val
);
127 CHECK_VALUE (val
, 385.0);