1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 #include "libgccjit.h"
6
7 #include "harness.h"
8
9 static char *dump_vrp1;
10
11 void
create_code(gcc_jit_context * ctxt,void * user_data)12 create_code (gcc_jit_context *ctxt, void *user_data)
13 {
14 /*
15 Simple sum-of-squares, to test conditionals and looping
16
17 int loop_test (int n)
18 {
19 int i;
20 int sum = 0;
21 for (i = 0; i < n ; i ++)
22 {
23 sum += i * i;
24 }
25 return sum;
26 */
27 gcc_jit_context_enable_dump (ctxt, "tree-vrp1", &dump_vrp1);
28
29 gcc_jit_type *the_type =
30 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
31 gcc_jit_type *return_type = the_type;
32
33 gcc_jit_param *n =
34 gcc_jit_context_new_param (ctxt, NULL, the_type, "n");
35 gcc_jit_param *params[1] = {n};
36 gcc_jit_function *func =
37 gcc_jit_context_new_function (ctxt, NULL,
38 GCC_JIT_FUNCTION_EXPORTED,
39 return_type,
40 "loop_test",
41 1, params, 0);
42
43 /* Build locals: */
44 gcc_jit_lvalue *i =
45 gcc_jit_function_new_local (func, NULL, the_type, "i");
46 gcc_jit_lvalue *sum =
47 gcc_jit_function_new_local (func, NULL, the_type, "sum");
48
49 gcc_jit_block *initial =
50 gcc_jit_function_new_block (func, "initial");
51 gcc_jit_block *loop_cond =
52 gcc_jit_function_new_block (func, "loop_cond");
53 gcc_jit_block *loop_body =
54 gcc_jit_function_new_block (func, "loop_body");
55 gcc_jit_block *after_loop =
56 gcc_jit_function_new_block (func, "after_loop");
57
58 /* sum = 0; */
59 gcc_jit_block_add_assignment (
60 initial, NULL,
61 sum,
62 gcc_jit_context_new_rvalue_from_int (ctxt, the_type, 0));
63
64 /* i = 0; */
65 gcc_jit_block_add_assignment (
66 initial, NULL,
67 i,
68 gcc_jit_context_new_rvalue_from_int (ctxt, the_type, 0));
69
70 gcc_jit_block_end_with_jump (initial, NULL, loop_cond);
71
72 /* if (i >= n) */
73 gcc_jit_block_end_with_conditional (
74 loop_cond, NULL,
75 gcc_jit_context_new_comparison (
76 ctxt, NULL,
77 GCC_JIT_COMPARISON_GE,
78 gcc_jit_lvalue_as_rvalue (i),
79 gcc_jit_param_as_rvalue (n)),
80 after_loop,
81 loop_body);
82
83 /* sum += i * i */
84 gcc_jit_block_add_assignment (
85 loop_body, NULL,
86 sum,
87 gcc_jit_context_new_binary_op (
88 ctxt, NULL,
89 GCC_JIT_BINARY_OP_PLUS, the_type,
90 gcc_jit_lvalue_as_rvalue (sum),
91 gcc_jit_context_new_binary_op (
92 ctxt, NULL,
93 GCC_JIT_BINARY_OP_MULT, the_type,
94 gcc_jit_lvalue_as_rvalue (i),
95 gcc_jit_lvalue_as_rvalue (i))));
96
97 /* i++ */
98 gcc_jit_block_add_assignment (
99 loop_body, NULL,
100 i,
101 gcc_jit_context_new_binary_op (
102 ctxt, NULL,
103 GCC_JIT_BINARY_OP_PLUS, the_type,
104 gcc_jit_lvalue_as_rvalue (i),
105 gcc_jit_context_new_rvalue_from_int (
106 ctxt,
107 the_type,
108 1)));
109
110 gcc_jit_block_end_with_jump (loop_body, NULL, loop_cond);
111
112 /* return sum */
113 gcc_jit_block_end_with_return (
114 after_loop,
115 NULL,
116 gcc_jit_lvalue_as_rvalue (sum));
117 }
118
119 void
verify_code(gcc_jit_context * ctxt,gcc_jit_result * result)120 verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
121 {
122 typedef int (*loop_test_fn_type) (int);
123 CHECK_NON_NULL (result);
124 loop_test_fn_type loop_test =
125 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test");
126 CHECK_NON_NULL (loop_test);
127 int val = loop_test (10);
128 note ("loop_test returned: %d", val);
129 CHECK_VALUE (val, 285);
130
131 CHECK_NON_NULL (dump_vrp1);
132 /* PR jit/64166
133 An example of using gcc_jit_context_enable_dump to verify a property
134 of the compile.
135
136 In this case, verify that vrp is able to deduce the
137 bounds of the iteration variable. Specifically, verify that some
138 variable is known to be in the range negative infinity to some
139 expression based on param "n" (actually n-1). */
140 CHECK_STRING_CONTAINS (dump_vrp1, "[-INF, n_");
141 free (dump_vrp1);
142 }
143