9 /**********************************************************************
10 GCC_JIT_FUNCTION_ALWAYS_INLINE and GCC_JIT_FUNCTION_INTERNAL
11 **********************************************************************/
13 create_test_of_hidden_function (gcc_jit_context
*ctxt
,
14 enum gcc_jit_function_kind hidden_kind
,
15 const char *hidden_func_name
,
16 const char *visible_func_name
)
18 /* Let's try to inject the equivalent of:
19 static double hidden_mult (double a, double b)
23 double my_square (double x)
25 return my_mult (x, x);
28 where hidden_mult can potentially be
29 inline __attribute__((always_inline)). */
30 gcc_jit_type
*double_type
=
31 gcc_jit_context_get_type (ctxt
, GCC_JIT_TYPE_DOUBLE
);
33 /* Create "my_mult" */
34 gcc_jit_param
*param_a
=
35 gcc_jit_context_new_param (ctxt
, NULL
, double_type
, "a");
36 gcc_jit_param
*param_b
=
37 gcc_jit_context_new_param (ctxt
, NULL
, double_type
, "b");
38 gcc_jit_param
*params
[2] = {param_a
, param_b
};
39 gcc_jit_function
*my_mult
=
40 gcc_jit_context_new_function (ctxt
, NULL
,
46 gcc_jit_block
*body_of_my_mult
=
47 gcc_jit_function_new_block (my_mult
, NULL
);
48 gcc_jit_block_end_with_return (
49 body_of_my_mult
, NULL
,
50 gcc_jit_context_new_binary_op (
52 GCC_JIT_BINARY_OP_MULT
,
54 gcc_jit_param_as_rvalue (param_a
),
55 gcc_jit_param_as_rvalue (param_b
)));
57 /* Create "my_square" */
58 gcc_jit_param
*param_x
=
59 gcc_jit_context_new_param (ctxt
, NULL
, double_type
, "x");
60 gcc_jit_function
*my_square
=
61 gcc_jit_context_new_function (ctxt
, NULL
,
62 GCC_JIT_FUNCTION_EXPORTED
,
67 gcc_jit_block
*body_of_my_square
=
68 gcc_jit_function_new_block (my_square
, NULL
);
69 gcc_jit_rvalue
*args
[2] = {gcc_jit_param_as_rvalue (param_x
),
70 gcc_jit_param_as_rvalue (param_x
)};
71 gcc_jit_block_end_with_return (
72 body_of_my_square
, NULL
,
73 gcc_jit_context_new_call (
80 create_tests_of_hidden_functions (gcc_jit_context
*ctxt
)
82 create_test_of_hidden_function (ctxt
,
83 GCC_JIT_FUNCTION_INTERNAL
,
85 "my_square_with_internal");
86 create_test_of_hidden_function (ctxt
,
87 GCC_JIT_FUNCTION_ALWAYS_INLINE
,
88 "my_always_inline_mult",
89 "my_square_with_always_inline");
93 verify_hidden_functions (gcc_jit_context
*ctxt
, gcc_jit_result
*result
)
95 CHECK_NON_NULL (result
);
97 /* GCC_JIT_FUNCTION_INTERNAL and GCC_JIT_FUNCTION_ALWAYS_INLINE
98 functions should not be accessible in the result. */
99 CHECK_VALUE (NULL
, gcc_jit_result_get_code (result
, "my_internal_mult"));
100 CHECK_VALUE (NULL
, gcc_jit_result_get_code (result
, "my_always_inline_mult"));
102 typedef double (*fn_type
) (double);
103 fn_type my_square_with_internal
=
104 (fn_type
)gcc_jit_result_get_code (result
, "my_square_with_internal");
105 CHECK_NON_NULL (my_square_with_internal
);
106 CHECK_VALUE (my_square_with_internal (5.0), 25.0);
108 fn_type my_square_with_always_inline
=
109 (fn_type
)gcc_jit_result_get_code (result
, "my_square_with_always_inline");
110 CHECK_NON_NULL (my_square_with_always_inline
);
111 CHECK_VALUE (my_square_with_always_inline (5.0), 25.0);
114 /**********************************************************************
116 **********************************************************************/
119 create_test_of_builtin_strcmp (gcc_jit_context
*ctxt
)
121 /* Let's try to inject the equivalent of:
123 test_of_builtin_strcmp (const char *a, const char *b)
125 return __builtin_strcmp (a, b);
128 gcc_jit_type
*int_type
=
129 gcc_jit_context_get_type (ctxt
, GCC_JIT_TYPE_INT
);
130 gcc_jit_type
*const_char_ptr_type
=
131 gcc_jit_context_get_type (ctxt
, GCC_JIT_TYPE_CONST_CHAR_PTR
);
133 /* Get the built-in function. */
134 gcc_jit_function
*builtin_fn
=
135 gcc_jit_context_get_builtin_function (ctxt
, "strcmp");
138 gcc_jit_object_get_debug_string (gcc_jit_function_as_object (builtin_fn
)),
141 /* Build the test_fn. */
142 gcc_jit_param
*param_a
=
143 gcc_jit_context_new_param (ctxt
, NULL
, const_char_ptr_type
, "a");
144 gcc_jit_param
*param_b
=
145 gcc_jit_context_new_param (ctxt
, NULL
, const_char_ptr_type
, "b");
146 gcc_jit_param
*params
[2] = {param_a
, param_b
};
147 gcc_jit_function
*test_fn
=
148 gcc_jit_context_new_function (ctxt
, NULL
,
149 GCC_JIT_FUNCTION_EXPORTED
,
151 "test_of_builtin_strcmp",
154 gcc_jit_rvalue
*args
[2] = {gcc_jit_param_as_rvalue (param_a
),
155 gcc_jit_param_as_rvalue (param_b
)};
156 gcc_jit_rvalue
*call
=
157 gcc_jit_context_new_call (ctxt
,
162 gcc_jit_object_get_debug_string (gcc_jit_rvalue_as_object (call
)),
165 gcc_jit_block
*initial
=
166 gcc_jit_function_new_block (test_fn
, "initial");
167 gcc_jit_block_end_with_return (initial
, NULL
, call
);
170 static char *trig_sincos_dump
;
171 static char *trig_statistics_dump
;
174 create_test_of_builtin_trig (gcc_jit_context
*ctxt
)
176 /* Let's try to inject the equivalent of:
178 test_of_builtin_trig (double theta)
180 return 2 * sin (theta) * cos (theta);
182 (in theory, optimizable to sin (2 * theta))
185 gcc_jit_context_enable_dump (ctxt
,
188 gcc_jit_context_enable_dump (ctxt
,
190 &trig_statistics_dump
);
192 gcc_jit_type
*double_t
=
193 gcc_jit_context_get_type (ctxt
, GCC_JIT_TYPE_DOUBLE
);
195 /* Get the built-in functions. */
196 gcc_jit_function
*builtin_sin
=
197 gcc_jit_context_get_builtin_function (ctxt
, "sin");
198 gcc_jit_function
*builtin_cos
=
199 gcc_jit_context_get_builtin_function (ctxt
, "cos");
201 /* Build the test_fn. */
202 gcc_jit_param
*param_theta
=
203 gcc_jit_context_new_param (ctxt
, NULL
, double_t
, "theta");
204 gcc_jit_function
*test_fn
=
205 gcc_jit_context_new_function (ctxt
, NULL
,
206 GCC_JIT_FUNCTION_EXPORTED
,
208 "test_of_builtin_trig",
211 gcc_jit_rvalue
*args
[1] = {gcc_jit_param_as_rvalue (param_theta
)};
212 gcc_jit_rvalue
*two
=
213 gcc_jit_context_new_rvalue_from_int (ctxt
, double_t
, 2);
214 gcc_jit_rvalue
*ret
=
215 gcc_jit_context_new_binary_op (
217 GCC_JIT_BINARY_OP_MULT
,
220 gcc_jit_context_new_binary_op (
222 GCC_JIT_BINARY_OP_MULT
,
224 gcc_jit_context_new_call (ctxt
, NULL
,
227 gcc_jit_context_new_call (ctxt
, NULL
,
231 gcc_jit_object_get_debug_string (gcc_jit_rvalue_as_object (ret
)),
232 "(double)2 * sin (theta) * cos (theta)");
234 gcc_jit_block
*initial
=
235 gcc_jit_function_new_block (test_fn
, "initial");
236 gcc_jit_block_end_with_return (initial
, NULL
, ret
);
240 create_use_of_builtins (gcc_jit_context
*ctxt
)
242 create_test_of_builtin_strcmp (ctxt
);
243 create_test_of_builtin_trig (ctxt
);
247 verify_test_of_builtin_strcmp (gcc_jit_context
*ctxt
, gcc_jit_result
*result
)
249 typedef int (*fn_type
) (const char *, const char *);
250 CHECK_NON_NULL (result
);
252 fn_type test_of_builtin_strcmp
=
253 (fn_type
)gcc_jit_result_get_code (result
, "test_of_builtin_strcmp");
254 CHECK_NON_NULL (test_of_builtin_strcmp
);
256 /* Verify that it correctly called strcmp. */
257 CHECK_VALUE (test_of_builtin_strcmp ("foo", "foo"), 0);
258 CHECK (test_of_builtin_strcmp ("foo", "bar") > 0);
259 CHECK (test_of_builtin_strcmp ("bar", "foo") < 0);
263 verify_test_of_builtin_trig (gcc_jit_context
*ctxt
, gcc_jit_result
*result
)
265 typedef double (*fn_type
) (double);
266 CHECK_NON_NULL (result
);
268 fn_type test_of_builtin_trig
=
269 (fn_type
)gcc_jit_result_get_code (result
, "test_of_builtin_trig");
270 CHECK_NON_NULL (test_of_builtin_trig
);
272 /* Verify that it correctly computes
274 (perhaps calling sin and cos). */
275 CHECK_DOUBLE_VALUE (test_of_builtin_trig (0.0 ), 0.0);
276 CHECK_DOUBLE_VALUE (test_of_builtin_trig (M_PI_4
), 1.0);
277 CHECK_DOUBLE_VALUE (test_of_builtin_trig (M_PI_2
), 0.0);
278 CHECK_DOUBLE_VALUE (test_of_builtin_trig (M_PI_4
* 3.0), -1.0);
279 CHECK_DOUBLE_VALUE (test_of_builtin_trig (M_PI
), 0.0);
282 The "sincos" pass merges sin/cos calls into the cexpi builtin.
283 Verify that a dump of the "sincos" pass was provided, and that it
284 shows a call to the cexpi builtin on a SSA name of "theta". */
285 CHECK_NON_NULL (trig_sincos_dump
);
286 CHECK_STRING_CONTAINS (trig_sincos_dump
, " = __builtin_cexpi (theta_");
287 free (trig_sincos_dump
);
289 /* Similarly, verify that the statistics dump was provided, and that
290 it shows the sincos optimization. */
291 CHECK_NON_NULL (trig_statistics_dump
);
292 CHECK_STRING_CONTAINS (
293 trig_statistics_dump
,
294 "sincos \"sincos statements inserted\" \"test_of_builtin_trig\" 1");
295 free (trig_statistics_dump
);
299 verify_use_of_builtins (gcc_jit_context
*ctxt
, gcc_jit_result
*result
)
301 verify_test_of_builtin_strcmp (ctxt
, result
);
302 verify_test_of_builtin_trig (ctxt
, result
);
305 /**********************************************************************
307 **********************************************************************/
310 create_use_of_void_return (gcc_jit_context
*ctxt
)
312 /* Let's try to inject the equivalent of:
314 test_of_void_return (int *out)
320 gcc_jit_type
*void_t
=
321 gcc_jit_context_get_type (ctxt
, GCC_JIT_TYPE_VOID
);
322 gcc_jit_type
*int_t
=
323 gcc_jit_context_get_type (ctxt
, GCC_JIT_TYPE_INT
);
324 gcc_jit_type
*int_ptr_t
=
325 gcc_jit_type_get_pointer (int_t
);
327 /* Build the test_fn. */
328 gcc_jit_param
*param_out
=
329 gcc_jit_context_new_param (ctxt
, NULL
, int_ptr_t
, "out");
330 gcc_jit_function
*test_fn
=
331 gcc_jit_context_new_function (ctxt
, NULL
,
332 GCC_JIT_FUNCTION_EXPORTED
,
334 "test_of_void_return",
337 gcc_jit_block
*initial
=
338 gcc_jit_function_new_block (test_fn
, "initial");
340 gcc_jit_block_add_assignment (
343 gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (param_out
),
345 gcc_jit_context_one (ctxt
, int_t
));
346 gcc_jit_block_end_with_void_return (initial
, NULL
);
350 verify_void_return (gcc_jit_context
*ctxt
, gcc_jit_result
*result
)
352 typedef void (*fn_type
) (int *);
353 CHECK_NON_NULL (result
);
355 fn_type test_of_void_return
=
356 (fn_type
)gcc_jit_result_get_code (result
, "test_of_void_return");
357 CHECK_NON_NULL (test_of_void_return
);
360 test_of_void_return (&i
);
361 CHECK_VALUE (i
, 1); /* ensure correct value was written back */
364 /**********************************************************************
366 **********************************************************************/
369 create_code (gcc_jit_context
*ctxt
, void *user_data
)
371 create_tests_of_hidden_functions (ctxt
);
372 create_use_of_builtins (ctxt
);
373 create_use_of_void_return (ctxt
);
378 verify_code (gcc_jit_context
*ctxt
, gcc_jit_result
*result
)
380 verify_hidden_functions (ctxt
, result
);
381 verify_use_of_builtins (ctxt
, result
);
382 verify_void_return (ctxt
, result
);