10 create_code (gcc_jit_context
*ctxt
, void *user_data
)
12 /* Let's try to inject the equivalent of:
15 test_nested_loops (int n, double *a, double *b)
18 for (int i = 0; i < n; i++)
19 for (int j = 0; j < n; j++)
20 result += a[i] * b[j];
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
,
46 gcc_jit_lvalue
*result
=
47 gcc_jit_function_new_local (func
, NULL
, val_type
, "result");
49 gcc_jit_function_new_local (func
, NULL
, int_type
, "i");
51 gcc_jit_function_new_local (func
, NULL
, int_type
, "j");
53 /* Create basic blocks. */
54 gcc_jit_block
*b_entry
=
55 gcc_jit_function_new_block (func
, "b_entry");
56 gcc_jit_block
*b_outer_loop_cond
=
57 gcc_jit_function_new_block (func
, "b_outer_loop_cond");
58 gcc_jit_block
*b_outer_loop_head
=
59 gcc_jit_function_new_block (func
, "b_outer_loop_head");
60 gcc_jit_block
*b_outer_loop_tail
=
61 gcc_jit_function_new_block (func
, "b_outer_loop_tail");
62 gcc_jit_block
*b_inner_loop_cond
=
63 gcc_jit_function_new_block (func
, "b_inner_loop_cond");
64 gcc_jit_block
*b_inner_loop_body
=
65 gcc_jit_function_new_block (func
, "b_inner_loop_body");
66 gcc_jit_block
*b_exit
=
67 gcc_jit_function_new_block (func
, "b_exit");
70 /* Populate b_entry. */
73 gcc_jit_block_add_assignment (
76 gcc_jit_context_zero (ctxt
, val_type
));
78 gcc_jit_block_add_assignment (
81 gcc_jit_context_zero (ctxt
, int_type
));
82 gcc_jit_block_end_with_jump (b_entry
, NULL
, b_outer_loop_cond
);
84 /* Populate b_outer_loop_cond. */
85 gcc_jit_block_end_with_conditional (
89 gcc_jit_context_new_comparison (
91 GCC_JIT_COMPARISON_LT
,
92 gcc_jit_lvalue_as_rvalue (i
),
93 gcc_jit_param_as_rvalue (param_n
)),
97 /* Populate b_outer_loop_head. */
99 gcc_jit_block_add_assignment (
100 b_outer_loop_head
, NULL
,
102 gcc_jit_context_zero (ctxt
, int_type
));
103 gcc_jit_block_end_with_jump (b_outer_loop_head
, NULL
, b_inner_loop_cond
);
105 /* Populate b_inner_loop_cond. */
106 gcc_jit_block_end_with_conditional (
110 gcc_jit_context_new_comparison (
112 GCC_JIT_COMPARISON_LT
,
113 gcc_jit_lvalue_as_rvalue (j
),
114 gcc_jit_param_as_rvalue (param_n
)),
118 /* Populate b_inner_loop_body. */
119 /* "result += a[i] * b[j];" */
120 gcc_jit_block_add_assignment_op (
121 b_inner_loop_body
, NULL
,
123 GCC_JIT_BINARY_OP_PLUS
,
124 gcc_jit_context_new_binary_op (
126 GCC_JIT_BINARY_OP_MULT
,
128 gcc_jit_lvalue_as_rvalue (
129 gcc_jit_context_new_array_access(
131 gcc_jit_param_as_rvalue (param_a
),
132 gcc_jit_lvalue_as_rvalue (i
))),
133 gcc_jit_lvalue_as_rvalue (
134 gcc_jit_context_new_array_access(
136 gcc_jit_param_as_rvalue (param_b
),
137 gcc_jit_lvalue_as_rvalue (j
)))));
139 gcc_jit_block_add_assignment_op (
140 b_inner_loop_body
, NULL
,
142 GCC_JIT_BINARY_OP_PLUS
,
143 gcc_jit_context_one (ctxt
, int_type
));
145 gcc_jit_block_end_with_jump (b_inner_loop_body
, NULL
, b_inner_loop_cond
);
147 /* Populate b_outer_loop_tail. */
149 gcc_jit_block_add_assignment_op (
150 b_outer_loop_tail
, NULL
,
152 GCC_JIT_BINARY_OP_PLUS
,
153 gcc_jit_context_one (ctxt
, int_type
));
154 gcc_jit_block_end_with_jump (b_outer_loop_tail
, NULL
, b_outer_loop_cond
);
156 /* Populate b_exit. */
157 /* "return result;" */
158 gcc_jit_block_end_with_return (
161 gcc_jit_lvalue_as_rvalue (result
));
165 verify_code (gcc_jit_context
*ctxt
, gcc_jit_result
*result
)
167 typedef double (*test_nested_loops_fn_type
) (int n
, double *a
, double *b
);
168 CHECK_NON_NULL (result
);
170 test_nested_loops_fn_type test_nested_loops
=
171 (test_nested_loops_fn_type
)gcc_jit_result_get_code (result
,
172 "test_nested_loops");
173 CHECK_NON_NULL (test_nested_loops
);
174 double test_a
[] = {1., 2., 3., 4., 5., 6., 7., 8., 9., 10.};
175 double test_b
[] = {5., 6., 7., 8., 9., 10., 1., 2., 3., 4.};
176 double val
= test_nested_loops (10, test_a
, test_b
);
177 note ("test_nested_loops returned: %f", val
);
178 CHECK_VALUE (val
, 3025.0);