]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/jit/docs/_build/texinfo/libgccjit.texi
Update copyright years.
[thirdparty/gcc.git] / gcc / jit / docs / _build / texinfo / libgccjit.texi
CommitLineData
35485da9
DM
1\input texinfo @c -*-texinfo-*-
2@c %**start of header
3@setfilename libgccjit.info
4@documentencoding UTF-8
5@ifinfo
421d0d0f 6@*Generated by Sphinx 2.2.2.@*
35485da9
DM
7@end ifinfo
8@settitle libgccjit Documentation
9@defindex ge
6f7585de 10@paragraphindent 0
35485da9 11@exampleindent 4
6f7585de 12@finalout
35485da9
DM
13@dircategory Miscellaneous
14@direntry
ac43b32c 15* libgccjit: (libgccjit.info). GCC-based Just In Time compiler library.
35485da9
DM
16@end direntry
17
6f7585de
DM
18@definfoenclose strong,`,'
19@definfoenclose emph,`,'
35485da9
DM
20@c %**end of header
21
22@copying
23@quotation
b95d97f1 24libgccjit 11.0.0 (experimental 20210114), Jan 14, 2021
35485da9
DM
25
26David Malcolm
27
7adcbafe 28Copyright @copyright{} 2014-2022 Free Software Foundation, Inc.
35485da9
DM
29@end quotation
30
31@end copying
32
33@titlepage
34@title libgccjit Documentation
35@insertcopying
36@end titlepage
37@contents
38
39@c %** start of user preamble
40
41@c %** end of user preamble
42
43@ifnottex
44@node Top
45@top libgccjit Documentation
46@insertcopying
47@end ifnottex
48
49@c %**start of body
50@anchor{index doc}@anchor{0}
7adcbafe 51@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
52@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
53@c
54@c This is free software: you can redistribute it and/or modify it
55@c under the terms of the GNU General Public License as published by
56@c the Free Software Foundation, either version 3 of the License, or
57@c (at your option) any later version.
58@c
59@c This program is distributed in the hope that it will be useful, but
60@c WITHOUT ANY WARRANTY; without even the implied warranty of
61@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
62@c General Public License for more details.
63@c
64@c You should have received a copy of the GNU General Public License
65@c along with this program. If not, see
786973ce 66@c <https://www.gnu.org/licenses/>.
35485da9 67
786973ce 68This document describes libgccjit@footnote{https://gcc.gnu.org/wiki/JIT}, an API
29df5715
DM
69for embedding GCC inside programs and libraries.
70
29df5715
DM
71There are actually two APIs for the library:
72
73
74@itemize *
75
76@item
77a pure C API: @code{libgccjit.h}
78
79@item
6f7585de 80a C++ wrapper API: @code{libgccjit++.h}. This is a collection of “thin”
29df5715
DM
81wrapper classes around the C API, to save typing.
82@end itemize
83
35485da9
DM
84Contents:
85
7adcbafe 86@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
87@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
88@c
89@c This is free software: you can redistribute it and/or modify it
90@c under the terms of the GNU General Public License as published by
91@c the Free Software Foundation, either version 3 of the License, or
92@c (at your option) any later version.
93@c
94@c This program is distributed in the hope that it will be useful, but
95@c WITHOUT ANY WARRANTY; without even the implied warranty of
96@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
97@c General Public License for more details.
98@c
99@c You should have received a copy of the GNU General Public License
100@c along with this program. If not, see
786973ce 101@c <https://www.gnu.org/licenses/>.
35485da9
DM
102
103@menu
104* Tutorial::
105* Topic Reference::
29df5715 106* C++ bindings for libgccjit::
35485da9
DM
107* Internals::
108* Indices and tables::
109* Index::
110
111@detailmenu
112 --- The Detailed Node Listing ---
113
114Tutorial
115
6f7585de 116* Tutorial part 1; “Hello world”: Tutorial part 1 “Hello world”.
35485da9
DM
117* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function.
118* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables.
119* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter.
fdce7209 120* Tutorial part 5; Implementing an Ahead-of-Time compiler: Tutorial part 5 Implementing an Ahead-of-Time compiler.
35485da9
DM
121
122Tutorial part 2: Creating a trivial machine code function
123
e250f0dc 124* Error-handling::
35485da9
DM
125* Options::
126* Full example::
127
128Tutorial part 3: Loops and variables
129
130* Expressions; lvalues and rvalues: Expressions lvalues and rvalues.
131* Control flow::
132* Visualizing the control flow graph::
133* Full example: Full example<2>.
134
135Tutorial part 4: Adding JIT-compilation to a toy interpreter
136
137* Our toy interpreter::
138* Compiling to machine code::
139* Setting things up::
140* Populating the function::
141* Verifying the control flow graph::
142* Compiling the context::
143* Single-stepping through the generated code::
144* Examining the generated code::
145* Putting it all together::
146* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?.
147
148Behind the curtain: How does our code get optimized?
149
150* Optimizing away stack manipulation::
151* Elimination of tail recursion::
152
fdce7209
DM
153Tutorial part 5: Implementing an Ahead-of-Time compiler
154
6f7585de 155* The “brainf” language::
fdce7209
DM
156* Converting a brainf script to libgccjit IR::
157* Compiling a context to a file::
158* Other forms of ahead-of-time-compilation::
159
35485da9
DM
160Topic Reference
161
162* Compilation contexts::
163* Objects::
164* Types::
165* Expressions::
166* Creating and using functions::
ecd5156d 167* Function pointers: Function pointers<2>.
35485da9 168* Source Locations::
fdce7209 169* Compiling a context::
fa22c20d 170* ABI and API compatibility::
afed3459 171* Performance::
421d0d0f 172* Using Assembly Language with libgccjit::
35485da9
DM
173
174Compilation contexts
175
176* Lifetime-management::
177* Thread-safety::
e250f0dc 178* Error-handling: Error-handling<2>.
35485da9
DM
179* Debugging::
180* Options: Options<2>.
181
182Options
183
184* String Options::
185* Boolean options::
186* Integer options::
fa22c20d 187* Additional command-line options::
35485da9
DM
188
189Types
190
191* Standard types::
192* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile.
47ee1b7c 193* Vector types::
35485da9 194* Structures and unions::
ecd5156d 195* Function pointer types::
35485da9
DM
196
197Expressions
198
199* Rvalues::
200* Lvalues::
201* Working with pointers@comma{} structs and unions: Working with pointers structs and unions.
202
203Rvalues
204
205* Simple expressions::
6069fe72 206* Vector expressions::
35485da9
DM
207* Unary Operations::
208* Binary Operations::
209* Comparisons::
210* Function calls::
15a65e63 211* Function pointers::
35485da9
DM
212* Type-coercion::
213
214Lvalues
215
216* Global variables::
217
218Creating and using functions
219
220* Params::
221* Functions::
222* Blocks::
223* Statements::
224
225Source Locations
226
227* Faking it::
228
fdce7209
DM
229Compiling a context
230
231* In-memory compilation::
232* Ahead-of-time compilation::
233
fa22c20d
DM
234ABI and API compatibility
235
6f7585de 236* Programmatically checking version::
fa22c20d
DM
237* ABI symbol tags::
238
239ABI symbol tags
240
241* LIBGCCJIT_ABI_0::
242* LIBGCCJIT_ABI_1::
6a3603e3 243* LIBGCCJIT_ABI_2::
ec5d0088 244* LIBGCCJIT_ABI_3::
afed3459 245* LIBGCCJIT_ABI_4::
199501ea 246* LIBGCCJIT_ABI_5::
0ebd1f00
DM
247* LIBGCCJIT_ABI_6::
248* LIBGCCJIT_ABI_7::
47ee1b7c 249* LIBGCCJIT_ABI_8::
15a65e63 250* LIBGCCJIT_ABI_9::
6069fe72 251* LIBGCCJIT_ABI_10::
6f7585de
DM
252* LIBGCCJIT_ABI_11::
253* LIBGCCJIT_ABI_12::
254* LIBGCCJIT_ABI_13::
02321f62 255* LIBGCCJIT_ABI_14::
421d0d0f 256* LIBGCCJIT_ABI_15::
afed3459
DM
257
258Performance
259
260* The timing API::
fa22c20d 261
421d0d0f
DM
262Using Assembly Language with libgccjit
263
264* Adding assembler instructions within a function::
265* Adding top-level assembler statements::
266
29df5715
DM
267C++ bindings for libgccjit
268
269* Tutorial: Tutorial<2>.
270* Topic Reference: Topic Reference<2>.
271
272Tutorial
273
6f7585de 274* Tutorial part 1; “Hello world”: Tutorial part 1 “Hello world”<2>.
29df5715
DM
275* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>.
276* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>.
277* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>.
278
279Tutorial part 2: Creating a trivial machine code function
280
281* Options: Options<3>.
282* Full example: Full example<3>.
283
284Tutorial part 3: Loops and variables
285
286* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>.
287* Control flow: Control flow<2>.
288* Visualizing the control flow graph: Visualizing the control flow graph<2>.
289* Full example: Full example<4>.
290
291Tutorial part 4: Adding JIT-compilation to a toy interpreter
292
293* Our toy interpreter: Our toy interpreter<2>.
294* Compiling to machine code: Compiling to machine code<2>.
295* Setting things up: Setting things up<2>.
296* Populating the function: Populating the function<2>.
297* Verifying the control flow graph: Verifying the control flow graph<2>.
298* Compiling the context: Compiling the context<2>.
299* Single-stepping through the generated code: Single-stepping through the generated code<2>.
300* Examining the generated code: Examining the generated code<2>.
301* Putting it all together: Putting it all together<2>.
302* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>.
303
304Behind the curtain: How does our code get optimized?
305
306* Optimizing away stack manipulation: Optimizing away stack manipulation<2>.
307* Elimination of tail recursion: Elimination of tail recursion<2>.
308
309Topic Reference
310
311* Compilation contexts: Compilation contexts<2>.
312* Objects: Objects<2>.
313* Types: Types<2>.
314* Expressions: Expressions<2>.
315* Creating and using functions: Creating and using functions<2>.
316* Source Locations: Source Locations<2>.
fdce7209 317* Compiling a context: Compiling a context<2>.
421d0d0f 318* Using Assembly Language with libgccjit++::
29df5715
DM
319
320Compilation contexts
321
322* Lifetime-management: Lifetime-management<2>.
323* Thread-safety: Thread-safety<2>.
324* Error-handling: Error-handling<3>.
325* Debugging: Debugging<2>.
326* Options: Options<4>.
327
328Options
329
35291c7d 330* String Options: String Options<2>.
29df5715
DM
331* Boolean options: Boolean options<2>.
332* Integer options: Integer options<2>.
fa22c20d 333* Additional command-line options: Additional command-line options<2>.
29df5715
DM
334
335Types
336
337* Standard types: Standard types<2>.
338* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>.
47ee1b7c 339* Vector types: Vector types<2>.
29df5715
DM
340* Structures and unions: Structures and unions<2>.
341
342Expressions
343
344* Rvalues: Rvalues<2>.
345* Lvalues: Lvalues<2>.
346* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>.
347
348Rvalues
349
350* Simple expressions: Simple expressions<2>.
6069fe72 351* Vector expressions: Vector expressions<2>.
29df5715
DM
352* Unary Operations: Unary Operations<2>.
353* Binary Operations: Binary Operations<2>.
354* Comparisons: Comparisons<2>.
355* Function calls: Function calls<2>.
ecd5156d 356* Function pointers: Function pointers<3>.
29df5715
DM
357* Type-coercion: Type-coercion<2>.
358
359Lvalues
360
361* Global variables: Global variables<2>.
362
363Creating and using functions
364
365* Params: Params<2>.
366* Functions: Functions<2>.
367* Blocks: Blocks<2>.
368* Statements: Statements<2>.
369
370Source Locations
371
372* Faking it: Faking it<2>.
373
fdce7209
DM
374Compiling a context
375
376* In-memory compilation: In-memory compilation<2>.
377* Ahead-of-time compilation: Ahead-of-time compilation<2>.
378
421d0d0f
DM
379Using Assembly Language with libgccjit++
380
381* Adding assembler instructions within a function: Adding assembler instructions within a function<2>.
382* Adding top-level assembler statements: Adding top-level assembler statements<2>.
383
35485da9
DM
384Internals
385
386* Working on the JIT library::
387* Running the test suite::
388* Environment variables::
18eb0d13 389* Packaging notes::
35485da9 390* Overview of code structure::
86d0ac88 391* Design notes::
1470e75f 392* Submitting patches::
35485da9 393
2712de78
DM
394Running the test suite
395
396* Running under valgrind::
397
35485da9
DM
398@end detailmenu
399@end menu
400
35485da9 401@node Tutorial,Topic Reference,Top,Top
421d0d0f 402@anchor{intro/index doc}@anchor{1}@anchor{intro/index libgccjit}@anchor{2}@anchor{intro/index tutorial}@anchor{3}
35485da9
DM
403@chapter Tutorial
404
405
7adcbafe 406@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
407@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
408@c
409@c This is free software: you can redistribute it and/or modify it
410@c under the terms of the GNU General Public License as published by
411@c the Free Software Foundation, either version 3 of the License, or
412@c (at your option) any later version.
413@c
414@c This program is distributed in the hope that it will be useful, but
415@c WITHOUT ANY WARRANTY; without even the implied warranty of
416@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
417@c General Public License for more details.
418@c
419@c You should have received a copy of the GNU General Public License
420@c along with this program. If not, see
786973ce 421@c <https://www.gnu.org/licenses/>.
35485da9
DM
422
423@menu
6f7585de 424* Tutorial part 1; “Hello world”: Tutorial part 1 “Hello world”.
35485da9
DM
425* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function.
426* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables.
427* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter.
fdce7209 428* Tutorial part 5; Implementing an Ahead-of-Time compiler: Tutorial part 5 Implementing an Ahead-of-Time compiler.
35485da9
DM
429
430@end menu
431
6f7585de 432@node Tutorial part 1 “Hello world”,Tutorial part 2 Creating a trivial machine code function,,Tutorial
35485da9 433@anchor{intro/tutorial01 doc}@anchor{4}@anchor{intro/tutorial01 tutorial-part-1-hello-world}@anchor{5}
6f7585de 434@section Tutorial part 1: “Hello world”
35485da9
DM
435
436
6f7585de 437Before we look at the details of the API, let’s look at building and
35485da9
DM
438running programs that use the library.
439
6f7585de 440Here’s a toy “hello world” program that uses the library to synthesize
35485da9
DM
441a call to @cite{printf} and uses it to write a message to stdout.
442
6f7585de 443Don’t worry about the content of the program for now; we’ll cover
35485da9
DM
444the details in later parts of this tutorial.
445
446@quotation
447
448@example
449/* Smoketest example for libgccjit.so
7adcbafe 450 Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
451
452This file is part of GCC.
453
454GCC is free software; you can redistribute it and/or modify it
455under the terms of the GNU General Public License as published by
456the Free Software Foundation; either version 3, or (at your option)
457any later version.
458
459GCC is distributed in the hope that it will be useful, but
460WITHOUT ANY WARRANTY; without even the implied warranty of
461MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
462General Public License for more details.
463
464You should have received a copy of the GNU General Public License
465along with GCC; see the file COPYING3. If not see
786973ce 466<https://www.gnu.org/licenses/>. */
35485da9
DM
467
468#include <libgccjit.h>
469
470#include <stdlib.h>
471#include <stdio.h>
472
473static void
474create_code (gcc_jit_context *ctxt)
475@{
476 /* Let's try to inject the equivalent of:
477 void
478 greet (const char *name)
479 @{
480 printf ("hello %s\n", name);
481 @}
482 */
483 gcc_jit_type *void_type =
484 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
485 gcc_jit_type *const_char_ptr_type =
486 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR);
487 gcc_jit_param *param_name =
488 gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name");
489 gcc_jit_function *func =
490 gcc_jit_context_new_function (ctxt, NULL,
491 GCC_JIT_FUNCTION_EXPORTED,
492 void_type,
493 "greet",
494 1, &param_name,
495 0);
496
497 gcc_jit_param *param_format =
498 gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format");
499 gcc_jit_function *printf_func =
500 gcc_jit_context_new_function (ctxt, NULL,
501 GCC_JIT_FUNCTION_IMPORTED,
502 gcc_jit_context_get_type (
503 ctxt, GCC_JIT_TYPE_INT),
504 "printf",
505 1, &param_format,
506 1);
507 gcc_jit_rvalue *args[2];
508 args[0] = gcc_jit_context_new_string_literal (ctxt, "hello %s\n");
509 args[1] = gcc_jit_param_as_rvalue (param_name);
510
511 gcc_jit_block *block = gcc_jit_function_new_block (func, NULL);
512
513 gcc_jit_block_add_eval (
514 block, NULL,
515 gcc_jit_context_new_call (ctxt,
516 NULL,
517 printf_func,
518 2, args));
519 gcc_jit_block_end_with_void_return (block, NULL);
520@}
521
522int
523main (int argc, char **argv)
524@{
525 gcc_jit_context *ctxt;
526 gcc_jit_result *result;
527
528 /* Get a "context" object for working with the library. */
529 ctxt = gcc_jit_context_acquire ();
530 if (!ctxt)
531 @{
532 fprintf (stderr, "NULL ctxt");
533 exit (1);
534 @}
535
536 /* Set some options on the context.
537 Let's see the code being generated, in assembler form. */
538 gcc_jit_context_set_bool_option (
539 ctxt,
540 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
541 0);
542
543 /* Populate the context. */
544 create_code (ctxt);
545
546 /* Compile the code. */
547 result = gcc_jit_context_compile (ctxt);
548 if (!result)
549 @{
550 fprintf (stderr, "NULL result");
551 exit (1);
552 @}
553
554 /* Extract the generated code from "result". */
555 typedef void (*fn_type) (const char *);
556 fn_type greet =
557 (fn_type)gcc_jit_result_get_code (result, "greet");
558 if (!greet)
559 @{
560 fprintf (stderr, "NULL greet");
561 exit (1);
562 @}
563
564 /* Now call the generated function: */
565 greet ("world");
566 fflush (stdout);
567
568 gcc_jit_context_release (ctxt);
569 gcc_jit_result_release (result);
570 return 0;
571@}
35485da9 572@end example
35485da9
DM
573@end quotation
574
575Copy the above to @cite{tut01-hello-world.c}.
576
577Assuming you have the jit library installed, build the test program
578using:
579
580@example
581$ gcc \
582 tut01-hello-world.c \
583 -o tut01-hello-world \
584 -lgccjit
585@end example
586
35485da9
DM
587You should then be able to run the built program:
588
589@example
590$ ./tut01-hello-world
591hello world
592@end example
593
7adcbafe 594@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
595@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
596@c
597@c This is free software: you can redistribute it and/or modify it
598@c under the terms of the GNU General Public License as published by
599@c the Free Software Foundation, either version 3 of the License, or
600@c (at your option) any later version.
601@c
602@c This program is distributed in the hope that it will be useful, but
603@c WITHOUT ANY WARRANTY; without even the implied warranty of
604@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
605@c General Public License for more details.
606@c
607@c You should have received a copy of the GNU General Public License
608@c along with this program. If not, see
786973ce 609@c <https://www.gnu.org/licenses/>.
35485da9 610
6f7585de 611@node Tutorial part 2 Creating a trivial machine code function,Tutorial part 3 Loops and variables,Tutorial part 1 “Hello world”,Tutorial
35485da9
DM
612@anchor{intro/tutorial02 doc}@anchor{6}@anchor{intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{7}
613@section Tutorial part 2: Creating a trivial machine code function
614
615
616Consider this C function:
617
618@example
619int square (int i)
620@{
621 return i * i;
622@}
623@end example
624
35485da9
DM
625How can we construct this at run-time using libgccjit?
626
627First we need to include the relevant header:
628
629@example
630#include <libgccjit.h>
631@end example
632
35485da9 633All state associated with compilation is associated with a
6f7585de 634@ref{8,,gcc_jit_context *}.
35485da9 635
6f7585de 636Create one using @ref{9,,gcc_jit_context_acquire()}:
35485da9
DM
637
638@example
639gcc_jit_context *ctxt;
640ctxt = gcc_jit_context_acquire ();
641@end example
642
35485da9
DM
643The JIT library has a system of types. It is statically-typed: every
644expression is of a specific type, fixed at compile-time. In our example,
6f7585de
DM
645all of the expressions are of the C @cite{int} type, so let’s obtain this from
646the context, as a @ref{a,,gcc_jit_type *}, using
647@ref{b,,gcc_jit_context_get_type()}:
35485da9
DM
648
649@example
650gcc_jit_type *int_type =
651 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
652@end example
653
6f7585de
DM
654@ref{a,,gcc_jit_type *} is an example of a “contextual” object: every
655entity in the API is associated with a @ref{8,,gcc_jit_context *}.
35485da9 656
6f7585de 657Memory management is easy: all such “contextual” objects are automatically
35485da9 658cleaned up for you when the context is released, using
6f7585de 659@ref{c,,gcc_jit_context_release()}:
35485da9
DM
660
661@example
662gcc_jit_context_release (ctxt);
663@end example
664
6f7585de 665so you don’t need to manually track and cleanup all objects, just the
35485da9
DM
666contexts.
667
668Although the API is C-based, there is a form of class hierarchy, which
669looks like this:
670
671@example
672+- gcc_jit_object
673 +- gcc_jit_location
674 +- gcc_jit_type
675 +- gcc_jit_struct
676 +- gcc_jit_field
677 +- gcc_jit_function
678 +- gcc_jit_block
679 +- gcc_jit_rvalue
680 +- gcc_jit_lvalue
681 +- gcc_jit_param
682@end example
683
35485da9 684There are casting methods for upcasting from subclasses to parent classes.
6f7585de 685For example, @ref{d,,gcc_jit_type_as_object()}:
35485da9
DM
686
687@example
688gcc_jit_object *obj = gcc_jit_type_as_object (int_type);
689@end example
690
6f7585de 691One thing you can do with a @ref{e,,gcc_jit_object *} is
35485da9 692to ask it for a human-readable description, using
6f7585de 693@ref{f,,gcc_jit_object_get_debug_string()}:
35485da9
DM
694
695@example
696printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj));
697@end example
698
35485da9
DM
699giving this text on stdout:
700
701@example
702obj: int
703@end example
704
35485da9
DM
705This is invaluable when debugging.
706
6f7585de 707Let’s create the function. To do so, we first need to construct
35485da9 708its single parameter, specifying its type and giving it a name,
6f7585de 709using @ref{10,,gcc_jit_context_new_param()}:
35485da9
DM
710
711@example
712gcc_jit_param *param_i =
713 gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
714@end example
715
35485da9 716Now we can create the function, using
6f7585de 717@ref{11,,gcc_jit_context_new_function()}:
35485da9
DM
718
719@example
720gcc_jit_function *func =
721 gcc_jit_context_new_function (ctxt, NULL,
722 GCC_JIT_FUNCTION_EXPORTED,
723 int_type,
724 "square",
725 1, &param_i,
726 0);
727@end example
728
35485da9
DM
729To define the code within the function, we must create basic blocks
730containing statements.
731
732Every basic block contains a list of statements, eventually terminated
733by a statement that either returns, or jumps to another basic block.
734
735Our function has no control-flow, so we just need one basic block:
736
737@example
738gcc_jit_block *block = gcc_jit_function_new_block (func, NULL);
739@end example
740
35485da9
DM
741Our basic block is relatively simple: it immediately terminates by
742returning the value of an expression.
743
6f7585de 744We can build the expression using @ref{12,,gcc_jit_context_new_binary_op()}:
35485da9
DM
745
746@example
747gcc_jit_rvalue *expr =
748 gcc_jit_context_new_binary_op (
749 ctxt, NULL,
750 GCC_JIT_BINARY_OP_MULT, int_type,
751 gcc_jit_param_as_rvalue (param_i),
752 gcc_jit_param_as_rvalue (param_i));
753@end example
754
6f7585de
DM
755A @ref{13,,gcc_jit_rvalue *} is another example of a
756@ref{e,,gcc_jit_object *} subclass. We can upcast it using
757@ref{14,,gcc_jit_rvalue_as_object()} and as before print it with
758@ref{f,,gcc_jit_object_get_debug_string()}.
35485da9
DM
759
760@example
761printf ("expr: %s\n",
762 gcc_jit_object_get_debug_string (
763 gcc_jit_rvalue_as_object (expr)));
764@end example
765
35485da9
DM
766giving this output:
767
768@example
769expr: i * i
770@end example
771
6f7585de 772Creating the expression in itself doesn’t do anything; we have to add
35485da9
DM
773this expression to a statement within the block. In this case, we use it
774to build a return statement, which terminates the basic block:
775
776@example
777gcc_jit_block_end_with_return (block, NULL, expr);
778@end example
779
6f7585de
DM
780OK, we’ve populated the context. We can now compile it using
781@ref{15,,gcc_jit_context_compile()}:
35485da9
DM
782
783@example
784gcc_jit_result *result;
785result = gcc_jit_context_compile (ctxt);
786@end example
787
6f7585de 788and get a @ref{16,,gcc_jit_result *}.
35485da9 789
6f7585de 790At this point we’re done with the context; we can release it:
81ba15f1
DM
791
792@example
793gcc_jit_context_release (ctxt);
794@end example
795
6f7585de 796We can now use @ref{17,,gcc_jit_result_get_code()} to look up a specific
35485da9
DM
797machine code routine within the result, in this case, the function we
798created above.
799
800@example
801void *fn_ptr = gcc_jit_result_get_code (result, "square");
802if (!fn_ptr)
803 @{
804 fprintf (stderr, "NULL fn_ptr");
805 goto error;
806 @}
807@end example
808
35485da9
DM
809We can now cast the pointer to an appropriate function pointer type, and
810then call it:
811
812@example
813typedef int (*fn_type) (int);
814fn_type square = (fn_type)fn_ptr;
815printf ("result: %d", square (5));
816@end example
817
35485da9
DM
818@example
819result: 25
820@end example
821
6f7585de 822Once we’re done with the code, we can release the result:
e250f0dc
DM
823
824@example
825gcc_jit_result_release (result);
826@end example
827
6f7585de 828We can’t call @code{square} anymore once we’ve released @code{result}.
e250f0dc 829
35485da9 830@menu
e250f0dc 831* Error-handling::
35485da9
DM
832* Options::
833* Full example::
834
835@end menu
836
e250f0dc
DM
837@node Error-handling,Options,,Tutorial part 2 Creating a trivial machine code function
838@anchor{intro/tutorial02 error-handling}@anchor{18}
839@subsection Error-handling
840
841
842Various kinds of errors are possible when using the API, such as
843mismatched types in an assignment. You can only compile and get code
844from a context if no errors occur.
845
846Errors are printed on stderr; they typically contain the name of the API
847entrypoint where the error occurred, and pertinent information on the
848problem:
849
850@example
851./buggy-program: error: gcc_jit_block_add_assignment: mismatching types: assignment to i (type: int) from "hello world" (type: const char *)
852@end example
853
e250f0dc
DM
854The API is designed to cope with errors without crashing, so you can get
855away with having a single error-handling check in your code:
856
857@example
858void *fn_ptr = gcc_jit_result_get_code (result, "square");
859if (!fn_ptr)
860 @{
861 fprintf (stderr, "NULL fn_ptr");
862 goto error;
863 @}
864@end example
865
6f7585de 866For more information, see the @ref{19,,error-handling guide}
e250f0dc
DM
867within the Topic eference.
868
869@node Options,Full example,Error-handling,Tutorial part 2 Creating a trivial machine code function
870@anchor{intro/tutorial02 options}@anchor{1a}
35485da9
DM
871@subsection Options
872
873
6f7585de
DM
874To get more information on what’s going on, you can set debugging flags
875on the context using @ref{1b,,gcc_jit_context_set_bool_option()}.
35485da9
DM
876
877@c (I'm deliberately not mentioning
878@c :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think
879@c it's probably more of use to implementors than to users)
880
6f7585de
DM
881Setting @ref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE} will dump a
882C-like representation to stderr when you compile (GCC’s “GIMPLE”
35485da9
DM
883representation):
884
885@example
886gcc_jit_context_set_bool_option (
887 ctxt,
888 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE,
889 1);
890result = gcc_jit_context_compile (ctxt);
891@end example
892
35485da9
DM
893@example
894square (signed int i)
895@{
896 signed int D.260;
897
898 entry:
899 D.260 = i * i;
900 return D.260;
901@}
902@end example
903
35485da9 904We can see the generated machine code in assembler form (on stderr) by
6f7585de 905setting @ref{1d,,GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE} on the context
35485da9
DM
906before compiling:
907
908@example
909gcc_jit_context_set_bool_option (
910 ctxt,
911 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
912 1);
913result = gcc_jit_context_compile (ctxt);
914@end example
915
35485da9
DM
916@example
917 .file "fake.c"
918 .text
919 .globl square
920 .type square, @@function
921square:
922.LFB6:
923 .cfi_startproc
924 pushq %rbp
925 .cfi_def_cfa_offset 16
926 .cfi_offset 6, -16
927 movq %rsp, %rbp
928 .cfi_def_cfa_register 6
929 movl %edi, -4(%rbp)
930.L14:
931 movl -4(%rbp), %eax
932 imull -4(%rbp), %eax
933 popq %rbp
934 .cfi_def_cfa 7, 8
935 ret
936 .cfi_endproc
937.LFE6:
938 .size square, .-square
939 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)"
940 .section .note.GNU-stack,"",@@progbits
941@end example
942
6f7585de 943By default, no optimizations are performed, the equivalent of GCC’s
35485da9 944@cite{-O0} option. We can turn things up to e.g. @cite{-O3} by calling
6f7585de
DM
945@ref{1e,,gcc_jit_context_set_int_option()} with
946@ref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}:
35485da9
DM
947
948@example
949gcc_jit_context_set_int_option (
950 ctxt,
951 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
952 3);
953@end example
954
35485da9
DM
955@example
956 .file "fake.c"
957 .text
958 .p2align 4,,15
959 .globl square
960 .type square, @@function
961square:
962.LFB7:
963 .cfi_startproc
964.L16:
965 movl %edi, %eax
966 imull %edi, %eax
967 ret
968 .cfi_endproc
969.LFE7:
970 .size square, .-square
971 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)"
972 .section .note.GNU-stack,"",@@progbits
973@end example
974
35485da9
DM
975Naturally this has only a small effect on such a trivial function.
976
977@node Full example,,Options,Tutorial part 2 Creating a trivial machine code function
e250f0dc 978@anchor{intro/tutorial02 full-example}@anchor{20}
35485da9
DM
979@subsection Full example
980
981
6f7585de 982Here’s what the above looks like as a complete program:
35485da9
DM
983
984@quotation
985
986@example
987/* Usage example for libgccjit.so
7adcbafe 988 Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
989
990This file is part of GCC.
991
992GCC is free software; you can redistribute it and/or modify it
993under the terms of the GNU General Public License as published by
994the Free Software Foundation; either version 3, or (at your option)
995any later version.
996
997GCC is distributed in the hope that it will be useful, but
998WITHOUT ANY WARRANTY; without even the implied warranty of
999MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1000General Public License for more details.
1001
1002You should have received a copy of the GNU General Public License
1003along with GCC; see the file COPYING3. If not see
786973ce 1004<https://www.gnu.org/licenses/>. */
35485da9
DM
1005
1006#include <libgccjit.h>
1007
1008#include <stdlib.h>
1009#include <stdio.h>
1010
1011void
1012create_code (gcc_jit_context *ctxt)
1013@{
1014 /* Let's try to inject the equivalent of:
1015
1016 int square (int i)
1017 @{
1018 return i * i;
1019 @}
1020 */
1021 gcc_jit_type *int_type =
1022 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
1023 gcc_jit_param *param_i =
1024 gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
1025 gcc_jit_function *func =
1026 gcc_jit_context_new_function (ctxt, NULL,
1027 GCC_JIT_FUNCTION_EXPORTED,
1028 int_type,
1029 "square",
1030 1, &param_i,
1031 0);
1032
1033 gcc_jit_block *block = gcc_jit_function_new_block (func, NULL);
1034
1035 gcc_jit_rvalue *expr =
1036 gcc_jit_context_new_binary_op (
1037 ctxt, NULL,
1038 GCC_JIT_BINARY_OP_MULT, int_type,
1039 gcc_jit_param_as_rvalue (param_i),
1040 gcc_jit_param_as_rvalue (param_i));
1041
1042 gcc_jit_block_end_with_return (block, NULL, expr);
1043@}
1044
1045int
1046main (int argc, char **argv)
1047@{
1048 gcc_jit_context *ctxt = NULL;
1049 gcc_jit_result *result = NULL;
1050
1051 /* Get a "context" object for working with the library. */
1052 ctxt = gcc_jit_context_acquire ();
1053 if (!ctxt)
1054 @{
1055 fprintf (stderr, "NULL ctxt");
1056 goto error;
1057 @}
1058
1059 /* Set some options on the context.
1060 Let's see the code being generated, in assembler form. */
1061 gcc_jit_context_set_bool_option (
1062 ctxt,
1063 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
1064 0);
1065
1066 /* Populate the context. */
1067 create_code (ctxt);
1068
1069 /* Compile the code. */
1070 result = gcc_jit_context_compile (ctxt);
1071 if (!result)
1072 @{
1073 fprintf (stderr, "NULL result");
1074 goto error;
1075 @}
1076
81ba15f1
DM
1077 /* We're done with the context; we can release it: */
1078 gcc_jit_context_release (ctxt);
1079 ctxt = NULL;
1080
35485da9
DM
1081 /* Extract the generated code from "result". */
1082 void *fn_ptr = gcc_jit_result_get_code (result, "square");
1083 if (!fn_ptr)
1084 @{
1085 fprintf (stderr, "NULL fn_ptr");
1086 goto error;
1087 @}
1088
1089 typedef int (*fn_type) (int);
1090 fn_type square = (fn_type)fn_ptr;
29df5715 1091 printf ("result: %d\n", square (5));
35485da9
DM
1092
1093 error:
81ba15f1
DM
1094 if (ctxt)
1095 gcc_jit_context_release (ctxt);
1096 if (result)
1097 gcc_jit_result_release (result);
35485da9
DM
1098 return 0;
1099@}
35485da9 1100@end example
35485da9
DM
1101@end quotation
1102
1103Building and running it:
1104
1105@example
1106$ gcc \
1107 tut02-square.c \
1108 -o tut02-square \
1109 -lgccjit
1110
1111# Run the built program:
1112$ ./tut02-square
1113result: 25
1114@end example
1115
7adcbafe 1116@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
1117@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
1118@c
1119@c This is free software: you can redistribute it and/or modify it
1120@c under the terms of the GNU General Public License as published by
1121@c the Free Software Foundation, either version 3 of the License, or
1122@c (at your option) any later version.
1123@c
1124@c This program is distributed in the hope that it will be useful, but
1125@c WITHOUT ANY WARRANTY; without even the implied warranty of
1126@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1127@c General Public License for more details.
1128@c
1129@c You should have received a copy of the GNU General Public License
1130@c along with this program. If not, see
786973ce 1131@c <https://www.gnu.org/licenses/>.
35485da9
DM
1132
1133@node Tutorial part 3 Loops and variables,Tutorial part 4 Adding JIT-compilation to a toy interpreter,Tutorial part 2 Creating a trivial machine code function,Tutorial
421d0d0f 1134@anchor{intro/tutorial03 doc}@anchor{21}@anchor{intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{22}
35485da9
DM
1135@section Tutorial part 3: Loops and variables
1136
1137
1138Consider this C function:
1139
1140@quotation
1141
1142@example
1143int loop_test (int n)
1144@{
1145 int sum = 0;
1146 for (int i = 0; i < n; i++)
1147 sum += i * i;
1148 return sum;
1149@}
1150@end example
35485da9
DM
1151@end quotation
1152
1153This example demonstrates some more features of libgccjit, with local
1154variables and a loop.
1155
6f7585de 1156To break this down into libgccjit terms, it’s usually easier to reword
35485da9
DM
1157the @cite{for} loop as a @cite{while} loop, giving:
1158
1159@quotation
1160
1161@example
1162int loop_test (int n)
1163@{
1164 int sum = 0;
1165 int i = 0;
1166 while (i < n)
1167 @{
1168 sum += i * i;
1169 i++;
1170 @}
1171 return sum;
1172@}
1173@end example
35485da9
DM
1174@end quotation
1175
6f7585de 1176Here’s what the final control flow graph will look like:
35485da9
DM
1177
1178@quotation
1179
1180
1181@float Figure
1182
421d0d0f 1183@image{libgccjit-figures/sum-of-squares1,,,image of a control flow graph,png}
35485da9
DM
1184
1185@end float
1186
1187@end quotation
1188
1189As before, we include the libgccjit header and make a
6f7585de 1190@ref{8,,gcc_jit_context *}.
35485da9
DM
1191
1192@example
1193#include <libgccjit.h>
1194
1195void test (void)
1196@{
1197 gcc_jit_context *ctxt;
1198 ctxt = gcc_jit_context_acquire ();
1199@end example
1200
35485da9
DM
1201The function works with the C @cite{int} type:
1202
1203@example
1204gcc_jit_type *the_type =
1205 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
1206gcc_jit_type *return_type = the_type;
1207@end example
1208
35485da9
DM
1209though we could equally well make it work on, say, @cite{double}:
1210
1211@example
1212gcc_jit_type *the_type =
1213 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE);
1214@end example
1215
6f7585de 1216Let’s build the function:
35485da9
DM
1217
1218@example
1219gcc_jit_param *n =
1220 gcc_jit_context_new_param (ctxt, NULL, the_type, "n");
1221gcc_jit_param *params[1] = @{n@};
1222gcc_jit_function *func =
1223 gcc_jit_context_new_function (ctxt, NULL,
1224 GCC_JIT_FUNCTION_EXPORTED,
1225 return_type,
1226 "loop_test",
1227 1, params, 0);
1228@end example
1229
35485da9
DM
1230@menu
1231* Expressions; lvalues and rvalues: Expressions lvalues and rvalues.
1232* Control flow::
1233* Visualizing the control flow graph::
1234* Full example: Full example<2>.
1235
1236@end menu
1237
1238@node Expressions lvalues and rvalues,Control flow,,Tutorial part 3 Loops and variables
e250f0dc 1239@anchor{intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{23}
35485da9
DM
1240@subsection Expressions: lvalues and rvalues
1241
1242
6f7585de 1243The base class of expression is the @ref{13,,gcc_jit_rvalue *},
35485da9
DM
1244representing an expression that can be on the @emph{right}-hand side of
1245an assignment: a value that can be computed somehow, and assigned
1246@emph{to} a storage area (such as a variable). It has a specific
6f7585de 1247@ref{a,,gcc_jit_type *}.
35485da9 1248
6f7585de
DM
1249Anothe important class is @ref{24,,gcc_jit_lvalue *}.
1250A @ref{24,,gcc_jit_lvalue *}. is something that can of the @emph{left}-hand
35485da9
DM
1251side of an assignment: a storage area (such as a variable).
1252
1253In other words, every assignment can be thought of as:
1254
1255@example
1256LVALUE = RVALUE;
1257@end example
1258
6f7585de
DM
1259Note that @ref{24,,gcc_jit_lvalue *} is a subclass of
1260@ref{13,,gcc_jit_rvalue *}, where in an assignment of the form:
35485da9
DM
1261
1262@example
1263LVALUE_A = LVALUE_B;
1264@end example
1265
35485da9
DM
1266the @cite{LVALUE_B} implies reading the current value of that storage
1267area, assigning it into the @cite{LVALUE_A}.
1268
6f7585de 1269So far the only expressions we’ve seen are @cite{i * i}:
35485da9
DM
1270
1271@example
1272gcc_jit_rvalue *expr =
1273 gcc_jit_context_new_binary_op (
1274 ctxt, NULL,
1275 GCC_JIT_BINARY_OP_MULT, int_type,
1276 gcc_jit_param_as_rvalue (param_i),
1277 gcc_jit_param_as_rvalue (param_i));
1278@end example
1279
6f7585de 1280which is a @ref{13,,gcc_jit_rvalue *}, and the various function
35485da9 1281parameters: @cite{param_i} and @cite{param_n}, instances of
6f7585de
DM
1282@ref{25,,gcc_jit_param *}, which is a subclass of
1283@ref{24,,gcc_jit_lvalue *} (and, in turn, of @ref{13,,gcc_jit_rvalue *}):
35485da9
DM
1284we can both read from and write to function parameters within the
1285body of a function.
1286
1287Our new example has a couple of local variables. We create them by
6f7585de 1288calling @ref{26,,gcc_jit_function_new_local()}, supplying a type and a
35485da9
DM
1289name:
1290
1291@example
1292/* Build locals: */
1293gcc_jit_lvalue *i =
1294 gcc_jit_function_new_local (func, NULL, the_type, "i");
1295gcc_jit_lvalue *sum =
1296 gcc_jit_function_new_local (func, NULL, the_type, "sum");
1297@end example
1298
6f7585de 1299These are instances of @ref{24,,gcc_jit_lvalue *} - they can be read from
35485da9
DM
1300and written to.
1301
1302Note that there is no precanned way to create @emph{and} initialize a variable
1303like in C:
1304
1305@example
1306int i = 0;
1307@end example
1308
35485da9
DM
1309Instead, having added the local to the function, we have to separately add
1310an assignment of @cite{0} to @cite{local_i} at the beginning of the function.
1311
1312@node Control flow,Visualizing the control flow graph,Expressions lvalues and rvalues,Tutorial part 3 Loops and variables
e250f0dc 1313@anchor{intro/tutorial03 control-flow}@anchor{27}
35485da9
DM
1314@subsection Control flow
1315
1316
1317This function has a loop, so we need to build some basic blocks to
1318handle the control flow. In this case, we need 4 blocks:
1319
1320
1321@enumerate
1322
1323@item
1324before the loop (initializing the locals)
1325
1326@item
1327the conditional at the top of the loop (comparing @cite{i < n})
1328
1329@item
1330the body of the loop
1331
1332@item
1333after the loop terminates (@cite{return sum})
1334@end enumerate
1335
6f7585de
DM
1336so we create these as @ref{28,,gcc_jit_block *} instances within the
1337@ref{29,,gcc_jit_function *}:
35485da9
DM
1338
1339@example
1340gcc_jit_block *b_initial =
1341 gcc_jit_function_new_block (func, "initial");
1342gcc_jit_block *b_loop_cond =
1343 gcc_jit_function_new_block (func, "loop_cond");
1344gcc_jit_block *b_loop_body =
1345 gcc_jit_function_new_block (func, "loop_body");
1346gcc_jit_block *b_after_loop =
1347 gcc_jit_function_new_block (func, "after_loop");
1348@end example
1349
35485da9
DM
1350We now populate each block with statements.
1351
1352The entry block @cite{b_initial} consists of initializations followed by a jump
1353to the conditional. We assign @cite{0} to @cite{i} and to @cite{sum}, using
6f7585de
DM
1354@ref{2a,,gcc_jit_block_add_assignment()} to add
1355an assignment statement, and using @ref{2b,,gcc_jit_context_zero()} to get
35485da9
DM
1356the constant value @cite{0} for the relevant type for the right-hand side of
1357the assignment:
1358
1359@example
1360/* sum = 0; */
1361gcc_jit_block_add_assignment (
1362 b_initial, NULL,
1363 sum,
1364 gcc_jit_context_zero (ctxt, the_type));
1365
1366/* i = 0; */
1367gcc_jit_block_add_assignment (
1368 b_initial, NULL,
1369 i,
1370 gcc_jit_context_zero (ctxt, the_type));
1371@end example
1372
35485da9
DM
1373We can then terminate the entry block by jumping to the conditional:
1374
1375@example
1376gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond);
1377@end example
1378
35485da9
DM
1379The conditional block is equivalent to the line @cite{while (i < n)} from our
1380C example. It contains a single statement: a conditional, which jumps to
1381one of two destination blocks depending on a boolean
6f7585de
DM
1382@ref{13,,gcc_jit_rvalue *}, in this case the comparison of @cite{i} and @cite{n}.
1383We build the comparison using @ref{2c,,gcc_jit_context_new_comparison()}:
35485da9
DM
1384
1385@example
7ef96183
DM
1386/* (i >= n) */
1387 gcc_jit_rvalue *guard =
1388 gcc_jit_context_new_comparison (
1389 ctxt, NULL,
1390 GCC_JIT_COMPARISON_GE,
1391 gcc_jit_lvalue_as_rvalue (i),
1392 gcc_jit_param_as_rvalue (n));
35485da9
DM
1393@end example
1394
6f7585de
DM
1395and can then use this to add @cite{b_loop_cond}’s sole statement, via
1396@ref{2d,,gcc_jit_block_end_with_conditional()}:
35485da9
DM
1397
1398@example
7ef96183
DM
1399/* Equivalent to:
1400 if (guard)
1401 goto after_loop;
1402 else
1403 goto loop_body; */
1404gcc_jit_block_end_with_conditional (
1405 b_loop_cond, NULL,
1406 guard,
1407 b_after_loop, /* on_true */
1408 b_loop_body); /* on_false */
35485da9
DM
1409@end example
1410
35485da9
DM
1411Next, we populate the body of the loop.
1412
1413The C statement @cite{sum += i * i;} is an assignment operation, where an
6f7585de
DM
1414lvalue is modified “in-place”. We use
1415@ref{2e,,gcc_jit_block_add_assignment_op()} to handle these operations:
35485da9
DM
1416
1417@example
1418/* sum += i * i */
1419gcc_jit_block_add_assignment_op (
1420 b_loop_body, NULL,
1421 sum,
1422 GCC_JIT_BINARY_OP_PLUS,
1423 gcc_jit_context_new_binary_op (
1424 ctxt, NULL,
1425 GCC_JIT_BINARY_OP_MULT, the_type,
1426 gcc_jit_lvalue_as_rvalue (i),
1427 gcc_jit_lvalue_as_rvalue (i)));
1428@end example
1429
35485da9 1430The @cite{i++} can be thought of as @cite{i += 1}, and can thus be handled in
6f7585de 1431a similar way. We use @ref{2f,,gcc_jit_context_one()} to get the constant
35485da9
DM
1432value @cite{1} (for the relevant type) for the right-hand side
1433of the assignment.
1434
1435@example
1436/* i++ */
1437gcc_jit_block_add_assignment_op (
1438 b_loop_body, NULL,
1439 i,
1440 GCC_JIT_BINARY_OP_PLUS,
1441 gcc_jit_context_one (ctxt, the_type));
1442@end example
1443
35485da9
DM
1444@cartouche
1445@quotation Note
1446For numeric constants other than 0 or 1, we could use
6f7585de
DM
1447@ref{30,,gcc_jit_context_new_rvalue_from_int()} and
1448@ref{31,,gcc_jit_context_new_rvalue_from_double()}.
35485da9
DM
1449@end quotation
1450@end cartouche
1451
1452The loop body completes by jumping back to the conditional:
1453
1454@example
1455gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond);
1456@end example
1457
35485da9
DM
1458Finally, we populate the @cite{b_after_loop} block, reached when the loop
1459conditional is false. We want to generate the equivalent of:
1460
1461@example
1462return sum;
1463@end example
1464
35485da9
DM
1465so the block is just one statement:
1466
1467@example
1468/* return sum */
1469gcc_jit_block_end_with_return (
1470 b_after_loop,
1471 NULL,
1472 gcc_jit_lvalue_as_rvalue (sum));
1473@end example
1474
35485da9
DM
1475@cartouche
1476@quotation Note
1477You can intermingle block creation with statement creation,
1478but given that the terminator statements generally include references
6f7585de 1479to other blocks, I find it’s clearer to create all the blocks,
35485da9
DM
1480@emph{then} all the statements.
1481@end quotation
1482@end cartouche
1483
6f7585de 1484We’ve finished populating the function. As before, we can now compile it
35485da9
DM
1485to machine code:
1486
1487@example
1488gcc_jit_result *result;
1489result = gcc_jit_context_compile (ctxt);
1490
1491typedef int (*loop_test_fn_type) (int);
1492loop_test_fn_type loop_test =
1493 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test");
1494if (!loop_test)
1495 goto error;
1496printf ("result: %d", loop_test (10));
1497@end example
1498
35485da9
DM
1499@example
1500result: 285
1501@end example
1502
35485da9 1503@node Visualizing the control flow graph,Full example<2>,Control flow,Tutorial part 3 Loops and variables
e250f0dc 1504@anchor{intro/tutorial03 visualizing-the-control-flow-graph}@anchor{32}
35485da9
DM
1505@subsection Visualizing the control flow graph
1506
1507
1508You can see the control flow graph of a function using
6f7585de 1509@ref{33,,gcc_jit_function_dump_to_dot()}:
35485da9
DM
1510
1511@example
1512gcc_jit_function_dump_to_dot (func, "/tmp/sum-of-squares.dot");
1513@end example
1514
35485da9
DM
1515giving a .dot file in GraphViz format.
1516
1517You can convert this to an image using @cite{dot}:
1518
1519@example
1520$ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png
1521@end example
1522
35485da9
DM
1523or use a viewer (my preferred one is xdot.py; see
1524@indicateurl{https://github.com/jrfonseca/xdot.py}; on Fedora you can
1525install it with @cite{yum install python-xdot}):
1526
1527@quotation
1528
1529
1530@float Figure
1531
421d0d0f 1532@image{libgccjit-figures/sum-of-squares1,,,image of a control flow graph,png}
35485da9
DM
1533
1534@end float
1535
1536@end quotation
1537
1538@node Full example<2>,,Visualizing the control flow graph,Tutorial part 3 Loops and variables
e250f0dc 1539@anchor{intro/tutorial03 full-example}@anchor{34}
35485da9
DM
1540@subsection Full example
1541
1542
1543@quotation
1544
1545@example
1546/* Usage example for libgccjit.so
7adcbafe 1547 Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
1548
1549This file is part of GCC.
1550
1551GCC is free software; you can redistribute it and/or modify it
1552under the terms of the GNU General Public License as published by
1553the Free Software Foundation; either version 3, or (at your option)
1554any later version.
1555
1556GCC is distributed in the hope that it will be useful, but
1557WITHOUT ANY WARRANTY; without even the implied warranty of
1558MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1559General Public License for more details.
1560
1561You should have received a copy of the GNU General Public License
1562along with GCC; see the file COPYING3. If not see
786973ce 1563<https://www.gnu.org/licenses/>. */
35485da9
DM
1564
1565#include <libgccjit.h>
1566
1567#include <stdlib.h>
1568#include <stdio.h>
1569
1570void
1571create_code (gcc_jit_context *ctxt)
1572@{
1573 /*
1574 Simple sum-of-squares, to test conditionals and looping
1575
1576 int loop_test (int n)
1577 @{
1578 int i;
1579 int sum = 0;
1580 for (i = 0; i < n ; i ++)
1581 @{
1582 sum += i * i;
1583 @}
1584 return sum;
1585 */
1586 gcc_jit_type *the_type =
1587 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
1588 gcc_jit_type *return_type = the_type;
1589
1590 gcc_jit_param *n =
1591 gcc_jit_context_new_param (ctxt, NULL, the_type, "n");
1592 gcc_jit_param *params[1] = @{n@};
1593 gcc_jit_function *func =
1594 gcc_jit_context_new_function (ctxt, NULL,
1595 GCC_JIT_FUNCTION_EXPORTED,
1596 return_type,
1597 "loop_test",
1598 1, params, 0);
1599
1600 /* Build locals: */
1601 gcc_jit_lvalue *i =
1602 gcc_jit_function_new_local (func, NULL, the_type, "i");
1603 gcc_jit_lvalue *sum =
1604 gcc_jit_function_new_local (func, NULL, the_type, "sum");
1605
1606 gcc_jit_block *b_initial =
1607 gcc_jit_function_new_block (func, "initial");
1608 gcc_jit_block *b_loop_cond =
1609 gcc_jit_function_new_block (func, "loop_cond");
1610 gcc_jit_block *b_loop_body =
1611 gcc_jit_function_new_block (func, "loop_body");
1612 gcc_jit_block *b_after_loop =
1613 gcc_jit_function_new_block (func, "after_loop");
1614
1615 /* sum = 0; */
1616 gcc_jit_block_add_assignment (
1617 b_initial, NULL,
1618 sum,
1619 gcc_jit_context_zero (ctxt, the_type));
1620
1621 /* i = 0; */
1622 gcc_jit_block_add_assignment (
1623 b_initial, NULL,
1624 i,
1625 gcc_jit_context_zero (ctxt, the_type));
1626
1627 gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond);
1628
1629 /* if (i >= n) */
1630 gcc_jit_block_end_with_conditional (
1631 b_loop_cond, NULL,
1632 gcc_jit_context_new_comparison (
1633 ctxt, NULL,
1634 GCC_JIT_COMPARISON_GE,
1635 gcc_jit_lvalue_as_rvalue (i),
1636 gcc_jit_param_as_rvalue (n)),
1637 b_after_loop,
1638 b_loop_body);
1639
1640 /* sum += i * i */
1641 gcc_jit_block_add_assignment_op (
1642 b_loop_body, NULL,
1643 sum,
1644 GCC_JIT_BINARY_OP_PLUS,
1645 gcc_jit_context_new_binary_op (
1646 ctxt, NULL,
1647 GCC_JIT_BINARY_OP_MULT, the_type,
1648 gcc_jit_lvalue_as_rvalue (i),
1649 gcc_jit_lvalue_as_rvalue (i)));
1650
1651 /* i++ */
1652 gcc_jit_block_add_assignment_op (
1653 b_loop_body, NULL,
1654 i,
1655 GCC_JIT_BINARY_OP_PLUS,
1656 gcc_jit_context_one (ctxt, the_type));
1657
1658 gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond);
1659
1660 /* return sum */
1661 gcc_jit_block_end_with_return (
1662 b_after_loop,
1663 NULL,
1664 gcc_jit_lvalue_as_rvalue (sum));
1665@}
1666
1667int
1668main (int argc, char **argv)
1669@{
1670 gcc_jit_context *ctxt = NULL;
1671 gcc_jit_result *result = NULL;
1672
1673 /* Get a "context" object for working with the library. */
1674 ctxt = gcc_jit_context_acquire ();
1675 if (!ctxt)
1676 @{
1677 fprintf (stderr, "NULL ctxt");
1678 goto error;
1679 @}
1680
1681 /* Set some options on the context.
1682 Let's see the code being generated, in assembler form. */
1683 gcc_jit_context_set_bool_option (
1684 ctxt,
1685 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
1686 0);
1687
1688 /* Populate the context. */
1689 create_code (ctxt);
1690
1691 /* Compile the code. */
1692 result = gcc_jit_context_compile (ctxt);
1693 if (!result)
1694 @{
1695 fprintf (stderr, "NULL result");
1696 goto error;
1697 @}
1698
1699 /* Extract the generated code from "result". */
1700 typedef int (*loop_test_fn_type) (int);
1701 loop_test_fn_type loop_test =
1702 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test");
1703 if (!loop_test)
1704 @{
1705 fprintf (stderr, "NULL loop_test");
1706 goto error;
1707 @}
1708
1709 /* Run the generated code. */
1710 int val = loop_test (10);
1711 printf("loop_test returned: %d\n", val);
1712
1713 error:
1714 gcc_jit_context_release (ctxt);
1715 gcc_jit_result_release (result);
1716 return 0;
1717@}
35485da9 1718@end example
35485da9
DM
1719@end quotation
1720
1721Building and running it:
1722
1723@example
1724$ gcc \
1725 tut03-sum-of-squares.c \
1726 -o tut03-sum-of-squares \
1727 -lgccjit
1728
1729# Run the built program:
1730$ ./tut03-sum-of-squares
1731loop_test returned: 285
1732@end example
1733
7adcbafe 1734@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
1735@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
1736@c
1737@c This is free software: you can redistribute it and/or modify it
1738@c under the terms of the GNU General Public License as published by
1739@c the Free Software Foundation, either version 3 of the License, or
1740@c (at your option) any later version.
1741@c
1742@c This program is distributed in the hope that it will be useful, but
1743@c WITHOUT ANY WARRANTY; without even the implied warranty of
1744@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1745@c General Public License for more details.
1746@c
1747@c You should have received a copy of the GNU General Public License
1748@c along with this program. If not, see
786973ce 1749@c <https://www.gnu.org/licenses/>.
35485da9 1750
fdce7209 1751@node Tutorial part 4 Adding JIT-compilation to a toy interpreter,Tutorial part 5 Implementing an Ahead-of-Time compiler,Tutorial part 3 Loops and variables,Tutorial
421d0d0f 1752@anchor{intro/tutorial04 doc}@anchor{35}@anchor{intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{36}
35485da9
DM
1753@section Tutorial part 4: Adding JIT-compilation to a toy interpreter
1754
1755
6f7585de 1756In this example we construct a “toy” interpreter, and add JIT-compilation
35485da9
DM
1757to it.
1758
1759@menu
1760* Our toy interpreter::
1761* Compiling to machine code::
1762* Setting things up::
1763* Populating the function::
1764* Verifying the control flow graph::
1765* Compiling the context::
1766* Single-stepping through the generated code::
1767* Examining the generated code::
1768* Putting it all together::
1769* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?.
1770
1771@end menu
1772
1773@node Our toy interpreter,Compiling to machine code,,Tutorial part 4 Adding JIT-compilation to a toy interpreter
e250f0dc 1774@anchor{intro/tutorial04 our-toy-interpreter}@anchor{37}
35485da9
DM
1775@subsection Our toy interpreter
1776
1777
6f7585de 1778It’s a stack-based interpreter, and is intended as a (very simple) example
35485da9
DM
1779of the kind of bytecode interpreter seen in dynamic languages such as
1780Python, Ruby etc.
1781
1782For the sake of simplicity, our toy virtual machine is very limited:
1783
1784@quotation
1785
1786
1787@itemize *
1788
1789@item
1790The only data type is @cite{int}
1791
1792@item
1793It can only work on one function at a time (so that the only
1794function call that can be made is to recurse).
1795
1796@item
1797Functions can only take one parameter.
1798
1799@item
1800Functions have a stack of @cite{int} values.
1801
1802@item
6f7585de 1803We’ll implement function call within the interpreter by calling a
35485da9
DM
1804function in our implementation, rather than implementing our own
1805frame stack.
1806
1807@item
1808The parser is only good enough to get the examples to work.
1809@end itemize
1810@end quotation
1811
1812Naturally, a real interpreter would be much more complicated that this.
1813
1814The following operations are supported:
1815
1816
1817@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxx}
1818@headitem
1819
1820Operation
1821
1822@tab
1823
1824Meaning
1825
1826@tab
1827
1828Old Stack
1829
1830@tab
1831
1832New Stack
1833
1834@item
1835
1836DUP
1837
1838@tab
1839
1840Duplicate top of stack.
1841
1842@tab
1843
1844@code{[..., x]}
1845
1846@tab
1847
1848@code{[..., x, x]}
1849
1850@item
1851
1852ROT
1853
1854@tab
1855
1856Swap top two elements
1857of stack.
1858
1859@tab
1860
1861@code{[..., x, y]}
1862
1863@tab
1864
1865@code{[..., y, x]}
1866
1867@item
1868
1869BINARY_ADD
1870
1871@tab
1872
1873Add the top two elements
1874on the stack.
1875
1876@tab
1877
1878@code{[..., x, y]}
1879
1880@tab
1881
1882@code{[..., (x+y)]}
1883
1884@item
1885
1886BINARY_SUBTRACT
1887
1888@tab
1889
1890Likewise, but subtract.
1891
1892@tab
1893
1894@code{[..., x, y]}
1895
1896@tab
1897
1898@code{[..., (x-y)]}
1899
1900@item
1901
1902BINARY_MULT
1903
1904@tab
1905
1906Likewise, but multiply.
1907
1908@tab
1909
1910@code{[..., x, y]}
1911
1912@tab
1913
1914@code{[..., (x*y)]}
1915
1916@item
1917
1918BINARY_COMPARE_LT
1919
1920@tab
1921
1922Compare the top two
1923elements on the stack
1924and push a nonzero/zero
1925if (x<y).
1926
1927@tab
1928
1929@code{[..., x, y]}
1930
1931@tab
1932
1933@code{[..., (x<y)]}
1934
1935@item
1936
1937RECURSE
1938
1939@tab
1940
1941Recurse, passing the top
1942of the stack, and
1943popping the result.
1944
1945@tab
1946
1947@code{[..., x]}
1948
1949@tab
1950
1951@code{[..., fn(x)]}
1952
1953@item
1954
1955RETURN
1956
1957@tab
1958
1959Return the top of the
1960stack.
1961
1962@tab
1963
1964@code{[x]}
1965
1966@tab
1967
1968@code{[]}
1969
1970@item
1971
1972PUSH_CONST @cite{arg}
1973
1974@tab
1975
1976Push an int const.
1977
1978@tab
1979
1980@code{[...]}
1981
1982@tab
1983
1984@code{[..., arg]}
1985
1986@item
1987
1988JUMP_ABS_IF_TRUE @cite{arg}
1989
1990@tab
1991
1992Pop; if top of stack was
1993nonzero, jump to
1994@code{arg}.
1995
1996@tab
1997
1998@code{[..., x]}
1999
2000@tab
2001
2002@code{[...]}
2003
2004@end multitable
2005
2006
2007Programs can be interpreted, disassembled, and compiled to machine code.
2008
6f7585de 2009The interpreter reads @code{.toy} scripts. Here’s what a simple recursive
35485da9
DM
2010factorial program looks like, the script @code{factorial.toy}.
2011The parser ignores lines beginning with a @cite{#}.
2012
2013@quotation
2014
2015@example
2016# Simple recursive factorial implementation, roughly equivalent to:
2017#
2018# int factorial (int arg)
2019# @{
2020# if (arg < 2)
2021# return arg
2022# return arg * factorial (arg - 1)
2023# @}
2024
2025# Initial state:
2026# stack: [arg]
2027
2028# 0:
2029DUP
2030# stack: [arg, arg]
2031
2032# 1:
2033PUSH_CONST 2
2034# stack: [arg, arg, 2]
2035
2036# 2:
2037BINARY_COMPARE_LT
2038# stack: [arg, (arg < 2)]
2039
2040# 3:
2041JUMP_ABS_IF_TRUE 9
2042# stack: [arg]
2043
2044# 4:
2045DUP
2046# stack: [arg, arg]
2047
2048# 5:
2049PUSH_CONST 1
2050# stack: [arg, arg, 1]
2051
2052# 6:
2053BINARY_SUBTRACT
2054# stack: [arg, (arg - 1)
2055
2056# 7:
2057RECURSE
2058# stack: [arg, factorial(arg - 1)]
2059
2060# 8:
2061BINARY_MULT
2062# stack: [arg * factorial(arg - 1)]
2063
2064# 9:
2065RETURN
35485da9 2066@end example
35485da9
DM
2067@end quotation
2068
2069The interpreter is a simple infinite loop with a big @code{switch} statement
2070based on what the next opcode is:
2071
2072@quotation
2073
2074@example
2075
2076static int
2077toyvm_function_interpret (toyvm_function *fn, int arg, FILE *trace)
2078@{
2079 toyvm_frame frame;
2080#define PUSH(ARG) (toyvm_frame_push (&frame, (ARG)))
2081#define POP(ARG) (toyvm_frame_pop (&frame))
2082
2083 frame.frm_function = fn;
2084 frame.frm_pc = 0;
2085 frame.frm_cur_depth = 0;
2086
2087 PUSH (arg);
2088
2089 while (1)
2090 @{
2091 toyvm_op *op;
2092 int x, y;
2093 assert (frame.frm_pc < fn->fn_num_ops);
2094 op = &fn->fn_ops[frame.frm_pc++];
2095
2096 if (trace)
2097 @{
2098 toyvm_frame_dump_stack (&frame, trace);
2099 toyvm_function_disassemble_op (fn, op, frame.frm_pc, trace);
2100 @}
2101
2102 switch (op->op_opcode)
2103 @{
2104 /* Ops taking no operand. */
2105 case DUP:
2106 x = POP ();
2107 PUSH (x);
2108 PUSH (x);
2109 break;
2110
2111 case ROT:
2112 y = POP ();
2113 x = POP ();
2114 PUSH (y);
2115 PUSH (x);
2116 break;
2117
2118 case BINARY_ADD:
2119 y = POP ();
2120 x = POP ();
2121 PUSH (x + y);
2122 break;
2123
2124 case BINARY_SUBTRACT:
2125 y = POP ();
2126 x = POP ();
2127 PUSH (x - y);
2128 break;
2129
2130 case BINARY_MULT:
2131 y = POP ();
2132 x = POP ();
2133 PUSH (x * y);
2134 break;
2135
2136 case BINARY_COMPARE_LT:
2137 y = POP ();
2138 x = POP ();
2139 PUSH (x < y);
2140 break;
2141
2142 case RECURSE:
2143 x = POP ();
2144 x = toyvm_function_interpret (fn, x, trace);
2145 PUSH (x);
2146 break;
2147
2148 case RETURN:
2149 return POP ();
2150
2151 /* Ops taking an operand. */
2152 case PUSH_CONST:
2153 PUSH (op->op_operand);
2154 break;
2155
2156 case JUMP_ABS_IF_TRUE:
2157 x = POP ();
2158 if (x)
2159 frame.frm_pc = op->op_operand;
2160 break;
2161
2162 default:
2163 assert (0); /* unknown opcode */
2164
2165 @} /* end of switch on opcode */
2166 @} /* end of while loop */
2167
2168#undef PUSH
2169#undef POP
2170@}
2171
35485da9 2172@end example
35485da9
DM
2173@end quotation
2174
2175@node Compiling to machine code,Setting things up,Our toy interpreter,Tutorial part 4 Adding JIT-compilation to a toy interpreter
e250f0dc 2176@anchor{intro/tutorial04 compiling-to-machine-code}@anchor{38}
35485da9
DM
2177@subsection Compiling to machine code
2178
2179
2180We want to generate machine code that can be cast to this type and
2181then directly executed in-process:
2182
2183@quotation
2184
2185@example
eeafb319
DM
2186typedef int (*toyvm_compiled_code) (int);
2187
eeafb319 2188@end example
eeafb319
DM
2189@end quotation
2190
6f7585de
DM
2191The lifetime of the code is tied to that of a @ref{16,,gcc_jit_result *}.
2192We’ll handle this by bundling them up in a structure, so that we can
2193clean them up together by calling @ref{39,,gcc_jit_result_release()}:
eeafb319
DM
2194
2195@quotation
2196
2197@example
2198
2199struct toyvm_compiled_function
2200@{
2201 gcc_jit_result *cf_jit_result;
2202 toyvm_compiled_code cf_code;
2203@};
35485da9 2204
35485da9 2205@end example
35485da9
DM
2206@end quotation
2207
6f7585de 2208Our compiler isn’t very sophisticated; it takes the implementation of
35485da9
DM
2209each opcode above, and maps it directly to the operations supported by
2210the libgccjit API.
2211
2212How should we handle the stack? In theory we could calculate what the
2213stack depth will be at each opcode, and optimize away the stack
6f7585de
DM
2214manipulation “by hand”. We’ll see below that libgccjit is able to do
2215this for us, so we’ll implement stack manipulation
35485da9
DM
2216in a direct way, by creating a @code{stack} array and @code{stack_depth}
2217variables, local within the generated function, equivalent to this C code:
2218
2219@example
2220int stack_depth;
2221int stack[MAX_STACK_DEPTH];
2222@end example
2223
6f7585de 2224We’ll also have local variables @code{x} and @code{y} for use when implementing
35485da9
DM
2225the opcodes, equivalent to this:
2226
2227@example
2228int x;
2229int y;
2230@end example
2231
35485da9
DM
2232This means our compiler has the following state:
2233
2234@quotation
2235
2236@example
2237
2238struct compilation_state
2239@{
2240 gcc_jit_context *ctxt;
2241
2242 gcc_jit_type *int_type;
2243 gcc_jit_type *bool_type;
2244 gcc_jit_type *stack_type; /* int[MAX_STACK_DEPTH] */
2245
2246 gcc_jit_rvalue *const_one;
2247
2248 gcc_jit_function *fn;
2249 gcc_jit_param *param_arg;
2250 gcc_jit_lvalue *stack;
2251 gcc_jit_lvalue *stack_depth;
2252 gcc_jit_lvalue *x;
2253 gcc_jit_lvalue *y;
2254
2255 gcc_jit_location *op_locs[MAX_OPS];
2256 gcc_jit_block *initial_block;
2257 gcc_jit_block *op_blocks[MAX_OPS];
2258
2259@};
2260
35485da9 2261@end example
35485da9
DM
2262@end quotation
2263
2264@node Setting things up,Populating the function,Compiling to machine code,Tutorial part 4 Adding JIT-compilation to a toy interpreter
e250f0dc 2265@anchor{intro/tutorial04 setting-things-up}@anchor{3a}
35485da9
DM
2266@subsection Setting things up
2267
2268
2269First we create our types:
2270
2271@quotation
2272
2273@example
2274 state.int_type =
2275 gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_INT);
2276 state.bool_type =
2277 gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_BOOL);
2278 state.stack_type =
2279 gcc_jit_context_new_array_type (state.ctxt, NULL,
2280 state.int_type, MAX_STACK_DEPTH);
2281
35485da9 2282@end example
35485da9
DM
2283@end quotation
2284
2285along with extracting a useful @cite{int} constant:
2286
2287@quotation
2288
2289@example
2290 state.const_one = gcc_jit_context_one (state.ctxt, state.int_type);
2291
35485da9 2292@end example
35485da9
DM
2293@end quotation
2294
6f7585de 2295We’ll implement push and pop in terms of the @code{stack} array and
35485da9
DM
2296@code{stack_depth}. Here are helper functions for adding statements to
2297a block, implementing pushing and popping values:
2298
2299@quotation
2300
2301@example
2302
2303static void
2304add_push (compilation_state *state,
2305 gcc_jit_block *block,
2306 gcc_jit_rvalue *rvalue,
2307 gcc_jit_location *loc)
2308@{
2309 /* stack[stack_depth] = RVALUE */
2310 gcc_jit_block_add_assignment (
2311 block,
2312 loc,
2313 /* stack[stack_depth] */
2314 gcc_jit_context_new_array_access (
2315 state->ctxt,
2316 loc,
2317 gcc_jit_lvalue_as_rvalue (state->stack),
2318 gcc_jit_lvalue_as_rvalue (state->stack_depth)),
2319 rvalue);
2320
2321 /* "stack_depth++;". */
2322 gcc_jit_block_add_assignment_op (
2323 block,
2324 loc,
2325 state->stack_depth,
2326 GCC_JIT_BINARY_OP_PLUS,
2327 state->const_one);
2328@}
2329
2330static void
2331add_pop (compilation_state *state,
2332 gcc_jit_block *block,
2333 gcc_jit_lvalue *lvalue,
2334 gcc_jit_location *loc)
2335@{
2336 /* "--stack_depth;". */
2337 gcc_jit_block_add_assignment_op (
2338 block,
2339 loc,
2340 state->stack_depth,
2341 GCC_JIT_BINARY_OP_MINUS,
2342 state->const_one);
2343
2344 /* "LVALUE = stack[stack_depth];". */
2345 gcc_jit_block_add_assignment (
2346 block,
2347 loc,
2348 lvalue,
2349 /* stack[stack_depth] */
2350 gcc_jit_lvalue_as_rvalue (
2351 gcc_jit_context_new_array_access (
2352 state->ctxt,
2353 loc,
2354 gcc_jit_lvalue_as_rvalue (state->stack),
2355 gcc_jit_lvalue_as_rvalue (state->stack_depth))));
2356@}
2357
35485da9 2358@end example
35485da9
DM
2359@end quotation
2360
2361We will support single-stepping through the generated code in the
6f7585de 2362debugger, so we need to create @ref{3b,,gcc_jit_location} instances, one
35485da9
DM
2363per operation in the source code. These will reference the lines of
2364e.g. @code{factorial.toy}.
2365
2366@quotation
2367
2368@example
2369 for (pc = 0; pc < fn->fn_num_ops; pc++)
2370 @{
2371 toyvm_op *op = &fn->fn_ops[pc];
2372
2373 state.op_locs[pc] = gcc_jit_context_new_location (state.ctxt,
2374 fn->fn_filename,
2375 op->op_linenum,
2376 0); /* column */
2377 @}
2378
35485da9 2379@end example
35485da9
DM
2380@end quotation
2381
6f7585de 2382Let’s create the function itself. As usual, we create its parameter
35485da9
DM
2383first, then use the parameter to create the function:
2384
2385@quotation
2386
2387@example
2388 state.param_arg =
2389 gcc_jit_context_new_param (state.ctxt, state.op_locs[0],
2390 state.int_type, "arg");
2391 state.fn =
2392 gcc_jit_context_new_function (state.ctxt,
2393 state.op_locs[0],
2394 GCC_JIT_FUNCTION_EXPORTED,
2395 state.int_type,
2396 funcname,
2397 1, &state.param_arg, 0);
2398
35485da9 2399@end example
35485da9
DM
2400@end quotation
2401
2402We create the locals within the function.
2403
2404@quotation
2405
2406@example
2407 state.stack =
2408 gcc_jit_function_new_local (state.fn, NULL,
2409 state.stack_type, "stack");
2410 state.stack_depth =
2411 gcc_jit_function_new_local (state.fn, NULL,
2412 state.int_type, "stack_depth");
2413 state.x =
2414 gcc_jit_function_new_local (state.fn, NULL,
2415 state.int_type, "x");
2416 state.y =
2417 gcc_jit_function_new_local (state.fn, NULL,
2418 state.int_type, "y");
2419
35485da9 2420@end example
35485da9
DM
2421@end quotation
2422
2423@node Populating the function,Verifying the control flow graph,Setting things up,Tutorial part 4 Adding JIT-compilation to a toy interpreter
e250f0dc 2424@anchor{intro/tutorial04 populating-the-function}@anchor{3c}
35485da9
DM
2425@subsection Populating the function
2426
2427
6f7585de 2428There’s some one-time initialization, and the API treats the first block
35485da9
DM
2429you create as the entrypoint of the function, so we need to create that
2430block first:
2431
2432@quotation
2433
2434@example
2435 state.initial_block = gcc_jit_function_new_block (state.fn, "initial");
2436
35485da9 2437@end example
35485da9
DM
2438@end quotation
2439
2440We can now create blocks for each of the operations. Most of these will
2441be consolidated into larger blocks when the optimizer runs.
2442
2443@quotation
2444
2445@example
2446 for (pc = 0; pc < fn->fn_num_ops; pc++)
2447 @{
2448 char buf[16];
2449 sprintf (buf, "instr%i", pc);
2450 state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf);
2451 @}
2452
35485da9 2453@end example
35485da9
DM
2454@end quotation
2455
6f7585de 2456Now that we have a block it can jump to when it’s done, we can populate
35485da9
DM
2457the initial block:
2458
2459@quotation
2460
2461@example
2462
2463 /* "stack_depth = 0;". */
2464 gcc_jit_block_add_assignment (
2465 state.initial_block,
2466 state.op_locs[0],
2467 state.stack_depth,
2468 gcc_jit_context_zero (state.ctxt, state.int_type));
2469
2470 /* "PUSH (arg);". */
2471 add_push (&state,
2472 state.initial_block,
2473 gcc_jit_param_as_rvalue (state.param_arg),
2474 state.op_locs[0]);
2475
2476 /* ...and jump to insn 0. */
2477 gcc_jit_block_end_with_jump (state.initial_block,
2478 state.op_locs[0],
2479 state.op_blocks[0]);
2480
35485da9 2481@end example
35485da9
DM
2482@end quotation
2483
2484We can now populate the blocks for the individual operations. We loop
2485through them, adding instructions to their blocks:
2486
2487@quotation
2488
2489@example
2490 for (pc = 0; pc < fn->fn_num_ops; pc++)
2491 @{
2492 gcc_jit_location *loc = state.op_locs[pc];
2493
2494 gcc_jit_block *block = state.op_blocks[pc];
2495 gcc_jit_block *next_block = (pc < fn->fn_num_ops
2496 ? state.op_blocks[pc + 1]
2497 : NULL);
2498
2499 toyvm_op *op;
2500 op = &fn->fn_ops[pc];
2501
35485da9 2502@end example
35485da9
DM
2503@end quotation
2504
6f7585de 2505We’re going to have another big @code{switch} statement for implementing
35485da9 2506the opcodes, this time for compiling them, rather than interpreting
6f7585de
DM
2507them. It’s helpful to have macros for implementing push and pop, so that
2508we can make the @code{switch} statement that’s coming up look as much as
35485da9
DM
2509possible like the one above within the interpreter:
2510
2511@example
2512
2513#define X_EQUALS_POP()\
2514 add_pop (&state, block, state.x, loc)
2515#define Y_EQUALS_POP()\
2516 add_pop (&state, block, state.y, loc)
2517#define PUSH_RVALUE(RVALUE)\
2518 add_push (&state, block, (RVALUE), loc)
2519#define PUSH_X()\
2520 PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.x))
2521#define PUSH_Y() \
2522 PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.y))
2523
35485da9
DM
2524@end example
2525
35485da9
DM
2526@cartouche
2527@quotation Note
2528A particularly clever implementation would have an @emph{identical}
2529@code{switch} statement shared by the interpreter and the compiler, with
6f7585de 2530some preprocessor “magic”. We’re not doing that here, for the sake
35485da9
DM
2531of simplicity.
2532@end quotation
2533@end cartouche
2534
2535When I first implemented this compiler, I accidentally missed an edit
2536when copying and pasting the @code{Y_EQUALS_POP} macro, so that popping the
2537stack into @code{y} instead erroneously assigned it to @code{x}, leaving @code{y}
2538uninitialized.
2539
2540To track this kind of thing down, we can use
6f7585de 2541@ref{3d,,gcc_jit_block_add_comment()} to add descriptive comments
35485da9
DM
2542to the internal representation. This is invaluable when looking through
2543the generated IR for, say @code{factorial}:
2544
2545@quotation
2546
2547@example
2548
2549 gcc_jit_block_add_comment (block, loc, opcode_names[op->op_opcode]);
2550
35485da9 2551@end example
35485da9
DM
2552@end quotation
2553
2554We can now write the big @code{switch} statement that implements the
2555individual opcodes, populating the relevant block with statements:
2556
2557@quotation
2558
2559@example
2560
2561 switch (op->op_opcode)
2562 @{
2563 case DUP:
2564 X_EQUALS_POP ();
2565 PUSH_X ();
2566 PUSH_X ();
2567 break;
2568
2569 case ROT:
2570 Y_EQUALS_POP ();
2571 X_EQUALS_POP ();
2572 PUSH_Y ();
2573 PUSH_X ();
2574 break;
2575
2576 case BINARY_ADD:
2577 Y_EQUALS_POP ();
2578 X_EQUALS_POP ();
2579 PUSH_RVALUE (
2580 gcc_jit_context_new_binary_op (
2581 state.ctxt,
2582 loc,
2583 GCC_JIT_BINARY_OP_PLUS,
2584 state.int_type,
2585 gcc_jit_lvalue_as_rvalue (state.x),
2586 gcc_jit_lvalue_as_rvalue (state.y)));
2587 break;
2588
2589 case BINARY_SUBTRACT:
2590 Y_EQUALS_POP ();
2591 X_EQUALS_POP ();
2592 PUSH_RVALUE (
2593 gcc_jit_context_new_binary_op (
2594 state.ctxt,
2595 loc,
2596 GCC_JIT_BINARY_OP_MINUS,
2597 state.int_type,
2598 gcc_jit_lvalue_as_rvalue (state.x),
2599 gcc_jit_lvalue_as_rvalue (state.y)));
2600 break;
2601
2602 case BINARY_MULT:
2603 Y_EQUALS_POP ();
2604 X_EQUALS_POP ();
2605 PUSH_RVALUE (
2606 gcc_jit_context_new_binary_op (
2607 state.ctxt,
2608 loc,
2609 GCC_JIT_BINARY_OP_MULT,
2610 state.int_type,
2611 gcc_jit_lvalue_as_rvalue (state.x),
2612 gcc_jit_lvalue_as_rvalue (state.y)));
2613 break;
2614
2615 case BINARY_COMPARE_LT:
2616 Y_EQUALS_POP ();
2617 X_EQUALS_POP ();
2618 PUSH_RVALUE (
2619 /* cast of bool to int */
2620 gcc_jit_context_new_cast (
2621 state.ctxt,
2622 loc,
2623 /* (x < y) as a bool */
2624 gcc_jit_context_new_comparison (
2625 state.ctxt,
2626 loc,
2627 GCC_JIT_COMPARISON_LT,
2628 gcc_jit_lvalue_as_rvalue (state.x),
2629 gcc_jit_lvalue_as_rvalue (state.y)),
2630 state.int_type));
2631 break;
2632
2633 case RECURSE:
2634 @{
2635 X_EQUALS_POP ();
2636 gcc_jit_rvalue *arg = gcc_jit_lvalue_as_rvalue (state.x);
2637 PUSH_RVALUE (
2638 gcc_jit_context_new_call (
2639 state.ctxt,
2640 loc,
2641 state.fn,
2642 1, &arg));
2643 break;
2644 @}
2645
2646 case RETURN:
2647 X_EQUALS_POP ();
2648 gcc_jit_block_end_with_return (
2649 block,
2650 loc,
2651 gcc_jit_lvalue_as_rvalue (state.x));
2652 break;
2653
2654 /* Ops taking an operand. */
2655 case PUSH_CONST:
2656 PUSH_RVALUE (
2657 gcc_jit_context_new_rvalue_from_int (
2658 state.ctxt,
2659 state.int_type,
2660 op->op_operand));
2661 break;
2662
2663 case JUMP_ABS_IF_TRUE:
2664 X_EQUALS_POP ();
2665 gcc_jit_block_end_with_conditional (
2666 block,
2667 loc,
2668 /* "(bool)x". */
2669 gcc_jit_context_new_cast (
2670 state.ctxt,
2671 loc,
2672 gcc_jit_lvalue_as_rvalue (state.x),
2673 state.bool_type),
2674 state.op_blocks[op->op_operand], /* on_true */
2675 next_block); /* on_false */
2676 break;
2677
2678 default:
2679 assert(0);
2680 @} /* end of switch on opcode */
2681
35485da9 2682@end example
35485da9
DM
2683@end quotation
2684
2685Every block must be terminated, via a call to one of the
2686@code{gcc_jit_block_end_with_} entrypoints. This has been done for two
2687of the opcodes, but we need to do it for the other ones, by jumping
2688to the next block.
2689
2690@quotation
2691
2692@example
2693 if (op->op_opcode != JUMP_ABS_IF_TRUE
2694 && op->op_opcode != RETURN)
2695 gcc_jit_block_end_with_jump (
2696 block,
2697 loc,
2698 next_block);
2699
35485da9 2700@end example
35485da9
DM
2701@end quotation
2702
2703This is analogous to simply incrementing the program counter.
2704
2705@node Verifying the control flow graph,Compiling the context,Populating the function,Tutorial part 4 Adding JIT-compilation to a toy interpreter
e250f0dc 2706@anchor{intro/tutorial04 verifying-the-control-flow-graph}@anchor{3e}
35485da9
DM
2707@subsection Verifying the control flow graph
2708
2709
2710Having finished looping over the blocks, the context is complete.
2711
2712As before, we can verify that the control flow and statements are sane by
6f7585de 2713using @ref{33,,gcc_jit_function_dump_to_dot()}:
35485da9
DM
2714
2715@example
2716gcc_jit_function_dump_to_dot (state.fn, "/tmp/factorial.dot");
2717@end example
2718
35485da9
DM
2719and viewing the result. Note how the label names, comments, and
2720variable names show up in the dump, to make it easier to spot
2721errors in our compiler.
2722
2723@quotation
2724
2725
2726@float Figure
2727
421d0d0f 2728@image{libgccjit-figures/factorial1,,,image of a control flow graph,png}
35485da9
DM
2729
2730@end float
2731
2732@end quotation
2733
2734@node Compiling the context,Single-stepping through the generated code,Verifying the control flow graph,Tutorial part 4 Adding JIT-compilation to a toy interpreter
e250f0dc 2735@anchor{intro/tutorial04 compiling-the-context}@anchor{3f}
35485da9
DM
2736@subsection Compiling the context
2737
2738
2739Having finished looping over the blocks and populating them with
2740statements, the context is complete.
2741
2742We can now compile it, and extract machine code from the result:
2743
2744@quotation
35485da9
DM
2745@end quotation
2746
2747We can now run the result:
2748
2749@quotation
2750
2751@example
eeafb319
DM
2752 toyvm_compiled_function *compiled_fn
2753 = toyvm_function_compile (fn);
2754
2755 toyvm_compiled_code code = compiled_fn->cf_code;
35485da9
DM
2756 printf ("compiler result: %d\n",
2757 code (atoi (argv[2])));
2758
eeafb319
DM
2759 gcc_jit_result_release (compiled_fn->cf_jit_result);
2760 free (compiled_fn);
2761
35485da9 2762@end example
35485da9
DM
2763@end quotation
2764
2765@node Single-stepping through the generated code,Examining the generated code,Compiling the context,Tutorial part 4 Adding JIT-compilation to a toy interpreter
e250f0dc 2766@anchor{intro/tutorial04 single-stepping-through-the-generated-code}@anchor{40}
35485da9
DM
2767@subsection Single-stepping through the generated code
2768
2769
6f7585de 2770It’s possible to debug the generated code. To do this we need to both:
35485da9
DM
2771
2772@quotation
2773
2774
2775@itemize *
2776
2777@item
2778Set up source code locations for our statements, so that we can
2779meaningfully step through the code. We did this above by
6f7585de 2780calling @ref{41,,gcc_jit_context_new_location()} and using the
35485da9
DM
2781results.
2782
2783@item
2784Enable the generation of debugging information, by setting
6f7585de
DM
2785@ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the
2786@ref{8,,gcc_jit_context} via
2787@ref{1b,,gcc_jit_context_set_bool_option()}:
35485da9
DM
2788
2789@example
2790gcc_jit_context_set_bool_option (
2791 ctxt,
2792 GCC_JIT_BOOL_OPTION_DEBUGINFO,
2793 1);
2794@end example
35485da9
DM
2795@end itemize
2796@end quotation
2797
2798Having done this, we can put a breakpoint on the generated function:
2799
2800@example
2801$ gdb --args ./toyvm factorial.toy 10
2802(gdb) break factorial
2803Function "factorial" not defined.
2804Make breakpoint pending on future shared library load? (y or [n]) y
2805Breakpoint 1 (factorial) pending.
2806(gdb) run
2807Breakpoint 1, factorial (arg=10) at factorial.toy:14
280814 DUP
2809@end example
2810
6f7585de 2811We’ve set up location information, which references @code{factorial.toy}.
35485da9
DM
2812This allows us to use e.g. @code{list} to see where we are in the script:
2813
2814@example
2815(gdb) list
28169
281710 # Initial state:
281811 # stack: [arg]
281912
282013 # 0:
282114 DUP
282215 # stack: [arg, arg]
282316
282417 # 1:
282518 PUSH_CONST 2
2826@end example
2827
35485da9
DM
2828and to step through the function, examining the data:
2829
2830@example
2831(gdb) n
283218 PUSH_CONST 2
2833(gdb) n
283422 BINARY_COMPARE_LT
2835(gdb) print stack
2836$5 = @{10, 10, 2, 0, -7152, 32767, 0, 0@}
2837(gdb) print stack_depth
2838$6 = 3
2839@end example
2840
6f7585de 2841You’ll see that the parts of the @code{stack} array that haven’t been
35485da9
DM
2842touched yet are uninitialized.
2843
2844@cartouche
2845@quotation Note
2846Turning on optimizations may lead to unpredictable results when
2847stepping through the generated code: the execution may appear to
6f7585de 2848“jump around” the source code. This is analogous to turning up the
35485da9
DM
2849optimization level in a regular compiler.
2850@end quotation
2851@end cartouche
2852
2853@node Examining the generated code,Putting it all together,Single-stepping through the generated code,Tutorial part 4 Adding JIT-compilation to a toy interpreter
e250f0dc 2854@anchor{intro/tutorial04 examining-the-generated-code}@anchor{43}
35485da9
DM
2855@subsection Examining the generated code
2856
2857
2858How good is the optimized code?
2859
2860We can turn up optimizations, by calling
6f7585de
DM
2861@ref{1e,,gcc_jit_context_set_int_option()} with
2862@ref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}:
35485da9
DM
2863
2864@example
2865gcc_jit_context_set_int_option (
2866 ctxt,
2867 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
2868 3);
2869@end example
2870
6f7585de 2871One of GCC’s internal representations is called “gimple”. A dump of the
35485da9
DM
2872initial gimple representation of the code can be seen by setting:
2873
2874@example
2875gcc_jit_context_set_bool_option (ctxt,
2876 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE,
2877 1);
2878@end example
2879
35485da9
DM
2880With optimization on and source locations displayed, this gives:
2881
2882@c We'll use "c" for gimple dumps
2883
2884@example
2885factorial (signed int arg)
2886@{
2887 <unnamed type> D.80;
2888 signed int D.81;
2889 signed int D.82;
2890 signed int D.83;
2891 signed int D.84;
2892 signed int D.85;
2893 signed int y;
2894 signed int x;
2895 signed int stack_depth;
2896 signed int stack[8];
2897
2898 try
2899 @{
2900 initial:
2901 stack_depth = 0;
2902 stack[stack_depth] = arg;
2903 stack_depth = stack_depth + 1;
2904 goto instr0;
2905 instr0:
2906 /* DUP */:
2907 stack_depth = stack_depth + -1;
2908 x = stack[stack_depth];
2909 stack[stack_depth] = x;
2910 stack_depth = stack_depth + 1;
2911 stack[stack_depth] = x;
2912 stack_depth = stack_depth + 1;
2913 goto instr1;
2914 instr1:
2915 /* PUSH_CONST */:
2916 stack[stack_depth] = 2;
2917 stack_depth = stack_depth + 1;
2918 goto instr2;
2919
2920 /* etc */
2921@end example
2922
35485da9
DM
2923You can see the generated machine code in assembly form via:
2924
2925@example
2926gcc_jit_context_set_bool_option (
2927 ctxt,
2928 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
2929 1);
2930result = gcc_jit_context_compile (ctxt);
2931@end example
2932
35485da9
DM
2933which shows that (on this x86_64 box) the compiler has unrolled the loop
2934and is using MMX instructions to perform several multiplications
2935simultaneously:
2936
2937@example
2938 .file "fake.c"
2939 .text
2940.Ltext0:
2941 .p2align 4,,15
2942 .globl factorial
2943 .type factorial, @@function
2944factorial:
2945.LFB0:
2946 .file 1 "factorial.toy"
2947 .loc 1 14 0
2948 .cfi_startproc
2949.LVL0:
2950.L2:
2951 .loc 1 26 0
2952 cmpl $1, %edi
2953 jle .L13
2954 leal -1(%rdi), %edx
2955 movl %edx, %ecx
2956 shrl $2, %ecx
2957 leal 0(,%rcx,4), %esi
2958 testl %esi, %esi
2959 je .L14
2960 cmpl $9, %edx
2961 jbe .L14
2962 leal -2(%rdi), %eax
2963 movl %eax, -16(%rsp)
2964 leal -3(%rdi), %eax
2965 movd -16(%rsp), %xmm0
2966 movl %edi, -16(%rsp)
2967 movl %eax, -12(%rsp)
2968 movd -16(%rsp), %xmm1
2969 xorl %eax, %eax
2970 movl %edx, -16(%rsp)
2971 movd -12(%rsp), %xmm4
2972 movd -16(%rsp), %xmm6
2973 punpckldq %xmm4, %xmm0
2974 movdqa .LC1(%rip), %xmm4
2975 punpckldq %xmm6, %xmm1
2976 punpcklqdq %xmm0, %xmm1
2977 movdqa .LC0(%rip), %xmm0
2978 jmp .L5
2979 # etc - edited for brevity
2980@end example
2981
35485da9
DM
2982This is clearly overkill for a function that will likely overflow the
2983@code{int} type before the vectorization is worthwhile - but then again, this
2984is a toy example.
2985
2986Turning down the optimization level to 2:
2987
2988@example
2989gcc_jit_context_set_int_option (
2990 ctxt,
2991 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
2992 3);
2993@end example
2994
35485da9
DM
2995yields this code, which is simple enough to quote in its entirety:
2996
2997@example
2998 .file "fake.c"
2999 .text
3000 .p2align 4,,15
3001 .globl factorial
3002 .type factorial, @@function
3003factorial:
3004.LFB0:
3005 .cfi_startproc
3006.L2:
3007 cmpl $1, %edi
3008 jle .L8
3009 movl $1, %edx
3010 jmp .L4
3011 .p2align 4,,10
3012 .p2align 3
3013.L6:
3014 movl %eax, %edi
3015.L4:
3016.L5:
3017 leal -1(%rdi), %eax
3018 imull %edi, %edx
3019 cmpl $1, %eax
3020 jne .L6
3021.L3:
3022.L7:
3023 imull %edx, %eax
3024 ret
3025.L8:
3026 movl %edi, %eax
3027 movl $1, %edx
3028 jmp .L7
3029 .cfi_endproc
3030.LFE0:
3031 .size factorial, .-factorial
3032 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-%@{gcc_release@})"
3033 .section .note.GNU-stack,"",@@progbits
3034@end example
3035
35485da9
DM
3036Note that the stack pushing and popping have been eliminated, as has the
3037recursive call (in favor of an iteration).
3038
3039@node Putting it all together,Behind the curtain How does our code get optimized?,Examining the generated code,Tutorial part 4 Adding JIT-compilation to a toy interpreter
e250f0dc 3040@anchor{intro/tutorial04 putting-it-all-together}@anchor{44}
35485da9
DM
3041@subsection Putting it all together
3042
3043
3044The complete example can be seen in the source tree at
3045@code{gcc/jit/docs/examples/tut04-toyvm/toyvm.c}
3046
3047along with a Makefile and a couple of sample .toy scripts:
3048
3049@example
3050$ ls -al
3051drwxrwxr-x. 2 david david 4096 Sep 19 17:46 .
3052drwxrwxr-x. 3 david david 4096 Sep 19 15:26 ..
3053-rw-rw-r--. 1 david david 615 Sep 19 12:43 factorial.toy
3054-rw-rw-r--. 1 david david 834 Sep 19 13:08 fibonacci.toy
3055-rw-rw-r--. 1 david david 238 Sep 19 14:22 Makefile
3056-rw-rw-r--. 1 david david 16457 Sep 19 17:07 toyvm.c
3057
3058$ make toyvm
3059g++ -Wall -g -o toyvm toyvm.c -lgccjit
3060
3061$ ./toyvm factorial.toy 10
3062interpreter result: 3628800
3063compiler result: 3628800
3064
3065$ ./toyvm fibonacci.toy 10
3066interpreter result: 55
3067compiler result: 55
3068@end example
3069
35485da9 3070@node Behind the curtain How does our code get optimized?,,Putting it all together,Tutorial part 4 Adding JIT-compilation to a toy interpreter
e250f0dc 3071@anchor{intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{45}
35485da9
DM
3072@subsection Behind the curtain: How does our code get optimized?
3073
3074
3075Our example is done, but you may be wondering about exactly how the
3076compiler turned what we gave it into the machine code seen above.
3077
3078We can examine what the compiler is doing in detail by setting:
3079
3080@example
3081gcc_jit_context_set_bool_option (state.ctxt,
3082 GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING,
3083 1);
3084gcc_jit_context_set_bool_option (state.ctxt,
3085 GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES,
3086 1);
3087@end example
3088
6f7585de 3089This will dump detailed information about the compiler’s state to a
35485da9
DM
3090directory under @code{/tmp}, and keep it from being cleaned up.
3091
3092The precise names and their formats of these files is subject to change.
3093Higher optimization levels lead to more files.
6f7585de 3094Here’s what I saw (edited for brevity; there were almost 200 files):
35485da9
DM
3095
3096@example
3097intermediate files written to /tmp/libgccjit-KPQbGw
3098$ ls /tmp/libgccjit-KPQbGw/
3099fake.c.000i.cgraph
3100fake.c.000i.type-inheritance
3101fake.c.004t.gimple
3102fake.c.007t.omplower
3103fake.c.008t.lower
3104fake.c.011t.eh
3105fake.c.012t.cfg
3106fake.c.014i.visibility
3107fake.c.015i.early_local_cleanups
3108fake.c.016t.ssa
3109# etc
3110@end example
3111
35485da9
DM
3112The gimple code is converted into Static Single Assignment form,
3113with annotations for use when generating the debuginfo:
3114
3115@example
3116$ less /tmp/libgccjit-KPQbGw/fake.c.016t.ssa
3117@end example
3118
35485da9
DM
3119@example
3120;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
3121
3122factorial (signed int arg)
3123@{
3124 signed int stack[8];
3125 signed int stack_depth;
3126 signed int x;
3127 signed int y;
3128 <unnamed type> _20;
3129 signed int _21;
3130 signed int _38;
3131 signed int _44;
3132 signed int _51;
3133 signed int _56;
3134
3135initial:
3136 stack_depth_3 = 0;
3137 # DEBUG stack_depth => stack_depth_3
3138 stack[stack_depth_3] = arg_5(D);
3139 stack_depth_7 = stack_depth_3 + 1;
3140 # DEBUG stack_depth => stack_depth_7
3141 # DEBUG instr0 => NULL
3142 # DEBUG /* DUP */ => NULL
3143 stack_depth_8 = stack_depth_7 + -1;
3144 # DEBUG stack_depth => stack_depth_8
3145 x_9 = stack[stack_depth_8];
3146 # DEBUG x => x_9
3147 stack[stack_depth_8] = x_9;
3148 stack_depth_11 = stack_depth_8 + 1;
3149 # DEBUG stack_depth => stack_depth_11
3150 stack[stack_depth_11] = x_9;
3151 stack_depth_13 = stack_depth_11 + 1;
3152 # DEBUG stack_depth => stack_depth_13
3153 # DEBUG instr1 => NULL
3154 # DEBUG /* PUSH_CONST */ => NULL
3155 stack[stack_depth_13] = 2;
3156
3157 /* etc; edited for brevity */
3158@end example
3159
35485da9 3160We can perhaps better see the code by turning off
6f7585de 3161@ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to suppress all those @code{DEBUG}
35485da9
DM
3162statements, giving:
3163
3164@example
3165$ less /tmp/libgccjit-1Hywc0/fake.c.016t.ssa
3166@end example
3167
35485da9
DM
3168@example
3169;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
3170
3171factorial (signed int arg)
3172@{
3173 signed int stack[8];
3174 signed int stack_depth;
3175 signed int x;
3176 signed int y;
3177 <unnamed type> _20;
3178 signed int _21;
3179 signed int _38;
3180 signed int _44;
3181 signed int _51;
3182 signed int _56;
3183
3184initial:
3185 stack_depth_3 = 0;
3186 stack[stack_depth_3] = arg_5(D);
3187 stack_depth_7 = stack_depth_3 + 1;
3188 stack_depth_8 = stack_depth_7 + -1;
3189 x_9 = stack[stack_depth_8];
3190 stack[stack_depth_8] = x_9;
3191 stack_depth_11 = stack_depth_8 + 1;
3192 stack[stack_depth_11] = x_9;
3193 stack_depth_13 = stack_depth_11 + 1;
3194 stack[stack_depth_13] = 2;
3195 stack_depth_15 = stack_depth_13 + 1;
3196 stack_depth_16 = stack_depth_15 + -1;
3197 y_17 = stack[stack_depth_16];
3198 stack_depth_18 = stack_depth_16 + -1;
3199 x_19 = stack[stack_depth_18];
3200 _20 = x_19 < y_17;
3201 _21 = (signed int) _20;
3202 stack[stack_depth_18] = _21;
3203 stack_depth_23 = stack_depth_18 + 1;
3204 stack_depth_24 = stack_depth_23 + -1;
3205 x_25 = stack[stack_depth_24];
3206 if (x_25 != 0)
3207 goto <bb 4> (instr9);
3208 else
3209 goto <bb 3> (instr4);
3210
3211instr4:
3212/* DUP */:
3213 stack_depth_26 = stack_depth_24 + -1;
3214 x_27 = stack[stack_depth_26];
3215 stack[stack_depth_26] = x_27;
3216 stack_depth_29 = stack_depth_26 + 1;
3217 stack[stack_depth_29] = x_27;
3218 stack_depth_31 = stack_depth_29 + 1;
3219 stack[stack_depth_31] = 1;
3220 stack_depth_33 = stack_depth_31 + 1;
3221 stack_depth_34 = stack_depth_33 + -1;
3222 y_35 = stack[stack_depth_34];
3223 stack_depth_36 = stack_depth_34 + -1;
3224 x_37 = stack[stack_depth_36];
3225 _38 = x_37 - y_35;
3226 stack[stack_depth_36] = _38;
3227 stack_depth_40 = stack_depth_36 + 1;
3228 stack_depth_41 = stack_depth_40 + -1;
3229 x_42 = stack[stack_depth_41];
3230 _44 = factorial (x_42);
3231 stack[stack_depth_41] = _44;
3232 stack_depth_46 = stack_depth_41 + 1;
3233 stack_depth_47 = stack_depth_46 + -1;
3234 y_48 = stack[stack_depth_47];
3235 stack_depth_49 = stack_depth_47 + -1;
3236 x_50 = stack[stack_depth_49];
3237 _51 = x_50 * y_48;
3238 stack[stack_depth_49] = _51;
3239 stack_depth_53 = stack_depth_49 + 1;
3240
3241 # stack_depth_1 = PHI <stack_depth_24(2), stack_depth_53(3)>
3242instr9:
3243/* RETURN */:
3244 stack_depth_54 = stack_depth_1 + -1;
3245 x_55 = stack[stack_depth_54];
3246 _56 = x_55;
3247 stack =@{v@} @{CLOBBER@};
3248 return _56;
3249
3250@}
3251@end example
3252
6f7585de
DM
3253Note in the above how all the @ref{28,,gcc_jit_block} instances we
3254created have been consolidated into just 3 blocks in GCC’s internal
35485da9
DM
3255representation: @code{initial}, @code{instr4} and @code{instr9}.
3256
3257@menu
3258* Optimizing away stack manipulation::
3259* Elimination of tail recursion::
3260
3261@end menu
3262
3263@node Optimizing away stack manipulation,Elimination of tail recursion,,Behind the curtain How does our code get optimized?
e250f0dc 3264@anchor{intro/tutorial04 optimizing-away-stack-manipulation}@anchor{46}
35485da9
DM
3265@subsubsection Optimizing away stack manipulation
3266
3267
6f7585de 3268Recall our simple implementation of stack operations. Let’s examine
35485da9
DM
3269how the stack operations are optimized away.
3270
3271After a pass of constant-propagation, the depth of the stack at each
3272opcode can be determined at compile-time:
3273
3274@example
3275$ less /tmp/libgccjit-1Hywc0/fake.c.021t.ccp1
3276@end example
3277
35485da9
DM
3278@example
3279;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
3280
3281factorial (signed int arg)
3282@{
3283 signed int stack[8];
3284 signed int stack_depth;
3285 signed int x;
3286 signed int y;
3287 <unnamed type> _20;
3288 signed int _21;
3289 signed int _38;
3290 signed int _44;
3291 signed int _51;
3292
3293initial:
3294 stack[0] = arg_5(D);
3295 x_9 = stack[0];
3296 stack[0] = x_9;
3297 stack[1] = x_9;
3298 stack[2] = 2;
3299 y_17 = stack[2];
3300 x_19 = stack[1];
3301 _20 = x_19 < y_17;
3302 _21 = (signed int) _20;
3303 stack[1] = _21;
3304 x_25 = stack[1];
3305 if (x_25 != 0)
3306 goto <bb 4> (instr9);
3307 else
3308 goto <bb 3> (instr4);
3309
3310instr4:
3311/* DUP */:
3312 x_27 = stack[0];
3313 stack[0] = x_27;
3314 stack[1] = x_27;
3315 stack[2] = 1;
3316 y_35 = stack[2];
3317 x_37 = stack[1];
3318 _38 = x_37 - y_35;
3319 stack[1] = _38;
3320 x_42 = stack[1];
3321 _44 = factorial (x_42);
3322 stack[1] = _44;
3323 y_48 = stack[1];
3324 x_50 = stack[0];
3325 _51 = x_50 * y_48;
3326 stack[0] = _51;
3327
3328instr9:
3329/* RETURN */:
3330 x_55 = stack[0];
3331 x_56 = x_55;
3332 stack =@{v@} @{CLOBBER@};
3333 return x_56;
3334
3335@}
3336@end example
3337
35485da9 3338Note how, in the above, all those @code{stack_depth} values are now just
6f7585de 3339constants: we’re accessing specific stack locations at each opcode.
35485da9 3340
6f7585de
DM
3341The “esra” pass (“Early Scalar Replacement of Aggregates”) breaks
3342out our “stack” array into individual elements:
35485da9
DM
3343
3344@example
3345$ less /tmp/libgccjit-1Hywc0/fake.c.024t.esra
3346@end example
3347
35485da9
DM
3348@example
3349;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
3350
3351Created a replacement for stack offset: 0, size: 32: stack$0
3352Created a replacement for stack offset: 32, size: 32: stack$1
3353Created a replacement for stack offset: 64, size: 32: stack$2
3354
3355Symbols to be put in SSA form
3356@{ D.89 D.90 D.91 @}
3357Incremental SSA update started at block: 0
3358Number of blocks in CFG: 5
3359Number of blocks to update: 4 ( 80%)
3360
3361
3362factorial (signed int arg)
3363@{
3364 signed int stack$2;
3365 signed int stack$1;
3366 signed int stack$0;
3367 signed int stack[8];
3368 signed int stack_depth;
3369 signed int x;
3370 signed int y;
3371 <unnamed type> _20;
3372 signed int _21;
3373 signed int _38;
3374 signed int _44;
3375 signed int _51;
3376
3377initial:
3378 stack$0_45 = arg_5(D);
3379 x_9 = stack$0_45;
3380 stack$0_39 = x_9;
3381 stack$1_32 = x_9;
3382 stack$2_30 = 2;
3383 y_17 = stack$2_30;
3384 x_19 = stack$1_32;
3385 _20 = x_19 < y_17;
3386 _21 = (signed int) _20;
3387 stack$1_28 = _21;
3388 x_25 = stack$1_28;
3389 if (x_25 != 0)
3390 goto <bb 4> (instr9);
3391 else
3392 goto <bb 3> (instr4);
3393
3394instr4:
3395/* DUP */:
3396 x_27 = stack$0_39;
3397 stack$0_22 = x_27;
3398 stack$1_14 = x_27;
3399 stack$2_12 = 1;
3400 y_35 = stack$2_12;
3401 x_37 = stack$1_14;
3402 _38 = x_37 - y_35;
3403 stack$1_10 = _38;
3404 x_42 = stack$1_10;
3405 _44 = factorial (x_42);
3406 stack$1_6 = _44;
3407 y_48 = stack$1_6;
3408 x_50 = stack$0_22;
3409 _51 = x_50 * y_48;
3410 stack$0_1 = _51;
3411
3412 # stack$0_52 = PHI <stack$0_39(2), stack$0_1(3)>
3413instr9:
3414/* RETURN */:
3415 x_55 = stack$0_52;
3416 x_56 = x_55;
3417 stack =@{v@} @{CLOBBER@};
3418 return x_56;
3419
3420@}
3421@end example
3422
35485da9
DM
3423Hence at this point, all those pushes and pops of the stack are now
3424simply assignments to specific temporary variables.
3425
3426After some copy propagation, the stack manipulation has been completely
3427optimized away:
3428
3429@example
3430$ less /tmp/libgccjit-1Hywc0/fake.c.026t.copyprop1
3431@end example
3432
35485da9
DM
3433@example
3434;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
3435
3436factorial (signed int arg)
3437@{
3438 signed int stack$2;
3439 signed int stack$1;
3440 signed int stack$0;
3441 signed int stack[8];
3442 signed int stack_depth;
3443 signed int x;
3444 signed int y;
3445 <unnamed type> _20;
3446 signed int _21;
3447 signed int _38;
3448 signed int _44;
3449 signed int _51;
3450
3451initial:
3452 stack$0_39 = arg_5(D);
3453 _20 = arg_5(D) <= 1;
3454 _21 = (signed int) _20;
3455 if (_21 != 0)
3456 goto <bb 4> (instr9);
3457 else
3458 goto <bb 3> (instr4);
3459
3460instr4:
3461/* DUP */:
3462 _38 = arg_5(D) + -1;
3463 _44 = factorial (_38);
3464 _51 = arg_5(D) * _44;
3465 stack$0_1 = _51;
3466
3467 # stack$0_52 = PHI <arg_5(D)(2), _51(3)>
3468instr9:
3469/* RETURN */:
3470 stack =@{v@} @{CLOBBER@};
3471 return stack$0_52;
3472
3473@}
3474@end example
3475
35485da9
DM
3476Later on, another pass finally eliminated @code{stack_depth} local and the
3477unused parts of the @cite{stack`} array altogether:
3478
3479@example
3480$ less /tmp/libgccjit-1Hywc0/fake.c.036t.release_ssa
3481@end example
3482
35485da9
DM
3483@example
3484;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
3485
3486Released 44 names, 314.29%, removed 44 holes
3487factorial (signed int arg)
3488@{
3489 signed int stack$0;
3490 signed int mult_acc_1;
3491 <unnamed type> _5;
3492 signed int _6;
3493 signed int _7;
3494 signed int mul_tmp_10;
3495 signed int mult_acc_11;
3496 signed int mult_acc_13;
3497
3498 # arg_9 = PHI <arg_8(D)(0)>
3499 # mult_acc_13 = PHI <1(0)>
3500initial:
3501
3502 <bb 5>:
3503 # arg_4 = PHI <arg_9(2), _7(3)>
3504 # mult_acc_1 = PHI <mult_acc_13(2), mult_acc_11(3)>
3505 _5 = arg_4 <= 1;
3506 _6 = (signed int) _5;
3507 if (_6 != 0)
3508 goto <bb 4> (instr9);
3509 else
3510 goto <bb 3> (instr4);
3511
3512instr4:
3513/* DUP */:
3514 _7 = arg_4 + -1;
3515 mult_acc_11 = mult_acc_1 * arg_4;
3516 goto <bb 5>;
3517
3518 # stack$0_12 = PHI <arg_4(5)>
3519instr9:
3520/* RETURN */:
3521 mul_tmp_10 = mult_acc_1 * stack$0_12;
3522 return mul_tmp_10;
3523
3524@}
3525@end example
3526
35485da9 3527@node Elimination of tail recursion,,Optimizing away stack manipulation,Behind the curtain How does our code get optimized?
e250f0dc 3528@anchor{intro/tutorial04 elimination-of-tail-recursion}@anchor{47}
35485da9
DM
3529@subsubsection Elimination of tail recursion
3530
3531
3532Another significant optimization is the detection that the call to
3533@code{factorial} is tail recursion, which can be eliminated in favor of
3534an iteration:
3535
3536@example
3537$ less /tmp/libgccjit-1Hywc0/fake.c.030t.tailr1
3538@end example
3539
35485da9
DM
3540@example
3541;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
3542
3543
3544Symbols to be put in SSA form
3545@{ D.88 @}
3546Incremental SSA update started at block: 0
3547Number of blocks in CFG: 5
3548Number of blocks to update: 4 ( 80%)
3549
3550
3551factorial (signed int arg)
3552@{
3553 signed int stack$2;
3554 signed int stack$1;
3555 signed int stack$0;
3556 signed int stack[8];
3557 signed int stack_depth;
3558 signed int x;
3559 signed int y;
3560 signed int mult_acc_1;
3561 <unnamed type> _20;
3562 signed int _21;
3563 signed int _38;
3564 signed int mul_tmp_44;
3565 signed int mult_acc_51;
3566
3567 # arg_5 = PHI <arg_39(D)(0), _38(3)>
3568 # mult_acc_1 = PHI <1(0), mult_acc_51(3)>
3569initial:
3570 _20 = arg_5 <= 1;
3571 _21 = (signed int) _20;
3572 if (_21 != 0)
3573 goto <bb 4> (instr9);
3574 else
3575 goto <bb 3> (instr4);
3576
3577instr4:
3578/* DUP */:
3579 _38 = arg_5 + -1;
3580 mult_acc_51 = mult_acc_1 * arg_5;
3581 goto <bb 2> (initial);
3582
3583 # stack$0_52 = PHI <arg_5(2)>
3584instr9:
3585/* RETURN */:
3586 stack =@{v@} @{CLOBBER@};
3587 mul_tmp_44 = mult_acc_1 * stack$0_52;
3588 return mul_tmp_44;
3589
3590@}
3591@end example
3592
7adcbafe 3593@c Copyright (C) 2015-2022 Free Software Foundation, Inc.
fdce7209
DM
3594@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
3595@c
3596@c This is free software: you can redistribute it and/or modify it
3597@c under the terms of the GNU General Public License as published by
3598@c the Free Software Foundation, either version 3 of the License, or
3599@c (at your option) any later version.
3600@c
3601@c This program is distributed in the hope that it will be useful, but
3602@c WITHOUT ANY WARRANTY; without even the implied warranty of
3603@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3604@c General Public License for more details.
3605@c
3606@c You should have received a copy of the GNU General Public License
3607@c along with this program. If not, see
786973ce 3608@c <https://www.gnu.org/licenses/>.
fdce7209
DM
3609
3610@node Tutorial part 5 Implementing an Ahead-of-Time compiler,,Tutorial part 4 Adding JIT-compilation to a toy interpreter,Tutorial
3611@anchor{intro/tutorial05 doc}@anchor{48}@anchor{intro/tutorial05 tutorial-part-5-implementing-an-ahead-of-time-compiler}@anchor{49}
3612@section Tutorial part 5: Implementing an Ahead-of-Time compiler
3613
3614
6f7585de
DM
3615If you have a pre-existing language frontend that’s compatible with
3616libgccjit’s license, it’s possible to hook it up to libgccjit as a
fdce7209
DM
3617backend. In the previous example we showed
3618how to do that for in-memory JIT-compilation, but libgccjit can also
3619compile code directly to a file, allowing you to implement a more
6f7585de 3620traditional ahead-of-time compiler (“JIT” is something of a misnomer
fdce7209
DM
3621for this use-case).
3622
3623The essential difference is to compile the context using
6f7585de
DM
3624@ref{4a,,gcc_jit_context_compile_to_file()} rather than
3625@ref{15,,gcc_jit_context_compile()}.
fdce7209
DM
3626
3627@menu
6f7585de 3628* The “brainf” language::
fdce7209
DM
3629* Converting a brainf script to libgccjit IR::
3630* Compiling a context to a file::
3631* Other forms of ahead-of-time-compilation::
3632
3633@end menu
3634
6f7585de 3635@node The “brainf” language,Converting a brainf script to libgccjit IR,,Tutorial part 5 Implementing an Ahead-of-Time compiler
fdce7209 3636@anchor{intro/tutorial05 the-brainf-language}@anchor{4b}
6f7585de 3637@subsection The “brainf” language
fdce7209
DM
3638
3639
3640In this example we use libgccjit to construct an ahead-of-time compiler
6f7585de 3641for an esoteric programming language that we shall refer to as “brainf”.
fdce7209
DM
3642
3643brainf scripts operate on an array of bytes, with a notional data pointer
3644within the array.
3645
6f7585de 3646brainf is hard for humans to read, but it’s trivial to write a parser for
fdce7209
DM
3647it, as there is no lexing; just a stream of bytes. The operations are:
3648
3649
3650@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
3651@headitem
3652
3653Character
3654
3655@tab
3656
3657Meaning
3658
3659@item
3660
3661@code{>}
3662
3663@tab
3664
3665@code{idx += 1}
3666
3667@item
3668
3669@code{<}
3670
3671@tab
3672
3673@code{idx -= 1}
3674
3675@item
3676
3677@code{+}
3678
3679@tab
3680
3681@code{data[idx] += 1}
3682
3683@item
3684
3685@code{-}
3686
3687@tab
3688
3689@code{data[idx] -= 1}
3690
3691@item
3692
3693@code{.}
3694
3695@tab
3696
3697@code{output (data[idx])}
3698
3699@item
3700
3701@code{,}
3702
3703@tab
3704
3705@code{data[idx] = input ()}
3706
3707@item
3708
3709@code{[}
3710
3711@tab
3712
3713loop until @code{data[idx] == 0}
3714
3715@item
3716
3717@code{]}
3718
3719@tab
3720
3721end of loop
3722
3723@item
3724
3725Anything else
3726
3727@tab
3728
3729ignored
3730
3731@end multitable
3732
3733
6f7585de 3734Unlike the previous example, we’ll implement an ahead-of-time compiler,
fdce7209
DM
3735which reads @code{.bf} scripts and outputs executables (though it would
3736be trivial to have it run them JIT-compiled in-process).
3737
6f7585de 3738Here’s what a simple @code{.bf} script looks like:
fdce7209
DM
3739
3740@quotation
3741
3742@example
3743[
3744 Emit the uppercase alphabet
3745]
3746
3747cell 0 = 26
3748++++++++++++++++++++++++++
3749
3750cell 1 = 65
3751>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
3752
3753while cell#0 != 0
3754[
3755 >
3756 . emit cell#1
3757 + increment cell@@1
3758 <- decrement cell@@0
3759]
fdce7209 3760@end example
fdce7209
DM
3761@end quotation
3762
3763@cartouche
3764@quotation Note
3765This example makes use of whitespace and comments for legibility, but
3766could have been written as:
3767
3768@example
3769++++++++++++++++++++++++++
3770>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
3771[>.+<-]
3772@end example
3773
6f7585de
DM
3774It’s not a particularly useful language, except for providing
3775compiler-writers with a test case that’s easy to parse. The point
3776is that you can use @ref{4a,,gcc_jit_context_compile_to_file()}
fdce7209 3777to use libgccjit as a backend for a pre-existing language frontend
6f7585de 3778(provided that the pre-existing frontend is compatible with libgccjit’s
fdce7209
DM
3779license).
3780@end quotation
3781@end cartouche
3782
6f7585de 3783@node Converting a brainf script to libgccjit IR,Compiling a context to a file,The “brainf” language,Tutorial part 5 Implementing an Ahead-of-Time compiler
fdce7209
DM
3784@anchor{intro/tutorial05 converting-a-brainf-script-to-libgccjit-ir}@anchor{4c}
3785@subsection Converting a brainf script to libgccjit IR
3786
3787
6f7585de 3788As before we write simple code to populate a @ref{8,,gcc_jit_context *}.
fdce7209
DM
3789
3790@quotation
3791
3792@example
3793
3794typedef struct bf_compiler
3795@{
3796 const char *filename;
3797 int line;
3798 int column;
3799
3800 gcc_jit_context *ctxt;
3801
3802 gcc_jit_type *void_type;
3803 gcc_jit_type *int_type;
3804 gcc_jit_type *byte_type;
3805 gcc_jit_type *array_type;
3806
3807 gcc_jit_function *func_getchar;
3808 gcc_jit_function *func_putchar;
3809
3810 gcc_jit_function *func;
3811 gcc_jit_block *curblock;
3812
3813 gcc_jit_rvalue *int_zero;
3814 gcc_jit_rvalue *int_one;
3815 gcc_jit_rvalue *byte_zero;
3816 gcc_jit_rvalue *byte_one;
3817 gcc_jit_lvalue *data_cells;
3818 gcc_jit_lvalue *idx;
3819
3820 int num_open_parens;
3821 gcc_jit_block *paren_test[MAX_OPEN_PARENS];
3822 gcc_jit_block *paren_body[MAX_OPEN_PARENS];
3823 gcc_jit_block *paren_after[MAX_OPEN_PARENS];
3824
3825@} bf_compiler;
3826
3827/* Bail out, with a message on stderr. */
3828
3829static void
3830fatal_error (bf_compiler *bfc, const char *msg)
3831@{
3832 fprintf (stderr,
3833 "%s:%i:%i: %s",
3834 bfc->filename, bfc->line, bfc->column, msg);
3835 abort ();
3836@}
3837
3838/* Get "data_cells[idx]" as an lvalue. */
3839
3840static gcc_jit_lvalue *
3841bf_get_current_data (bf_compiler *bfc, gcc_jit_location *loc)
3842@{
3843 return gcc_jit_context_new_array_access (
3844 bfc->ctxt,
3845 loc,
3846 gcc_jit_lvalue_as_rvalue (bfc->data_cells),
3847 gcc_jit_lvalue_as_rvalue (bfc->idx));
3848@}
3849
3850/* Get "data_cells[idx] == 0" as a boolean rvalue. */
3851
3852static gcc_jit_rvalue *
3853bf_current_data_is_zero (bf_compiler *bfc, gcc_jit_location *loc)
3854@{
3855 return gcc_jit_context_new_comparison (
3856 bfc->ctxt,
3857 loc,
3858 GCC_JIT_COMPARISON_EQ,
3859 gcc_jit_lvalue_as_rvalue (bf_get_current_data (bfc, loc)),
3860 bfc->byte_zero);
3861@}
3862
3863/* Compile one bf character. */
3864
3865static void
3866bf_compile_char (bf_compiler *bfc,
3867 unsigned char ch)
3868@{
3869 gcc_jit_location *loc =
3870 gcc_jit_context_new_location (bfc->ctxt,
3871 bfc->filename,
3872 bfc->line,
3873 bfc->column);
3874
3875 /* Turn this on to trace execution, by injecting putchar ()
3876 of each source char. */
3877 if (0)
3878 @{
3879 gcc_jit_rvalue *arg =
3880 gcc_jit_context_new_rvalue_from_int (
3881 bfc->ctxt,
3882 bfc->int_type,
3883 ch);
3884 gcc_jit_rvalue *call =
3885 gcc_jit_context_new_call (bfc->ctxt,
3886 loc,
3887 bfc->func_putchar,
3888 1, &arg);
3889 gcc_jit_block_add_eval (bfc->curblock,
3890 loc,
3891 call);
3892 @}
3893
3894 switch (ch)
3895 @{
3896 case '>':
3897 gcc_jit_block_add_comment (bfc->curblock,
3898 loc,
3899 "'>': idx += 1;");
3900 gcc_jit_block_add_assignment_op (bfc->curblock,
3901 loc,
3902 bfc->idx,
3903 GCC_JIT_BINARY_OP_PLUS,
3904 bfc->int_one);
3905 break;
3906
3907 case '<':
3908 gcc_jit_block_add_comment (bfc->curblock,
3909 loc,
3910 "'<': idx -= 1;");
3911 gcc_jit_block_add_assignment_op (bfc->curblock,
3912 loc,
3913 bfc->idx,
3914 GCC_JIT_BINARY_OP_MINUS,
3915 bfc->int_one);
3916 break;
3917
3918 case '+':
3919 gcc_jit_block_add_comment (bfc->curblock,
3920 loc,
3921 "'+': data[idx] += 1;");
3922 gcc_jit_block_add_assignment_op (bfc->curblock,
3923 loc,
3924 bf_get_current_data (bfc, loc),
3925 GCC_JIT_BINARY_OP_PLUS,
3926 bfc->byte_one);
3927 break;
3928
3929 case '-':
3930 gcc_jit_block_add_comment (bfc->curblock,
3931 loc,
3932 "'-': data[idx] -= 1;");
3933 gcc_jit_block_add_assignment_op (bfc->curblock,
3934 loc,
3935 bf_get_current_data (bfc, loc),
3936 GCC_JIT_BINARY_OP_MINUS,
3937 bfc->byte_one);
3938 break;
3939
3940 case '.':
3941 @{
3942 gcc_jit_rvalue *arg =
3943 gcc_jit_context_new_cast (
3944 bfc->ctxt,
3945 loc,
3946 gcc_jit_lvalue_as_rvalue (bf_get_current_data (bfc, loc)),
3947 bfc->int_type);
3948 gcc_jit_rvalue *call =
3949 gcc_jit_context_new_call (bfc->ctxt,
3950 loc,
3951 bfc->func_putchar,
3952 1, &arg);
3953 gcc_jit_block_add_comment (bfc->curblock,
3954 loc,
3955 "'.': putchar ((int)data[idx]);");
3956 gcc_jit_block_add_eval (bfc->curblock,
3957 loc,
3958 call);
3959 @}
3960 break;
3961
3962 case ',':
3963 @{
3964 gcc_jit_rvalue *call =
3965 gcc_jit_context_new_call (bfc->ctxt,
3966 loc,
3967 bfc->func_getchar,
3968 0, NULL);
3969 gcc_jit_block_add_comment (
3970 bfc->curblock,
3971 loc,
3972 "',': data[idx] = (unsigned char)getchar ();");
3973 gcc_jit_block_add_assignment (bfc->curblock,
3974 loc,
3975 bf_get_current_data (bfc, loc),
3976 gcc_jit_context_new_cast (
3977 bfc->ctxt,
3978 loc,
3979 call,
3980 bfc->byte_type));
3981 @}
3982 break;
3983
3984 case '[':
3985 @{
3986 gcc_jit_block *loop_test =
3987 gcc_jit_function_new_block (bfc->func, NULL);
3988 gcc_jit_block *on_zero =
3989 gcc_jit_function_new_block (bfc->func, NULL);
3990 gcc_jit_block *on_non_zero =
3991 gcc_jit_function_new_block (bfc->func, NULL);
3992
3993 if (bfc->num_open_parens == MAX_OPEN_PARENS)
3994 fatal_error (bfc, "too many open parens");
3995
3996 gcc_jit_block_end_with_jump (
3997 bfc->curblock,
3998 loc,
3999 loop_test);
4000
4001 gcc_jit_block_add_comment (
4002 loop_test,
4003 loc,
4004 "'['");
4005 gcc_jit_block_end_with_conditional (
4006 loop_test,
4007 loc,
4008 bf_current_data_is_zero (bfc, loc),
4009 on_zero,
4010 on_non_zero);
4011 bfc->paren_test[bfc->num_open_parens] = loop_test;
4012 bfc->paren_body[bfc->num_open_parens] = on_non_zero;
4013 bfc->paren_after[bfc->num_open_parens] = on_zero;
4014 bfc->num_open_parens += 1;
4015 bfc->curblock = on_non_zero;
4016 @}
4017 break;
4018
4019 case ']':
4020 @{
4021 gcc_jit_block_add_comment (
4022 bfc->curblock,
4023 loc,
4024 "']'");
4025
4026 if (bfc->num_open_parens == 0)
4027 fatal_error (bfc, "mismatching parens");
4028 bfc->num_open_parens -= 1;
4029 gcc_jit_block_end_with_jump (
4030 bfc->curblock,
4031 loc,
4032 bfc->paren_test[bfc->num_open_parens]);
4033 bfc->curblock = bfc->paren_after[bfc->num_open_parens];
4034 @}
4035 break;
4036
4037 case '\n':
4038 bfc->line +=1;
4039 bfc->column = 0;
4040 break;
4041 @}
4042
4043 if (ch != '\n')
4044 bfc->column += 1;
4045@}
4046
4047/* Compile the given .bf file into a gcc_jit_context, containing a
4048 single "main" function suitable for compiling into an executable. */
4049
4050gcc_jit_context *
4051bf_compile (const char *filename)
4052@{
4053 bf_compiler bfc;
4054 FILE *f_in;
4055 int ch;
4056
4057 memset (&bfc, 0, sizeof (bfc));
4058
4059 bfc.filename = filename;
4060 f_in = fopen (filename, "r");
4061 if (!f_in)
4062 fatal_error (&bfc, "unable to open file");
4063 bfc.line = 1;
4064
4065 bfc.ctxt = gcc_jit_context_acquire ();
4066
4067 gcc_jit_context_set_int_option (
4068 bfc.ctxt,
4069 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
4070 3);
4071 gcc_jit_context_set_bool_option (
4072 bfc.ctxt,
4073 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE,
4074 0);
4075 gcc_jit_context_set_bool_option (
4076 bfc.ctxt,
4077 GCC_JIT_BOOL_OPTION_DEBUGINFO,
4078 1);
4079 gcc_jit_context_set_bool_option (
4080 bfc.ctxt,
4081 GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING,
4082 0);
4083 gcc_jit_context_set_bool_option (
4084 bfc.ctxt,
4085 GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES,
4086 0);
4087
4088 bfc.void_type =
4089 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_VOID);
4090 bfc.int_type =
4091 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_INT);
4092 bfc.byte_type =
4093 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_UNSIGNED_CHAR);
4094 bfc.array_type =
4095 gcc_jit_context_new_array_type (bfc.ctxt,
4096 NULL,
4097 bfc.byte_type,
4098 30000);
4099
4100 bfc.func_getchar =
4101 gcc_jit_context_new_function (bfc.ctxt, NULL,
4102 GCC_JIT_FUNCTION_IMPORTED,
4103 bfc.int_type,
4104 "getchar",
4105 0, NULL,
4106 0);
4107
4108 gcc_jit_param *param_c =
4109 gcc_jit_context_new_param (bfc.ctxt, NULL, bfc.int_type, "c");
4110 bfc.func_putchar =
4111 gcc_jit_context_new_function (bfc.ctxt, NULL,
4112 GCC_JIT_FUNCTION_IMPORTED,
4113 bfc.void_type,
4114 "putchar",
4115 1, &param_c,
4116 0);
4117
4118 bfc.func = make_main (bfc.ctxt);
4119 bfc.curblock =
4120 gcc_jit_function_new_block (bfc.func, "initial");
4121 bfc.int_zero = gcc_jit_context_zero (bfc.ctxt, bfc.int_type);
4122 bfc.int_one = gcc_jit_context_one (bfc.ctxt, bfc.int_type);
4123 bfc.byte_zero = gcc_jit_context_zero (bfc.ctxt, bfc.byte_type);
4124 bfc.byte_one = gcc_jit_context_one (bfc.ctxt, bfc.byte_type);
4125
4126 bfc.data_cells =
4127 gcc_jit_context_new_global (bfc.ctxt, NULL,
4128 GCC_JIT_GLOBAL_INTERNAL,
4129 bfc.array_type,
4130 "data_cells");
4131 bfc.idx =
4132 gcc_jit_function_new_local (bfc.func, NULL,
4133 bfc.int_type,
4134 "idx");
4135
4136 gcc_jit_block_add_comment (bfc.curblock,
4137 NULL,
4138 "idx = 0;");
4139 gcc_jit_block_add_assignment (bfc.curblock,
4140 NULL,
4141 bfc.idx,
4142 bfc.int_zero);
4143
4144 bfc.num_open_parens = 0;
4145
4146 while ( EOF != (ch = fgetc (f_in)))
4147 bf_compile_char (&bfc, (unsigned char)ch);
4148
4149 gcc_jit_block_end_with_return (bfc.curblock, NULL, bfc.int_zero);
4150
4151 fclose (f_in);
4152
4153 return bfc.ctxt;
4154@}
4155
fdce7209 4156@end example
fdce7209
DM
4157@end quotation
4158
4159@node Compiling a context to a file,Other forms of ahead-of-time-compilation,Converting a brainf script to libgccjit IR,Tutorial part 5 Implementing an Ahead-of-Time compiler
4160@anchor{intro/tutorial05 compiling-a-context-to-a-file}@anchor{4d}
4161@subsection Compiling a context to a file
4162
4163
6f7585de
DM
4164Unlike the previous tutorial, this time we’ll compile the context
4165directly to an executable, using @ref{4a,,gcc_jit_context_compile_to_file()}:
fdce7209
DM
4166
4167@example
4168gcc_jit_context_compile_to_file (ctxt,
4169 GCC_JIT_OUTPUT_KIND_EXECUTABLE,
4170 output_file);
4171@end example
4172
6f7585de
DM
4173Here’s the top-level of the compiler, which is what actually calls into
4174@ref{4a,,gcc_jit_context_compile_to_file()}:
fdce7209
DM
4175
4176@quotation
4177
4178@example
4179
4180int
4181main (int argc, char **argv)
4182@{
4183 const char *input_file;
4184 const char *output_file;
4185 gcc_jit_context *ctxt;
4186 const char *err;
4187
4188 if (argc != 3)
4189 @{
4190 fprintf (stderr, "%s: INPUT_FILE OUTPUT_FILE\n", argv[0]);
4191 return 1;
4192 @}
4193
4194 input_file = argv[1];
4195 output_file = argv[2];
4196 ctxt = bf_compile (input_file);
4197
4198 gcc_jit_context_compile_to_file (ctxt,
4199 GCC_JIT_OUTPUT_KIND_EXECUTABLE,
4200 output_file);
4201
4202 err = gcc_jit_context_get_first_error (ctxt);
4203
4204 if (err)
4205 @{
4206 gcc_jit_context_release (ctxt);
4207 return 1;
4208 @}
4209
4210 gcc_jit_context_release (ctxt);
4211 return 0;
4212@}
4213
fdce7209 4214@end example
fdce7209
DM
4215@end quotation
4216
4217Note how once the context is populated you could trivially instead compile
6f7585de 4218it to memory using @ref{15,,gcc_jit_context_compile()} and run it in-process
fdce7209
DM
4219as in the previous tutorial.
4220
6f7585de 4221To create an executable, we need to export a @code{main} function. Here’s
fdce7209
DM
4222how to create one from the JIT API:
4223
4224@quotation
4225
4226@example
4227
4228/* Make "main" function:
4229 int
4230 main (int argc, char **argv)
4231 @{
4232 ...
4233 @}
4234*/
4235static gcc_jit_function *
4236make_main (gcc_jit_context *ctxt)
4237@{
4238 gcc_jit_type *int_type =
4239 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
4240 gcc_jit_param *param_argc =
4241 gcc_jit_context_new_param (ctxt, NULL, int_type, "argc");
4242 gcc_jit_type *char_ptr_ptr_type =
4243 gcc_jit_type_get_pointer (
4244 gcc_jit_type_get_pointer (
4245 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR)));
4246 gcc_jit_param *param_argv =
4247 gcc_jit_context_new_param (ctxt, NULL, char_ptr_ptr_type, "argv");
4248 gcc_jit_param *params[2] = @{param_argc, param_argv@};
4249 gcc_jit_function *func_main =
4250 gcc_jit_context_new_function (ctxt, NULL,
4251 GCC_JIT_FUNCTION_EXPORTED,
4252 int_type,
4253 "main",
4254 2, params,
4255 0);
4256 return func_main;
4257@}
4258
fdce7209 4259@end example
fdce7209
DM
4260@end quotation
4261
4262@cartouche
4263@quotation Note
4264The above implementation ignores @code{argc} and @code{argv}, but you could
4265make use of them by exposing @code{param_argc} and @code{param_argv} to the
4266caller.
4267@end quotation
4268@end cartouche
4269
4270Upon compiling this C code, we obtain a bf-to-machine-code compiler;
6f7585de 4271let’s call it @code{bfc}:
fdce7209
DM
4272
4273@example
4274$ gcc \
4275 tut05-bf.c \
4276 -o bfc \
4277 -lgccjit
4278@end example
4279
fdce7209
DM
4280We can now use @code{bfc} to compile .bf files into machine code executables:
4281
4282@example
4283$ ./bfc \
4284 emit-alphabet.bf \
4285 a.out
4286@end example
4287
fdce7209
DM
4288which we can run directly:
4289
4290@example
4291$ ./a.out
4292ABCDEFGHIJKLMNOPQRSTUVWXYZ
4293@end example
4294
fdce7209
DM
4295Success!
4296
4297We can also inspect the generated executable using standard tools:
4298
4299@example
4300$ objdump -d a.out |less
4301@end example
4302
fdce7209
DM
4303which shows that libgccjit has managed to optimize the function
4304somewhat (for example, the runs of 26 and 65 increment operations
4305have become integer constants 0x1a and 0x41):
4306
4307@example
43080000000000400620 <main>:
4309 400620: 80 3d 39 0a 20 00 00 cmpb $0x0,0x200a39(%rip) # 601060 <data
4310 400627: 74 07 je 400630 <main
4311 400629: eb fe jmp 400629 <main+0x9>
4312 40062b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
4313 400630: 48 83 ec 08 sub $0x8,%rsp
4314 400634: 0f b6 05 26 0a 20 00 movzbl 0x200a26(%rip),%eax # 601061 <data_cells+0x1>
4315 40063b: c6 05 1e 0a 20 00 1a movb $0x1a,0x200a1e(%rip) # 601060 <data_cells>
4316 400642: 8d 78 41 lea 0x41(%rax),%edi
4317 400645: 40 88 3d 15 0a 20 00 mov %dil,0x200a15(%rip) # 601061 <data_cells+0x1>
4318 40064c: 0f 1f 40 00 nopl 0x0(%rax)
4319 400650: 40 0f b6 ff movzbl %dil,%edi
4320 400654: e8 87 fe ff ff callq 4004e0 <putchar@@plt>
4321 400659: 0f b6 05 01 0a 20 00 movzbl 0x200a01(%rip),%eax # 601061 <data_cells+0x1>
4322 400660: 80 2d f9 09 20 00 01 subb $0x1,0x2009f9(%rip) # 601060 <data_cells>
4323 400667: 8d 78 01 lea 0x1(%rax),%edi
4324 40066a: 40 88 3d f0 09 20 00 mov %dil,0x2009f0(%rip) # 601061 <data_cells+0x1>
4325 400671: 75 dd jne 400650 <main+0x30>
4326 400673: 31 c0 xor %eax,%eax
4327 400675: 48 83 c4 08 add $0x8,%rsp
4328 400679: c3 retq
4329 40067a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
4330@end example
4331
fdce7209 4332We also set up debugging information (via
6f7585de
DM
4333@ref{41,,gcc_jit_context_new_location()} and
4334@ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO}), so it’s possible to use @code{gdb}
fdce7209
DM
4335to singlestep through the generated binary and inspect the internal
4336state @code{idx} and @code{data_cells}:
4337
4338@example
4339(gdb) break main
4340Breakpoint 1 at 0x400790
4341(gdb) run
4342Starting program: a.out
4343
4344Breakpoint 1, 0x0000000000400790 in main (argc=1, argv=0x7fffffffe448)
4345(gdb) stepi
43460x0000000000400797 in main (argc=1, argv=0x7fffffffe448)
4347(gdb) stepi
43480x00000000004007a0 in main (argc=1, argv=0x7fffffffe448)
4349(gdb) stepi
43509 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
4351(gdb) list
43524
43535 cell 0 = 26
43546 ++++++++++++++++++++++++++
43557
43568 cell 1 = 65
43579 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
435810
435911 while cell#0 != 0
436012 [
436113 >
4362(gdb) n
43636 ++++++++++++++++++++++++++
4364(gdb) n
43659 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
4366(gdb) p idx
4367$1 = 1
4368(gdb) p data_cells
4369$2 = "\032", '\000' <repeats 29998 times>
4370(gdb) p data_cells[0]
4371$3 = 26 '\032'
4372(gdb) p data_cells[1]
4373$4 = 0 '\000'
4374(gdb) list
43754
43765 cell 0 = 26
43776 ++++++++++++++++++++++++++
43787
43798 cell 1 = 65
43809 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
438110
438211 while cell#0 != 0
438312 [
438413 >
4385@end example
4386
fdce7209
DM
4387@node Other forms of ahead-of-time-compilation,,Compiling a context to a file,Tutorial part 5 Implementing an Ahead-of-Time compiler
4388@anchor{intro/tutorial05 other-forms-of-ahead-of-time-compilation}@anchor{4e}
4389@subsection Other forms of ahead-of-time-compilation
4390
4391
6f7585de
DM
4392The above demonstrates compiling a @ref{8,,gcc_jit_context *} directly
4393to an executable. It’s also possible to compile it to an object file,
fdce7209 4394and to a dynamic library. See the documentation of
6f7585de 4395@ref{4a,,gcc_jit_context_compile_to_file()} for more information.
fdce7209 4396
7adcbafe 4397@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
4398@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
4399@c
4400@c This is free software: you can redistribute it and/or modify it
4401@c under the terms of the GNU General Public License as published by
4402@c the Free Software Foundation, either version 3 of the License, or
4403@c (at your option) any later version.
4404@c
4405@c This program is distributed in the hope that it will be useful, but
4406@c WITHOUT ANY WARRANTY; without even the implied warranty of
4407@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4408@c General Public License for more details.
4409@c
4410@c You should have received a copy of the GNU General Public License
4411@c along with this program. If not, see
786973ce 4412@c <https://www.gnu.org/licenses/>.
35485da9 4413
29df5715 4414@node Topic Reference,C++ bindings for libgccjit,Tutorial,Top
fdce7209 4415@anchor{topics/index doc}@anchor{4f}@anchor{topics/index topic-reference}@anchor{50}
35485da9
DM
4416@chapter Topic Reference
4417
4418
7adcbafe 4419@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
4420@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
4421@c
4422@c This is free software: you can redistribute it and/or modify it
4423@c under the terms of the GNU General Public License as published by
4424@c the Free Software Foundation, either version 3 of the License, or
4425@c (at your option) any later version.
4426@c
4427@c This program is distributed in the hope that it will be useful, but
4428@c WITHOUT ANY WARRANTY; without even the implied warranty of
4429@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4430@c General Public License for more details.
4431@c
4432@c You should have received a copy of the GNU General Public License
4433@c along with this program. If not, see
786973ce 4434@c <https://www.gnu.org/licenses/>.
35485da9
DM
4435
4436@menu
4437* Compilation contexts::
4438* Objects::
4439* Types::
4440* Expressions::
4441* Creating and using functions::
ecd5156d 4442* Function pointers: Function pointers<2>.
35485da9 4443* Source Locations::
fdce7209 4444* Compiling a context::
fa22c20d 4445* ABI and API compatibility::
afed3459 4446* Performance::
421d0d0f 4447* Using Assembly Language with libgccjit::
35485da9 4448
6f7585de
DM
4449@end menu
4450
4451@node Compilation contexts,Objects,,Topic Reference
421d0d0f 4452@anchor{topics/contexts doc}@anchor{51}@anchor{topics/contexts compilation-contexts}@anchor{52}
6f7585de 4453@section Compilation contexts
35485da9 4454
6f7585de
DM
4455
4456@geindex gcc_jit_context (C type)
4457@anchor{topics/contexts c gcc_jit_context}@anchor{8}
4458@deffn {C Type} gcc_jit_context
4459@end deffn
4460
4461The top-level of the API is the @ref{8,,gcc_jit_context} type.
4462
4463A @ref{8,,gcc_jit_context} instance encapsulates the state of a
4464compilation.
4465
4466You can set up options on it, and add types, functions and code.
4467Invoking @ref{15,,gcc_jit_context_compile()} on it gives you a
4468@ref{16,,gcc_jit_result}.
4469
4470@menu
35485da9
DM
4471* Lifetime-management::
4472* Thread-safety::
e250f0dc 4473* Error-handling: Error-handling<2>.
35485da9
DM
4474* Debugging::
4475* Options: Options<2>.
4476
6f7585de 4477@end menu
35485da9 4478
6f7585de
DM
4479@node Lifetime-management,Thread-safety,,Compilation contexts
4480@anchor{topics/contexts lifetime-management}@anchor{53}
4481@subsection Lifetime-management
35485da9 4482
35485da9 4483
6f7585de
DM
4484Contexts are the unit of lifetime-management within the API: objects
4485have their lifetime bounded by the context they are created within, and
4486cleanup of such objects is done for you when the context is released.
35485da9 4487
6f7585de
DM
4488@geindex gcc_jit_context_acquire (C function)
4489@anchor{topics/contexts c gcc_jit_context_acquire}@anchor{9}
4490@deffn {C Function} gcc_jit_context *gcc_jit_context_acquire (void)
35485da9 4491
6f7585de 4492This function acquires a new @ref{8,,gcc_jit_context *} instance,
35485da9
DM
4493which is independent of any others that may be present within this
4494process.
4495@end deffn
4496
4497@geindex gcc_jit_context_release (C function)
6f7585de 4498@anchor{topics/contexts c gcc_jit_context_release}@anchor{c}
35485da9
DM
4499@deffn {C Function} void gcc_jit_context_release (gcc_jit_context@w{ }*ctxt)
4500
4501This function releases all resources associated with the given context.
6f7585de 4502Both the context itself and all of its @ref{e,,gcc_jit_object *}
35485da9
DM
4503instances are cleaned up. It should be called exactly once on a given
4504context.
4505
6f7585de 4506It is invalid to use the context or any of its “contextual” objects
35485da9
DM
4507after calling this.
4508
4509@example
4510gcc_jit_context_release (ctxt);
4511@end example
35485da9
DM
4512@end deffn
4513
4514@geindex gcc_jit_context_new_child_context (C function)
6f7585de 4515@anchor{topics/contexts c gcc_jit_context_new_child_context}@anchor{54}
35485da9
DM
4516@deffn {C Function} gcc_jit_context * gcc_jit_context_new_child_context (gcc_jit_context@w{ }*parent_ctxt)
4517
4518Given an existing JIT context, create a child context.
4519
4520The child inherits a copy of all option-settings from the parent.
4521
4522The child can reference objects created within the parent, but not
4523vice-versa.
4524
4525The lifetime of the child context must be bounded by that of the
4526parent: you should release a child context before releasing the parent
4527context.
4528
4529If you use a function from a parent context within a child context,
4530you have to compile the parent context before you can compile the
4531child context, and the gcc_jit_result of the parent context must
4532outlive the gcc_jit_result of the child context.
4533
4534This allows caching of shared initializations. For example, you could
4535create types and declarations of global functions in a parent context
4536once within a process, and then create child contexts whenever a
4537function or loop becomes hot. Each such child context can be used for
4538JIT-compiling just one function or loop, but can reference types
4539and helper functions created within the parent context.
4540
4541Contexts can be arbitrarily nested, provided the above rules are
6f7585de 4542followed, but it’s probably not worth going above 2 or 3 levels, and
35485da9
DM
4543there will likely be a performance hit for such nesting.
4544@end deffn
4545
e250f0dc 4546@node Thread-safety,Error-handling<2>,Lifetime-management,Compilation contexts
fdce7209 4547@anchor{topics/contexts thread-safety}@anchor{55}
35485da9
DM
4548@subsection Thread-safety
4549
4550
6f7585de
DM
4551Instances of @ref{8,,gcc_jit_context *} created via
4552@ref{9,,gcc_jit_context_acquire()} are independent from each other:
35485da9
DM
4553only one thread may use a given context at once, but multiple threads
4554could each have their own contexts without needing locks.
4555
6f7585de 4556Contexts created via @ref{54,,gcc_jit_context_new_child_context()} are
35485da9 4557related to their parent context. They can be partitioned by their
6f7585de
DM
4558ultimate ancestor into independent “family trees”. Only one thread
4559within a process may use a given “family tree” of such contexts at once,
4560and if you’re using multiple threads you should provide your own locking
35485da9
DM
4561around entire such context partitions.
4562
e250f0dc 4563@node Error-handling<2>,Debugging,Thread-safety,Compilation contexts
fdce7209 4564@anchor{topics/contexts error-handling}@anchor{19}@anchor{topics/contexts id1}@anchor{56}
35485da9
DM
4565@subsection Error-handling
4566
4567
e250f0dc
DM
4568Various kinds of errors are possible when using the API, such as
4569mismatched types in an assignment. You can only compile and get code from
4570a context if no errors occur.
35485da9
DM
4571
4572Errors are printed on stderr and can be queried using
6f7585de 4573@ref{57,,gcc_jit_context_get_first_error()}.
e250f0dc
DM
4574
4575They typically contain the name of the API entrypoint where the error
4576occurred, and pertinent information on the problem:
4577
4578@example
4579./buggy-program: error: gcc_jit_block_add_assignment: mismatching types: assignment to i (type: int) from "hello world" (type: const char *)
4580@end example
4581
e250f0dc 4582In general, if an error occurs when using an API entrypoint, the
6f7585de 4583entrypoint returns NULL. You don’t have to check everywhere for NULL
e250f0dc
DM
4584results, since the API handles a NULL being passed in for any
4585argument by issuing another error. This typically leads to a cascade of
303e1d56
DM
4586followup error messages, but is safe (albeit verbose). The first error
4587message is usually the one to pay attention to, since it is likely to
4588be responsible for all of the rest:
35485da9
DM
4589
4590@geindex gcc_jit_context_get_first_error (C function)
6f7585de 4591@anchor{topics/contexts c gcc_jit_context_get_first_error}@anchor{57}
35485da9
DM
4592@deffn {C Function} const char * gcc_jit_context_get_first_error (gcc_jit_context@w{ }*ctxt)
4593
4594Returns the first error message that occurred on the context.
4595
4596The returned string is valid for the rest of the lifetime of the
4597context.
4598
4599If no errors occurred, this will be NULL.
4600@end deffn
4601
303e1d56 4602If you are wrapping the C API for a higher-level language that supports
7ef96183 4603exception-handling, you may instead be interested in the last error that
303e1d56
DM
4604occurred on the context, so that you can embed this in an exception:
4605
4606@geindex gcc_jit_context_get_last_error (C function)
6f7585de 4607@anchor{topics/contexts c gcc_jit_context_get_last_error}@anchor{58}
303e1d56
DM
4608@deffn {C Function} const char * gcc_jit_context_get_last_error (gcc_jit_context@w{ }*ctxt)
4609
4610Returns the last error message that occurred on the context.
4611
303e1d56 4612If no errors occurred, this will be NULL.
dc44ee3a
DM
4613
4614If non-NULL, the returned string is only guaranteed to be valid until
4615the next call to libgccjit relating to this context.
303e1d56
DM
4616@end deffn
4617
e250f0dc 4618@node Debugging,Options<2>,Error-handling<2>,Compilation contexts
fdce7209 4619@anchor{topics/contexts debugging}@anchor{59}
35485da9
DM
4620@subsection Debugging
4621
4622
4623@geindex gcc_jit_context_dump_to_file (C function)
6f7585de 4624@anchor{topics/contexts c gcc_jit_context_dump_to_file}@anchor{5a}
35485da9
DM
4625@deffn {C Function} void gcc_jit_context_dump_to_file (gcc_jit_context@w{ }*ctxt, const char@w{ }*path, int@w{ }update_locations)
4626
4627To help with debugging: dump a C-like representation to the given path,
6f7585de 4628describing what’s been set up on the context.
35485da9 4629
6f7585de 4630If “update_locations” is true, then also set up @ref{3b,,gcc_jit_location}
35485da9
DM
4631information throughout the context, pointing at the dump file as if it
4632were a source file. This may be of use in conjunction with
6f7585de 4633@ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to allow stepping through the
35485da9
DM
4634code in a debugger.
4635@end deffn
4636
eb4c16eb 4637@geindex gcc_jit_context_set_logfile (C function)
6f7585de 4638@anchor{topics/contexts c gcc_jit_context_set_logfile}@anchor{5b}
eb4c16eb
DM
4639@deffn {C Function} void gcc_jit_context_set_logfile (gcc_jit_context@w{ }*ctxt, FILE@w{ }*logfile, int@w{ }flags, int@w{ }verbosity)
4640
6f7585de 4641To help with debugging; enable ongoing logging of the context’s
eb4c16eb
DM
4642activity to the given file.
4643
4644For example, the following will enable logging to stderr.
4645
4646@example
4647gcc_jit_context_set_logfile (ctxt, stderr, 0, 0);
4648@end example
4649
eb4c16eb
DM
4650Examples of information logged include:
4651
4652
4653@itemize *
4654
4655@item
4656API calls
4657
4658@item
4659the various steps involved within compilation
4660
4661@item
6f7585de 4662activity on any @ref{16,,gcc_jit_result} instances created by
eb4c16eb
DM
4663the context
4664
4665@item
4666activity within any child contexts
4667@end itemize
4668
6f7585de 4669An example of a log can be seen @ref{5c,,here},
eb4c16eb
DM
4670though the precise format and kinds of information logged is subject
4671to change.
4672
4673The caller remains responsible for closing @cite{logfile}, and it must not
4674be closed until all users are released. In particular, note that
6f7585de 4675child contexts and @ref{16,,gcc_jit_result} instances created by
eb4c16eb
DM
4676the context will use the logfile.
4677
4678There may a performance cost for logging.
4679
4680You can turn off logging on @cite{ctxt} by passing @cite{NULL} for @cite{logfile}.
4681Doing so only affects the context; it does not affect child contexts
6f7585de 4682or @ref{16,,gcc_jit_result} instances already created by
eb4c16eb
DM
4683the context.
4684
6f7585de 4685The parameters “flags” and “verbosity” are reserved for future
eb4c16eb
DM
4686expansion, and must be zero for now.
4687@end deffn
4688
6f7585de 4689To contrast the above: @ref{5a,,gcc_jit_context_dump_to_file()} dumps the
eb4c16eb 4690current state of a context to the given path, whereas
6f7585de 4691@ref{5b,,gcc_jit_context_set_logfile()} enables on-going logging of
eb4c16eb
DM
4692future activies on a context to the given @cite{FILE *}.
4693
86d0ac88 4694@geindex gcc_jit_context_dump_reproducer_to_file (C function)
6f7585de 4695@anchor{topics/contexts c gcc_jit_context_dump_reproducer_to_file}@anchor{5d}
86d0ac88
DM
4696@deffn {C Function} void gcc_jit_context_dump_reproducer_to_file (gcc_jit_context@w{ }*ctxt, const char@w{ }*path)
4697
4698Write C source code into @cite{path} that can be compiled into a
4699self-contained executable (i.e. with libgccjit as the only dependency).
4700The generated code will attempt to replay the API calls that have been
4701made into the given context.
4702
4703This may be useful when debugging the library or client code, for
4704reducing a complicated recipe for reproducing a bug into a simpler
4705form. For example, consider client code that parses some source file
4706into some internal representation, and then walks this IR, calling into
4707libgccjit. If this encounters a bug, a call to
4708@cite{gcc_jit_context_dump_reproducer_to_file} will write out C code for
4709a much simpler executable that performs the equivalent calls into
4710libgccjit, without needing the client code and its data.
4711
4712Typically you need to supply @code{-Wno-unused-variable} when
4713compiling the generated file (since the result of each API call is
4714assigned to a unique variable within the generated C source, and not
4715all are necessarily then used).
4716@end deffn
4717
463366a0 4718@geindex gcc_jit_context_enable_dump (C function)
6f7585de 4719@anchor{topics/contexts c gcc_jit_context_enable_dump}@anchor{5e}
463366a0
DM
4720@deffn {C Function} void gcc_jit_context_enable_dump (gcc_jit_context@w{ }*ctxt, const char@w{ }*dumpname, char@w{ }**out_ptr)
4721
4722Enable the dumping of a specific set of internal state from the
4723compilation, capturing the result in-memory as a buffer.
4724
6f7585de
DM
4725Parameter “dumpname” corresponds to the equivalent gcc command-line
4726option, without the “-fdump-” prefix.
463366a0
DM
4727For example, to get the equivalent of @code{-fdump-tree-vrp1},
4728supply @code{"tree-vrp1"}:
4729
4730@example
4731static char *dump_vrp1;
4732
4733void
4734create_code (gcc_jit_context *ctxt)
4735@{
4736 gcc_jit_context_enable_dump (ctxt, "tree-vrp1", &dump_vrp1);
4737 /* (other API calls omitted for brevity) */
4738@}
4739@end example
4740
463366a0
DM
4741The context directly stores the dumpname as a @code{(const char *)}, so
4742the passed string must outlive the context.
4743
6f7585de 4744@ref{15,,gcc_jit_context_compile()} will capture the dump as a
463366a0
DM
4745dynamically-allocated buffer, writing it to @code{*out_ptr}.
4746
4747The caller becomes responsible for calling:
4748
4749@example
4750free (*out_ptr)
4751@end example
4752
6f7585de 4753each time that @ref{15,,gcc_jit_context_compile()} is called.
463366a0
DM
4754@code{*out_ptr} will be written to, either with the address of a buffer,
4755or with @code{NULL} if an error occurred.
4756
4757@cartouche
4758@quotation Warning
4759This API entrypoint is likely to be less stable than the others.
4760In particular, both the precise dumpnames, and the format and content
4761of the dumps are subject to change.
4762
6f7585de 4763It exists primarily for writing the library’s own test suite.
463366a0
DM
4764@end quotation
4765@end cartouche
4766@end deffn
4767
35485da9 4768@node Options<2>,,Debugging,Compilation contexts
fdce7209 4769@anchor{topics/contexts options}@anchor{5f}
35485da9
DM
4770@subsection Options
4771
4772
6a3603e3
DM
4773Options present in the initial release of libgccjit were handled using
4774enums, whereas those added subsequently have their own per-option API
4775entrypoints.
4776
4777Adding entrypoints for each new option means that client code that use
4778the new options can be identified directly from binary metadata, which
4779would not be possible if we instead extended the various
4780@code{enum gcc_jit_*_option}.
4781
35485da9
DM
4782@menu
4783* String Options::
4784* Boolean options::
4785* Integer options::
fa22c20d 4786* Additional command-line options::
35485da9
DM
4787
4788@end menu
4789
4790@node String Options,Boolean options,,Options<2>
fdce7209 4791@anchor{topics/contexts string-options}@anchor{60}
35485da9
DM
4792@subsubsection String Options
4793
4794
4795@geindex gcc_jit_context_set_str_option (C function)
6f7585de 4796@anchor{topics/contexts c gcc_jit_context_set_str_option}@anchor{61}
35485da9
DM
4797@deffn {C Function} void gcc_jit_context_set_str_option (gcc_jit_context@w{ }*ctxt, enum gcc_jit_str_option@w{ }opt, const char@w{ }*value)
4798
4799Set a string option of the context.
4800
4801@geindex gcc_jit_str_option (C type)
6f7585de 4802@anchor{topics/contexts c gcc_jit_str_option}@anchor{62}
35485da9
DM
4803@deffn {C Type} enum gcc_jit_str_option
4804@end deffn
4805
c575221a
DM
4806The parameter @code{value} can be NULL. If non-NULL, the call takes a
4807copy of the underlying string, so it is valid to pass in a pointer to
4808an on-stack buffer.
4809
6a3603e3 4810There is just one string option specified this way:
35485da9
DM
4811
4812@geindex GCC_JIT_STR_OPTION_PROGNAME (C macro)
6f7585de 4813@anchor{topics/contexts c GCC_JIT_STR_OPTION_PROGNAME}@anchor{63}
35485da9
DM
4814@deffn {C Macro} GCC_JIT_STR_OPTION_PROGNAME
4815
4816The name of the program, for use as a prefix when printing error
6f7585de 4817messages to stderr. If @cite{NULL}, or default, “libgccjit.so” is used.
35485da9
DM
4818@end deffn
4819@end deffn
4820
4821@node Boolean options,Integer options,String Options,Options<2>
fdce7209 4822@anchor{topics/contexts boolean-options}@anchor{64}
35485da9
DM
4823@subsubsection Boolean options
4824
4825
4826@geindex gcc_jit_context_set_bool_option (C function)
6f7585de 4827@anchor{topics/contexts c gcc_jit_context_set_bool_option}@anchor{1b}
35485da9
DM
4828@deffn {C Function} void gcc_jit_context_set_bool_option (gcc_jit_context@w{ }*ctxt, enum gcc_jit_bool_option@w{ }opt, int@w{ }value)
4829
4830Set a boolean option of the context.
6f7585de 4831Zero is “false” (the default), non-zero is “true”.
35485da9
DM
4832
4833@geindex gcc_jit_bool_option (C type)
6f7585de 4834@anchor{topics/contexts c gcc_jit_bool_option}@anchor{65}
35485da9
DM
4835@deffn {C Type} enum gcc_jit_bool_option
4836@end deffn
4837
4838@geindex GCC_JIT_BOOL_OPTION_DEBUGINFO (C macro)
6f7585de 4839@anchor{topics/contexts c GCC_JIT_BOOL_OPTION_DEBUGINFO}@anchor{42}
35485da9
DM
4840@deffn {C Macro} GCC_JIT_BOOL_OPTION_DEBUGINFO
4841
6f7585de 4842If true, @ref{15,,gcc_jit_context_compile()} will attempt to do the right
35485da9
DM
4843thing so that if you attach a debugger to the process, it will
4844be able to inspect variables and step through your code.
4845
6f7585de 4846Note that you can’t step through code unless you set up source
35485da9 4847location information for the code (by creating and passing in
6f7585de 4848@ref{3b,,gcc_jit_location} instances).
35485da9
DM
4849@end deffn
4850
4851@geindex GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE (C macro)
6f7585de 4852@anchor{topics/contexts c GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE}@anchor{66}
35485da9
DM
4853@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE
4854
6f7585de
DM
4855If true, @ref{15,,gcc_jit_context_compile()} will dump its initial
4856“tree” representation of your code to stderr (before any
35485da9
DM
4857optimizations).
4858
6f7585de 4859Here’s some sample output (from the @cite{square} example):
35485da9
DM
4860
4861@example
4862<statement_list 0x7f4875a62cc0
4863 type <void_type 0x7f4875a64bd0 VOID
4864 align 8 symtab 0 alias set -1 canonical type 0x7f4875a64bd0
4865 pointer_to_this <pointer_type 0x7f4875a64c78>>
4866 side-effects head 0x7f4875a761e0 tail 0x7f4875a761f8 stmts 0x7f4875a62d20 0x7f4875a62d00
4867
4868 stmt <label_expr 0x7f4875a62d20 type <void_type 0x7f4875a64bd0>
4869 side-effects
4870 arg 0 <label_decl 0x7f4875a79080 entry type <void_type 0x7f4875a64bd0>
4871 VOID file (null) line 0 col 0
4872 align 1 context <function_decl 0x7f4875a77500 square>>>
4873 stmt <return_expr 0x7f4875a62d00
4874 type <integer_type 0x7f4875a645e8 public SI
4875 size <integer_cst 0x7f4875a623a0 constant 32>
4876 unit size <integer_cst 0x7f4875a623c0 constant 4>
4877 align 32 symtab 0 alias set -1 canonical type 0x7f4875a645e8 precision 32 min <integer_cst 0x7f4875a62340 -2147483648> max <integer_cst 0x7f4875a62360 2147483647>
4878 pointer_to_this <pointer_type 0x7f4875a6b348>>
4879 side-effects
4880 arg 0 <modify_expr 0x7f4875a72a78 type <integer_type 0x7f4875a645e8>
4881 side-effects arg 0 <result_decl 0x7f4875a7a000 D.54>
4882 arg 1 <mult_expr 0x7f4875a72a50 type <integer_type 0x7f4875a645e8>
4883 arg 0 <parm_decl 0x7f4875a79000 i> arg 1 <parm_decl 0x7f4875a79000 i>>>>>
4884@end example
35485da9
DM
4885@end deffn
4886
4887@geindex GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE (C macro)
6f7585de 4888@anchor{topics/contexts c GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}@anchor{1c}
35485da9
DM
4889@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE
4890
6f7585de 4891If true, @ref{15,,gcc_jit_context_compile()} will dump the “gimple”
35485da9
DM
4892representation of your code to stderr, before any optimizations
4893are performed. The dump resembles C code:
4894
4895@example
4896square (signed int i)
4897@{
4898 signed int D.56;
4899
4900 entry:
4901 D.56 = i * i;
4902 return D.56;
4903@}
4904@end example
35485da9
DM
4905@end deffn
4906
4907@geindex GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE (C macro)
6f7585de 4908@anchor{topics/contexts c GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE}@anchor{1d}
35485da9
DM
4909@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE
4910
6f7585de 4911If true, @ref{15,,gcc_jit_context_compile()} will dump the final
35485da9
DM
4912generated code to stderr, in the form of assembly language:
4913
4914@example
4915 .file "fake.c"
4916 .text
4917 .globl square
4918 .type square, @@function
4919square:
4920.LFB0:
4921 .cfi_startproc
4922 pushq %rbp
4923 .cfi_def_cfa_offset 16
4924 .cfi_offset 6, -16
4925 movq %rsp, %rbp
4926 .cfi_def_cfa_register 6
4927 movl %edi, -4(%rbp)
4928.L2:
4929 movl -4(%rbp), %eax
4930 imull -4(%rbp), %eax
4931 popq %rbp
4932 .cfi_def_cfa 7, 8
4933 ret
4934 .cfi_endproc
4935.LFE0:
4936 .size square, .-square
4937 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.1-%@{gcc_release@})"
4938 .section .note.GNU-stack,"",@@progbits
4939@end example
35485da9
DM
4940@end deffn
4941
4942@geindex GCC_JIT_BOOL_OPTION_DUMP_SUMMARY (C macro)
6f7585de 4943@anchor{topics/contexts c GCC_JIT_BOOL_OPTION_DUMP_SUMMARY}@anchor{67}
35485da9
DM
4944@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_SUMMARY
4945
6f7585de 4946If true, @ref{15,,gcc_jit_context_compile()} will print information to stderr
afed3459 4947on the actions it is performing.
35485da9
DM
4948@end deffn
4949
4950@geindex GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING (C macro)
6f7585de 4951@anchor{topics/contexts c GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING}@anchor{68}
35485da9
DM
4952@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING
4953
6f7585de
DM
4954If true, @ref{15,,gcc_jit_context_compile()} will dump copious
4955amount of information on what it’s doing to various
35485da9 4956files within a temporary directory. Use
6f7585de 4957@ref{69,,GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES} (see below) to
35485da9
DM
4958see the results. The files are intended to be human-readable,
4959but the exact files and their formats are subject to change.
4960@end deffn
4961
4962@geindex GCC_JIT_BOOL_OPTION_SELFCHECK_GC (C macro)
6f7585de 4963@anchor{topics/contexts c GCC_JIT_BOOL_OPTION_SELFCHECK_GC}@anchor{6a}
35485da9
DM
4964@deffn {C Macro} GCC_JIT_BOOL_OPTION_SELFCHECK_GC
4965
4966If true, libgccjit will aggressively run its garbage collector, to
4967shake out bugs (greatly slowing down the compile). This is likely
4968to only be of interest to developers @emph{of} the library. It is
4969used when running the selftest suite.
4970@end deffn
4971
4972@geindex GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES (C macro)
6f7585de 4973@anchor{topics/contexts c GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES}@anchor{69}
35485da9
DM
4974@deffn {C Macro} GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES
4975
6f7585de 4976If true, the @ref{8,,gcc_jit_context} will not clean up intermediate files
35485da9
DM
4977written to the filesystem, and will display their location on stderr.
4978@end deffn
4979@end deffn
4980
6a3603e3 4981@geindex gcc_jit_context_set_bool_allow_unreachable_blocks (C function)
6f7585de 4982@anchor{topics/contexts c gcc_jit_context_set_bool_allow_unreachable_blocks}@anchor{6b}
6a3603e3
DM
4983@deffn {C Function} void gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context@w{ }*ctxt, int@w{ }bool_value)
4984
4985By default, libgccjit will issue an error about unreachable blocks
4986within a function.
4987
4988This entrypoint can be used to disable that error.
4989
6f7585de 4990This entrypoint was added in @ref{6c,,LIBGCCJIT_ABI_2}; you can test for
6a3603e3
DM
4991its presence using
4992
4993@example
4994#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks
4995@end example
6a3603e3
DM
4996@end deffn
4997
199501ea 4998@geindex gcc_jit_context_set_bool_use_external_driver (C function)
6f7585de 4999@anchor{topics/contexts c gcc_jit_context_set_bool_use_external_driver}@anchor{6d}
199501ea
DM
5000@deffn {C Function} void gcc_jit_context_set_bool_use_external_driver (gcc_jit_context@w{ }*ctxt, int@w{ }bool_value)
5001
6f7585de 5002libgccjit internally generates assembler, and uses “driver” code
199501ea
DM
5003for converting it to other formats (e.g. shared libraries).
5004
5005By default, libgccjit will use an embedded copy of the driver
5006code.
5007
5008This option can be used to instead invoke an external driver executable
5009as a subprocess.
5010
6f7585de 5011This entrypoint was added in @ref{6e,,LIBGCCJIT_ABI_5}; you can test for
199501ea
DM
5012its presence using
5013
5014@example
5015#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_use_external_driver
5016@end example
199501ea
DM
5017@end deffn
5018
fa22c20d 5019@node Integer options,Additional command-line options,Boolean options,Options<2>
199501ea 5020@anchor{topics/contexts integer-options}@anchor{6f}
35485da9
DM
5021@subsubsection Integer options
5022
5023
5024@geindex gcc_jit_context_set_int_option (C function)
6f7585de 5025@anchor{topics/contexts c gcc_jit_context_set_int_option}@anchor{1e}
35485da9
DM
5026@deffn {C Function} void gcc_jit_context_set_int_option (gcc_jit_context@w{ }*ctxt, enum gcc_jit_int_option@w{ }opt, int@w{ }value)
5027
5028Set an integer option of the context.
5029
5030@geindex gcc_jit_int_option (C type)
6f7585de 5031@anchor{topics/contexts c gcc_jit_int_option}@anchor{70}
35485da9
DM
5032@deffn {C Type} enum gcc_jit_int_option
5033@end deffn
5034
6a3603e3 5035There is just one integer option specified this way:
35485da9
DM
5036
5037@geindex GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL (C macro)
6f7585de 5038@anchor{topics/contexts c GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}@anchor{1f}
35485da9
DM
5039@deffn {C Macro} GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL
5040
5041How much to optimize the code.
5042
6f7585de 5043Valid values are 0-3, corresponding to GCC’s command-line options
35485da9
DM
5044-O0 through -O3.
5045
5046The default value is 0 (unoptimized).
5047@end deffn
5048@end deffn
5049
fa22c20d 5050@node Additional command-line options,,Integer options,Options<2>
199501ea 5051@anchor{topics/contexts additional-command-line-options}@anchor{71}
fa22c20d
DM
5052@subsubsection Additional command-line options
5053
5054
5055@geindex gcc_jit_context_add_command_line_option (C function)
6f7585de 5056@anchor{topics/contexts c gcc_jit_context_add_command_line_option}@anchor{72}
fa22c20d
DM
5057@deffn {C Function} void gcc_jit_context_add_command_line_option (gcc_jit_context@w{ }*ctxt, const char@w{ }*optname)
5058
5059Add an arbitrary gcc command-line option to the context, for use
6f7585de
DM
5060by @ref{15,,gcc_jit_context_compile()} and
5061@ref{4a,,gcc_jit_context_compile_to_file()}.
fa22c20d
DM
5062
5063The parameter @code{optname} must be non-NULL. The underlying buffer is
5064copied, so that it does not need to outlive the call.
5065
5066Extra options added by @cite{gcc_jit_context_add_command_line_option} are
5067applied @emph{after} the regular options above, potentially overriding them.
5068Options from parent contexts are inherited by child contexts; options
5069from the parent are applied @emph{before} those from the child.
5070
5071For example:
5072
5073@example
5074gcc_jit_context_add_command_line_option (ctxt, "-ffast-math");
5075gcc_jit_context_add_command_line_option (ctxt, "-fverbose-asm");
5076@end example
5077
fa22c20d 5078Note that only some options are likely to be meaningful; there is no
6f7585de 5079“frontend” within libgccjit, so typically only those affecting
fa22c20d
DM
5080optimization and code-generation are likely to be useful.
5081
6f7585de 5082This entrypoint was added in @ref{73,,LIBGCCJIT_ABI_1}; you can test for
fa22c20d
DM
5083its presence using
5084
5085@example
5086#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option
5087@end example
6f7585de
DM
5088@end deffn
5089
5090@geindex gcc_jit_context_add_driver_option (C function)
5091@anchor{topics/contexts c gcc_jit_context_add_driver_option}@anchor{74}
5092@deffn {C Function} void gcc_jit_context_add_driver_option (gcc_jit_context@w{ }*ctxt, const char@w{ }*optname)
5093
5094Add an arbitrary gcc driver option to the context, for use by
5095@ref{15,,gcc_jit_context_compile()} and
5096@ref{4a,,gcc_jit_context_compile_to_file()}.
5097
5098The parameter @code{optname} must be non-NULL. The underlying buffer is
5099copied, so that it does not need to outlive the call.
5100
5101Extra options added by @cite{gcc_jit_context_add_driver_option} are
5102applied @emph{after} all other options potentially overriding them.
5103Options from parent contexts are inherited by child contexts; options
5104from the parent are applied @emph{before} those from the child.
5105
5106For example:
fa22c20d 5107
6f7585de
DM
5108@example
5109gcc_jit_context_add_driver_option (ctxt, "-lm");
5110gcc_jit_context_add_driver_option (ctxt, "-fuse-linker-plugin");
5111@end example
5112
5113Note that only some options are likely to be meaningful; there is no
5114“frontend” within libgccjit, so typically only those affecting
5115assembler and linker are likely to be useful.
5116
5117This entrypoint was added in @ref{75,,LIBGCCJIT_ABI_11}; you can test for
5118its presence using
5119
5120@example
5121#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option
5122@end example
fa22c20d
DM
5123@end deffn
5124
7adcbafe 5125@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
5126@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
5127@c
5128@c This is free software: you can redistribute it and/or modify it
5129@c under the terms of the GNU General Public License as published by
5130@c the Free Software Foundation, either version 3 of the License, or
5131@c (at your option) any later version.
5132@c
5133@c This program is distributed in the hope that it will be useful, but
5134@c WITHOUT ANY WARRANTY; without even the implied warranty of
5135@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5136@c General Public License for more details.
5137@c
5138@c You should have received a copy of the GNU General Public License
5139@c along with this program. If not, see
786973ce 5140@c <https://www.gnu.org/licenses/>.
35485da9
DM
5141
5142@node Objects,Types,Compilation contexts,Topic Reference
421d0d0f 5143@anchor{topics/objects doc}@anchor{76}@anchor{topics/objects objects}@anchor{77}
35485da9
DM
5144@section Objects
5145
5146
5147@geindex gcc_jit_object (C type)
6f7585de 5148@anchor{topics/objects c gcc_jit_object}@anchor{e}
35485da9
DM
5149@deffn {C Type} gcc_jit_object
5150@end deffn
5151
5152Almost every entity in the API (with the exception of
6f7585de
DM
5153@ref{8,,gcc_jit_context *} and @ref{16,,gcc_jit_result *}) is a
5154“contextual” object, a @ref{e,,gcc_jit_object *}
35485da9
DM
5155
5156A JIT object:
5157
5158@quotation
5159
5160
5161@itemize *
5162
5163@item
6f7585de 5164is associated with a @ref{8,,gcc_jit_context *}.
35485da9
DM
5165
5166@item
5167is automatically cleaned up for you when its context is released so
6f7585de 5168you don’t need to manually track and cleanup all objects, just the
35485da9
DM
5169contexts.
5170@end itemize
5171@end quotation
5172
5173Although the API is C-based, there is a form of class hierarchy, which
5174looks like this:
5175
5176@example
5177+- gcc_jit_object
5178 +- gcc_jit_location
5179 +- gcc_jit_type
5180 +- gcc_jit_struct
5181 +- gcc_jit_field
5182 +- gcc_jit_function
5183 +- gcc_jit_block
5184 +- gcc_jit_rvalue
5185 +- gcc_jit_lvalue
5186 +- gcc_jit_param
ec5d0088 5187 +- gcc_jit_case
421d0d0f 5188 +- gcc_jit_extended_asm
35485da9
DM
5189@end example
5190
35485da9 5191There are casting methods for upcasting from subclasses to parent classes.
6f7585de 5192For example, @ref{d,,gcc_jit_type_as_object()}:
35485da9
DM
5193
5194@example
5195gcc_jit_object *obj = gcc_jit_type_as_object (int_type);
5196@end example
5197
6f7585de 5198The object “base class” has the following operations:
35485da9
DM
5199
5200@geindex gcc_jit_object_get_context (C function)
6f7585de 5201@anchor{topics/objects c gcc_jit_object_get_context}@anchor{78}
35485da9
DM
5202@deffn {C Function} gcc_jit_context *gcc_jit_object_get_context (gcc_jit_object@w{ }*obj)
5203
6f7585de 5204Which context is “obj” within?
35485da9
DM
5205@end deffn
5206
5207@geindex gcc_jit_object_get_debug_string (C function)
6f7585de 5208@anchor{topics/objects c gcc_jit_object_get_debug_string}@anchor{f}
35485da9
DM
5209@deffn {C Function} const char *gcc_jit_object_get_debug_string (gcc_jit_object@w{ }*obj)
5210
5211Generate a human-readable description for the given object.
5212
5213For example,
5214
5215@example
5216printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj));
5217@end example
5218
35485da9
DM
5219might give this text on stdout:
5220
5221@example
5222obj: 4.0 * (float)i
5223@end example
5224
35485da9
DM
5225@cartouche
5226@quotation Note
5227If you call this on an object, the @cite{const char *} buffer is allocated
5228and generated on the first call for that object, and the buffer will
5229have the same lifetime as the object i.e. it will exist until the
6f7585de 5230object’s context is released.
35485da9
DM
5231@end quotation
5232@end cartouche
5233@end deffn
5234
7adcbafe 5235@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
5236@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
5237@c
5238@c This is free software: you can redistribute it and/or modify it
5239@c under the terms of the GNU General Public License as published by
5240@c the Free Software Foundation, either version 3 of the License, or
5241@c (at your option) any later version.
5242@c
5243@c This program is distributed in the hope that it will be useful, but
5244@c WITHOUT ANY WARRANTY; without even the implied warranty of
5245@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5246@c General Public License for more details.
5247@c
5248@c You should have received a copy of the GNU General Public License
5249@c along with this program. If not, see
786973ce 5250@c <https://www.gnu.org/licenses/>.
35485da9
DM
5251
5252@node Types,Expressions,Objects,Topic Reference
6f7585de 5253@anchor{topics/types doc}@anchor{79}@anchor{topics/types types}@anchor{7a}
35485da9
DM
5254@section Types
5255
5256
5257@geindex gcc_jit_type (C type)
6f7585de 5258@anchor{topics/types c gcc_jit_type}@anchor{a}
35485da9
DM
5259@deffn {C Type} gcc_jit_type
5260
5261gcc_jit_type represents a type within the library.
5262@end deffn
5263
5264@geindex gcc_jit_type_as_object (C function)
6f7585de 5265@anchor{topics/types c gcc_jit_type_as_object}@anchor{d}
35485da9
DM
5266@deffn {C Function} gcc_jit_object *gcc_jit_type_as_object (gcc_jit_type@w{ }*type)
5267
5268Upcast a type to an object.
5269@end deffn
5270
5271Types can be created in several ways:
5272
5273
5274@itemize *
5275
5276@item
5277fundamental types can be accessed using
6f7585de 5278@ref{b,,gcc_jit_context_get_type()}:
35485da9
DM
5279
5280@example
47ee1b7c 5281gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
35485da9
DM
5282@end example
5283
6f7585de 5284See @ref{b,,gcc_jit_context_get_type()} for the available types.
35485da9
DM
5285
5286@item
5287derived types can be accessed by using functions such as
6f7585de 5288@ref{7b,,gcc_jit_type_get_pointer()} and @ref{7c,,gcc_jit_type_get_const()}:
35485da9
DM
5289
5290@example
5291gcc_jit_type *const_int_star = gcc_jit_type_get_pointer (gcc_jit_type_get_const (int_type));
5292gcc_jit_type *int_const_star = gcc_jit_type_get_const (gcc_jit_type_get_pointer (int_type));
5293@end example
5294
35485da9
DM
5295@item
5296by creating structures (see below).
5297@end itemize
5298
5299@menu
5300* Standard types::
5301* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile.
47ee1b7c 5302* Vector types::
35485da9 5303* Structures and unions::
ecd5156d 5304* Function pointer types::
35485da9
DM
5305
5306@end menu
5307
5308@node Standard types,Pointers const and volatile,,Types
6f7585de 5309@anchor{topics/types standard-types}@anchor{7d}
35485da9
DM
5310@subsection Standard types
5311
5312
5313@geindex gcc_jit_context_get_type (C function)
6f7585de 5314@anchor{topics/types c gcc_jit_context_get_type}@anchor{b}
35485da9
DM
5315@deffn {C Function} gcc_jit_type *gcc_jit_context_get_type (gcc_jit_context@w{ }*ctxt, enum gcc_jit_types@w{ }type_)
5316
5317Access a specific type. The available types are:
5318
5319
eeafb319 5320@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
35485da9
DM
5321@headitem
5322
5323@cite{enum gcc_jit_types} value
5324
5325@tab
5326
5327Meaning
5328
5329@item
5330
5331@code{GCC_JIT_TYPE_VOID}
5332
5333@tab
5334
6f7585de 5335C’s @code{void} type.
35485da9
DM
5336
5337@item
5338
5339@code{GCC_JIT_TYPE_VOID_PTR}
5340
5341@tab
5342
6f7585de 5343C’s @code{void *}.
35485da9
DM
5344
5345@item
5346
5347@code{GCC_JIT_TYPE_BOOL}
5348
5349@tab
5350
6f7585de 5351C++’s @code{bool} type; also C99’s
35485da9
DM
5352@code{_Bool} type, aka @code{bool} if
5353using stdbool.h.
5354
5355@item
5356
5357@code{GCC_JIT_TYPE_CHAR}
5358
5359@tab
5360
6f7585de 5361C’s @code{char} (of some signedness)
35485da9
DM
5362
5363@item
5364
5365@code{GCC_JIT_TYPE_SIGNED_CHAR}
5366
5367@tab
5368
6f7585de 5369C’s @code{signed char}
35485da9
DM
5370
5371@item
5372
5373@code{GCC_JIT_TYPE_UNSIGNED_CHAR}
5374
5375@tab
5376
6f7585de 5377C’s @code{unsigned char}
35485da9
DM
5378
5379@item
5380
5381@code{GCC_JIT_TYPE_SHORT}
5382
5383@tab
5384
6f7585de 5385C’s @code{short} (signed)
35485da9
DM
5386
5387@item
5388
5389@code{GCC_JIT_TYPE_UNSIGNED_SHORT}
5390
5391@tab
5392
6f7585de 5393C’s @code{unsigned short}
35485da9
DM
5394
5395@item
5396
5397@code{GCC_JIT_TYPE_INT}
5398
5399@tab
5400
6f7585de 5401C’s @code{int} (signed)
35485da9
DM
5402
5403@item
5404
5405@code{GCC_JIT_TYPE_UNSIGNED_INT}
5406
5407@tab
5408
6f7585de 5409C’s @code{unsigned int}
35485da9
DM
5410
5411@item
5412
5413@code{GCC_JIT_TYPE_LONG}
5414
5415@tab
5416
6f7585de 5417C’s @code{long} (signed)
35485da9
DM
5418
5419@item
5420
5421@code{GCC_JIT_TYPE_UNSIGNED_LONG}
5422
5423@tab
5424
6f7585de 5425C’s @code{unsigned long}
35485da9
DM
5426
5427@item
5428
5429@code{GCC_JIT_TYPE_LONG_LONG}
5430
5431@tab
5432
6f7585de 5433C99’s @code{long long} (signed)
35485da9
DM
5434
5435@item
5436
5437@code{GCC_JIT_TYPE_UNSIGNED_LONG_LONG}
5438
5439@tab
5440
6f7585de 5441C99’s @code{unsigned long long}
35485da9
DM
5442
5443@item
5444
5445@code{GCC_JIT_TYPE_FLOAT}
5446
5447@tab
5448
5449@item
5450
5451@code{GCC_JIT_TYPE_DOUBLE}
5452
5453@tab
5454
5455@item
5456
5457@code{GCC_JIT_TYPE_LONG_DOUBLE}
5458
5459@tab
5460
5461@item
5462
5463@code{GCC_JIT_TYPE_CONST_CHAR_PTR}
5464
5465@tab
5466
5467C type: @code{(const char *)}
5468
5469@item
5470
5471@code{GCC_JIT_TYPE_SIZE_T}
5472
5473@tab
5474
6f7585de 5475C’s @code{size_t} type
35485da9
DM
5476
5477@item
5478
5479@code{GCC_JIT_TYPE_FILE_PTR}
5480
5481@tab
5482
5483C type: @code{(FILE *)}
5484
eeafb319
DM
5485@item
5486
5487@code{GCC_JIT_TYPE_COMPLEX_FLOAT}
5488
5489@tab
5490
6f7585de 5491C99’s @code{_Complex float}
eeafb319
DM
5492
5493@item
5494
5495@code{GCC_JIT_TYPE_COMPLEX_DOUBLE}
5496
5497@tab
5498
6f7585de 5499C99’s @code{_Complex double}
eeafb319
DM
5500
5501@item
5502
5503@code{GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE}
5504
5505@tab
5506
6f7585de 5507C99’s @code{_Complex long double}
eeafb319 5508
35485da9
DM
5509@end multitable
5510
5511@end deffn
5512
5513@geindex gcc_jit_context_get_int_type (C function)
6f7585de 5514@anchor{topics/types c gcc_jit_context_get_int_type}@anchor{7e}
35485da9
DM
5515@deffn {C Function} gcc_jit_type * gcc_jit_context_get_int_type (gcc_jit_context@w{ }*ctxt, int@w{ }num_bytes, int@w{ }is_signed)
5516
5517Access the integer type of the given size.
5518@end deffn
5519
47ee1b7c 5520@node Pointers const and volatile,Vector types,Standard types,Types
6f7585de 5521@anchor{topics/types pointers-const-and-volatile}@anchor{7f}
35485da9
DM
5522@subsection Pointers, @cite{const}, and @cite{volatile}
5523
5524
5525@geindex gcc_jit_type_get_pointer (C function)
6f7585de 5526@anchor{topics/types c gcc_jit_type_get_pointer}@anchor{7b}
35485da9
DM
5527@deffn {C Function} gcc_jit_type *gcc_jit_type_get_pointer (gcc_jit_type@w{ }*type)
5528
6f7585de 5529Given type “T”, get type “T*”.
35485da9
DM
5530@end deffn
5531
5532@geindex gcc_jit_type_get_const (C function)
6f7585de 5533@anchor{topics/types c gcc_jit_type_get_const}@anchor{7c}
35485da9
DM
5534@deffn {C Function} gcc_jit_type *gcc_jit_type_get_const (gcc_jit_type@w{ }*type)
5535
6f7585de 5536Given type “T”, get type “const T”.
35485da9
DM
5537@end deffn
5538
5539@geindex gcc_jit_type_get_volatile (C function)
6f7585de 5540@anchor{topics/types c gcc_jit_type_get_volatile}@anchor{80}
35485da9
DM
5541@deffn {C Function} gcc_jit_type *gcc_jit_type_get_volatile (gcc_jit_type@w{ }*type)
5542
6f7585de 5543Given type “T”, get type “volatile T”.
35485da9
DM
5544@end deffn
5545
5546@geindex gcc_jit_context_new_array_type (C function)
6f7585de 5547@anchor{topics/types c gcc_jit_context_new_array_type}@anchor{81}
35485da9
DM
5548@deffn {C Function} gcc_jit_type * gcc_jit_context_new_array_type (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*element_type, int@w{ }num_elements)
5549
6f7585de 5550Given non-@cite{void} type “T”, get type “T[N]” (for a constant N).
35485da9
DM
5551@end deffn
5552
0ebd1f00 5553@geindex gcc_jit_type_get_aligned (C function)
6f7585de 5554@anchor{topics/types c gcc_jit_type_get_aligned}@anchor{82}
0ebd1f00
DM
5555@deffn {C Function} gcc_jit_type * gcc_jit_type_get_aligned (gcc_jit_type@w{ }*type, size_t@w{ }alignment_in_bytes)
5556
6f7585de 5557Given non-@cite{void} type “T”, get type:
0ebd1f00
DM
5558
5559@example
5560T __attribute__ ((aligned (ALIGNMENT_IN_BYTES)))
5561@end example
5562
0ebd1f00
DM
5563The alignment must be a power of two.
5564
6f7585de 5565This entrypoint was added in @ref{83,,LIBGCCJIT_ABI_7}; you can test for
0ebd1f00
DM
5566its presence using
5567
5568@example
5569#ifdef LIBGCCJIT_HAVE_gcc_jit_type_get_aligned
5570@end example
0ebd1f00
DM
5571@end deffn
5572
47ee1b7c 5573@node Vector types,Structures and unions,Pointers const and volatile,Types
6f7585de 5574@anchor{topics/types vector-types}@anchor{84}
47ee1b7c
DM
5575@subsection Vector types
5576
5577
5578@geindex gcc_jit_type_get_vector (C function)
6f7585de 5579@anchor{topics/types c gcc_jit_type_get_vector}@anchor{85}
47ee1b7c
DM
5580@deffn {C Function} gcc_jit_type * gcc_jit_type_get_vector (gcc_jit_type@w{ }*type, size_t@w{ }num_units)
5581
6f7585de 5582Given type “T”, get type:
47ee1b7c
DM
5583
5584@example
5585T __attribute__ ((vector_size (sizeof(T) * num_units))
5586@end example
5587
47ee1b7c
DM
5588T must be integral or floating point; num_units must be a power of two.
5589
5590This can be used to construct a vector type in which operations
5591are applied element-wise. The compiler will automatically
5592use SIMD instructions where possible. See:
5593@indicateurl{https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html}
5594
5595For example, assuming 4-byte @code{ints}, then:
5596
5597@example
5598typedef int v4si __attribute__ ((vector_size (16)));
5599@end example
5600
47ee1b7c
DM
5601can be obtained using:
5602
5603@example
5604gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt,
5605 GCC_JIT_TYPE_INT);
5606gcc_jit_type *v4si_type = gcc_jit_type_get_vector (int_type, 4);
5607@end example
5608
6f7585de 5609This API entrypoint was added in @ref{86,,LIBGCCJIT_ABI_8}; you can test
47ee1b7c
DM
5610for its presence using
5611
5612@example
5613#ifdef LIBGCCJIT_HAVE_gcc_jit_type_get_vector
5614@end example
5615
6069fe72 5616Vector rvalues can be generated using
6f7585de 5617@ref{87,,gcc_jit_context_new_rvalue_from_vector()}.
47ee1b7c
DM
5618@end deffn
5619
ecd5156d 5620@node Structures and unions,Function pointer types,Vector types,Types
6f7585de 5621@anchor{topics/types structures-and-unions}@anchor{88}
35485da9
DM
5622@subsection Structures and unions
5623
5624
5625@geindex gcc_jit_struct (C type)
6f7585de 5626@anchor{topics/types c gcc_jit_struct}@anchor{89}
35485da9
DM
5627@deffn {C Type} gcc_jit_struct
5628@end deffn
5629
5630A compound type analagous to a C @cite{struct}.
5631
5632@geindex gcc_jit_field (C type)
6f7585de 5633@anchor{topics/types c gcc_jit_field}@anchor{8a}
35485da9
DM
5634@deffn {C Type} gcc_jit_field
5635@end deffn
5636
6f7585de 5637A field within a @ref{89,,gcc_jit_struct}.
35485da9 5638
6f7585de
DM
5639You can model C @cite{struct} types by creating @ref{89,,gcc_jit_struct *} and
5640@ref{8a,,gcc_jit_field} instances, in either order:
35485da9
DM
5641
5642
5643@itemize *
5644
5645@item
5646by creating the fields, then the structure. For example, to model:
5647
5648@example
5649struct coord @{double x; double y; @};
5650@end example
5651
35485da9
DM
5652you could call:
5653
5654@example
5655gcc_jit_field *field_x =
5656 gcc_jit_context_new_field (ctxt, NULL, double_type, "x");
5657gcc_jit_field *field_y =
5658 gcc_jit_context_new_field (ctxt, NULL, double_type, "y");
5659gcc_jit_field *fields[2] = @{field_x, field_y@};
5660gcc_jit_struct *coord =
5661 gcc_jit_context_new_struct_type (ctxt, NULL, "coord", 2, fields);
5662@end example
5663
35485da9
DM
5664@item
5665by creating the structure, then populating it with fields, typically
5666to allow modelling self-referential structs such as:
5667
5668@example
5669struct node @{ int m_hash; struct node *m_next; @};
5670@end example
5671
35485da9
DM
5672like this:
5673
5674@example
5675gcc_jit_type *node =
5676 gcc_jit_context_new_opaque_struct (ctxt, NULL, "node");
5677gcc_jit_type *node_ptr =
5678 gcc_jit_type_get_pointer (node);
5679gcc_jit_field *field_hash =
5680 gcc_jit_context_new_field (ctxt, NULL, int_type, "m_hash");
5681gcc_jit_field *field_next =
5682 gcc_jit_context_new_field (ctxt, NULL, node_ptr, "m_next");
5683gcc_jit_field *fields[2] = @{field_hash, field_next@};
5684gcc_jit_struct_set_fields (node, NULL, 2, fields);
5685@end example
35485da9
DM
5686@end itemize
5687
5688@geindex gcc_jit_context_new_field (C function)
6f7585de 5689@anchor{topics/types c gcc_jit_context_new_field}@anchor{8b}
35485da9
DM
5690@deffn {C Function} gcc_jit_field * gcc_jit_context_new_field (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, const char@w{ }*name)
5691
5692Construct a new field, with the given type and name.
c575221a 5693
6f7585de
DM
5694The parameter @code{type} must be non-@cite{void}.
5695
5696The parameter @code{name} must be non-NULL. The call takes a copy of the
5697underlying string, so it is valid to pass in a pointer to an on-stack
5698buffer.
5699@end deffn
5700
5701@geindex gcc_jit_context_new_bitfield (C function)
5702@anchor{topics/types c gcc_jit_context_new_bitfield}@anchor{8c}
5703@deffn {C Function} gcc_jit_field * gcc_jit_context_new_bitfield (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, int@w{ }width, const char@w{ }*name)
5704
5705Construct a new bit field, with the given type width and name.
5706
c575221a
DM
5707The parameter @code{name} must be non-NULL. The call takes a copy of the
5708underlying string, so it is valid to pass in a pointer to an on-stack
5709buffer.
6f7585de
DM
5710
5711The parameter @code{type} must be an integer type.
5712
5713The parameter @code{width} must be a positive integer that does not exceed the
5714size of @code{type}.
5715
0981cf96 5716This API entrypoint was added in @ref{8d,,LIBGCCJIT_ABI_12}; you can test
6f7585de 5717for its presence using
6f7585de 5718
0981cf96 5719@example
6f7585de 5720#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield
0981cf96 5721@end example
35485da9
DM
5722@end deffn
5723
5724@geindex gcc_jit_field_as_object (C function)
0981cf96 5725@anchor{topics/types c gcc_jit_field_as_object}@anchor{8e}
35485da9
DM
5726@deffn {C Function} gcc_jit_object * gcc_jit_field_as_object (gcc_jit_field@w{ }*field)
5727
5728Upcast from field to object.
5729@end deffn
5730
5731@geindex gcc_jit_context_new_struct_type (C function)
0981cf96 5732@anchor{topics/types c gcc_jit_context_new_struct_type}@anchor{8f}
35485da9
DM
5733@deffn {C Function} gcc_jit_struct *gcc_jit_context_new_struct_type (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, const char@w{ }*name, int@w{ }num_fields, gcc_jit_field@w{ }**fields)
5734
5735@quotation
5736
5737Construct a new struct type, with the given name and fields.
c575221a
DM
5738
5739The parameter @code{name} must be non-NULL. The call takes a copy of
5740the underlying string, so it is valid to pass in a pointer to an
5741on-stack buffer.
35485da9
DM
5742@end quotation
5743@end deffn
5744
5745@geindex gcc_jit_context_new_opaque_struct (C function)
0981cf96 5746@anchor{topics/types c gcc_jit_context_new_opaque_struct}@anchor{90}
35485da9
DM
5747@deffn {C Function} gcc_jit_struct * gcc_jit_context_new_opaque_struct (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, const char@w{ }*name)
5748
5749Construct a new struct type, with the given name, but without
5750specifying the fields. The fields can be omitted (in which case the
5751size of the struct is not known), or later specified using
0981cf96 5752@ref{91,,gcc_jit_struct_set_fields()}.
c575221a
DM
5753
5754The parameter @code{name} must be non-NULL. The call takes a copy of
5755the underlying string, so it is valid to pass in a pointer to an
5756on-stack buffer.
35485da9
DM
5757@end deffn
5758
5759@geindex gcc_jit_struct_as_type (C function)
0981cf96 5760@anchor{topics/types c gcc_jit_struct_as_type}@anchor{92}
35485da9
DM
5761@deffn {C Function} gcc_jit_type * gcc_jit_struct_as_type (gcc_jit_struct@w{ }*struct_type)
5762
5763Upcast from struct to type.
5764@end deffn
5765
5766@geindex gcc_jit_struct_set_fields (C function)
0981cf96 5767@anchor{topics/types c gcc_jit_struct_set_fields}@anchor{91}
35485da9
DM
5768@deffn {C Function} void gcc_jit_struct_set_fields (gcc_jit_struct@w{ }*struct_type, gcc_jit_location@w{ }*loc, int@w{ }num_fields, gcc_jit_field@w{ }**fields)
5769
5770Populate the fields of a formerly-opaque struct type.
5771
5772This can only be called once on a given struct type.
5773@end deffn
5774
e807aeaa 5775@geindex gcc_jit_context_new_union_type (C function)
0981cf96 5776@anchor{topics/types c gcc_jit_context_new_union_type}@anchor{93}
e807aeaa
DM
5777@deffn {C Function} gcc_jit_type * gcc_jit_context_new_union_type (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, const char@w{ }*name, int@w{ }num_fields, gcc_jit_field@w{ }**fields)
5778
5779Construct a new union type, with the given name and fields.
5780
5781The parameter @code{name} must be non-NULL. It is copied, so the input
5782buffer does not need to outlive the call.
5783
5784Example of use:
5785
5786@example
5787
5788union int_or_float
5789@{
5790 int as_int;
5791 float as_float;
5792@};
5793
5794void
5795create_code (gcc_jit_context *ctxt, void *user_data)
5796@{
5797 /* Let's try to inject the equivalent of:
5798 float
5799 test_union (int i)
5800 @{
5801 union int_or_float u;
5802 u.as_int = i;
5803 return u.as_float;
5804 @}
5805 */
5806 gcc_jit_type *int_type =
5807 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
5808 gcc_jit_type *float_type =
5809 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT);
5810 gcc_jit_field *as_int =
5811 gcc_jit_context_new_field (ctxt,
5812 NULL,
5813 int_type,
5814 "as_int");
5815 gcc_jit_field *as_float =
5816 gcc_jit_context_new_field (ctxt,
5817 NULL,
5818 float_type,
5819 "as_float");
5820 gcc_jit_field *fields[] = @{as_int, as_float@};
5821 gcc_jit_type *union_type =
5822 gcc_jit_context_new_union_type (ctxt, NULL,
5823 "int_or_float", 2, fields);
5824
5825 /* Build the test function. */
5826 gcc_jit_param *param_i =
5827 gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
5828 gcc_jit_function *test_fn =
5829 gcc_jit_context_new_function (ctxt, NULL,
5830 GCC_JIT_FUNCTION_EXPORTED,
5831 float_type,
5832 "test_union",
5833 1, &param_i,
5834 0);
5835
5836 gcc_jit_lvalue *u =
5837 gcc_jit_function_new_local (test_fn, NULL,
5838 union_type, "u");
5839
5840 gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
5841
5842 /* u.as_int = i; */
5843 gcc_jit_block_add_assignment (
5844 block,
5845 NULL,
5846 /* "u.as_int = ..." */
5847 gcc_jit_lvalue_access_field (u,
5848 NULL,
5849 as_int),
5850 gcc_jit_param_as_rvalue (param_i));
5851
5852 /* return u.as_float; */
5853 gcc_jit_block_end_with_return (
5854 block, NULL,
5855 gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (u),
5856 NULL,
5857 as_float));
5858@}
5859
e807aeaa 5860@end example
e807aeaa
DM
5861@end deffn
5862
ecd5156d 5863@node Function pointer types,,Structures and unions,Types
0981cf96 5864@anchor{topics/types function-pointer-types}@anchor{94}
ecd5156d
DM
5865@subsection Function pointer types
5866
5867
5868Function pointer types can be created using
0981cf96 5869@ref{95,,gcc_jit_context_new_function_ptr_type()}.
ecd5156d 5870
7adcbafe 5871@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
5872@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
5873@c
5874@c This is free software: you can redistribute it and/or modify it
5875@c under the terms of the GNU General Public License as published by
5876@c the Free Software Foundation, either version 3 of the License, or
5877@c (at your option) any later version.
5878@c
5879@c This program is distributed in the hope that it will be useful, but
5880@c WITHOUT ANY WARRANTY; without even the implied warranty of
5881@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5882@c General Public License for more details.
5883@c
5884@c You should have received a copy of the GNU General Public License
5885@c along with this program. If not, see
786973ce 5886@c <https://www.gnu.org/licenses/>.
35485da9
DM
5887
5888@node Expressions,Creating and using functions,Types,Topic Reference
421d0d0f 5889@anchor{topics/expressions doc}@anchor{96}@anchor{topics/expressions expressions}@anchor{97}
35485da9
DM
5890@section Expressions
5891
5892
5893@menu
5894* Rvalues::
5895* Lvalues::
5896* Working with pointers@comma{} structs and unions: Working with pointers structs and unions.
5897
35485da9
DM
5898@end menu
5899
35485da9 5900@node Rvalues,Lvalues,,Expressions
0981cf96 5901@anchor{topics/expressions rvalues}@anchor{98}
35485da9
DM
5902@subsection Rvalues
5903
5904
5905@geindex gcc_jit_rvalue (C type)
6f7585de 5906@anchor{topics/expressions c gcc_jit_rvalue}@anchor{13}
35485da9
DM
5907@deffn {C Type} gcc_jit_rvalue
5908@end deffn
5909
6f7585de 5910A @ref{13,,gcc_jit_rvalue *} is an expression that can be computed.
35485da9
DM
5911
5912It can be simple, e.g.:
5913
5914@quotation
5915
5916
5917@itemize *
5918
5919@item
5920an integer value e.g. @cite{0} or @cite{42}
5921
5922@item
6f7585de 5923a string literal e.g. @cite{“Hello world”}
35485da9
DM
5924
5925@item
5926a variable e.g. @cite{i}. These are also lvalues (see below).
5927@end itemize
5928@end quotation
5929
5930or compound e.g.:
5931
5932@quotation
5933
5934
5935@itemize *
5936
5937@item
5938a unary expression e.g. @cite{!cond}
5939
5940@item
5941a binary expression e.g. @cite{(a + b)}
5942
5943@item
5944a function call e.g. @cite{get_distance (&player_ship@comma{} &target)}
5945
5946@item
5947etc.
5948@end itemize
5949@end quotation
5950
5951Every rvalue has an associated type, and the API will check to ensure
5952that types match up correctly (otherwise the context will emit an error).
5953
5954@geindex gcc_jit_rvalue_get_type (C function)
0981cf96 5955@anchor{topics/expressions c gcc_jit_rvalue_get_type}@anchor{99}
35485da9
DM
5956@deffn {C Function} gcc_jit_type *gcc_jit_rvalue_get_type (gcc_jit_rvalue@w{ }*rvalue)
5957
5958Get the type of this rvalue.
5959@end deffn
5960
5961@geindex gcc_jit_rvalue_as_object (C function)
6f7585de 5962@anchor{topics/expressions c gcc_jit_rvalue_as_object}@anchor{14}
35485da9
DM
5963@deffn {C Function} gcc_jit_object *gcc_jit_rvalue_as_object (gcc_jit_rvalue@w{ }*rvalue)
5964
5965Upcast the given rvalue to be an object.
5966@end deffn
5967
5968@menu
5969* Simple expressions::
6069fe72 5970* Vector expressions::
35485da9
DM
5971* Unary Operations::
5972* Binary Operations::
5973* Comparisons::
5974* Function calls::
15a65e63 5975* Function pointers::
35485da9
DM
5976* Type-coercion::
5977
5978@end menu
5979
6069fe72 5980@node Simple expressions,Vector expressions,,Rvalues
0981cf96 5981@anchor{topics/expressions simple-expressions}@anchor{9a}
35485da9
DM
5982@subsubsection Simple expressions
5983
5984
5985@geindex gcc_jit_context_new_rvalue_from_int (C function)
6f7585de 5986@anchor{topics/expressions c gcc_jit_context_new_rvalue_from_int}@anchor{30}
35485da9
DM
5987@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_rvalue_from_int (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type, int@w{ }value)
5988
5989Given a numeric type (integer or floating point), build an rvalue for
ccce3b2a
DM
5990the given constant @code{int} value.
5991@end deffn
5992
5993@geindex gcc_jit_context_new_rvalue_from_long (C function)
0981cf96 5994@anchor{topics/expressions c gcc_jit_context_new_rvalue_from_long}@anchor{9b}
ccce3b2a
DM
5995@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_rvalue_from_long (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type, long@w{ }value)
5996
5997Given a numeric type (integer or floating point), build an rvalue for
5998the given constant @code{long} value.
35485da9
DM
5999@end deffn
6000
6001@geindex gcc_jit_context_zero (C function)
6f7585de 6002@anchor{topics/expressions c gcc_jit_context_zero}@anchor{2b}
35485da9
DM
6003@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_zero (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type)
6004
6005Given a numeric type (integer or floating point), get the rvalue for
6006zero. Essentially this is just a shortcut for:
6007
6008@example
6009gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0)
6010@end example
35485da9
DM
6011@end deffn
6012
6013@geindex gcc_jit_context_one (C function)
6f7585de 6014@anchor{topics/expressions c gcc_jit_context_one}@anchor{2f}
35485da9
DM
6015@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_one (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type)
6016
6017Given a numeric type (integer or floating point), get the rvalue for
51c5c6b5 6018one. Essentially this is just a shortcut for:
35485da9
DM
6019
6020@example
6021gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1)
6022@end example
35485da9
DM
6023@end deffn
6024
6025@geindex gcc_jit_context_new_rvalue_from_double (C function)
6f7585de 6026@anchor{topics/expressions c gcc_jit_context_new_rvalue_from_double}@anchor{31}
35485da9
DM
6027@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_rvalue_from_double (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type, double@w{ }value)
6028
6029Given a numeric type (integer or floating point), build an rvalue for
ccce3b2a 6030the given constant @code{double} value.
35485da9
DM
6031@end deffn
6032
6033@geindex gcc_jit_context_new_rvalue_from_ptr (C function)
0981cf96 6034@anchor{topics/expressions c gcc_jit_context_new_rvalue_from_ptr}@anchor{9c}
35485da9
DM
6035@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*pointer_type, void@w{ }*value)
6036
6037Given a pointer type, build an rvalue for the given address.
6038@end deffn
6039
6040@geindex gcc_jit_context_null (C function)
0981cf96 6041@anchor{topics/expressions c gcc_jit_context_null}@anchor{9d}
35485da9
DM
6042@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_null (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*pointer_type)
6043
6044Given a pointer type, build an rvalue for @code{NULL}. Essentially this
6045is just a shortcut for:
6046
6047@example
6048gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL)
6049@end example
35485da9
DM
6050@end deffn
6051
6052@geindex gcc_jit_context_new_string_literal (C function)
0981cf96 6053@anchor{topics/expressions c gcc_jit_context_new_string_literal}@anchor{9e}
35485da9
DM
6054@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_string_literal (gcc_jit_context@w{ }*ctxt, const char@w{ }*value)
6055
6056Generate an rvalue for the given NIL-terminated string, of type
6057@code{GCC_JIT_TYPE_CONST_CHAR_PTR}.
c575221a
DM
6058
6059The parameter @code{value} must be non-NULL. The call takes a copy of the
6060underlying string, so it is valid to pass in a pointer to an on-stack
6061buffer.
35485da9
DM
6062@end deffn
6063
6069fe72 6064@node Vector expressions,Unary Operations,Simple expressions,Rvalues
0981cf96 6065@anchor{topics/expressions vector-expressions}@anchor{9f}
6069fe72
DM
6066@subsubsection Vector expressions
6067
6068
6069@geindex gcc_jit_context_new_rvalue_from_vector (C function)
6f7585de 6070@anchor{topics/expressions c gcc_jit_context_new_rvalue_from_vector}@anchor{87}
6069fe72
DM
6071@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_rvalue_from_vector (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*vec_type, size_t@w{ }num_elements, gcc_jit_rvalue@w{ }**elements)
6072
6073Build a vector rvalue from an array of elements.
6074
6f7585de
DM
6075“vec_type” should be a vector type, created using
6076@ref{85,,gcc_jit_type_get_vector()}.
6069fe72 6077
6f7585de 6078“num_elements” should match that of the vector type.
6069fe72 6079
0981cf96 6080This entrypoint was added in @ref{a0,,LIBGCCJIT_ABI_10}; you can test for
6069fe72
DM
6081its presence using
6082
6083@example
6084#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_rvalue_from_vector
6085@end example
6069fe72
DM
6086@end deffn
6087
6088@node Unary Operations,Binary Operations,Vector expressions,Rvalues
0981cf96 6089@anchor{topics/expressions unary-operations}@anchor{a1}
35485da9
DM
6090@subsubsection Unary Operations
6091
6092
6093@geindex gcc_jit_context_new_unary_op (C function)
0981cf96 6094@anchor{topics/expressions c gcc_jit_context_new_unary_op}@anchor{a2}
35485da9
DM
6095@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_unary_op (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, enum gcc_jit_unary_op@w{ }op, gcc_jit_type@w{ }*result_type, gcc_jit_rvalue@w{ }*rvalue)
6096
6097Build a unary operation out of an input rvalue.
6f7585de
DM
6098
6099The parameter @code{result_type} must be a numeric type.
35485da9
DM
6100@end deffn
6101
6102@geindex gcc_jit_unary_op (C type)
0981cf96 6103@anchor{topics/expressions c gcc_jit_unary_op}@anchor{a3}
35485da9
DM
6104@deffn {C Type} enum gcc_jit_unary_op
6105@end deffn
6106
6107The available unary operations are:
6108
6109
6110@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx}
6111@headitem
6112
6113Unary Operation
6114
6115@tab
6116
6117C equivalent
6118
6119@item
6120
0981cf96 6121@ref{a4,,GCC_JIT_UNARY_OP_MINUS}
35485da9
DM
6122
6123@tab
6124
6125@cite{-(EXPR)}
6126
6127@item
6128
0981cf96 6129@ref{a5,,GCC_JIT_UNARY_OP_BITWISE_NEGATE}
35485da9
DM
6130
6131@tab
6132
6133@cite{~(EXPR)}
6134
6135@item
6136
0981cf96 6137@ref{a6,,GCC_JIT_UNARY_OP_LOGICAL_NEGATE}
35485da9
DM
6138
6139@tab
6140
6141@cite{!(EXPR)}
6142
18146f45
DM
6143@item
6144
0981cf96 6145@ref{a7,,GCC_JIT_UNARY_OP_ABS}
18146f45
DM
6146
6147@tab
6148
6149@cite{abs (EXPR)}
6150
35485da9
DM
6151@end multitable
6152
6153
6154@geindex GCC_JIT_UNARY_OP_MINUS (C macro)
0981cf96 6155@anchor{topics/expressions c GCC_JIT_UNARY_OP_MINUS}@anchor{a4}
35485da9
DM
6156@deffn {C Macro} GCC_JIT_UNARY_OP_MINUS
6157
6158Negate an arithmetic value; analogous to:
6159
6160@example
6161-(EXPR)
6162@end example
6163
35485da9
DM
6164in C.
6165@end deffn
6166
6167@geindex GCC_JIT_UNARY_OP_BITWISE_NEGATE (C macro)
0981cf96 6168@anchor{topics/expressions c GCC_JIT_UNARY_OP_BITWISE_NEGATE}@anchor{a5}
35485da9
DM
6169@deffn {C Macro} GCC_JIT_UNARY_OP_BITWISE_NEGATE
6170
6f7585de 6171Bitwise negation of an integer value (one’s complement); analogous
35485da9
DM
6172to:
6173
6174@example
6175~(EXPR)
6176@end example
6177
35485da9
DM
6178in C.
6179@end deffn
6180
6181@geindex GCC_JIT_UNARY_OP_LOGICAL_NEGATE (C macro)
0981cf96 6182@anchor{topics/expressions c GCC_JIT_UNARY_OP_LOGICAL_NEGATE}@anchor{a6}
35485da9
DM
6183@deffn {C Macro} GCC_JIT_UNARY_OP_LOGICAL_NEGATE
6184
6185Logical negation of an arithmetic or pointer value; analogous to:
6186
6187@example
6188!(EXPR)
6189@end example
6190
35485da9
DM
6191in C.
6192@end deffn
6193
18146f45 6194@geindex GCC_JIT_UNARY_OP_ABS (C macro)
0981cf96 6195@anchor{topics/expressions c GCC_JIT_UNARY_OP_ABS}@anchor{a7}
18146f45
DM
6196@deffn {C Macro} GCC_JIT_UNARY_OP_ABS
6197
6198Absolute value of an arithmetic expression; analogous to:
6199
6200@example
6201abs (EXPR)
6202@end example
6203
18146f45
DM
6204in C.
6205@end deffn
6206
35485da9 6207@node Binary Operations,Comparisons,Unary Operations,Rvalues
0981cf96 6208@anchor{topics/expressions binary-operations}@anchor{a8}
35485da9
DM
6209@subsubsection Binary Operations
6210
6211
6212@geindex gcc_jit_context_new_binary_op (C function)
6f7585de 6213@anchor{topics/expressions c gcc_jit_context_new_binary_op}@anchor{12}
35485da9
DM
6214@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_new_binary_op (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, enum gcc_jit_binary_op@w{ }op, gcc_jit_type@w{ }*result_type, gcc_jit_rvalue@w{ }*a, gcc_jit_rvalue@w{ }*b)
6215
6216Build a binary operation out of two constituent rvalues.
6f7585de
DM
6217
6218The parameter @code{result_type} must be a numeric type.
35485da9
DM
6219@end deffn
6220
6221@geindex gcc_jit_binary_op (C type)
0981cf96 6222@anchor{topics/expressions c gcc_jit_binary_op}@anchor{a9}
35485da9
DM
6223@deffn {C Type} enum gcc_jit_binary_op
6224@end deffn
6225
6226The available binary operations are:
6227
6228
6229@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx}
6230@headitem
6231
6232Binary Operation
6233
6234@tab
6235
6236C equivalent
6237
6238@item
6239
0981cf96 6240@ref{aa,,GCC_JIT_BINARY_OP_PLUS}
35485da9
DM
6241
6242@tab
6243
6244@cite{x + y}
6245
6246@item
6247
0981cf96 6248@ref{ab,,GCC_JIT_BINARY_OP_MINUS}
35485da9
DM
6249
6250@tab
6251
6252@cite{x - y}
6253
6254@item
6255
0981cf96 6256@ref{ac,,GCC_JIT_BINARY_OP_MULT}
35485da9
DM
6257
6258@tab
6259
6260@cite{x * y}
6261
6262@item
6263
0981cf96 6264@ref{ad,,GCC_JIT_BINARY_OP_DIVIDE}
35485da9
DM
6265
6266@tab
6267
6268@cite{x / y}
6269
6270@item
6271
0981cf96 6272@ref{ae,,GCC_JIT_BINARY_OP_MODULO}
35485da9
DM
6273
6274@tab
6275
6276@cite{x % y}
6277
6278@item
6279
0981cf96 6280@ref{af,,GCC_JIT_BINARY_OP_BITWISE_AND}
35485da9
DM
6281
6282@tab
6283
6284@cite{x & y}
6285
6286@item
6287
0981cf96 6288@ref{b0,,GCC_JIT_BINARY_OP_BITWISE_XOR}
35485da9
DM
6289
6290@tab
6291
6292@cite{x ^ y}
6293
6294@item
6295
0981cf96 6296@ref{b1,,GCC_JIT_BINARY_OP_BITWISE_OR}
35485da9
DM
6297
6298@tab
6299
6300@cite{x | y}
6301
6302@item
6303
0981cf96 6304@ref{b2,,GCC_JIT_BINARY_OP_LOGICAL_AND}
35485da9
DM
6305
6306@tab
6307
6308@cite{x && y}
6309
6310@item
6311
0981cf96 6312@ref{b3,,GCC_JIT_BINARY_OP_LOGICAL_OR}
35485da9
DM
6313
6314@tab
6315
6316@cite{x || y}
6317
6318@item
6319
0981cf96 6320@ref{b4,,GCC_JIT_BINARY_OP_LSHIFT}
35485da9
DM
6321
6322@tab
6323
6324@cite{x << y}
6325
6326@item
6327
0981cf96 6328@ref{b5,,GCC_JIT_BINARY_OP_RSHIFT}
35485da9
DM
6329
6330@tab
6331
6332@cite{x >> y}
6333
6334@end multitable
6335
6336
6337@geindex GCC_JIT_BINARY_OP_PLUS (C macro)
0981cf96 6338@anchor{topics/expressions c GCC_JIT_BINARY_OP_PLUS}@anchor{aa}
35485da9
DM
6339@deffn {C Macro} GCC_JIT_BINARY_OP_PLUS
6340
6341Addition of arithmetic values; analogous to:
6342
6343@example
6344(EXPR_A) + (EXPR_B)
6345@end example
6346
35485da9
DM
6347in C.
6348
0981cf96 6349For pointer addition, use @ref{b6,,gcc_jit_context_new_array_access()}.
35485da9
DM
6350@end deffn
6351
7ef96183 6352@geindex GCC_JIT_BINARY_OP_MINUS (C macro)
0981cf96 6353@anchor{topics/expressions c GCC_JIT_BINARY_OP_MINUS}@anchor{ab}
7ef96183 6354@deffn {C Macro} GCC_JIT_BINARY_OP_MINUS
35485da9
DM
6355
6356Subtraction of arithmetic values; analogous to:
6357
6358@example
6359(EXPR_A) - (EXPR_B)
6360@end example
6361
35485da9
DM
6362in C.
6363@end deffn
6364
6365@geindex GCC_JIT_BINARY_OP_MULT (C macro)
0981cf96 6366@anchor{topics/expressions c GCC_JIT_BINARY_OP_MULT}@anchor{ac}
35485da9
DM
6367@deffn {C Macro} GCC_JIT_BINARY_OP_MULT
6368
6369Multiplication of a pair of arithmetic values; analogous to:
6370
6371@example
6372(EXPR_A) * (EXPR_B)
6373@end example
6374
35485da9
DM
6375in C.
6376@end deffn
6377
6378@geindex GCC_JIT_BINARY_OP_DIVIDE (C macro)
0981cf96 6379@anchor{topics/expressions c GCC_JIT_BINARY_OP_DIVIDE}@anchor{ad}
35485da9
DM
6380@deffn {C Macro} GCC_JIT_BINARY_OP_DIVIDE
6381
6382Quotient of division of arithmetic values; analogous to:
6383
6384@example
6385(EXPR_A) / (EXPR_B)
6386@end example
6387
35485da9
DM
6388in C.
6389
6390The result type affects the kind of division: if the result type is
6391integer-based, then the result is truncated towards zero, whereas
6392a floating-point result type indicates floating-point division.
6393@end deffn
6394
6395@geindex GCC_JIT_BINARY_OP_MODULO (C macro)
0981cf96 6396@anchor{topics/expressions c GCC_JIT_BINARY_OP_MODULO}@anchor{ae}
35485da9
DM
6397@deffn {C Macro} GCC_JIT_BINARY_OP_MODULO
6398
6399Remainder of division of arithmetic values; analogous to:
6400
6401@example
6402(EXPR_A) % (EXPR_B)
6403@end example
6404
35485da9
DM
6405in C.
6406@end deffn
6407
6408@geindex GCC_JIT_BINARY_OP_BITWISE_AND (C macro)
0981cf96 6409@anchor{topics/expressions c GCC_JIT_BINARY_OP_BITWISE_AND}@anchor{af}
35485da9
DM
6410@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_AND
6411
6412Bitwise AND; analogous to:
6413
6414@example
6415(EXPR_A) & (EXPR_B)
6416@end example
6417
35485da9
DM
6418in C.
6419@end deffn
6420
6421@geindex GCC_JIT_BINARY_OP_BITWISE_XOR (C macro)
0981cf96 6422@anchor{topics/expressions c GCC_JIT_BINARY_OP_BITWISE_XOR}@anchor{b0}
35485da9
DM
6423@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_XOR
6424
6425Bitwise exclusive OR; analogous to:
6426
6427@example
6428(EXPR_A) ^ (EXPR_B)
6429@end example
6430
35485da9
DM
6431in C.
6432@end deffn
6433
6434@geindex GCC_JIT_BINARY_OP_BITWISE_OR (C macro)
0981cf96 6435@anchor{topics/expressions c GCC_JIT_BINARY_OP_BITWISE_OR}@anchor{b1}
35485da9
DM
6436@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_OR
6437
6438Bitwise inclusive OR; analogous to:
6439
6440@example
6441(EXPR_A) | (EXPR_B)
6442@end example
6443
35485da9
DM
6444in C.
6445@end deffn
6446
6447@geindex GCC_JIT_BINARY_OP_LOGICAL_AND (C macro)
0981cf96 6448@anchor{topics/expressions c GCC_JIT_BINARY_OP_LOGICAL_AND}@anchor{b2}
35485da9
DM
6449@deffn {C Macro} GCC_JIT_BINARY_OP_LOGICAL_AND
6450
6451Logical AND; analogous to:
6452
6453@example
6454(EXPR_A) && (EXPR_B)
6455@end example
6456
35485da9
DM
6457in C.
6458@end deffn
6459
6460@geindex GCC_JIT_BINARY_OP_LOGICAL_OR (C macro)
0981cf96 6461@anchor{topics/expressions c GCC_JIT_BINARY_OP_LOGICAL_OR}@anchor{b3}
35485da9
DM
6462@deffn {C Macro} GCC_JIT_BINARY_OP_LOGICAL_OR
6463
6464Logical OR; analogous to:
6465
6466@example
6467(EXPR_A) || (EXPR_B)
6468@end example
6469
35485da9
DM
6470in C.
6471@end deffn
6472
6473@geindex GCC_JIT_BINARY_OP_LSHIFT (C macro)
0981cf96 6474@anchor{topics/expressions c GCC_JIT_BINARY_OP_LSHIFT}@anchor{b4}
35485da9
DM
6475@deffn {C Macro} GCC_JIT_BINARY_OP_LSHIFT
6476
6477Left shift; analogous to:
6478
6479@example
6480(EXPR_A) << (EXPR_B)
6481@end example
6482
35485da9
DM
6483in C.
6484@end deffn
6485
6486@geindex GCC_JIT_BINARY_OP_RSHIFT (C macro)
0981cf96 6487@anchor{topics/expressions c GCC_JIT_BINARY_OP_RSHIFT}@anchor{b5}
35485da9
DM
6488@deffn {C Macro} GCC_JIT_BINARY_OP_RSHIFT
6489
6490Right shift; analogous to:
6491
6492@example
6493(EXPR_A) >> (EXPR_B)
6494@end example
6495
35485da9
DM
6496in C.
6497@end deffn
6498
6499@node Comparisons,Function calls,Binary Operations,Rvalues
0981cf96 6500@anchor{topics/expressions comparisons}@anchor{b7}
35485da9
DM
6501@subsubsection Comparisons
6502
6503
6504@geindex gcc_jit_context_new_comparison (C function)
6f7585de 6505@anchor{topics/expressions c gcc_jit_context_new_comparison}@anchor{2c}
35485da9
DM
6506@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_comparison (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, enum gcc_jit_comparison@w{ }op, gcc_jit_rvalue@w{ }*a, gcc_jit_rvalue@w{ }*b)
6507
6508Build a boolean rvalue out of the comparison of two other rvalues.
6509@end deffn
6510
6511@geindex gcc_jit_comparison (C type)
0981cf96 6512@anchor{topics/expressions c gcc_jit_comparison}@anchor{b8}
35485da9
DM
6513@deffn {C Type} enum gcc_jit_comparison
6514@end deffn
6515
6516
6517@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx}
6518@headitem
6519
6520Comparison
6521
6522@tab
6523
6524C equivalent
6525
6526@item
6527
6528@code{GCC_JIT_COMPARISON_EQ}
6529
6530@tab
6531
6532@cite{x == y}
6533
6534@item
6535
6536@code{GCC_JIT_COMPARISON_NE}
6537
6538@tab
6539
6540@cite{x != y}
6541
6542@item
6543
6544@code{GCC_JIT_COMPARISON_LT}
6545
6546@tab
6547
6548@cite{x < y}
6549
6550@item
6551
6552@code{GCC_JIT_COMPARISON_LE}
6553
6554@tab
6555
6556@cite{x <= y}
6557
6558@item
6559
6560@code{GCC_JIT_COMPARISON_GT}
6561
6562@tab
6563
6564@cite{x > y}
6565
6566@item
6567
6568@code{GCC_JIT_COMPARISON_GE}
6569
6570@tab
6571
6572@cite{x >= y}
6573
6574@end multitable
6575
6576
15a65e63 6577@node Function calls,Function pointers,Comparisons,Rvalues
0981cf96 6578@anchor{topics/expressions function-calls}@anchor{b9}
35485da9
DM
6579@subsubsection Function calls
6580
6581
6582@geindex gcc_jit_context_new_call (C function)
0981cf96 6583@anchor{topics/expressions c gcc_jit_context_new_call}@anchor{ba}
35485da9
DM
6584@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_call (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_function@w{ }*func, int@w{ }numargs, gcc_jit_rvalue@w{ }**args)
6585
6586Given a function and the given table of argument rvalues, construct a
6587call to the function, with the result as an rvalue.
6588
6589@cartouche
6590@quotation Note
0981cf96 6591@ref{ba,,gcc_jit_context_new_call()} merely builds a
6f7585de 6592@ref{13,,gcc_jit_rvalue} i.e. an expression that can be evaluated,
35485da9 6593perhaps as part of a more complicated expression.
6f7585de 6594The call @emph{won’t} happen unless you add a statement to a function
35485da9
DM
6595that evaluates the expression.
6596
6597For example, if you want to call a function and discard the result
6598(or to call a function with @code{void} return type), use
0981cf96 6599@ref{bb,,gcc_jit_block_add_eval()}:
35485da9
DM
6600
6601@example
6602/* Add "(void)printf (arg0, arg1);". */
6603gcc_jit_block_add_eval (
6604 block, NULL,
6605 gcc_jit_context_new_call (
6606 ctxt,
6607 NULL,
6608 printf_func,
6609 2, args));
6610@end example
35485da9
DM
6611@end quotation
6612@end cartouche
6613@end deffn
6614
f51703a8 6615@geindex gcc_jit_context_new_call_through_ptr (C function)
0981cf96 6616@anchor{topics/expressions c gcc_jit_context_new_call_through_ptr}@anchor{bc}
f51703a8
DM
6617@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_call_through_ptr (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*fn_ptr, int@w{ }numargs, gcc_jit_rvalue@w{ }**args)
6618
ecd5156d 6619Given an rvalue of function pointer type (e.g. from
0981cf96 6620@ref{95,,gcc_jit_context_new_function_ptr_type()}), and the given table of
f51703a8
DM
6621argument rvalues, construct a call to the function pointer, with the
6622result as an rvalue.
6623
6624@cartouche
6625@quotation Note
0981cf96 6626The same caveat as for @ref{ba,,gcc_jit_context_new_call()} applies.
f51703a8
DM
6627@end quotation
6628@end cartouche
6629@end deffn
6630
0ebd1f00 6631@geindex gcc_jit_rvalue_set_bool_require_tail_call (C function)
0981cf96 6632@anchor{topics/expressions c gcc_jit_rvalue_set_bool_require_tail_call}@anchor{bd}
0ebd1f00
DM
6633@deffn {C Function} void gcc_jit_rvalue_set_bool_require_tail_call (gcc_jit_rvalue@w{ }*call, int@w{ }require_tail_call)
6634
6f7585de 6635Given an @ref{13,,gcc_jit_rvalue *} for a call created through
0981cf96
DM
6636@ref{ba,,gcc_jit_context_new_call()} or
6637@ref{bc,,gcc_jit_context_new_call_through_ptr()}, mark/clear the
0ebd1f00
DM
6638call as needing tail-call optimization. The optimizer will
6639attempt to optimize the call into a jump instruction; if it is
6640unable to do do, an error will be emitted.
6641
6642This may be useful when implementing functions that use the
6643continuation-passing style (e.g. for functional programming
6f7585de
DM
6644languages), in which every function “returns” by calling a
6645“continuation” function pointer. This call must be
0ebd1f00
DM
6646guaranteed to be implemented as a jump, otherwise the program
6647could consume an arbitrary amount of stack space as it executed.
6648
0981cf96 6649This entrypoint was added in @ref{be,,LIBGCCJIT_ABI_6}; you can test for
0ebd1f00
DM
6650its presence using
6651
6652@example
6653#ifdef LIBGCCJIT_HAVE_gcc_jit_rvalue_set_bool_require_tail_call
6654@end example
0ebd1f00
DM
6655@end deffn
6656
15a65e63 6657@node Function pointers,Type-coercion,Function calls,Rvalues
0981cf96 6658@anchor{topics/expressions function-pointers}@anchor{bf}
15a65e63
DM
6659@subsubsection Function pointers
6660
6661
ecd5156d 6662Function pointers can be obtained:
15a65e63 6663
ecd5156d 6664@quotation
15a65e63 6665
15a65e63 6666
ecd5156d 6667@itemize *
15a65e63 6668
ecd5156d 6669@item
6f7585de 6670from a @ref{29,,gcc_jit_function} using
0981cf96 6671@ref{c0,,gcc_jit_function_get_address()}, or
ecd5156d
DM
6672
6673@item
6674from an existing function using
0981cf96 6675@ref{9c,,gcc_jit_context_new_rvalue_from_ptr()},
ecd5156d 6676using a function pointer type obtained using
0981cf96 6677@ref{95,,gcc_jit_context_new_function_ptr_type()}.
ecd5156d
DM
6678@end itemize
6679@end quotation
15a65e63
DM
6680
6681@node Type-coercion,,Function pointers,Rvalues
0981cf96 6682@anchor{topics/expressions type-coercion}@anchor{c1}
35485da9
DM
6683@subsubsection Type-coercion
6684
6685
6686@geindex gcc_jit_context_new_cast (C function)
0981cf96 6687@anchor{topics/expressions c gcc_jit_context_new_cast}@anchor{c2}
35485da9
DM
6688@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_cast (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*rvalue, gcc_jit_type@w{ }*type)
6689
6690Given an rvalue of T, construct another rvalue of another type.
6691
6692Currently only a limited set of conversions are possible:
6693
6694@quotation
6695
6696
6697@itemize *
6698
6699@item
6700int <-> float
6701
6702@item
6703int <-> bool
6704
6705@item
6706P* <-> Q*, for pointer types P and Q
6707@end itemize
6708@end quotation
6709@end deffn
6710
6711@node Lvalues,Working with pointers structs and unions,Rvalues,Expressions
0981cf96 6712@anchor{topics/expressions lvalues}@anchor{c3}
35485da9
DM
6713@subsection Lvalues
6714
6715
6716@geindex gcc_jit_lvalue (C type)
6f7585de 6717@anchor{topics/expressions c gcc_jit_lvalue}@anchor{24}
35485da9
DM
6718@deffn {C Type} gcc_jit_lvalue
6719@end deffn
6720
6721An lvalue is something that can of the @emph{left}-hand side of an assignment:
6722a storage area (such as a variable). It is also usable as an rvalue,
6723where the rvalue is computed by reading from the storage area.
6724
6725@geindex gcc_jit_lvalue_as_object (C function)
0981cf96 6726@anchor{topics/expressions c gcc_jit_lvalue_as_object}@anchor{c4}
35485da9
DM
6727@deffn {C Function} gcc_jit_object * gcc_jit_lvalue_as_object (gcc_jit_lvalue@w{ }*lvalue)
6728
6729Upcast an lvalue to be an object.
6730@end deffn
6731
6732@geindex gcc_jit_lvalue_as_rvalue (C function)
0981cf96 6733@anchor{topics/expressions c gcc_jit_lvalue_as_rvalue}@anchor{c5}
35485da9
DM
6734@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue@w{ }*lvalue)
6735
6736Upcast an lvalue to be an rvalue.
6737@end deffn
6738
6739@geindex gcc_jit_lvalue_get_address (C function)
0981cf96 6740@anchor{topics/expressions c gcc_jit_lvalue_get_address}@anchor{c6}
35485da9
DM
6741@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_get_address (gcc_jit_lvalue@w{ }*lvalue, gcc_jit_location@w{ }*loc)
6742
6743Take the address of an lvalue; analogous to:
6744
6745@example
6746&(EXPR)
6747@end example
6748
35485da9
DM
6749in C.
6750@end deffn
6751
6752@menu
6753* Global variables::
6754
6755@end menu
6756
6757@node Global variables,,,Lvalues
0981cf96 6758@anchor{topics/expressions global-variables}@anchor{c7}
35485da9
DM
6759@subsubsection Global variables
6760
6761
6762@geindex gcc_jit_context_new_global (C function)
0981cf96 6763@anchor{topics/expressions c gcc_jit_context_new_global}@anchor{c8}
791cfef8 6764@deffn {C Function} gcc_jit_lvalue * gcc_jit_context_new_global (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, enum gcc_jit_global_kind@w{ }kind, gcc_jit_type@w{ }*type, const char@w{ }*name)
35485da9
DM
6765
6766Add a new global variable of the given type and name to the context.
791cfef8 6767
6f7585de
DM
6768The parameter @code{type} must be non-@cite{void}.
6769
c575221a
DM
6770The parameter @code{name} must be non-NULL. The call takes a copy of the
6771underlying string, so it is valid to pass in a pointer to an on-stack
6772buffer.
6773
6f7585de
DM
6774The “kind” parameter determines the visibility of the “global” outside
6775of the @ref{16,,gcc_jit_result}:
791cfef8
DM
6776
6777@geindex gcc_jit_global_kind (C type)
0981cf96 6778@anchor{topics/expressions c gcc_jit_global_kind}@anchor{c9}
791cfef8
DM
6779@deffn {C Type} enum gcc_jit_global_kind
6780@end deffn
6781
6782@geindex GCC_JIT_GLOBAL_EXPORTED (C macro)
0981cf96 6783@anchor{topics/expressions c GCC_JIT_GLOBAL_EXPORTED}@anchor{ca}
791cfef8
DM
6784@deffn {C Macro} GCC_JIT_GLOBAL_EXPORTED
6785
6786Global is defined by the client code and is visible
6787by name outside of this JIT context via
0981cf96 6788@ref{cb,,gcc_jit_result_get_global()} (and this value is required for
791cfef8
DM
6789the global to be accessible via that entrypoint).
6790@end deffn
6791
6792@geindex GCC_JIT_GLOBAL_INTERNAL (C macro)
0981cf96 6793@anchor{topics/expressions c GCC_JIT_GLOBAL_INTERNAL}@anchor{cc}
791cfef8
DM
6794@deffn {C Macro} GCC_JIT_GLOBAL_INTERNAL
6795
6796Global is defined by the client code, but is invisible
6f7585de 6797outside of it. Analogous to a “static” global within a .c file.
791cfef8
DM
6798Specifically, the variable will only be visible within this
6799context and within child contexts.
6800@end deffn
6801
6802@geindex GCC_JIT_GLOBAL_IMPORTED (C macro)
0981cf96 6803@anchor{topics/expressions c GCC_JIT_GLOBAL_IMPORTED}@anchor{cd}
791cfef8
DM
6804@deffn {C Macro} GCC_JIT_GLOBAL_IMPORTED
6805
6f7585de
DM
6806Global is not defined by the client code; we’re merely
6807referring to it. Analogous to using an “extern” global from a
791cfef8
DM
6808header file.
6809@end deffn
35485da9
DM
6810@end deffn
6811
02321f62
AC
6812@geindex gcc_jit_global_set_initializer (C function)
6813@anchor{topics/expressions c gcc_jit_global_set_initializer}@anchor{ce}
6814@deffn {C Function} gcc_jit_lvalue * gcc_jit_global_set_initializer (gcc_jit_lvalue@w{ }*global, const void@w{ }*blob, size_t@w{ }num_bytes)
6815
6816Set an initializer for @code{global} using the memory content pointed
6817by @code{blob} for @code{num_bytes}. @code{global} must be an array of an
6818integral type. Return the global itself.
6819
6820The parameter @code{blob} must be non-NULL. The call copies the memory
6821pointed by @code{blob} for @code{num_bytes} bytes, so it is valid to pass
6822in a pointer to an on-stack buffer. The content will be stored in
6823the compilation unit and used as initialization value of the array.
6824
6825This entrypoint was added in @ref{cf,,LIBGCCJIT_ABI_14}; you can test for
6826its presence using
6827
6828@example
6829#ifdef LIBGCCJIT_HAVE_gcc_jit_global_set_initializer
6830@end example
6831@end deffn
6832
35485da9 6833@node Working with pointers structs and unions,,Lvalues,Expressions
02321f62 6834@anchor{topics/expressions working-with-pointers-structs-and-unions}@anchor{d0}
35485da9
DM
6835@subsection Working with pointers, structs and unions
6836
6837
6838@geindex gcc_jit_rvalue_dereference (C function)
02321f62 6839@anchor{topics/expressions c gcc_jit_rvalue_dereference}@anchor{d1}
35485da9
DM
6840@deffn {C Function} gcc_jit_lvalue * gcc_jit_rvalue_dereference (gcc_jit_rvalue@w{ }*rvalue, gcc_jit_location@w{ }*loc)
6841
6842Given an rvalue of pointer type @code{T *}, dereferencing the pointer,
6843getting an lvalue of type @code{T}. Analogous to:
6844
6845@example
6846*(EXPR)
6847@end example
6848
35485da9
DM
6849in C.
6850@end deffn
6851
6852Field access is provided separately for both lvalues and rvalues.
6853
6854@geindex gcc_jit_lvalue_access_field (C function)
02321f62 6855@anchor{topics/expressions c gcc_jit_lvalue_access_field}@anchor{d2}
35485da9
DM
6856@deffn {C Function} gcc_jit_lvalue * gcc_jit_lvalue_access_field (gcc_jit_lvalue@w{ }*struct_, gcc_jit_location@w{ }*loc, gcc_jit_field@w{ }*field)
6857
6858Given an lvalue of struct or union type, access the given field,
6f7585de 6859getting an lvalue of the field’s type. Analogous to:
35485da9
DM
6860
6861@example
6862(EXPR).field = ...;
6863@end example
6864
35485da9
DM
6865in C.
6866@end deffn
6867
6868@geindex gcc_jit_rvalue_access_field (C function)
02321f62 6869@anchor{topics/expressions c gcc_jit_rvalue_access_field}@anchor{d3}
35485da9
DM
6870@deffn {C Function} gcc_jit_rvalue * gcc_jit_rvalue_access_field (gcc_jit_rvalue@w{ }*struct_, gcc_jit_location@w{ }*loc, gcc_jit_field@w{ }*field)
6871
6872Given an rvalue of struct or union type, access the given field
6873as an rvalue. Analogous to:
6874
6875@example
6876(EXPR).field
6877@end example
6878
35485da9
DM
6879in C.
6880@end deffn
6881
6882@geindex gcc_jit_rvalue_dereference_field (C function)
02321f62 6883@anchor{topics/expressions c gcc_jit_rvalue_dereference_field}@anchor{d4}
35485da9
DM
6884@deffn {C Function} gcc_jit_lvalue * gcc_jit_rvalue_dereference_field (gcc_jit_rvalue@w{ }*ptr, gcc_jit_location@w{ }*loc, gcc_jit_field@w{ }*field)
6885
6886Given an rvalue of pointer type @code{T *} where T is of struct or union
6887type, access the given field as an lvalue. Analogous to:
6888
6889@example
6890(EXPR)->field
6891@end example
6892
35485da9
DM
6893in C, itself equivalent to @code{(*EXPR).FIELD}.
6894@end deffn
6895
6896@geindex gcc_jit_context_new_array_access (C function)
0981cf96 6897@anchor{topics/expressions c gcc_jit_context_new_array_access}@anchor{b6}
35485da9
DM
6898@deffn {C Function} gcc_jit_lvalue * gcc_jit_context_new_array_access (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*ptr, gcc_jit_rvalue@w{ }*index)
6899
6900Given an rvalue of pointer type @code{T *}, get at the element @cite{T} at
6901the given index, using standard C array indexing rules i.e. each
6902increment of @code{index} corresponds to @code{sizeof(T)} bytes.
6903Analogous to:
6904
6905@example
6906PTR[INDEX]
6907@end example
6908
35485da9
DM
6909in C (or, indeed, to @code{PTR + INDEX}).
6910@end deffn
6911
7adcbafe 6912@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
6913@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
6914@c
6915@c This is free software: you can redistribute it and/or modify it
6916@c under the terms of the GNU General Public License as published by
6917@c the Free Software Foundation, either version 3 of the License, or
6918@c (at your option) any later version.
6919@c
6920@c This program is distributed in the hope that it will be useful, but
6921@c WITHOUT ANY WARRANTY; without even the implied warranty of
6922@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6923@c General Public License for more details.
6924@c
6925@c You should have received a copy of the GNU General Public License
6926@c along with this program. If not, see
786973ce 6927@c <https://www.gnu.org/licenses/>.
35485da9 6928
ecd5156d 6929@node Creating and using functions,Function pointers<2>,Expressions,Topic Reference
02321f62 6930@anchor{topics/functions doc}@anchor{d5}@anchor{topics/functions creating-and-using-functions}@anchor{d6}
35485da9
DM
6931@section Creating and using functions
6932
6933
6934@menu
6935* Params::
6936* Functions::
6937* Blocks::
6938* Statements::
6939
6940@end menu
6941
6942@node Params,Functions,,Creating and using functions
02321f62 6943@anchor{topics/functions params}@anchor{d7}
35485da9
DM
6944@subsection Params
6945
6946
6947@geindex gcc_jit_param (C type)
6f7585de 6948@anchor{topics/functions c gcc_jit_param}@anchor{25}
35485da9
DM
6949@deffn {C Type} gcc_jit_param
6950
6951A @cite{gcc_jit_param} represents a parameter to a function.
6952@end deffn
6953
6954@geindex gcc_jit_context_new_param (C function)
6f7585de 6955@anchor{topics/functions c gcc_jit_context_new_param}@anchor{10}
35485da9
DM
6956@deffn {C Function} gcc_jit_param * gcc_jit_context_new_param (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, const char@w{ }*name)
6957
6958In preparation for creating a function, create a new parameter of the
6959given type and name.
c575221a 6960
6f7585de
DM
6961The parameter @code{type} must be non-@cite{void}.
6962
c575221a
DM
6963The parameter @code{name} must be non-NULL. The call takes a copy of the
6964underlying string, so it is valid to pass in a pointer to an on-stack
6965buffer.
35485da9
DM
6966@end deffn
6967
6968Parameters are lvalues, and thus are also rvalues (and objects), so the
6969following upcasts are available:
6970
6971@geindex gcc_jit_param_as_lvalue (C function)
02321f62 6972@anchor{topics/functions c gcc_jit_param_as_lvalue}@anchor{d8}
35485da9
DM
6973@deffn {C Function} gcc_jit_lvalue * gcc_jit_param_as_lvalue (gcc_jit_param@w{ }*param)
6974
6975Upcasting from param to lvalue.
6976@end deffn
6977
6978@geindex gcc_jit_param_as_rvalue (C function)
02321f62 6979@anchor{topics/functions c gcc_jit_param_as_rvalue}@anchor{d9}
35485da9
DM
6980@deffn {C Function} gcc_jit_rvalue * gcc_jit_param_as_rvalue (gcc_jit_param@w{ }*param)
6981
6982Upcasting from param to rvalue.
6983@end deffn
6984
6985@geindex gcc_jit_param_as_object (C function)
02321f62 6986@anchor{topics/functions c gcc_jit_param_as_object}@anchor{da}
35485da9
DM
6987@deffn {C Function} gcc_jit_object * gcc_jit_param_as_object (gcc_jit_param@w{ }*param)
6988
6989Upcasting from param to object.
6990@end deffn
6991
6992@node Functions,Blocks,Params,Creating and using functions
02321f62 6993@anchor{topics/functions functions}@anchor{db}
35485da9
DM
6994@subsection Functions
6995
6996
6997@geindex gcc_jit_function (C type)
6f7585de 6998@anchor{topics/functions c gcc_jit_function}@anchor{29}
35485da9
DM
6999@deffn {C Type} gcc_jit_function
7000
6f7585de
DM
7001A @cite{gcc_jit_function} represents a function - either one that we’re
7002creating ourselves, or one that we’re referencing.
35485da9
DM
7003@end deffn
7004
7005@geindex gcc_jit_context_new_function (C function)
6f7585de 7006@anchor{topics/functions c gcc_jit_context_new_function}@anchor{11}
35485da9
DM
7007@deffn {C Function} gcc_jit_function * gcc_jit_context_new_function (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, enum gcc_jit_function_kind@w{ }kind, gcc_jit_type@w{ }*return_type, const char@w{ }*name, int@w{ }num_params, gcc_jit_param@w{ }**params, int@w{ }is_variadic)
7008
7009Create a gcc_jit_function with the given name and parameters.
7010
7011@geindex gcc_jit_function_kind (C type)
02321f62 7012@anchor{topics/functions c gcc_jit_function_kind}@anchor{dc}
35485da9
DM
7013@deffn {C Type} enum gcc_jit_function_kind
7014@end deffn
7015
7016This enum controls the kind of function created, and has the following
7017values:
7018
7019@quotation
7020
7021@geindex GCC_JIT_FUNCTION_EXPORTED (C macro)
02321f62 7022@anchor{topics/functions c GCC_JIT_FUNCTION_EXPORTED}@anchor{dd}
35485da9
DM
7023@deffn {C Macro} GCC_JIT_FUNCTION_EXPORTED
7024
7025Function is defined by the client code and visible
7026by name outside of the JIT.
81ba15f1
DM
7027
7028This value is required if you want to extract machine code
6f7585de
DM
7029for this function from a @ref{16,,gcc_jit_result} via
7030@ref{17,,gcc_jit_result_get_code()}.
35485da9
DM
7031@end deffn
7032
7033@geindex GCC_JIT_FUNCTION_INTERNAL (C macro)
02321f62 7034@anchor{topics/functions c GCC_JIT_FUNCTION_INTERNAL}@anchor{de}
35485da9
DM
7035@deffn {C Macro} GCC_JIT_FUNCTION_INTERNAL
7036
7037Function is defined by the client code, but is invisible
6f7585de 7038outside of the JIT. Analogous to a “static” function.
35485da9
DM
7039@end deffn
7040
7041@geindex GCC_JIT_FUNCTION_IMPORTED (C macro)
02321f62 7042@anchor{topics/functions c GCC_JIT_FUNCTION_IMPORTED}@anchor{df}
35485da9
DM
7043@deffn {C Macro} GCC_JIT_FUNCTION_IMPORTED
7044
6f7585de
DM
7045Function is not defined by the client code; we’re merely
7046referring to it. Analogous to using an “extern” function from a
35485da9
DM
7047header file.
7048@end deffn
7049
7050@geindex GCC_JIT_FUNCTION_ALWAYS_INLINE (C macro)
02321f62 7051@anchor{topics/functions c GCC_JIT_FUNCTION_ALWAYS_INLINE}@anchor{e0}
35485da9
DM
7052@deffn {C Macro} GCC_JIT_FUNCTION_ALWAYS_INLINE
7053
7054Function is only ever inlined into other functions, and is
7055invisible outside of the JIT.
7056
7057Analogous to prefixing with @code{inline} and adding
7058@code{__attribute__((always_inline))}
7059
7060Inlining will only occur when the optimization level is
7061above 0; when optimization is off, this is essentially the
7062same as GCC_JIT_FUNCTION_INTERNAL.
7063@end deffn
7064@end quotation
c575221a
DM
7065
7066The parameter @code{name} must be non-NULL. The call takes a copy of the
7067underlying string, so it is valid to pass in a pointer to an on-stack
7068buffer.
35485da9
DM
7069@end deffn
7070
7071@geindex gcc_jit_context_get_builtin_function (C function)
02321f62 7072@anchor{topics/functions c gcc_jit_context_get_builtin_function}@anchor{e1}
bf40f0ba
DM
7073@deffn {C Function} gcc_jit_function * gcc_jit_context_get_builtin_function (gcc_jit_context@w{ }*ctxt, const char@w{ }*name)
7074
7075Get the @ref{29,,gcc_jit_function} for the built-in function with the
7076given name. For example:
7077
7078@example
7079gcc_jit_function *fn
7080 = gcc_jit_context_get_builtin_function (ctxt, "__builtin_memcpy");
7081@end example
7082
7083@cartouche
7084@quotation Note
7085Due to technical limitations with how libgccjit interacts with
7086the insides of GCC, not all built-in functions are supported. More
7087precisely, not all types are supported for parameters of built-in
7088functions from libgccjit. Attempts to get a built-in function that
7089uses such a parameter will lead to an error being emitted within
7090the context.
7091@end quotation
7092@end cartouche
35485da9
DM
7093@end deffn
7094
7095@geindex gcc_jit_function_as_object (C function)
02321f62 7096@anchor{topics/functions c gcc_jit_function_as_object}@anchor{e2}
35485da9
DM
7097@deffn {C Function} gcc_jit_object * gcc_jit_function_as_object (gcc_jit_function@w{ }*func)
7098
7099Upcasting from function to object.
7100@end deffn
7101
7102@geindex gcc_jit_function_get_param (C function)
02321f62 7103@anchor{topics/functions c gcc_jit_function_get_param}@anchor{e3}
35485da9
DM
7104@deffn {C Function} gcc_jit_param * gcc_jit_function_get_param (gcc_jit_function@w{ }*func, int@w{ }index)
7105
7106Get the param of the given index (0-based).
7107@end deffn
7108
7109@geindex gcc_jit_function_dump_to_dot (C function)
6f7585de 7110@anchor{topics/functions c gcc_jit_function_dump_to_dot}@anchor{33}
35485da9
DM
7111@deffn {C Function} void gcc_jit_function_dump_to_dot (gcc_jit_function@w{ }*func, const char@w{ }*path)
7112
7113Emit the function in graphviz format to the given path.
7114@end deffn
7115
7116@geindex gcc_jit_function_new_local (C function)
6f7585de 7117@anchor{topics/functions c gcc_jit_function_new_local}@anchor{26}
35485da9
DM
7118@deffn {C Function} gcc_jit_lvalue * gcc_jit_function_new_local (gcc_jit_function@w{ }*func, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, const char@w{ }*name)
7119
7120Create a new local variable within the function, of the given type and
7121name.
c575221a 7122
6f7585de
DM
7123The parameter @code{type} must be non-@cite{void}.
7124
c575221a
DM
7125The parameter @code{name} must be non-NULL. The call takes a copy of the
7126underlying string, so it is valid to pass in a pointer to an on-stack
7127buffer.
35485da9
DM
7128@end deffn
7129
7130@node Blocks,Statements,Functions,Creating and using functions
02321f62 7131@anchor{topics/functions blocks}@anchor{e4}
35485da9
DM
7132@subsection Blocks
7133
7134
7135@geindex gcc_jit_block (C type)
6f7585de 7136@anchor{topics/functions c gcc_jit_block}@anchor{28}
35485da9
DM
7137@deffn {C Type} gcc_jit_block
7138
7139A @cite{gcc_jit_block} represents a basic block within a function i.e. a
7140sequence of statements with a single entry point and a single exit
7141point.
7142
7143The first basic block that you create within a function will
7144be the entrypoint.
7145
7146Each basic block that you create within a function must be
ec5d0088
DM
7147terminated, either with a conditional, a jump, a return, or a
7148switch.
35485da9 7149
6f7585de 7150It’s legal to have multiple basic blocks that return within
35485da9
DM
7151one function.
7152@end deffn
7153
7154@geindex gcc_jit_function_new_block (C function)
02321f62 7155@anchor{topics/functions c gcc_jit_function_new_block}@anchor{e5}
35485da9
DM
7156@deffn {C Function} gcc_jit_block * gcc_jit_function_new_block (gcc_jit_function@w{ }*func, const char@w{ }*name)
7157
7158Create a basic block of the given name. The name may be NULL, but
7159providing meaningful names is often helpful when debugging: it may
7160show up in dumps of the internal representation, and in error
c575221a
DM
7161messages. It is copied, so the input buffer does not need to outlive
7162the call; you can pass in a pointer to an on-stack buffer, e.g.:
7163
7164@example
7165for (pc = 0; pc < fn->fn_num_ops; pc++)
7166 @{
7167 char buf[16];
7168 sprintf (buf, "instr%i", pc);
7169 state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf);
7170 @}
7171@end example
35485da9
DM
7172@end deffn
7173
7174@geindex gcc_jit_block_as_object (C function)
02321f62 7175@anchor{topics/functions c gcc_jit_block_as_object}@anchor{e6}
35485da9
DM
7176@deffn {C Function} gcc_jit_object * gcc_jit_block_as_object (gcc_jit_block@w{ }*block)
7177
7178Upcast from block to object.
7179@end deffn
7180
7181@geindex gcc_jit_block_get_function (C function)
02321f62 7182@anchor{topics/functions c gcc_jit_block_get_function}@anchor{e7}
35485da9
DM
7183@deffn {C Function} gcc_jit_function * gcc_jit_block_get_function (gcc_jit_block@w{ }*block)
7184
7185Which function is this block within?
7186@end deffn
7187
7188@node Statements,,Blocks,Creating and using functions
02321f62 7189@anchor{topics/functions statements}@anchor{e8}
35485da9
DM
7190@subsection Statements
7191
7192
7193@geindex gcc_jit_block_add_eval (C function)
0981cf96 7194@anchor{topics/functions c gcc_jit_block_add_eval}@anchor{bb}
35485da9
DM
7195@deffn {C Function} void gcc_jit_block_add_eval (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*rvalue)
7196
7197Add evaluation of an rvalue, discarding the result
6f7585de 7198(e.g. a function call that “returns” void).
35485da9
DM
7199
7200This is equivalent to this C code:
7201
7202@example
7203(void)expression;
7204@end example
35485da9
DM
7205@end deffn
7206
7207@geindex gcc_jit_block_add_assignment (C function)
6f7585de 7208@anchor{topics/functions c gcc_jit_block_add_assignment}@anchor{2a}
35485da9
DM
7209@deffn {C Function} void gcc_jit_block_add_assignment (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_lvalue@w{ }*lvalue, gcc_jit_rvalue@w{ }*rvalue)
7210
7211Add evaluation of an rvalue, assigning the result to the given
7212lvalue.
7213
7214This is roughly equivalent to this C code:
7215
7216@example
7217lvalue = rvalue;
7218@end example
35485da9
DM
7219@end deffn
7220
7221@geindex gcc_jit_block_add_assignment_op (C function)
6f7585de 7222@anchor{topics/functions c gcc_jit_block_add_assignment_op}@anchor{2e}
35485da9
DM
7223@deffn {C Function} void gcc_jit_block_add_assignment_op (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_lvalue@w{ }*lvalue, enum gcc_jit_binary_op@w{ }op, gcc_jit_rvalue@w{ }*rvalue)
7224
7225Add evaluation of an rvalue, using the result to modify an
7226lvalue.
7227
6f7585de 7228This is analogous to “+=” and friends:
35485da9
DM
7229
7230@example
7231lvalue += rvalue;
7232lvalue *= rvalue;
7233lvalue /= rvalue;
7234@end example
7235
35485da9
DM
7236etc. For example:
7237
7238@example
7239/* "i++" */
7240gcc_jit_block_add_assignment_op (
7241 loop_body, NULL,
7242 i,
7243 GCC_JIT_BINARY_OP_PLUS,
7244 gcc_jit_context_one (ctxt, int_type));
7245@end example
35485da9
DM
7246@end deffn
7247
7248@geindex gcc_jit_block_add_comment (C function)
6f7585de 7249@anchor{topics/functions c gcc_jit_block_add_comment}@anchor{3d}
35485da9
DM
7250@deffn {C Function} void gcc_jit_block_add_comment (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, const char@w{ }*text)
7251
7252Add a no-op textual comment to the internal representation of the
7253code. It will be optimized away, but will be visible in the dumps
6f7585de
DM
7254seen via @ref{66,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE}
7255and @ref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE},
7256and thus may be of use when debugging how your project’s internal
35485da9 7257representation gets converted to the libgccjit IR.
c575221a
DM
7258
7259The parameter @code{text} must be non-NULL. It is copied, so the input
7260buffer does not need to outlive the call. For example:
7261
7262@example
7263char buf[100];
7264snprintf (buf, sizeof (buf),
7265 "op%i: %s",
7266 pc, opcode_names[op->op_opcode]);
7267gcc_jit_block_add_comment (block, loc, buf);
7268@end example
35485da9
DM
7269@end deffn
7270
7271@geindex gcc_jit_block_end_with_conditional (C function)
6f7585de 7272@anchor{topics/functions c gcc_jit_block_end_with_conditional}@anchor{2d}
35485da9
DM
7273@deffn {C Function} void gcc_jit_block_end_with_conditional (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*boolval, gcc_jit_block@w{ }*on_true, gcc_jit_block@w{ }*on_false)
7274
7275Terminate a block by adding evaluation of an rvalue, branching on the
7276result to the appropriate successor block.
7277
7278This is roughly equivalent to this C code:
7279
7280@example
7281if (boolval)
7282 goto on_true;
7283else
7284 goto on_false;
7285@end example
7286
35485da9
DM
7287block, boolval, on_true, and on_false must be non-NULL.
7288@end deffn
7289
7290@geindex gcc_jit_block_end_with_jump (C function)
02321f62 7291@anchor{topics/functions c gcc_jit_block_end_with_jump}@anchor{e9}
35485da9
DM
7292@deffn {C Function} void gcc_jit_block_end_with_jump (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_block@w{ }*target)
7293
7294Terminate a block by adding a jump to the given target block.
7295
7296This is roughly equivalent to this C code:
7297
7298@example
7299goto target;
7300@end example
35485da9
DM
7301@end deffn
7302
7303@geindex gcc_jit_block_end_with_return (C function)
02321f62 7304@anchor{topics/functions c gcc_jit_block_end_with_return}@anchor{ea}
35485da9
DM
7305@deffn {C Function} void gcc_jit_block_end_with_return (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*rvalue)
7306
7307Terminate a block by adding evaluation of an rvalue, returning the value.
7308
7309This is roughly equivalent to this C code:
7310
7311@example
7312return expression;
7313@end example
35485da9
DM
7314@end deffn
7315
7316@geindex gcc_jit_block_end_with_void_return (C function)
02321f62 7317@anchor{topics/functions c gcc_jit_block_end_with_void_return}@anchor{eb}
35485da9
DM
7318@deffn {C Function} void gcc_jit_block_end_with_void_return (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc)
7319
7320Terminate a block by adding a valueless return, for use within a function
6f7585de 7321with “void” return type.
35485da9
DM
7322
7323This is equivalent to this C code:
7324
7325@example
7326return;
7327@end example
35485da9
DM
7328@end deffn
7329
ec5d0088 7330@geindex gcc_jit_block_end_with_switch (C function)
02321f62 7331@anchor{topics/functions c gcc_jit_block_end_with_switch}@anchor{ec}
ec5d0088
DM
7332@deffn {C Function} void gcc_jit_block_end_with_switch (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*expr, gcc_jit_block@w{ }*default_block, int@w{ }num_cases, gcc_jit_case@w{ }**cases)
7333
7334Terminate a block by adding evalation of an rvalue, then performing
7335a multiway branch.
7336
7337This is roughly equivalent to this C code:
7338
7339@example
7340switch (expr)
7341 @{
7342 default:
7343 goto default_block;
7344
7345 case C0.min_value ... C0.max_value:
7346 goto C0.dest_block;
7347
7348 case C1.min_value ... C1.max_value:
7349 goto C1.dest_block;
7350
7351 ...etc...
7352
7353 case C[N - 1].min_value ... C[N - 1].max_value:
7354 goto C[N - 1].dest_block;
7355@}
7356@end example
7357
ec5d0088
DM
7358@code{block}, @code{expr}, @code{default_block} and @code{cases} must all be
7359non-NULL.
7360
7361@code{expr} must be of the same integer type as all of the @code{min_value}
7362and @code{max_value} within the cases.
7363
7364@code{num_cases} must be >= 0.
7365
7366The ranges of the cases must not overlap (or have duplicate
7367values).
7368
7369The API entrypoints relating to switch statements and cases:
7370
7371@quotation
7372
7373
7374@itemize *
7375
7376@item
02321f62 7377@ref{ec,,gcc_jit_block_end_with_switch()}
ec5d0088
DM
7378
7379@item
02321f62 7380@ref{ed,,gcc_jit_case_as_object()}
ec5d0088
DM
7381
7382@item
02321f62 7383@ref{ee,,gcc_jit_context_new_case()}
ec5d0088
DM
7384@end itemize
7385@end quotation
7386
02321f62 7387were added in @ref{ef,,LIBGCCJIT_ABI_3}; you can test for their presence
ec5d0088
DM
7388using
7389
7390@example
7391#ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS
7392@end example
7393
ec5d0088 7394@geindex gcc_jit_case (C type)
02321f62 7395@anchor{topics/functions c gcc_jit_case}@anchor{f0}
ec5d0088
DM
7396@deffn {C Type} gcc_jit_case
7397@end deffn
7398
7399A @cite{gcc_jit_case} represents a case within a switch statement, and
6f7585de 7400is created within a particular @ref{8,,gcc_jit_context} using
02321f62 7401@ref{ee,,gcc_jit_context_new_case()}.
ec5d0088
DM
7402
7403Each case expresses a multivalued range of integer values. You
7404can express single-valued cases by passing in the same value for
7405both @cite{min_value} and @cite{max_value}.
7406
7407@geindex gcc_jit_context_new_case (C function)
02321f62 7408@anchor{topics/functions c gcc_jit_context_new_case}@anchor{ee}
ec5d0088
DM
7409@deffn {C Function} gcc_jit_case * gcc_jit_context_new_case (gcc_jit_context@w{ }*ctxt, gcc_jit_rvalue@w{ }*min_value, gcc_jit_rvalue@w{ }*max_value, gcc_jit_block@w{ }*dest_block)
7410
7411Create a new gcc_jit_case instance for use in a switch statement.
7412@cite{min_value} and @cite{max_value} must be constants of an integer type,
7413which must match that of the expression of the switch statement.
7414
7415@cite{dest_block} must be within the same function as the switch
7416statement.
7417@end deffn
7418
7419@geindex gcc_jit_case_as_object (C function)
02321f62 7420@anchor{topics/functions c gcc_jit_case_as_object}@anchor{ed}
ec5d0088
DM
7421@deffn {C Function} gcc_jit_object * gcc_jit_case_as_object (gcc_jit_case@w{ }*case_)
7422
7423Upcast from a case to an object.
7424@end deffn
7425
6f7585de 7426Here’s an example of creating a switch statement:
ec5d0088
DM
7427
7428@quotation
7429
7430@example
7431
7432void
7433create_code (gcc_jit_context *ctxt, void *user_data)
7434@{
7435 /* Let's try to inject the equivalent of:
7436 int
7437 test_switch (int x)
7438 @{
7439 switch (x)
7440 @{
7441 case 0 ... 5:
7442 return 3;
7443
7444 case 25 ... 27:
7445 return 4;
7446
7447 case -42 ... -17:
7448 return 83;
7449
7450 case 40:
7451 return 8;
7452
7453 default:
7454 return 10;
7455 @}
7456 @}
7457 */
7458 gcc_jit_type *t_int =
7459 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
7460 gcc_jit_type *return_type = t_int;
7461 gcc_jit_param *x =
7462 gcc_jit_context_new_param (ctxt, NULL, t_int, "x");
7463 gcc_jit_param *params[1] = @{x@};
7464 gcc_jit_function *func =
7465 gcc_jit_context_new_function (ctxt, NULL,
7466 GCC_JIT_FUNCTION_EXPORTED,
7467 return_type,
7468 "test_switch",
7469 1, params, 0);
7470
7471 gcc_jit_block *b_initial =
7472 gcc_jit_function_new_block (func, "initial");
7473
7474 gcc_jit_block *b_default =
7475 gcc_jit_function_new_block (func, "default");
7476 gcc_jit_block *b_case_0_5 =
7477 gcc_jit_function_new_block (func, "case_0_5");
7478 gcc_jit_block *b_case_25_27 =
7479 gcc_jit_function_new_block (func, "case_25_27");
7480 gcc_jit_block *b_case_m42_m17 =
7481 gcc_jit_function_new_block (func, "case_m42_m17");
7482 gcc_jit_block *b_case_40 =
7483 gcc_jit_function_new_block (func, "case_40");
7484
7485 gcc_jit_case *cases[4] = @{
7486 gcc_jit_context_new_case (
7487 ctxt,
7488 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 0),
7489 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 5),
7490 b_case_0_5),
7491 gcc_jit_context_new_case (
7492 ctxt,
7493 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 25),
7494 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 27),
7495 b_case_25_27),
7496 gcc_jit_context_new_case (
7497 ctxt,
7498 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -42),
7499 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -17),
7500 b_case_m42_m17),
7501 gcc_jit_context_new_case (
7502 ctxt,
7503 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40),
7504 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40),
7505 b_case_40)
7506 @};
7507 gcc_jit_block_end_with_switch (
7508 b_initial, NULL,
7509 gcc_jit_param_as_rvalue (x),
7510 b_default,
7511 4, cases);
7512
7513 gcc_jit_block_end_with_return (
7514 b_case_0_5, NULL,
7515 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3));
7516 gcc_jit_block_end_with_return (
7517 b_case_25_27, NULL,
7518 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 4));
7519 gcc_jit_block_end_with_return (
7520 b_case_m42_m17, NULL,
7521 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 83));
7522 gcc_jit_block_end_with_return (
7523 b_case_40, NULL,
7524 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 8));
7525 gcc_jit_block_end_with_return (
7526 b_default, NULL,
7527 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10));
7528@}
7529
ec5d0088 7530@end example
ec5d0088
DM
7531@end quotation
7532@end deffn
7533
421d0d0f
DM
7534See also @ref{f1,,gcc_jit_extended_asm} for entrypoints for adding inline
7535assembler statements to a function.
7536
7adcbafe 7537@c Copyright (C) 2017-2022 Free Software Foundation, Inc.
ecd5156d
DM
7538@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
7539@c
7540@c This is free software: you can redistribute it and/or modify it
7541@c under the terms of the GNU General Public License as published by
7542@c the Free Software Foundation, either version 3 of the License, or
7543@c (at your option) any later version.
7544@c
7545@c This program is distributed in the hope that it will be useful, but
7546@c WITHOUT ANY WARRANTY; without even the implied warranty of
7547@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7548@c General Public License for more details.
7549@c
7550@c You should have received a copy of the GNU General Public License
7551@c along with this program. If not, see
786973ce 7552@c <https://www.gnu.org/licenses/>.
ecd5156d
DM
7553
7554@node Function pointers<2>,Source Locations,Creating and using functions,Topic Reference
421d0d0f 7555@anchor{topics/function-pointers doc}@anchor{f2}@anchor{topics/function-pointers function-pointers}@anchor{f3}
ecd5156d
DM
7556@section Function pointers
7557
7558
7559You can generate calls that use a function pointer via
0981cf96 7560@ref{bc,,gcc_jit_context_new_call_through_ptr()}.
ecd5156d 7561
6f7585de 7562To do requires a @ref{13,,gcc_jit_rvalue} of the correct function pointer type.
ecd5156d 7563
6f7585de 7564Function pointers for a @ref{29,,gcc_jit_function} can be obtained
0981cf96 7565via @ref{c0,,gcc_jit_function_get_address()}.
ecd5156d
DM
7566
7567@geindex gcc_jit_function_get_address (C function)
0981cf96 7568@anchor{topics/function-pointers c gcc_jit_function_get_address}@anchor{c0}
ecd5156d
DM
7569@deffn {C Function} gcc_jit_rvalue * gcc_jit_function_get_address (gcc_jit_function@w{ }*fn, gcc_jit_location@w{ }*loc)
7570
7571Get the address of a function as an rvalue, of function pointer
7572type.
7573
421d0d0f 7574This entrypoint was added in @ref{f4,,LIBGCCJIT_ABI_9}; you can test
ecd5156d
DM
7575for its presence using
7576
7577@example
7578#ifdef LIBGCCJIT_HAVE_gcc_jit_function_get_address
7579@end example
ecd5156d
DM
7580@end deffn
7581
7582Alternatively, given an existing function, you can obtain a pointer
6f7585de 7583to it in @ref{13,,gcc_jit_rvalue} form using
0981cf96
DM
7584@ref{9c,,gcc_jit_context_new_rvalue_from_ptr()}, using a function pointer
7585type obtained using @ref{95,,gcc_jit_context_new_function_ptr_type()}.
ecd5156d 7586
6f7585de 7587Here’s an example of creating a function pointer type corresponding to C’s
ecd5156d
DM
7588@code{void (*) (int, int, int)}:
7589
7590@example
7591gcc_jit_type *void_type =
7592 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
7593gcc_jit_type *int_type =
7594 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
7595
7596/* Build the function ptr type. */
7597gcc_jit_type *param_types[3];
7598param_types[0] = int_type;
7599param_types[1] = int_type;
7600param_types[2] = int_type;
7601
7602gcc_jit_type *fn_ptr_type =
7603 gcc_jit_context_new_function_ptr_type (ctxt, NULL,
7604 void_type,
7605 3, param_types, 0);
7606@end example
7607
ecd5156d 7608@geindex gcc_jit_context_new_function_ptr_type (C function)
0981cf96 7609@anchor{topics/function-pointers c gcc_jit_context_new_function_ptr_type}@anchor{95}
ecd5156d
DM
7610@deffn {C Function} gcc_jit_type * gcc_jit_context_new_function_ptr_type (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*return_type, int@w{ }num_params, gcc_jit_type@w{ }**param_types, int@w{ }is_variadic)
7611
6f7585de 7612Generate a @ref{a,,gcc_jit_type} for a function pointer with the
ecd5156d 7613given return type and parameters.
6f7585de
DM
7614
7615Each of @cite{param_types} must be non-@cite{void}; @cite{return_type} may be @cite{void}.
ecd5156d
DM
7616@end deffn
7617
7adcbafe 7618@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
7619@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
7620@c
7621@c This is free software: you can redistribute it and/or modify it
7622@c under the terms of the GNU General Public License as published by
7623@c the Free Software Foundation, either version 3 of the License, or
7624@c (at your option) any later version.
7625@c
7626@c This program is distributed in the hope that it will be useful, but
7627@c WITHOUT ANY WARRANTY; without even the implied warranty of
7628@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7629@c General Public License for more details.
7630@c
7631@c You should have received a copy of the GNU General Public License
7632@c along with this program. If not, see
786973ce 7633@c <https://www.gnu.org/licenses/>.
35485da9 7634
ecd5156d 7635@node Source Locations,Compiling a context,Function pointers<2>,Topic Reference
421d0d0f 7636@anchor{topics/locations doc}@anchor{f5}@anchor{topics/locations source-locations}@anchor{f6}
35485da9
DM
7637@section Source Locations
7638
7639
7640@geindex gcc_jit_location (C type)
6f7585de 7641@anchor{topics/locations c gcc_jit_location}@anchor{3b}
35485da9
DM
7642@deffn {C Type} gcc_jit_location
7643
7644A @cite{gcc_jit_location} encapsulates a source code location, so that
7645you can (optionally) associate locations in your language with
7646statements in the JIT-compiled code, allowing the debugger to
7647single-step through your language.
7648
7649@cite{gcc_jit_location} instances are optional: you can always pass NULL to
7650any API entrypoint accepting one.
7651
6f7585de 7652You can construct them using @ref{41,,gcc_jit_context_new_location()}.
35485da9 7653
6f7585de
DM
7654You need to enable @ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the
7655@ref{8,,gcc_jit_context} for these locations to actually be usable by
35485da9
DM
7656the debugger:
7657
7658@example
7659gcc_jit_context_set_bool_option (
7660 ctxt,
7661 GCC_JIT_BOOL_OPTION_DEBUGINFO,
7662 1);
7663@end example
35485da9
DM
7664@end deffn
7665
7666@geindex gcc_jit_context_new_location (C function)
6f7585de 7667@anchor{topics/locations c gcc_jit_context_new_location}@anchor{41}
35485da9
DM
7668@deffn {C Function} gcc_jit_location * gcc_jit_context_new_location (gcc_jit_context@w{ }*ctxt, const char@w{ }*filename, int@w{ }line, int@w{ }column)
7669
7670Create a @cite{gcc_jit_location} instance representing the given source
7671location.
c575221a
DM
7672
7673The parameter @code{filename} must be non-NULL. The call takes a copy of
7674the underlying string, so it is valid to pass in a pointer to an
7675on-stack buffer.
35485da9
DM
7676@end deffn
7677
7678@menu
7679* Faking it::
7680
7681@end menu
7682
7683@node Faking it,,,Source Locations
421d0d0f 7684@anchor{topics/locations faking-it}@anchor{f7}
35485da9
DM
7685@subsection Faking it
7686
7687
6f7585de 7688If you don’t have source code for your internal representation, but need
35485da9 7689to debug, you can generate a C-like representation of the functions in
6f7585de 7690your context using @ref{5a,,gcc_jit_context_dump_to_file()}:
35485da9
DM
7691
7692@example
7693gcc_jit_context_dump_to_file (ctxt, "/tmp/something.c",
7694 1 /* update_locations */);
7695@end example
7696
35485da9
DM
7697This will dump C-like code to the given path. If the @cite{update_locations}
7698argument is true, this will also set up @cite{gcc_jit_location} information
7699throughout the context, pointing at the dump file as if it were a source
7700file, giving you @emph{something} you can step through in the debugger.
7701
7adcbafe 7702@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
7703@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
7704@c
7705@c This is free software: you can redistribute it and/or modify it
7706@c under the terms of the GNU General Public License as published by
7707@c the Free Software Foundation, either version 3 of the License, or
7708@c (at your option) any later version.
7709@c
7710@c This program is distributed in the hope that it will be useful, but
7711@c WITHOUT ANY WARRANTY; without even the implied warranty of
7712@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7713@c General Public License for more details.
7714@c
7715@c You should have received a copy of the GNU General Public License
7716@c along with this program. If not, see
786973ce 7717@c <https://www.gnu.org/licenses/>.
35485da9 7718
fa22c20d 7719@node Compiling a context,ABI and API compatibility,Source Locations,Topic Reference
421d0d0f 7720@anchor{topics/compilation doc}@anchor{f8}@anchor{topics/compilation compiling-a-context}@anchor{f9}
fdce7209 7721@section Compiling a context
35485da9
DM
7722
7723
6f7585de
DM
7724Once populated, a @ref{8,,gcc_jit_context *} can be compiled to
7725machine code, either in-memory via @ref{15,,gcc_jit_context_compile()} or
7726to disk via @ref{4a,,gcc_jit_context_compile_to_file()}.
fdce7209
DM
7727
7728You can compile a context multiple times (using either form of
7729compilation), although any errors that occur on the context will
7730prevent any future compilation of that context.
7731
7732@menu
7733* In-memory compilation::
7734* Ahead-of-time compilation::
7735
7736@end menu
7737
7738@node In-memory compilation,Ahead-of-time compilation,,Compiling a context
421d0d0f 7739@anchor{topics/compilation in-memory-compilation}@anchor{fa}
fdce7209 7740@subsection In-memory compilation
35485da9 7741
35485da9
DM
7742
7743@geindex gcc_jit_context_compile (C function)
6f7585de 7744@anchor{topics/compilation c gcc_jit_context_compile}@anchor{15}
35485da9
DM
7745@deffn {C Function} gcc_jit_result * gcc_jit_context_compile (gcc_jit_context@w{ }*ctxt)
7746
7747This calls into GCC and builds the code, returning a
7748@cite{gcc_jit_result *}.
791cfef8 7749
7ef96183 7750If the result is non-NULL, the caller becomes responsible for
6f7585de 7751calling @ref{39,,gcc_jit_result_release()} on it once they’re done
791cfef8 7752with it.
35485da9
DM
7753@end deffn
7754
fdce7209 7755@geindex gcc_jit_result (C type)
6f7585de 7756@anchor{topics/compilation c gcc_jit_result}@anchor{16}
fdce7209
DM
7757@deffn {C Type} gcc_jit_result
7758
7759A @cite{gcc_jit_result} encapsulates the result of compiling a context
7760in-memory, and the lifetimes of any machine code functions or globals
dc44ee3a 7761that are within the result.
fdce7209
DM
7762@end deffn
7763
35485da9 7764@geindex gcc_jit_result_get_code (C function)
6f7585de 7765@anchor{topics/compilation c gcc_jit_result_get_code}@anchor{17}
35485da9
DM
7766@deffn {C Function} void * gcc_jit_result_get_code (gcc_jit_result@w{ }*result, const char@w{ }*funcname)
7767
7768Locate a given function within the built machine code.
81ba15f1
DM
7769
7770Functions are looked up by name. For this to succeed, a function
7771with a name matching @cite{funcname} must have been created on
6f7585de
DM
7772@cite{result}’s context (or a parent context) via a call to
7773@ref{11,,gcc_jit_context_new_function()} with @cite{kind}
02321f62 7774@ref{dd,,GCC_JIT_FUNCTION_EXPORTED}:
81ba15f1
DM
7775
7776@example
7777gcc_jit_context_new_function (ctxt,
7778 any_location, /* or NULL */
7779 /* Required for func to be visible to
7780 gcc_jit_result_get_code: */
7781 GCC_JIT_FUNCTION_EXPORTED,
7782 any_return_type,
7783 /* Must string-compare equal: */
7784 funcname,
7785 /* etc */);
7786@end example
7787
81ba15f1
DM
7788If such a function is not found (or @cite{result} or @cite{funcname} are
7789@code{NULL}), an error message will be emitted on stderr and
7790@code{NULL} will be returned.
7791
7792If the function is found, the result will need to be cast to a
7793function pointer of the correct type before it can be called.
7794
7795Note that the resulting machine code becomes invalid after
6f7585de
DM
7796@ref{39,,gcc_jit_result_release()} is called on the
7797@ref{16,,gcc_jit_result *}; attempting to call it after that may lead
791cfef8
DM
7798to a segmentation fault.
7799@end deffn
7800
7801@geindex gcc_jit_result_get_global (C function)
0981cf96 7802@anchor{topics/compilation c gcc_jit_result_get_global}@anchor{cb}
791cfef8
DM
7803@deffn {C Function} void * gcc_jit_result_get_global (gcc_jit_result@w{ }*result, const char@w{ }*name)
7804
7805Locate a given global within the built machine code.
7806
7807Globals are looked up by name. For this to succeed, a global
7808with a name matching @cite{name} must have been created on
6f7585de 7809@cite{result}’s context (or a parent context) via a call to
0981cf96
DM
7810@ref{c8,,gcc_jit_context_new_global()} with @cite{kind}
7811@ref{ca,,GCC_JIT_GLOBAL_EXPORTED}.
791cfef8
DM
7812
7813If the global is found, the result will need to be cast to a
7814pointer of the correct type before it can be called.
7815
7816This is a @emph{pointer} to the global, so e.g. for an @code{int} this is
7817an @code{int *}.
7818
7819For example, given an @code{int foo;} created this way:
7820
7821@example
7822gcc_jit_lvalue *exported_global =
7823 gcc_jit_context_new_global (ctxt,
7824 any_location, /* or NULL */
7825 GCC_JIT_GLOBAL_EXPORTED,
7826 int_type,
7827 "foo");
7828@end example
7829
791cfef8
DM
7830we can access it like this:
7831
7832@example
7833int *ptr_to_foo =
7834 (int *)gcc_jit_result_get_global (result, "foo");
7835@end example
7836
791cfef8
DM
7837If such a global is not found (or @cite{result} or @cite{name} are
7838@code{NULL}), an error message will be emitted on stderr and
7839@code{NULL} will be returned.
7840
7841Note that the resulting address becomes invalid after
6f7585de
DM
7842@ref{39,,gcc_jit_result_release()} is called on the
7843@ref{16,,gcc_jit_result *}; attempting to use it after that may lead
81ba15f1 7844to a segmentation fault.
35485da9
DM
7845@end deffn
7846
7847@geindex gcc_jit_result_release (C function)
6f7585de 7848@anchor{topics/compilation c gcc_jit_result_release}@anchor{39}
35485da9
DM
7849@deffn {C Function} void gcc_jit_result_release (gcc_jit_result@w{ }*result)
7850
6f7585de
DM
7851Once we’re done with the code, this unloads the built .so file.
7852This cleans up the result; after calling this, it’s no longer
791cfef8 7853valid to use the result, or any code or globals that were obtained
6f7585de 7854by calling @ref{17,,gcc_jit_result_get_code()} or
0981cf96 7855@ref{cb,,gcc_jit_result_get_global()} on it.
fdce7209
DM
7856@end deffn
7857
7858@node Ahead-of-time compilation,,In-memory compilation,Compiling a context
421d0d0f 7859@anchor{topics/compilation ahead-of-time-compilation}@anchor{fb}
fdce7209
DM
7860@subsection Ahead-of-time compilation
7861
7862
7863Although libgccjit is primarily aimed at just-in-time compilation, it
7864can also be used for implementing more traditional ahead-of-time
6f7585de 7865compilers, via the @ref{4a,,gcc_jit_context_compile_to_file()}
fdce7209
DM
7866API entrypoint.
7867
7868@geindex gcc_jit_context_compile_to_file (C function)
6f7585de 7869@anchor{topics/compilation c gcc_jit_context_compile_to_file}@anchor{4a}
fdce7209
DM
7870@deffn {C Function} void gcc_jit_context_compile_to_file (gcc_jit_context@w{ }*ctxt, enum gcc_jit_output_kind@w{ }output_kind, const char@w{ }*output_path)
7871
6f7585de 7872Compile the @ref{8,,gcc_jit_context *} to a file of the given
fdce7209
DM
7873kind.
7874@end deffn
7875
6f7585de 7876@ref{4a,,gcc_jit_context_compile_to_file()} ignores the suffix of
fdce7209
DM
7877@code{output_path}, and insteads uses the given
7878@code{enum gcc_jit_output_kind} to decide what to do.
7879
7880@cartouche
7881@quotation Note
7882This is different from the @code{gcc} program, which does make use of the
7883suffix of the output file when determining what to do.
7884@end quotation
7885@end cartouche
7886
7887@geindex gcc_jit_output_kind (C type)
421d0d0f 7888@anchor{topics/compilation c gcc_jit_output_kind}@anchor{fc}
fdce7209
DM
7889@deffn {C Type} enum gcc_jit_output_kind
7890@end deffn
7891
7892The available kinds of output are:
7893
7894
7895@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxx}
7896@headitem
7897
7898Output kind
7899
7900@tab
7901
7902Typical suffix
7903
7904@item
7905
421d0d0f 7906@ref{fd,,GCC_JIT_OUTPUT_KIND_ASSEMBLER}
fdce7209
DM
7907
7908@tab
7909
7910.s
7911
7912@item
7913
421d0d0f 7914@ref{fe,,GCC_JIT_OUTPUT_KIND_OBJECT_FILE}
fdce7209
DM
7915
7916@tab
7917
7918.o
7919
7920@item
7921
421d0d0f 7922@ref{ff,,GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY}
fdce7209
DM
7923
7924@tab
7925
7926.so or .dll
7927
7928@item
7929
421d0d0f 7930@ref{100,,GCC_JIT_OUTPUT_KIND_EXECUTABLE}
fdce7209
DM
7931
7932@tab
7933
7934None, or .exe
7935
7936@end multitable
7937
7938
7939@geindex GCC_JIT_OUTPUT_KIND_ASSEMBLER (C macro)
421d0d0f 7940@anchor{topics/compilation c GCC_JIT_OUTPUT_KIND_ASSEMBLER}@anchor{fd}
fdce7209
DM
7941@deffn {C Macro} GCC_JIT_OUTPUT_KIND_ASSEMBLER
7942
7943Compile the context to an assembler file.
7944@end deffn
7945
7946@geindex GCC_JIT_OUTPUT_KIND_OBJECT_FILE (C macro)
421d0d0f 7947@anchor{topics/compilation c GCC_JIT_OUTPUT_KIND_OBJECT_FILE}@anchor{fe}
fdce7209
DM
7948@deffn {C Macro} GCC_JIT_OUTPUT_KIND_OBJECT_FILE
7949
7950Compile the context to an object file.
7951@end deffn
7952
7953@geindex GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY (C macro)
421d0d0f 7954@anchor{topics/compilation c GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY}@anchor{ff}
fdce7209
DM
7955@deffn {C Macro} GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY
7956
7957Compile the context to a dynamic library.
7958
7959There is currently no support for specifying other libraries to link
7960against.
7961@end deffn
7962
7963@geindex GCC_JIT_OUTPUT_KIND_EXECUTABLE (C macro)
421d0d0f 7964@anchor{topics/compilation c GCC_JIT_OUTPUT_KIND_EXECUTABLE}@anchor{100}
fdce7209
DM
7965@deffn {C Macro} GCC_JIT_OUTPUT_KIND_EXECUTABLE
7966
7967Compile the context to an executable.
7968
7969There is currently no support for specifying libraries to link
7970against.
35485da9
DM
7971@end deffn
7972
7adcbafe 7973@c Copyright (C) 2015-2022 Free Software Foundation, Inc.
fa22c20d
DM
7974@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
7975@c
7976@c This is free software: you can redistribute it and/or modify it
7977@c under the terms of the GNU General Public License as published by
7978@c the Free Software Foundation, either version 3 of the License, or
7979@c (at your option) any later version.
7980@c
7981@c This program is distributed in the hope that it will be useful, but
7982@c WITHOUT ANY WARRANTY; without even the implied warranty of
7983@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7984@c General Public License for more details.
7985@c
7986@c You should have received a copy of the GNU General Public License
7987@c along with this program. If not, see
786973ce 7988@c <https://www.gnu.org/licenses/>.
fa22c20d 7989
afed3459 7990@node ABI and API compatibility,Performance,Compiling a context,Topic Reference
421d0d0f 7991@anchor{topics/compatibility doc}@anchor{101}@anchor{topics/compatibility abi-and-api-compatibility}@anchor{102}
fa22c20d
DM
7992@section ABI and API compatibility
7993
7994
7995The libgccjit developers strive for ABI and API backward-compatibility:
7996programs built against libgccjit.so stand a good chance of running
7997without recompilation against newer versions of libgccjit.so, and
7998ought to recompile without modification against newer versions of
7999libgccjit.h.
8000
8001@cartouche
8002@quotation Note
8003The libgccjit++.h C++ API is more experimental, and less
8004locked-down at this time.
8005@end quotation
8006@end cartouche
8007
8008API compatibility is achieved by extending the API rather than changing
8009it. For ABI compatiblity, we avoid bumping the SONAME, and instead use
8010symbol versioning to tag each symbol, so that a binary linked against
8011libgccjit.so is tagged according to the symbols that it uses.
8012
6f7585de 8013For example, @ref{72,,gcc_jit_context_add_command_line_option()} was added in
fa22c20d
DM
8014@code{LIBGCCJIT_ABI_1}. If a client program uses it, this can be detected
8015from metadata by using @code{objdump}:
8016
8017@example
8018$ objdump -p testsuite/jit/test-extra-options.c.exe | tail -n 8
8019
8020Version References:
8021 required from libgccjit.so.0:
8022 0x00824161 0x00 04 LIBGCCJIT_ABI_1
8023 0x00824160 0x00 03 LIBGCCJIT_ABI_0
8024 required from libc.so.6:
fa22c20d
DM
8025@end example
8026
fa22c20d
DM
8027You can see the symbol tags provided by libgccjit.so using @code{objdump}:
8028
8029@example
8030$ objdump -p libgccjit.so | less
8031[...snip...]
8032Version definitions:
80331 0x01 0x0ff81f20 libgccjit.so.0
80342 0x00 0x00824160 LIBGCCJIT_ABI_0
80353 0x00 0x00824161 LIBGCCJIT_ABI_1
8036 LIBGCCJIT_ABI_0
8037[...snip...]
8038@end example
8039
fa22c20d 8040@menu
6f7585de 8041* Programmatically checking version::
fa22c20d
DM
8042* ABI symbol tags::
8043
6f7585de 8044@end menu
fa22c20d 8045
6f7585de 8046@node Programmatically checking version,ABI symbol tags,,ABI and API compatibility
421d0d0f 8047@anchor{topics/compatibility programmatically-checking-version}@anchor{103}
6f7585de 8048@subsection Programmatically checking version
fa22c20d 8049
fa22c20d 8050
6f7585de
DM
8051Client code can programmatically check libgccjit version using:
8052
8053@geindex gcc_jit_version_major (C function)
421d0d0f 8054@anchor{topics/compatibility c gcc_jit_version_major}@anchor{104}
6f7585de
DM
8055@deffn {C Function} int gcc_jit_version_major (void)
8056
8057Return libgccjit major version. This is analogous to __GNUC__ in C code.
8058@end deffn
8059
8060@geindex gcc_jit_version_minor (C function)
421d0d0f 8061@anchor{topics/compatibility c gcc_jit_version_minor}@anchor{105}
6f7585de
DM
8062@deffn {C Function} int gcc_jit_version_minor (void)
8063
8064Return libgccjit minor version. This is analogous to
8065__GNUC_MINOR__ in C code.
8066@end deffn
8067
8068@geindex gcc_jit_version_patchlevel (C function)
421d0d0f 8069@anchor{topics/compatibility c gcc_jit_version_patchlevel}@anchor{106}
6f7585de
DM
8070@deffn {C Function} int gcc_jit_version_patchlevel (void)
8071
8072Return libgccjit patchlevel version. This is analogous to
8073__GNUC_PATCHLEVEL__ in C code.
8074@end deffn
8075
8076@cartouche
8077@quotation Note
8078These entry points has been added with @code{LIBGCCJIT_ABI_13}
8079(see below).
8080@end quotation
8081@end cartouche
fa22c20d 8082
6f7585de 8083@node ABI symbol tags,,Programmatically checking version,ABI and API compatibility
421d0d0f 8084@anchor{topics/compatibility abi-symbol-tags}@anchor{107}
fa22c20d
DM
8085@subsection ABI symbol tags
8086
8087
8088The initial release of libgccjit (in gcc 5.1) did not use symbol versioning.
8089
8090Newer releases use the following tags.
8091
8092@menu
8093* LIBGCCJIT_ABI_0::
8094* LIBGCCJIT_ABI_1::
6a3603e3 8095* LIBGCCJIT_ABI_2::
ec5d0088 8096* LIBGCCJIT_ABI_3::
afed3459 8097* LIBGCCJIT_ABI_4::
199501ea 8098* LIBGCCJIT_ABI_5::
0ebd1f00
DM
8099* LIBGCCJIT_ABI_6::
8100* LIBGCCJIT_ABI_7::
47ee1b7c 8101* LIBGCCJIT_ABI_8::
15a65e63 8102* LIBGCCJIT_ABI_9::
6069fe72 8103* LIBGCCJIT_ABI_10::
6f7585de
DM
8104* LIBGCCJIT_ABI_11::
8105* LIBGCCJIT_ABI_12::
8106* LIBGCCJIT_ABI_13::
02321f62 8107* LIBGCCJIT_ABI_14::
421d0d0f 8108* LIBGCCJIT_ABI_15::
fa22c20d
DM
8109
8110@end menu
8111
8112@node LIBGCCJIT_ABI_0,LIBGCCJIT_ABI_1,,ABI symbol tags
421d0d0f 8113@anchor{topics/compatibility id1}@anchor{108}@anchor{topics/compatibility libgccjit-abi-0}@anchor{109}
fa22c20d
DM
8114@subsubsection @code{LIBGCCJIT_ABI_0}
8115
8116
8117All entrypoints in the initial release of libgccjit are tagged with
8118@code{LIBGCCJIT_ABI_0}, to signify the transition to symbol versioning.
8119
8120Binaries built against older copies of @code{libgccjit.so} should
8121continue to work, with this being handled transparently by the linker
8122(see this post@footnote{https://gcc.gnu.org/ml/gcc-patches/2015-06/msg02126.html})
8123
6a3603e3 8124@node LIBGCCJIT_ABI_1,LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_0,ABI symbol tags
421d0d0f 8125@anchor{topics/compatibility id2}@anchor{10a}@anchor{topics/compatibility libgccjit-abi-1}@anchor{73}
fa22c20d
DM
8126@subsubsection @code{LIBGCCJIT_ABI_1}
8127
8128
8129@code{LIBGCCJIT_ABI_1} covers the addition of
6f7585de 8130@ref{72,,gcc_jit_context_add_command_line_option()}
6a3603e3 8131
ec5d0088 8132@node LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_3,LIBGCCJIT_ABI_1,ABI symbol tags
421d0d0f 8133@anchor{topics/compatibility id3}@anchor{10b}@anchor{topics/compatibility libgccjit-abi-2}@anchor{6c}
6a3603e3
DM
8134@subsubsection @code{LIBGCCJIT_ABI_2}
8135
8136
8137@code{LIBGCCJIT_ABI_2} covers the addition of
6f7585de 8138@ref{6b,,gcc_jit_context_set_bool_allow_unreachable_blocks()}
fa22c20d 8139
afed3459 8140@node LIBGCCJIT_ABI_3,LIBGCCJIT_ABI_4,LIBGCCJIT_ABI_2,ABI symbol tags
421d0d0f 8141@anchor{topics/compatibility id4}@anchor{10c}@anchor{topics/compatibility libgccjit-abi-3}@anchor{ef}
ec5d0088
DM
8142@subsubsection @code{LIBGCCJIT_ABI_3}
8143
8144
8145@code{LIBGCCJIT_ABI_3} covers the addition of switch statements via API
8146entrypoints:
8147
8148@quotation
8149
8150
8151@itemize *
8152
8153@item
02321f62 8154@ref{ec,,gcc_jit_block_end_with_switch()}
ec5d0088
DM
8155
8156@item
02321f62 8157@ref{ed,,gcc_jit_case_as_object()}
ec5d0088
DM
8158
8159@item
02321f62 8160@ref{ee,,gcc_jit_context_new_case()}
ec5d0088
DM
8161@end itemize
8162@end quotation
8163
199501ea 8164@node LIBGCCJIT_ABI_4,LIBGCCJIT_ABI_5,LIBGCCJIT_ABI_3,ABI symbol tags
421d0d0f 8165@anchor{topics/compatibility id5}@anchor{10d}@anchor{topics/compatibility libgccjit-abi-4}@anchor{10e}
afed3459
DM
8166@subsubsection @code{LIBGCCJIT_ABI_4}
8167
8168
8169@code{LIBGCCJIT_ABI_4} covers the addition of timers via API
8170entrypoints:
8171
8172@quotation
8173
8174
8175@itemize *
8176
8177@item
421d0d0f 8178@ref{10f,,gcc_jit_context_get_timer()}
afed3459
DM
8179
8180@item
421d0d0f 8181@ref{110,,gcc_jit_context_set_timer()}
afed3459
DM
8182
8183@item
421d0d0f 8184@ref{111,,gcc_jit_timer_new()}
afed3459
DM
8185
8186@item
421d0d0f 8187@ref{112,,gcc_jit_timer_release()}
afed3459
DM
8188
8189@item
421d0d0f 8190@ref{113,,gcc_jit_timer_push()}
afed3459
DM
8191
8192@item
421d0d0f 8193@ref{114,,gcc_jit_timer_pop()}
afed3459
DM
8194
8195@item
421d0d0f 8196@ref{115,,gcc_jit_timer_print()}
afed3459
DM
8197@end itemize
8198@end quotation
8199
0ebd1f00 8200@node LIBGCCJIT_ABI_5,LIBGCCJIT_ABI_6,LIBGCCJIT_ABI_4,ABI symbol tags
421d0d0f 8201@anchor{topics/compatibility id6}@anchor{116}@anchor{topics/compatibility libgccjit-abi-5}@anchor{6e}
199501ea
DM
8202@subsubsection @code{LIBGCCJIT_ABI_5}
8203
8204
8205@code{LIBGCCJIT_ABI_5} covers the addition of
6f7585de 8206@ref{6d,,gcc_jit_context_set_bool_use_external_driver()}
199501ea 8207
0ebd1f00 8208@node LIBGCCJIT_ABI_6,LIBGCCJIT_ABI_7,LIBGCCJIT_ABI_5,ABI symbol tags
421d0d0f 8209@anchor{topics/compatibility id7}@anchor{117}@anchor{topics/compatibility libgccjit-abi-6}@anchor{be}
0ebd1f00
DM
8210@subsubsection @code{LIBGCCJIT_ABI_6}
8211
8212
8213@code{LIBGCCJIT_ABI_6} covers the addition of
0981cf96 8214@ref{bd,,gcc_jit_rvalue_set_bool_require_tail_call()}
0ebd1f00 8215
47ee1b7c 8216@node LIBGCCJIT_ABI_7,LIBGCCJIT_ABI_8,LIBGCCJIT_ABI_6,ABI symbol tags
421d0d0f 8217@anchor{topics/compatibility id8}@anchor{118}@anchor{topics/compatibility libgccjit-abi-7}@anchor{83}
0ebd1f00
DM
8218@subsubsection @code{LIBGCCJIT_ABI_7}
8219
8220
8221@code{LIBGCCJIT_ABI_7} covers the addition of
6f7585de 8222@ref{82,,gcc_jit_type_get_aligned()}
0ebd1f00 8223
15a65e63 8224@node LIBGCCJIT_ABI_8,LIBGCCJIT_ABI_9,LIBGCCJIT_ABI_7,ABI symbol tags
421d0d0f 8225@anchor{topics/compatibility id9}@anchor{119}@anchor{topics/compatibility libgccjit-abi-8}@anchor{86}
47ee1b7c
DM
8226@subsubsection @code{LIBGCCJIT_ABI_8}
8227
8228
8229@code{LIBGCCJIT_ABI_8} covers the addition of
6f7585de 8230@ref{85,,gcc_jit_type_get_vector()}
47ee1b7c 8231
6069fe72 8232@node LIBGCCJIT_ABI_9,LIBGCCJIT_ABI_10,LIBGCCJIT_ABI_8,ABI symbol tags
421d0d0f 8233@anchor{topics/compatibility id10}@anchor{11a}@anchor{topics/compatibility libgccjit-abi-9}@anchor{f4}
15a65e63
DM
8234@subsubsection @code{LIBGCCJIT_ABI_9}
8235
8236
8237@code{LIBGCCJIT_ABI_9} covers the addition of
0981cf96 8238@ref{c0,,gcc_jit_function_get_address()}
6069fe72 8239
6f7585de 8240@node LIBGCCJIT_ABI_10,LIBGCCJIT_ABI_11,LIBGCCJIT_ABI_9,ABI symbol tags
421d0d0f 8241@anchor{topics/compatibility id11}@anchor{11b}@anchor{topics/compatibility libgccjit-abi-10}@anchor{a0}
6069fe72
DM
8242@subsubsection @code{LIBGCCJIT_ABI_10}
8243
8244
8245@code{LIBGCCJIT_ABI_10} covers the addition of
6f7585de
DM
8246@ref{87,,gcc_jit_context_new_rvalue_from_vector()}
8247
8248@node LIBGCCJIT_ABI_11,LIBGCCJIT_ABI_12,LIBGCCJIT_ABI_10,ABI symbol tags
421d0d0f 8249@anchor{topics/compatibility id12}@anchor{11c}@anchor{topics/compatibility libgccjit-abi-11}@anchor{75}
6f7585de
DM
8250@subsubsection @code{LIBGCCJIT_ABI_11}
8251
8252
8253@code{LIBGCCJIT_ABI_11} covers the addition of
8254@ref{74,,gcc_jit_context_add_driver_option()}
8255
8256@node LIBGCCJIT_ABI_12,LIBGCCJIT_ABI_13,LIBGCCJIT_ABI_11,ABI symbol tags
421d0d0f 8257@anchor{topics/compatibility id13}@anchor{11d}@anchor{topics/compatibility libgccjit-abi-12}@anchor{8d}
6f7585de
DM
8258@subsubsection @code{LIBGCCJIT_ABI_12}
8259
8260
8261@code{LIBGCCJIT_ABI_12} covers the addition of
8262@ref{8c,,gcc_jit_context_new_bitfield()}
8263
02321f62 8264@node LIBGCCJIT_ABI_13,LIBGCCJIT_ABI_14,LIBGCCJIT_ABI_12,ABI symbol tags
421d0d0f 8265@anchor{topics/compatibility id14}@anchor{11e}@anchor{topics/compatibility libgccjit-abi-13}@anchor{11f}
6f7585de
DM
8266@subsubsection @code{LIBGCCJIT_ABI_13}
8267
8268
8269@code{LIBGCCJIT_ABI_13} covers the addition of version functions via API
8270entrypoints:
8271
8272@quotation
8273
8274
8275@itemize *
8276
8277@item
421d0d0f 8278@ref{104,,gcc_jit_version_major()}
6f7585de
DM
8279
8280@item
421d0d0f 8281@ref{105,,gcc_jit_version_minor()}
6f7585de
DM
8282
8283@item
421d0d0f 8284@ref{106,,gcc_jit_version_patchlevel()}
6f7585de
DM
8285@end itemize
8286@end quotation
15a65e63 8287
421d0d0f
DM
8288@node LIBGCCJIT_ABI_14,LIBGCCJIT_ABI_15,LIBGCCJIT_ABI_13,ABI symbol tags
8289@anchor{topics/compatibility id15}@anchor{120}@anchor{topics/compatibility libgccjit-abi-14}@anchor{cf}
02321f62
AC
8290@subsubsection @code{LIBGCCJIT_ABI_14}
8291
8292
8293@code{LIBGCCJIT_ABI_14} covers the addition of
8294@ref{ce,,gcc_jit_global_set_initializer()}
8295
421d0d0f
DM
8296@node LIBGCCJIT_ABI_15,,LIBGCCJIT_ABI_14,ABI symbol tags
8297@anchor{topics/compatibility id16}@anchor{121}@anchor{topics/compatibility libgccjit-abi-15}@anchor{122}
8298@subsubsection @code{LIBGCCJIT_ABI_15}
8299
8300
8301@code{LIBGCCJIT_ABI_15} covers the addition of API entrypoints for directly
8302embedding assembler instructions:
8303
8304@quotation
8305
8306
8307@itemize *
8308
8309@item
8310@ref{123,,gcc_jit_block_add_extended_asm()}
8311
8312@item
8313@ref{124,,gcc_jit_block_end_with_extended_asm_goto()}
8314
8315@item
8316@ref{125,,gcc_jit_extended_asm_as_object()}
8317
8318@item
8319@ref{126,,gcc_jit_extended_asm_set_volatile_flag()}
8320
8321@item
8322@ref{127,,gcc_jit_extended_asm_set_inline_flag()}
8323
8324@item
8325@ref{128,,gcc_jit_extended_asm_add_output_operand()}
8326
8327@item
8328@ref{129,,gcc_jit_extended_asm_add_input_operand()}
8329
8330@item
8331@ref{12a,,gcc_jit_extended_asm_add_clobber()}
8332
8333@item
8334@ref{12b,,gcc_jit_context_add_top_level_asm()}
8335@end itemize
8336@end quotation
8337
7adcbafe 8338@c Copyright (C) 2015-2022 Free Software Foundation, Inc.
afed3459
DM
8339@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
8340@c
8341@c This is free software: you can redistribute it and/or modify it
8342@c under the terms of the GNU General Public License as published by
8343@c the Free Software Foundation, either version 3 of the License, or
8344@c (at your option) any later version.
8345@c
8346@c This program is distributed in the hope that it will be useful, but
8347@c WITHOUT ANY WARRANTY; without even the implied warranty of
8348@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8349@c General Public License for more details.
8350@c
8351@c You should have received a copy of the GNU General Public License
8352@c along with this program. If not, see
786973ce 8353@c <https://www.gnu.org/licenses/>.
afed3459 8354
421d0d0f
DM
8355@node Performance,Using Assembly Language with libgccjit,ABI and API compatibility,Topic Reference
8356@anchor{topics/performance doc}@anchor{12c}@anchor{topics/performance performance}@anchor{12d}
afed3459
DM
8357@section Performance
8358
8359
8360@menu
8361* The timing API::
8362
8363@end menu
8364
8365@node The timing API,,,Performance
421d0d0f 8366@anchor{topics/performance the-timing-api}@anchor{12e}
afed3459
DM
8367@subsection The timing API
8368
8369
8370As of GCC 6, libgccjit exposes a timing API, for printing reports on
8371how long was spent in different parts of code.
8372
421d0d0f 8373You can create a @ref{12f,,gcc_jit_timer} instance, which will
afed3459 8374measure time spent since its creation. The timer maintains a stack
6f7585de 8375of “timer items”: as control flow moves through your code, you can push
afed3459
DM
8376and pop named items relating to your code onto the stack, and the timer
8377will account the time spent accordingly.
8378
6f7585de 8379You can also asssociate a timer with a @ref{8,,gcc_jit_context}, in
afed3459
DM
8380which case the time spent inside compilation will be subdivided.
8381
8382For example, the following code uses a timer, recording client items
6f7585de 8383“create_code”, “compile”, and “running code”:
afed3459
DM
8384
8385@example
8386/* Create a timer. */
8387gcc_jit_timer *timer = gcc_jit_timer_new ();
8388if (!timer)
8389 @{
8390 error ("gcc_jit_timer_new failed");
8391 return -1;
8392 @}
8393
8394/* Let's repeatedly compile and run some code, accumulating it
8395 all into the timer. */
8396for (int i = 0; i < num_iterations; i++)
8397 @{
8398 /* Create a context and associate it with the timer. */
8399 gcc_jit_context *ctxt = gcc_jit_context_acquire ();
8400 if (!ctxt)
8401 @{
8402 error ("gcc_jit_context_acquire failed");
8403 return -1;
8404 @}
8405 gcc_jit_context_set_timer (ctxt, timer);
8406
8407 /* Populate the context, timing it as client item "create_code". */
8408 gcc_jit_timer_push (timer, "create_code");
8409 create_code (ctxt);
8410 gcc_jit_timer_pop (timer, "create_code");
8411
8412 /* Compile the context, timing it as client item "compile". */
8413 gcc_jit_timer_push (timer, "compile");
8414 result = gcc_jit_context_compile (ctxt);
8415 gcc_jit_timer_pop (timer, "compile");
8416
8417 /* Run the generated code, timing it as client item "running code". */
8418 gcc_jit_timer_push (timer, "running code");
8419 run_the_code (ctxt, result);
8420 gcc_jit_timer_pop (timer, "running code");
8421
8422 /* Clean up. */
8423 gcc_jit_context_release (ctxt);
8424 gcc_jit_result_release (result);
8425@}
8426
8427/* Print the accumulated timings. */
8428gcc_jit_timer_print (timer, stderr);
8429gcc_jit_timer_release (timer);
8430@end example
8431
afed3459
DM
8432giving output like this, showing the internal GCC items at the top, then
8433client items, then the total:
8434
8435@example
8436Execution times (seconds)
8437GCC items:
8438 phase setup : 0.29 (14%) usr 0.00 ( 0%) sys 0.32 ( 5%) wall 10661 kB (50%) ggc
8439 phase parsing : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 653 kB ( 3%) ggc
8440 phase finalize : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
8441 dump files : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 0 kB ( 0%) ggc
8442 callgraph construction : 0.02 ( 1%) usr 0.01 ( 6%) sys 0.01 ( 0%) wall 242 kB ( 1%) ggc
8443 callgraph optimization : 0.03 ( 2%) usr 0.00 ( 0%) sys 0.02 ( 0%) wall 142 kB ( 1%) ggc
8444 trivially dead code : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
8445 df scan insns : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 9 kB ( 0%) ggc
8446 df live regs : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 0 kB ( 0%) ggc
8447 inline parameters : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 82 kB ( 0%) ggc
8448 tree CFG cleanup : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
8449 tree PHI insertion : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.02 ( 0%) wall 64 kB ( 0%) ggc
8450 tree SSA other : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 18 kB ( 0%) ggc
8451 expand : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 398 kB ( 2%) ggc
8452 jump : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
8453 loop init : 0.01 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 67 kB ( 0%) ggc
8454 integrated RA : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 2468 kB (12%) ggc
8455 thread pro- & epilogue : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 162 kB ( 1%) ggc
8456 final : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 216 kB ( 1%) ggc
8457 rest of compilation : 1.37 (69%) usr 0.00 ( 0%) sys 1.13 (18%) wall 1391 kB ( 6%) ggc
8458 assemble JIT code : 0.01 ( 1%) usr 0.00 ( 0%) sys 4.04 (66%) wall 0 kB ( 0%) ggc
8459 load JIT result : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
8460 JIT client code : 0.00 ( 0%) usr 0.01 ( 6%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
8461Client items:
8462 create_code : 0.00 ( 0%) usr 0.01 ( 6%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
8463 compile : 0.36 (18%) usr 0.15 (83%) sys 0.86 (14%) wall 14939 kB (70%) ggc
8464 running code : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
8465 TOTAL : 2.00 0.18 6.12 21444 kB
8466@end example
8467
afed3459
DM
8468The exact format is intended to be human-readable, and is subject to change.
8469
8470@geindex LIBGCCJIT_HAVE_TIMING_API (C macro)
421d0d0f 8471@anchor{topics/performance c LIBGCCJIT_HAVE_TIMING_API}@anchor{130}
afed3459
DM
8472@deffn {C Macro} LIBGCCJIT_HAVE_TIMING_API
8473
8474The timer API was added to libgccjit in GCC 6.
8475This macro is only defined in versions of libgccjit.h which have the
8476timer API, and so can be used to guard code that may need to compile
8477against earlier releases:
8478
8479@example
8480#ifdef LIBGCCJIT_HAVE_TIMING_API
8481gcc_jit_timer *t = gcc_jit_timer_new ();
8482gcc_jit_context_set_timer (ctxt, t);
8483#endif
8484@end example
afed3459
DM
8485@end deffn
8486
8487@geindex gcc_jit_timer (C type)
421d0d0f 8488@anchor{topics/performance c gcc_jit_timer}@anchor{12f}
afed3459
DM
8489@deffn {C Type} gcc_jit_timer
8490@end deffn
8491
8492@geindex gcc_jit_timer_new (C function)
421d0d0f 8493@anchor{topics/performance c gcc_jit_timer_new}@anchor{111}
afed3459
DM
8494@deffn {C Function} gcc_jit_timer * gcc_jit_timer_new (void)
8495
421d0d0f 8496Create a @ref{12f,,gcc_jit_timer} instance, and start timing:
afed3459
DM
8497
8498@example
8499gcc_jit_timer *t = gcc_jit_timer_new ();
8500@end example
8501
421d0d0f 8502This API entrypoint was added in @ref{10e,,LIBGCCJIT_ABI_4}; you can test
afed3459
DM
8503for its presence using
8504
8505@example
8506#ifdef LIBGCCJIT_HAVE_TIMING_API
8507@end example
afed3459
DM
8508@end deffn
8509
8510@geindex gcc_jit_timer_release (C function)
421d0d0f 8511@anchor{topics/performance c gcc_jit_timer_release}@anchor{112}
afed3459
DM
8512@deffn {C Function} void gcc_jit_timer_release (gcc_jit_timer@w{ }*timer)
8513
421d0d0f 8514Release a @ref{12f,,gcc_jit_timer} instance:
afed3459
DM
8515
8516@example
8517gcc_jit_timer_release (t);
8518@end example
8519
afed3459
DM
8520This should be called exactly once on a timer.
8521
421d0d0f 8522This API entrypoint was added in @ref{10e,,LIBGCCJIT_ABI_4}; you can test
afed3459
DM
8523for its presence using
8524
8525@example
8526#ifdef LIBGCCJIT_HAVE_TIMING_API
8527@end example
afed3459
DM
8528@end deffn
8529
8530@geindex gcc_jit_context_set_timer (C function)
421d0d0f 8531@anchor{topics/performance c gcc_jit_context_set_timer}@anchor{110}
afed3459
DM
8532@deffn {C Function} void gcc_jit_context_set_timer (gcc_jit_context@w{ }*ctxt, gcc_jit_timer@w{ }*timer)
8533
421d0d0f 8534Associate a @ref{12f,,gcc_jit_timer} instance with a context:
afed3459
DM
8535
8536@example
8537gcc_jit_context_set_timer (ctxt, t);
8538@end example
8539
afed3459 8540A timer instance can be shared between multiple
6f7585de 8541@ref{8,,gcc_jit_context} instances.
afed3459
DM
8542
8543Timers have no locking, so if you have a multithreaded program, you
8544must provide your own locks if more than one thread could be working
8545with the same timer via timer-associated contexts.
8546
421d0d0f 8547This API entrypoint was added in @ref{10e,,LIBGCCJIT_ABI_4}; you can test
afed3459
DM
8548for its presence using
8549
8550@example
8551#ifdef LIBGCCJIT_HAVE_TIMING_API
8552@end example
afed3459
DM
8553@end deffn
8554
8555@geindex gcc_jit_context_get_timer (C function)
421d0d0f 8556@anchor{topics/performance c gcc_jit_context_get_timer}@anchor{10f}
afed3459
DM
8557@deffn {C Function} gcc_jit_timer *gcc_jit_context_get_timer (gcc_jit_context@w{ }*ctxt)
8558
8559Get the timer associated with a context (if any).
8560
421d0d0f 8561This API entrypoint was added in @ref{10e,,LIBGCCJIT_ABI_4}; you can test
afed3459
DM
8562for its presence using
8563
8564@example
8565#ifdef LIBGCCJIT_HAVE_TIMING_API
8566@end example
afed3459
DM
8567@end deffn
8568
8569@geindex gcc_jit_timer_push (C function)
421d0d0f 8570@anchor{topics/performance c gcc_jit_timer_push}@anchor{113}
afed3459
DM
8571@deffn {C Function} void gcc_jit_timer_push (gcc_jit_timer@w{ }*timer, const char@w{ }*item_name)
8572
6f7585de 8573Push the given item onto the timer’s stack:
afed3459
DM
8574
8575@example
8576gcc_jit_timer_push (t, "running code");
8577run_the_code (ctxt, result);
8578gcc_jit_timer_pop (t, "running code");
8579@end example
8580
421d0d0f 8581This API entrypoint was added in @ref{10e,,LIBGCCJIT_ABI_4}; you can test
afed3459
DM
8582for its presence using
8583
8584@example
8585#ifdef LIBGCCJIT_HAVE_TIMING_API
8586@end example
afed3459
DM
8587@end deffn
8588
8589@geindex gcc_jit_timer_pop (C function)
421d0d0f 8590@anchor{topics/performance c gcc_jit_timer_pop}@anchor{114}
afed3459
DM
8591@deffn {C Function} void gcc_jit_timer_pop (gcc_jit_timer@w{ }*timer, const char@w{ }*item_name)
8592
6f7585de 8593Pop the top item from the timer’s stack.
afed3459 8594
6f7585de 8595If “item_name” is provided, it must match that of the top item.
afed3459
DM
8596Alternatively, @code{NULL} can be passed in, to suppress checking.
8597
421d0d0f 8598This API entrypoint was added in @ref{10e,,LIBGCCJIT_ABI_4}; you can test
afed3459
DM
8599for its presence using
8600
8601@example
8602#ifdef LIBGCCJIT_HAVE_TIMING_API
8603@end example
afed3459
DM
8604@end deffn
8605
8606@geindex gcc_jit_timer_print (C function)
421d0d0f 8607@anchor{topics/performance c gcc_jit_timer_print}@anchor{115}
afed3459
DM
8608@deffn {C Function} void gcc_jit_timer_print (gcc_jit_timer@w{ }*timer, FILE@w{ }*f_out)
8609
8610Print timing information to the given stream about activity since
8611the timer was started.
8612
421d0d0f 8613This API entrypoint was added in @ref{10e,,LIBGCCJIT_ABI_4}; you can test
afed3459
DM
8614for its presence using
8615
8616@example
8617#ifdef LIBGCCJIT_HAVE_TIMING_API
8618@end example
afed3459
DM
8619@end deffn
8620
7adcbafe 8621@c Copyright (C) 2020-2022 Free Software Foundation, Inc.
421d0d0f
DM
8622@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
8623@c
8624@c This is free software: you can redistribute it and/or modify it
8625@c under the terms of the GNU General Public License as published by
8626@c the Free Software Foundation, either version 3 of the License, or
8627@c (at your option) any later version.
8628@c
8629@c This program is distributed in the hope that it will be useful, but
8630@c WITHOUT ANY WARRANTY; without even the implied warranty of
8631@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8632@c General Public License for more details.
8633@c
8634@c You should have received a copy of the GNU General Public License
8635@c along with this program. If not, see
786973ce 8636@c <https://www.gnu.org/licenses/>.
421d0d0f
DM
8637
8638@node Using Assembly Language with libgccjit,,Performance,Topic Reference
8639@anchor{topics/asm doc}@anchor{131}@anchor{topics/asm using-assembly-language-with-libgccjit}@anchor{132}
8640@section Using Assembly Language with libgccjit
8641
8642
8643libgccjit has some support for directly embedding assembler instructions.
8644This is based on GCC’s support for inline @code{asm} in C code, and the
8645following assumes a familiarity with that functionality. See
8646How to Use Inline Assembly Language in C Code@footnote{https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html}
8647in GCC’s documentation, the “Extended Asm” section in particular.
8648
8649These entrypoints were added in @ref{122,,LIBGCCJIT_ABI_15}; you can test
8650for their presence using
8651
8652@quotation
8653
8654@example
8655#ifdef LIBGCCJIT_HAVE_ASM_STATEMENTS
8656@end example
8657@end quotation
8658
8659@menu
8660* Adding assembler instructions within a function::
8661* Adding top-level assembler statements::
8662
8663@end menu
8664
8665@node Adding assembler instructions within a function,Adding top-level assembler statements,,Using Assembly Language with libgccjit
8666@anchor{topics/asm adding-assembler-instructions-within-a-function}@anchor{133}
8667@subsection Adding assembler instructions within a function
8668
8669
8670@geindex gcc_jit_extended_asm (C type)
8671@anchor{topics/asm c gcc_jit_extended_asm}@anchor{f1}
8672@deffn {C Type} gcc_jit_extended_asm
8673
8674A @cite{gcc_jit_extended_asm} represents an extended @code{asm} statement: a
8675series of low-level instructions inside a function that convert inputs
8676to outputs.
8677
8678To avoid having an API entrypoint with a very large number of
8679parameters, an extended @code{asm} statement is made in stages:
8680an initial call to create the @ref{f1,,gcc_jit_extended_asm},
8681followed by calls to add operands and set other properties of the
8682statement.
8683
8684There are two API entrypoints for creating a @ref{f1,,gcc_jit_extended_asm}:
8685
8686
8687@itemize *
8688
8689@item
8690@ref{123,,gcc_jit_block_add_extended_asm()} for an @code{asm} statement with
8691no control flow, and
8692
8693@item
8694@ref{124,,gcc_jit_block_end_with_extended_asm_goto()} for an @code{asm goto}.
8695@end itemize
8696
8697For example, to create the equivalent of:
8698
8699@example
8700 asm ("mov %1, %0\n\t"
8701 "add $1, %0"
8702 : "=r" (dst)
8703 : "r" (src));
8704@end example
8705
8706the following API calls could be used:
8707
8708@example
8709 gcc_jit_extended_asm *ext_asm
8710 = gcc_jit_block_add_extended_asm (block, NULL,
8711 "mov %1, %0\n\t"
8712 "add $1, %0");
8713 gcc_jit_extended_asm_add_output_operand (ext_asm, NULL, "=r", dst);
8714 gcc_jit_extended_asm_add_input_operand (ext_asm, NULL, "r",
8715 gcc_jit_lvalue_as_rvalue (src));
8716@end example
8717
8718@cartouche
8719@quotation Warning
8720When considering the numbering of operands within an
8721extended @code{asm} statement (e.g. the @code{%0} and @code{%1}
8722above), the equivalent to the C syntax is followed i.e. all
8723output operands, then all input operands, regardless of
8724what order the calls to
8725@ref{128,,gcc_jit_extended_asm_add_output_operand()} and
8726@ref{129,,gcc_jit_extended_asm_add_input_operand()} were made in.
8727@end quotation
8728@end cartouche
8729
8730As in the C syntax, operands can be given symbolic names to avoid having
8731to number them. For example, to create the equivalent of:
8732
8733@example
8734 asm ("bsfl %[aMask], %[aIndex]"
8735 : [aIndex] "=r" (Index)
8736 : [aMask] "r" (Mask)
8737 : "cc");
8738@end example
8739
8740the following API calls could be used:
8741
8742@example
8743 gcc_jit_extended_asm *ext_asm
8744 = gcc_jit_block_add_extended_asm (block, NULL,
8745 "bsfl %[aMask], %[aIndex]");
8746 gcc_jit_extended_asm_add_output_operand (ext_asm, "aIndex", "=r", index);
8747 gcc_jit_extended_asm_add_input_operand (ext_asm, "aMask", "r",
8748 gcc_jit_param_as_rvalue (mask));
8749 gcc_jit_extended_asm_add_clobber (ext_asm, "cc");
8750@end example
8751@end deffn
8752
8753@geindex gcc_jit_block_add_extended_asm (C function)
8754@anchor{topics/asm c gcc_jit_block_add_extended_asm}@anchor{123}
8755@deffn {C Function} gcc_jit_extended_asm * gcc_jit_block_add_extended_asm (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, const char@w{ }*asm_template)
8756
8757Create a @ref{f1,,gcc_jit_extended_asm} for an extended @code{asm} statement
8758with no control flow (i.e. without the @code{goto} qualifier).
8759
8760The parameter @code{asm_template} corresponds to the @cite{AssemblerTemplate}
8761within C’s extended @code{asm} syntax. It must be non-NULL. The call takes
8762a copy of the underlying string, so it is valid to pass in a pointer to
8763an on-stack buffer.
8764@end deffn
8765
8766@geindex gcc_jit_block_end_with_extended_asm_goto (C function)
8767@anchor{topics/asm c gcc_jit_block_end_with_extended_asm_goto}@anchor{124}
8768@deffn {C Function} gcc_jit_extended_asm * gcc_jit_block_end_with_extended_asm_goto (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, const char@w{ }*asm_template, int@w{ }num_goto_blocks, gcc_jit_block@w{ }**goto_blocks, gcc_jit_block@w{ }*fallthrough_block)
8769
8770Create a @ref{f1,,gcc_jit_extended_asm} for an extended @code{asm} statement
8771that may perform jumps, and use it to terminate the given block.
8772This is equivalent to the @code{goto} qualifier in C’s extended @code{asm}
8773syntax.
8774
8775For example, to create the equivalent of:
8776
8777@example
8778 asm goto ("btl %1, %0\n\t"
8779 "jc %l[carry]"
8780 : // No outputs
8781 : "r" (p1), "r" (p2)
8782 : "cc"
8783 : carry);
8784@end example
8785
8786the following API calls could be used:
8787
8788@example
8789 const char *asm_template =
8790 (use_name
8791 ? /* Label referred to by name: "%l[carry]". */
8792 ("btl %1, %0\n\t"
8793 "jc %l[carry]")
8794 : /* Label referred to numerically: "%l2". */
8795 ("btl %1, %0\n\t"
8796 "jc %l2"));
8797
8798 gcc_jit_extended_asm *ext_asm
8799 = gcc_jit_block_end_with_extended_asm_goto (b_start, NULL,
8800 asm_template,
8801 1, &b_carry,
8802 b_fallthru);
8803 gcc_jit_extended_asm_add_input_operand (ext_asm, NULL, "r",
8804 gcc_jit_param_as_rvalue (p1));
8805 gcc_jit_extended_asm_add_input_operand (ext_asm, NULL, "r",
8806 gcc_jit_param_as_rvalue (p2));
8807 gcc_jit_extended_asm_add_clobber (ext_asm, "cc");
8808@end example
8809
8810here referencing a @ref{28,,gcc_jit_block} named “carry”.
8811
8812@code{num_goto_blocks} must be >= 0.
8813
8814@code{goto_blocks} must be non-NULL. This corresponds to the @code{GotoLabels}
8815parameter within C’s extended @code{asm} syntax. The block names can be
8816referenced within the assembler template.
8817
8818@code{fallthrough_block} can be NULL. If non-NULL, it specifies the block
8819to fall through to after the statement.
8820
8821@cartouche
8822@quotation Note
8823This is needed since each @ref{28,,gcc_jit_block} must have a
8824single exit point, as a basic block: you can’t jump from the
8825middle of a block. A “goto” is implicitly added after the
8826asm to handle the fallthrough case, which is equivalent to what
8827would have happened in the C case.
8828@end quotation
8829@end cartouche
8830@end deffn
8831
8832@geindex gcc_jit_extended_asm_set_volatile_flag (C function)
8833@anchor{topics/asm c gcc_jit_extended_asm_set_volatile_flag}@anchor{126}
8834@deffn {C Function} void gcc_jit_extended_asm_set_volatile_flag (gcc_jit_extended_asm@w{ }*ext_asm, int@w{ }flag)
8835
8836Set whether the @ref{f1,,gcc_jit_extended_asm} has side-effects, equivalent to the
8837volatile@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile}
8838qualifier in C’s extended asm syntax.
8839
8840For example, to create the equivalent of:
8841
8842@example
8843asm volatile ("rdtsc\n\t" // Returns the time in EDX:EAX.
8844 "shl $32, %%rdx\n\t" // Shift the upper bits left.
8845 "or %%rdx, %0" // 'Or' in the lower bits.
8846 : "=a" (msr)
8847 :
8848 : "rdx");
8849@end example
8850
8851the following API calls could be used:
8852
8853@example
8854 gcc_jit_extended_asm *ext_asm
8855 = gcc_jit_block_add_extended_asm
8856 (block, NULL,
8857 "rdtsc\n\t" /* Returns the time in EDX:EAX. */
8858 "shl $32, %%rdx\n\t" /* Shift the upper bits left. */
8859 "or %%rdx, %0"); /* 'Or' in the lower bits. */
8860 gcc_jit_extended_asm_set_volatile_flag (ext_asm, 1);
8861 gcc_jit_extended_asm_add_output_operand (ext_asm, NULL, "=a", msr);
8862 gcc_jit_extended_asm_add_clobber (ext_asm, "rdx");
8863@end example
8864
8865where the @ref{f1,,gcc_jit_extended_asm} is flagged as volatile.
8866@end deffn
8867
8868@geindex gcc_jit_extended_asm_set_inline_flag (C function)
8869@anchor{topics/asm c gcc_jit_extended_asm_set_inline_flag}@anchor{127}
8870@deffn {C Function} void gcc_jit_extended_asm_set_inline_flag (gcc_jit_extended_asm@w{ }*ext_asm, int@w{ }flag)
8871
8872Set the equivalent of the
8873inline@footnote{https://gcc.gnu.org/onlinedocs/gcc/Size-of-an-asm.html#Size-of-an-asm}
8874qualifier in C’s extended @code{asm} syntax.
8875@end deffn
8876
8877@geindex gcc_jit_extended_asm_add_output_operand (C function)
8878@anchor{topics/asm c gcc_jit_extended_asm_add_output_operand}@anchor{128}
8879@deffn {C Function} void gcc_jit_extended_asm_add_output_operand (gcc_jit_extended_asm@w{ }*ext_asm, const char@w{ }*asm_symbolic_name, const char@w{ }*constraint, gcc_jit_lvalue@w{ }*dest)
8880
8881Add an output operand to the extended @code{asm} statement. See the
8882Output Operands@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#OutputOperands}
8883section of the documentation of the C syntax.
8884
8885@code{asm_symbolic_name} corresponds to the @code{asmSymbolicName} component of C’s
8886extended @code{asm} syntax. It can be NULL. If non-NULL it specifies the
8887symbolic name for the operand.
8888
8889@code{constraint} corresponds to the @code{constraint} component of C’s extended
8890@code{asm} syntax. It must be non-NULL.
8891
8892@code{dest} corresponds to the @code{cvariablename} component of C’s extended
8893@code{asm} syntax. It must be non-NULL.
8894
8895@example
8896// Example with a NULL symbolic name, the equivalent of:
8897// : "=r" (dst)
8898gcc_jit_extended_asm_add_output_operand (ext_asm, NULL, "=r", dst);
8899
8900// Example with a symbolic name ("aIndex"), the equivalent of:
8901// : [aIndex] "=r" (index)
8902gcc_jit_extended_asm_add_output_operand (ext_asm, "aIndex", "=r", index);
8903@end example
8904
8905This function can’t be called on an @code{asm goto} as such instructions can’t
8906have outputs; see the
8907Goto Labels@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#GotoLabels}
8908section of GCC’s “Extended Asm” documentation.
8909@end deffn
8910
8911@geindex gcc_jit_extended_asm_add_input_operand (C function)
8912@anchor{topics/asm c gcc_jit_extended_asm_add_input_operand}@anchor{129}
8913@deffn {C Function} void gcc_jit_extended_asm_add_input_operand (gcc_jit_extended_asm@w{ }*ext_asm, const char@w{ }*asm_symbolic_name, const char@w{ }*constraint, gcc_jit_rvalue@w{ }*src)
8914
8915Add an input operand to the extended @code{asm} statement. See the
8916Input Operands@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#InputOperands}
8917section of the documentation of the C syntax.
8918
8919@code{asm_symbolic_name} corresponds to the @code{asmSymbolicName} component of C’s
8920extended @code{asm} syntax. It can be NULL. If non-NULL it specifies the
8921symbolic name for the operand.
8922
8923@code{constraint} corresponds to the @code{constraint} component of C’s extended
8924@code{asm} syntax. It must be non-NULL.
8925
8926@code{src} corresponds to the @code{cexpression} component of C’s extended
8927@code{asm} syntax. It must be non-NULL.
8928
8929@example
8930// Example with a NULL symbolic name, the equivalent of:
8931// : "r" (src)
8932gcc_jit_extended_asm_add_input_operand (ext_asm, NULL, "r",
8933 gcc_jit_lvalue_as_rvalue (src));
8934
8935// Example with a symbolic name ("aMask"), the equivalent of:
8936// : [aMask] "r" (Mask)
8937gcc_jit_extended_asm_add_input_operand (ext_asm, "aMask", "r",
8938 gcc_jit_lvalue_as_rvalue (mask));
8939@end example
8940@end deffn
8941
8942@geindex gcc_jit_extended_asm_add_clobber (C function)
8943@anchor{topics/asm c gcc_jit_extended_asm_add_clobber}@anchor{12a}
8944@deffn {C Function} void gcc_jit_extended_asm_add_clobber (gcc_jit_extended_asm@w{ }*ext_asm, const char@w{ }*victim)
8945
8946Add @cite{victim} to the list of registers clobbered by the extended @code{asm}
8947statement. It must be non-NULL. See the
8948Clobbers and Scratch Registers@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Clobbers-and-Scratch-Registers#}
8949section of the documentation of the C syntax.
8950
8951Statements with multiple clobbers will require multiple calls, one per
8952clobber.
8953
8954For example:
8955
8956@example
8957gcc_jit_extended_asm_add_clobber (ext_asm, "r0");
8958gcc_jit_extended_asm_add_clobber (ext_asm, "cc");
8959gcc_jit_extended_asm_add_clobber (ext_asm, "memory");
8960@end example
8961@end deffn
8962
8963A @ref{f1,,gcc_jit_extended_asm} is a @ref{e,,gcc_jit_object} “owned” by
8964the block’s context. The following upcast is available:
8965
8966@geindex gcc_jit_extended_asm_as_object (C function)
8967@anchor{topics/asm c gcc_jit_extended_asm_as_object}@anchor{125}
8968@deffn {C Function} gcc_jit_object * gcc_jit_extended_asm_as_object (gcc_jit_extended_asm@w{ }*ext_asm)
8969
8970Upcast from extended @code{asm} to object.
8971@end deffn
8972
8973@node Adding top-level assembler statements,,Adding assembler instructions within a function,Using Assembly Language with libgccjit
8974@anchor{topics/asm adding-top-level-assembler-statements}@anchor{134}
8975@subsection Adding top-level assembler statements
8976
8977
8978In addition to creating extended @code{asm} instructions within a function,
8979there is support for creating “top-level” assembler statements, outside
8980of any function.
8981
8982@geindex gcc_jit_context_add_top_level_asm (C function)
8983@anchor{topics/asm c gcc_jit_context_add_top_level_asm}@anchor{12b}
8984@deffn {C Function} void gcc_jit_context_add_top_level_asm (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, const char@w{ }*asm_stmts)
8985
8986Create a set of top-level asm statements, analogous to those created
8987by GCC’s “basic” @code{asm} syntax in C at file scope.
8988
8989For example, to create the equivalent of:
8990
8991@example
8992 asm ("\t.pushsection .text\n"
8993 "\t.globl add_asm\n"
8994 "\t.type add_asm, @@function\n"
8995 "add_asm:\n"
8996 "\tmovq %rdi, %rax\n"
8997 "\tadd %rsi, %rax\n"
8998 "\tret\n"
8999 "\t.popsection\n");
9000@end example
9001
9002the following API calls could be used:
9003
9004@example
9005 gcc_jit_context_add_top_level_asm (ctxt, NULL,
9006 "\t.pushsection .text\n"
9007 "\t.globl add_asm\n"
9008 "\t.type add_asm, @@function\n"
9009 "add_asm:\n"
9010 "\tmovq %rdi, %rax\n"
9011 "\tadd %rsi, %rax\n"
9012 "\tret\n"
9013 "\t# some asm here\n"
9014 "\t.popsection\n");
9015@end example
9016@end deffn
9017
7adcbafe 9018@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
35485da9
DM
9019@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
9020@c
9021@c This is free software: you can redistribute it and/or modify it
9022@c under the terms of the GNU General Public License as published by
9023@c the Free Software Foundation, either version 3 of the License, or
9024@c (at your option) any later version.
9025@c
9026@c This program is distributed in the hope that it will be useful, but
9027@c WITHOUT ANY WARRANTY; without even the implied warranty of
9028@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9029@c General Public License for more details.
9030@c
9031@c You should have received a copy of the GNU General Public License
9032@c along with this program. If not, see
786973ce 9033@c <https://www.gnu.org/licenses/>.
35485da9 9034
29df5715 9035@node C++ bindings for libgccjit,Internals,Topic Reference,Top
421d0d0f 9036@anchor{cp/index doc}@anchor{135}@anchor{cp/index c-bindings-for-libgccjit}@anchor{136}
29df5715 9037@chapter C++ bindings for libgccjit
35485da9
DM
9038
9039
29df5715 9040This document describes the C++ bindings to
786973ce 9041libgccjit@footnote{https://gcc.gnu.org/wiki/JIT}, an API for embedding GCC
29df5715 9042inside programs and libraries.
35485da9 9043
29df5715 9044The C++ bindings consist of a single header file @code{libgccjit++.h}.
35485da9 9045
6f7585de 9046This is a collection of “thin” wrapper classes around the C API.
29df5715
DM
9047Everything is an inline function, implemented in terms of the C API,
9048so there is nothing extra to link against.
35485da9 9049
29df5715 9050Contents:
35485da9 9051
7adcbafe 9052@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
29df5715
DM
9053@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
9054@c
9055@c This is free software: you can redistribute it and/or modify it
9056@c under the terms of the GNU General Public License as published by
9057@c the Free Software Foundation, either version 3 of the License, or
9058@c (at your option) any later version.
9059@c
9060@c This program is distributed in the hope that it will be useful, but
9061@c WITHOUT ANY WARRANTY; without even the implied warranty of
9062@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9063@c General Public License for more details.
9064@c
9065@c You should have received a copy of the GNU General Public License
9066@c along with this program. If not, see
786973ce 9067@c <https://www.gnu.org/licenses/>.
35485da9 9068
29df5715
DM
9069@menu
9070* Tutorial: Tutorial<2>.
9071* Topic Reference: Topic Reference<2>.
35485da9 9072
29df5715 9073@end menu
35485da9 9074
29df5715 9075@node Tutorial<2>,Topic Reference<2>,,C++ bindings for libgccjit
421d0d0f 9076@anchor{cp/intro/index doc}@anchor{137}@anchor{cp/intro/index tutorial}@anchor{138}
29df5715 9077@section Tutorial
35485da9 9078
35485da9 9079
7adcbafe 9080@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
29df5715
DM
9081@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
9082@c
9083@c This is free software: you can redistribute it and/or modify it
9084@c under the terms of the GNU General Public License as published by
9085@c the Free Software Foundation, either version 3 of the License, or
9086@c (at your option) any later version.
9087@c
9088@c This program is distributed in the hope that it will be useful, but
9089@c WITHOUT ANY WARRANTY; without even the implied warranty of
9090@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9091@c General Public License for more details.
9092@c
9093@c You should have received a copy of the GNU General Public License
9094@c along with this program. If not, see
786973ce 9095@c <https://www.gnu.org/licenses/>.
35485da9 9096
2712de78 9097@menu
6f7585de 9098* Tutorial part 1; “Hello world”: Tutorial part 1 “Hello world”<2>.
29df5715
DM
9099* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>.
9100* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>.
9101* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>.
2712de78
DM
9102
9103@end menu
9104
6f7585de 9105@node Tutorial part 1 “Hello world”<2>,Tutorial part 2 Creating a trivial machine code function<2>,,Tutorial<2>
421d0d0f 9106@anchor{cp/intro/tutorial01 doc}@anchor{139}@anchor{cp/intro/tutorial01 tutorial-part-1-hello-world}@anchor{13a}
6f7585de 9107@subsection Tutorial part 1: “Hello world”
2712de78
DM
9108
9109
6f7585de 9110Before we look at the details of the API, let’s look at building and
29df5715 9111running programs that use the library.
2712de78 9112
6f7585de 9113Here’s a toy “hello world” program that uses the library’s C++ API to
29df5715 9114synthesize a call to @cite{printf} and uses it to write a message to stdout.
2712de78 9115
6f7585de 9116Don’t worry about the content of the program for now; we’ll cover
29df5715
DM
9117the details in later parts of this tutorial.
9118
9119@quotation
2712de78
DM
9120
9121@example
29df5715 9122/* Smoketest example for libgccjit.so C++ API
7adcbafe 9123 Copyright (C) 2014-2022 Free Software Foundation, Inc.
2712de78 9124
29df5715 9125This file is part of GCC.
2712de78 9126
29df5715
DM
9127GCC is free software; you can redistribute it and/or modify it
9128under the terms of the GNU General Public License as published by
9129the Free Software Foundation; either version 3, or (at your option)
9130any later version.
2712de78 9131
29df5715
DM
9132GCC is distributed in the hope that it will be useful, but
9133WITHOUT ANY WARRANTY; without even the implied warranty of
9134MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9135General Public License for more details.
2712de78 9136
29df5715
DM
9137You should have received a copy of the GNU General Public License
9138along with GCC; see the file COPYING3. If not see
786973ce 9139<https://www.gnu.org/licenses/>. */
2712de78 9140
29df5715
DM
9141#include <libgccjit++.h>
9142
9143#include <stdlib.h>
9144#include <stdio.h>
9145
9146static void
9147create_code (gccjit::context ctxt)
9148@{
9149 /* Let's try to inject the equivalent of this C code:
9150 void
9151 greet (const char *name)
9152 @{
9153 printf ("hello %s\n", name);
9154 @}
9155 */
9156 gccjit::type void_type = ctxt.get_type (GCC_JIT_TYPE_VOID);
9157 gccjit::type const_char_ptr_type =
9158 ctxt.get_type (GCC_JIT_TYPE_CONST_CHAR_PTR);
9159 gccjit::param param_name =
9160 ctxt.new_param (const_char_ptr_type, "name");
9161 std::vector<gccjit::param> func_params;
9162 func_params.push_back (param_name);
9163 gccjit::function func =
9164 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
9165 void_type,
9166 "greet",
9167 func_params, 0);
9168
9169 gccjit::param param_format =
9170 ctxt.new_param (const_char_ptr_type, "format");
9171 std::vector<gccjit::param> printf_params;
9172 printf_params.push_back (param_format);
9173 gccjit::function printf_func =
9174 ctxt.new_function (GCC_JIT_FUNCTION_IMPORTED,
9175 ctxt.get_type (GCC_JIT_TYPE_INT),
9176 "printf",
9177 printf_params, 1);
9178
9179 gccjit::block block = func.new_block ();
9180 block.add_eval (ctxt.new_call (printf_func,
9181 ctxt.new_rvalue ("hello %s\n"),
9182 param_name));
9183 block.end_with_return ();
9184@}
9185
9186int
9187main (int argc, char **argv)
9188@{
9189 gccjit::context ctxt;
9190 gcc_jit_result *result;
9191
9192 /* Get a "context" object for working with the library. */
9193 ctxt = gccjit::context::acquire ();
9194
9195 /* Set some options on the context.
9196 Turn this on to see the code being generated, in assembler form. */
9197 ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 0);
9198
9199 /* Populate the context. */
9200 create_code (ctxt);
9201
9202 /* Compile the code. */
9203 result = ctxt.compile ();
9204 if (!result)
9205 @{
9206 fprintf (stderr, "NULL result");
9207 exit (1);
9208 @}
9209
9210 ctxt.release ();
9211
9212 /* Extract the generated code from "result". */
9213 typedef void (*fn_type) (const char *);
9214 fn_type greet =
9215 (fn_type)gcc_jit_result_get_code (result, "greet");
9216 if (!greet)
9217 @{
9218 fprintf (stderr, "NULL greet");
9219 exit (1);
9220 @}
9221
9222 /* Now call the generated function: */
9223 greet ("world");
9224 fflush (stdout);
9225
9226 gcc_jit_result_release (result);
9227 return 0;
9228@}
29df5715 9229@end example
29df5715
DM
9230@end quotation
9231
9232Copy the above to @cite{tut01-hello-world.cc}.
9233
9234Assuming you have the jit library installed, build the test program
9235using:
9236
9237@example
9238$ gcc \
9239 tut01-hello-world.cc \
9240 -o tut01-hello-world \
9241 -lgccjit
9242@end example
9243
29df5715
DM
9244You should then be able to run the built program:
9245
9246@example
9247$ ./tut01-hello-world
9248hello world
9249@end example
9250
7adcbafe 9251@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
29df5715
DM
9252@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
9253@c
9254@c This is free software: you can redistribute it and/or modify it
9255@c under the terms of the GNU General Public License as published by
9256@c the Free Software Foundation, either version 3 of the License, or
9257@c (at your option) any later version.
9258@c
9259@c This program is distributed in the hope that it will be useful, but
9260@c WITHOUT ANY WARRANTY; without even the implied warranty of
9261@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9262@c General Public License for more details.
9263@c
9264@c You should have received a copy of the GNU General Public License
9265@c along with this program. If not, see
786973ce 9266@c <https://www.gnu.org/licenses/>.
29df5715 9267
6f7585de 9268@node Tutorial part 2 Creating a trivial machine code function<2>,Tutorial part 3 Loops and variables<2>,Tutorial part 1 “Hello world”<2>,Tutorial<2>
421d0d0f 9269@anchor{cp/intro/tutorial02 doc}@anchor{13b}@anchor{cp/intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{13c}
29df5715
DM
9270@subsection Tutorial part 2: Creating a trivial machine code function
9271
9272
9273Consider this C function:
9274
9275@example
9276int square (int i)
9277@{
9278 return i * i;
9279@}
9280@end example
9281
6f7585de 9282How can we construct this at run-time using libgccjit’s C++ API?
29df5715
DM
9283
9284First we need to include the relevant header:
9285
9286@example
9287#include <libgccjit++.h>
9288@end example
9289
29df5715 9290All state associated with compilation is associated with a
421d0d0f 9291@ref{13d,,gccjit;;context}, which is a thin C++ wrapper around the C API’s
6f7585de 9292@ref{8,,gcc_jit_context *}.
29df5715 9293
421d0d0f 9294Create one using @ref{13e,,gccjit;;context;;acquire()}:
29df5715
DM
9295
9296@example
9297gccjit::context ctxt;
9298ctxt = gccjit::context::acquire ();
9299@end example
9300
29df5715
DM
9301The JIT library has a system of types. It is statically-typed: every
9302expression is of a specific type, fixed at compile-time. In our example,
6f7585de 9303all of the expressions are of the C @cite{int} type, so let’s obtain this from
421d0d0f
DM
9304the context, as a @ref{13f,,gccjit;;type}, using
9305@ref{140,,gccjit;;context;;get_type()}:
29df5715
DM
9306
9307@example
9308gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT);
9309@end example
9310
421d0d0f
DM
9311@ref{13f,,gccjit;;type} is an example of a “contextual” object: every
9312entity in the API is associated with a @ref{13d,,gccjit;;context}.
29df5715 9313
6f7585de 9314Memory management is easy: all such “contextual” objects are automatically
29df5715 9315cleaned up for you when the context is released, using
421d0d0f 9316@ref{141,,gccjit;;context;;release()}:
29df5715
DM
9317
9318@example
9319ctxt.release ();
9320@end example
9321
6f7585de 9322so you don’t need to manually track and cleanup all objects, just the
29df5715
DM
9323contexts.
9324
9325All of the C++ classes in the API are thin wrappers around pointers to
9326types in the C API.
9327
9328The C++ class hierarchy within the @code{gccjit} namespace looks like this:
9329
9330@example
9331+- object
9332 +- location
9333 +- type
9334 +- struct
9335 +- field
9336 +- function
9337 +- block
9338 +- rvalue
9339 +- lvalue
9340 +- param
9341@end example
9342
421d0d0f 9343One thing you can do with a @ref{142,,gccjit;;object} is
29df5715 9344to ask it for a human-readable description as a @code{std::string}, using
421d0d0f 9345@ref{143,,gccjit;;object;;get_debug_string()}:
29df5715
DM
9346
9347@example
9348printf ("obj: %s\n", obj.get_debug_string ().c_str ());
9349@end example
9350
29df5715
DM
9351giving this text on stdout:
9352
9353@example
9354obj: int
9355@end example
9356
29df5715
DM
9357This is invaluable when debugging.
9358
6f7585de 9359Let’s create the function. To do so, we first need to construct
29df5715 9360its single parameter, specifying its type and giving it a name,
421d0d0f 9361using @ref{144,,gccjit;;context;;new_param()}:
29df5715
DM
9362
9363@example
9364gccjit::param param_i = ctxt.new_param (int_type, "i");
9365@end example
9366
29df5715
DM
9367and we can then make a vector of all of the params of the function,
9368in this case just one:
9369
9370@example
9371std::vector<gccjit::param> params;
9372params.push_back (param_i);
9373@end example
9374
29df5715
DM
9375Now we can create the function, using
9376@code{gccjit::context::new_function()}:
9377
9378@example
9379gccjit::function func =
9380 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
9381 int_type,
9382 "square",
9383 params,
9384 0);
9385@end example
9386
29df5715
DM
9387To define the code within the function, we must create basic blocks
9388containing statements.
9389
9390Every basic block contains a list of statements, eventually terminated
9391by a statement that either returns, or jumps to another basic block.
9392
9393Our function has no control-flow, so we just need one basic block:
9394
9395@example
9396gccjit::block block = func.new_block ();
9397@end example
9398
29df5715
DM
9399Our basic block is relatively simple: it immediately terminates by
9400returning the value of an expression.
9401
421d0d0f 9402We can build the expression using @ref{145,,gccjit;;context;;new_binary_op()}:
29df5715
DM
9403
9404@example
9405gccjit::rvalue expr =
9406 ctxt.new_binary_op (
9407 GCC_JIT_BINARY_OP_MULT, int_type,
9408 param_i, param_i);
9409@end example
9410
421d0d0f
DM
9411A @ref{146,,gccjit;;rvalue} is another example of a
9412@ref{142,,gccjit;;object} subclass. As before, we can print it with
9413@ref{143,,gccjit;;object;;get_debug_string()}.
29df5715
DM
9414
9415@example
9416printf ("expr: %s\n", expr.get_debug_string ().c_str ());
9417@end example
9418
29df5715
DM
9419giving this output:
9420
9421@example
9422expr: i * i
9423@end example
9424
421d0d0f 9425Note that @ref{146,,gccjit;;rvalue} provides numerous overloaded operators
29df5715
DM
9426which can be used to dramatically reduce the amount of typing needed.
9427We can build the above binary operation more directly with this one-liner:
9428
9429@example
9430gccjit::rvalue expr = param_i * param_i;
9431@end example
9432
6f7585de 9433Creating the expression in itself doesn’t do anything; we have to add
29df5715
DM
9434this expression to a statement within the block. In this case, we use it
9435to build a return statement, which terminates the basic block:
9436
9437@example
9438block.end_with_return (expr);
9439@end example
9440
6f7585de 9441OK, we’ve populated the context. We can now compile it using
421d0d0f 9442@ref{147,,gccjit;;context;;compile()}:
29df5715
DM
9443
9444@example
9445gcc_jit_result *result;
9446result = ctxt.compile ();
9447@end example
9448
6f7585de 9449and get a @ref{16,,gcc_jit_result *}.
29df5715 9450
6f7585de 9451We can now use @ref{17,,gcc_jit_result_get_code()} to look up a specific
29df5715
DM
9452machine code routine within the result, in this case, the function we
9453created above.
9454
9455@example
9456void *fn_ptr = gcc_jit_result_get_code (result, "square");
9457if (!fn_ptr)
9458 @{
9459 fprintf (stderr, "NULL fn_ptr");
9460 goto error;
9461 @}
9462@end example
9463
29df5715
DM
9464We can now cast the pointer to an appropriate function pointer type, and
9465then call it:
9466
9467@example
9468typedef int (*fn_type) (int);
9469fn_type square = (fn_type)fn_ptr;
9470printf ("result: %d", square (5));
9471@end example
9472
29df5715
DM
9473@example
9474result: 25
9475@end example
9476
29df5715
DM
9477@menu
9478* Options: Options<3>.
9479* Full example: Full example<3>.
9480
9481@end menu
9482
9483@node Options<3>,Full example<3>,,Tutorial part 2 Creating a trivial machine code function<2>
421d0d0f 9484@anchor{cp/intro/tutorial02 options}@anchor{148}
29df5715
DM
9485@subsubsection Options
9486
9487
6f7585de 9488To get more information on what’s going on, you can set debugging flags
421d0d0f 9489on the context using @ref{149,,gccjit;;context;;set_bool_option()}.
29df5715
DM
9490
9491@c (I'm deliberately not mentioning
9492@c :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think
9493@c it's probably more of use to implementors than to users)
9494
6f7585de
DM
9495Setting @ref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE} will dump a
9496C-like representation to stderr when you compile (GCC’s “GIMPLE”
29df5715
DM
9497representation):
9498
9499@example
9500ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1);
9501result = ctxt.compile ();
9502@end example
9503
29df5715
DM
9504@example
9505square (signed int i)
9506@{
9507 signed int D.260;
9508
9509 entry:
9510 D.260 = i * i;
9511 return D.260;
9512@}
9513@end example
9514
29df5715 9515We can see the generated machine code in assembler form (on stderr) by
6f7585de 9516setting @ref{1d,,GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE} on the context
29df5715
DM
9517before compiling:
9518
9519@example
9520ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1);
9521result = ctxt.compile ();
9522@end example
9523
29df5715
DM
9524@example
9525 .file "fake.c"
9526 .text
9527 .globl square
9528 .type square, @@function
9529square:
9530.LFB6:
9531 .cfi_startproc
9532 pushq %rbp
9533 .cfi_def_cfa_offset 16
9534 .cfi_offset 6, -16
9535 movq %rsp, %rbp
9536 .cfi_def_cfa_register 6
9537 movl %edi, -4(%rbp)
9538.L14:
9539 movl -4(%rbp), %eax
9540 imull -4(%rbp), %eax
9541 popq %rbp
9542 .cfi_def_cfa 7, 8
9543 ret
9544 .cfi_endproc
9545.LFE6:
9546 .size square, .-square
9547 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)"
9548 .section .note.GNU-stack,"",@@progbits
9549@end example
9550
6f7585de 9551By default, no optimizations are performed, the equivalent of GCC’s
29df5715 9552@cite{-O0} option. We can turn things up to e.g. @cite{-O3} by calling
421d0d0f 9553@ref{14a,,gccjit;;context;;set_int_option()} with
6f7585de 9554@ref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}:
29df5715
DM
9555
9556@example
9557ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3);
9558@end example
9559
29df5715
DM
9560@example
9561 .file "fake.c"
9562 .text
9563 .p2align 4,,15
9564 .globl square
9565 .type square, @@function
9566square:
9567.LFB7:
9568 .cfi_startproc
9569.L16:
9570 movl %edi, %eax
9571 imull %edi, %eax
9572 ret
9573 .cfi_endproc
9574.LFE7:
9575 .size square, .-square
9576 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)"
9577 .section .note.GNU-stack,"",@@progbits
9578@end example
9579
29df5715
DM
9580Naturally this has only a small effect on such a trivial function.
9581
9582@node Full example<3>,,Options<3>,Tutorial part 2 Creating a trivial machine code function<2>
421d0d0f 9583@anchor{cp/intro/tutorial02 full-example}@anchor{14b}
29df5715
DM
9584@subsubsection Full example
9585
9586
6f7585de 9587Here’s what the above looks like as a complete program:
29df5715
DM
9588
9589@quotation
9590
9591@example
9592/* Usage example for libgccjit.so's C++ API
7adcbafe 9593 Copyright (C) 2014-2022 Free Software Foundation, Inc.
29df5715
DM
9594
9595This file is part of GCC.
9596
9597GCC is free software; you can redistribute it and/or modify it
9598under the terms of the GNU General Public License as published by
9599the Free Software Foundation; either version 3, or (at your option)
9600any later version.
9601
9602GCC is distributed in the hope that it will be useful, but
9603WITHOUT ANY WARRANTY; without even the implied warranty of
9604MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9605General Public License for more details.
9606
9607You should have received a copy of the GNU General Public License
9608along with GCC; see the file COPYING3. If not see
786973ce 9609<https://www.gnu.org/licenses/>. */
29df5715
DM
9610
9611#include <libgccjit++.h>
9612
9613#include <stdlib.h>
9614#include <stdio.h>
9615
9616void
9617create_code (gccjit::context ctxt)
9618@{
9619 /* Let's try to inject the equivalent of this C code:
9620
9621 int square (int i)
9622 @{
9623 return i * i;
9624 @}
9625 */
9626 gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT);
9627 gccjit::param param_i = ctxt.new_param (int_type, "i");
9628 std::vector<gccjit::param> params;
9629 params.push_back (param_i);
9630 gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
9631 int_type,
9632 "square",
9633 params, 0);
9634
9635 gccjit::block block = func.new_block ();
9636
9637 gccjit::rvalue expr =
9638 ctxt.new_binary_op (GCC_JIT_BINARY_OP_MULT, int_type,
9639 param_i, param_i);
9640
9641 block.end_with_return (expr);
9642@}
9643
9644int
9645main (int argc, char **argv)
9646@{
9647 /* Get a "context" object for working with the library. */
9648 gccjit::context ctxt = gccjit::context::acquire ();
9649
9650 /* Set some options on the context.
9651 Turn this on to see the code being generated, in assembler form. */
9652 ctxt.set_bool_option (
9653 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
9654 0);
9655
9656 /* Populate the context. */
9657 create_code (ctxt);
9658
9659 /* Compile the code. */
9660 gcc_jit_result *result = ctxt.compile ();
9661
9662 /* We're done with the context; we can release it: */
9663 ctxt.release ();
9664
9665 if (!result)
9666 @{
9667 fprintf (stderr, "NULL result");
9668 return 1;
9669 @}
9670
9671 /* Extract the generated code from "result". */
9672 void *fn_ptr = gcc_jit_result_get_code (result, "square");
9673 if (!fn_ptr)
9674 @{
9675 fprintf (stderr, "NULL fn_ptr");
9676 gcc_jit_result_release (result);
9677 return 1;
9678 @}
9679
9680 typedef int (*fn_type) (int);
9681 fn_type square = (fn_type)fn_ptr;
9682 printf ("result: %d\n", square (5));
9683
9684 gcc_jit_result_release (result);
9685 return 0;
9686@}
29df5715 9687@end example
29df5715
DM
9688@end quotation
9689
9690Building and running it:
9691
9692@example
9693$ gcc \
9694 tut02-square.cc \
9695 -o tut02-square \
9696 -lgccjit
9697
9698# Run the built program:
9699$ ./tut02-square
9700result: 25
9701@end example
9702
7adcbafe 9703@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
29df5715
DM
9704@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
9705@c
9706@c This is free software: you can redistribute it and/or modify it
9707@c under the terms of the GNU General Public License as published by
9708@c the Free Software Foundation, either version 3 of the License, or
9709@c (at your option) any later version.
9710@c
9711@c This program is distributed in the hope that it will be useful, but
9712@c WITHOUT ANY WARRANTY; without even the implied warranty of
9713@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9714@c General Public License for more details.
9715@c
9716@c You should have received a copy of the GNU General Public License
9717@c along with this program. If not, see
786973ce 9718@c <https://www.gnu.org/licenses/>.
29df5715
DM
9719
9720@node Tutorial part 3 Loops and variables<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>,Tutorial part 2 Creating a trivial machine code function<2>,Tutorial<2>
421d0d0f 9721@anchor{cp/intro/tutorial03 doc}@anchor{14c}@anchor{cp/intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{14d}
29df5715
DM
9722@subsection Tutorial part 3: Loops and variables
9723
9724
9725Consider this C function:
9726
9727@quotation
9728
9729@example
9730int loop_test (int n)
9731@{
9732 int sum = 0;
9733 for (int i = 0; i < n; i++)
9734 sum += i * i;
9735 return sum;
9736@}
9737@end example
29df5715
DM
9738@end quotation
9739
9740This example demonstrates some more features of libgccjit, with local
9741variables and a loop.
9742
6f7585de 9743To break this down into libgccjit terms, it’s usually easier to reword
29df5715
DM
9744the @cite{for} loop as a @cite{while} loop, giving:
9745
9746@quotation
9747
9748@example
9749int loop_test (int n)
9750@{
9751 int sum = 0;
9752 int i = 0;
9753 while (i < n)
9754 @{
9755 sum += i * i;
9756 i++;
9757 @}
9758 return sum;
9759@}
9760@end example
29df5715
DM
9761@end quotation
9762
6f7585de 9763Here’s what the final control flow graph will look like:
29df5715
DM
9764
9765@quotation
9766
9767
9768@float Figure
9769
421d0d0f 9770@image{libgccjit-figures/sum-of-squares,,,image of a control flow graph,png}
29df5715
DM
9771
9772@end float
9773
9774@end quotation
9775
9776As before, we include the libgccjit++ header and make a
421d0d0f 9777@ref{13d,,gccjit;;context}.
29df5715
DM
9778
9779@example
9780#include <libgccjit++.h>
9781
9782void test (void)
9783@{
9784 gccjit::context ctxt;
9785 ctxt = gccjit::context::acquire ();
9786@end example
9787
29df5715
DM
9788The function works with the C @cite{int} type.
9789
9790In the previous tutorial we acquired this via
9791
9792@example
9793gccjit::type the_type = ctxt.get_type (ctxt, GCC_JIT_TYPE_INT);
9794@end example
9795
29df5715
DM
9796though we could equally well make it work on, say, @cite{double}:
9797
9798@example
9799gccjit::type the_type = ctxt.get_type (ctxt, GCC_JIT_TYPE_DOUBLE);
9800@end example
9801
29df5715
DM
9802For integer types we can use @code{gccjit::context::get_int_type}
9803to directly bind a specific type:
9804
9805@example
9806gccjit::type the_type = ctxt.get_int_type <int> ();
9807@end example
9808
6f7585de 9809Let’s build the function:
29df5715
DM
9810
9811@example
9812gcc_jit_param n = ctxt.new_param (the_type, "n");
9813std::vector<gccjit::param> params;
9814params.push_back (n);
9815gccjit::function func =
9816 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
9817 return_type,
9818 "loop_test",
9819 params, 0);
9820@end example
9821
29df5715
DM
9822@menu
9823* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>.
9824* Control flow: Control flow<2>.
9825* Visualizing the control flow graph: Visualizing the control flow graph<2>.
9826* Full example: Full example<4>.
9827
9828@end menu
9829
9830@node Expressions lvalues and rvalues<2>,Control flow<2>,,Tutorial part 3 Loops and variables<2>
421d0d0f 9831@anchor{cp/intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{14e}
29df5715
DM
9832@subsubsection Expressions: lvalues and rvalues
9833
9834
421d0d0f 9835The base class of expression is the @ref{146,,gccjit;;rvalue},
29df5715
DM
9836representing an expression that can be on the @emph{right}-hand side of
9837an assignment: a value that can be computed somehow, and assigned
9838@emph{to} a storage area (such as a variable). It has a specific
421d0d0f 9839@ref{13f,,gccjit;;type}.
29df5715 9840
421d0d0f
DM
9841Anothe important class is @ref{14f,,gccjit;;lvalue}.
9842A @ref{14f,,gccjit;;lvalue}. is something that can of the @emph{left}-hand
29df5715
DM
9843side of an assignment: a storage area (such as a variable).
9844
9845In other words, every assignment can be thought of as:
9846
9847@example
9848LVALUE = RVALUE;
9849@end example
9850
421d0d0f
DM
9851Note that @ref{14f,,gccjit;;lvalue} is a subclass of
9852@ref{146,,gccjit;;rvalue}, where in an assignment of the form:
29df5715
DM
9853
9854@example
9855LVALUE_A = LVALUE_B;
9856@end example
9857
29df5715
DM
9858the @cite{LVALUE_B} implies reading the current value of that storage
9859area, assigning it into the @cite{LVALUE_A}.
9860
6f7585de 9861So far the only expressions we’ve seen are from the previous tutorial:
29df5715
DM
9862
9863
9864@enumerate
9865
9866@item
9867the multiplication @cite{i * i}:
9868@end enumerate
9869
9870@quotation
9871
9872@example
9873gccjit::rvalue expr =
9874 ctxt.new_binary_op (
9875 GCC_JIT_BINARY_OP_MULT, int_type,
9876 param_i, param_i);
9877
9878/* Alternatively, using operator-overloading: */
9879gccjit::rvalue expr = param_i * param_i;
9880@end example
9881
421d0d0f 9882which is a @ref{146,,gccjit;;rvalue}, and
29df5715
DM
9883@end quotation
9884
9885
9886@enumerate 2
9887
9888@item
9889the various function parameters: @cite{param_i} and @cite{param_n}, instances of
421d0d0f
DM
9890@ref{150,,gccjit;;param}, which is a subclass of @ref{14f,,gccjit;;lvalue}
9891(and, in turn, of @ref{146,,gccjit;;rvalue}):
29df5715
DM
9892we can both read from and write to function parameters within the
9893body of a function.
9894@end enumerate
9895
9896Our new example has a new kind of expression: we have two local
9897variables. We create them by calling
421d0d0f 9898@ref{151,,gccjit;;function;;new_local()}, supplying a type and a name:
29df5715
DM
9899
9900@example
9901/* Build locals: */
9902gccjit::lvalue i = func.new_local (the_type, "i");
9903gccjit::lvalue sum = func.new_local (the_type, "sum");
9904@end example
9905
421d0d0f 9906These are instances of @ref{14f,,gccjit;;lvalue} - they can be read from
29df5715
DM
9907and written to.
9908
9909Note that there is no precanned way to create @emph{and} initialize a variable
9910like in C:
9911
9912@example
9913int i = 0;
9914@end example
9915
29df5715
DM
9916Instead, having added the local to the function, we have to separately add
9917an assignment of @cite{0} to @cite{local_i} at the beginning of the function.
9918
9919@node Control flow<2>,Visualizing the control flow graph<2>,Expressions lvalues and rvalues<2>,Tutorial part 3 Loops and variables<2>
421d0d0f 9920@anchor{cp/intro/tutorial03 control-flow}@anchor{152}
29df5715
DM
9921@subsubsection Control flow
9922
9923
9924This function has a loop, so we need to build some basic blocks to
9925handle the control flow. In this case, we need 4 blocks:
9926
9927
9928@enumerate
9929
9930@item
9931before the loop (initializing the locals)
9932
9933@item
9934the conditional at the top of the loop (comparing @cite{i < n})
9935
9936@item
9937the body of the loop
9938
9939@item
9940after the loop terminates (@cite{return sum})
9941@end enumerate
9942
421d0d0f
DM
9943so we create these as @ref{153,,gccjit;;block} instances within the
9944@ref{154,,gccjit;;function}:
29df5715
DM
9945
9946@example
9947gccjit::block b_initial = func.new_block ("initial");
9948gccjit::block b_loop_cond = func.new_block ("loop_cond");
9949gccjit::block b_loop_body = func.new_block ("loop_body");
9950gccjit::block b_after_loop = func.new_block ("after_loop");
9951@end example
9952
29df5715
DM
9953We now populate each block with statements.
9954
9955The entry block @cite{b_initial} consists of initializations followed by a jump
9956to the conditional. We assign @cite{0} to @cite{i} and to @cite{sum}, using
421d0d0f
DM
9957@ref{155,,gccjit;;block;;add_assignment()} to add
9958an assignment statement, and using @ref{156,,gccjit;;context;;zero()} to get
29df5715
DM
9959the constant value @cite{0} for the relevant type for the right-hand side of
9960the assignment:
9961
9962@example
9963/* sum = 0; */
9964b_initial.add_assignment (sum, ctxt.zero (the_type));
9965
9966/* i = 0; */
9967b_initial.add_assignment (i, ctxt.zero (the_type));
9968@end example
9969
29df5715
DM
9970We can then terminate the entry block by jumping to the conditional:
9971
9972@example
9973b_initial.end_with_jump (b_loop_cond);
9974@end example
9975
29df5715
DM
9976The conditional block is equivalent to the line @cite{while (i < n)} from our
9977C example. It contains a single statement: a conditional, which jumps to
9978one of two destination blocks depending on a boolean
421d0d0f 9979@ref{146,,gccjit;;rvalue}, in this case the comparison of @cite{i} and @cite{n}.
29df5715 9980
421d0d0f 9981We could build the comparison using @ref{157,,gccjit;;context;;new_comparison()}:
29df5715
DM
9982
9983@example
9984gccjit::rvalue guard =
9985 ctxt.new_comparison (GCC_JIT_COMPARISON_GE,
9986 i, n);
9987@end example
9988
6f7585de 9989and can then use this to add @cite{b_loop_cond}’s sole statement, via
421d0d0f 9990@ref{158,,gccjit;;block;;end_with_conditional()}:
29df5715
DM
9991
9992@example
7ef96183
DM
9993b_loop_cond.end_with_conditional (guard,
9994 b_after_loop, // on_true
9995 b_loop_body); // on_false
29df5715
DM
9996@end example
9997
421d0d0f 9998However @ref{146,,gccjit;;rvalue} has overloaded operators for this, so we
29df5715
DM
9999express the conditional as
10000
10001@example
10002gccjit::rvalue guard = (i >= n);
10003@end example
10004
7ef96183 10005and hence we can write the block more concisely as:
29df5715
DM
10006
10007@example
10008b_loop_cond.end_with_conditional (
10009 i >= n,
7ef96183
DM
10010 b_after_loop, // on_true
10011 b_loop_body); // on_false
29df5715
DM
10012@end example
10013
29df5715
DM
10014Next, we populate the body of the loop.
10015
10016The C statement @cite{sum += i * i;} is an assignment operation, where an
6f7585de 10017lvalue is modified “in-place”. We use
421d0d0f 10018@ref{159,,gccjit;;block;;add_assignment_op()} to handle these operations:
29df5715
DM
10019
10020@example
10021/* sum += i * i */
10022b_loop_body.add_assignment_op (sum,
10023 GCC_JIT_BINARY_OP_PLUS,
10024 i * i);
10025@end example
10026
29df5715 10027The @cite{i++} can be thought of as @cite{i += 1}, and can thus be handled in
6f7585de 10028a similar way. We use @ref{2f,,gcc_jit_context_one()} to get the constant
29df5715
DM
10029value @cite{1} (for the relevant type) for the right-hand side
10030of the assignment.
10031
10032@example
10033/* i++ */
10034b_loop_body.add_assignment_op (i,
10035 GCC_JIT_BINARY_OP_PLUS,
10036 ctxt.one (the_type));
10037@end example
10038
29df5715
DM
10039@cartouche
10040@quotation Note
10041For numeric constants other than 0 or 1, we could use
421d0d0f 10042@ref{15a,,gccjit;;context;;new_rvalue()}, which has overloads
29df5715
DM
10043for both @code{int} and @code{double}.
10044@end quotation
10045@end cartouche
10046
10047The loop body completes by jumping back to the conditional:
10048
10049@example
10050b_loop_body.end_with_jump (b_loop_cond);
10051@end example
10052
29df5715
DM
10053Finally, we populate the @cite{b_after_loop} block, reached when the loop
10054conditional is false. We want to generate the equivalent of:
10055
10056@example
10057return sum;
10058@end example
10059
29df5715
DM
10060so the block is just one statement:
10061
10062@example
10063/* return sum */
10064b_after_loop.end_with_return (sum);
10065@end example
10066
29df5715
DM
10067@cartouche
10068@quotation Note
10069You can intermingle block creation with statement creation,
10070but given that the terminator statements generally include references
6f7585de 10071to other blocks, I find it’s clearer to create all the blocks,
29df5715
DM
10072@emph{then} all the statements.
10073@end quotation
10074@end cartouche
10075
6f7585de 10076We’ve finished populating the function. As before, we can now compile it
29df5715
DM
10077to machine code:
10078
10079@example
10080gcc_jit_result *result;
10081result = ctxt.compile ();
10082
10083ctxt.release ();
10084
10085if (!result)
10086 @{
10087 fprintf (stderr, "NULL result");
10088 return 1;
10089 @}
10090
10091typedef int (*loop_test_fn_type) (int);
10092loop_test_fn_type loop_test =
10093 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test");
10094if (!loop_test)
10095 @{
10096 fprintf (stderr, "NULL loop_test");
10097 gcc_jit_result_release (result);
10098 return 1;
10099 @}
10100printf ("result: %d", loop_test (10));
10101@end example
10102
29df5715
DM
10103@example
10104result: 285
10105@end example
10106
29df5715 10107@node Visualizing the control flow graph<2>,Full example<4>,Control flow<2>,Tutorial part 3 Loops and variables<2>
421d0d0f 10108@anchor{cp/intro/tutorial03 visualizing-the-control-flow-graph}@anchor{15b}
29df5715
DM
10109@subsubsection Visualizing the control flow graph
10110
10111
10112You can see the control flow graph of a function using
421d0d0f 10113@ref{15c,,gccjit;;function;;dump_to_dot()}:
29df5715
DM
10114
10115@example
10116func.dump_to_dot ("/tmp/sum-of-squares.dot");
10117@end example
10118
29df5715
DM
10119giving a .dot file in GraphViz format.
10120
10121You can convert this to an image using @cite{dot}:
10122
10123@example
10124$ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png
10125@end example
10126
29df5715
DM
10127or use a viewer (my preferred one is xdot.py; see
10128@indicateurl{https://github.com/jrfonseca/xdot.py}; on Fedora you can
10129install it with @cite{yum install python-xdot}):
10130
10131@quotation
10132
10133
10134@float Figure
10135
421d0d0f 10136@image{libgccjit-figures/sum-of-squares,,,image of a control flow graph,png}
29df5715
DM
10137
10138@end float
10139
10140@end quotation
10141
10142@node Full example<4>,,Visualizing the control flow graph<2>,Tutorial part 3 Loops and variables<2>
421d0d0f 10143@anchor{cp/intro/tutorial03 full-example}@anchor{15d}
29df5715
DM
10144@subsubsection Full example
10145
10146
10147@quotation
10148
10149@example
10150/* Usage example for libgccjit.so's C++ API
7adcbafe 10151 Copyright (C) 2014-2022 Free Software Foundation, Inc.
29df5715
DM
10152
10153This file is part of GCC.
10154
10155GCC is free software; you can redistribute it and/or modify it
10156under the terms of the GNU General Public License as published by
10157the Free Software Foundation; either version 3, or (at your option)
10158any later version.
10159
10160GCC is distributed in the hope that it will be useful, but
10161WITHOUT ANY WARRANTY; without even the implied warranty of
10162MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10163General Public License for more details.
10164
10165You should have received a copy of the GNU General Public License
10166along with GCC; see the file COPYING3. If not see
786973ce 10167<https://www.gnu.org/licenses/>. */
29df5715
DM
10168
10169#include <libgccjit++.h>
10170
10171#include <stdlib.h>
10172#include <stdio.h>
10173
10174void
10175create_code (gccjit::context ctxt)
10176@{
10177 /*
10178 Simple sum-of-squares, to test conditionals and looping
10179
10180 int loop_test (int n)
10181 @{
10182 int i;
10183 int sum = 0;
10184 for (i = 0; i < n ; i ++)
10185 @{
10186 sum += i * i;
10187 @}
10188 return sum;
10189 */
10190 gccjit::type the_type = ctxt.get_int_type <int> ();
10191 gccjit::type return_type = the_type;
10192
10193 gccjit::param n = ctxt.new_param (the_type, "n");
10194 std::vector<gccjit::param> params;
10195 params.push_back (n);
10196 gccjit::function func =
10197 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
10198 return_type,
10199 "loop_test",
10200 params, 0);
10201
10202 /* Build locals: */
10203 gccjit::lvalue i = func.new_local (the_type, "i");
10204 gccjit::lvalue sum = func.new_local (the_type, "sum");
10205
10206 gccjit::block b_initial = func.new_block ("initial");
10207 gccjit::block b_loop_cond = func.new_block ("loop_cond");
10208 gccjit::block b_loop_body = func.new_block ("loop_body");
10209 gccjit::block b_after_loop = func.new_block ("after_loop");
10210
10211 /* sum = 0; */
10212 b_initial.add_assignment (sum, ctxt.zero (the_type));
10213
10214 /* i = 0; */
10215 b_initial.add_assignment (i, ctxt.zero (the_type));
10216
10217 b_initial.end_with_jump (b_loop_cond);
10218
10219 /* if (i >= n) */
10220 b_loop_cond.end_with_conditional (
10221 i >= n,
10222 b_after_loop,
10223 b_loop_body);
10224
10225 /* sum += i * i */
10226 b_loop_body.add_assignment_op (sum,
10227 GCC_JIT_BINARY_OP_PLUS,
10228 i * i);
10229
10230 /* i++ */
10231 b_loop_body.add_assignment_op (i,
10232 GCC_JIT_BINARY_OP_PLUS,
10233 ctxt.one (the_type));
10234
10235 b_loop_body.end_with_jump (b_loop_cond);
10236
10237 /* return sum */
10238 b_after_loop.end_with_return (sum);
10239@}
10240
10241int
10242main (int argc, char **argv)
10243@{
10244 gccjit::context ctxt;
10245 gcc_jit_result *result = NULL;
10246
10247 /* Get a "context" object for working with the library. */
10248 ctxt = gccjit::context::acquire ();
10249
10250 /* Set some options on the context.
10251 Turn this on to see the code being generated, in assembler form. */
10252 ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
10253 0);
10254
10255 /* Populate the context. */
10256 create_code (ctxt);
10257
10258 /* Compile the code. */
10259 result = ctxt.compile ();
10260
10261 ctxt.release ();
10262
10263 if (!result)
10264 @{
10265 fprintf (stderr, "NULL result");
10266 return 1;
10267 @}
10268
10269 /* Extract the generated code from "result". */
10270 typedef int (*loop_test_fn_type) (int);
10271 loop_test_fn_type loop_test =
10272 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test");
10273 if (!loop_test)
10274 @{
10275 fprintf (stderr, "NULL loop_test");
10276 gcc_jit_result_release (result);
10277 return 1;
10278 @}
10279
10280 /* Run the generated code. */
10281 int val = loop_test (10);
10282 printf("loop_test returned: %d\n", val);
10283
10284 gcc_jit_result_release (result);
10285 return 0;
10286@}
29df5715 10287@end example
29df5715
DM
10288@end quotation
10289
10290Building and running it:
10291
10292@example
10293$ gcc \
10294 tut03-sum-of-squares.cc \
10295 -o tut03-sum-of-squares \
10296 -lgccjit
10297
10298# Run the built program:
10299$ ./tut03-sum-of-squares
10300loop_test returned: 285
10301@end example
10302
7adcbafe 10303@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
29df5715
DM
10304@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
10305@c
10306@c This is free software: you can redistribute it and/or modify it
10307@c under the terms of the GNU General Public License as published by
10308@c the Free Software Foundation, either version 3 of the License, or
10309@c (at your option) any later version.
10310@c
10311@c This program is distributed in the hope that it will be useful, but
10312@c WITHOUT ANY WARRANTY; without even the implied warranty of
10313@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10314@c General Public License for more details.
10315@c
10316@c You should have received a copy of the GNU General Public License
10317@c along with this program. If not, see
786973ce 10318@c <https://www.gnu.org/licenses/>.
29df5715
DM
10319
10320@node Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>,,Tutorial part 3 Loops and variables<2>,Tutorial<2>
421d0d0f 10321@anchor{cp/intro/tutorial04 doc}@anchor{15e}@anchor{cp/intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{15f}
29df5715
DM
10322@subsection Tutorial part 4: Adding JIT-compilation to a toy interpreter
10323
10324
6f7585de 10325In this example we construct a “toy” interpreter, and add JIT-compilation
29df5715
DM
10326to it.
10327
10328@menu
10329* Our toy interpreter: Our toy interpreter<2>.
10330* Compiling to machine code: Compiling to machine code<2>.
10331* Setting things up: Setting things up<2>.
10332* Populating the function: Populating the function<2>.
10333* Verifying the control flow graph: Verifying the control flow graph<2>.
10334* Compiling the context: Compiling the context<2>.
10335* Single-stepping through the generated code: Single-stepping through the generated code<2>.
10336* Examining the generated code: Examining the generated code<2>.
10337* Putting it all together: Putting it all together<2>.
10338* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>.
10339
10340@end menu
10341
10342@node Our toy interpreter<2>,Compiling to machine code<2>,,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
421d0d0f 10343@anchor{cp/intro/tutorial04 our-toy-interpreter}@anchor{160}
29df5715
DM
10344@subsubsection Our toy interpreter
10345
10346
6f7585de 10347It’s a stack-based interpreter, and is intended as a (very simple) example
29df5715
DM
10348of the kind of bytecode interpreter seen in dynamic languages such as
10349Python, Ruby etc.
10350
10351For the sake of simplicity, our toy virtual machine is very limited:
10352
10353@quotation
10354
10355
10356@itemize *
10357
10358@item
10359The only data type is @cite{int}
10360
10361@item
10362It can only work on one function at a time (so that the only
10363function call that can be made is to recurse).
10364
10365@item
10366Functions can only take one parameter.
10367
10368@item
10369Functions have a stack of @cite{int} values.
10370
10371@item
6f7585de 10372We’ll implement function call within the interpreter by calling a
29df5715
DM
10373function in our implementation, rather than implementing our own
10374frame stack.
10375
10376@item
10377The parser is only good enough to get the examples to work.
10378@end itemize
10379@end quotation
10380
10381Naturally, a real interpreter would be much more complicated that this.
10382
10383The following operations are supported:
10384
10385
10386@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxx}
10387@headitem
10388
10389Operation
10390
10391@tab
10392
10393Meaning
10394
10395@tab
10396
10397Old Stack
10398
10399@tab
10400
10401New Stack
10402
10403@item
10404
10405DUP
10406
10407@tab
10408
10409Duplicate top of stack.
10410
10411@tab
10412
10413@code{[..., x]}
10414
10415@tab
10416
10417@code{[..., x, x]}
10418
10419@item
10420
10421ROT
10422
10423@tab
10424
10425Swap top two elements
10426of stack.
10427
10428@tab
10429
10430@code{[..., x, y]}
10431
10432@tab
10433
10434@code{[..., y, x]}
10435
10436@item
10437
10438BINARY_ADD
10439
10440@tab
10441
10442Add the top two elements
10443on the stack.
10444
10445@tab
10446
10447@code{[..., x, y]}
10448
10449@tab
10450
10451@code{[..., (x+y)]}
10452
10453@item
10454
10455BINARY_SUBTRACT
10456
10457@tab
10458
10459Likewise, but subtract.
10460
10461@tab
10462
10463@code{[..., x, y]}
10464
10465@tab
10466
10467@code{[..., (x-y)]}
10468
10469@item
10470
10471BINARY_MULT
10472
10473@tab
10474
10475Likewise, but multiply.
10476
10477@tab
10478
10479@code{[..., x, y]}
10480
10481@tab
10482
10483@code{[..., (x*y)]}
10484
10485@item
10486
10487BINARY_COMPARE_LT
10488
10489@tab
10490
10491Compare the top two
10492elements on the stack
10493and push a nonzero/zero
10494if (x<y).
10495
10496@tab
10497
10498@code{[..., x, y]}
10499
10500@tab
10501
10502@code{[..., (x<y)]}
10503
10504@item
10505
10506RECURSE
10507
10508@tab
10509
10510Recurse, passing the top
10511of the stack, and
10512popping the result.
10513
10514@tab
10515
10516@code{[..., x]}
10517
10518@tab
10519
10520@code{[..., fn(x)]}
10521
10522@item
10523
10524RETURN
10525
10526@tab
10527
10528Return the top of the
10529stack.
10530
10531@tab
10532
10533@code{[x]}
10534
10535@tab
10536
10537@code{[]}
10538
10539@item
10540
10541PUSH_CONST @cite{arg}
10542
10543@tab
10544
10545Push an int const.
10546
10547@tab
10548
10549@code{[...]}
10550
10551@tab
10552
10553@code{[..., arg]}
10554
10555@item
10556
10557JUMP_ABS_IF_TRUE @cite{arg}
10558
10559@tab
10560
10561Pop; if top of stack was
10562nonzero, jump to
10563@code{arg}.
10564
10565@tab
10566
10567@code{[..., x]}
10568
10569@tab
10570
10571@code{[...]}
10572
10573@end multitable
10574
10575
10576Programs can be interpreted, disassembled, and compiled to machine code.
10577
6f7585de 10578The interpreter reads @code{.toy} scripts. Here’s what a simple recursive
29df5715
DM
10579factorial program looks like, the script @code{factorial.toy}.
10580The parser ignores lines beginning with a @cite{#}.
10581
10582@quotation
10583
10584@example
10585# Simple recursive factorial implementation, roughly equivalent to:
10586#
10587# int factorial (int arg)
10588# @{
10589# if (arg < 2)
10590# return arg
10591# return arg * factorial (arg - 1)
10592# @}
10593
10594# Initial state:
10595# stack: [arg]
10596
10597# 0:
10598DUP
10599# stack: [arg, arg]
10600
10601# 1:
10602PUSH_CONST 2
10603# stack: [arg, arg, 2]
10604
10605# 2:
10606BINARY_COMPARE_LT
10607# stack: [arg, (arg < 2)]
10608
10609# 3:
10610JUMP_ABS_IF_TRUE 9
10611# stack: [arg]
10612
10613# 4:
10614DUP
10615# stack: [arg, arg]
10616
10617# 5:
10618PUSH_CONST 1
10619# stack: [arg, arg, 1]
10620
10621# 6:
10622BINARY_SUBTRACT
10623# stack: [arg, (arg - 1)
10624
10625# 7:
10626RECURSE
10627# stack: [arg, factorial(arg - 1)]
10628
10629# 8:
10630BINARY_MULT
10631# stack: [arg * factorial(arg - 1)]
10632
10633# 9:
10634RETURN
29df5715 10635@end example
29df5715
DM
10636@end quotation
10637
10638The interpreter is a simple infinite loop with a big @code{switch} statement
10639based on what the next opcode is:
10640
10641@quotation
10642
10643@example
10644
10645int
10646toyvm_function::interpret (int arg, FILE *trace)
10647@{
10648 toyvm_frame frame;
10649#define PUSH(ARG) (frame.push (ARG))
10650#define POP(ARG) (frame.pop ())
10651
10652 frame.frm_function = this;
10653 frame.frm_pc = 0;
10654 frame.frm_cur_depth = 0;
10655
10656 PUSH (arg);
10657
10658 while (1)
10659 @{
10660 toyvm_op *op;
10661 int x, y;
10662 assert (frame.frm_pc < fn_num_ops);
10663 op = &fn_ops[frame.frm_pc++];
10664
10665 if (trace)
10666 @{
10667 frame.dump_stack (trace);
10668 disassemble_op (op, frame.frm_pc, trace);
10669 @}
10670
10671 switch (op->op_opcode)
10672 @{
10673 /* Ops taking no operand. */
10674 case DUP:
10675 x = POP ();
10676 PUSH (x);
10677 PUSH (x);
10678 break;
10679
10680 case ROT:
10681 y = POP ();
10682 x = POP ();
10683 PUSH (y);
10684 PUSH (x);
10685 break;
10686
10687 case BINARY_ADD:
10688 y = POP ();
10689 x = POP ();
10690 PUSH (x + y);
10691 break;
10692
10693 case BINARY_SUBTRACT:
10694 y = POP ();
10695 x = POP ();
10696 PUSH (x - y);
10697 break;
10698
10699 case BINARY_MULT:
10700 y = POP ();
10701 x = POP ();
10702 PUSH (x * y);
10703 break;
10704
10705 case BINARY_COMPARE_LT:
10706 y = POP ();
10707 x = POP ();
10708 PUSH (x < y);
10709 break;
10710
10711 case RECURSE:
10712 x = POP ();
10713 x = interpret (x, trace);
10714 PUSH (x);
10715 break;
10716
10717 case RETURN:
10718 return POP ();
10719
10720 /* Ops taking an operand. */
10721 case PUSH_CONST:
10722 PUSH (op->op_operand);
10723 break;
10724
10725 case JUMP_ABS_IF_TRUE:
10726 x = POP ();
10727 if (x)
10728 frame.frm_pc = op->op_operand;
10729 break;
10730
10731 default:
10732 assert (0); /* unknown opcode */
10733
10734 @} /* end of switch on opcode */
10735 @} /* end of while loop */
10736
10737#undef PUSH
10738#undef POP
10739@}
10740
29df5715 10741@end example
29df5715
DM
10742@end quotation
10743
10744@node Compiling to machine code<2>,Setting things up<2>,Our toy interpreter<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
421d0d0f 10745@anchor{cp/intro/tutorial04 compiling-to-machine-code}@anchor{161}
29df5715
DM
10746@subsubsection Compiling to machine code
10747
10748
10749We want to generate machine code that can be cast to this type and
10750then directly executed in-process:
10751
10752@quotation
10753
10754@example
10755typedef int (*toyvm_compiled_func) (int);
10756
29df5715 10757@end example
29df5715
DM
10758@end quotation
10759
6f7585de 10760Our compiler isn’t very sophisticated; it takes the implementation of
29df5715
DM
10761each opcode above, and maps it directly to the operations supported by
10762the libgccjit API.
10763
10764How should we handle the stack? In theory we could calculate what the
10765stack depth will be at each opcode, and optimize away the stack
6f7585de
DM
10766manipulation “by hand”. We’ll see below that libgccjit is able to do
10767this for us, so we’ll implement stack manipulation
29df5715
DM
10768in a direct way, by creating a @code{stack} array and @code{stack_depth}
10769variables, local within the generated function, equivalent to this C code:
10770
10771@example
10772int stack_depth;
10773int stack[MAX_STACK_DEPTH];
10774@end example
10775
6f7585de 10776We’ll also have local variables @code{x} and @code{y} for use when implementing
29df5715
DM
10777the opcodes, equivalent to this:
10778
10779@example
10780int x;
10781int y;
10782@end example
10783
29df5715
DM
10784This means our compiler has the following state:
10785
10786@quotation
10787
10788@example
10789
10790 toyvm_function &toyvmfn;
10791
10792 gccjit::context ctxt;
10793
10794 gccjit::type int_type;
10795 gccjit::type bool_type;
10796 gccjit::type stack_type; /* int[MAX_STACK_DEPTH] */
10797
10798 gccjit::rvalue const_one;
10799
10800 gccjit::function fn;
10801 gccjit::param param_arg;
10802 gccjit::lvalue stack;
10803 gccjit::lvalue stack_depth;
10804 gccjit::lvalue x;
10805 gccjit::lvalue y;
10806
10807 gccjit::location op_locs[MAX_OPS];
10808 gccjit::block initial_block;
10809 gccjit::block op_blocks[MAX_OPS];
10810
29df5715 10811@end example
29df5715
DM
10812@end quotation
10813
10814@node Setting things up<2>,Populating the function<2>,Compiling to machine code<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
421d0d0f 10815@anchor{cp/intro/tutorial04 setting-things-up}@anchor{162}
29df5715
DM
10816@subsubsection Setting things up
10817
10818
10819First we create our types:
10820
10821@quotation
10822
10823@example
10824
10825void
10826compilation_state::create_types ()
10827@{
10828 /* Create types. */
10829 int_type = ctxt.get_type (GCC_JIT_TYPE_INT);
10830 bool_type = ctxt.get_type (GCC_JIT_TYPE_BOOL);
10831 stack_type = ctxt.new_array_type (int_type, MAX_STACK_DEPTH);
10832
29df5715 10833@end example
29df5715
DM
10834@end quotation
10835
10836along with extracting a useful @cite{int} constant:
10837
10838@quotation
10839
10840@example
10841 const_one = ctxt.one (int_type);
10842
10843@}
10844
29df5715 10845@end example
29df5715
DM
10846@end quotation
10847
6f7585de 10848We’ll implement push and pop in terms of the @code{stack} array and
29df5715
DM
10849@code{stack_depth}. Here are helper functions for adding statements to
10850a block, implementing pushing and popping values:
10851
10852@quotation
10853
10854@example
10855
10856void
10857compilation_state::add_push (gccjit::block block,
10858 gccjit::rvalue rvalue,
10859 gccjit::location loc)
10860@{
10861 /* stack[stack_depth] = RVALUE */
10862 block.add_assignment (
10863 /* stack[stack_depth] */
10864 ctxt.new_array_access (
10865 stack,
10866 stack_depth,
10867 loc),
10868 rvalue,
10869 loc);
10870
10871 /* "stack_depth++;". */
10872 block.add_assignment_op (
10873 stack_depth,
10874 GCC_JIT_BINARY_OP_PLUS,
10875 const_one,
10876 loc);
10877@}
10878
10879void
10880compilation_state::add_pop (gccjit::block block,
10881 gccjit::lvalue lvalue,
10882 gccjit::location loc)
10883@{
10884 /* "--stack_depth;". */
10885 block.add_assignment_op (
10886 stack_depth,
10887 GCC_JIT_BINARY_OP_MINUS,
10888 const_one,
10889 loc);
10890
10891 /* "LVALUE = stack[stack_depth];". */
10892 block.add_assignment (
10893 lvalue,
10894 /* stack[stack_depth] */
10895 ctxt.new_array_access (stack,
10896 stack_depth,
10897 loc),
10898 loc);
10899@}
10900
29df5715 10901@end example
29df5715
DM
10902@end quotation
10903
10904We will support single-stepping through the generated code in the
421d0d0f 10905debugger, so we need to create @ref{163,,gccjit;;location} instances, one
29df5715
DM
10906per operation in the source code. These will reference the lines of
10907e.g. @code{factorial.toy}.
10908
10909@quotation
10910
10911@example
10912
10913void
10914compilation_state::create_locations ()
10915@{
10916 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++)
10917 @{
10918 toyvm_op *op = &toyvmfn.fn_ops[pc];
10919
10920 op_locs[pc] = ctxt.new_location (toyvmfn.fn_filename,
10921 op->op_linenum,
10922 0); /* column */
10923 @}
10924@}
10925
29df5715 10926@end example
29df5715
DM
10927@end quotation
10928
6f7585de 10929Let’s create the function itself. As usual, we create its parameter
29df5715
DM
10930first, then use the parameter to create the function:
10931
10932@quotation
10933
10934@example
10935
10936void
10937compilation_state::create_function (const char *funcname)
10938@{
10939 std::vector <gccjit::param> params;
10940 param_arg = ctxt.new_param (int_type, "arg", op_locs[0]);
10941 params.push_back (param_arg);
10942 fn = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
10943 int_type,
10944 funcname,
10945 params, 0,
10946 op_locs[0]);
10947
29df5715 10948@end example
29df5715
DM
10949@end quotation
10950
10951We create the locals within the function.
10952
10953@quotation
10954
10955@example
10956 stack = fn.new_local (stack_type, "stack");
10957 stack_depth = fn.new_local (int_type, "stack_depth");
10958 x = fn.new_local (int_type, "x");
10959 y = fn.new_local (int_type, "y");
10960
29df5715 10961@end example
29df5715
DM
10962@end quotation
10963
10964@node Populating the function<2>,Verifying the control flow graph<2>,Setting things up<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
421d0d0f 10965@anchor{cp/intro/tutorial04 populating-the-function}@anchor{164}
29df5715
DM
10966@subsubsection Populating the function
10967
10968
6f7585de 10969There’s some one-time initialization, and the API treats the first block
29df5715
DM
10970you create as the entrypoint of the function, so we need to create that
10971block first:
10972
10973@quotation
10974
10975@example
10976 initial_block = fn.new_block ("initial");
10977
29df5715 10978@end example
29df5715
DM
10979@end quotation
10980
10981We can now create blocks for each of the operations. Most of these will
10982be consolidated into larger blocks when the optimizer runs.
10983
10984@quotation
10985
10986@example
10987 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++)
10988 @{
10989 char buf[16];
10990 sprintf (buf, "instr%i", pc);
10991 op_blocks[pc] = fn.new_block (buf);
10992 @}
10993
29df5715 10994@end example
29df5715
DM
10995@end quotation
10996
6f7585de 10997Now that we have a block it can jump to when it’s done, we can populate
29df5715
DM
10998the initial block:
10999
11000@quotation
11001
11002@example
11003
11004 /* "stack_depth = 0;". */
11005 initial_block.add_assignment (stack_depth,
11006 ctxt.zero (int_type),
11007 op_locs[0]);
11008
11009 /* "PUSH (arg);". */
11010 add_push (initial_block,
11011 param_arg,
11012 op_locs[0]);
11013
11014 /* ...and jump to insn 0. */
11015 initial_block.end_with_jump (op_blocks[0],
11016 op_locs[0]);
11017
29df5715 11018@end example
29df5715
DM
11019@end quotation
11020
11021We can now populate the blocks for the individual operations. We loop
11022through them, adding instructions to their blocks:
11023
11024@quotation
11025
11026@example
11027 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++)
11028 @{
11029 gccjit::location loc = op_locs[pc];
11030
11031 gccjit::block block = op_blocks[pc];
11032 gccjit::block next_block = (pc < toyvmfn.fn_num_ops
11033 ? op_blocks[pc + 1]
11034 : NULL);
11035
11036 toyvm_op *op;
11037 op = &toyvmfn.fn_ops[pc];
11038
29df5715 11039@end example
29df5715
DM
11040@end quotation
11041
6f7585de 11042We’re going to have another big @code{switch} statement for implementing
29df5715 11043the opcodes, this time for compiling them, rather than interpreting
6f7585de
DM
11044them. It’s helpful to have macros for implementing push and pop, so that
11045we can make the @code{switch} statement that’s coming up look as much as
29df5715
DM
11046possible like the one above within the interpreter:
11047
11048@example
11049
11050#define X_EQUALS_POP()\
11051 add_pop (block, x, loc)
11052#define Y_EQUALS_POP()\
11053 add_pop (block, y, loc)
11054#define PUSH_RVALUE(RVALUE)\
11055 add_push (block, (RVALUE), loc)
11056#define PUSH_X()\
11057 PUSH_RVALUE (x)
11058#define PUSH_Y() \
11059 PUSH_RVALUE (y)
11060
29df5715
DM
11061@end example
11062
29df5715
DM
11063@cartouche
11064@quotation Note
11065A particularly clever implementation would have an @emph{identical}
11066@code{switch} statement shared by the interpreter and the compiler, with
6f7585de 11067some preprocessor “magic”. We’re not doing that here, for the sake
29df5715
DM
11068of simplicity.
11069@end quotation
11070@end cartouche
11071
11072When I first implemented this compiler, I accidentally missed an edit
11073when copying and pasting the @code{Y_EQUALS_POP} macro, so that popping the
11074stack into @code{y} instead erroneously assigned it to @code{x}, leaving @code{y}
11075uninitialized.
11076
11077To track this kind of thing down, we can use
421d0d0f 11078@ref{165,,gccjit;;block;;add_comment()} to add descriptive comments
29df5715
DM
11079to the internal representation. This is invaluable when looking through
11080the generated IR for, say @code{factorial}:
11081
11082@quotation
11083
11084@example
11085
11086 block.add_comment (opcode_names[op->op_opcode], loc);
11087
29df5715 11088@end example
29df5715
DM
11089@end quotation
11090
11091We can now write the big @code{switch} statement that implements the
11092individual opcodes, populating the relevant block with statements:
11093
11094@quotation
11095
11096@example
11097
11098 switch (op->op_opcode)
11099 @{
11100 case DUP:
11101 X_EQUALS_POP ();
11102 PUSH_X ();
11103 PUSH_X ();
11104 break;
11105
11106 case ROT:
11107 Y_EQUALS_POP ();
11108 X_EQUALS_POP ();
11109 PUSH_Y ();
11110 PUSH_X ();
11111 break;
11112
11113 case BINARY_ADD:
11114 Y_EQUALS_POP ();
11115 X_EQUALS_POP ();
11116 PUSH_RVALUE (
11117 ctxt.new_binary_op (
11118 GCC_JIT_BINARY_OP_PLUS,
11119 int_type,
11120 x, y,
11121 loc));
11122 break;
11123
11124 case BINARY_SUBTRACT:
11125 Y_EQUALS_POP ();
11126 X_EQUALS_POP ();
11127 PUSH_RVALUE (
11128 ctxt.new_binary_op (
11129 GCC_JIT_BINARY_OP_MINUS,
11130 int_type,
11131 x, y,
11132 loc));
11133 break;
11134
11135 case BINARY_MULT:
11136 Y_EQUALS_POP ();
11137 X_EQUALS_POP ();
11138 PUSH_RVALUE (
11139 ctxt.new_binary_op (
11140 GCC_JIT_BINARY_OP_MULT,
11141 int_type,
11142 x, y,
11143 loc));
11144 break;
11145
11146 case BINARY_COMPARE_LT:
11147 Y_EQUALS_POP ();
11148 X_EQUALS_POP ();
11149 PUSH_RVALUE (
11150 /* cast of bool to int */
11151 ctxt.new_cast (
11152 /* (x < y) as a bool */
11153 ctxt.new_comparison (
11154 GCC_JIT_COMPARISON_LT,
11155 x, y,
11156 loc),
11157 int_type,
11158 loc));
11159 break;
11160
11161 case RECURSE:
11162 @{
11163 X_EQUALS_POP ();
11164 PUSH_RVALUE (
11165 ctxt.new_call (
11166 fn,
11167 x,
11168 loc));
11169 break;
11170 @}
11171
11172 case RETURN:
11173 X_EQUALS_POP ();
11174 block.end_with_return (x, loc);
11175 break;
11176
11177 /* Ops taking an operand. */
11178 case PUSH_CONST:
11179 PUSH_RVALUE (
11180 ctxt.new_rvalue (int_type, op->op_operand));
11181 break;
11182
11183 case JUMP_ABS_IF_TRUE:
11184 X_EQUALS_POP ();
11185 block.end_with_conditional (
11186 /* "(bool)x". */
11187 ctxt.new_cast (x, bool_type, loc),
11188 op_blocks[op->op_operand], /* on_true */
11189 next_block, /* on_false */
11190 loc);
11191 break;
11192
11193 default:
11194 assert(0);
11195 @} /* end of switch on opcode */
11196
29df5715 11197@end example
29df5715
DM
11198@end quotation
11199
11200Every block must be terminated, via a call to one of the
11201@code{gccjit::block::end_with_} entrypoints. This has been done for two
11202of the opcodes, but we need to do it for the other ones, by jumping
11203to the next block.
11204
11205@quotation
11206
11207@example
11208 if (op->op_opcode != JUMP_ABS_IF_TRUE
11209 && op->op_opcode != RETURN)
11210 block.end_with_jump (next_block, loc);
11211
29df5715 11212@end example
29df5715
DM
11213@end quotation
11214
11215This is analogous to simply incrementing the program counter.
11216
11217@node Verifying the control flow graph<2>,Compiling the context<2>,Populating the function<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
421d0d0f 11218@anchor{cp/intro/tutorial04 verifying-the-control-flow-graph}@anchor{166}
29df5715
DM
11219@subsubsection Verifying the control flow graph
11220
11221
11222Having finished looping over the blocks, the context is complete.
11223
11224As before, we can verify that the control flow and statements are sane by
421d0d0f 11225using @ref{15c,,gccjit;;function;;dump_to_dot()}:
29df5715
DM
11226
11227@example
11228fn.dump_to_dot ("/tmp/factorial.dot");
11229@end example
11230
29df5715
DM
11231and viewing the result. Note how the label names, comments, and
11232variable names show up in the dump, to make it easier to spot
11233errors in our compiler.
11234
11235@quotation
11236
11237
11238@float Figure
11239
421d0d0f 11240@image{libgccjit-figures/factorial,,,image of a control flow graph,png}
29df5715
DM
11241
11242@end float
11243
11244@end quotation
11245
11246@node Compiling the context<2>,Single-stepping through the generated code<2>,Verifying the control flow graph<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
421d0d0f 11247@anchor{cp/intro/tutorial04 compiling-the-context}@anchor{167}
29df5715
DM
11248@subsubsection Compiling the context
11249
11250
11251Having finished looping over the blocks and populating them with
11252statements, the context is complete.
11253
199501ea
DM
11254We can now compile it, extract machine code from the result, and
11255run it:
29df5715
DM
11256
11257@quotation
11258
11259@example
29df5715 11260
199501ea
DM
11261class compilation_result
11262@{
11263public:
11264 compilation_result (gcc_jit_result *result) :
11265 m_result (result)
11266 @{
11267 @}
11268 ~compilation_result ()
11269 @{
11270 gcc_jit_result_release (m_result);
11271 @}
11272
11273 void *get_code (const char *funcname)
11274 @{
11275 return gcc_jit_result_get_code (m_result, funcname);
11276 @}
11277
11278private:
11279 gcc_jit_result *m_result;
11280@};
11281
29df5715
DM
11282@end example
11283
199501ea
DM
11284@example
11285 compilation_result compiler_result = fn->compile ();
29df5715 11286
199501ea
DM
11287 const char *funcname = fn->get_function_name ();
11288 toyvm_compiled_func code
11289 = (toyvm_compiled_func)compiler_result.get_code (funcname);
29df5715 11290
29df5715
DM
11291 printf ("compiler result: %d\n",
11292 code (atoi (argv[2])));
11293
29df5715 11294@end example
29df5715
DM
11295@end quotation
11296
11297@node Single-stepping through the generated code<2>,Examining the generated code<2>,Compiling the context<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
421d0d0f 11298@anchor{cp/intro/tutorial04 single-stepping-through-the-generated-code}@anchor{168}
29df5715
DM
11299@subsubsection Single-stepping through the generated code
11300
11301
6f7585de 11302It’s possible to debug the generated code. To do this we need to both:
29df5715
DM
11303
11304@quotation
11305
11306
11307@itemize *
11308
11309@item
11310Set up source code locations for our statements, so that we can
11311meaningfully step through the code. We did this above by
421d0d0f 11312calling @ref{169,,gccjit;;context;;new_location()} and using the
29df5715
DM
11313results.
11314
11315@item
11316Enable the generation of debugging information, by setting
6f7585de 11317@ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the
421d0d0f
DM
11318@ref{13d,,gccjit;;context} via
11319@ref{149,,gccjit;;context;;set_bool_option()}:
29df5715
DM
11320
11321@example
11322ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1);
11323@end example
29df5715
DM
11324@end itemize
11325@end quotation
11326
11327Having done this, we can put a breakpoint on the generated function:
11328
11329@example
11330$ gdb --args ./toyvm factorial.toy 10
11331(gdb) break factorial
11332Function "factorial" not defined.
11333Make breakpoint pending on future shared library load? (y or [n]) y
11334Breakpoint 1 (factorial) pending.
11335(gdb) run
11336Breakpoint 1, factorial (arg=10) at factorial.toy:14
1133714 DUP
11338@end example
11339
6f7585de 11340We’ve set up location information, which references @code{factorial.toy}.
29df5715
DM
11341This allows us to use e.g. @code{list} to see where we are in the script:
11342
11343@example
11344(gdb) list
113459
1134610 # Initial state:
1134711 # stack: [arg]
1134812
1134913 # 0:
1135014 DUP
1135115 # stack: [arg, arg]
1135216
1135317 # 1:
1135418 PUSH_CONST 2
11355@end example
11356
29df5715
DM
11357and to step through the function, examining the data:
11358
11359@example
11360(gdb) n
1136118 PUSH_CONST 2
11362(gdb) n
1136322 BINARY_COMPARE_LT
11364(gdb) print stack
11365$5 = @{10, 10, 2, 0, -7152, 32767, 0, 0@}
11366(gdb) print stack_depth
11367$6 = 3
11368@end example
11369
6f7585de 11370You’ll see that the parts of the @code{stack} array that haven’t been
29df5715
DM
11371touched yet are uninitialized.
11372
11373@cartouche
11374@quotation Note
11375Turning on optimizations may lead to unpredictable results when
11376stepping through the generated code: the execution may appear to
6f7585de 11377“jump around” the source code. This is analogous to turning up the
29df5715
DM
11378optimization level in a regular compiler.
11379@end quotation
11380@end cartouche
11381
11382@node Examining the generated code<2>,Putting it all together<2>,Single-stepping through the generated code<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
421d0d0f 11383@anchor{cp/intro/tutorial04 examining-the-generated-code}@anchor{16a}
29df5715
DM
11384@subsubsection Examining the generated code
11385
11386
11387How good is the optimized code?
11388
11389We can turn up optimizations, by calling
421d0d0f 11390@ref{14a,,gccjit;;context;;set_int_option()} with
6f7585de 11391@ref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}:
29df5715
DM
11392
11393@example
11394ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3);
11395@end example
11396
6f7585de 11397One of GCC’s internal representations is called “gimple”. A dump of the
29df5715
DM
11398initial gimple representation of the code can be seen by setting:
11399
11400@example
11401ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1);
11402@end example
11403
29df5715
DM
11404With optimization on and source locations displayed, this gives:
11405
11406@c We'll use "c" for gimple dumps
11407
11408@example
11409factorial (signed int arg)
11410@{
11411 <unnamed type> D.80;
11412 signed int D.81;
11413 signed int D.82;
11414 signed int D.83;
11415 signed int D.84;
11416 signed int D.85;
11417 signed int y;
11418 signed int x;
11419 signed int stack_depth;
11420 signed int stack[8];
11421
11422 try
11423 @{
11424 initial:
11425 stack_depth = 0;
11426 stack[stack_depth] = arg;
11427 stack_depth = stack_depth + 1;
11428 goto instr0;
11429 instr0:
11430 /* DUP */:
11431 stack_depth = stack_depth + -1;
11432 x = stack[stack_depth];
11433 stack[stack_depth] = x;
11434 stack_depth = stack_depth + 1;
11435 stack[stack_depth] = x;
11436 stack_depth = stack_depth + 1;
11437 goto instr1;
11438 instr1:
11439 /* PUSH_CONST */:
11440 stack[stack_depth] = 2;
11441 stack_depth = stack_depth + 1;
11442 goto instr2;
11443
11444 /* etc */
11445@end example
11446
29df5715
DM
11447You can see the generated machine code in assembly form via:
11448
11449@example
11450ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1);
11451result = ctxt.compile ();
11452@end example
11453
29df5715
DM
11454which shows that (on this x86_64 box) the compiler has unrolled the loop
11455and is using MMX instructions to perform several multiplications
11456simultaneously:
11457
11458@example
11459 .file "fake.c"
11460 .text
11461.Ltext0:
11462 .p2align 4,,15
11463 .globl factorial
11464 .type factorial, @@function
11465factorial:
11466.LFB0:
11467 .file 1 "factorial.toy"
11468 .loc 1 14 0
11469 .cfi_startproc
11470.LVL0:
11471.L2:
11472 .loc 1 26 0
11473 cmpl $1, %edi
11474 jle .L13
11475 leal -1(%rdi), %edx
11476 movl %edx, %ecx
11477 shrl $2, %ecx
11478 leal 0(,%rcx,4), %esi
11479 testl %esi, %esi
11480 je .L14
11481 cmpl $9, %edx
11482 jbe .L14
11483 leal -2(%rdi), %eax
11484 movl %eax, -16(%rsp)
11485 leal -3(%rdi), %eax
11486 movd -16(%rsp), %xmm0
11487 movl %edi, -16(%rsp)
11488 movl %eax, -12(%rsp)
11489 movd -16(%rsp), %xmm1
11490 xorl %eax, %eax
11491 movl %edx, -16(%rsp)
11492 movd -12(%rsp), %xmm4
11493 movd -16(%rsp), %xmm6
11494 punpckldq %xmm4, %xmm0
11495 movdqa .LC1(%rip), %xmm4
11496 punpckldq %xmm6, %xmm1
11497 punpcklqdq %xmm0, %xmm1
11498 movdqa .LC0(%rip), %xmm0
11499 jmp .L5
11500 # etc - edited for brevity
11501@end example
11502
29df5715
DM
11503This is clearly overkill for a function that will likely overflow the
11504@code{int} type before the vectorization is worthwhile - but then again, this
11505is a toy example.
11506
11507Turning down the optimization level to 2:
11508
11509@example
11510ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 2);
11511@end example
11512
29df5715
DM
11513yields this code, which is simple enough to quote in its entirety:
11514
11515@example
11516 .file "fake.c"
11517 .text
11518 .p2align 4,,15
11519 .globl factorial
11520 .type factorial, @@function
11521factorial:
11522.LFB0:
11523 .cfi_startproc
11524.L2:
11525 cmpl $1, %edi
11526 jle .L8
11527 movl $1, %edx
11528 jmp .L4
11529 .p2align 4,,10
11530 .p2align 3
11531.L6:
11532 movl %eax, %edi
11533.L4:
11534.L5:
11535 leal -1(%rdi), %eax
11536 imull %edi, %edx
11537 cmpl $1, %eax
11538 jne .L6
11539.L3:
11540.L7:
11541 imull %edx, %eax
11542 ret
11543.L8:
11544 movl %edi, %eax
11545 movl $1, %edx
11546 jmp .L7
11547 .cfi_endproc
11548.LFE0:
11549 .size factorial, .-factorial
11550 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-%@{gcc_release@})"
11551 .section .note.GNU-stack,"",@@progbits
11552@end example
11553
29df5715
DM
11554Note that the stack pushing and popping have been eliminated, as has the
11555recursive call (in favor of an iteration).
11556
11557@node Putting it all together<2>,Behind the curtain How does our code get optimized?<2>,Examining the generated code<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
421d0d0f 11558@anchor{cp/intro/tutorial04 putting-it-all-together}@anchor{16b}
29df5715
DM
11559@subsubsection Putting it all together
11560
11561
11562The complete example can be seen in the source tree at
11563@code{gcc/jit/docs/examples/tut04-toyvm/toyvm.cc}
11564
11565along with a Makefile and a couple of sample .toy scripts:
11566
11567@example
11568$ ls -al
11569drwxrwxr-x. 2 david david 4096 Sep 19 17:46 .
11570drwxrwxr-x. 3 david david 4096 Sep 19 15:26 ..
11571-rw-rw-r--. 1 david david 615 Sep 19 12:43 factorial.toy
11572-rw-rw-r--. 1 david david 834 Sep 19 13:08 fibonacci.toy
11573-rw-rw-r--. 1 david david 238 Sep 19 14:22 Makefile
11574-rw-rw-r--. 1 david david 16457 Sep 19 17:07 toyvm.cc
11575
11576$ make toyvm
11577g++ -Wall -g -o toyvm toyvm.cc -lgccjit
11578
11579$ ./toyvm factorial.toy 10
11580interpreter result: 3628800
11581compiler result: 3628800
11582
11583$ ./toyvm fibonacci.toy 10
11584interpreter result: 55
11585compiler result: 55
11586@end example
11587
29df5715 11588@node Behind the curtain How does our code get optimized?<2>,,Putting it all together<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
421d0d0f 11589@anchor{cp/intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{16c}
29df5715
DM
11590@subsubsection Behind the curtain: How does our code get optimized?
11591
11592
11593Our example is done, but you may be wondering about exactly how the
11594compiler turned what we gave it into the machine code seen above.
11595
11596We can examine what the compiler is doing in detail by setting:
11597
11598@example
11599state.ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 1);
11600state.ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 1);
11601@end example
11602
6f7585de 11603This will dump detailed information about the compiler’s state to a
29df5715
DM
11604directory under @code{/tmp}, and keep it from being cleaned up.
11605
11606The precise names and their formats of these files is subject to change.
11607Higher optimization levels lead to more files.
6f7585de 11608Here’s what I saw (edited for brevity; there were almost 200 files):
29df5715
DM
11609
11610@example
11611intermediate files written to /tmp/libgccjit-KPQbGw
11612$ ls /tmp/libgccjit-KPQbGw/
11613fake.c.000i.cgraph
11614fake.c.000i.type-inheritance
11615fake.c.004t.gimple
11616fake.c.007t.omplower
11617fake.c.008t.lower
11618fake.c.011t.eh
11619fake.c.012t.cfg
11620fake.c.014i.visibility
11621fake.c.015i.early_local_cleanups
11622fake.c.016t.ssa
11623# etc
11624@end example
11625
29df5715
DM
11626The gimple code is converted into Static Single Assignment form,
11627with annotations for use when generating the debuginfo:
11628
11629@example
11630$ less /tmp/libgccjit-KPQbGw/fake.c.016t.ssa
11631@end example
11632
29df5715
DM
11633@example
11634;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
11635
11636factorial (signed int arg)
11637@{
11638 signed int stack[8];
11639 signed int stack_depth;
11640 signed int x;
11641 signed int y;
11642 <unnamed type> _20;
11643 signed int _21;
11644 signed int _38;
11645 signed int _44;
11646 signed int _51;
11647 signed int _56;
11648
11649initial:
11650 stack_depth_3 = 0;
11651 # DEBUG stack_depth => stack_depth_3
11652 stack[stack_depth_3] = arg_5(D);
11653 stack_depth_7 = stack_depth_3 + 1;
11654 # DEBUG stack_depth => stack_depth_7
11655 # DEBUG instr0 => NULL
11656 # DEBUG /* DUP */ => NULL
11657 stack_depth_8 = stack_depth_7 + -1;
11658 # DEBUG stack_depth => stack_depth_8
11659 x_9 = stack[stack_depth_8];
11660 # DEBUG x => x_9
11661 stack[stack_depth_8] = x_9;
11662 stack_depth_11 = stack_depth_8 + 1;
11663 # DEBUG stack_depth => stack_depth_11
11664 stack[stack_depth_11] = x_9;
11665 stack_depth_13 = stack_depth_11 + 1;
11666 # DEBUG stack_depth => stack_depth_13
11667 # DEBUG instr1 => NULL
11668 # DEBUG /* PUSH_CONST */ => NULL
11669 stack[stack_depth_13] = 2;
11670
11671 /* etc; edited for brevity */
11672@end example
11673
29df5715 11674We can perhaps better see the code by turning off
6f7585de 11675@ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to suppress all those @code{DEBUG}
29df5715
DM
11676statements, giving:
11677
11678@example
11679$ less /tmp/libgccjit-1Hywc0/fake.c.016t.ssa
11680@end example
11681
29df5715
DM
11682@example
11683;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
11684
11685factorial (signed int arg)
11686@{
11687 signed int stack[8];
11688 signed int stack_depth;
11689 signed int x;
11690 signed int y;
11691 <unnamed type> _20;
11692 signed int _21;
11693 signed int _38;
11694 signed int _44;
11695 signed int _51;
11696 signed int _56;
11697
11698initial:
11699 stack_depth_3 = 0;
11700 stack[stack_depth_3] = arg_5(D);
11701 stack_depth_7 = stack_depth_3 + 1;
11702 stack_depth_8 = stack_depth_7 + -1;
11703 x_9 = stack[stack_depth_8];
11704 stack[stack_depth_8] = x_9;
11705 stack_depth_11 = stack_depth_8 + 1;
11706 stack[stack_depth_11] = x_9;
11707 stack_depth_13 = stack_depth_11 + 1;
11708 stack[stack_depth_13] = 2;
11709 stack_depth_15 = stack_depth_13 + 1;
11710 stack_depth_16 = stack_depth_15 + -1;
11711 y_17 = stack[stack_depth_16];
11712 stack_depth_18 = stack_depth_16 + -1;
11713 x_19 = stack[stack_depth_18];
11714 _20 = x_19 < y_17;
11715 _21 = (signed int) _20;
11716 stack[stack_depth_18] = _21;
11717 stack_depth_23 = stack_depth_18 + 1;
11718 stack_depth_24 = stack_depth_23 + -1;
11719 x_25 = stack[stack_depth_24];
11720 if (x_25 != 0)
11721 goto <bb 4> (instr9);
11722 else
11723 goto <bb 3> (instr4);
11724
11725instr4:
11726/* DUP */:
11727 stack_depth_26 = stack_depth_24 + -1;
11728 x_27 = stack[stack_depth_26];
11729 stack[stack_depth_26] = x_27;
11730 stack_depth_29 = stack_depth_26 + 1;
11731 stack[stack_depth_29] = x_27;
11732 stack_depth_31 = stack_depth_29 + 1;
11733 stack[stack_depth_31] = 1;
11734 stack_depth_33 = stack_depth_31 + 1;
11735 stack_depth_34 = stack_depth_33 + -1;
11736 y_35 = stack[stack_depth_34];
11737 stack_depth_36 = stack_depth_34 + -1;
11738 x_37 = stack[stack_depth_36];
11739 _38 = x_37 - y_35;
11740 stack[stack_depth_36] = _38;
11741 stack_depth_40 = stack_depth_36 + 1;
11742 stack_depth_41 = stack_depth_40 + -1;
11743 x_42 = stack[stack_depth_41];
11744 _44 = factorial (x_42);
11745 stack[stack_depth_41] = _44;
11746 stack_depth_46 = stack_depth_41 + 1;
11747 stack_depth_47 = stack_depth_46 + -1;
11748 y_48 = stack[stack_depth_47];
11749 stack_depth_49 = stack_depth_47 + -1;
11750 x_50 = stack[stack_depth_49];
11751 _51 = x_50 * y_48;
11752 stack[stack_depth_49] = _51;
11753 stack_depth_53 = stack_depth_49 + 1;
11754
11755 # stack_depth_1 = PHI <stack_depth_24(2), stack_depth_53(3)>
11756instr9:
11757/* RETURN */:
11758 stack_depth_54 = stack_depth_1 + -1;
11759 x_55 = stack[stack_depth_54];
11760 _56 = x_55;
11761 stack =@{v@} @{CLOBBER@};
11762 return _56;
11763
11764@}
11765@end example
11766
421d0d0f 11767Note in the above how all the @ref{153,,gccjit;;block} instances we
6f7585de 11768created have been consolidated into just 3 blocks in GCC’s internal
29df5715
DM
11769representation: @code{initial}, @code{instr4} and @code{instr9}.
11770
11771@menu
11772* Optimizing away stack manipulation: Optimizing away stack manipulation<2>.
11773* Elimination of tail recursion: Elimination of tail recursion<2>.
11774
11775@end menu
11776
11777@node Optimizing away stack manipulation<2>,Elimination of tail recursion<2>,,Behind the curtain How does our code get optimized?<2>
421d0d0f 11778@anchor{cp/intro/tutorial04 optimizing-away-stack-manipulation}@anchor{16d}
29df5715
DM
11779@subsubsection Optimizing away stack manipulation
11780
11781
6f7585de 11782Recall our simple implementation of stack operations. Let’s examine
29df5715
DM
11783how the stack operations are optimized away.
11784
11785After a pass of constant-propagation, the depth of the stack at each
11786opcode can be determined at compile-time:
11787
11788@example
11789$ less /tmp/libgccjit-1Hywc0/fake.c.021t.ccp1
11790@end example
11791
29df5715
DM
11792@example
11793;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
11794
11795factorial (signed int arg)
11796@{
11797 signed int stack[8];
11798 signed int stack_depth;
11799 signed int x;
11800 signed int y;
11801 <unnamed type> _20;
11802 signed int _21;
11803 signed int _38;
11804 signed int _44;
11805 signed int _51;
11806
11807initial:
11808 stack[0] = arg_5(D);
11809 x_9 = stack[0];
11810 stack[0] = x_9;
11811 stack[1] = x_9;
11812 stack[2] = 2;
11813 y_17 = stack[2];
11814 x_19 = stack[1];
11815 _20 = x_19 < y_17;
11816 _21 = (signed int) _20;
11817 stack[1] = _21;
11818 x_25 = stack[1];
11819 if (x_25 != 0)
11820 goto <bb 4> (instr9);
11821 else
11822 goto <bb 3> (instr4);
11823
11824instr4:
11825/* DUP */:
11826 x_27 = stack[0];
11827 stack[0] = x_27;
11828 stack[1] = x_27;
11829 stack[2] = 1;
11830 y_35 = stack[2];
11831 x_37 = stack[1];
11832 _38 = x_37 - y_35;
11833 stack[1] = _38;
11834 x_42 = stack[1];
11835 _44 = factorial (x_42);
11836 stack[1] = _44;
11837 y_48 = stack[1];
11838 x_50 = stack[0];
11839 _51 = x_50 * y_48;
11840 stack[0] = _51;
11841
11842instr9:
11843/* RETURN */:
11844 x_55 = stack[0];
11845 x_56 = x_55;
11846 stack =@{v@} @{CLOBBER@};
11847 return x_56;
11848
11849@}
11850@end example
11851
29df5715 11852Note how, in the above, all those @code{stack_depth} values are now just
6f7585de 11853constants: we’re accessing specific stack locations at each opcode.
29df5715 11854
6f7585de
DM
11855The “esra” pass (“Early Scalar Replacement of Aggregates”) breaks
11856out our “stack” array into individual elements:
29df5715
DM
11857
11858@example
11859$ less /tmp/libgccjit-1Hywc0/fake.c.024t.esra
11860@end example
11861
29df5715
DM
11862@example
11863;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
11864
11865Created a replacement for stack offset: 0, size: 32: stack$0
11866Created a replacement for stack offset: 32, size: 32: stack$1
11867Created a replacement for stack offset: 64, size: 32: stack$2
11868
11869Symbols to be put in SSA form
11870@{ D.89 D.90 D.91 @}
11871Incremental SSA update started at block: 0
11872Number of blocks in CFG: 5
11873Number of blocks to update: 4 ( 80%)
11874
11875
11876factorial (signed int arg)
11877@{
11878 signed int stack$2;
11879 signed int stack$1;
11880 signed int stack$0;
11881 signed int stack[8];
11882 signed int stack_depth;
11883 signed int x;
11884 signed int y;
11885 <unnamed type> _20;
11886 signed int _21;
11887 signed int _38;
11888 signed int _44;
11889 signed int _51;
11890
11891initial:
11892 stack$0_45 = arg_5(D);
11893 x_9 = stack$0_45;
11894 stack$0_39 = x_9;
11895 stack$1_32 = x_9;
11896 stack$2_30 = 2;
11897 y_17 = stack$2_30;
11898 x_19 = stack$1_32;
11899 _20 = x_19 < y_17;
11900 _21 = (signed int) _20;
11901 stack$1_28 = _21;
11902 x_25 = stack$1_28;
11903 if (x_25 != 0)
11904 goto <bb 4> (instr9);
11905 else
11906 goto <bb 3> (instr4);
11907
11908instr4:
11909/* DUP */:
11910 x_27 = stack$0_39;
11911 stack$0_22 = x_27;
11912 stack$1_14 = x_27;
11913 stack$2_12 = 1;
11914 y_35 = stack$2_12;
11915 x_37 = stack$1_14;
11916 _38 = x_37 - y_35;
11917 stack$1_10 = _38;
11918 x_42 = stack$1_10;
11919 _44 = factorial (x_42);
11920 stack$1_6 = _44;
11921 y_48 = stack$1_6;
11922 x_50 = stack$0_22;
11923 _51 = x_50 * y_48;
11924 stack$0_1 = _51;
11925
11926 # stack$0_52 = PHI <stack$0_39(2), stack$0_1(3)>
11927instr9:
11928/* RETURN */:
11929 x_55 = stack$0_52;
11930 x_56 = x_55;
11931 stack =@{v@} @{CLOBBER@};
11932 return x_56;
11933
11934@}
11935@end example
11936
29df5715
DM
11937Hence at this point, all those pushes and pops of the stack are now
11938simply assignments to specific temporary variables.
11939
11940After some copy propagation, the stack manipulation has been completely
11941optimized away:
11942
11943@example
11944$ less /tmp/libgccjit-1Hywc0/fake.c.026t.copyprop1
11945@end example
11946
29df5715
DM
11947@example
11948;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
11949
11950factorial (signed int arg)
11951@{
11952 signed int stack$2;
11953 signed int stack$1;
11954 signed int stack$0;
11955 signed int stack[8];
11956 signed int stack_depth;
11957 signed int x;
11958 signed int y;
11959 <unnamed type> _20;
11960 signed int _21;
11961 signed int _38;
11962 signed int _44;
11963 signed int _51;
11964
11965initial:
11966 stack$0_39 = arg_5(D);
11967 _20 = arg_5(D) <= 1;
11968 _21 = (signed int) _20;
11969 if (_21 != 0)
11970 goto <bb 4> (instr9);
11971 else
11972 goto <bb 3> (instr4);
11973
11974instr4:
11975/* DUP */:
11976 _38 = arg_5(D) + -1;
11977 _44 = factorial (_38);
11978 _51 = arg_5(D) * _44;
11979 stack$0_1 = _51;
11980
11981 # stack$0_52 = PHI <arg_5(D)(2), _51(3)>
11982instr9:
11983/* RETURN */:
11984 stack =@{v@} @{CLOBBER@};
11985 return stack$0_52;
11986
11987@}
11988@end example
11989
29df5715
DM
11990Later on, another pass finally eliminated @code{stack_depth} local and the
11991unused parts of the @cite{stack`} array altogether:
11992
11993@example
11994$ less /tmp/libgccjit-1Hywc0/fake.c.036t.release_ssa
11995@end example
11996
29df5715
DM
11997@example
11998;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
11999
12000Released 44 names, 314.29%, removed 44 holes
12001factorial (signed int arg)
12002@{
12003 signed int stack$0;
12004 signed int mult_acc_1;
12005 <unnamed type> _5;
12006 signed int _6;
12007 signed int _7;
12008 signed int mul_tmp_10;
12009 signed int mult_acc_11;
12010 signed int mult_acc_13;
12011
12012 # arg_9 = PHI <arg_8(D)(0)>
12013 # mult_acc_13 = PHI <1(0)>
12014initial:
12015
12016 <bb 5>:
12017 # arg_4 = PHI <arg_9(2), _7(3)>
12018 # mult_acc_1 = PHI <mult_acc_13(2), mult_acc_11(3)>
12019 _5 = arg_4 <= 1;
12020 _6 = (signed int) _5;
12021 if (_6 != 0)
12022 goto <bb 4> (instr9);
12023 else
12024 goto <bb 3> (instr4);
12025
12026instr4:
12027/* DUP */:
12028 _7 = arg_4 + -1;
12029 mult_acc_11 = mult_acc_1 * arg_4;
12030 goto <bb 5>;
12031
12032 # stack$0_12 = PHI <arg_4(5)>
12033instr9:
12034/* RETURN */:
12035 mul_tmp_10 = mult_acc_1 * stack$0_12;
12036 return mul_tmp_10;
12037
12038@}
12039@end example
12040
29df5715 12041@node Elimination of tail recursion<2>,,Optimizing away stack manipulation<2>,Behind the curtain How does our code get optimized?<2>
421d0d0f 12042@anchor{cp/intro/tutorial04 elimination-of-tail-recursion}@anchor{16e}
29df5715
DM
12043@subsubsection Elimination of tail recursion
12044
12045
12046Another significant optimization is the detection that the call to
12047@code{factorial} is tail recursion, which can be eliminated in favor of
12048an iteration:
12049
12050@example
12051$ less /tmp/libgccjit-1Hywc0/fake.c.030t.tailr1
12052@end example
12053
29df5715
DM
12054@example
12055;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
12056
12057
12058Symbols to be put in SSA form
12059@{ D.88 @}
12060Incremental SSA update started at block: 0
12061Number of blocks in CFG: 5
12062Number of blocks to update: 4 ( 80%)
12063
12064
12065factorial (signed int arg)
12066@{
12067 signed int stack$2;
12068 signed int stack$1;
12069 signed int stack$0;
12070 signed int stack[8];
12071 signed int stack_depth;
12072 signed int x;
12073 signed int y;
12074 signed int mult_acc_1;
12075 <unnamed type> _20;
12076 signed int _21;
12077 signed int _38;
12078 signed int mul_tmp_44;
12079 signed int mult_acc_51;
12080
12081 # arg_5 = PHI <arg_39(D)(0), _38(3)>
12082 # mult_acc_1 = PHI <1(0), mult_acc_51(3)>
12083initial:
12084 _20 = arg_5 <= 1;
12085 _21 = (signed int) _20;
12086 if (_21 != 0)
12087 goto <bb 4> (instr9);
12088 else
12089 goto <bb 3> (instr4);
12090
12091instr4:
12092/* DUP */:
12093 _38 = arg_5 + -1;
12094 mult_acc_51 = mult_acc_1 * arg_5;
12095 goto <bb 2> (initial);
12096
12097 # stack$0_52 = PHI <arg_5(2)>
12098instr9:
12099/* RETURN */:
12100 stack =@{v@} @{CLOBBER@};
12101 mul_tmp_44 = mult_acc_1 * stack$0_52;
12102 return mul_tmp_44;
12103
12104@}
12105@end example
12106
7adcbafe 12107@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
29df5715
DM
12108@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
12109@c
12110@c This is free software: you can redistribute it and/or modify it
12111@c under the terms of the GNU General Public License as published by
12112@c the Free Software Foundation, either version 3 of the License, or
12113@c (at your option) any later version.
12114@c
12115@c This program is distributed in the hope that it will be useful, but
12116@c WITHOUT ANY WARRANTY; without even the implied warranty of
12117@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12118@c General Public License for more details.
12119@c
12120@c You should have received a copy of the GNU General Public License
12121@c along with this program. If not, see
786973ce 12122@c <https://www.gnu.org/licenses/>.
29df5715
DM
12123
12124@node Topic Reference<2>,,Tutorial<2>,C++ bindings for libgccjit
421d0d0f 12125@anchor{cp/topics/index doc}@anchor{16f}@anchor{cp/topics/index topic-reference}@anchor{170}
29df5715
DM
12126@section Topic Reference
12127
12128
7adcbafe 12129@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
29df5715
DM
12130@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
12131@c
12132@c This is free software: you can redistribute it and/or modify it
12133@c under the terms of the GNU General Public License as published by
12134@c the Free Software Foundation, either version 3 of the License, or
12135@c (at your option) any later version.
12136@c
12137@c This program is distributed in the hope that it will be useful, but
12138@c WITHOUT ANY WARRANTY; without even the implied warranty of
12139@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12140@c General Public License for more details.
12141@c
12142@c You should have received a copy of the GNU General Public License
12143@c along with this program. If not, see
786973ce 12144@c <https://www.gnu.org/licenses/>.
29df5715
DM
12145
12146@menu
12147* Compilation contexts: Compilation contexts<2>.
12148* Objects: Objects<2>.
12149* Types: Types<2>.
12150* Expressions: Expressions<2>.
12151* Creating and using functions: Creating and using functions<2>.
12152* Source Locations: Source Locations<2>.
fdce7209 12153* Compiling a context: Compiling a context<2>.
421d0d0f 12154* Using Assembly Language with libgccjit++::
29df5715 12155
29df5715
DM
12156@end menu
12157
29df5715 12158@node Compilation contexts<2>,Objects<2>,,Topic Reference<2>
421d0d0f 12159@anchor{cp/topics/contexts doc}@anchor{171}@anchor{cp/topics/contexts compilation-contexts}@anchor{172}
29df5715
DM
12160@subsection Compilation contexts
12161
12162
12163@geindex gccjit;;context (C++ class)
421d0d0f 12164@anchor{cp/topics/contexts _CPPv4N6gccjit7contextE}@anchor{13d}@anchor{cp/topics/contexts _CPPv3N6gccjit7contextE}@anchor{173}@anchor{cp/topics/contexts _CPPv2N6gccjit7contextE}@anchor{174}@anchor{cp/topics/contexts gccjit context}@anchor{175}
29df5715
DM
12165@deffn {C++ Class} gccjit::context
12166@end deffn
12167
421d0d0f 12168The top-level of the C++ API is the @ref{13d,,gccjit;;context} type.
29df5715 12169
421d0d0f 12170A @ref{13d,,gccjit;;context} instance encapsulates the state of a
29df5715
DM
12171compilation.
12172
12173You can set up options on it, and add types, functions and code.
421d0d0f 12174Invoking @ref{147,,gccjit;;context;;compile()} on it gives you a
6f7585de 12175@ref{16,,gcc_jit_result *}.
29df5715 12176
6f7585de 12177It is a thin wrapper around the C API’s @ref{8,,gcc_jit_context *}.
29df5715
DM
12178
12179@menu
12180* Lifetime-management: Lifetime-management<2>.
12181* Thread-safety: Thread-safety<2>.
12182* Error-handling: Error-handling<3>.
12183* Debugging: Debugging<2>.
12184* Options: Options<4>.
12185
12186@end menu
12187
12188@node Lifetime-management<2>,Thread-safety<2>,,Compilation contexts<2>
421d0d0f 12189@anchor{cp/topics/contexts lifetime-management}@anchor{176}
29df5715
DM
12190@subsubsection Lifetime-management
12191
12192
12193Contexts are the unit of lifetime-management within the API: objects
12194have their lifetime bounded by the context they are created within, and
12195cleanup of such objects is done for you when the context is released.
12196
12197@geindex gccjit;;context;;acquire (C++ function)
421d0d0f
DM
12198@anchor{cp/topics/contexts _CPPv4N6gccjit7context7acquireEv}@anchor{13e}@anchor{cp/topics/contexts _CPPv3N6gccjit7context7acquireEv}@anchor{177}@anchor{cp/topics/contexts _CPPv2N6gccjit7context7acquireEv}@anchor{178}@anchor{cp/topics/contexts gccjit context acquire}@anchor{179}
12199@deffn {C++ Function} gccjit::@ref{13d,,context} gccjit::@ref{13d,,context}::acquire ()
29df5715 12200
421d0d0f 12201This function acquires a new @ref{13d,,gccjit;;context} instance,
29df5715
DM
12202which is independent of any others that may be present within this
12203process.
12204@end deffn
12205
12206@geindex gccjit;;context;;release (C++ function)
421d0d0f
DM
12207@anchor{cp/topics/contexts _CPPv4N6gccjit7context7releaseEv}@anchor{141}@anchor{cp/topics/contexts _CPPv3N6gccjit7context7releaseEv}@anchor{17a}@anchor{cp/topics/contexts _CPPv2N6gccjit7context7releaseEv}@anchor{17b}@anchor{cp/topics/contexts gccjit context release}@anchor{17c}
12208@deffn {C++ Function} void gccjit::@ref{13d,,context}::release ()
29df5715
DM
12209
12210This function releases all resources associated with the given context.
12211Both the context itself and all of its @code{gccjit::object *}
12212instances are cleaned up. It should be called exactly once on a given
12213context.
12214
6f7585de 12215It is invalid to use the context or any of its “contextual” objects
29df5715
DM
12216after calling this.
12217
12218@example
12219ctxt.release ();
12220@end example
29df5715
DM
12221@end deffn
12222
12223@geindex gccjit;;context;;new_child_context (C++ function)
421d0d0f
DM
12224@anchor{cp/topics/contexts _CPPv4N6gccjit7context17new_child_contextEv}@anchor{17d}@anchor{cp/topics/contexts _CPPv3N6gccjit7context17new_child_contextEv}@anchor{17e}@anchor{cp/topics/contexts _CPPv2N6gccjit7context17new_child_contextEv}@anchor{17f}@anchor{cp/topics/contexts gccjit context new_child_context}@anchor{180}
12225@deffn {C++ Function} gccjit::@ref{13d,,context} gccjit::@ref{13d,,context}::new_child_context ()
29df5715
DM
12226
12227Given an existing JIT context, create a child context.
12228
12229The child inherits a copy of all option-settings from the parent.
12230
12231The child can reference objects created within the parent, but not
12232vice-versa.
12233
12234The lifetime of the child context must be bounded by that of the
12235parent: you should release a child context before releasing the parent
12236context.
12237
12238If you use a function from a parent context within a child context,
12239you have to compile the parent context before you can compile the
12240child context, and the gccjit::result of the parent context must
12241outlive the gccjit::result of the child context.
12242
12243This allows caching of shared initializations. For example, you could
12244create types and declarations of global functions in a parent context
12245once within a process, and then create child contexts whenever a
12246function or loop becomes hot. Each such child context can be used for
12247JIT-compiling just one function or loop, but can reference types
12248and helper functions created within the parent context.
12249
12250Contexts can be arbitrarily nested, provided the above rules are
6f7585de 12251followed, but it’s probably not worth going above 2 or 3 levels, and
29df5715
DM
12252there will likely be a performance hit for such nesting.
12253@end deffn
12254
12255@node Thread-safety<2>,Error-handling<3>,Lifetime-management<2>,Compilation contexts<2>
421d0d0f 12256@anchor{cp/topics/contexts thread-safety}@anchor{181}
29df5715
DM
12257@subsubsection Thread-safety
12258
12259
421d0d0f
DM
12260Instances of @ref{13d,,gccjit;;context} created via
12261@ref{13e,,gccjit;;context;;acquire()} are independent from each other:
29df5715
DM
12262only one thread may use a given context at once, but multiple threads
12263could each have their own contexts without needing locks.
12264
421d0d0f 12265Contexts created via @ref{17d,,gccjit;;context;;new_child_context()} are
29df5715 12266related to their parent context. They can be partitioned by their
6f7585de
DM
12267ultimate ancestor into independent “family trees”. Only one thread
12268within a process may use a given “family tree” of such contexts at once,
12269and if you’re using multiple threads you should provide your own locking
29df5715
DM
12270around entire such context partitions.
12271
12272@node Error-handling<3>,Debugging<2>,Thread-safety<2>,Compilation contexts<2>
421d0d0f 12273@anchor{cp/topics/contexts error-handling}@anchor{182}
29df5715
DM
12274@subsubsection Error-handling
12275
12276
12277@c FIXME: How does error-handling work for C++ API?
12278
12279You can only compile and get code from a context if no errors occur.
12280
12281In general, if an error occurs when using an API entrypoint, it returns
6f7585de 12282NULL. You don’t have to check everywhere for NULL results, since the
29df5715
DM
12283API gracefully handles a NULL being passed in for any argument.
12284
12285Errors are printed on stderr and can be queried using
421d0d0f 12286@ref{183,,gccjit;;context;;get_first_error()}.
29df5715
DM
12287
12288@geindex gccjit;;context;;get_first_error (C++ function)
421d0d0f
DM
12289@anchor{cp/topics/contexts _CPPv4N6gccjit7context15get_first_errorEPN6gccjit7contextE}@anchor{183}@anchor{cp/topics/contexts _CPPv3N6gccjit7context15get_first_errorEPN6gccjit7contextE}@anchor{184}@anchor{cp/topics/contexts _CPPv2N6gccjit7context15get_first_errorEPN6gccjit7contextE}@anchor{185}@anchor{cp/topics/contexts gccjit context get_first_error__gccjit contextP}@anchor{186}
12290@deffn {C++ Function} const char *gccjit::@ref{13d,,context}::get_first_error (gccjit::context *ctxt)
29df5715
DM
12291
12292Returns the first error message that occurred on the context.
12293
12294The returned string is valid for the rest of the lifetime of the
12295context.
12296
12297If no errors occurred, this will be NULL.
12298@end deffn
12299
12300@node Debugging<2>,Options<4>,Error-handling<3>,Compilation contexts<2>
421d0d0f 12301@anchor{cp/topics/contexts debugging}@anchor{187}
29df5715
DM
12302@subsubsection Debugging
12303
12304
12305@geindex gccjit;;context;;dump_to_file (C++ function)
421d0d0f
DM
12306@anchor{cp/topics/contexts _CPPv4N6gccjit7context12dump_to_fileERKNSt6stringEi}@anchor{188}@anchor{cp/topics/contexts _CPPv3N6gccjit7context12dump_to_fileERKNSt6stringEi}@anchor{189}@anchor{cp/topics/contexts _CPPv2N6gccjit7context12dump_to_fileERKNSt6stringEi}@anchor{18a}@anchor{cp/topics/contexts gccjit context dump_to_file__ssCR i}@anchor{18b}
12307@deffn {C++ Function} void gccjit::@ref{13d,,context}::dump_to_file (const std::string &path, int update_locations)
29df5715
DM
12308
12309To help with debugging: dump a C-like representation to the given path,
6f7585de 12310describing what’s been set up on the context.
29df5715 12311
421d0d0f 12312If “update_locations” is true, then also set up @ref{163,,gccjit;;location}
29df5715
DM
12313information throughout the context, pointing at the dump file as if it
12314were a source file. This may be of use in conjunction with
12315@code{GCCJIT::BOOL_OPTION_DEBUGINFO} to allow stepping through the
12316code in a debugger.
12317@end deffn
12318
86d0ac88 12319@geindex gccjit;;context;;dump_reproducer_to_file (C++ function)
421d0d0f
DM
12320@anchor{cp/topics/contexts _CPPv4N6gccjit7context23dump_reproducer_to_fileEP15gcc_jit_contextPKc}@anchor{18c}@anchor{cp/topics/contexts _CPPv3N6gccjit7context23dump_reproducer_to_fileEP15gcc_jit_contextPKc}@anchor{18d}@anchor{cp/topics/contexts _CPPv2N6gccjit7context23dump_reproducer_to_fileEP15gcc_jit_contextPKc}@anchor{18e}@anchor{cp/topics/contexts gccjit context dump_reproducer_to_file__gcc_jit_contextP cCP}@anchor{18f}
12321@deffn {C++ Function} void gccjit::@ref{13d,,context}::dump_reproducer_to_file (gcc_jit_context *ctxt, const char *path)
86d0ac88
DM
12322
12323This is a thin wrapper around the C API
6f7585de 12324@ref{5d,,gcc_jit_context_dump_reproducer_to_file()}, and hence works the
86d0ac88
DM
12325same way.
12326
12327Note that the generated source is C code, not C++; this might be of use
12328for seeing what the C++ bindings are doing at the C level.
12329@end deffn
12330
29df5715 12331@node Options<4>,,Debugging<2>,Compilation contexts<2>
421d0d0f 12332@anchor{cp/topics/contexts options}@anchor{190}
29df5715
DM
12333@subsubsection Options
12334
12335
29df5715 12336@menu
35291c7d 12337* String Options: String Options<2>.
29df5715
DM
12338* Boolean options: Boolean options<2>.
12339* Integer options: Integer options<2>.
fa22c20d 12340* Additional command-line options: Additional command-line options<2>.
29df5715
DM
12341
12342@end menu
12343
35291c7d 12344@node String Options<2>,Boolean options<2>,,Options<4>
421d0d0f 12345@anchor{cp/topics/contexts string-options}@anchor{191}
35291c7d
DM
12346@subsubsection String Options
12347
12348
12349@geindex gccjit;;context;;set_str_option (C++ function)
421d0d0f
DM
12350@anchor{cp/topics/contexts _CPPv4N6gccjit7context14set_str_optionE18gcc_jit_str_optionPKc}@anchor{192}@anchor{cp/topics/contexts _CPPv3N6gccjit7context14set_str_optionE18gcc_jit_str_optionPKc}@anchor{193}@anchor{cp/topics/contexts _CPPv2N6gccjit7context14set_str_optionE18gcc_jit_str_optionPKc}@anchor{194}@anchor{cp/topics/contexts gccjit context set_str_option__gcc_jit_str_option cCP}@anchor{195}
12351@deffn {C++ Function} void gccjit::@ref{13d,,context}::set_str_option (enum gcc_jit_str_option, const char *value)
35291c7d
DM
12352
12353Set a string option of the context.
12354
12355This is a thin wrapper around the C API
6f7585de 12356@ref{61,,gcc_jit_context_set_str_option()}; the options have the same
35291c7d
DM
12357meaning.
12358@end deffn
12359
12360@node Boolean options<2>,Integer options<2>,String Options<2>,Options<4>
421d0d0f 12361@anchor{cp/topics/contexts boolean-options}@anchor{196}
29df5715
DM
12362@subsubsection Boolean options
12363
12364
12365@geindex gccjit;;context;;set_bool_option (C++ function)
421d0d0f
DM
12366@anchor{cp/topics/contexts _CPPv4N6gccjit7context15set_bool_optionE19gcc_jit_bool_optioni}@anchor{149}@anchor{cp/topics/contexts _CPPv3N6gccjit7context15set_bool_optionE19gcc_jit_bool_optioni}@anchor{197}@anchor{cp/topics/contexts _CPPv2N6gccjit7context15set_bool_optionE19gcc_jit_bool_optioni}@anchor{198}@anchor{cp/topics/contexts gccjit context set_bool_option__gcc_jit_bool_option i}@anchor{199}
12367@deffn {C++ Function} void gccjit::@ref{13d,,context}::set_bool_option (enum gcc_jit_bool_option, int value)
29df5715
DM
12368
12369Set a boolean option of the context.
12370
12371This is a thin wrapper around the C API
6f7585de 12372@ref{1b,,gcc_jit_context_set_bool_option()}; the options have the same
29df5715
DM
12373meaning.
12374@end deffn
12375
6a3603e3 12376@geindex gccjit;;context;;set_bool_allow_unreachable_blocks (C++ function)
421d0d0f
DM
12377@anchor{cp/topics/contexts _CPPv4N6gccjit7context33set_bool_allow_unreachable_blocksEi}@anchor{19a}@anchor{cp/topics/contexts _CPPv3N6gccjit7context33set_bool_allow_unreachable_blocksEi}@anchor{19b}@anchor{cp/topics/contexts _CPPv2N6gccjit7context33set_bool_allow_unreachable_blocksEi}@anchor{19c}@anchor{cp/topics/contexts gccjit context set_bool_allow_unreachable_blocks__i}@anchor{19d}
12378@deffn {C++ Function} void gccjit::@ref{13d,,context}::set_bool_allow_unreachable_blocks (int bool_value)
6a3603e3
DM
12379
12380By default, libgccjit will issue an error about unreachable blocks
12381within a function.
12382
12383This entrypoint can be used to disable that error; it is a thin wrapper
12384around the C API
6f7585de 12385@ref{6b,,gcc_jit_context_set_bool_allow_unreachable_blocks()}.
6a3603e3 12386
6f7585de 12387This entrypoint was added in @ref{6c,,LIBGCCJIT_ABI_2}; you can test for
6a3603e3
DM
12388its presence using
12389
12390@example
12391#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks
12392@end example
6a3603e3
DM
12393@end deffn
12394
199501ea 12395@geindex gccjit;;context;;set_bool_use_external_driver (C++ function)
421d0d0f
DM
12396@anchor{cp/topics/contexts _CPPv4N6gccjit7context28set_bool_use_external_driverEi}@anchor{19e}@anchor{cp/topics/contexts _CPPv3N6gccjit7context28set_bool_use_external_driverEi}@anchor{19f}@anchor{cp/topics/contexts _CPPv2N6gccjit7context28set_bool_use_external_driverEi}@anchor{1a0}@anchor{cp/topics/contexts gccjit context set_bool_use_external_driver__i}@anchor{1a1}
12397@deffn {C++ Function} void gccjit::@ref{13d,,context}::set_bool_use_external_driver (int bool_value)
199501ea 12398
6f7585de 12399libgccjit internally generates assembler, and uses “driver” code
199501ea
DM
12400for converting it to other formats (e.g. shared libraries).
12401
12402By default, libgccjit will use an embedded copy of the driver
12403code.
12404
12405This option can be used to instead invoke an external driver executable
12406as a subprocess; it is a thin wrapper around the C API
6f7585de 12407@ref{6d,,gcc_jit_context_set_bool_use_external_driver()}.
199501ea 12408
6f7585de 12409This entrypoint was added in @ref{6e,,LIBGCCJIT_ABI_5}; you can test for
199501ea
DM
12410its presence using
12411
12412@example
12413#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_use_external_driver
12414@end example
199501ea
DM
12415@end deffn
12416
fa22c20d 12417@node Integer options<2>,Additional command-line options<2>,Boolean options<2>,Options<4>
421d0d0f 12418@anchor{cp/topics/contexts integer-options}@anchor{1a2}
29df5715
DM
12419@subsubsection Integer options
12420
12421
12422@geindex gccjit;;context;;set_int_option (C++ function)
421d0d0f
DM
12423@anchor{cp/topics/contexts _CPPv4N6gccjit7context14set_int_optionE18gcc_jit_int_optioni}@anchor{14a}@anchor{cp/topics/contexts _CPPv3N6gccjit7context14set_int_optionE18gcc_jit_int_optioni}@anchor{1a3}@anchor{cp/topics/contexts _CPPv2N6gccjit7context14set_int_optionE18gcc_jit_int_optioni}@anchor{1a4}@anchor{cp/topics/contexts gccjit context set_int_option__gcc_jit_int_option i}@anchor{1a5}
12424@deffn {C++ Function} void gccjit::@ref{13d,,context}::set_int_option (enum gcc_jit_int_option, int value)
29df5715
DM
12425
12426Set an integer option of the context.
12427
12428This is a thin wrapper around the C API
6f7585de 12429@ref{1e,,gcc_jit_context_set_int_option()}; the options have the same
29df5715
DM
12430meaning.
12431@end deffn
12432
fa22c20d 12433@node Additional command-line options<2>,,Integer options<2>,Options<4>
421d0d0f 12434@anchor{cp/topics/contexts additional-command-line-options}@anchor{1a6}
fa22c20d
DM
12435@subsubsection Additional command-line options
12436
12437
12438@geindex gccjit;;context;;add_command_line_option (C++ function)
421d0d0f
DM
12439@anchor{cp/topics/contexts _CPPv4N6gccjit7context23add_command_line_optionEPKc}@anchor{1a7}@anchor{cp/topics/contexts _CPPv3N6gccjit7context23add_command_line_optionEPKc}@anchor{1a8}@anchor{cp/topics/contexts _CPPv2N6gccjit7context23add_command_line_optionEPKc}@anchor{1a9}@anchor{cp/topics/contexts gccjit context add_command_line_option__cCP}@anchor{1aa}
12440@deffn {C++ Function} void gccjit::@ref{13d,,context}::add_command_line_option (const char *optname)
fa22c20d
DM
12441
12442Add an arbitrary gcc command-line option to the context for use
12443when compiling.
12444
12445This is a thin wrapper around the C API
6f7585de 12446@ref{72,,gcc_jit_context_add_command_line_option()}.
fa22c20d 12447
6f7585de 12448This entrypoint was added in @ref{73,,LIBGCCJIT_ABI_1}; you can test for
fa22c20d
DM
12449its presence using
12450
12451@example
12452#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option
12453@end example
fa22c20d
DM
12454@end deffn
12455
7adcbafe 12456@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
29df5715
DM
12457@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
12458@c
12459@c This is free software: you can redistribute it and/or modify it
12460@c under the terms of the GNU General Public License as published by
12461@c the Free Software Foundation, either version 3 of the License, or
12462@c (at your option) any later version.
12463@c
12464@c This program is distributed in the hope that it will be useful, but
12465@c WITHOUT ANY WARRANTY; without even the implied warranty of
12466@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12467@c General Public License for more details.
12468@c
12469@c You should have received a copy of the GNU General Public License
12470@c along with this program. If not, see
786973ce 12471@c <https://www.gnu.org/licenses/>.
29df5715
DM
12472
12473@node Objects<2>,Types<2>,Compilation contexts<2>,Topic Reference<2>
421d0d0f 12474@anchor{cp/topics/objects doc}@anchor{1ab}@anchor{cp/topics/objects objects}@anchor{1ac}
29df5715
DM
12475@subsection Objects
12476
12477
12478@geindex gccjit;;object (C++ class)
421d0d0f 12479@anchor{cp/topics/objects _CPPv4N6gccjit6objectE}@anchor{142}@anchor{cp/topics/objects _CPPv3N6gccjit6objectE}@anchor{1ad}@anchor{cp/topics/objects _CPPv2N6gccjit6objectE}@anchor{1ae}@anchor{cp/topics/objects gccjit object}@anchor{1af}
29df5715
DM
12480@deffn {C++ Class} gccjit::object
12481@end deffn
12482
12483Almost every entity in the API (with the exception of
421d0d0f
DM
12484@ref{13d,,gccjit;;context} and @ref{16,,gcc_jit_result *}) is a
12485“contextual” object, a @ref{142,,gccjit;;object}.
29df5715
DM
12486
12487A JIT object:
12488
12489@quotation
12490
12491
12492@itemize *
12493
12494@item
421d0d0f 12495is associated with a @ref{13d,,gccjit;;context}.
29df5715
DM
12496
12497@item
12498is automatically cleaned up for you when its context is released so
6f7585de 12499you don’t need to manually track and cleanup all objects, just the
29df5715
DM
12500contexts.
12501@end itemize
12502@end quotation
12503
12504The C++ class hierarchy within the @code{gccjit} namespace looks like this:
12505
12506@example
12507+- object
12508 +- location
12509 +- type
12510 +- struct
12511 +- field
12512 +- function
12513 +- block
12514 +- rvalue
12515 +- lvalue
12516 +- param
ec5d0088 12517 +- case_
29df5715
DM
12518@end example
12519
421d0d0f 12520The @ref{142,,gccjit;;object} base class has the following operations:
29df5715
DM
12521
12522@geindex gccjit;;object;;get_context (C++ function)
421d0d0f
DM
12523@anchor{cp/topics/objects _CPPv4NK6gccjit6object11get_contextEv}@anchor{1b0}@anchor{cp/topics/objects _CPPv3NK6gccjit6object11get_contextEv}@anchor{1b1}@anchor{cp/topics/objects _CPPv2NK6gccjit6object11get_contextEv}@anchor{1b2}@anchor{cp/topics/objects gccjit object get_contextC}@anchor{1b3}
12524@deffn {C++ Function} gccjit::@ref{13d,,context} gccjit::@ref{142,,object}::get_context () const
29df5715
DM
12525
12526Which context is the obj within?
12527@end deffn
12528
12529@geindex gccjit;;object;;get_debug_string (C++ function)
421d0d0f
DM
12530@anchor{cp/topics/objects _CPPv4NK6gccjit6object16get_debug_stringEv}@anchor{143}@anchor{cp/topics/objects _CPPv3NK6gccjit6object16get_debug_stringEv}@anchor{1b4}@anchor{cp/topics/objects _CPPv2NK6gccjit6object16get_debug_stringEv}@anchor{1b5}@anchor{cp/topics/objects gccjit object get_debug_stringC}@anchor{1b6}
12531@deffn {C++ Function} std::string gccjit::@ref{142,,object}::get_debug_string () const
29df5715
DM
12532
12533Generate a human-readable description for the given object.
12534
12535For example,
12536
12537@example
12538printf ("obj: %s\n", obj.get_debug_string ().c_str ());
12539@end example
12540
29df5715
DM
12541might give this text on stdout:
12542
12543@example
12544obj: 4.0 * (float)i
12545@end example
29df5715
DM
12546@end deffn
12547
7adcbafe 12548@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
29df5715
DM
12549@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
12550@c
12551@c This is free software: you can redistribute it and/or modify it
12552@c under the terms of the GNU General Public License as published by
12553@c the Free Software Foundation, either version 3 of the License, or
12554@c (at your option) any later version.
12555@c
12556@c This program is distributed in the hope that it will be useful, but
12557@c WITHOUT ANY WARRANTY; without even the implied warranty of
12558@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12559@c General Public License for more details.
12560@c
12561@c You should have received a copy of the GNU General Public License
12562@c along with this program. If not, see
786973ce 12563@c <https://www.gnu.org/licenses/>.
29df5715
DM
12564
12565@node Types<2>,Expressions<2>,Objects<2>,Topic Reference<2>
421d0d0f 12566@anchor{cp/topics/types doc}@anchor{1b7}@anchor{cp/topics/types types}@anchor{1b8}
29df5715
DM
12567@subsection Types
12568
12569
12570@geindex gccjit;;type (C++ class)
421d0d0f 12571@anchor{cp/topics/types _CPPv4N6gccjit4typeE}@anchor{13f}@anchor{cp/topics/types _CPPv3N6gccjit4typeE}@anchor{1b9}@anchor{cp/topics/types _CPPv2N6gccjit4typeE}@anchor{1ba}@anchor{cp/topics/types gccjit type}@anchor{1bb}
29df5715
DM
12572@deffn {C++ Class} gccjit::type
12573
12574gccjit::type represents a type within the library. It is a subclass
421d0d0f 12575of @ref{142,,gccjit;;object}.
29df5715
DM
12576@end deffn
12577
12578Types can be created in several ways:
12579
12580
12581@itemize *
12582
12583@item
12584fundamental types can be accessed using
421d0d0f 12585@ref{140,,gccjit;;context;;get_type()}:
29df5715
DM
12586
12587@example
12588gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT);
12589@end example
12590
29df5715
DM
12591or using the @code{gccjit::context::get_int_type} template:
12592
12593@example
12594gccjit::type t = ctxt.get_int_type <unsigned short> ();
12595@end example
12596
6f7585de 12597See @ref{b,,gcc_jit_context_get_type()} for the available types.
29df5715
DM
12598
12599@item
12600derived types can be accessed by using functions such as
421d0d0f 12601@ref{1bc,,gccjit;;type;;get_pointer()} and @ref{1bd,,gccjit;;type;;get_const()}:
29df5715
DM
12602
12603@example
12604gccjit::type const_int_star = int_type.get_const ().get_pointer ();
12605gccjit::type int_const_star = int_type.get_pointer ().get_const ();
12606@end example
12607
29df5715
DM
12608@item
12609by creating structures (see below).
12610@end itemize
12611
12612@menu
12613* Standard types: Standard types<2>.
12614* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>.
47ee1b7c 12615* Vector types: Vector types<2>.
29df5715
DM
12616* Structures and unions: Structures and unions<2>.
12617
12618@end menu
12619
12620@node Standard types<2>,Pointers const and volatile<2>,,Types<2>
421d0d0f 12621@anchor{cp/topics/types standard-types}@anchor{1be}
29df5715
DM
12622@subsubsection Standard types
12623
12624
12625@geindex gccjit;;context;;get_type (C++ function)
421d0d0f
DM
12626@anchor{cp/topics/types _CPPv4N6gccjit7context8get_typeE13gcc_jit_types}@anchor{140}@anchor{cp/topics/types _CPPv3N6gccjit7context8get_typeE13gcc_jit_types}@anchor{1bf}@anchor{cp/topics/types _CPPv2N6gccjit7context8get_typeE13gcc_jit_types}@anchor{1c0}@anchor{cp/topics/types gccjit context get_type__gcc_jit_types}@anchor{1c1}
12627@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{13d,,context}::get_type (enum gcc_jit_types)
29df5715
DM
12628
12629Access a specific type. This is a thin wrapper around
6f7585de 12630@ref{b,,gcc_jit_context_get_type()}; the parameter has the same meaning.
29df5715
DM
12631@end deffn
12632
12633@geindex gccjit;;context;;get_int_type (C++ function)
421d0d0f
DM
12634@anchor{cp/topics/types _CPPv4N6gccjit7context12get_int_typeE6size_ti}@anchor{1c2}@anchor{cp/topics/types _CPPv3N6gccjit7context12get_int_typeE6size_ti}@anchor{1c3}@anchor{cp/topics/types _CPPv2N6gccjit7context12get_int_typeE6size_ti}@anchor{1c4}@anchor{cp/topics/types gccjit context get_int_type__s i}@anchor{1c5}
12635@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{13d,,context}::get_int_type (size_t num_bytes, int is_signed)
29df5715
DM
12636
12637Access the integer type of the given size.
12638@end deffn
12639
12640@geindex gccjit;;context;;get_int_type<T> (C++ function)
421d0d0f
DM
12641@anchor{cp/topics/types _CPPv4IEN6gccjit7context12get_int_typeI1TEEN6gccjit4typeEv}@anchor{1c6}@anchor{cp/topics/types _CPPv3IEN6gccjit7context12get_int_typeI1TEEv}@anchor{1c7}@anchor{cp/topics/types _CPPv2IEN6gccjit7context12get_int_typeI1TEEv}@anchor{1c8}
12642@deffn {C++ Function} template<>gccjit::@ref{13f,,type} gccjit::@ref{13d,,context}::get_int_type<T> ()
29df5715
DM
12643
12644Access the given integer type. For example, you could map the
12645@code{unsigned short} type into a gccjit::type via:
12646
12647@example
12648gccjit::type t = ctxt.get_int_type <unsigned short> ();
12649@end example
29df5715
DM
12650@end deffn
12651
47ee1b7c 12652@node Pointers const and volatile<2>,Vector types<2>,Standard types<2>,Types<2>
421d0d0f 12653@anchor{cp/topics/types pointers-const-and-volatile}@anchor{1c9}
29df5715
DM
12654@subsubsection Pointers, @cite{const}, and @cite{volatile}
12655
12656
12657@geindex gccjit;;type;;get_pointer (C++ function)
421d0d0f
DM
12658@anchor{cp/topics/types _CPPv4N6gccjit4type11get_pointerEv}@anchor{1bc}@anchor{cp/topics/types _CPPv3N6gccjit4type11get_pointerEv}@anchor{1ca}@anchor{cp/topics/types _CPPv2N6gccjit4type11get_pointerEv}@anchor{1cb}@anchor{cp/topics/types gccjit type get_pointer}@anchor{1cc}
12659@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{13f,,type}::get_pointer ()
29df5715 12660
6f7585de 12661Given type “T”, get type “T*”.
29df5715
DM
12662@end deffn
12663
29df5715 12664@geindex gccjit;;type;;get_const (C++ function)
421d0d0f
DM
12665@anchor{cp/topics/types _CPPv4N6gccjit4type9get_constEv}@anchor{1bd}@anchor{cp/topics/types _CPPv3N6gccjit4type9get_constEv}@anchor{1cd}@anchor{cp/topics/types _CPPv2N6gccjit4type9get_constEv}@anchor{1ce}@anchor{cp/topics/types gccjit type get_const}@anchor{1cf}
12666@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{13f,,type}::get_const ()
29df5715 12667
6f7585de 12668Given type “T”, get type “const T”.
29df5715
DM
12669@end deffn
12670
12671@geindex gccjit;;type;;get_volatile (C++ function)
421d0d0f
DM
12672@anchor{cp/topics/types _CPPv4N6gccjit4type12get_volatileEv}@anchor{1d0}@anchor{cp/topics/types _CPPv3N6gccjit4type12get_volatileEv}@anchor{1d1}@anchor{cp/topics/types _CPPv2N6gccjit4type12get_volatileEv}@anchor{1d2}@anchor{cp/topics/types gccjit type get_volatile}@anchor{1d3}
12673@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{13f,,type}::get_volatile ()
29df5715 12674
6f7585de 12675Given type “T”, get type “volatile T”.
29df5715
DM
12676@end deffn
12677
0ebd1f00 12678@geindex gccjit;;type;;get_aligned (C++ function)
421d0d0f
DM
12679@anchor{cp/topics/types _CPPv4N6gccjit4type11get_alignedE6size_t}@anchor{1d4}@anchor{cp/topics/types _CPPv3N6gccjit4type11get_alignedE6size_t}@anchor{1d5}@anchor{cp/topics/types _CPPv2N6gccjit4type11get_alignedE6size_t}@anchor{1d6}@anchor{cp/topics/types gccjit type get_aligned__s}@anchor{1d7}
12680@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{13f,,type}::get_aligned (size_t alignment_in_bytes)
0ebd1f00 12681
6f7585de 12682Given type “T”, get type:
0ebd1f00
DM
12683
12684@example
12685T __attribute__ ((aligned (ALIGNMENT_IN_BYTES)))
12686@end example
12687
0ebd1f00
DM
12688The alignment must be a power of two.
12689@end deffn
12690
29df5715 12691@geindex gccjit;;context;;new_array_type (C++ function)
421d0d0f
DM
12692@anchor{cp/topics/types _CPPv4N6gccjit7context14new_array_typeEN6gccjit4typeEiN6gccjit8locationE}@anchor{1d8}@anchor{cp/topics/types _CPPv3N6gccjit7context14new_array_typeEN6gccjit4typeEiN6gccjit8locationE}@anchor{1d9}@anchor{cp/topics/types _CPPv2N6gccjit7context14new_array_typeEN6gccjit4typeEiN6gccjit8locationE}@anchor{1da}@anchor{cp/topics/types gccjit context new_array_type__gccjit type i gccjit location}@anchor{1db}
12693@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{13d,,context}::new_array_type (gccjit::type element_type, int num_elements, gccjit::location loc)
29df5715 12694
6f7585de
DM
12695Given type “T”, get type “T[N]” (for a constant N).
12696Param “loc” is optional.
29df5715
DM
12697@end deffn
12698
47ee1b7c 12699@node Vector types<2>,Structures and unions<2>,Pointers const and volatile<2>,Types<2>
421d0d0f 12700@anchor{cp/topics/types vector-types}@anchor{1dc}
47ee1b7c
DM
12701@subsubsection Vector types
12702
12703
12704@geindex gccjit;;type;;get_vector (C++ function)
421d0d0f
DM
12705@anchor{cp/topics/types _CPPv4N6gccjit4type10get_vectorE6size_t}@anchor{1dd}@anchor{cp/topics/types _CPPv3N6gccjit4type10get_vectorE6size_t}@anchor{1de}@anchor{cp/topics/types _CPPv2N6gccjit4type10get_vectorE6size_t}@anchor{1df}@anchor{cp/topics/types gccjit type get_vector__s}@anchor{1e0}
12706@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{13f,,type}::get_vector (size_t num_units)
47ee1b7c 12707
6f7585de 12708Given type “T”, get type:
47ee1b7c
DM
12709
12710@example
12711T __attribute__ ((vector_size (sizeof(T) * num_units))
12712@end example
12713
47ee1b7c
DM
12714T must be integral or floating point; num_units must be a power of two.
12715@end deffn
12716
12717@node Structures and unions<2>,,Vector types<2>,Types<2>
421d0d0f 12718@anchor{cp/topics/types structures-and-unions}@anchor{1e1}
29df5715
DM
12719@subsubsection Structures and unions
12720
12721
12722@geindex gccjit;;struct_ (C++ class)
421d0d0f 12723@anchor{cp/topics/types _CPPv4N6gccjit7struct_E}@anchor{1e2}@anchor{cp/topics/types _CPPv3N6gccjit7struct_E}@anchor{1e3}@anchor{cp/topics/types _CPPv2N6gccjit7struct_E}@anchor{1e4}@anchor{cp/topics/types gccjit struct_}@anchor{1e5}
29df5715
DM
12724@deffn {C++ Class} gccjit::struct_
12725@end deffn
12726
12727A compound type analagous to a C @cite{struct}.
12728
421d0d0f
DM
12729@ref{1e2,,gccjit;;struct_} is a subclass of @ref{13f,,gccjit;;type} (and thus
12730of @ref{142,,gccjit;;object} in turn).
29df5715
DM
12731
12732@geindex gccjit;;field (C++ class)
421d0d0f 12733@anchor{cp/topics/types _CPPv4N6gccjit5fieldE}@anchor{1e6}@anchor{cp/topics/types _CPPv3N6gccjit5fieldE}@anchor{1e7}@anchor{cp/topics/types _CPPv2N6gccjit5fieldE}@anchor{1e8}@anchor{cp/topics/types gccjit field}@anchor{1e9}
29df5715
DM
12734@deffn {C++ Class} gccjit::field
12735@end deffn
12736
421d0d0f 12737A field within a @ref{1e2,,gccjit;;struct_}.
29df5715 12738
421d0d0f 12739@ref{1e6,,gccjit;;field} is a subclass of @ref{142,,gccjit;;object}.
29df5715 12740
421d0d0f
DM
12741You can model C @cite{struct} types by creating @ref{1e2,,gccjit;;struct_} and
12742@ref{1e6,,gccjit;;field} instances, in either order:
29df5715
DM
12743
12744
12745@itemize *
12746
12747@item
12748by creating the fields, then the structure. For example, to model:
12749
12750@example
12751struct coord @{double x; double y; @};
12752@end example
12753
29df5715
DM
12754you could call:
12755
12756@example
12757gccjit::field field_x = ctxt.new_field (double_type, "x");
12758gccjit::field field_y = ctxt.new_field (double_type, "y");
12759std::vector fields;
12760fields.push_back (field_x);
12761fields.push_back (field_y);
12762gccjit::struct_ coord = ctxt.new_struct_type ("coord", fields);
12763@end example
12764
29df5715
DM
12765@item
12766by creating the structure, then populating it with fields, typically
12767to allow modelling self-referential structs such as:
12768
12769@example
12770struct node @{ int m_hash; struct node *m_next; @};
12771@end example
12772
29df5715
DM
12773like this:
12774
12775@example
12776gccjit::struct_ node = ctxt.new_opaque_struct_type ("node");
12777gccjit::type node_ptr = node.get_pointer ();
12778gccjit::field field_hash = ctxt.new_field (int_type, "m_hash");
12779gccjit::field field_next = ctxt.new_field (node_ptr, "m_next");
12780std::vector fields;
12781fields.push_back (field_hash);
12782fields.push_back (field_next);
12783node.set_fields (fields);
12784@end example
29df5715
DM
12785@end itemize
12786
12787@c FIXME: the above API doesn't seem to exist yet
12788
12789@geindex gccjit;;context;;new_field (C++ function)
421d0d0f
DM
12790@anchor{cp/topics/types _CPPv4N6gccjit7context9new_fieldEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{1ea}@anchor{cp/topics/types _CPPv3N6gccjit7context9new_fieldEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{1eb}@anchor{cp/topics/types _CPPv2N6gccjit7context9new_fieldEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{1ec}@anchor{cp/topics/types gccjit context new_field__gccjit type cCP gccjit location}@anchor{1ed}
12791@deffn {C++ Function} gccjit::@ref{1e6,,field} gccjit::@ref{13d,,context}::new_field (gccjit::type type, const char *name, gccjit::location loc)
29df5715
DM
12792
12793Construct a new field, with the given type and name.
12794@end deffn
12795
12796@geindex gccjit;;context;;new_struct_type (C++ function)
421d0d0f
DM
12797@anchor{cp/topics/types _CPPv4N6gccjit7context15new_struct_typeERKNSt6stringERNSt6vectorI5fieldEEN6gccjit8locationE}@anchor{1ee}@anchor{cp/topics/types _CPPv3N6gccjit7context15new_struct_typeERKNSt6stringERNSt6vectorI5fieldEEN6gccjit8locationE}@anchor{1ef}@anchor{cp/topics/types _CPPv2N6gccjit7context15new_struct_typeERKNSt6stringERNSt6vectorI5fieldEEN6gccjit8locationE}@anchor{1f0}@anchor{cp/topics/types gccjit context new_struct_type__ssCR std vector field R gccjit location}@anchor{1f1}
12798@deffn {C++ Function} gccjit::@ref{1e2,,struct_} gccjit::@ref{13d,,context}::new_struct_type (const std::string &name, std::vector<field> &fields, gccjit::location loc)
29df5715
DM
12799
12800@quotation
12801
12802Construct a new struct type, with the given name and fields.
12803@end quotation
12804@end deffn
12805
12806@geindex gccjit;;context;;new_opaque_struct (C++ function)
421d0d0f
DM
12807@anchor{cp/topics/types _CPPv4N6gccjit7context17new_opaque_structERKNSt6stringEN6gccjit8locationE}@anchor{1f2}@anchor{cp/topics/types _CPPv3N6gccjit7context17new_opaque_structERKNSt6stringEN6gccjit8locationE}@anchor{1f3}@anchor{cp/topics/types _CPPv2N6gccjit7context17new_opaque_structERKNSt6stringEN6gccjit8locationE}@anchor{1f4}@anchor{cp/topics/types gccjit context new_opaque_struct__ssCR gccjit location}@anchor{1f5}
12808@deffn {C++ Function} gccjit::@ref{1e2,,struct_} gccjit::@ref{13d,,context}::new_opaque_struct (const std::string &name, gccjit::location loc)
29df5715
DM
12809
12810Construct a new struct type, with the given name, but without
12811specifying the fields. The fields can be omitted (in which case the
12812size of the struct is not known), or later specified using
0981cf96 12813@ref{91,,gcc_jit_struct_set_fields()}.
29df5715
DM
12814@end deffn
12815
7adcbafe 12816@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
29df5715
DM
12817@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
12818@c
12819@c This is free software: you can redistribute it and/or modify it
12820@c under the terms of the GNU General Public License as published by
12821@c the Free Software Foundation, either version 3 of the License, or
12822@c (at your option) any later version.
12823@c
12824@c This program is distributed in the hope that it will be useful, but
12825@c WITHOUT ANY WARRANTY; without even the implied warranty of
12826@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12827@c General Public License for more details.
12828@c
12829@c You should have received a copy of the GNU General Public License
12830@c along with this program. If not, see
786973ce 12831@c <https://www.gnu.org/licenses/>.
29df5715
DM
12832
12833@node Expressions<2>,Creating and using functions<2>,Types<2>,Topic Reference<2>
421d0d0f 12834@anchor{cp/topics/expressions doc}@anchor{1f6}@anchor{cp/topics/expressions expressions}@anchor{1f7}
29df5715
DM
12835@subsection Expressions
12836
12837
12838@menu
12839* Rvalues: Rvalues<2>.
12840* Lvalues: Lvalues<2>.
12841* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>.
12842
29df5715
DM
12843@end menu
12844
29df5715 12845@node Rvalues<2>,Lvalues<2>,,Expressions<2>
421d0d0f 12846@anchor{cp/topics/expressions rvalues}@anchor{1f8}
29df5715
DM
12847@subsubsection Rvalues
12848
12849
12850@geindex gccjit;;rvalue (C++ class)
421d0d0f 12851@anchor{cp/topics/expressions _CPPv4N6gccjit6rvalueE}@anchor{146}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvalueE}@anchor{1f9}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalueE}@anchor{1fa}@anchor{cp/topics/expressions gccjit rvalue}@anchor{1fb}
29df5715
DM
12852@deffn {C++ Class} gccjit::rvalue
12853@end deffn
12854
421d0d0f
DM
12855A @ref{146,,gccjit;;rvalue} is an expression that can be computed. It is a
12856subclass of @ref{142,,gccjit;;object}, and is a thin wrapper around
6f7585de 12857@ref{13,,gcc_jit_rvalue *} from the C API.
29df5715
DM
12858
12859It can be simple, e.g.:
12860
12861@quotation
12862
12863
12864@itemize *
12865
12866@item
12867an integer value e.g. @cite{0} or @cite{42}
12868
12869@item
6f7585de 12870a string literal e.g. @cite{“Hello world”}
29df5715
DM
12871
12872@item
12873a variable e.g. @cite{i}. These are also lvalues (see below).
12874@end itemize
12875@end quotation
12876
12877or compound e.g.:
12878
12879@quotation
12880
12881
12882@itemize *
12883
12884@item
12885a unary expression e.g. @cite{!cond}
12886
12887@item
12888a binary expression e.g. @cite{(a + b)}
12889
12890@item
12891a function call e.g. @cite{get_distance (&player_ship@comma{} &target)}
12892
12893@item
12894etc.
12895@end itemize
12896@end quotation
12897
12898Every rvalue has an associated type, and the API will check to ensure
12899that types match up correctly (otherwise the context will emit an error).
12900
12901@geindex gccjit;;rvalue;;get_type (C++ function)
421d0d0f
DM
12902@anchor{cp/topics/expressions _CPPv4N6gccjit6rvalue8get_typeEv}@anchor{1fc}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvalue8get_typeEv}@anchor{1fd}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalue8get_typeEv}@anchor{1fe}@anchor{cp/topics/expressions gccjit rvalue get_type}@anchor{1ff}
12903@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{146,,rvalue}::get_type ()
29df5715
DM
12904
12905Get the type of this rvalue.
12906@end deffn
12907
12908@menu
12909* Simple expressions: Simple expressions<2>.
6069fe72 12910* Vector expressions: Vector expressions<2>.
29df5715
DM
12911* Unary Operations: Unary Operations<2>.
12912* Binary Operations: Binary Operations<2>.
12913* Comparisons: Comparisons<2>.
12914* Function calls: Function calls<2>.
ecd5156d 12915* Function pointers: Function pointers<3>.
29df5715
DM
12916* Type-coercion: Type-coercion<2>.
12917
12918@end menu
12919
6069fe72 12920@node Simple expressions<2>,Vector expressions<2>,,Rvalues<2>
421d0d0f 12921@anchor{cp/topics/expressions simple-expressions}@anchor{200}
29df5715
DM
12922@subsubsection Simple expressions
12923
12924
12925@geindex gccjit;;context;;new_rvalue (C++ function)
421d0d0f
DM
12926@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueEN6gccjit4typeEi}@anchor{15a}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueEN6gccjit4typeEi}@anchor{201}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeEi}@anchor{202}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type iC}@anchor{203}
12927@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_rvalue (gccjit::type numeric_type, int value) const
29df5715
DM
12928
12929Given a numeric type (integer or floating point), build an rvalue for
12930the given constant @code{int} value.
12931@end deffn
12932
ccce3b2a 12933@geindex gccjit;;context;;new_rvalue (C++ function)
421d0d0f
DM
12934@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueEN6gccjit4typeEl}@anchor{204}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueEN6gccjit4typeEl}@anchor{205}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeEl}@anchor{206}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type lC}@anchor{207}
12935@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_rvalue (gccjit::type numeric_type, long value) const
ccce3b2a
DM
12936
12937Given a numeric type (integer or floating point), build an rvalue for
12938the given constant @code{long} value.
12939@end deffn
12940
29df5715 12941@geindex gccjit;;context;;zero (C++ function)
421d0d0f
DM
12942@anchor{cp/topics/expressions _CPPv4NK6gccjit7context4zeroEN6gccjit4typeE}@anchor{156}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context4zeroEN6gccjit4typeE}@anchor{208}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context4zeroEN6gccjit4typeE}@anchor{209}@anchor{cp/topics/expressions gccjit context zero__gccjit typeC}@anchor{20a}
12943@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::zero (gccjit::type numeric_type) const
29df5715
DM
12944
12945Given a numeric type (integer or floating point), get the rvalue for
12946zero. Essentially this is just a shortcut for:
12947
12948@example
12949ctxt.new_rvalue (numeric_type, 0)
12950@end example
29df5715
DM
12951@end deffn
12952
12953@geindex gccjit;;context;;one (C++ function)
421d0d0f
DM
12954@anchor{cp/topics/expressions _CPPv4NK6gccjit7context3oneEN6gccjit4typeE}@anchor{20b}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context3oneEN6gccjit4typeE}@anchor{20c}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context3oneEN6gccjit4typeE}@anchor{20d}@anchor{cp/topics/expressions gccjit context one__gccjit typeC}@anchor{20e}
12955@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::one (gccjit::type numeric_type) const
29df5715
DM
12956
12957Given a numeric type (integer or floating point), get the rvalue for
51c5c6b5 12958one. Essentially this is just a shortcut for:
29df5715
DM
12959
12960@example
12961ctxt.new_rvalue (numeric_type, 1)
12962@end example
29df5715
DM
12963@end deffn
12964
12965@geindex gccjit;;context;;new_rvalue (C++ function)
421d0d0f
DM
12966@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueEN6gccjit4typeEd}@anchor{20f}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueEN6gccjit4typeEd}@anchor{210}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeEd}@anchor{211}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type doubleC}@anchor{212}
12967@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_rvalue (gccjit::type numeric_type, double value) const
29df5715
DM
12968
12969Given a numeric type (integer or floating point), build an rvalue for
ccce3b2a 12970the given constant @code{double} value.
29df5715
DM
12971@end deffn
12972
12973@geindex gccjit;;context;;new_rvalue (C++ function)
421d0d0f
DM
12974@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueEN6gccjit4typeEPv}@anchor{213}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueEN6gccjit4typeEPv}@anchor{214}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeEPv}@anchor{215}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type voidPC}@anchor{216}
12975@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_rvalue (gccjit::type pointer_type, void *value) const
29df5715
DM
12976
12977Given a pointer type, build an rvalue for the given address.
12978@end deffn
12979
12980@geindex gccjit;;context;;new_rvalue (C++ function)
421d0d0f
DM
12981@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueERKNSt6stringE}@anchor{217}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueERKNSt6stringE}@anchor{218}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueERKNSt6stringE}@anchor{219}@anchor{cp/topics/expressions gccjit context new_rvalue__ssCRC}@anchor{21a}
12982@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_rvalue (const std::string &value) const
29df5715
DM
12983
12984Generate an rvalue of type @code{GCC_JIT_TYPE_CONST_CHAR_PTR} for
12985the given string. This is akin to a string literal.
12986@end deffn
12987
6069fe72 12988@node Vector expressions<2>,Unary Operations<2>,Simple expressions<2>,Rvalues<2>
421d0d0f 12989@anchor{cp/topics/expressions vector-expressions}@anchor{21b}
6069fe72
DM
12990@subsubsection Vector expressions
12991
12992
12993@geindex gccjit;;context;;new_rvalue (C++ function)
421d0d0f
DM
12994@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueEN6gccjit4typeENSt6vectorIN6gccjit6rvalueEEE}@anchor{21c}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueEN6gccjit4typeENSt6vectorIN6gccjit6rvalueEEE}@anchor{21d}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeENSt6vectorIN6gccjit6rvalueEEE}@anchor{21e}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type std vector gccjit rvalue C}@anchor{21f}
12995@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_rvalue (gccjit::type vector_type, std::vector<gccjit::rvalue> elements) const
6069fe72
DM
12996
12997Given a vector type, and a vector of scalar rvalue elements, generate a
12998vector rvalue.
12999
13000The number of elements needs to match that of the vector type.
13001@end deffn
13002
13003@node Unary Operations<2>,Binary Operations<2>,Vector expressions<2>,Rvalues<2>
421d0d0f 13004@anchor{cp/topics/expressions unary-operations}@anchor{220}
29df5715
DM
13005@subsubsection Unary Operations
13006
13007
13008@geindex gccjit;;context;;new_unary_op (C++ function)
421d0d0f
DM
13009@anchor{cp/topics/expressions _CPPv4N6gccjit7context12new_unary_opE16gcc_jit_unary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{221}@anchor{cp/topics/expressions _CPPv3N6gccjit7context12new_unary_opE16gcc_jit_unary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{222}@anchor{cp/topics/expressions _CPPv2N6gccjit7context12new_unary_opE16gcc_jit_unary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{223}@anchor{cp/topics/expressions gccjit context new_unary_op__gcc_jit_unary_op gccjit type gccjit rvalue gccjit location}@anchor{224}
13010@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_unary_op (enum gcc_jit_unary_op, gccjit::type result_type, gccjit::rvalue rvalue, gccjit::location loc)
29df5715
DM
13011
13012Build a unary operation out of an input rvalue.
13013
13014Parameter @code{loc} is optional.
13015
6f7585de 13016This is a thin wrapper around the C API’s
0981cf96 13017@ref{a2,,gcc_jit_context_new_unary_op()} and the available unary
29df5715
DM
13018operations are documented there.
13019@end deffn
13020
13021There are shorter ways to spell the various specific kinds of unary
13022operation:
13023
13024@geindex gccjit;;context;;new_minus (C++ function)
421d0d0f
DM
13025@anchor{cp/topics/expressions _CPPv4N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{225}@anchor{cp/topics/expressions _CPPv3N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{226}@anchor{cp/topics/expressions _CPPv2N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{227}@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit location}@anchor{228}
13026@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)
29df5715
DM
13027
13028Negate an arithmetic value; for example:
13029
13030@example
13031gccjit::rvalue negpi = ctxt.new_minus (t_double, pi);
13032@end example
13033
29df5715
DM
13034builds the equivalent of this C expression:
13035
13036@example
13037-pi
13038@end example
29df5715
DM
13039@end deffn
13040
13041@geindex new_bitwise_negate (C++ function)
421d0d0f
DM
13042@anchor{cp/topics/expressions _CPPv418new_bitwise_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{229}@anchor{cp/topics/expressions _CPPv318new_bitwise_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{22a}@anchor{cp/topics/expressions _CPPv218new_bitwise_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{22b}@anchor{cp/topics/expressions new_bitwise_negate__gccjit type gccjit rvalue gccjit location}@anchor{22c}
13043@deffn {C++ Function} gccjit::@ref{146,,rvalue} new_bitwise_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)
29df5715 13044
6f7585de 13045Bitwise negation of an integer value (one’s complement); for example:
29df5715
DM
13046
13047@example
13048gccjit::rvalue mask = ctxt.new_bitwise_negate (t_int, a);
13049@end example
13050
29df5715
DM
13051builds the equivalent of this C expression:
13052
13053@example
13054~a
13055@end example
29df5715
DM
13056@end deffn
13057
13058@geindex new_logical_negate (C++ function)
421d0d0f
DM
13059@anchor{cp/topics/expressions _CPPv418new_logical_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{22d}@anchor{cp/topics/expressions _CPPv318new_logical_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{22e}@anchor{cp/topics/expressions _CPPv218new_logical_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{22f}@anchor{cp/topics/expressions new_logical_negate__gccjit type gccjit rvalue gccjit location}@anchor{230}
13060@deffn {C++ Function} gccjit::@ref{146,,rvalue} new_logical_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)
29df5715
DM
13061
13062Logical negation of an arithmetic or pointer value; for example:
13063
13064@example
13065gccjit::rvalue guard = ctxt.new_logical_negate (t_bool, cond);
13066@end example
13067
29df5715
DM
13068builds the equivalent of this C expression:
13069
13070@example
13071!cond
13072@end example
29df5715
DM
13073@end deffn
13074
13075The most concise way to spell them is with overloaded operators:
13076
13077@geindex operator- (C++ function)
421d0d0f
DM
13078@anchor{cp/topics/expressions _CPPv4miN6gccjit6rvalueE}@anchor{231}@anchor{cp/topics/expressions _CPPv3miN6gccjit6rvalueE}@anchor{232}@anchor{cp/topics/expressions _CPPv2miN6gccjit6rvalueE}@anchor{233}@anchor{cp/topics/expressions sub-operator__gccjit rvalue}@anchor{234}
13079@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator@w{-} (gccjit::rvalue a)
29df5715
DM
13080
13081@example
13082gccjit::rvalue negpi = -pi;
13083@end example
29df5715
DM
13084@end deffn
13085
13086@geindex operator~ (C++ function)
421d0d0f
DM
13087@anchor{cp/topics/expressions _CPPv4coN6gccjit6rvalueE}@anchor{235}@anchor{cp/topics/expressions _CPPv3coN6gccjit6rvalueE}@anchor{236}@anchor{cp/topics/expressions _CPPv2coN6gccjit6rvalueE}@anchor{237}@anchor{cp/topics/expressions inv-operator__gccjit rvalue}@anchor{238}
13088@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator~ (gccjit::rvalue a)
29df5715
DM
13089
13090@example
13091gccjit::rvalue mask = ~a;
13092@end example
29df5715
DM
13093@end deffn
13094
13095@geindex operator! (C++ function)
421d0d0f
DM
13096@anchor{cp/topics/expressions _CPPv4ntN6gccjit6rvalueE}@anchor{239}@anchor{cp/topics/expressions _CPPv3ntN6gccjit6rvalueE}@anchor{23a}@anchor{cp/topics/expressions _CPPv2ntN6gccjit6rvalueE}@anchor{23b}@anchor{cp/topics/expressions not-operator__gccjit rvalue}@anchor{23c}
13097@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator! (gccjit::rvalue a)
29df5715
DM
13098
13099@example
13100gccjit::rvalue guard = !cond;
13101@end example
29df5715
DM
13102@end deffn
13103
13104@node Binary Operations<2>,Comparisons<2>,Unary Operations<2>,Rvalues<2>
421d0d0f 13105@anchor{cp/topics/expressions binary-operations}@anchor{23d}
29df5715
DM
13106@subsubsection Binary Operations
13107
13108
13109@geindex gccjit;;context;;new_binary_op (C++ function)
421d0d0f
DM
13110@anchor{cp/topics/expressions _CPPv4N6gccjit7context13new_binary_opE17gcc_jit_binary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{145}@anchor{cp/topics/expressions _CPPv3N6gccjit7context13new_binary_opE17gcc_jit_binary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{23e}@anchor{cp/topics/expressions _CPPv2N6gccjit7context13new_binary_opE17gcc_jit_binary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{23f}@anchor{cp/topics/expressions gccjit context new_binary_op__gcc_jit_binary_op gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{240}
13111@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_binary_op (enum gcc_jit_binary_op, gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13112
13113Build a binary operation out of two constituent rvalues.
13114
13115Parameter @code{loc} is optional.
13116
6f7585de
DM
13117This is a thin wrapper around the C API’s
13118@ref{12,,gcc_jit_context_new_binary_op()} and the available binary
29df5715
DM
13119operations are documented there.
13120@end deffn
13121
13122There are shorter ways to spell the various specific kinds of binary
13123operation:
13124
13125@geindex gccjit;;context;;new_plus (C++ function)
421d0d0f
DM
13126@anchor{cp/topics/expressions _CPPv4N6gccjit7context8new_plusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{241}@anchor{cp/topics/expressions _CPPv3N6gccjit7context8new_plusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{242}@anchor{cp/topics/expressions _CPPv2N6gccjit7context8new_plusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{243}@anchor{cp/topics/expressions gccjit context new_plus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{244}
13127@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_plus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13128@end deffn
13129
13130@geindex gccjit;;context;;new_minus (C++ function)
421d0d0f
DM
13131@anchor{cp/topics/expressions _CPPv4N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{245}@anchor{cp/topics/expressions _CPPv3N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{246}@anchor{cp/topics/expressions _CPPv2N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{247}@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{248}
13132@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13133@end deffn
13134
13135@geindex gccjit;;context;;new_mult (C++ function)
421d0d0f
DM
13136@anchor{cp/topics/expressions _CPPv4N6gccjit7context8new_multEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{249}@anchor{cp/topics/expressions _CPPv3N6gccjit7context8new_multEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{24a}@anchor{cp/topics/expressions _CPPv2N6gccjit7context8new_multEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{24b}@anchor{cp/topics/expressions gccjit context new_mult__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{24c}
13137@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_mult (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13138@end deffn
13139
13140@geindex gccjit;;context;;new_divide (C++ function)
421d0d0f
DM
13141@anchor{cp/topics/expressions _CPPv4N6gccjit7context10new_divideEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{24d}@anchor{cp/topics/expressions _CPPv3N6gccjit7context10new_divideEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{24e}@anchor{cp/topics/expressions _CPPv2N6gccjit7context10new_divideEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{24f}@anchor{cp/topics/expressions gccjit context new_divide__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{250}
13142@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_divide (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13143@end deffn
13144
13145@geindex gccjit;;context;;new_modulo (C++ function)
421d0d0f
DM
13146@anchor{cp/topics/expressions _CPPv4N6gccjit7context10new_moduloEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{251}@anchor{cp/topics/expressions _CPPv3N6gccjit7context10new_moduloEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{252}@anchor{cp/topics/expressions _CPPv2N6gccjit7context10new_moduloEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{253}@anchor{cp/topics/expressions gccjit context new_modulo__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{254}
13147@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_modulo (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13148@end deffn
13149
13150@geindex gccjit;;context;;new_bitwise_and (C++ function)
421d0d0f
DM
13151@anchor{cp/topics/expressions _CPPv4N6gccjit7context15new_bitwise_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{255}@anchor{cp/topics/expressions _CPPv3N6gccjit7context15new_bitwise_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{256}@anchor{cp/topics/expressions _CPPv2N6gccjit7context15new_bitwise_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{257}@anchor{cp/topics/expressions gccjit context new_bitwise_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{258}
13152@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_bitwise_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13153@end deffn
13154
13155@geindex gccjit;;context;;new_bitwise_xor (C++ function)
421d0d0f
DM
13156@anchor{cp/topics/expressions _CPPv4N6gccjit7context15new_bitwise_xorEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{259}@anchor{cp/topics/expressions _CPPv3N6gccjit7context15new_bitwise_xorEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{25a}@anchor{cp/topics/expressions _CPPv2N6gccjit7context15new_bitwise_xorEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{25b}@anchor{cp/topics/expressions gccjit context new_bitwise_xor__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{25c}
13157@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_bitwise_xor (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13158@end deffn
13159
13160@geindex gccjit;;context;;new_bitwise_or (C++ function)
421d0d0f
DM
13161@anchor{cp/topics/expressions _CPPv4N6gccjit7context14new_bitwise_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{25d}@anchor{cp/topics/expressions _CPPv3N6gccjit7context14new_bitwise_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{25e}@anchor{cp/topics/expressions _CPPv2N6gccjit7context14new_bitwise_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{25f}@anchor{cp/topics/expressions gccjit context new_bitwise_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{260}
13162@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_bitwise_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13163@end deffn
13164
13165@geindex gccjit;;context;;new_logical_and (C++ function)
421d0d0f
DM
13166@anchor{cp/topics/expressions _CPPv4N6gccjit7context15new_logical_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{261}@anchor{cp/topics/expressions _CPPv3N6gccjit7context15new_logical_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{262}@anchor{cp/topics/expressions _CPPv2N6gccjit7context15new_logical_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{263}@anchor{cp/topics/expressions gccjit context new_logical_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{264}
13167@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_logical_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13168@end deffn
13169
13170@geindex gccjit;;context;;new_logical_or (C++ function)
421d0d0f
DM
13171@anchor{cp/topics/expressions _CPPv4N6gccjit7context14new_logical_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{265}@anchor{cp/topics/expressions _CPPv3N6gccjit7context14new_logical_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{266}@anchor{cp/topics/expressions _CPPv2N6gccjit7context14new_logical_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{267}@anchor{cp/topics/expressions gccjit context new_logical_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{268}
13172@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_logical_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13173@end deffn
13174
13175The most concise way to spell them is with overloaded operators:
13176
13177@geindex operator+ (C++ function)
421d0d0f
DM
13178@anchor{cp/topics/expressions _CPPv4plN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{269}@anchor{cp/topics/expressions _CPPv3plN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{26a}@anchor{cp/topics/expressions _CPPv2plN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{26b}@anchor{cp/topics/expressions add-operator__gccjit rvalue gccjit rvalue}@anchor{26c}
13179@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator+ (gccjit::rvalue a, gccjit::rvalue b)
29df5715
DM
13180
13181@example
13182gccjit::rvalue sum = a + b;
13183@end example
29df5715
DM
13184@end deffn
13185
13186@geindex operator- (C++ function)
421d0d0f
DM
13187@anchor{cp/topics/expressions _CPPv4miN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{26d}@anchor{cp/topics/expressions _CPPv3miN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{26e}@anchor{cp/topics/expressions _CPPv2miN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{26f}@anchor{cp/topics/expressions sub-operator__gccjit rvalue gccjit rvalue}@anchor{270}
13188@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator@w{-} (gccjit::rvalue a, gccjit::rvalue b)
29df5715
DM
13189
13190@example
13191gccjit::rvalue diff = a - b;
13192@end example
29df5715
DM
13193@end deffn
13194
13195@geindex operator* (C++ function)
421d0d0f
DM
13196@anchor{cp/topics/expressions _CPPv4mlN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{271}@anchor{cp/topics/expressions _CPPv3mlN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{272}@anchor{cp/topics/expressions _CPPv2mlN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{273}@anchor{cp/topics/expressions mul-operator__gccjit rvalue gccjit rvalue}@anchor{274}
13197@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator* (gccjit::rvalue a, gccjit::rvalue b)
29df5715
DM
13198
13199@example
13200gccjit::rvalue prod = a * b;
13201@end example
29df5715
DM
13202@end deffn
13203
13204@geindex operator/ (C++ function)
421d0d0f
DM
13205@anchor{cp/topics/expressions _CPPv4dvN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{275}@anchor{cp/topics/expressions _CPPv3dvN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{276}@anchor{cp/topics/expressions _CPPv2dvN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{277}@anchor{cp/topics/expressions div-operator__gccjit rvalue gccjit rvalue}@anchor{278}
13206@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator/ (gccjit::rvalue a, gccjit::rvalue b)
29df5715
DM
13207
13208@example
13209gccjit::rvalue result = a / b;
13210@end example
29df5715
DM
13211@end deffn
13212
13213@geindex operator% (C++ function)
421d0d0f
DM
13214@anchor{cp/topics/expressions _CPPv4rmN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{279}@anchor{cp/topics/expressions _CPPv3rmN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{27a}@anchor{cp/topics/expressions _CPPv2rmN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{27b}@anchor{cp/topics/expressions mod-operator__gccjit rvalue gccjit rvalue}@anchor{27c}
13215@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator% (gccjit::rvalue a, gccjit::rvalue b)
29df5715
DM
13216
13217@example
13218gccjit::rvalue mod = a % b;
13219@end example
29df5715
DM
13220@end deffn
13221
13222@geindex operator& (C++ function)
421d0d0f
DM
13223@anchor{cp/topics/expressions _CPPv4anN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{27d}@anchor{cp/topics/expressions _CPPv3anN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{27e}@anchor{cp/topics/expressions _CPPv2anN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{27f}@anchor{cp/topics/expressions and-operator__gccjit rvalue gccjit rvalue}@anchor{280}
13224@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator& (gccjit::rvalue a, gccjit::rvalue b)
29df5715
DM
13225
13226@example
13227gccjit::rvalue x = a & b;
13228@end example
29df5715
DM
13229@end deffn
13230
13231@geindex operator^ (C++ function)
421d0d0f
DM
13232@anchor{cp/topics/expressions _CPPv4eoN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{281}@anchor{cp/topics/expressions _CPPv3eoN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{282}@anchor{cp/topics/expressions _CPPv2eoN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{283}@anchor{cp/topics/expressions xor-operator__gccjit rvalue gccjit rvalue}@anchor{284}
13233@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator^ (gccjit::rvalue a, gccjit::rvalue b)
29df5715
DM
13234
13235@example
13236gccjit::rvalue x = a ^ b;
13237@end example
29df5715
DM
13238@end deffn
13239
13240@geindex operator| (C++ function)
421d0d0f
DM
13241@anchor{cp/topics/expressions _CPPv4orN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{285}@anchor{cp/topics/expressions _CPPv3orN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{286}@anchor{cp/topics/expressions _CPPv2orN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{287}@anchor{cp/topics/expressions or-operator__gccjit rvalue gccjit rvalue}@anchor{288}
13242@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator| (gccjit::rvalue a, gccjit::rvalue b)
29df5715
DM
13243
13244@example
13245gccjit::rvalue x = a | b;
13246@end example
29df5715
DM
13247@end deffn
13248
13249@geindex operator&& (C++ function)
421d0d0f
DM
13250@anchor{cp/topics/expressions _CPPv4aaN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{289}@anchor{cp/topics/expressions _CPPv3aaN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{28a}@anchor{cp/topics/expressions _CPPv2aaN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{28b}@anchor{cp/topics/expressions sand-operator__gccjit rvalue gccjit rvalue}@anchor{28c}
13251@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator&& (gccjit::rvalue a, gccjit::rvalue b)
29df5715
DM
13252
13253@example
13254gccjit::rvalue cond = a && b;
13255@end example
29df5715
DM
13256@end deffn
13257
13258@geindex operator|| (C++ function)
421d0d0f
DM
13259@anchor{cp/topics/expressions _CPPv4ooN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{28d}@anchor{cp/topics/expressions _CPPv3ooN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{28e}@anchor{cp/topics/expressions _CPPv2ooN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{28f}@anchor{cp/topics/expressions sor-operator__gccjit rvalue gccjit rvalue}@anchor{290}
13260@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator|| (gccjit::rvalue a, gccjit::rvalue b)
29df5715
DM
13261
13262@example
13263gccjit::rvalue cond = a || b;
13264@end example
29df5715
DM
13265@end deffn
13266
13267These can of course be combined, giving a terse way to build compound
13268expressions:
13269
13270@quotation
13271
13272@example
13273gccjit::rvalue discriminant = (b * b) - (four * a * c);
13274@end example
29df5715
DM
13275@end quotation
13276
13277@node Comparisons<2>,Function calls<2>,Binary Operations<2>,Rvalues<2>
421d0d0f 13278@anchor{cp/topics/expressions comparisons}@anchor{291}
29df5715
DM
13279@subsubsection Comparisons
13280
13281
13282@geindex gccjit;;context;;new_comparison (C++ function)
421d0d0f
DM
13283@anchor{cp/topics/expressions _CPPv4N6gccjit7context14new_comparisonE18gcc_jit_comparisonN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{157}@anchor{cp/topics/expressions _CPPv3N6gccjit7context14new_comparisonE18gcc_jit_comparisonN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{292}@anchor{cp/topics/expressions _CPPv2N6gccjit7context14new_comparisonE18gcc_jit_comparisonN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{293}@anchor{cp/topics/expressions gccjit context new_comparison__gcc_jit_comparison gccjit rvalue gccjit rvalue gccjit location}@anchor{294}
13284@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_comparison (enum gcc_jit_comparison, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13285
13286Build a boolean rvalue out of the comparison of two other rvalues.
13287
13288Parameter @code{loc} is optional.
13289
6f7585de
DM
13290This is a thin wrapper around the C API’s
13291@ref{2c,,gcc_jit_context_new_comparison()} and the available kinds
29df5715
DM
13292of comparison are documented there.
13293@end deffn
13294
13295There are shorter ways to spell the various specific kinds of binary
13296operation:
13297
13298@geindex gccjit;;context;;new_eq (C++ function)
421d0d0f
DM
13299@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_eqEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{295}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_eqEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{296}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_eqEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{297}@anchor{cp/topics/expressions gccjit context new_eq__gccjit rvalue gccjit rvalue gccjit location}@anchor{298}
13300@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_eq (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13301@end deffn
13302
13303@geindex gccjit;;context;;new_ne (C++ function)
421d0d0f
DM
13304@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_neEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{299}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_neEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{29a}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_neEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{29b}@anchor{cp/topics/expressions gccjit context new_ne__gccjit rvalue gccjit rvalue gccjit location}@anchor{29c}
13305@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_ne (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13306@end deffn
13307
13308@geindex gccjit;;context;;new_lt (C++ function)
421d0d0f
DM
13309@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_ltEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{29d}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_ltEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{29e}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_ltEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{29f}@anchor{cp/topics/expressions gccjit context new_lt__gccjit rvalue gccjit rvalue gccjit location}@anchor{2a0}
13310@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_lt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13311@end deffn
13312
13313@geindex gccjit;;context;;new_le (C++ function)
421d0d0f
DM
13314@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_leEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2a1}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_leEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2a2}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_leEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2a3}@anchor{cp/topics/expressions gccjit context new_le__gccjit rvalue gccjit rvalue gccjit location}@anchor{2a4}
13315@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_le (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13316@end deffn
13317
13318@geindex gccjit;;context;;new_gt (C++ function)
421d0d0f
DM
13319@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_gtEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2a5}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_gtEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2a6}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_gtEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2a7}@anchor{cp/topics/expressions gccjit context new_gt__gccjit rvalue gccjit rvalue gccjit location}@anchor{2a8}
13320@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_gt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13321@end deffn
13322
13323@geindex gccjit;;context;;new_ge (C++ function)
421d0d0f
DM
13324@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_geEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2a9}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_geEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2aa}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_geEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2ab}@anchor{cp/topics/expressions gccjit context new_ge__gccjit rvalue gccjit rvalue gccjit location}@anchor{2ac}
13325@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_ge (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
29df5715
DM
13326@end deffn
13327
13328The most concise way to spell them is with overloaded operators:
13329
13330@geindex operator== (C++ function)
421d0d0f
DM
13331@anchor{cp/topics/expressions _CPPv4eqN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2ad}@anchor{cp/topics/expressions _CPPv3eqN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2ae}@anchor{cp/topics/expressions _CPPv2eqN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2af}@anchor{cp/topics/expressions eq-operator__gccjit rvalue gccjit rvalue}@anchor{2b0}
13332@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator== (gccjit::rvalue a, gccjit::rvalue b)
29df5715
DM
13333
13334@example
13335gccjit::rvalue cond = (a == ctxt.zero (t_int));
13336@end example
29df5715
DM
13337@end deffn
13338
13339@geindex operator!= (C++ function)
421d0d0f
DM
13340@anchor{cp/topics/expressions _CPPv4neN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b1}@anchor{cp/topics/expressions _CPPv3neN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b2}@anchor{cp/topics/expressions _CPPv2neN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b3}@anchor{cp/topics/expressions neq-operator__gccjit rvalue gccjit rvalue}@anchor{2b4}
13341@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator!= (gccjit::rvalue a, gccjit::rvalue b)
29df5715
DM
13342
13343@example
13344gccjit::rvalue cond = (i != j);
13345@end example
29df5715
DM
13346@end deffn
13347
13348@geindex operator< (C++ function)
421d0d0f
DM
13349@anchor{cp/topics/expressions _CPPv4ltN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b5}@anchor{cp/topics/expressions _CPPv3ltN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b6}@anchor{cp/topics/expressions _CPPv2ltN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b7}@anchor{cp/topics/expressions lt-operator__gccjit rvalue gccjit rvalue}@anchor{2b8}
13350@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator< (gccjit::rvalue a, gccjit::rvalue b)
29df5715
DM
13351
13352@example
13353gccjit::rvalue cond = i < n;
13354@end example
29df5715
DM
13355@end deffn
13356
13357@geindex operator<= (C++ function)
421d0d0f
DM
13358@anchor{cp/topics/expressions _CPPv4leN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b9}@anchor{cp/topics/expressions _CPPv3leN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2ba}@anchor{cp/topics/expressions _CPPv2leN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2bb}@anchor{cp/topics/expressions lte-operator__gccjit rvalue gccjit rvalue}@anchor{2bc}
13359@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator<= (gccjit::rvalue a, gccjit::rvalue b)
29df5715
DM
13360
13361@example
13362gccjit::rvalue cond = i <= n;
13363@end example
29df5715
DM
13364@end deffn
13365
13366@geindex operator> (C++ function)
421d0d0f
DM
13367@anchor{cp/topics/expressions _CPPv4gtN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2bd}@anchor{cp/topics/expressions _CPPv3gtN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2be}@anchor{cp/topics/expressions _CPPv2gtN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2bf}@anchor{cp/topics/expressions gt-operator__gccjit rvalue gccjit rvalue}@anchor{2c0}
13368@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator> (gccjit::rvalue a, gccjit::rvalue b)
29df5715
DM
13369
13370@example
13371gccjit::rvalue cond = (ch > limit);
13372@end example
29df5715
DM
13373@end deffn
13374
13375@geindex operator>= (C++ function)
421d0d0f
DM
13376@anchor{cp/topics/expressions _CPPv4geN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2c1}@anchor{cp/topics/expressions _CPPv3geN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2c2}@anchor{cp/topics/expressions _CPPv2geN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2c3}@anchor{cp/topics/expressions gte-operator__gccjit rvalue gccjit rvalue}@anchor{2c4}
13377@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator>= (gccjit::rvalue a, gccjit::rvalue b)
29df5715
DM
13378
13379@example
13380gccjit::rvalue cond = (score >= ctxt.new_rvalue (t_int, 100));
13381@end example
29df5715
DM
13382@end deffn
13383
13384@c TODO: beyond this point
13385
ecd5156d 13386@node Function calls<2>,Function pointers<3>,Comparisons<2>,Rvalues<2>
421d0d0f 13387@anchor{cp/topics/expressions function-calls}@anchor{2c5}
29df5715
DM
13388@subsubsection Function calls
13389
13390
13391@geindex gcc_jit_context_new_call (C++ function)
421d0d0f 13392@anchor{cp/topics/expressions _CPPv424gcc_jit_context_new_callP15gcc_jit_contextP16gcc_jit_locationP16gcc_jit_functioniPP14gcc_jit_rvalue}@anchor{2c6}@anchor{cp/topics/expressions _CPPv324gcc_jit_context_new_callP15gcc_jit_contextP16gcc_jit_locationP16gcc_jit_functioniPP14gcc_jit_rvalue}@anchor{2c7}@anchor{cp/topics/expressions _CPPv224gcc_jit_context_new_callP15gcc_jit_contextP16gcc_jit_locationP16gcc_jit_functioniPP14gcc_jit_rvalue}@anchor{2c8}@anchor{cp/topics/expressions gcc_jit_context_new_call__gcc_jit_contextP gcc_jit_locationP gcc_jit_functionP i gcc_jit_rvaluePP}@anchor{2c9}
6f7585de 13393@deffn {C++ Function} gcc_jit_rvalue *gcc_jit_context_new_call (gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_function *func, int numargs, gcc_jit_rvalue **args)
29df5715
DM
13394
13395Given a function and the given table of argument rvalues, construct a
13396call to the function, with the result as an rvalue.
13397
13398@cartouche
13399@quotation Note
13400@code{gccjit::context::new_call()} merely builds a
421d0d0f 13401@ref{146,,gccjit;;rvalue} i.e. an expression that can be evaluated,
29df5715 13402perhaps as part of a more complicated expression.
6f7585de 13403The call @emph{won’t} happen unless you add a statement to a function
29df5715
DM
13404that evaluates the expression.
13405
13406For example, if you want to call a function and discard the result
13407(or to call a function with @code{void} return type), use
421d0d0f 13408@ref{2ca,,gccjit;;block;;add_eval()}:
29df5715
DM
13409
13410@example
13411/* Add "(void)printf (arg0, arg1);". */
13412block.add_eval (ctxt.new_call (printf_func, arg0, arg1));
13413@end example
29df5715
DM
13414@end quotation
13415@end cartouche
13416@end deffn
13417
ecd5156d 13418@node Function pointers<3>,Type-coercion<2>,Function calls<2>,Rvalues<2>
421d0d0f 13419@anchor{cp/topics/expressions function-pointers}@anchor{2cb}
15a65e63
DM
13420@subsubsection Function pointers
13421
13422
13423@geindex gccjit;;function;;get_address (C++ function)
421d0d0f
DM
13424@anchor{cp/topics/expressions _CPPv4N6gccjit8function11get_addressEN6gccjit8locationE}@anchor{2cc}@anchor{cp/topics/expressions _CPPv3N6gccjit8function11get_addressEN6gccjit8locationE}@anchor{2cd}@anchor{cp/topics/expressions _CPPv2N6gccjit8function11get_addressEN6gccjit8locationE}@anchor{2ce}@anchor{cp/topics/expressions gccjit function get_address__gccjit location}@anchor{2cf}
13425@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{154,,function}::get_address (gccjit::location loc)
15a65e63
DM
13426
13427Get the address of a function as an rvalue, of function pointer
13428type.
13429@end deffn
13430
ecd5156d 13431@node Type-coercion<2>,,Function pointers<3>,Rvalues<2>
421d0d0f 13432@anchor{cp/topics/expressions type-coercion}@anchor{2d0}
29df5715
DM
13433@subsubsection Type-coercion
13434
13435
13436@geindex gccjit;;context;;new_cast (C++ function)
421d0d0f
DM
13437@anchor{cp/topics/expressions _CPPv4N6gccjit7context8new_castEN6gccjit6rvalueEN6gccjit4typeEN6gccjit8locationE}@anchor{2d1}@anchor{cp/topics/expressions _CPPv3N6gccjit7context8new_castEN6gccjit6rvalueEN6gccjit4typeEN6gccjit8locationE}@anchor{2d2}@anchor{cp/topics/expressions _CPPv2N6gccjit7context8new_castEN6gccjit6rvalueEN6gccjit4typeEN6gccjit8locationE}@anchor{2d3}@anchor{cp/topics/expressions gccjit context new_cast__gccjit rvalue gccjit type gccjit location}@anchor{2d4}
13438@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_cast (gccjit::rvalue rvalue, gccjit::type type, gccjit::location loc)
29df5715
DM
13439
13440Given an rvalue of T, construct another rvalue of another type.
13441
13442Currently only a limited set of conversions are possible:
13443
13444@quotation
13445
13446
13447@itemize *
13448
13449@item
13450int <-> float
13451
13452@item
13453int <-> bool
13454
13455@item
13456P* <-> Q*, for pointer types P and Q
13457@end itemize
13458@end quotation
13459@end deffn
13460
13461@node Lvalues<2>,Working with pointers structs and unions<2>,Rvalues<2>,Expressions<2>
421d0d0f 13462@anchor{cp/topics/expressions lvalues}@anchor{2d5}
29df5715
DM
13463@subsubsection Lvalues
13464
13465
13466@geindex gccjit;;lvalue (C++ class)
421d0d0f 13467@anchor{cp/topics/expressions _CPPv4N6gccjit6lvalueE}@anchor{14f}@anchor{cp/topics/expressions _CPPv3N6gccjit6lvalueE}@anchor{2d6}@anchor{cp/topics/expressions _CPPv2N6gccjit6lvalueE}@anchor{2d7}@anchor{cp/topics/expressions gccjit lvalue}@anchor{2d8}
29df5715
DM
13468@deffn {C++ Class} gccjit::lvalue
13469@end deffn
13470
13471An lvalue is something that can of the @emph{left}-hand side of an assignment:
13472a storage area (such as a variable). It is a subclass of
421d0d0f 13473@ref{146,,gccjit;;rvalue}, where the rvalue is computed by reading from the
29df5715
DM
13474storage area.
13475
6f7585de 13476It iss a thin wrapper around @ref{24,,gcc_jit_lvalue *} from the C API.
29df5715
DM
13477
13478@geindex gccjit;;lvalue;;get_address (C++ function)
421d0d0f
DM
13479@anchor{cp/topics/expressions _CPPv4N6gccjit6lvalue11get_addressEN6gccjit8locationE}@anchor{2d9}@anchor{cp/topics/expressions _CPPv3N6gccjit6lvalue11get_addressEN6gccjit8locationE}@anchor{2da}@anchor{cp/topics/expressions _CPPv2N6gccjit6lvalue11get_addressEN6gccjit8locationE}@anchor{2db}@anchor{cp/topics/expressions gccjit lvalue get_address__gccjit location}@anchor{2dc}
13480@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{14f,,lvalue}::get_address (gccjit::location loc)
29df5715
DM
13481
13482Take the address of an lvalue; analogous to:
13483
13484@example
13485&(EXPR)
13486@end example
13487
29df5715
DM
13488in C.
13489
6f7585de 13490Parameter “loc” is optional.
29df5715
DM
13491@end deffn
13492
13493@menu
13494* Global variables: Global variables<2>.
13495
13496@end menu
13497
13498@node Global variables<2>,,,Lvalues<2>
421d0d0f 13499@anchor{cp/topics/expressions global-variables}@anchor{2dd}
29df5715
DM
13500@subsubsection Global variables
13501
13502
13503@geindex gccjit;;context;;new_global (C++ function)
421d0d0f
DM
13504@anchor{cp/topics/expressions _CPPv4N6gccjit7context10new_globalE19gcc_jit_global_kindN6gccjit4typeEPKcN6gccjit8locationE}@anchor{2de}@anchor{cp/topics/expressions _CPPv3N6gccjit7context10new_globalE19gcc_jit_global_kindN6gccjit4typeEPKcN6gccjit8locationE}@anchor{2df}@anchor{cp/topics/expressions _CPPv2N6gccjit7context10new_globalE19gcc_jit_global_kindN6gccjit4typeEPKcN6gccjit8locationE}@anchor{2e0}@anchor{cp/topics/expressions gccjit context new_global__gcc_jit_global_kind gccjit type cCP gccjit location}@anchor{2e1}
13505@deffn {C++ Function} gccjit::@ref{14f,,lvalue} gccjit::@ref{13d,,context}::new_global (enum gcc_jit_global_kind, gccjit::type type, const char *name, gccjit::location loc)
29df5715
DM
13506
13507Add a new global variable of the given type and name to the context.
791cfef8 13508
0981cf96 13509This is a thin wrapper around @ref{c8,,gcc_jit_context_new_global()} from
6f7585de 13510the C API; the “kind” parameter has the same meaning as there.
29df5715
DM
13511@end deffn
13512
13513@node Working with pointers structs and unions<2>,,Lvalues<2>,Expressions<2>
421d0d0f 13514@anchor{cp/topics/expressions working-with-pointers-structs-and-unions}@anchor{2e2}
29df5715
DM
13515@subsubsection Working with pointers, structs and unions
13516
13517
13518@geindex gccjit;;rvalue;;dereference (C++ function)
421d0d0f
DM
13519@anchor{cp/topics/expressions _CPPv4N6gccjit6rvalue11dereferenceEN6gccjit8locationE}@anchor{2e3}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvalue11dereferenceEN6gccjit8locationE}@anchor{2e4}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalue11dereferenceEN6gccjit8locationE}@anchor{2e5}@anchor{cp/topics/expressions gccjit rvalue dereference__gccjit location}@anchor{2e6}
13520@deffn {C++ Function} gccjit::@ref{14f,,lvalue} gccjit::@ref{146,,rvalue}::dereference (gccjit::location loc)
29df5715
DM
13521
13522Given an rvalue of pointer type @code{T *}, dereferencing the pointer,
13523getting an lvalue of type @code{T}. Analogous to:
13524
13525@example
13526*(EXPR)
13527@end example
13528
29df5715
DM
13529in C.
13530
6f7585de 13531Parameter “loc” is optional.
29df5715
DM
13532@end deffn
13533
6f7585de 13534If you don’t need to specify the location, this can also be expressed using
29df5715
DM
13535an overloaded operator:
13536
adb6d84b 13537@geindex gccjit;;rvalue;;operator* (C++ function)
421d0d0f
DM
13538@anchor{cp/topics/expressions _CPPv4N6gccjit6rvaluemlEv}@anchor{2e7}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvaluemlEv}@anchor{2e8}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvaluemlEv}@anchor{2e9}@anchor{cp/topics/expressions gccjit rvalue mul-operator}@anchor{2ea}
13539@deffn {C++ Function} gccjit::@ref{14f,,lvalue} gccjit::@ref{146,,rvalue}::operator* ()
29df5715
DM
13540
13541@example
13542gccjit::lvalue content = *ptr;
13543@end example
29df5715
DM
13544@end deffn
13545
13546Field access is provided separately for both lvalues and rvalues:
13547
13548@geindex gccjit;;lvalue;;access_field (C++ function)
421d0d0f
DM
13549@anchor{cp/topics/expressions _CPPv4N6gccjit6lvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2eb}@anchor{cp/topics/expressions _CPPv3N6gccjit6lvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2ec}@anchor{cp/topics/expressions _CPPv2N6gccjit6lvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2ed}@anchor{cp/topics/expressions gccjit lvalue access_field__gccjit field gccjit location}@anchor{2ee}
13550@deffn {C++ Function} gccjit::@ref{14f,,lvalue} gccjit::@ref{14f,,lvalue}::access_field (gccjit::field field, gccjit::location loc)
29df5715
DM
13551
13552Given an lvalue of struct or union type, access the given field,
6f7585de 13553getting an lvalue of the field’s type. Analogous to:
29df5715
DM
13554
13555@example
13556(EXPR).field = ...;
13557@end example
13558
29df5715
DM
13559in C.
13560@end deffn
13561
13562@geindex gccjit;;rvalue;;access_field (C++ function)
421d0d0f
DM
13563@anchor{cp/topics/expressions _CPPv4N6gccjit6rvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2ef}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2f0}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2f1}@anchor{cp/topics/expressions gccjit rvalue access_field__gccjit field gccjit location}@anchor{2f2}
13564@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{146,,rvalue}::access_field (gccjit::field field, gccjit::location loc)
29df5715
DM
13565
13566Given an rvalue of struct or union type, access the given field
13567as an rvalue. Analogous to:
13568
13569@example
13570(EXPR).field
13571@end example
13572
29df5715
DM
13573in C.
13574@end deffn
13575
13576@geindex gccjit;;rvalue;;dereference_field (C++ function)
421d0d0f
DM
13577@anchor{cp/topics/expressions _CPPv4N6gccjit6rvalue17dereference_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2f3}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvalue17dereference_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2f4}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalue17dereference_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2f5}@anchor{cp/topics/expressions gccjit rvalue dereference_field__gccjit field gccjit location}@anchor{2f6}
13578@deffn {C++ Function} gccjit::@ref{14f,,lvalue} gccjit::@ref{146,,rvalue}::dereference_field (gccjit::field field, gccjit::location loc)
29df5715
DM
13579
13580Given an rvalue of pointer type @code{T *} where T is of struct or union
13581type, access the given field as an lvalue. Analogous to:
13582
13583@example
13584(EXPR)->field
13585@end example
13586
29df5715
DM
13587in C, itself equivalent to @code{(*EXPR).FIELD}.
13588@end deffn
13589
13590@geindex gccjit;;context;;new_array_access (C++ function)
421d0d0f
DM
13591@anchor{cp/topics/expressions _CPPv4N6gccjit7context16new_array_accessEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2f7}@anchor{cp/topics/expressions _CPPv3N6gccjit7context16new_array_accessEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2f8}@anchor{cp/topics/expressions _CPPv2N6gccjit7context16new_array_accessEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2f9}@anchor{cp/topics/expressions gccjit context new_array_access__gccjit rvalue gccjit rvalue gccjit location}@anchor{2fa}
13592@deffn {C++ Function} gccjit::@ref{14f,,lvalue} gccjit::@ref{13d,,context}::new_array_access (gccjit::rvalue ptr, gccjit::rvalue index, gccjit::location loc)
29df5715
DM
13593
13594Given an rvalue of pointer type @code{T *}, get at the element @cite{T} at
13595the given index, using standard C array indexing rules i.e. each
13596increment of @code{index} corresponds to @code{sizeof(T)} bytes.
13597Analogous to:
13598
13599@example
13600PTR[INDEX]
13601@end example
13602
29df5715
DM
13603in C (or, indeed, to @code{PTR + INDEX}).
13604
6f7585de 13605Parameter “loc” is optional.
29df5715
DM
13606@end deffn
13607
421d0d0f 13608For array accesses where you don’t need to specify a @ref{163,,gccjit;;location},
29df5715
DM
13609two overloaded operators are available:
13610
13611@quotation
13612
13613gccjit::lvalue gccjit::rvalue::operator[] (gccjit::rvalue index)
13614
13615@example
13616gccjit::lvalue element = array[idx];
13617@end example
13618
29df5715
DM
13619gccjit::lvalue gccjit::rvalue::operator[] (int index)
13620
13621@example
13622gccjit::lvalue element = array[0];
13623@end example
29df5715
DM
13624@end quotation
13625
7adcbafe 13626@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
29df5715
DM
13627@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
13628@c
13629@c This is free software: you can redistribute it and/or modify it
13630@c under the terms of the GNU General Public License as published by
13631@c the Free Software Foundation, either version 3 of the License, or
13632@c (at your option) any later version.
13633@c
13634@c This program is distributed in the hope that it will be useful, but
13635@c WITHOUT ANY WARRANTY; without even the implied warranty of
13636@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13637@c General Public License for more details.
13638@c
13639@c You should have received a copy of the GNU General Public License
13640@c along with this program. If not, see
786973ce 13641@c <https://www.gnu.org/licenses/>.
29df5715
DM
13642
13643@node Creating and using functions<2>,Source Locations<2>,Expressions<2>,Topic Reference<2>
421d0d0f 13644@anchor{cp/topics/functions doc}@anchor{2fb}@anchor{cp/topics/functions creating-and-using-functions}@anchor{2fc}
29df5715
DM
13645@subsection Creating and using functions
13646
13647
13648@menu
13649* Params: Params<2>.
13650* Functions: Functions<2>.
13651* Blocks: Blocks<2>.
13652* Statements: Statements<2>.
13653
13654@end menu
13655
13656@node Params<2>,Functions<2>,,Creating and using functions<2>
421d0d0f 13657@anchor{cp/topics/functions params}@anchor{2fd}
29df5715
DM
13658@subsubsection Params
13659
13660
13661@geindex gccjit;;param (C++ class)
421d0d0f 13662@anchor{cp/topics/functions _CPPv4N6gccjit5paramE}@anchor{150}@anchor{cp/topics/functions _CPPv3N6gccjit5paramE}@anchor{2fe}@anchor{cp/topics/functions _CPPv2N6gccjit5paramE}@anchor{2ff}@anchor{cp/topics/functions gccjit param}@anchor{300}
29df5715
DM
13663@deffn {C++ Class} gccjit::param
13664
13665A @cite{gccjit::param} represents a parameter to a function.
13666@end deffn
13667
13668@geindex gccjit;;context;;new_param (C++ function)
421d0d0f
DM
13669@anchor{cp/topics/functions _CPPv4N6gccjit7context9new_paramEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{144}@anchor{cp/topics/functions _CPPv3N6gccjit7context9new_paramEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{301}@anchor{cp/topics/functions _CPPv2N6gccjit7context9new_paramEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{302}@anchor{cp/topics/functions gccjit context new_param__gccjit type cCP gccjit location}@anchor{303}
13670@deffn {C++ Function} gccjit::@ref{150,,param} gccjit::@ref{13d,,context}::new_param (gccjit::type type, const char *name, gccjit::location loc)
29df5715
DM
13671
13672In preparation for creating a function, create a new parameter of the
13673given type and name.
13674@end deffn
13675
421d0d0f
DM
13676@ref{150,,gccjit;;param} is a subclass of @ref{14f,,gccjit;;lvalue} (and thus
13677of @ref{146,,gccjit;;rvalue} and @ref{142,,gccjit;;object}). It is a thin
6f7585de 13678wrapper around the C API’s @ref{25,,gcc_jit_param *}.
29df5715
DM
13679
13680@node Functions<2>,Blocks<2>,Params<2>,Creating and using functions<2>
421d0d0f 13681@anchor{cp/topics/functions functions}@anchor{304}
29df5715
DM
13682@subsubsection Functions
13683
13684
13685@geindex gccjit;;function (C++ class)
421d0d0f 13686@anchor{cp/topics/functions _CPPv4N6gccjit8functionE}@anchor{154}@anchor{cp/topics/functions _CPPv3N6gccjit8functionE}@anchor{305}@anchor{cp/topics/functions _CPPv2N6gccjit8functionE}@anchor{306}@anchor{cp/topics/functions gccjit function}@anchor{307}
29df5715
DM
13687@deffn {C++ Class} gccjit::function
13688
6f7585de
DM
13689A @cite{gccjit::function} represents a function - either one that we’re
13690creating ourselves, or one that we’re referencing.
29df5715
DM
13691@end deffn
13692
adb6d84b 13693@geindex gccjit;;context;;new_function (C++ function)
421d0d0f
DM
13694@anchor{cp/topics/functions _CPPv4N6gccjit7context12new_functionE21gcc_jit_function_kindN6gccjit4typeEPKcRNSt6vectorI5paramEEiN6gccjit8locationE}@anchor{308}@anchor{cp/topics/functions _CPPv3N6gccjit7context12new_functionE21gcc_jit_function_kindN6gccjit4typeEPKcRNSt6vectorI5paramEEiN6gccjit8locationE}@anchor{309}@anchor{cp/topics/functions _CPPv2N6gccjit7context12new_functionE21gcc_jit_function_kindN6gccjit4typeEPKcRNSt6vectorI5paramEEiN6gccjit8locationE}@anchor{30a}@anchor{cp/topics/functions gccjit context new_function__gcc_jit_function_kind gccjit type cCP std vector param R i gccjit location}@anchor{30b}
13695@deffn {C++ Function} gccjit::@ref{154,,function} gccjit::@ref{13d,,context}::new_function (enum gcc_jit_function_kind, gccjit::type return_type, const char *name, std::vector<param> &params, int is_variadic, gccjit::location loc)
29df5715
DM
13696
13697Create a gcc_jit_function with the given name and parameters.
13698
6f7585de 13699Parameters “is_variadic” and “loc” are optional.
29df5715 13700
6f7585de 13701This is a wrapper around the C API’s @ref{11,,gcc_jit_context_new_function()}.
29df5715
DM
13702@end deffn
13703
13704@geindex gccjit;;context;;get_builtin_function (C++ function)
421d0d0f
DM
13705@anchor{cp/topics/functions _CPPv4N6gccjit7context20get_builtin_functionEPKc}@anchor{30c}@anchor{cp/topics/functions _CPPv3N6gccjit7context20get_builtin_functionEPKc}@anchor{30d}@anchor{cp/topics/functions _CPPv2N6gccjit7context20get_builtin_functionEPKc}@anchor{30e}@anchor{cp/topics/functions gccjit context get_builtin_function__cCP}@anchor{30f}
13706@deffn {C++ Function} gccjit::@ref{154,,function} gccjit::@ref{13d,,context}::get_builtin_function (const char *name)
29df5715 13707
6f7585de 13708This is a wrapper around the C API’s
02321f62 13709@ref{e1,,gcc_jit_context_get_builtin_function()}.
29df5715
DM
13710@end deffn
13711
13712@geindex gccjit;;function;;get_param (C++ function)
421d0d0f
DM
13713@anchor{cp/topics/functions _CPPv4NK6gccjit8function9get_paramEi}@anchor{310}@anchor{cp/topics/functions _CPPv3NK6gccjit8function9get_paramEi}@anchor{311}@anchor{cp/topics/functions _CPPv2NK6gccjit8function9get_paramEi}@anchor{312}@anchor{cp/topics/functions gccjit function get_param__iC}@anchor{313}
13714@deffn {C++ Function} gccjit::@ref{150,,param} gccjit::@ref{154,,function}::get_param (int index) const
29df5715
DM
13715
13716Get the param of the given index (0-based).
13717@end deffn
13718
13719@geindex gccjit;;function;;dump_to_dot (C++ function)
421d0d0f
DM
13720@anchor{cp/topics/functions _CPPv4N6gccjit8function11dump_to_dotEPKc}@anchor{15c}@anchor{cp/topics/functions _CPPv3N6gccjit8function11dump_to_dotEPKc}@anchor{314}@anchor{cp/topics/functions _CPPv2N6gccjit8function11dump_to_dotEPKc}@anchor{315}@anchor{cp/topics/functions gccjit function dump_to_dot__cCP}@anchor{316}
13721@deffn {C++ Function} void gccjit::@ref{154,,function}::dump_to_dot (const char *path)
29df5715
DM
13722
13723Emit the function in graphviz format to the given path.
13724@end deffn
13725
13726@geindex gccjit;;function;;new_local (C++ function)
421d0d0f
DM
13727@anchor{cp/topics/functions _CPPv4N6gccjit8function9new_localEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{151}@anchor{cp/topics/functions _CPPv3N6gccjit8function9new_localEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{317}@anchor{cp/topics/functions _CPPv2N6gccjit8function9new_localEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{318}@anchor{cp/topics/functions gccjit function new_local__gccjit type cCP gccjit location}@anchor{319}
13728@deffn {C++ Function} gccjit::@ref{14f,,lvalue} gccjit::@ref{154,,function}::new_local (gccjit::type type, const char *name, gccjit::location loc)
29df5715
DM
13729
13730Create a new local variable within the function, of the given type and
13731name.
13732@end deffn
13733
13734@node Blocks<2>,Statements<2>,Functions<2>,Creating and using functions<2>
421d0d0f 13735@anchor{cp/topics/functions blocks}@anchor{31a}
29df5715
DM
13736@subsubsection Blocks
13737
13738
13739@geindex gccjit;;block (C++ class)
421d0d0f 13740@anchor{cp/topics/functions _CPPv4N6gccjit5blockE}@anchor{153}@anchor{cp/topics/functions _CPPv3N6gccjit5blockE}@anchor{31b}@anchor{cp/topics/functions _CPPv2N6gccjit5blockE}@anchor{31c}@anchor{cp/topics/functions gccjit block}@anchor{31d}
29df5715
DM
13741@deffn {C++ Class} gccjit::block
13742
13743A @cite{gccjit::block} represents a basic block within a function i.e. a
13744sequence of statements with a single entry point and a single exit
13745point.
13746
421d0d0f 13747@ref{153,,gccjit;;block} is a subclass of @ref{142,,gccjit;;object}.
29df5715
DM
13748
13749The first basic block that you create within a function will
13750be the entrypoint.
13751
13752Each basic block that you create within a function must be
ec5d0088
DM
13753terminated, either with a conditional, a jump, a return, or
13754a switch.
29df5715 13755
6f7585de 13756It’s legal to have multiple basic blocks that return within
29df5715
DM
13757one function.
13758@end deffn
13759
13760@geindex gccjit;;function;;new_block (C++ function)
421d0d0f
DM
13761@anchor{cp/topics/functions _CPPv4N6gccjit8function9new_blockEPKc}@anchor{31e}@anchor{cp/topics/functions _CPPv3N6gccjit8function9new_blockEPKc}@anchor{31f}@anchor{cp/topics/functions _CPPv2N6gccjit8function9new_blockEPKc}@anchor{320}@anchor{cp/topics/functions gccjit function new_block__cCP}@anchor{321}
13762@deffn {C++ Function} gccjit::@ref{153,,block} gccjit::@ref{154,,function}::new_block (const char *name)
29df5715
DM
13763
13764Create a basic block of the given name. The name may be NULL, but
13765providing meaningful names is often helpful when debugging: it may
13766show up in dumps of the internal representation, and in error
13767messages.
13768@end deffn
13769
13770@node Statements<2>,,Blocks<2>,Creating and using functions<2>
421d0d0f 13771@anchor{cp/topics/functions statements}@anchor{322}
29df5715
DM
13772@subsubsection Statements
13773
13774
13775@geindex gccjit;;block;;add_eval (C++ function)
421d0d0f
DM
13776@anchor{cp/topics/functions _CPPv4N6gccjit5block8add_evalEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2ca}@anchor{cp/topics/functions _CPPv3N6gccjit5block8add_evalEN6gccjit6rvalueEN6gccjit8locationE}@anchor{323}@anchor{cp/topics/functions _CPPv2N6gccjit5block8add_evalEN6gccjit6rvalueEN6gccjit8locationE}@anchor{324}@anchor{cp/topics/functions gccjit block add_eval__gccjit rvalue gccjit location}@anchor{325}
13777@deffn {C++ Function} void gccjit::@ref{153,,block}::add_eval (gccjit::rvalue rvalue, gccjit::location loc)
29df5715
DM
13778
13779Add evaluation of an rvalue, discarding the result
6f7585de 13780(e.g. a function call that “returns” void).
29df5715
DM
13781
13782This is equivalent to this C code:
13783
13784@example
13785(void)expression;
13786@end example
29df5715
DM
13787@end deffn
13788
13789@geindex gccjit;;block;;add_assignment (C++ function)
421d0d0f
DM
13790@anchor{cp/topics/functions _CPPv4N6gccjit5block14add_assignmentEN6gccjit6lvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{155}@anchor{cp/topics/functions _CPPv3N6gccjit5block14add_assignmentEN6gccjit6lvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{326}@anchor{cp/topics/functions _CPPv2N6gccjit5block14add_assignmentEN6gccjit6lvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{327}@anchor{cp/topics/functions gccjit block add_assignment__gccjit lvalue gccjit rvalue gccjit location}@anchor{328}
13791@deffn {C++ Function} void gccjit::@ref{153,,block}::add_assignment (gccjit::lvalue lvalue, gccjit::rvalue rvalue, gccjit::location loc)
29df5715
DM
13792
13793Add evaluation of an rvalue, assigning the result to the given
13794lvalue.
13795
13796This is roughly equivalent to this C code:
13797
13798@example
13799lvalue = rvalue;
13800@end example
29df5715
DM
13801@end deffn
13802
13803@geindex gccjit;;block;;add_assignment_op (C++ function)
421d0d0f
DM
13804@anchor{cp/topics/functions _CPPv4N6gccjit5block17add_assignment_opEN6gccjit6lvalueE17gcc_jit_binary_opN6gccjit6rvalueEN6gccjit8locationE}@anchor{159}@anchor{cp/topics/functions _CPPv3N6gccjit5block17add_assignment_opEN6gccjit6lvalueE17gcc_jit_binary_opN6gccjit6rvalueEN6gccjit8locationE}@anchor{329}@anchor{cp/topics/functions _CPPv2N6gccjit5block17add_assignment_opEN6gccjit6lvalueE17gcc_jit_binary_opN6gccjit6rvalueEN6gccjit8locationE}@anchor{32a}@anchor{cp/topics/functions gccjit block add_assignment_op__gccjit lvalue gcc_jit_binary_op gccjit rvalue gccjit location}@anchor{32b}
13805@deffn {C++ Function} void gccjit::@ref{153,,block}::add_assignment_op (gccjit::lvalue lvalue, enum gcc_jit_binary_op, gccjit::rvalue rvalue, gccjit::location loc)
29df5715
DM
13806
13807Add evaluation of an rvalue, using the result to modify an
13808lvalue.
13809
6f7585de 13810This is analogous to “+=” and friends:
29df5715
DM
13811
13812@example
13813lvalue += rvalue;
13814lvalue *= rvalue;
13815lvalue /= rvalue;
13816@end example
13817
29df5715
DM
13818etc. For example:
13819
13820@example
13821/* "i++" */
13822loop_body.add_assignment_op (
13823 i,
13824 GCC_JIT_BINARY_OP_PLUS,
13825 ctxt.one (int_type));
13826@end example
29df5715
DM
13827@end deffn
13828
13829@geindex gccjit;;block;;add_comment (C++ function)
421d0d0f
DM
13830@anchor{cp/topics/functions _CPPv4N6gccjit5block11add_commentEPKcN6gccjit8locationE}@anchor{165}@anchor{cp/topics/functions _CPPv3N6gccjit5block11add_commentEPKcN6gccjit8locationE}@anchor{32c}@anchor{cp/topics/functions _CPPv2N6gccjit5block11add_commentEPKcN6gccjit8locationE}@anchor{32d}@anchor{cp/topics/functions gccjit block add_comment__cCP gccjit location}@anchor{32e}
13831@deffn {C++ Function} void gccjit::@ref{153,,block}::add_comment (const char *text, gccjit::location loc)
29df5715
DM
13832
13833Add a no-op textual comment to the internal representation of the
13834code. It will be optimized away, but will be visible in the dumps
6f7585de
DM
13835seen via @ref{66,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE}
13836and @ref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE},
13837and thus may be of use when debugging how your project’s internal
29df5715
DM
13838representation gets converted to the libgccjit IR.
13839
6f7585de 13840Parameter “loc” is optional.
29df5715
DM
13841@end deffn
13842
13843@geindex gccjit;;block;;end_with_conditional (C++ function)
421d0d0f
DM
13844@anchor{cp/topics/functions _CPPv4N6gccjit5block20end_with_conditionalEN6gccjit6rvalueEN6gccjit5blockEN6gccjit5blockEN6gccjit8locationE}@anchor{158}@anchor{cp/topics/functions _CPPv3N6gccjit5block20end_with_conditionalEN6gccjit6rvalueEN6gccjit5blockEN6gccjit5blockEN6gccjit8locationE}@anchor{32f}@anchor{cp/topics/functions _CPPv2N6gccjit5block20end_with_conditionalEN6gccjit6rvalueEN6gccjit5blockEN6gccjit5blockEN6gccjit8locationE}@anchor{330}@anchor{cp/topics/functions gccjit block end_with_conditional__gccjit rvalue gccjit block gccjit block gccjit location}@anchor{331}
13845@deffn {C++ Function} void gccjit::@ref{153,,block}::end_with_conditional (gccjit::rvalue boolval, gccjit::block on_true, gccjit::block on_false, gccjit::location loc)
29df5715
DM
13846
13847Terminate a block by adding evaluation of an rvalue, branching on the
13848result to the appropriate successor block.
13849
13850This is roughly equivalent to this C code:
13851
13852@example
13853if (boolval)
13854 goto on_true;
13855else
13856 goto on_false;
13857@end example
13858
29df5715
DM
13859block, boolval, on_true, and on_false must be non-NULL.
13860@end deffn
13861
13862@geindex gccjit;;block;;end_with_jump (C++ function)
421d0d0f
DM
13863@anchor{cp/topics/functions _CPPv4N6gccjit5block13end_with_jumpEN6gccjit5blockEN6gccjit8locationE}@anchor{332}@anchor{cp/topics/functions _CPPv3N6gccjit5block13end_with_jumpEN6gccjit5blockEN6gccjit8locationE}@anchor{333}@anchor{cp/topics/functions _CPPv2N6gccjit5block13end_with_jumpEN6gccjit5blockEN6gccjit8locationE}@anchor{334}@anchor{cp/topics/functions gccjit block end_with_jump__gccjit block gccjit location}@anchor{335}
13864@deffn {C++ Function} void gccjit::@ref{153,,block}::end_with_jump (gccjit::block target, gccjit::location loc)
29df5715
DM
13865
13866Terminate a block by adding a jump to the given target block.
13867
13868This is roughly equivalent to this C code:
13869
13870@example
13871goto target;
13872@end example
29df5715
DM
13873@end deffn
13874
13875@geindex gccjit;;block;;end_with_return (C++ function)
421d0d0f
DM
13876@anchor{cp/topics/functions _CPPv4N6gccjit5block15end_with_returnEN6gccjit6rvalueEN6gccjit8locationE}@anchor{336}@anchor{cp/topics/functions _CPPv3N6gccjit5block15end_with_returnEN6gccjit6rvalueEN6gccjit8locationE}@anchor{337}@anchor{cp/topics/functions _CPPv2N6gccjit5block15end_with_returnEN6gccjit6rvalueEN6gccjit8locationE}@anchor{338}@anchor{cp/topics/functions gccjit block end_with_return__gccjit rvalue gccjit location}@anchor{339}
13877@deffn {C++ Function} void gccjit::@ref{153,,block}::end_with_return (gccjit::rvalue rvalue, gccjit::location loc)
29df5715
DM
13878
13879Terminate a block.
13880
13881Both params are optional.
13882
13883An rvalue must be provided for a function returning non-void, and
6f7585de 13884must not be provided by a function “returning” @cite{void}.
29df5715
DM
13885
13886If an rvalue is provided, the block is terminated by evaluating the
13887rvalue and returning the value.
13888
13889This is roughly equivalent to this C code:
13890
13891@example
13892return expression;
13893@end example
13894
29df5715 13895If an rvalue is not provided, the block is terminated by adding a
6f7585de 13896valueless return, for use within a function with “void” return type.
29df5715
DM
13897
13898This is equivalent to this C code:
13899
13900@example
13901return;
13902@end example
29df5715
DM
13903@end deffn
13904
ec5d0088 13905@geindex gccjit;;block;;end_with_switch (C++ function)
421d0d0f
DM
13906@anchor{cp/topics/functions _CPPv4N6gccjit5block15end_with_switchEN6gccjit6rvalueEN6gccjit5blockENSt6vectorIN6gccjit5case_EEEN6gccjit8locationE}@anchor{33a}@anchor{cp/topics/functions _CPPv3N6gccjit5block15end_with_switchEN6gccjit6rvalueEN6gccjit5blockENSt6vectorIN6gccjit5case_EEEN6gccjit8locationE}@anchor{33b}@anchor{cp/topics/functions _CPPv2N6gccjit5block15end_with_switchEN6gccjit6rvalueEN6gccjit5blockENSt6vectorIN6gccjit5case_EEEN6gccjit8locationE}@anchor{33c}@anchor{cp/topics/functions gccjit block end_with_switch__gccjit rvalue gccjit block std vector gccjit case_ gccjit location}@anchor{33d}
13907@deffn {C++ Function} void gccjit::@ref{153,,block}::end_with_switch (gccjit::rvalue expr, gccjit::block default_block, std::vector<gccjit::case_> cases, gccjit::location loc)
ec5d0088
DM
13908
13909Terminate a block by adding evalation of an rvalue, then performing
13910a multiway branch.
13911
13912This is roughly equivalent to this C code:
13913
13914@example
13915switch (expr)
13916 @{
13917 default:
13918 goto default_block;
13919
13920 case C0.min_value ... C0.max_value:
13921 goto C0.dest_block;
13922
13923 case C1.min_value ... C1.max_value:
13924 goto C1.dest_block;
13925
13926 ...etc...
13927
13928 case C[N - 1].min_value ... C[N - 1].max_value:
13929 goto C[N - 1].dest_block;
13930@}
13931@end example
13932
ec5d0088
DM
13933@code{expr} must be of the same integer type as all of the @code{min_value}
13934and @code{max_value} within the cases.
13935
13936The ranges of the cases must not overlap (or have duplicate
13937values).
13938
13939The API entrypoints relating to switch statements and cases:
13940
13941@quotation
13942
13943
13944@itemize *
13945
13946@item
421d0d0f 13947@ref{33a,,gccjit;;block;;end_with_switch()}
ec5d0088
DM
13948
13949@item
421d0d0f 13950@code{gccjit::context::new_case()}
ec5d0088
DM
13951@end itemize
13952@end quotation
13953
02321f62 13954were added in @ref{ef,,LIBGCCJIT_ABI_3}; you can test for their presence
ec5d0088
DM
13955using
13956
13957@example
13958#ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS
13959@end example
13960
ec5d0088 13961A @cite{gccjit::case_} represents a case within a switch statement, and
421d0d0f
DM
13962is created within a particular @ref{13d,,gccjit;;context} using
13963@code{gccjit::context::new_case()}. It is a subclass of
13964@ref{142,,gccjit;;object}.
ec5d0088
DM
13965
13966Each case expresses a multivalued range of integer values. You
13967can express single-valued cases by passing in the same value for
13968both @cite{min_value} and @cite{max_value}.
13969
6f7585de 13970Here’s an example of creating a switch statement:
ec5d0088
DM
13971
13972@quotation
13973
13974@example
13975
13976void
13977create_code (gcc_jit_context *c_ctxt, void *user_data)
13978@{
13979 /* Let's try to inject the equivalent of:
13980 int
13981 test_switch (int x)
13982 @{
13983 switch (x)
13984 @{
13985 case 0 ... 5:
13986 return 3;
13987
13988 case 25 ... 27:
13989 return 4;
13990
13991 case -42 ... -17:
13992 return 83;
13993
13994 case 40:
13995 return 8;
13996
13997 default:
13998 return 10;
13999 @}
14000 @}
14001 */
14002 gccjit::context ctxt (c_ctxt);
14003 gccjit::type t_int = ctxt.get_type (GCC_JIT_TYPE_INT);
14004 gccjit::type return_type = t_int;
14005 gccjit::param x = ctxt.new_param (t_int, "x");
14006 std::vector <gccjit::param> params;
14007 params.push_back (x);
14008 gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
14009 return_type,
14010 "test_switch",
14011 params, 0);
14012
14013 gccjit::block b_initial = func.new_block ("initial");
14014
14015 gccjit::block b_default = func.new_block ("default");
14016 gccjit::block b_case_0_5 = func.new_block ("case_0_5");
14017 gccjit::block b_case_25_27 = func.new_block ("case_25_27");
14018 gccjit::block b_case_m42_m17 = func.new_block ("case_m42_m17");
14019 gccjit::block b_case_40 = func.new_block ("case_40");
14020
14021 std::vector <gccjit::case_> cases;
14022 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 0),
14023 ctxt.new_rvalue (t_int, 5),
14024 b_case_0_5));
14025 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 25),
14026 ctxt.new_rvalue (t_int, 27),
14027 b_case_25_27));
14028 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, -42),
14029 ctxt.new_rvalue (t_int, -17),
14030 b_case_m42_m17));
14031 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 40),
14032 ctxt.new_rvalue (t_int, 40),
14033 b_case_40));
14034 b_initial.end_with_switch (x,
14035 b_default,
14036 cases);
14037
14038 b_case_0_5.end_with_return (ctxt.new_rvalue (t_int, 3));
14039 b_case_25_27.end_with_return (ctxt.new_rvalue (t_int, 4));
14040 b_case_m42_m17.end_with_return (ctxt.new_rvalue (t_int, 83));
14041 b_case_40.end_with_return (ctxt.new_rvalue (t_int, 8));
14042 b_default.end_with_return (ctxt.new_rvalue (t_int, 10));
14043@}
14044
ec5d0088 14045@end example
ec5d0088
DM
14046@end quotation
14047@end deffn
14048
7adcbafe 14049@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
29df5715
DM
14050@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
14051@c
14052@c This is free software: you can redistribute it and/or modify it
14053@c under the terms of the GNU General Public License as published by
14054@c the Free Software Foundation, either version 3 of the License, or
14055@c (at your option) any later version.
14056@c
14057@c This program is distributed in the hope that it will be useful, but
14058@c WITHOUT ANY WARRANTY; without even the implied warranty of
14059@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14060@c General Public License for more details.
14061@c
14062@c You should have received a copy of the GNU General Public License
14063@c along with this program. If not, see
786973ce 14064@c <https://www.gnu.org/licenses/>.
29df5715 14065
fdce7209 14066@node Source Locations<2>,Compiling a context<2>,Creating and using functions<2>,Topic Reference<2>
421d0d0f 14067@anchor{cp/topics/locations doc}@anchor{33e}@anchor{cp/topics/locations source-locations}@anchor{33f}
29df5715
DM
14068@subsection Source Locations
14069
14070
14071@geindex gccjit;;location (C++ class)
421d0d0f 14072@anchor{cp/topics/locations _CPPv4N6gccjit8locationE}@anchor{163}@anchor{cp/topics/locations _CPPv3N6gccjit8locationE}@anchor{340}@anchor{cp/topics/locations _CPPv2N6gccjit8locationE}@anchor{341}@anchor{cp/topics/locations gccjit location}@anchor{342}
29df5715
DM
14073@deffn {C++ Class} gccjit::location
14074
14075A @cite{gccjit::location} encapsulates a source code location, so that
14076you can (optionally) associate locations in your language with
14077statements in the JIT-compiled code, allowing the debugger to
14078single-step through your language.
14079
14080@cite{gccjit::location} instances are optional: you can always omit them
14081from any C++ API entrypoint accepting one.
14082
421d0d0f 14083You can construct them using @ref{169,,gccjit;;context;;new_location()}.
29df5715 14084
6f7585de 14085You need to enable @ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the
421d0d0f 14086@ref{13d,,gccjit;;context} for these locations to actually be usable by
29df5715
DM
14087the debugger:
14088
14089@example
14090ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1);
14091@end example
29df5715
DM
14092@end deffn
14093
14094@geindex gccjit;;context;;new_location (C++ function)
421d0d0f
DM
14095@anchor{cp/topics/locations _CPPv4N6gccjit7context12new_locationEPKcii}@anchor{169}@anchor{cp/topics/locations _CPPv3N6gccjit7context12new_locationEPKcii}@anchor{343}@anchor{cp/topics/locations _CPPv2N6gccjit7context12new_locationEPKcii}@anchor{344}@anchor{cp/topics/locations gccjit context new_location__cCP i i}@anchor{345}
14096@deffn {C++ Function} gccjit::@ref{163,,location} gccjit::@ref{13d,,context}::new_location (const char *filename, int line, int column)
29df5715
DM
14097
14098Create a @cite{gccjit::location} instance representing the given source
14099location.
14100@end deffn
14101
14102@menu
14103* Faking it: Faking it<2>.
14104
14105@end menu
14106
14107@node Faking it<2>,,,Source Locations<2>
421d0d0f 14108@anchor{cp/topics/locations faking-it}@anchor{346}
29df5715
DM
14109@subsubsection Faking it
14110
14111
6f7585de 14112If you don’t have source code for your internal representation, but need
29df5715 14113to debug, you can generate a C-like representation of the functions in
421d0d0f 14114your context using @ref{188,,gccjit;;context;;dump_to_file()}:
29df5715
DM
14115
14116@example
14117ctxt.dump_to_file ("/tmp/something.c",
14118 1 /* update_locations */);
14119@end example
14120
29df5715
DM
14121This will dump C-like code to the given path. If the @cite{update_locations}
14122argument is true, this will also set up @cite{gccjit::location} information
14123throughout the context, pointing at the dump file as if it were a source
14124file, giving you @emph{something} you can step through in the debugger.
14125
7adcbafe 14126@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
29df5715
DM
14127@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
14128@c
14129@c This is free software: you can redistribute it and/or modify it
14130@c under the terms of the GNU General Public License as published by
14131@c the Free Software Foundation, either version 3 of the License, or
14132@c (at your option) any later version.
14133@c
14134@c This program is distributed in the hope that it will be useful, but
14135@c WITHOUT ANY WARRANTY; without even the implied warranty of
14136@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14137@c General Public License for more details.
14138@c
14139@c You should have received a copy of the GNU General Public License
14140@c along with this program. If not, see
786973ce 14141@c <https://www.gnu.org/licenses/>.
29df5715 14142
421d0d0f
DM
14143@node Compiling a context<2>,Using Assembly Language with libgccjit++,Source Locations<2>,Topic Reference<2>
14144@anchor{cp/topics/compilation doc}@anchor{347}@anchor{cp/topics/compilation compiling-a-context}@anchor{348}
fdce7209 14145@subsection Compiling a context
29df5715
DM
14146
14147
421d0d0f
DM
14148Once populated, a @ref{13d,,gccjit;;context} can be compiled to
14149machine code, either in-memory via @ref{147,,gccjit;;context;;compile()} or
14150to disk via @ref{349,,gccjit;;context;;compile_to_file()}.
fdce7209
DM
14151
14152You can compile a context multiple times (using either form of
14153compilation), although any errors that occur on the context will
14154prevent any future compilation of that context.
14155
14156@menu
14157* In-memory compilation: In-memory compilation<2>.
14158* Ahead-of-time compilation: Ahead-of-time compilation<2>.
14159
14160@end menu
14161
14162@node In-memory compilation<2>,Ahead-of-time compilation<2>,,Compiling a context<2>
421d0d0f 14163@anchor{cp/topics/compilation in-memory-compilation}@anchor{34a}
fdce7209 14164@subsubsection In-memory compilation
29df5715 14165
29df5715
DM
14166
14167@geindex gccjit;;context;;compile (C++ function)
421d0d0f
DM
14168@anchor{cp/topics/compilation _CPPv4N6gccjit7context7compileEv}@anchor{147}@anchor{cp/topics/compilation _CPPv3N6gccjit7context7compileEv}@anchor{34b}@anchor{cp/topics/compilation _CPPv2N6gccjit7context7compileEv}@anchor{34c}@anchor{cp/topics/compilation gccjit context compile}@anchor{34d}
14169@deffn {C++ Function} gcc_jit_result *gccjit::@ref{13d,,context}::compile ()
29df5715
DM
14170
14171This calls into GCC and builds the code, returning a
14172@cite{gcc_jit_result *}.
fdce7209
DM
14173
14174This is a thin wrapper around the
6f7585de 14175@ref{15,,gcc_jit_context_compile()} API entrypoint.
29df5715
DM
14176@end deffn
14177
fdce7209 14178@node Ahead-of-time compilation<2>,,In-memory compilation<2>,Compiling a context<2>
421d0d0f 14179@anchor{cp/topics/compilation ahead-of-time-compilation}@anchor{34e}
fdce7209 14180@subsubsection Ahead-of-time compilation
29df5715 14181
29df5715 14182
fdce7209
DM
14183Although libgccjit is primarily aimed at just-in-time compilation, it
14184can also be used for implementing more traditional ahead-of-time
421d0d0f 14185compilers, via the @ref{349,,gccjit;;context;;compile_to_file()} method.
29df5715 14186
fdce7209 14187@geindex gccjit;;context;;compile_to_file (C++ function)
421d0d0f
DM
14188@anchor{cp/topics/compilation _CPPv4N6gccjit7context15compile_to_fileE19gcc_jit_output_kindPKc}@anchor{349}@anchor{cp/topics/compilation _CPPv3N6gccjit7context15compile_to_fileE19gcc_jit_output_kindPKc}@anchor{34f}@anchor{cp/topics/compilation _CPPv2N6gccjit7context15compile_to_fileE19gcc_jit_output_kindPKc}@anchor{350}@anchor{cp/topics/compilation gccjit context compile_to_file__gcc_jit_output_kind cCP}@anchor{351}
14189@deffn {C++ Function} void gccjit::@ref{13d,,context}::compile_to_file (enum gcc_jit_output_kind, const char *output_path)
fdce7209 14190
421d0d0f 14191Compile the @ref{13d,,gccjit;;context} to a file of the given
fdce7209
DM
14192kind.
14193
14194This is a thin wrapper around the
6f7585de 14195@ref{4a,,gcc_jit_context_compile_to_file()} API entrypoint.
29df5715
DM
14196@end deffn
14197
7adcbafe 14198@c Copyright (C) 2020-2022 Free Software Foundation, Inc.
421d0d0f
DM
14199@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
14200@c
14201@c This is free software: you can redistribute it and/or modify it
14202@c under the terms of the GNU General Public License as published by
14203@c the Free Software Foundation, either version 3 of the License, or
14204@c (at your option) any later version.
14205@c
14206@c This program is distributed in the hope that it will be useful, but
14207@c WITHOUT ANY WARRANTY; without even the implied warranty of
14208@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14209@c General Public License for more details.
14210@c
14211@c You should have received a copy of the GNU General Public License
14212@c along with this program. If not, see
786973ce 14213@c <https://www.gnu.org/licenses/>.
421d0d0f
DM
14214
14215@node Using Assembly Language with libgccjit++,,Compiling a context<2>,Topic Reference<2>
14216@anchor{cp/topics/asm doc}@anchor{352}@anchor{cp/topics/asm using-assembly-language-with-libgccjit}@anchor{353}
14217@subsection Using Assembly Language with libgccjit++
14218
14219
14220libgccjit has some support for directly embedding assembler instructions.
14221This is based on GCC’s support for inline @code{asm} in C code, and the
14222following assumes a familiarity with that functionality. See
14223How to Use Inline Assembly Language in C Code@footnote{https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html}
14224in GCC’s documentation, the “Extended Asm” section in particular.
14225
14226These entrypoints were added in @ref{122,,LIBGCCJIT_ABI_15}; you can test
14227for their presence using
14228
14229@quotation
14230
14231@example
14232#ifdef LIBGCCJIT_HAVE_ASM_STATEMENTS
14233@end example
14234@end quotation
14235
14236@menu
14237* Adding assembler instructions within a function: Adding assembler instructions within a function<2>.
14238* Adding top-level assembler statements: Adding top-level assembler statements<2>.
14239
14240@end menu
14241
14242@node Adding assembler instructions within a function<2>,Adding top-level assembler statements<2>,,Using Assembly Language with libgccjit++
14243@anchor{cp/topics/asm adding-assembler-instructions-within-a-function}@anchor{354}
14244@subsubsection Adding assembler instructions within a function
14245
14246
14247@geindex gccjit;;extended_asm (C++ class)
14248@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asmE}@anchor{355}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asmE}@anchor{356}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asmE}@anchor{357}@anchor{cp/topics/asm gccjit extended_asm}@anchor{358}
14249@deffn {C++ Class} gccjit::extended_asm
14250
14251A @cite{gccjit::extended_asm} represents an extended @code{asm} statement: a
14252series of low-level instructions inside a function that convert inputs
14253to outputs.
14254
14255@ref{355,,gccjit;;extended_asm} is a subclass of @ref{142,,gccjit;;object}.
14256It is a thin wrapper around the C API’s @ref{f1,,gcc_jit_extended_asm *}.
14257
14258To avoid having an API entrypoint with a very large number of
14259parameters, an extended @code{asm} statement is made in stages:
14260an initial call to create the @ref{355,,gccjit;;extended_asm},
14261followed by calls to add operands and set other properties of the
14262statement.
14263
14264There are two API entrypoints for creating a @ref{355,,gccjit;;extended_asm}:
14265
14266
14267@itemize *
14268
14269@item
14270@ref{359,,gccjit;;block;;add_extended_asm()} for an @code{asm} statement with
14271no control flow, and
14272
14273@item
14274@ref{35a,,gccjit;;block;;end_with_extended_asm_goto()} for an @code{asm goto}.
14275@end itemize
14276
14277For example, to create the equivalent of:
14278
14279@example
14280 asm ("mov %1, %0\n\t"
14281 "add $1, %0"
14282 : "=r" (dst)
14283 : "r" (src));
14284@end example
14285
14286the following API calls could be used:
14287
14288@example
14289 block.add_extended_asm ("mov %1, %0\n\t"
14290 "add $1, %0")
14291 .add_output_operand ("=r", dst)
14292 .add_input_operand ("r", src);
14293@end example
14294
14295@cartouche
14296@quotation Warning
14297When considering the numbering of operands within an
14298extended @code{asm} statement (e.g. the @code{%0} and @code{%1}
14299above), the equivalent to the C syntax is followed i.e. all
14300output operands, then all input operands, regardless of
14301what order the calls to
14302@ref{35b,,gccjit;;extended_asm;;add_output_operand()} and
14303@ref{35c,,gccjit;;extended_asm;;add_input_operand()} were made in.
14304@end quotation
14305@end cartouche
14306
14307As in the C syntax, operands can be given symbolic names to avoid having
14308to number them. For example, to create the equivalent of:
14309
14310@example
14311 asm ("bsfl %[aMask], %[aIndex]"
14312 : [aIndex] "=r" (Index)
14313 : [aMask] "r" (Mask)
14314 : "cc");
14315@end example
14316
14317the following API calls could be used:
14318
14319@example
14320 block.add_extended_asm ("bsfl %[aMask], %[aIndex]")
14321 .add_output_operand ("aIndex", "=r", index)
14322 .add_input_operand ("aMask", "r", mask)
14323 .add_clobber ("cc");
14324@end example
14325@end deffn
14326
14327@geindex gccjit;;block;;add_extended_asm (C++ function)
14328@anchor{cp/topics/asm _CPPv4N6gccjit5block16add_extended_asmERKNSt6stringEN6gccjit8locationE}@anchor{359}@anchor{cp/topics/asm _CPPv3N6gccjit5block16add_extended_asmERKNSt6stringEN6gccjit8locationE}@anchor{35d}@anchor{cp/topics/asm _CPPv2N6gccjit5block16add_extended_asmERKNSt6stringEN6gccjit8locationE}@anchor{35e}@anchor{cp/topics/asm gccjit block add_extended_asm__ssCR gccjit location}@anchor{35f}
14329@deffn {C++ Function} @ref{355,,extended_asm} gccjit::@ref{153,,block}::add_extended_asm (const std::string &asm_template, gccjit::location loc = location())
14330
14331Create a @ref{355,,gccjit;;extended_asm} for an extended @code{asm} statement
14332with no control flow (i.e. without the @code{goto} qualifier).
14333
14334The parameter @code{asm_template} corresponds to the @cite{AssemblerTemplate}
14335within C’s extended @code{asm} syntax. It must be non-NULL. The call takes
14336a copy of the underlying string, so it is valid to pass in a pointer to
14337an on-stack buffer.
14338@end deffn
14339
14340@geindex gccjit;;block;;end_with_extended_asm_goto (C++ function)
14341@anchor{cp/topics/asm _CPPv4N6gccjit5block26end_with_extended_asm_gotoERKNSt6stringENSt6vectorI5blockEEP5block8location}@anchor{35a}@anchor{cp/topics/asm _CPPv3N6gccjit5block26end_with_extended_asm_gotoERKNSt6stringENSt6vectorI5blockEEP5block8location}@anchor{360}@anchor{cp/topics/asm _CPPv2N6gccjit5block26end_with_extended_asm_gotoERKNSt6stringENSt6vectorI5blockEEP5block8location}@anchor{361}@anchor{cp/topics/asm gccjit block end_with_extended_asm_goto__ssCR std vector block blockP location}@anchor{362}
14342@deffn {C++ Function} @ref{355,,extended_asm} gccjit::@ref{153,,block}::end_with_extended_asm_goto (const std::string &asm_template, std::vector<block> goto_blocks, block *fallthrough_block, location loc = location())
14343
14344Create a @ref{355,,gccjit;;extended_asm} for an extended @code{asm} statement
14345that may perform jumps, and use it to terminate the given block.
14346This is equivalent to the @code{goto} qualifier in C’s extended @code{asm}
14347syntax.
14348
14349For example, to create the equivalent of:
14350
14351@example
14352 asm goto ("btl %1, %0\n\t"
14353 "jc %l[carry]"
14354 : // No outputs
14355 : "r" (p1), "r" (p2)
14356 : "cc"
14357 : carry);
14358@end example
14359
14360the following API calls could be used:
14361
14362@example
14363 const char *asm_template =
14364 (use_name
14365 ? /* Label referred to by name: "%l[carry]". */
14366 ("btl %1, %0\n\t"
14367 "jc %l[carry]")
14368 : /* Label referred to numerically: "%l2". */
14369 ("btl %1, %0\n\t"
14370 "jc %l2"));
14371
14372 std::vector<gccjit::block> goto_blocks (@{b_carry@});
14373 gccjit::extended_asm ext_asm
14374 = (b_start.end_with_extended_asm_goto (asm_template,
14375 goto_blocks,
14376 &b_fallthru)
14377 .add_input_operand ("r", p1)
14378 .add_input_operand ("r", p2)
14379 .add_clobber ("cc"));
14380@end example
14381
14382here referencing a @code{gcc_jit_block} named “carry”.
14383
14384@code{num_goto_blocks} corresponds to the @code{GotoLabels} parameter within C’s
14385extended @code{asm} syntax. The block names can be referenced within the
14386assembler template.
14387
14388@code{fallthrough_block} can be NULL. If non-NULL, it specifies the block
14389to fall through to after the statement.
14390
14391@cartouche
14392@quotation Note
14393This is needed since each @ref{153,,gccjit;;block} must have a
14394single exit point, as a basic block: you can’t jump from the
14395middle of a block. A “goto” is implicitly added after the
14396asm to handle the fallthrough case, which is equivalent to what
14397would have happened in the C case.
14398@end quotation
14399@end cartouche
14400@end deffn
14401
14402@geindex gccjit;;extended_asm;;set_volatile_flag (C++ function)
14403@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm17set_volatile_flagEb}@anchor{363}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm17set_volatile_flagEb}@anchor{364}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm17set_volatile_flagEb}@anchor{365}@anchor{cp/topics/asm gccjit extended_asm set_volatile_flag__b}@anchor{366}
14404@deffn {C++ Function} gccjit::@ref{355,,extended_asm} &gccjit::@ref{355,,extended_asm}::set_volatile_flag (bool flag)
14405
14406Set whether the @ref{355,,gccjit;;extended_asm} has side-effects, equivalent to the
14407volatile@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile}
14408qualifier in C’s extended asm syntax.
14409
14410For example, to create the equivalent of:
14411
14412@example
14413asm volatile ("rdtsc\n\t" // Returns the time in EDX:EAX.
14414 "shl $32, %%rdx\n\t" // Shift the upper bits left.
14415 "or %%rdx, %0" // 'Or' in the lower bits.
14416 : "=a" (msr)
14417 :
14418 : "rdx");
14419@end example
14420
14421the following API calls could be used:
14422
14423@example
14424 gccjit::extended_asm ext_asm
14425 = block.add_extended_asm
14426 ("rdtsc\n\t" /* Returns the time in EDX:EAX. */
14427 "shl $32, %%rdx\n\t" /* Shift the upper bits left. */
14428 "or %%rdx, %0") /* 'Or' in the lower bits. */
14429 .set_volatile_flag (true)
14430 .add_output_operand ("=a", msr)
14431 .add_clobber ("rdx");
14432@end example
14433
14434where the @ref{355,,gccjit;;extended_asm} is flagged as volatile.
14435@end deffn
14436
14437@geindex gccjit;;extended_asm;;set_inline_flag (C++ function)
14438@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm15set_inline_flagEb}@anchor{367}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm15set_inline_flagEb}@anchor{368}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm15set_inline_flagEb}@anchor{369}@anchor{cp/topics/asm gccjit extended_asm set_inline_flag__b}@anchor{36a}
14439@deffn {C++ Function} gccjit::@ref{355,,extended_asm} &gccjit::@ref{355,,extended_asm}::set_inline_flag (bool flag)
14440
14441Set the equivalent of the
14442inline@footnote{https://gcc.gnu.org/onlinedocs/gcc/Size-of-an-asm.html#Size-of-an-asm}
14443qualifier in C’s extended @code{asm} syntax.
14444@end deffn
14445
14446@geindex gccjit;;extended_asm;;add_output_operand (C++ function)
14447@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm18add_output_operandERKNSt6stringERKNSt6stringEN6gccjit6lvalueE}@anchor{35b}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm18add_output_operandERKNSt6stringERKNSt6stringEN6gccjit6lvalueE}@anchor{36b}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm18add_output_operandERKNSt6stringERKNSt6stringEN6gccjit6lvalueE}@anchor{36c}@anchor{cp/topics/asm gccjit extended_asm add_output_operand__ssCR ssCR gccjit lvalue}@anchor{36d}
14448@deffn {C++ Function} gccjit::@ref{355,,extended_asm} &gccjit::@ref{355,,extended_asm}::add_output_operand (const std::string &asm_symbolic_name, const std::string &constraint, gccjit::lvalue dest)
14449
14450Add an output operand to the extended @code{asm} statement. See the
14451Output Operands@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#OutputOperands}
14452section of the documentation of the C syntax.
14453
14454@code{asm_symbolic_name} corresponds to the @code{asmSymbolicName} component of
14455C’s extended @code{asm} syntax, and specifies the symbolic name for the operand.
14456See the overload below for an alternative that does not supply a symbolic
14457name.
14458
14459@code{constraint} corresponds to the @code{constraint} component of C’s extended
14460@code{asm} syntax.
14461
14462@code{dest} corresponds to the @code{cvariablename} component of C’s extended
14463@code{asm} syntax.
14464
14465@example
14466// Example with a symbolic name ("aIndex"), the equivalent of:
14467// : [aIndex] "=r" (index)
14468ext_asm.add_output_operand ("aIndex", "=r", index);
14469@end example
14470
14471This function can’t be called on an @code{asm goto} as such instructions can’t
14472have outputs; see the
14473Goto Labels@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#GotoLabels}
14474section of GCC’s “Extended Asm” documentation.
14475@end deffn
14476
14477@geindex gccjit;;extended_asm;;add_output_operand (C++ function)
14478@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm18add_output_operandERKNSt6stringEN6gccjit6lvalueE}@anchor{36e}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm18add_output_operandERKNSt6stringEN6gccjit6lvalueE}@anchor{36f}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm18add_output_operandERKNSt6stringEN6gccjit6lvalueE}@anchor{370}@anchor{cp/topics/asm gccjit extended_asm add_output_operand__ssCR gccjit lvalue}@anchor{371}
14479@deffn {C++ Function} gccjit::@ref{355,,extended_asm} &gccjit::@ref{355,,extended_asm}::add_output_operand (const std::string &constraint, gccjit::lvalue dest)
14480
14481As above, but don’t supply a symbolic name for the operand.
14482
14483@example
14484// Example without a symbolic name, the equivalent of:
14485// : "=r" (dst)
14486ext_asm.add_output_operand ("=r", dst);
14487@end example
14488@end deffn
14489
14490@geindex gccjit;;extended_asm;;add_input_operand (C++ function)
14491@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm17add_input_operandERKNSt6stringERKNSt6stringEN6gccjit6rvalueE}@anchor{35c}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm17add_input_operandERKNSt6stringERKNSt6stringEN6gccjit6rvalueE}@anchor{372}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm17add_input_operandERKNSt6stringERKNSt6stringEN6gccjit6rvalueE}@anchor{373}@anchor{cp/topics/asm gccjit extended_asm add_input_operand__ssCR ssCR gccjit rvalue}@anchor{374}
14492@deffn {C++ Function} gccjit::@ref{355,,extended_asm} &gccjit::@ref{355,,extended_asm}::add_input_operand (const std::string &asm_symbolic_name, const std::string &constraint, gccjit::rvalue src)
14493
14494Add an input operand to the extended @code{asm} statement. See the
14495Input Operands@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#InputOperands}
14496section of the documentation of the C syntax.
14497
14498@code{asm_symbolic_name} corresponds to the @code{asmSymbolicName} component
14499of C’s extended @code{asm} syntax. See the overload below for an alternative
14500that does not supply a symbolic name.
14501
14502@code{constraint} corresponds to the @code{constraint} component of C’s extended
14503@code{asm} syntax.
14504
14505@code{src} corresponds to the @code{cexpression} component of C’s extended
14506@code{asm} syntax.
14507
14508@example
14509// Example with a symbolic name ("aMask"), the equivalent of:
14510// : [aMask] "r" (Mask)
14511ext_asm.add_input_operand ("aMask", "r", mask);
14512@end example
14513@end deffn
14514
14515@geindex gccjit;;extended_asm;;add_input_operand (C++ function)
14516@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm17add_input_operandERKNSt6stringEN6gccjit6rvalueE}@anchor{375}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm17add_input_operandERKNSt6stringEN6gccjit6rvalueE}@anchor{376}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm17add_input_operandERKNSt6stringEN6gccjit6rvalueE}@anchor{377}@anchor{cp/topics/asm gccjit extended_asm add_input_operand__ssCR gccjit rvalue}@anchor{378}
14517@deffn {C++ Function} gccjit::@ref{355,,extended_asm} &gccjit::@ref{355,,extended_asm}::add_input_operand (const std::string &constraint, gccjit::rvalue src)
14518
14519As above, but don’t supply a symbolic name for the operand.
14520
14521@example
14522// Example without a symbolic name, the equivalent of:
14523// : "r" (src)
14524ext_asm.add_input_operand ("r", src);
14525@end example
14526@end deffn
14527
14528@geindex gccjit;;extended_asm;;add_clobber (C++ function)
14529@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm11add_clobberERKNSt6stringE}@anchor{379}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm11add_clobberERKNSt6stringE}@anchor{37a}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm11add_clobberERKNSt6stringE}@anchor{37b}@anchor{cp/topics/asm gccjit extended_asm add_clobber__ssCR}@anchor{37c}
14530@deffn {C++ Function} gccjit::@ref{355,,extended_asm} &gccjit::@ref{355,,extended_asm}::add_clobber (const std::string &victim)
14531
14532Add @cite{victim} to the list of registers clobbered by the extended @code{asm}
14533statement. See the
14534Clobbers and Scratch Registers@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Clobbers-and-Scratch-Registers#}
14535section of the documentation of the C syntax.
14536
14537Statements with multiple clobbers will require multiple calls, one per
14538clobber.
14539
14540For example:
14541
14542@example
14543ext_asm.add_clobber ("r0").add_clobber ("cc").add_clobber ("memory");
14544@end example
14545@end deffn
14546
14547@node Adding top-level assembler statements<2>,,Adding assembler instructions within a function<2>,Using Assembly Language with libgccjit++
14548@anchor{cp/topics/asm adding-top-level-assembler-statements}@anchor{37d}
14549@subsubsection Adding top-level assembler statements
14550
14551
14552In addition to creating extended @code{asm} instructions within a function,
14553there is support for creating “top-level” assembler statements, outside
14554of any function.
14555
14556@geindex gccjit;;context;;add_top_level_asm (C++ function)
14557@anchor{cp/topics/asm _CPPv4N6gccjit7context17add_top_level_asmEPKcN6gccjit8locationE}@anchor{37e}@anchor{cp/topics/asm _CPPv3N6gccjit7context17add_top_level_asmEPKcN6gccjit8locationE}@anchor{37f}@anchor{cp/topics/asm _CPPv2N6gccjit7context17add_top_level_asmEPKcN6gccjit8locationE}@anchor{380}@anchor{cp/topics/asm gccjit context add_top_level_asm__cCP gccjit location}@anchor{381}
14558@deffn {C++ Function} void gccjit::@ref{13d,,context}::add_top_level_asm (const char *asm_stmts, gccjit::location loc = location())
14559
14560Create a set of top-level asm statements, analogous to those created
14561by GCC’s “basic” @code{asm} syntax in C at file scope.
14562
14563For example, to create the equivalent of:
14564
14565@example
14566 asm ("\t.pushsection .text\n"
14567 "\t.globl add_asm\n"
14568 "\t.type add_asm, @@function\n"
14569 "add_asm:\n"
14570 "\tmovq %rdi, %rax\n"
14571 "\tadd %rsi, %rax\n"
14572 "\tret\n"
14573 "\t.popsection\n");
14574@end example
14575
14576the following API calls could be used:
14577
14578@example
14579 ctxt.add_top_level_asm ("\t.pushsection .text\n"
14580 "\t.globl add_asm\n"
14581 "\t.type add_asm, @@function\n"
14582 "add_asm:\n"
14583 "\tmovq %rdi, %rax\n"
14584 "\tadd %rsi, %rax\n"
14585 "\tret\n"
14586 "\t# some asm here\n"
14587 "\t.popsection\n");
14588@end example
14589@end deffn
14590
7adcbafe 14591@c Copyright (C) 2014-2022 Free Software Foundation, Inc.
29df5715
DM
14592@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
14593@c
14594@c This is free software: you can redistribute it and/or modify it
14595@c under the terms of the GNU General Public License as published by
14596@c the Free Software Foundation, either version 3 of the License, or
14597@c (at your option) any later version.
14598@c
14599@c This program is distributed in the hope that it will be useful, but
14600@c WITHOUT ANY WARRANTY; without even the implied warranty of
14601@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14602@c General Public License for more details.
14603@c
14604@c You should have received a copy of the GNU General Public License
14605@c along with this program. If not, see
786973ce 14606@c <https://www.gnu.org/licenses/>.
29df5715
DM
14607
14608@node Internals,Indices and tables,C++ bindings for libgccjit,Top
421d0d0f 14609@anchor{internals/index doc}@anchor{382}@anchor{internals/index internals}@anchor{383}
29df5715
DM
14610@chapter Internals
14611
14612
14613@menu
14614* Working on the JIT library::
14615* Running the test suite::
14616* Environment variables::
18eb0d13 14617* Packaging notes::
29df5715 14618* Overview of code structure::
86d0ac88 14619* Design notes::
1470e75f 14620* Submitting patches::
29df5715
DM
14621
14622@end menu
14623
14624@node Working on the JIT library,Running the test suite,,Internals
421d0d0f 14625@anchor{internals/index working-on-the-jit-library}@anchor{384}
29df5715
DM
14626@section Working on the JIT library
14627
14628
6f7585de 14629Having checked out the source code (to “src”), you can configure and build
29df5715
DM
14630the JIT library like this:
14631
14632@example
14633mkdir build
14634mkdir install
14635PREFIX=$(pwd)/install
14636cd build
14637../src/configure \
14638 --enable-host-shared \
433d16df 14639 --enable-languages=jit,c++ \
29df5715
DM
14640 --disable-bootstrap \
14641 --enable-checking=release \
14642 --prefix=$PREFIX
14643nice make -j4 # altering the "4" to however many cores you have
14644@end example
14645
29df5715
DM
14646This should build a libgccjit.so within jit/build/gcc:
14647
14648@example
14649[build] $ file gcc/libgccjit.so*
14650gcc/libgccjit.so: symbolic link to `libgccjit.so.0'
14651gcc/libgccjit.so.0: symbolic link to `libgccjit.so.0.0.1'
14652gcc/libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped
14653@end example
14654
6f7585de 14655Here’s what those configuration options mean:
29df5715
DM
14656
14657@geindex command line option; --enable-host-shared
421d0d0f 14658@anchor{internals/index cmdoption-enable-host-shared}@anchor{385}
6f7585de 14659@deffn {Option} @w{-}@w{-}enable@w{-}host@w{-}shared
29df5715
DM
14660
14661Configuring with this option means that the compiler is built as
14662position-independent code, which incurs a slight performance hit,
14663but it necessary for a shared library.
14664@end deffn
14665
433d16df 14666@geindex command line option; --enable-languages=jit@comma{}c++
421d0d0f 14667@anchor{internals/index cmdoption-enable-languages}@anchor{386}
6f7585de 14668@deffn {Option} @w{-}@w{-}enable@w{-}languages=jit,c++
29df5715
DM
14669
14670This specifies which frontends to build. The JIT library looks like
14671a frontend to the rest of the code.
433d16df
DM
14672
14673The C++ portion of the JIT test suite requires the C++ frontend to be
14674enabled at configure-time, or you may see errors like this when
14675running the test suite:
14676
14677@example
14678xgcc: error: /home/david/jit/src/gcc/testsuite/jit.dg/test-quadratic.cc: C++ compiler not installed on this system
14679c++: error trying to exec 'cc1plus': execvp: No such file or directory
14680@end example
29df5715
DM
14681@end deffn
14682
14683@geindex command line option; --disable-bootstrap
421d0d0f 14684@anchor{internals/index cmdoption-disable-bootstrap}@anchor{387}
6f7585de 14685@deffn {Option} @w{-}@w{-}disable@w{-}bootstrap
29df5715 14686
6f7585de
DM
14687For hacking on the “jit” subdirectory, performing a full
14688bootstrap can be overkill, since it’s unused by a bootstrap. However,
29df5715
DM
14689when submitting patches, you should remove this option, to ensure that
14690the compiler can still bootstrap itself.
14691@end deffn
14692
14693@geindex command line option; --enable-checking=release
421d0d0f 14694@anchor{internals/index cmdoption-enable-checking}@anchor{388}
6f7585de 14695@deffn {Option} @w{-}@w{-}enable@w{-}checking=release
29df5715
DM
14696
14697The compile can perform extensive self-checking as it runs, useful when
14698debugging, but slowing things down.
14699
14700For maximum speed, configure with @code{--enable-checking=release} to
14701disable this self-checking.
14702@end deffn
14703
14704@node Running the test suite,Environment variables,Working on the JIT library,Internals
421d0d0f 14705@anchor{internals/index running-the-test-suite}@anchor{389}
29df5715
DM
14706@section Running the test suite
14707
14708
14709@example
14710[build] $ cd gcc
14711[gcc] $ make check-jit RUNTESTFLAGS="-v -v -v"
14712@end example
14713
29df5715
DM
14714A summary of the tests can then be seen in:
14715
14716@example
14717jit/build/gcc/testsuite/jit/jit.sum
14718@end example
14719
29df5715
DM
14720and detailed logs in:
14721
14722@example
14723jit/build/gcc/testsuite/jit/jit.log
14724@end example
14725
77f4ead7
DM
14726The test executables are normally deleted after each test is run. For
14727debugging, they can be preserved by setting
14728@geindex PRESERVE_EXECUTABLES
14729@geindex environment variable; PRESERVE_EXECUTABLES
14730@code{PRESERVE_EXECUTABLES}
14731in the environment. If so, they can then be seen as:
29df5715
DM
14732
14733@example
14734jit/build/gcc/testsuite/jit/*.exe
14735@end example
14736
29df5715
DM
14737which can be run independently.
14738
6f7585de 14739You can compile and run individual tests by passing “jit.exp=TESTNAME” to RUNTESTFLAGS e.g.:
29df5715
DM
14740
14741@example
77f4ead7
DM
14742[gcc] $ PRESERVE_EXECUTABLES= \
14743 make check-jit \
14744 RUNTESTFLAGS="-v -v -v jit.exp=test-factorial.c"
29df5715
DM
14745@end example
14746
29df5715
DM
14747and once a test has been compiled, you can debug it directly:
14748
14749@example
14750[gcc] $ PATH=.:$PATH \
14751 LD_LIBRARY_PATH=. \
14752 LIBRARY_PATH=. \
14753 gdb --args \
50bb6c8e 14754 testsuite/jit/test-factorial.c.exe
29df5715
DM
14755@end example
14756
29df5715
DM
14757@menu
14758* Running under valgrind::
14759
14760@end menu
14761
14762@node Running under valgrind,,,Running the test suite
421d0d0f 14763@anchor{internals/index running-under-valgrind}@anchor{38a}
29df5715
DM
14764@subsection Running under valgrind
14765
14766
77f4ead7
DM
14767The jit testsuite detects if
14768@geindex RUN_UNDER_VALGRIND
14769@geindex environment variable; RUN_UNDER_VALGRIND
14770@code{RUN_UNDER_VALGRIND} is present in the
29df5715 14771environment (with any value). If it is present, it runs the test client
786973ce 14772code under valgrind@footnote{https://valgrind.org},
29df5715 14773specifcally, the default
786973ce 14774memcheck@footnote{https://valgrind.org/docs/manual/mc-manual.html}
29df5715 14775tool with
786973ce 14776--leak-check=full@footnote{https://valgrind.org/docs/manual/mc-manual.html#opt.leak-check}.
29df5715
DM
14777
14778It automatically parses the output from valgrind, injecting XFAIL results if
14779any issues are found, or PASS results if the output is clean. The output
14780is saved to @code{TESTNAME.exe.valgrind.txt}.
14781
14782For example, the following invocation verbosely runs the testcase
14783@code{test-sum-of-squares.c} under valgrind, showing an issue:
14784
14785@example
14786$ RUN_UNDER_VALGRIND= \
14787 make check-jit \
14788 RUNTESTFLAGS="-v -v -v jit.exp=test-sum-of-squares.c"
14789
14790(...verbose log contains detailed valgrind errors, if any...)
14791
14792 === jit Summary ===
14793
14794# of expected passes 28
14795# of expected failures 2
14796
14797$ less testsuite/jit/jit.sum
14798(...other results...)
50bb6c8e
DM
14799XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: definitely lost: 8 bytes in 1 blocks
14800XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: unsuppressed errors: 1
29df5715
DM
14801(...other results...)
14802
50bb6c8e 14803$ less testsuite/jit/test-sum-of-squares.c.exe.valgrind.txt
29df5715 14804(...shows full valgrind report for this test case...)
2712de78
DM
14805@end example
14806
6f7585de 14807When running under valgrind, it’s best to have configured gcc with
2712de78
DM
14808@code{--enable-valgrind-annotations}, which automatically suppresses
14809various known false positives.
14810
18eb0d13 14811@node Environment variables,Packaging notes,Running the test suite,Internals
421d0d0f 14812@anchor{internals/index environment-variables}@anchor{38b}
35485da9
DM
14813@section Environment variables
14814
14815
14816When running client code against a locally-built libgccjit, three
14817environment variables need to be set up:
14818
14819@geindex environment variable; LD_LIBRARY_PATH
421d0d0f 14820@anchor{internals/index envvar-LD_LIBRARY_PATH}@anchor{38c}
35485da9
DM
14821@deffn {Environment Variable} LD_LIBRARY_PATH
14822
14823@quotation
14824
14825@cite{libgccjit.so} is dynamically linked into client code, so if running
14826against a locally-built library, @code{LD_LIBRARY_PATH} needs to be set
6f7585de 14827up appropriately. The library can be found within the “gcc”
35485da9
DM
14828subdirectory of the build tree:
14829@end quotation
14830
14831@example
14832$ file libgccjit.so*
14833libgccjit.so: symbolic link to `libgccjit.so.0'
14834libgccjit.so.0: symbolic link to `libgccjit.so.0.0.1'
14835libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, not stripped
14836@end example
35485da9
DM
14837@end deffn
14838
14839@geindex environment variable; PATH
421d0d0f 14840@anchor{internals/index envvar-PATH}@anchor{38d}
35485da9
DM
14841@deffn {Environment Variable} PATH
14842
14843The library uses a driver executable for converting from .s assembler
14844files to .so shared libraries. Specifically, it looks for a name
14845expanded from
14846@code{$@{target_noncanonical@}-gcc-$@{gcc_BASEVER@}$@{exeext@}}
14847such as @code{x86_64-unknown-linux-gnu-gcc-5.0.0}.
14848
14849Hence @code{PATH} needs to include a directory where the library can
14850locate this executable.
14851
14852The executable is normally installed to the installation bindir
6f7585de 14853(e.g. /usr/bin), but a copy is also created within the “gcc”
35485da9
DM
14854subdirectory of the build tree for running the testsuite, and for ease
14855of development.
14856@end deffn
14857
14858@geindex environment variable; LIBRARY_PATH
421d0d0f 14859@anchor{internals/index envvar-LIBRARY_PATH}@anchor{38e}
35485da9
DM
14860@deffn {Environment Variable} LIBRARY_PATH
14861
14862The driver executable invokes the linker, and the latter needs to locate
14863support libraries needed by the generated code, or you will see errors
14864like:
14865
14866@example
14867ld: cannot find crtbeginS.o: No such file or directory
14868ld: cannot find -lgcc
14869ld: cannot find -lgcc_s
14870@end example
14871
35485da9 14872Hence if running directly from a locally-built copy (without installing),
6f7585de 14873@code{LIBRARY_PATH} needs to contain the “gcc” subdirectory of the build
35485da9
DM
14874tree.
14875@end deffn
14876
14877For example, to run a binary that uses the library against a non-installed
14878build of the library in LIBGCCJIT_BUILD_DIR you need an invocation of the
14879client code like this, to preprend the dir to each of the environment
14880variables:
14881
14882@example
14883$ LD_LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LD_LIBRARY_PATH) \
14884 PATH=$(LIBGCCJIT_BUILD_DIR):$(PATH) \
14885 LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LIBRARY_PATH) \
14886 ./jit-hello-world
14887hello world
14888@end example
14889
18eb0d13 14890@node Packaging notes,Overview of code structure,Environment variables,Internals
421d0d0f 14891@anchor{internals/index packaging-notes}@anchor{38f}
18eb0d13
DM
14892@section Packaging notes
14893
14894
421d0d0f 14895The configure-time option @ref{385,,--enable-host-shared} is needed when
18eb0d13
DM
14896building the jit in order to get position-independent code. This will
14897slow down the regular compiler by a few percent. Hence when packaging gcc
14898with libgccjit, please configure and build twice:
14899
14900@quotation
14901
14902
14903@itemize *
14904
14905@item
421d0d0f 14906once without @ref{385,,--enable-host-shared} for most languages, and
18eb0d13
DM
14907
14908@item
421d0d0f 14909once with @ref{385,,--enable-host-shared} for the jit
18eb0d13
DM
14910@end itemize
14911@end quotation
14912
14913For example:
14914
14915@example
14916# Configure and build with --enable-host-shared
14917# for the jit:
14918mkdir configuration-for-jit
14919pushd configuration-for-jit
14920$(SRCDIR)/configure \
14921 --enable-host-shared \
14922 --enable-languages=jit \
14923 --prefix=$(DESTDIR)
14924make
14925popd
14926
14927# Configure and build *without* --enable-host-shared
14928# for maximum speed:
14929mkdir standard-configuration
14930pushd standard-configuration
14931$(SRCDIR)/configure \
14932 --enable-languages=all \
14933 --prefix=$(DESTDIR)
14934make
14935popd
14936
14937# Both of the above are configured to install to $(DESTDIR)
14938# Install the configuration with --enable-host-shared first
14939# *then* the one without, so that the faster build
14940# of "cc1" et al overwrites the slower build.
14941pushd configuration-for-jit
14942make install
14943popd
14944
14945pushd standard-configuration
14946make install
14947popd
14948@end example
14949
18eb0d13 14950@node Overview of code structure,Design notes,Packaging notes,Internals
421d0d0f 14951@anchor{internals/index overview-of-code-structure}@anchor{390}
35485da9
DM
14952@section Overview of code structure
14953
14954
1470e75f
DM
14955The library is implemented in C++. The source files have the @code{.c}
14956extension for legacy reasons.
14957
35485da9
DM
14958
14959@itemize *
14960
14961@item
14962@code{libgccjit.c} implements the API entrypoints. It performs error
14963checking, then calls into classes of the gcc::jit::recording namespace
14964within @code{jit-recording.c} and @code{jit-recording.h}.
14965
14966@item
14967The gcc::jit::recording classes (within @code{jit-recording.c} and
14968@code{jit-recording.h}) record the API calls that are made:
14969
14970@quotation
14971
14972@example
14973
14974 /* Indentation indicates inheritance: */
14975 class context;
35485da9
DM
14976 class memento;
14977 class string;
14978 class location;
14979 class type;
14980 class function_type;
14981 class compound_type;
14982 class struct_;
14983 class union_;
6069fe72 14984 class vector_type;
35485da9 14985 class field;
6f7585de 14986 class bitfield;
35485da9
DM
14987 class fields;
14988 class function;
14989 class block;
14990 class rvalue;
14991 class lvalue;
14992 class local;
14993 class global;
14994 class param;
0ebd1f00 14995 class base_call;
15a65e63 14996 class function_pointer;
35485da9 14997 class statement;
421d0d0f 14998 class extended_asm;
ec5d0088 14999 class case_;
421d0d0f 15000 class top_level_asm;
35485da9 15001
35485da9 15002@end example
35485da9
DM
15003@end quotation
15004
15005@item
15006When the context is compiled, the gcc::jit::playback classes (within
15007@code{jit-playback.c} and @code{jit-playback.h}) replay the API calls
15008within langhook:parse_file:
15009
15010@quotation
15011
15012@example
15013
15014 /* Indentation indicates inheritance: */
15015 class context;
15016 class wrapper;
15017 class type;
15018 class compound_type;
15019 class field;
15020 class function;
15021 class block;
15022 class rvalue;
15023 class lvalue;
15024 class param;
15025 class source_file;
15026 class source_line;
15027 class location;
ec5d0088 15028 class case_;
35485da9 15029
35485da9
DM
15030@end example
15031
35485da9
DM
15032@example
15033Client Code . Generated . libgccjit.so
15034 . code .
15035 . . JIT API . JIT "Frontend". (libbackend.a)
15036....................................................................................
15037 │ . . . .
15038 ──────────────────────────> . .
15039 . . │ . .
15040 . . V . .
15041 . . ──> libgccjit.c .
15042 . . │ (error-checking).
15043 . . │ .
15044 . . ──> jit-recording.c
15045 . . (record API calls)
15046 . . <─────── .
15047 . . │ . .
15048 <─────────────────────────── . .
15049 │ . . . .
15050 │ . . . .
15051 V . . gcc_jit_context_compile .
15052 ──────────────────────────> . .
463366a0 15053 . . │ start of recording::context::compile ()
35485da9 15054 . . │ . .
463366a0
DM
15055 . . │ start of playback::context::compile ()
15056 . . │ (create tempdir) .
15057 . . │ . .
2712de78
DM
15058 . . │ ACQUIRE MUTEX .
15059 . . │ . .
35485da9
DM
15060 . . V───────────────────────> toplev::main (for now)
15061 . . . . │
15062 . . . . (various code)
15063 . . . . │
15064 . . . . V
15065 . . . <───────────────── langhook:parse_file
15066 . . . │ .
15067 . . . │ (jit_langhook_parse_file)
15068 . . . │ .
15069..........................................│..................VVVVVVVVVVVVV...
15070 . . . │ . No GC in here
15071 . . . │ jit-playback.c
15072 . . . │ (playback of API calls)
15073 . . . ───────────────> creation of functions,
15074 . . . . types, expression trees
15075 . . . <──────────────── etc
15076 . . . │(handle_locations: add locations to
15077 . . . │ linemap and associate them with trees)
15078 . . . │ .
15079 . . . │ . No GC in here
15080..........................................│..................AAAAAAAAAAAAA...
15081 . . . │ for each function
15082 . . . ──> postprocess
15083 . . . │ .
15084 . . . ────────────> cgraph_finalize_function
15085 . . . <────────────
15086 . . . <── .
15087 . . . │ .
15088 . . . ──────────────────> (end of
15089 . . . . │ langhook_parse_file)
15090 . . . . │
15091 . . . . (various code)
15092 . . . . │
15093 . . . . ↓
15094 . . . <───────────────── langhook:write_globals
15095 . . . │ .
15096 . . . │ (jit_langhook_write_globals)
15097 . . . │ .
15098 . . . │ .
15099 . . . ──────────────────> finalize_compilation_unit
15100 . . . . │
15101 . . . . (the middle─end and backend)
15102 . . . . ↓
15103 . . <───────────────────────────── end of toplev::main
35485da9 15104 . . │ . .
463366a0
DM
15105 . . V───────────────────────> toplev::finalize
15106 . . . . │ (purge internal state)
15107 . . <──────────────────────── end of toplev::finalize
15108 . . │ . .
fdce7209
DM
15109 . . V─> playback::context::postprocess:
15110 . . │ . .
15111 . . │ (assuming an in-memory compile):
15112 . . │ . .
199501ea
DM
15113 . . --> Convert assembler to DSO, via embedded
15114 . . copy of driver:
15115 . . driver::main ()
15116 . . invocation of "as"
15117 . . invocation of "ld"
15118 . . driver::finalize ()
15119 . . <----
fdce7209
DM
15120 . . │ . .
15121 . . │ . Load DSO (dlopen "fake.so")
15122 . . │ . .
15123 . . │ . Bundle it up in a jit::result
15124 . . <── . .
463366a0 15125 . . │ . .
2712de78
DM
15126 . . │ RELEASE MUTEX .
15127 . . │ . .
463366a0
DM
15128 . . │ end of playback::context::compile ()
15129 . . │ . .
15130 . . │ playback::context dtor
15131 . . ──> . .
d2286af3 15132 . . │ Normally we cleanup the tempdir here:
463366a0
DM
15133 . . │ ("fake.so" is unlinked from the
15134 . . │ filesystem at this point)
d2286af3
DM
15135 . . │ If the client code requested debuginfo, the
15136 . . │ cleanup happens later (in gcc_jit_result_release)
15137 . . │ to make it easier on the debugger (see PR jit/64206)
463366a0
DM
15138 . . <── . .
15139 . . │ . .
463366a0 15140 . . │ end of recording::context::compile ()
35485da9
DM
15141 <─────────────────────────── . .
15142 │ . . . .
463366a0
DM
15143 V . . gcc_jit_result_get_code .
15144 ──────────────────────────> . .
15145 . . │ dlsym () within loaded DSO
15146 <─────────────────────────── . .
35485da9
DM
15147 Get (void*). . . .
15148 │ . . . .
15149 │ Call it . . . .
15150 ───────────────> . . .
15151 . │ . . .
15152 . │ . . .
15153 <─────────────── . . .
15154 │ . . . .
463366a0
DM
15155etc│ . . . .
15156 │ . . . .
15157 V . . gcc_jit_result_release .
15158 ──────────────────────────> . .
15159 . . │ dlclose () the loaded DSO
15160 . . │ (code becomes uncallable)
d2286af3
DM
15161 . . │ . .
15162 . . │ If the client code requested debuginfo, then
15163 . . │ cleanup of the tempdir was delayed.
15164 . . │ If that was the case, clean it up now.
463366a0 15165 <─────────────────────────── . .
35485da9 15166 │ . . . .
35485da9 15167@end example
35485da9
DM
15168@end quotation
15169@end itemize
15170
15171Here is a high-level summary from @code{jit-common.h}:
15172
15173@quotation
15174
15175In order to allow jit objects to be usable outside of a compile
6f7585de 15176whilst working with the existing structure of GCC’s code the
35485da9
DM
15177C API is implemented in terms of a gcc::jit::recording::context,
15178which records the calls made to it.
15179
15180When a gcc_jit_context is compiled, the recording context creates a
15181playback context. The playback context invokes the bulk of the GCC
6f7585de 15182code, and within the “frontend” parsing hook, plays back the recorded
35485da9
DM
15183API calls, creating GCC tree objects.
15184
15185So there are two parallel families of classes: those relating to
15186recording, and those relating to playback:
15187
15188
15189@itemize *
15190
15191@item
15192Visibility: recording objects are exposed back to client code,
15193whereas playback objects are internal to the library.
15194
15195@item
15196Lifetime: recording objects have a lifetime equal to that of the
15197recording context that created them, whereas playback objects only
15198exist within the frontend hook.
15199
15200@item
15201Memory allocation: recording objects are allocated by the recording
15202context, and automatically freed by it when the context is released,
15203whereas playback objects are allocated within the GC heap, and
15204garbage-collected; they can own GC-references.
15205
15206@item
15207Integration with rest of GCC: recording objects are unrelated to the
6f7585de
DM
15208rest of GCC, whereas playback objects are wrappers around “tree”
15209instances. Hence you can’t ask a recording rvalue or lvalue what its
35485da9
DM
15210type is, whereas you can for a playback rvalue of lvalue (since it
15211can work with the underlying GCC tree nodes).
15212
15213@item
6f7585de 15214Instancing: There can be multiple recording contexts “alive” at once
35485da9
DM
15215(albeit it only one compiling at once), whereas there can only be one
15216playback context alive at one time (since it interacts with the GC).
15217@end itemize
15218
15219Ultimately if GCC could support multiple GC heaps and contexts, and
15220finer-grained initialization, then this recording vs playback
15221distinction could be eliminated.
15222
15223During a playback, we associate objects from the recording with
15224their counterparts during this playback. For simplicity, we store this
15225within the recording objects, as @code{void *m_playback_obj}, casting it to
15226the appropriate playback object subclass. For these casts to make
15227sense, the two class hierarchies need to have the same structure.
15228
15229Note that the playback objects that @code{m_playback_obj} points to are
6f7585de 15230GC-allocated, but the recording objects don’t own references:
35485da9 15231these associations only exist within a part of the code where
6f7585de 15232the GC doesn’t collect, and are set back to NULL before the GC can
35485da9
DM
15233run.
15234@end quotation
fdce7209 15235@anchor{internals/index example-of-log-file}@anchor{5c}
eb4c16eb 15236Another way to understand the structure of the code is to enable logging,
6f7585de 15237via @ref{5b,,gcc_jit_context_set_logfile()}. Here is an example of a log
eb4c16eb
DM
15238generated via this call:
15239
15240@example
199501ea 15241JIT: libgccjit (GCC) version 6.0.0 20150803 (experimental) (x86_64-pc-linux-gnu)
53c04ec9 15242JIT: compiled by GNU C version 4.8.3 20140911 (Red Hat 4.8.3-7), GMP version 5.1.2, MPFR version 3.1.2, MPC version 1.0.1
eb4c16eb 15243JIT: entering: gcc_jit_context_set_str_option
0ed4f017 15244JIT: GCC_JIT_STR_OPTION_PROGNAME: "./test-hello-world.c.exe"
eb4c16eb
DM
15245JIT: exiting: gcc_jit_context_set_str_option
15246JIT: entering: gcc_jit_context_set_int_option
0ed4f017 15247JIT: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL: 3
eb4c16eb
DM
15248JIT: exiting: gcc_jit_context_set_int_option
15249JIT: entering: gcc_jit_context_set_bool_option
0ed4f017 15250JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO: true
eb4c16eb
DM
15251JIT: exiting: gcc_jit_context_set_bool_option
15252JIT: entering: gcc_jit_context_set_bool_option
0ed4f017 15253JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE: false
eb4c16eb
DM
15254JIT: exiting: gcc_jit_context_set_bool_option
15255JIT: entering: gcc_jit_context_set_bool_option
0ed4f017 15256JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE: false
eb4c16eb
DM
15257JIT: exiting: gcc_jit_context_set_bool_option
15258JIT: entering: gcc_jit_context_set_bool_option
0ed4f017 15259JIT: GCC_JIT_BOOL_OPTION_SELFCHECK_GC: true
eb4c16eb
DM
15260JIT: exiting: gcc_jit_context_set_bool_option
15261JIT: entering: gcc_jit_context_set_bool_option
0ed4f017 15262JIT: GCC_JIT_BOOL_OPTION_DUMP_SUMMARY: false
eb4c16eb
DM
15263JIT: exiting: gcc_jit_context_set_bool_option
15264JIT: entering: gcc_jit_context_get_type
15265JIT: exiting: gcc_jit_context_get_type
15266JIT: entering: gcc_jit_context_get_type
15267JIT: exiting: gcc_jit_context_get_type
15268JIT: entering: gcc_jit_context_new_param
15269JIT: exiting: gcc_jit_context_new_param
15270JIT: entering: gcc_jit_context_new_function
15271JIT: exiting: gcc_jit_context_new_function
15272JIT: entering: gcc_jit_context_new_param
15273JIT: exiting: gcc_jit_context_new_param
15274JIT: entering: gcc_jit_context_get_type
15275JIT: exiting: gcc_jit_context_get_type
15276JIT: entering: gcc_jit_context_new_function
15277JIT: exiting: gcc_jit_context_new_function
15278JIT: entering: gcc_jit_context_new_string_literal
15279JIT: exiting: gcc_jit_context_new_string_literal
15280JIT: entering: gcc_jit_function_new_block
15281JIT: exiting: gcc_jit_function_new_block
15282JIT: entering: gcc_jit_block_add_comment
15283JIT: exiting: gcc_jit_block_add_comment
15284JIT: entering: gcc_jit_context_new_call
15285JIT: exiting: gcc_jit_context_new_call
15286JIT: entering: gcc_jit_block_add_eval
15287JIT: exiting: gcc_jit_block_add_eval
15288JIT: entering: gcc_jit_block_end_with_void_return
15289JIT: exiting: gcc_jit_block_end_with_void_return
fdce7209
DM
15290JIT: entering: gcc_jit_context_dump_reproducer_to_file
15291JIT: entering: void gcc::jit::recording::context::dump_reproducer_to_file(const char*)
15292JIT: exiting: void gcc::jit::recording::context::dump_reproducer_to_file(const char*)
15293JIT: exiting: gcc_jit_context_dump_reproducer_to_file
eb4c16eb 15294JIT: entering: gcc_jit_context_compile
fdce7209 15295JIT: in-memory compile of ctxt: 0x1283e20
eb4c16eb 15296JIT: entering: gcc::jit::result* gcc::jit::recording::context::compile()
0ed4f017
DM
15297JIT: GCC_JIT_STR_OPTION_PROGNAME: "./test-hello-world.c.exe"
15298JIT: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL: 3
15299JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO: true
15300JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE: false
15301JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE: false
15302JIT: GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE: false
15303JIT: GCC_JIT_BOOL_OPTION_DUMP_SUMMARY: false
15304JIT: GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING: false
15305JIT: GCC_JIT_BOOL_OPTION_SELFCHECK_GC: true
15306JIT: GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES: false
eb3982c1 15307JIT: gcc_jit_context_set_bool_allow_unreachable_blocks: false
199501ea 15308JIT: gcc_jit_context_set_bool_use_external_driver: false
eb4c16eb
DM
15309JIT: entering: void gcc::jit::recording::context::validate()
15310JIT: exiting: void gcc::jit::recording::context::validate()
15311JIT: entering: gcc::jit::playback::context::context(gcc::jit::recording::context*)
15312JIT: exiting: gcc::jit::playback::context::context(gcc::jit::recording::context*)
fdce7209
DM
15313JIT: entering: gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*)
15314JIT: exiting: gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*)
15315JIT: entering: void gcc::jit::playback::context::compile()
d2286af3
DM
15316JIT: entering: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int)
15317JIT: exiting: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int)
15318JIT: entering: bool gcc::jit::tempdir::create()
15319JIT: m_path_template: /tmp/libgccjit-XXXXXX
15320JIT: m_path_tempdir: /tmp/libgccjit-CKq1M9
15321JIT: exiting: bool gcc::jit::tempdir::create()
eb4c16eb
DM
15322JIT: entering: void gcc::jit::playback::context::acquire_mutex()
15323JIT: exiting: void gcc::jit::playback::context::acquire_mutex()
2cb844ce
DM
15324JIT: entering: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*)
15325JIT: reusing cached configure-time options
15326JIT: configure_time_options[0]: -mtune=generic
15327JIT: configure_time_options[1]: -march=x86-64
15328JIT: exiting: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*)
eb4c16eb
DM
15329JIT: entering: toplev::main
15330JIT: argv[0]: ./test-hello-world.c.exe
15331JIT: argv[1]: /tmp/libgccjit-CKq1M9/fake.c
15332JIT: argv[2]: -fPIC
15333JIT: argv[3]: -O3
15334JIT: argv[4]: -g
15335JIT: argv[5]: -quiet
15336JIT: argv[6]: --param
15337JIT: argv[7]: ggc-min-expand=0
15338JIT: argv[8]: --param
15339JIT: argv[9]: ggc-min-heapsize=0
2cb844ce
DM
15340JIT: argv[10]: -mtune=generic
15341JIT: argv[11]: -march=x86-64
eb4c16eb
DM
15342JIT: entering: bool jit_langhook_init()
15343JIT: exiting: bool jit_langhook_init()
15344JIT: entering: void gcc::jit::playback::context::replay()
15345JIT: entering: void gcc::jit::recording::context::replay_into(gcc::jit::replayer*)
15346JIT: exiting: void gcc::jit::recording::context::replay_into(gcc::jit::replayer*)
15347JIT: entering: void gcc::jit::recording::context::disassociate_from_playback()
15348JIT: exiting: void gcc::jit::recording::context::disassociate_from_playback()
15349JIT: entering: void gcc::jit::playback::context::handle_locations()
15350JIT: exiting: void gcc::jit::playback::context::handle_locations()
15351JIT: entering: void gcc::jit::playback::function::build_stmt_list()
15352JIT: exiting: void gcc::jit::playback::function::build_stmt_list()
15353JIT: entering: void gcc::jit::playback::function::build_stmt_list()
15354JIT: exiting: void gcc::jit::playback::function::build_stmt_list()
15355JIT: entering: void gcc::jit::playback::function::postprocess()
15356JIT: exiting: void gcc::jit::playback::function::postprocess()
15357JIT: entering: void gcc::jit::playback::function::postprocess()
15358JIT: exiting: void gcc::jit::playback::function::postprocess()
15359JIT: exiting: void gcc::jit::playback::context::replay()
eb4c16eb
DM
15360JIT: exiting: toplev::main
15361JIT: entering: void gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*)
15362JIT: exiting: void gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*)
15363JIT: entering: toplev::finalize
15364JIT: exiting: toplev::finalize
fdce7209
DM
15365JIT: entering: virtual void gcc::jit::playback::compile_to_memory::postprocess(const char*)
15366JIT: entering: void gcc::jit::playback::context::convert_to_dso(const char*)
15367JIT: entering: void gcc::jit::playback::context::invoke_driver(const char*, const char*, const char*, timevar_id_t, bool, bool)
eb3982c1
DM
15368JIT: entering: void gcc::jit::playback::context::add_multilib_driver_arguments(vec<char*>*)
15369JIT: exiting: void gcc::jit::playback::context::add_multilib_driver_arguments(vec<char*>*)
15370JIT: argv[0]: x86_64-unknown-linux-gnu-gcc-6.0.0
15371JIT: argv[1]: -m64
15372JIT: argv[2]: -shared
15373JIT: argv[3]: /tmp/libgccjit-CKq1M9/fake.s
15374JIT: argv[4]: -o
15375JIT: argv[5]: /tmp/libgccjit-CKq1M9/fake.so
15376JIT: argv[6]: -fno-use-linker-plugin
199501ea
DM
15377JIT: entering: void gcc::jit::playback::context::invoke_embedded_driver(const vec<char*>*)
15378JIT: exiting: void gcc::jit::playback::context::invoke_embedded_driver(const vec<char*>*)
fdce7209
DM
15379JIT: exiting: void gcc::jit::playback::context::invoke_driver(const char*, const char*, const char*, timevar_id_t, bool, bool)
15380JIT: exiting: void gcc::jit::playback::context::convert_to_dso(const char*)
15381JIT: entering: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso()
15382JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO was set: handing over tempdir to jit::result
15383JIT: entering: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*)
15384JIT: exiting: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*)
15385JIT: exiting: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso()
15386JIT: exiting: virtual void gcc::jit::playback::compile_to_memory::postprocess(const char*)
eb4c16eb
DM
15387JIT: entering: void gcc::jit::playback::context::release_mutex()
15388JIT: exiting: void gcc::jit::playback::context::release_mutex()
fdce7209 15389JIT: exiting: void gcc::jit::playback::context::compile()
eb4c16eb
DM
15390JIT: entering: gcc::jit::playback::context::~context()
15391JIT: exiting: gcc::jit::playback::context::~context()
15392JIT: exiting: gcc::jit::result* gcc::jit::recording::context::compile()
15393JIT: gcc_jit_context_compile: returning (gcc_jit_result *)0x12f75d0
15394JIT: exiting: gcc_jit_context_compile
15395JIT: entering: gcc_jit_result_get_code
15396JIT: locating fnname: hello_world
15397JIT: entering: void* gcc::jit::result::get_code(const char*)
15398JIT: exiting: void* gcc::jit::result::get_code(const char*)
15399JIT: gcc_jit_result_get_code: returning (void *)0x7ff6b8cd87f0
15400JIT: exiting: gcc_jit_result_get_code
15401JIT: entering: gcc_jit_context_release
15402JIT: deleting ctxt: 0x1283e20
15403JIT: entering: gcc::jit::recording::context::~context()
15404JIT: exiting: gcc::jit::recording::context::~context()
15405JIT: exiting: gcc_jit_context_release
15406JIT: entering: gcc_jit_result_release
15407JIT: deleting result: 0x12f75d0
15408JIT: entering: virtual gcc::jit::result::~result()
d2286af3
DM
15409JIT: entering: gcc::jit::tempdir::~tempdir()
15410JIT: unlinking .s file: /tmp/libgccjit-CKq1M9/fake.s
15411JIT: unlinking .so file: /tmp/libgccjit-CKq1M9/fake.so
15412JIT: removing tempdir: /tmp/libgccjit-CKq1M9
15413JIT: exiting: gcc::jit::tempdir::~tempdir()
eb4c16eb
DM
15414JIT: exiting: virtual gcc::jit::result::~result()
15415JIT: exiting: gcc_jit_result_release
15416JIT: gcc::jit::logger::~logger()
eb4c16eb
DM
15417@end example
15418
1470e75f 15419@node Design notes,Submitting patches,Overview of code structure,Internals
421d0d0f 15420@anchor{internals/index design-notes}@anchor{391}
86d0ac88
DM
15421@section Design notes
15422
15423
15424It should not be possible for client code to cause an internal compiler
15425error. If this @emph{does} happen, the root cause should be isolated (perhaps
6f7585de 15426using @ref{5d,,gcc_jit_context_dump_reproducer_to_file()}) and the cause
86d0ac88
DM
15427should be rejected via additional checking. The checking ideally should
15428be within the libgccjit API entrypoints in libgccjit.c, since this is as
15429close as possible to the error; failing that, a good place is within
15430@code{recording::context::validate ()} in jit-recording.c.
15431
1470e75f 15432@node Submitting patches,,Design notes,Internals
421d0d0f 15433@anchor{internals/index submitting-patches}@anchor{392}
1470e75f
DM
15434@section Submitting patches
15435
15436
15437Please read the contribution guidelines for gcc at
15438@indicateurl{https://gcc.gnu.org/contribute.html}.
15439
15440Patches for the jit should be sent to both the
15441@email{gcc-patches@@gcc.gnu.org} and @email{jit@@gcc.gnu.org} mailing lists,
6f7585de 15442with “jit” and “PATCH” in the Subject line.
1470e75f 15443
6f7585de 15444You don’t need to do a full bootstrap for code that just touches the
1470e75f
DM
15445@code{jit} and @code{testsuite/jit.dg} subdirectories. However, please run
15446@code{make check-jit} before submitting the patch, and mention the results
15447in your email (along with the host triple that the tests were run on).
15448
15449A good patch should contain the information listed in the
15450gcc contribution guide linked to above; for a @code{jit} patch, the patch
15451shold contain:
15452
15453@quotation
15454
15455
15456@itemize *
15457
15458@item
15459the code itself (for example, a new API entrypoint will typically
15460touch @code{libgccjit.h} and @code{.c}, along with support code in
15461@code{jit-recording.[ch]} and @code{jit-playback.[ch]} as appropriate)
15462
15463@item
15464test coverage
15465
15466@item
15467documentation for the C API
15468
15469@item
15470documentation for the C++ API
15471@end itemize
15472@end quotation
15473
15474A patch that adds new API entrypoints should also contain:
15475
15476@quotation
15477
15478
15479@itemize *
15480
15481@item
6f7585de
DM
15482a feature macro in @code{libgccjit.h} so that client code that doesn’t
15483use a “configure” mechanism can still easily detect the presence of
1470e75f
DM
15484the entrypoint. See e.g. @code{LIBGCCJIT_HAVE_SWITCH_STATEMENTS} (for
15485a category of entrypoints) and
15486@code{LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks}
15487(for an individual entrypoint).
15488
15489@item
15490a new ABI tag containing the new symbols (in @code{libgccjit.map}), so
15491that we can detect client code that uses them
15492
15493@item
6f7585de 15494Support for @ref{5d,,gcc_jit_context_dump_reproducer_to_file()}. Most
1470e75f
DM
15495jit testcases attempt to dump their contexts to a .c file; @code{jit.exp}
15496then sanity-checks the generated c by compiling them (though
15497not running them). A new API entrypoint
6f7585de 15498needs to “know” how to write itself back out to C (by implementing
1470e75f
DM
15499@code{gcc::jit::recording::memento::write_reproducer} for the appropriate
15500@code{memento} subclass).
15501
15502@item
15503C++ bindings for the new entrypoints (see @code{libgccjit++.h}); ideally
15504with test coverage, though the C++ API test coverage is admittedly
15505spotty at the moment
15506
15507@item
15508documentation for the new C entrypoints
15509
15510@item
15511documentation for the new C++ entrypoints
15512
15513@item
15514documentation for the new ABI tag (see @code{topics/compatibility.rst}).
15515@end itemize
15516@end quotation
15517
15518Depending on the patch you can either extend an existing test case, or
15519add a new test case. If you add an entirely new testcase: @code{jit.exp}
15520expects jit testcases to begin with @code{test-}, or @code{test-error-} (for a
6f7585de 15521testcase that generates an error on a @ref{8,,gcc_jit_context}).
1470e75f 15522
6f7585de 15523Every new testcase that doesn’t generate errors should also touch
1470e75f
DM
15524@code{gcc/testsuite/jit.dg/all-non-failing-tests.h}:
15525
15526@quotation
15527
15528
15529@itemize *
15530
15531@item
6f7585de 15532Testcases that don’t generate errors should ideally be added to the
1470e75f
DM
15533@code{testcases} array in that file; this means that, in addition
15534to being run standalone, they also get run within
15535@code{test-combination.c} (which runs all successful tests inside one
6f7585de 15536big @ref{8,,gcc_jit_context}), and @code{test-threads.c} (which runs all
1470e75f 15537successful tests in one process, each one running in a different
6f7585de 15538thread on a different @ref{8,,gcc_jit_context}).
1470e75f
DM
15539
15540@cartouche
15541@quotation Note
6f7585de 15542Given that exported functions within a @ref{8,,gcc_jit_context}
1470e75f
DM
15543must have unique names, and most testcases are run within
15544@code{test-combination.c}, this means that every jit-compiled test
6f7585de 15545function typically needs a name that’s unique across the entire
1470e75f
DM
15546test suite.
15547@end quotation
15548@end cartouche
15549
15550@item
6f7585de
DM
15551Testcases that aren’t to be added to the @code{testcases} array should
15552instead add a comment to the file clarifying why they’re not in that
1470e75f
DM
15553array. See the file for examples.
15554@end itemize
15555@end quotation
15556
15557Typically a patch that touches the .rst documentation will also need the
15558texinfo to be regenerated. You can do this with
786973ce 15559Sphinx 1.0@footnote{https://sphinx-doc.org/} or later by
6f7585de 15560running @code{make texinfo} within @code{SRCDIR/gcc/jit/docs}. Don’t do this
1470e75f
DM
15561within the patch sent to the mailing list; it can often be relatively
15562large and inconsequential (e.g. anchor renumbering), rather like generated
6f7585de 15563“configure” changes from configure.ac. You can regenerate it when
1470e75f
DM
15564committing to svn.
15565
35485da9 15566@node Indices and tables,Index,Internals,Top
421d0d0f 15567@anchor{index indices-and-tables}@anchor{393}
35485da9
DM
15568@unnumbered Indices and tables
15569
15570
15571
15572@itemize *
15573
15574@item
6f7585de 15575genindex
35485da9
DM
15576
15577@item
6f7585de 15578modindex
35485da9
DM
15579
15580@item
6f7585de 15581search
35485da9
DM
15582@end itemize
15583
15584@c Some notes:
15585@c
15586@c The Sphinx C domain appears to lack explicit support for enum values,
15587@c so I've been using :c:macro: for them.
15588@c
786973ce 15589@c See https://sphinx-doc.org/domains.html#the-c-domain
35485da9
DM
15590
15591@node Index,,Indices and tables,Top
15592@unnumbered Index
15593
15594
15595@printindex ge
15596
6f7585de 15597
35485da9
DM
15598@c %**end of body
15599@bye