]>
Commit | Line | Data |
---|---|---|
8d9254fc | 1 | .. Copyright (C) 2014-2020 Free Software Foundation, Inc. |
35485da9 DM |
2 | Originally contributed by David Malcolm <dmalcolm@redhat.com> |
3 | ||
4 | This is free software: you can redistribute it and/or modify it | |
5 | under the terms of the GNU General Public License as published by | |
6 | the Free Software Foundation, either version 3 of the License, or | |
7 | (at your option) any later version. | |
8 | ||
9 | This program is distributed in the hope that it will be useful, but | |
10 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU General Public License | |
15 | along with this program. If not, see | |
16 | <http://www.gnu.org/licenses/>. | |
17 | ||
18 | .. default-domain:: c | |
19 | ||
20 | Creating and using functions | |
21 | ============================ | |
22 | ||
23 | Params | |
24 | ------ | |
25 | .. type:: gcc_jit_param | |
26 | ||
27 | A `gcc_jit_param` represents a parameter to a function. | |
28 | ||
29 | .. function:: gcc_jit_param *\ | |
30 | gcc_jit_context_new_param (gcc_jit_context *ctxt,\ | |
31 | gcc_jit_location *loc,\ | |
32 | gcc_jit_type *type,\ | |
33 | const char *name) | |
34 | ||
35 | In preparation for creating a function, create a new parameter of the | |
36 | given type and name. | |
37 | ||
c575221a DM |
38 | The parameter ``name`` must be non-NULL. The call takes a copy of the |
39 | underlying string, so it is valid to pass in a pointer to an on-stack | |
40 | buffer. | |
41 | ||
35485da9 DM |
42 | Parameters are lvalues, and thus are also rvalues (and objects), so the |
43 | following upcasts are available: | |
44 | ||
45 | .. function:: gcc_jit_lvalue *\ | |
46 | gcc_jit_param_as_lvalue (gcc_jit_param *param) | |
47 | ||
48 | Upcasting from param to lvalue. | |
49 | ||
50 | .. function:: gcc_jit_rvalue *\ | |
51 | gcc_jit_param_as_rvalue (gcc_jit_param *param) | |
52 | ||
53 | Upcasting from param to rvalue. | |
54 | ||
55 | .. function:: gcc_jit_object *\ | |
56 | gcc_jit_param_as_object (gcc_jit_param *param) | |
57 | ||
58 | Upcasting from param to object. | |
59 | ||
60 | ||
61 | Functions | |
62 | --------- | |
63 | ||
64 | .. type:: gcc_jit_function | |
65 | ||
66 | A `gcc_jit_function` represents a function - either one that we're | |
67 | creating ourselves, or one that we're referencing. | |
68 | ||
69 | .. function:: gcc_jit_function *\ | |
70 | gcc_jit_context_new_function (gcc_jit_context *ctxt,\ | |
71 | gcc_jit_location *loc,\ | |
72 | enum gcc_jit_function_kind kind,\ | |
73 | gcc_jit_type *return_type,\ | |
74 | const char *name,\ | |
75 | int num_params,\ | |
76 | gcc_jit_param **params,\ | |
77 | int is_variadic) | |
78 | ||
79 | Create a gcc_jit_function with the given name and parameters. | |
80 | ||
81 | .. type:: enum gcc_jit_function_kind | |
82 | ||
83 | This enum controls the kind of function created, and has the following | |
84 | values: | |
85 | ||
86 | .. macro:: GCC_JIT_FUNCTION_EXPORTED | |
87 | ||
88 | Function is defined by the client code and visible | |
89 | by name outside of the JIT. | |
90 | ||
81ba15f1 DM |
91 | This value is required if you want to extract machine code |
92 | for this function from a :type:`gcc_jit_result` via | |
93 | :func:`gcc_jit_result_get_code`. | |
94 | ||
35485da9 DM |
95 | .. macro:: GCC_JIT_FUNCTION_INTERNAL |
96 | ||
97 | Function is defined by the client code, but is invisible | |
98 | outside of the JIT. Analogous to a "static" function. | |
99 | ||
100 | .. macro:: GCC_JIT_FUNCTION_IMPORTED | |
101 | ||
102 | Function is not defined by the client code; we're merely | |
103 | referring to it. Analogous to using an "extern" function from a | |
104 | header file. | |
105 | ||
106 | .. macro:: GCC_JIT_FUNCTION_ALWAYS_INLINE | |
107 | ||
108 | Function is only ever inlined into other functions, and is | |
109 | invisible outside of the JIT. | |
110 | ||
111 | Analogous to prefixing with ``inline`` and adding | |
112 | ``__attribute__((always_inline))`` | |
113 | ||
114 | Inlining will only occur when the optimization level is | |
115 | above 0; when optimization is off, this is essentially the | |
116 | same as GCC_JIT_FUNCTION_INTERNAL. | |
117 | ||
c575221a DM |
118 | The parameter ``name`` must be non-NULL. The call takes a copy of the |
119 | underlying string, so it is valid to pass in a pointer to an on-stack | |
120 | buffer. | |
121 | ||
35485da9 DM |
122 | .. function:: gcc_jit_function *\ |
123 | gcc_jit_context_get_builtin_function (gcc_jit_context *ctxt,\ | |
124 | const char *name) | |
125 | ||
126 | .. function:: gcc_jit_object *\ | |
127 | gcc_jit_function_as_object (gcc_jit_function *func) | |
128 | ||
129 | Upcasting from function to object. | |
130 | ||
131 | .. function:: gcc_jit_param *\ | |
132 | gcc_jit_function_get_param (gcc_jit_function *func, int index) | |
133 | ||
134 | Get the param of the given index (0-based). | |
135 | ||
136 | .. function:: void \ | |
137 | gcc_jit_function_dump_to_dot (gcc_jit_function *func,\ | |
138 | const char *path) | |
139 | ||
140 | Emit the function in graphviz format to the given path. | |
141 | ||
142 | .. function:: gcc_jit_lvalue *\ | |
143 | gcc_jit_function_new_local (gcc_jit_function *func,\ | |
144 | gcc_jit_location *loc,\ | |
145 | gcc_jit_type *type,\ | |
146 | const char *name) | |
147 | ||
148 | Create a new local variable within the function, of the given type and | |
149 | name. | |
150 | ||
c575221a DM |
151 | The parameter ``name`` must be non-NULL. The call takes a copy of the |
152 | underlying string, so it is valid to pass in a pointer to an on-stack | |
153 | buffer. | |
35485da9 DM |
154 | |
155 | Blocks | |
156 | ------ | |
157 | .. type:: gcc_jit_block | |
158 | ||
159 | A `gcc_jit_block` represents a basic block within a function i.e. a | |
160 | sequence of statements with a single entry point and a single exit | |
161 | point. | |
162 | ||
163 | The first basic block that you create within a function will | |
164 | be the entrypoint. | |
165 | ||
166 | Each basic block that you create within a function must be | |
ec5d0088 DM |
167 | terminated, either with a conditional, a jump, a return, or a |
168 | switch. | |
35485da9 DM |
169 | |
170 | It's legal to have multiple basic blocks that return within | |
171 | one function. | |
172 | ||
173 | .. function:: gcc_jit_block *\ | |
174 | gcc_jit_function_new_block (gcc_jit_function *func,\ | |
175 | const char *name) | |
176 | ||
177 | Create a basic block of the given name. The name may be NULL, but | |
178 | providing meaningful names is often helpful when debugging: it may | |
179 | show up in dumps of the internal representation, and in error | |
c575221a DM |
180 | messages. It is copied, so the input buffer does not need to outlive |
181 | the call; you can pass in a pointer to an on-stack buffer, e.g.: | |
182 | ||
183 | .. code-block:: c | |
184 | ||
185 | for (pc = 0; pc < fn->fn_num_ops; pc++) | |
186 | { | |
187 | char buf[16]; | |
188 | sprintf (buf, "instr%i", pc); | |
189 | state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf); | |
190 | } | |
35485da9 DM |
191 | |
192 | .. function:: gcc_jit_object *\ | |
193 | gcc_jit_block_as_object (gcc_jit_block *block) | |
194 | ||
195 | Upcast from block to object. | |
196 | ||
197 | .. function:: gcc_jit_function *\ | |
198 | gcc_jit_block_get_function (gcc_jit_block *block) | |
199 | ||
200 | Which function is this block within? | |
201 | ||
202 | ||
203 | Statements | |
204 | ---------- | |
205 | ||
206 | .. function:: void\ | |
207 | gcc_jit_block_add_eval (gcc_jit_block *block,\ | |
208 | gcc_jit_location *loc,\ | |
209 | gcc_jit_rvalue *rvalue) | |
210 | ||
211 | Add evaluation of an rvalue, discarding the result | |
212 | (e.g. a function call that "returns" void). | |
213 | ||
214 | This is equivalent to this C code: | |
215 | ||
216 | .. code-block:: c | |
217 | ||
218 | (void)expression; | |
219 | ||
220 | .. function:: void\ | |
221 | gcc_jit_block_add_assignment (gcc_jit_block *block,\ | |
222 | gcc_jit_location *loc,\ | |
223 | gcc_jit_lvalue *lvalue,\ | |
224 | gcc_jit_rvalue *rvalue) | |
225 | ||
226 | Add evaluation of an rvalue, assigning the result to the given | |
227 | lvalue. | |
228 | ||
229 | This is roughly equivalent to this C code: | |
230 | ||
231 | .. code-block:: c | |
232 | ||
233 | lvalue = rvalue; | |
234 | ||
235 | .. function:: void\ | |
236 | gcc_jit_block_add_assignment_op (gcc_jit_block *block,\ | |
237 | gcc_jit_location *loc,\ | |
238 | gcc_jit_lvalue *lvalue,\ | |
239 | enum gcc_jit_binary_op op,\ | |
240 | gcc_jit_rvalue *rvalue) | |
241 | ||
242 | Add evaluation of an rvalue, using the result to modify an | |
243 | lvalue. | |
244 | ||
245 | This is analogous to "+=" and friends: | |
246 | ||
247 | .. code-block:: c | |
248 | ||
249 | lvalue += rvalue; | |
250 | lvalue *= rvalue; | |
251 | lvalue /= rvalue; | |
252 | ||
253 | etc. For example: | |
254 | ||
255 | .. code-block:: c | |
256 | ||
257 | /* "i++" */ | |
258 | gcc_jit_block_add_assignment_op ( | |
259 | loop_body, NULL, | |
260 | i, | |
261 | GCC_JIT_BINARY_OP_PLUS, | |
262 | gcc_jit_context_one (ctxt, int_type)); | |
263 | ||
264 | .. function:: void\ | |
265 | gcc_jit_block_add_comment (gcc_jit_block *block,\ | |
266 | gcc_jit_location *loc,\ | |
267 | const char *text) | |
268 | ||
269 | Add a no-op textual comment to the internal representation of the | |
270 | code. It will be optimized away, but will be visible in the dumps | |
271 | seen via :macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` | |
272 | and :macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE`, | |
273 | and thus may be of use when debugging how your project's internal | |
274 | representation gets converted to the libgccjit IR. | |
275 | ||
c575221a DM |
276 | The parameter ``text`` must be non-NULL. It is copied, so the input |
277 | buffer does not need to outlive the call. For example: | |
278 | ||
279 | .. code-block:: c | |
280 | ||
281 | char buf[100]; | |
282 | snprintf (buf, sizeof (buf), | |
283 | "op%i: %s", | |
284 | pc, opcode_names[op->op_opcode]); | |
285 | gcc_jit_block_add_comment (block, loc, buf); | |
286 | ||
35485da9 DM |
287 | .. function:: void\ |
288 | gcc_jit_block_end_with_conditional (gcc_jit_block *block,\ | |
289 | gcc_jit_location *loc,\ | |
290 | gcc_jit_rvalue *boolval,\ | |
291 | gcc_jit_block *on_true,\ | |
292 | gcc_jit_block *on_false) | |
293 | ||
294 | Terminate a block by adding evaluation of an rvalue, branching on the | |
295 | result to the appropriate successor block. | |
296 | ||
297 | This is roughly equivalent to this C code: | |
298 | ||
299 | .. code-block:: c | |
300 | ||
301 | if (boolval) | |
302 | goto on_true; | |
303 | else | |
304 | goto on_false; | |
305 | ||
306 | block, boolval, on_true, and on_false must be non-NULL. | |
307 | ||
308 | .. function:: void\ | |
309 | gcc_jit_block_end_with_jump (gcc_jit_block *block,\ | |
310 | gcc_jit_location *loc,\ | |
311 | gcc_jit_block *target) | |
312 | ||
313 | ||
314 | Terminate a block by adding a jump to the given target block. | |
315 | ||
316 | This is roughly equivalent to this C code: | |
317 | ||
318 | .. code-block:: c | |
319 | ||
320 | goto target; | |
321 | ||
322 | .. function:: void\ | |
323 | gcc_jit_block_end_with_return (gcc_jit_block *block,\ | |
324 | gcc_jit_location *loc,\ | |
325 | gcc_jit_rvalue *rvalue) | |
326 | ||
327 | ||
328 | Terminate a block by adding evaluation of an rvalue, returning the value. | |
329 | ||
330 | This is roughly equivalent to this C code: | |
331 | ||
332 | .. code-block:: c | |
333 | ||
334 | return expression; | |
335 | ||
336 | .. function:: void\ | |
337 | gcc_jit_block_end_with_void_return (gcc_jit_block *block,\ | |
338 | gcc_jit_location *loc) | |
339 | ||
340 | ||
341 | Terminate a block by adding a valueless return, for use within a function | |
342 | with "void" return type. | |
343 | ||
344 | This is equivalent to this C code: | |
345 | ||
346 | .. code-block:: c | |
347 | ||
348 | return; | |
ec5d0088 DM |
349 | |
350 | .. function:: void\ | |
351 | gcc_jit_block_end_with_switch (gcc_jit_block *block,\ | |
352 | gcc_jit_location *loc,\ | |
353 | gcc_jit_rvalue *expr,\ | |
354 | gcc_jit_block *default_block,\ | |
355 | int num_cases,\ | |
356 | gcc_jit_case **cases) | |
357 | ||
358 | Terminate a block by adding evalation of an rvalue, then performing | |
359 | a multiway branch. | |
360 | ||
361 | This is roughly equivalent to this C code: | |
362 | ||
363 | .. code-block:: c | |
364 | ||
365 | switch (expr) | |
366 | { | |
367 | default: | |
368 | goto default_block; | |
369 | ||
370 | case C0.min_value ... C0.max_value: | |
371 | goto C0.dest_block; | |
372 | ||
373 | case C1.min_value ... C1.max_value: | |
374 | goto C1.dest_block; | |
375 | ||
376 | ...etc... | |
377 | ||
378 | case C[N - 1].min_value ... C[N - 1].max_value: | |
379 | goto C[N - 1].dest_block; | |
380 | } | |
381 | ||
382 | ``block``, ``expr``, ``default_block`` and ``cases`` must all be | |
383 | non-NULL. | |
384 | ||
385 | ``expr`` must be of the same integer type as all of the ``min_value`` | |
386 | and ``max_value`` within the cases. | |
387 | ||
388 | ``num_cases`` must be >= 0. | |
389 | ||
390 | The ranges of the cases must not overlap (or have duplicate | |
391 | values). | |
392 | ||
393 | The API entrypoints relating to switch statements and cases: | |
394 | ||
395 | * :c:func:`gcc_jit_block_end_with_switch` | |
396 | ||
397 | * :c:func:`gcc_jit_case_as_object` | |
398 | ||
399 | * :c:func:`gcc_jit_context_new_case` | |
400 | ||
401 | were added in :ref:`LIBGCCJIT_ABI_3`; you can test for their presence | |
402 | using | |
403 | ||
404 | .. code-block:: c | |
405 | ||
406 | #ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS | |
407 | ||
408 | .. type:: gcc_jit_case | |
409 | ||
410 | A `gcc_jit_case` represents a case within a switch statement, and | |
411 | is created within a particular :c:type:`gcc_jit_context` using | |
412 | :c:func:`gcc_jit_context_new_case`. | |
413 | ||
414 | Each case expresses a multivalued range of integer values. You | |
415 | can express single-valued cases by passing in the same value for | |
416 | both `min_value` and `max_value`. | |
417 | ||
418 | .. function:: gcc_jit_case *\ | |
419 | gcc_jit_context_new_case (gcc_jit_context *ctxt,\ | |
420 | gcc_jit_rvalue *min_value,\ | |
421 | gcc_jit_rvalue *max_value,\ | |
422 | gcc_jit_block *dest_block) | |
423 | ||
424 | Create a new gcc_jit_case instance for use in a switch statement. | |
425 | `min_value` and `max_value` must be constants of an integer type, | |
426 | which must match that of the expression of the switch statement. | |
427 | ||
428 | `dest_block` must be within the same function as the switch | |
429 | statement. | |
430 | ||
431 | .. function:: gcc_jit_object *\ | |
432 | gcc_jit_case_as_object (gcc_jit_case *case_) | |
433 | ||
434 | Upcast from a case to an object. | |
435 | ||
436 | Here's an example of creating a switch statement: | |
437 | ||
438 | .. literalinclude:: ../../../testsuite/jit.dg/test-switch.c | |
439 | :start-after: /* Quote from here in docs/topics/functions.rst. */ | |
440 | :end-before: /* Quote up to here in docs/topics/functions.rst. */ | |
441 | :language: c |