111
|
1 #include <stdlib.h>
|
|
2 #include <stdio.h>
|
|
3 #include <string.h>
|
|
4
|
|
5 #include "libgccjit.h"
|
|
6
|
|
7 #include "harness.h"
|
|
8
|
|
9 void
|
|
10 create_code (gcc_jit_context *ctxt, void *user_data)
|
|
11 {
|
|
12 /* Let's try to inject the equivalent of:
|
|
13
|
|
14 int
|
|
15 my_factorial (int x)
|
|
16 {
|
|
17 if (x < 2)
|
|
18 return x;
|
|
19 else
|
|
20 return x * my_factorial (x - 1);
|
|
21 }
|
|
22
|
|
23 and see if the optimizer eliminates the recursion (it does).
|
|
24 */
|
|
25 gcc_jit_type *the_type =
|
|
26 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
|
|
27 gcc_jit_type *return_type = the_type;
|
|
28
|
|
29 gcc_jit_param *x =
|
|
30 gcc_jit_context_new_param (ctxt, NULL, the_type, "x");
|
|
31 gcc_jit_param *params[1] = {x};
|
|
32 gcc_jit_function *func =
|
|
33 gcc_jit_context_new_function (ctxt, NULL,
|
|
34 GCC_JIT_FUNCTION_EXPORTED,
|
|
35 return_type,
|
|
36 "my_factorial",
|
|
37 1, params, 0);
|
|
38
|
|
39 gcc_jit_block *initial =
|
|
40 gcc_jit_function_new_block (func, "initial");
|
|
41 gcc_jit_block *on_true =
|
|
42 gcc_jit_function_new_block (func, "on_true");
|
|
43 gcc_jit_block *on_false =
|
|
44 gcc_jit_function_new_block (func, "on_false");
|
|
45
|
|
46 /* if (x < 2) */
|
|
47 gcc_jit_block_end_with_conditional (
|
|
48 initial, NULL,
|
|
49 gcc_jit_context_new_comparison (
|
|
50 ctxt, NULL,
|
|
51 GCC_JIT_COMPARISON_LT,
|
|
52 gcc_jit_param_as_rvalue (x),
|
|
53 gcc_jit_context_new_rvalue_from_int (
|
|
54 ctxt,
|
|
55 the_type,
|
|
56 2)),
|
|
57 on_true,
|
|
58 on_false);
|
|
59
|
|
60 /* true branch: */
|
|
61 /* return x */
|
|
62 gcc_jit_block_end_with_return (
|
|
63 on_true,
|
|
64 NULL,
|
|
65 gcc_jit_param_as_rvalue (x));
|
|
66
|
|
67 /* false branch: */
|
|
68 gcc_jit_rvalue *x_minus_1 =
|
|
69 gcc_jit_context_new_binary_op (
|
|
70 ctxt, NULL,
|
|
71 GCC_JIT_BINARY_OP_MINUS, the_type,
|
|
72 gcc_jit_param_as_rvalue (x),
|
|
73 gcc_jit_context_new_rvalue_from_int (
|
|
74 ctxt,
|
|
75 the_type,
|
|
76 1));
|
|
77 gcc_jit_block_end_with_return (
|
|
78 on_false,
|
|
79 NULL,
|
|
80 gcc_jit_context_new_binary_op (
|
|
81 ctxt, NULL,
|
|
82 GCC_JIT_BINARY_OP_MULT, the_type,
|
|
83 gcc_jit_param_as_rvalue (x),
|
|
84 /* my_factorial (x - 1) */
|
|
85 gcc_jit_context_new_call (
|
|
86 ctxt, NULL,
|
|
87 func,
|
|
88 1, &x_minus_1)));
|
|
89 }
|
|
90
|
|
91 void
|
|
92 verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
|
|
93 {
|
|
94 typedef int (*my_factorial_fn_type) (int);
|
|
95 CHECK_NON_NULL (result);
|
|
96 my_factorial_fn_type my_factorial =
|
|
97 (my_factorial_fn_type)gcc_jit_result_get_code (result, "my_factorial");
|
|
98 CHECK_NON_NULL (my_factorial);
|
|
99 int val = my_factorial (10);
|
|
100 note ("my_factorial returned: %d", val);
|
|
101 CHECK_VALUE (val, 3628800);
|
|
102 }
|
|
103
|