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