]> 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
863e76f9 1\input texinfo @c -*-texinfo-*-
2@c %**start of header
3@setfilename libgccjit.info
4@documentencoding UTF-8
5@ifinfo
6@*Generated by Sphinx 1.1.3.@*
7@end ifinfo
8@settitle libgccjit Documentation
9@defindex ge
10@paragraphindent 2
11@exampleindent 4
12@afourlatex
13@dircategory Miscellaneous
14@direntry
15* libgccjit: (libgccjit.info). One line description of project.
16@end direntry
17
18@c %**end of header
19
20@copying
21@quotation
17c0b84b 22libgccjit 6.0.0 (experimental 20150803), August 03, 2015
863e76f9 23
24David Malcolm
25
f1717362 26Copyright @copyright{} 2014-2016 Free Software Foundation, Inc.
863e76f9 27@end quotation
28
29@end copying
30
31@titlepage
32@title libgccjit Documentation
33@insertcopying
34@end titlepage
35@contents
36
37@c %** start of user preamble
38
39@c %** end of user preamble
40
41@ifnottex
42@node Top
43@top libgccjit Documentation
44@insertcopying
45@end ifnottex
46
47@c %**start of body
48@anchor{index doc}@anchor{0}
f1717362 49@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 50@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
51@c
52@c This is free software: you can redistribute it and/or modify it
53@c under the terms of the GNU General Public License as published by
54@c the Free Software Foundation, either version 3 of the License, or
55@c (at your option) any later version.
56@c
57@c This program is distributed in the hope that it will be useful, but
58@c WITHOUT ANY WARRANTY; without even the implied warranty of
59@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
60@c General Public License for more details.
61@c
62@c You should have received a copy of the GNU General Public License
63@c along with this program. If not, see
64@c <http://www.gnu.org/licenses/>.
65
36b809a0 66This document describes libgccjit@footnote{http://gcc.gnu.org/wiki/JIT}, an API
67for embedding GCC inside programs and libraries.
68
69Note that libgccjit is currently of "Alpha" quality;
70the APIs are not yet set in stone, and they shouldn't be used in
71production yet.
72
73There are actually two APIs for the library:
74
75
76@itemize *
77
78@item
79a pure C API: @code{libgccjit.h}
80
81@item
82a C++ wrapper API: @code{libgccjit++.h}. This is a collection of "thin"
83wrapper classes around the C API, to save typing.
84@end itemize
85
863e76f9 86Contents:
87
f1717362 88@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 89@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
90@c
91@c This is free software: you can redistribute it and/or modify it
92@c under the terms of the GNU General Public License as published by
93@c the Free Software Foundation, either version 3 of the License, or
94@c (at your option) any later version.
95@c
96@c This program is distributed in the hope that it will be useful, but
97@c WITHOUT ANY WARRANTY; without even the implied warranty of
98@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
99@c General Public License for more details.
100@c
101@c You should have received a copy of the GNU General Public License
102@c along with this program. If not, see
103@c <http://www.gnu.org/licenses/>.
104
105@menu
106* Tutorial::
107* Topic Reference::
36b809a0 108* C++ bindings for libgccjit::
863e76f9 109* Internals::
110* Indices and tables::
111* Index::
112
113@detailmenu
114 --- The Detailed Node Listing ---
115
116Tutorial
117
118* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world".
119* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function.
120* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables.
121* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter.
69834ed9 122* Tutorial part 5; Implementing an Ahead-of-Time compiler: Tutorial part 5 Implementing an Ahead-of-Time compiler.
863e76f9 123
124Tutorial part 2: Creating a trivial machine code function
125
eac6fba2 126* Error-handling::
863e76f9 127* Options::
128* Full example::
129
130Tutorial part 3: Loops and variables
131
132* Expressions; lvalues and rvalues: Expressions lvalues and rvalues.
133* Control flow::
134* Visualizing the control flow graph::
135* Full example: Full example<2>.
136
137Tutorial part 4: Adding JIT-compilation to a toy interpreter
138
139* Our toy interpreter::
140* Compiling to machine code::
141* Setting things up::
142* Populating the function::
143* Verifying the control flow graph::
144* Compiling the context::
145* Single-stepping through the generated code::
146* Examining the generated code::
147* Putting it all together::
148* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?.
149
150Behind the curtain: How does our code get optimized?
151
152* Optimizing away stack manipulation::
153* Elimination of tail recursion::
154
69834ed9 155Tutorial part 5: Implementing an Ahead-of-Time compiler
156
157* The "brainf" language::
158* Converting a brainf script to libgccjit IR::
159* Compiling a context to a file::
160* Other forms of ahead-of-time-compilation::
161
863e76f9 162Topic Reference
163
164* Compilation contexts::
165* Objects::
166* Types::
167* Expressions::
168* Creating and using functions::
169* Source Locations::
69834ed9 170* Compiling a context::
adb2df55 171* ABI and API compatibility::
17c0b84b 172* Performance::
863e76f9 173
174Compilation contexts
175
176* Lifetime-management::
177* Thread-safety::
eac6fba2 178* Error-handling: Error-handling<2>.
863e76f9 179* Debugging::
180* Options: Options<2>.
181
182Options
183
184* String Options::
185* Boolean options::
186* Integer options::
adb2df55 187* Additional command-line options::
863e76f9 188
189Types
190
191* Standard types::
192* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile.
193* Structures and unions::
194
195Expressions
196
197* Rvalues::
198* Lvalues::
199* Working with pointers@comma{} structs and unions: Working with pointers structs and unions.
200
201Rvalues
202
203* Simple expressions::
204* Unary Operations::
205* Binary Operations::
206* Comparisons::
207* Function calls::
208* Type-coercion::
209
210Lvalues
211
212* Global variables::
213
214Creating and using functions
215
216* Params::
217* Functions::
218* Blocks::
219* Statements::
220
221Source Locations
222
223* Faking it::
224
69834ed9 225Compiling a context
226
227* In-memory compilation::
228* Ahead-of-time compilation::
229
adb2df55 230ABI and API compatibility
231
232* ABI symbol tags::
233
234ABI symbol tags
235
236* LIBGCCJIT_ABI_0::
237* LIBGCCJIT_ABI_1::
04feb56e 238* LIBGCCJIT_ABI_2::
a24ef8d2 239* LIBGCCJIT_ABI_3::
17c0b84b 240* LIBGCCJIT_ABI_4::
241
242Performance
243
244* The timing API::
adb2df55 245
36b809a0 246C++ bindings for libgccjit
247
248* Tutorial: Tutorial<2>.
249* Topic Reference: Topic Reference<2>.
250
251Tutorial
252
253* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world"<2>.
254* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>.
255* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>.
256* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>.
257
258Tutorial part 2: Creating a trivial machine code function
259
260* Options: Options<3>.
261* Full example: Full example<3>.
262
263Tutorial part 3: Loops and variables
264
265* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>.
266* Control flow: Control flow<2>.
267* Visualizing the control flow graph: Visualizing the control flow graph<2>.
268* Full example: Full example<4>.
269
270Tutorial part 4: Adding JIT-compilation to a toy interpreter
271
272* Our toy interpreter: Our toy interpreter<2>.
273* Compiling to machine code: Compiling to machine code<2>.
274* Setting things up: Setting things up<2>.
275* Populating the function: Populating the function<2>.
276* Verifying the control flow graph: Verifying the control flow graph<2>.
277* Compiling the context: Compiling the context<2>.
278* Single-stepping through the generated code: Single-stepping through the generated code<2>.
279* Examining the generated code: Examining the generated code<2>.
280* Putting it all together: Putting it all together<2>.
281* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>.
282
283Behind the curtain: How does our code get optimized?
284
285* Optimizing away stack manipulation: Optimizing away stack manipulation<2>.
286* Elimination of tail recursion: Elimination of tail recursion<2>.
287
288Topic Reference
289
290* Compilation contexts: Compilation contexts<2>.
291* Objects: Objects<2>.
292* Types: Types<2>.
293* Expressions: Expressions<2>.
294* Creating and using functions: Creating and using functions<2>.
295* Source Locations: Source Locations<2>.
69834ed9 296* Compiling a context: Compiling a context<2>.
36b809a0 297
298Compilation contexts
299
300* Lifetime-management: Lifetime-management<2>.
301* Thread-safety: Thread-safety<2>.
302* Error-handling: Error-handling<3>.
303* Debugging: Debugging<2>.
304* Options: Options<4>.
305
306Options
307
e5a6940a 308* String Options: String Options<2>.
36b809a0 309* Boolean options: Boolean options<2>.
310* Integer options: Integer options<2>.
adb2df55 311* Additional command-line options: Additional command-line options<2>.
36b809a0 312
313Types
314
315* Standard types: Standard types<2>.
316* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>.
317* Structures and unions: Structures and unions<2>.
318
319Expressions
320
321* Rvalues: Rvalues<2>.
322* Lvalues: Lvalues<2>.
323* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>.
324
325Rvalues
326
327* Simple expressions: Simple expressions<2>.
328* Unary Operations: Unary Operations<2>.
329* Binary Operations: Binary Operations<2>.
330* Comparisons: Comparisons<2>.
331* Function calls: Function calls<2>.
332* Type-coercion: Type-coercion<2>.
333
334Lvalues
335
336* Global variables: Global variables<2>.
337
338Creating and using functions
339
340* Params: Params<2>.
341* Functions: Functions<2>.
342* Blocks: Blocks<2>.
343* Statements: Statements<2>.
344
345Source Locations
346
347* Faking it: Faking it<2>.
348
69834ed9 349Compiling a context
350
351* In-memory compilation: In-memory compilation<2>.
352* Ahead-of-time compilation: Ahead-of-time compilation<2>.
353
863e76f9 354Internals
355
356* Working on the JIT library::
357* Running the test suite::
358* Environment variables::
9dba8b1d 359* Packaging notes::
863e76f9 360* Overview of code structure::
c97b0d1d 361* Design notes::
bc06177c 362* Submitting patches::
863e76f9 363
57687d8b 364Running the test suite
365
366* Running under valgrind::
367
863e76f9 368@end detailmenu
369@end menu
370
371
372@node Tutorial,Topic Reference,Top,Top
373@anchor{intro/index libgccjit}@anchor{1}@anchor{intro/index doc}@anchor{2}@anchor{intro/index tutorial}@anchor{3}
374@chapter Tutorial
375
376
f1717362 377@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 378@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
379@c
380@c This is free software: you can redistribute it and/or modify it
381@c under the terms of the GNU General Public License as published by
382@c the Free Software Foundation, either version 3 of the License, or
383@c (at your option) any later version.
384@c
385@c This program is distributed in the hope that it will be useful, but
386@c WITHOUT ANY WARRANTY; without even the implied warranty of
387@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
388@c General Public License for more details.
389@c
390@c You should have received a copy of the GNU General Public License
391@c along with this program. If not, see
392@c <http://www.gnu.org/licenses/>.
393
394@menu
395* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world".
396* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function.
397* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables.
398* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter.
69834ed9 399* Tutorial part 5; Implementing an Ahead-of-Time compiler: Tutorial part 5 Implementing an Ahead-of-Time compiler.
863e76f9 400
401@end menu
402
403@node Tutorial part 1 "Hello world",Tutorial part 2 Creating a trivial machine code function,,Tutorial
404@anchor{intro/tutorial01 doc}@anchor{4}@anchor{intro/tutorial01 tutorial-part-1-hello-world}@anchor{5}
405@section Tutorial part 1: "Hello world"
406
407
408Before we look at the details of the API, let's look at building and
409running programs that use the library.
410
411Here's a toy "hello world" program that uses the library to synthesize
412a call to @cite{printf} and uses it to write a message to stdout.
413
414Don't worry about the content of the program for now; we'll cover
415the details in later parts of this tutorial.
416
417@quotation
418
419@example
420/* Smoketest example for libgccjit.so
f1717362 421 Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 422
423This file is part of GCC.
424
425GCC is free software; you can redistribute it and/or modify it
426under the terms of the GNU General Public License as published by
427the Free Software Foundation; either version 3, or (at your option)
428any later version.
429
430GCC is distributed in the hope that it will be useful, but
431WITHOUT ANY WARRANTY; without even the implied warranty of
432MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
433General Public License for more details.
434
435You should have received a copy of the GNU General Public License
436along with GCC; see the file COPYING3. If not see
437<http://www.gnu.org/licenses/>. */
438
439#include <libgccjit.h>
440
441#include <stdlib.h>
442#include <stdio.h>
443
444static void
445create_code (gcc_jit_context *ctxt)
446@{
447 /* Let's try to inject the equivalent of:
448 void
449 greet (const char *name)
450 @{
451 printf ("hello %s\n", name);
452 @}
453 */
454 gcc_jit_type *void_type =
455 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
456 gcc_jit_type *const_char_ptr_type =
457 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR);
458 gcc_jit_param *param_name =
459 gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name");
460 gcc_jit_function *func =
461 gcc_jit_context_new_function (ctxt, NULL,
462 GCC_JIT_FUNCTION_EXPORTED,
463 void_type,
464 "greet",
465 1, &param_name,
466 0);
467
468 gcc_jit_param *param_format =
469 gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format");
470 gcc_jit_function *printf_func =
471 gcc_jit_context_new_function (ctxt, NULL,
472 GCC_JIT_FUNCTION_IMPORTED,
473 gcc_jit_context_get_type (
474 ctxt, GCC_JIT_TYPE_INT),
475 "printf",
476 1, &param_format,
477 1);
478 gcc_jit_rvalue *args[2];
479 args[0] = gcc_jit_context_new_string_literal (ctxt, "hello %s\n");
480 args[1] = gcc_jit_param_as_rvalue (param_name);
481
482 gcc_jit_block *block = gcc_jit_function_new_block (func, NULL);
483
484 gcc_jit_block_add_eval (
485 block, NULL,
486 gcc_jit_context_new_call (ctxt,
487 NULL,
488 printf_func,
489 2, args));
490 gcc_jit_block_end_with_void_return (block, NULL);
491@}
492
493int
494main (int argc, char **argv)
495@{
496 gcc_jit_context *ctxt;
497 gcc_jit_result *result;
498
499 /* Get a "context" object for working with the library. */
500 ctxt = gcc_jit_context_acquire ();
501 if (!ctxt)
502 @{
503 fprintf (stderr, "NULL ctxt");
504 exit (1);
505 @}
506
507 /* Set some options on the context.
508 Let's see the code being generated, in assembler form. */
509 gcc_jit_context_set_bool_option (
510 ctxt,
511 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
512 0);
513
514 /* Populate the context. */
515 create_code (ctxt);
516
517 /* Compile the code. */
518 result = gcc_jit_context_compile (ctxt);
519 if (!result)
520 @{
521 fprintf (stderr, "NULL result");
522 exit (1);
523 @}
524
525 /* Extract the generated code from "result". */
526 typedef void (*fn_type) (const char *);
527 fn_type greet =
528 (fn_type)gcc_jit_result_get_code (result, "greet");
529 if (!greet)
530 @{
531 fprintf (stderr, "NULL greet");
532 exit (1);
533 @}
534
535 /* Now call the generated function: */
536 greet ("world");
537 fflush (stdout);
538
539 gcc_jit_context_release (ctxt);
540 gcc_jit_result_release (result);
541 return 0;
542@}
543
544@end example
545
546@noindent
547@end quotation
548
549Copy the above to @cite{tut01-hello-world.c}.
550
551Assuming you have the jit library installed, build the test program
552using:
553
554@example
555$ gcc \
556 tut01-hello-world.c \
557 -o tut01-hello-world \
558 -lgccjit
559@end example
560
561@noindent
562
563You should then be able to run the built program:
564
565@example
566$ ./tut01-hello-world
567hello world
568@end example
569
570@noindent
571
f1717362 572@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 573@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
574@c
575@c This is free software: you can redistribute it and/or modify it
576@c under the terms of the GNU General Public License as published by
577@c the Free Software Foundation, either version 3 of the License, or
578@c (at your option) any later version.
579@c
580@c This program is distributed in the hope that it will be useful, but
581@c WITHOUT ANY WARRANTY; without even the implied warranty of
582@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
583@c General Public License for more details.
584@c
585@c You should have received a copy of the GNU General Public License
586@c along with this program. If not, see
587@c <http://www.gnu.org/licenses/>.
588
589@node Tutorial part 2 Creating a trivial machine code function,Tutorial part 3 Loops and variables,Tutorial part 1 "Hello world",Tutorial
590@anchor{intro/tutorial02 doc}@anchor{6}@anchor{intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{7}
591@section Tutorial part 2: Creating a trivial machine code function
592
593
594Consider this C function:
595
596@example
597int square (int i)
598@{
599 return i * i;
600@}
601@end example
602
603@noindent
604
605How can we construct this at run-time using libgccjit?
606
607First we need to include the relevant header:
608
609@example
610#include <libgccjit.h>
611@end example
612
613@noindent
614
615All state associated with compilation is associated with a
616@pxref{8,,gcc_jit_context *}.
617
618Create one using @pxref{9,,gcc_jit_context_acquire()}:
619
620@example
621gcc_jit_context *ctxt;
622ctxt = gcc_jit_context_acquire ();
623@end example
624
625@noindent
626
627The JIT library has a system of types. It is statically-typed: every
628expression is of a specific type, fixed at compile-time. In our example,
629all of the expressions are of the C @cite{int} type, so let's obtain this from
630the context, as a @pxref{a,,gcc_jit_type *}, using
631@pxref{b,,gcc_jit_context_get_type()}:
632
633@example
634gcc_jit_type *int_type =
635 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
636@end example
637
638@noindent
639
640@pxref{a,,gcc_jit_type *} is an example of a "contextual" object: every
641entity in the API is associated with a @pxref{8,,gcc_jit_context *}.
642
643Memory management is easy: all such "contextual" objects are automatically
644cleaned up for you when the context is released, using
645@pxref{c,,gcc_jit_context_release()}:
646
647@example
648gcc_jit_context_release (ctxt);
649@end example
650
651@noindent
652
653so you don't need to manually track and cleanup all objects, just the
654contexts.
655
656Although the API is C-based, there is a form of class hierarchy, which
657looks like this:
658
659@example
660+- gcc_jit_object
661 +- gcc_jit_location
662 +- gcc_jit_type
663 +- gcc_jit_struct
664 +- gcc_jit_field
665 +- gcc_jit_function
666 +- gcc_jit_block
667 +- gcc_jit_rvalue
668 +- gcc_jit_lvalue
669 +- gcc_jit_param
670@end example
671
672@noindent
673
674There are casting methods for upcasting from subclasses to parent classes.
675For example, @pxref{d,,gcc_jit_type_as_object()}:
676
677@example
678gcc_jit_object *obj = gcc_jit_type_as_object (int_type);
679@end example
680
681@noindent
682
683One thing you can do with a @pxref{e,,gcc_jit_object *} is
684to ask it for a human-readable description, using
685@pxref{f,,gcc_jit_object_get_debug_string()}:
686
687@example
688printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj));
689@end example
690
691@noindent
692
693giving this text on stdout:
694
695@example
696obj: int
697@end example
698
699@noindent
700
701This is invaluable when debugging.
702
703Let's create the function. To do so, we first need to construct
704its single parameter, specifying its type and giving it a name,
705using @pxref{10,,gcc_jit_context_new_param()}:
706
707@example
708gcc_jit_param *param_i =
709 gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
710@end example
711
712@noindent
713
714Now we can create the function, using
715@pxref{11,,gcc_jit_context_new_function()}:
716
717@example
718gcc_jit_function *func =
719 gcc_jit_context_new_function (ctxt, NULL,
720 GCC_JIT_FUNCTION_EXPORTED,
721 int_type,
722 "square",
723 1, &param_i,
724 0);
725@end example
726
727@noindent
728
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
741@noindent
742
743Our basic block is relatively simple: it immediately terminates by
744returning the value of an expression.
745
746We can build the expression using @pxref{12,,gcc_jit_context_new_binary_op()}:
747
748@example
749gcc_jit_rvalue *expr =
750 gcc_jit_context_new_binary_op (
751 ctxt, NULL,
752 GCC_JIT_BINARY_OP_MULT, int_type,
753 gcc_jit_param_as_rvalue (param_i),
754 gcc_jit_param_as_rvalue (param_i));
755@end example
756
757@noindent
758
759A @pxref{13,,gcc_jit_rvalue *} is another example of a
760@pxref{e,,gcc_jit_object *} subclass. We can upcast it using
761@pxref{14,,gcc_jit_rvalue_as_object()} and as before print it with
762@pxref{f,,gcc_jit_object_get_debug_string()}.
763
764@example
765printf ("expr: %s\n",
766 gcc_jit_object_get_debug_string (
767 gcc_jit_rvalue_as_object (expr)));
768@end example
769
770@noindent
771
772giving this output:
773
774@example
775expr: i * i
776@end example
777
778@noindent
779
780Creating the expression in itself doesn't do anything; we have to add
781this expression to a statement within the block. In this case, we use it
782to build a return statement, which terminates the basic block:
783
784@example
785gcc_jit_block_end_with_return (block, NULL, expr);
786@end example
787
788@noindent
789
790OK, we've populated the context. We can now compile it using
791@pxref{15,,gcc_jit_context_compile()}:
792
793@example
794gcc_jit_result *result;
795result = gcc_jit_context_compile (ctxt);
796@end example
797
798@noindent
799
800and get a @pxref{16,,gcc_jit_result *}.
801
97e241d3 802At this point we're done with the context; we can release it:
803
804@example
805gcc_jit_context_release (ctxt);
806@end example
807
808@noindent
809
863e76f9 810We can now use @pxref{17,,gcc_jit_result_get_code()} to look up a specific
811machine code routine within the result, in this case, the function we
812created above.
813
814@example
815void *fn_ptr = gcc_jit_result_get_code (result, "square");
816if (!fn_ptr)
817 @{
818 fprintf (stderr, "NULL fn_ptr");
819 goto error;
820 @}
821@end example
822
823@noindent
824
825We can now cast the pointer to an appropriate function pointer type, and
826then call it:
827
828@example
829typedef int (*fn_type) (int);
830fn_type square = (fn_type)fn_ptr;
831printf ("result: %d", square (5));
832@end example
833
834@noindent
835
836@example
837result: 25
838@end example
839
840@noindent
841
eac6fba2 842Once we're done with the code, we can release the result:
843
844@example
845gcc_jit_result_release (result);
846@end example
847
848@noindent
849
850We can't call @code{square} anymore once we've released @code{result}.
851
863e76f9 852@menu
eac6fba2 853* Error-handling::
863e76f9 854* Options::
855* Full example::
856
857@end menu
858
eac6fba2 859@node Error-handling,Options,,Tutorial part 2 Creating a trivial machine code function
860@anchor{intro/tutorial02 error-handling}@anchor{18}
861@subsection Error-handling
862
863
864Various kinds of errors are possible when using the API, such as
865mismatched types in an assignment. You can only compile and get code
866from a context if no errors occur.
867
868Errors are printed on stderr; they typically contain the name of the API
869entrypoint where the error occurred, and pertinent information on the
870problem:
871
872@example
873./buggy-program: error: gcc_jit_block_add_assignment: mismatching types: assignment to i (type: int) from "hello world" (type: const char *)
874@end example
875
876@noindent
877
878The API is designed to cope with errors without crashing, so you can get
879away with having a single error-handling check in your code:
880
881@example
882void *fn_ptr = gcc_jit_result_get_code (result, "square");
883if (!fn_ptr)
884 @{
885 fprintf (stderr, "NULL fn_ptr");
886 goto error;
887 @}
888@end example
889
890@noindent
891
892For more information, see the @pxref{19,,error-handling guide}
893within the Topic eference.
894
895@node Options,Full example,Error-handling,Tutorial part 2 Creating a trivial machine code function
896@anchor{intro/tutorial02 options}@anchor{1a}
863e76f9 897@subsection Options
898
899
900To get more information on what's going on, you can set debugging flags
eac6fba2 901on the context using @pxref{1b,,gcc_jit_context_set_bool_option()}.
863e76f9 902
903@c (I'm deliberately not mentioning
904@c :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think
905@c it's probably more of use to implementors than to users)
906
eac6fba2 907Setting @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE} will dump a
863e76f9 908C-like representation to stderr when you compile (GCC's "GIMPLE"
909representation):
910
911@example
912gcc_jit_context_set_bool_option (
913 ctxt,
914 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE,
915 1);
916result = gcc_jit_context_compile (ctxt);
917@end example
918
919@noindent
920
921@example
922square (signed int i)
923@{
924 signed int D.260;
925
926 entry:
927 D.260 = i * i;
928 return D.260;
929@}
930@end example
931
932@noindent
933
934We can see the generated machine code in assembler form (on stderr) by
eac6fba2 935setting @pxref{1d,,GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE} on the context
863e76f9 936before compiling:
937
938@example
939gcc_jit_context_set_bool_option (
940 ctxt,
941 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
942 1);
943result = gcc_jit_context_compile (ctxt);
944@end example
945
946@noindent
947
948@example
949 .file "fake.c"
950 .text
951 .globl square
952 .type square, @@function
953square:
954.LFB6:
955 .cfi_startproc
956 pushq %rbp
957 .cfi_def_cfa_offset 16
958 .cfi_offset 6, -16
959 movq %rsp, %rbp
960 .cfi_def_cfa_register 6
961 movl %edi, -4(%rbp)
962.L14:
963 movl -4(%rbp), %eax
964 imull -4(%rbp), %eax
965 popq %rbp
966 .cfi_def_cfa 7, 8
967 ret
968 .cfi_endproc
969.LFE6:
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
975@noindent
976
977By default, no optimizations are performed, the equivalent of GCC's
978@cite{-O0} option. We can turn things up to e.g. @cite{-O3} by calling
eac6fba2 979@pxref{1e,,gcc_jit_context_set_int_option()} with
980@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}:
863e76f9 981
982@example
983gcc_jit_context_set_int_option (
984 ctxt,
985 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
986 3);
987@end example
988
989@noindent
990
991@example
992 .file "fake.c"
993 .text
994 .p2align 4,,15
995 .globl square
996 .type square, @@function
997square:
998.LFB7:
999 .cfi_startproc
1000.L16:
1001 movl %edi, %eax
1002 imull %edi, %eax
1003 ret
1004 .cfi_endproc
1005.LFE7:
1006 .size square, .-square
1007 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)"
1008 .section .note.GNU-stack,"",@@progbits
1009@end example
1010
1011@noindent
1012
1013Naturally this has only a small effect on such a trivial function.
1014
1015@node Full example,,Options,Tutorial part 2 Creating a trivial machine code function
eac6fba2 1016@anchor{intro/tutorial02 full-example}@anchor{20}
863e76f9 1017@subsection Full example
1018
1019
1020Here's what the above looks like as a complete program:
1021
1022@quotation
1023
1024@example
1025/* Usage example for libgccjit.so
f1717362 1026 Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 1027
1028This file is part of GCC.
1029
1030GCC is free software; you can redistribute it and/or modify it
1031under the terms of the GNU General Public License as published by
1032the Free Software Foundation; either version 3, or (at your option)
1033any later version.
1034
1035GCC is distributed in the hope that it will be useful, but
1036WITHOUT ANY WARRANTY; without even the implied warranty of
1037MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1038General Public License for more details.
1039
1040You should have received a copy of the GNU General Public License
1041along with GCC; see the file COPYING3. If not see
1042<http://www.gnu.org/licenses/>. */
1043
1044#include <libgccjit.h>
1045
1046#include <stdlib.h>
1047#include <stdio.h>
1048
1049void
1050create_code (gcc_jit_context *ctxt)
1051@{
1052 /* Let's try to inject the equivalent of:
1053
1054 int square (int i)
1055 @{
1056 return i * i;
1057 @}
1058 */
1059 gcc_jit_type *int_type =
1060 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
1061 gcc_jit_param *param_i =
1062 gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
1063 gcc_jit_function *func =
1064 gcc_jit_context_new_function (ctxt, NULL,
1065 GCC_JIT_FUNCTION_EXPORTED,
1066 int_type,
1067 "square",
1068 1, &param_i,
1069 0);
1070
1071 gcc_jit_block *block = gcc_jit_function_new_block (func, NULL);
1072
1073 gcc_jit_rvalue *expr =
1074 gcc_jit_context_new_binary_op (
1075 ctxt, NULL,
1076 GCC_JIT_BINARY_OP_MULT, int_type,
1077 gcc_jit_param_as_rvalue (param_i),
1078 gcc_jit_param_as_rvalue (param_i));
1079
1080 gcc_jit_block_end_with_return (block, NULL, expr);
1081@}
1082
1083int
1084main (int argc, char **argv)
1085@{
1086 gcc_jit_context *ctxt = NULL;
1087 gcc_jit_result *result = NULL;
1088
1089 /* Get a "context" object for working with the library. */
1090 ctxt = gcc_jit_context_acquire ();
1091 if (!ctxt)
1092 @{
1093 fprintf (stderr, "NULL ctxt");
1094 goto error;
1095 @}
1096
1097 /* Set some options on the context.
1098 Let's see the code being generated, in assembler form. */
1099 gcc_jit_context_set_bool_option (
1100 ctxt,
1101 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
1102 0);
1103
1104 /* Populate the context. */
1105 create_code (ctxt);
1106
1107 /* Compile the code. */
1108 result = gcc_jit_context_compile (ctxt);
1109 if (!result)
1110 @{
1111 fprintf (stderr, "NULL result");
1112 goto error;
1113 @}
1114
97e241d3 1115 /* We're done with the context; we can release it: */
1116 gcc_jit_context_release (ctxt);
1117 ctxt = NULL;
1118
863e76f9 1119 /* Extract the generated code from "result". */
1120 void *fn_ptr = gcc_jit_result_get_code (result, "square");
1121 if (!fn_ptr)
1122 @{
1123 fprintf (stderr, "NULL fn_ptr");
1124 goto error;
1125 @}
1126
1127 typedef int (*fn_type) (int);
1128 fn_type square = (fn_type)fn_ptr;
36b809a0 1129 printf ("result: %d\n", square (5));
863e76f9 1130
1131 error:
97e241d3 1132 if (ctxt)
1133 gcc_jit_context_release (ctxt);
1134 if (result)
1135 gcc_jit_result_release (result);
863e76f9 1136 return 0;
1137@}
1138
1139@end example
1140
1141@noindent
1142@end quotation
1143
1144Building and running it:
1145
1146@example
1147$ gcc \
1148 tut02-square.c \
1149 -o tut02-square \
1150 -lgccjit
1151
1152# Run the built program:
1153$ ./tut02-square
1154result: 25
1155@end example
1156
1157@noindent
1158
f1717362 1159@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 1160@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
1161@c
1162@c This is free software: you can redistribute it and/or modify it
1163@c under the terms of the GNU General Public License as published by
1164@c the Free Software Foundation, either version 3 of the License, or
1165@c (at your option) any later version.
1166@c
1167@c This program is distributed in the hope that it will be useful, but
1168@c WITHOUT ANY WARRANTY; without even the implied warranty of
1169@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1170@c General Public License for more details.
1171@c
1172@c You should have received a copy of the GNU General Public License
1173@c along with this program. If not, see
1174@c <http://www.gnu.org/licenses/>.
1175
1176@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
eac6fba2 1177@anchor{intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{21}@anchor{intro/tutorial03 doc}@anchor{22}
863e76f9 1178@section Tutorial part 3: Loops and variables
1179
1180
1181Consider this C function:
1182
1183@quotation
1184
1185@example
1186int loop_test (int n)
1187@{
1188 int sum = 0;
1189 for (int i = 0; i < n; i++)
1190 sum += i * i;
1191 return sum;
1192@}
1193@end example
1194
1195@noindent
1196@end quotation
1197
1198This example demonstrates some more features of libgccjit, with local
1199variables and a loop.
1200
1201To break this down into libgccjit terms, it's usually easier to reword
1202the @cite{for} loop as a @cite{while} loop, giving:
1203
1204@quotation
1205
1206@example
1207int loop_test (int n)
1208@{
1209 int sum = 0;
1210 int i = 0;
1211 while (i < n)
1212 @{
1213 sum += i * i;
1214 i++;
1215 @}
1216 return sum;
1217@}
1218@end example
1219
1220@noindent
1221@end quotation
1222
1223Here's what the final control flow graph will look like:
1224
1225@quotation
1226
1227
1228@float Figure
1229
1eddded5 1230@image{sum-of-squares1,,,image of a control flow graph,png}
863e76f9 1231
1232@end float
1233
1234@end quotation
1235
1236As before, we include the libgccjit header and make a
1237@pxref{8,,gcc_jit_context *}.
1238
1239@example
1240#include <libgccjit.h>
1241
1242void test (void)
1243@{
1244 gcc_jit_context *ctxt;
1245 ctxt = gcc_jit_context_acquire ();
1246@end example
1247
1248@noindent
1249
1250The function works with the C @cite{int} type:
1251
1252@example
1253gcc_jit_type *the_type =
1254 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
1255gcc_jit_type *return_type = the_type;
1256@end example
1257
1258@noindent
1259
1260though we could equally well make it work on, say, @cite{double}:
1261
1262@example
1263gcc_jit_type *the_type =
1264 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE);
1265@end example
1266
1267@noindent
1268
1269Let's build the function:
1270
1271@example
1272gcc_jit_param *n =
1273 gcc_jit_context_new_param (ctxt, NULL, the_type, "n");
1274gcc_jit_param *params[1] = @{n@};
1275gcc_jit_function *func =
1276 gcc_jit_context_new_function (ctxt, NULL,
1277 GCC_JIT_FUNCTION_EXPORTED,
1278 return_type,
1279 "loop_test",
1280 1, params, 0);
1281@end example
1282
1283@noindent
1284
1285@menu
1286* Expressions; lvalues and rvalues: Expressions lvalues and rvalues.
1287* Control flow::
1288* Visualizing the control flow graph::
1289* Full example: Full example<2>.
1290
1291@end menu
1292
1293@node Expressions lvalues and rvalues,Control flow,,Tutorial part 3 Loops and variables
eac6fba2 1294@anchor{intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{23}
863e76f9 1295@subsection Expressions: lvalues and rvalues
1296
1297
1298The base class of expression is the @pxref{13,,gcc_jit_rvalue *},
1299representing an expression that can be on the @emph{right}-hand side of
1300an assignment: a value that can be computed somehow, and assigned
1301@emph{to} a storage area (such as a variable). It has a specific
1302@pxref{a,,gcc_jit_type *}.
1303
eac6fba2 1304Anothe important class is @pxref{24,,gcc_jit_lvalue *}.
1305A @pxref{24,,gcc_jit_lvalue *}. is something that can of the @emph{left}-hand
863e76f9 1306side of an assignment: a storage area (such as a variable).
1307
1308In other words, every assignment can be thought of as:
1309
1310@example
1311LVALUE = RVALUE;
1312@end example
1313
1314@noindent
1315
eac6fba2 1316Note that @pxref{24,,gcc_jit_lvalue *} is a subclass of
863e76f9 1317@pxref{13,,gcc_jit_rvalue *}, where in an assignment of the form:
1318
1319@example
1320LVALUE_A = LVALUE_B;
1321@end example
1322
1323@noindent
1324
1325the @cite{LVALUE_B} implies reading the current value of that storage
1326area, assigning it into the @cite{LVALUE_A}.
1327
1328So far the only expressions we've seen are @cite{i * i}:
1329
1330@example
1331gcc_jit_rvalue *expr =
1332 gcc_jit_context_new_binary_op (
1333 ctxt, NULL,
1334 GCC_JIT_BINARY_OP_MULT, int_type,
1335 gcc_jit_param_as_rvalue (param_i),
1336 gcc_jit_param_as_rvalue (param_i));
1337@end example
1338
1339@noindent
1340
1341which is a @pxref{13,,gcc_jit_rvalue *}, and the various function
1342parameters: @cite{param_i} and @cite{param_n}, instances of
eac6fba2 1343@pxref{25,,gcc_jit_param *}, which is a subclass of
1344@pxref{24,,gcc_jit_lvalue *} (and, in turn, of @pxref{13,,gcc_jit_rvalue *}):
863e76f9 1345we can both read from and write to function parameters within the
1346body of a function.
1347
1348Our new example has a couple of local variables. We create them by
eac6fba2 1349calling @pxref{26,,gcc_jit_function_new_local()}, supplying a type and a
863e76f9 1350name:
1351
1352@example
1353/* Build locals: */
1354gcc_jit_lvalue *i =
1355 gcc_jit_function_new_local (func, NULL, the_type, "i");
1356gcc_jit_lvalue *sum =
1357 gcc_jit_function_new_local (func, NULL, the_type, "sum");
1358@end example
1359
1360@noindent
1361
eac6fba2 1362These are instances of @pxref{24,,gcc_jit_lvalue *} - they can be read from
863e76f9 1363and written to.
1364
1365Note that there is no precanned way to create @emph{and} initialize a variable
1366like in C:
1367
1368@example
1369int i = 0;
1370@end example
1371
1372@noindent
1373
1374Instead, having added the local to the function, we have to separately add
1375an assignment of @cite{0} to @cite{local_i} at the beginning of the function.
1376
1377@node Control flow,Visualizing the control flow graph,Expressions lvalues and rvalues,Tutorial part 3 Loops and variables
eac6fba2 1378@anchor{intro/tutorial03 control-flow}@anchor{27}
863e76f9 1379@subsection Control flow
1380
1381
1382This function has a loop, so we need to build some basic blocks to
1383handle the control flow. In this case, we need 4 blocks:
1384
1385
1386@enumerate
1387
1388@item
1389before the loop (initializing the locals)
1390
1391@item
1392the conditional at the top of the loop (comparing @cite{i < n})
1393
1394@item
1395the body of the loop
1396
1397@item
1398after the loop terminates (@cite{return sum})
1399@end enumerate
1400
eac6fba2 1401so we create these as @pxref{28,,gcc_jit_block *} instances within the
1402@pxref{29,,gcc_jit_function *}:
863e76f9 1403
1404@example
1405gcc_jit_block *b_initial =
1406 gcc_jit_function_new_block (func, "initial");
1407gcc_jit_block *b_loop_cond =
1408 gcc_jit_function_new_block (func, "loop_cond");
1409gcc_jit_block *b_loop_body =
1410 gcc_jit_function_new_block (func, "loop_body");
1411gcc_jit_block *b_after_loop =
1412 gcc_jit_function_new_block (func, "after_loop");
1413@end example
1414
1415@noindent
1416
1417We now populate each block with statements.
1418
1419The entry block @cite{b_initial} consists of initializations followed by a jump
1420to the conditional. We assign @cite{0} to @cite{i} and to @cite{sum}, using
eac6fba2 1421@pxref{2a,,gcc_jit_block_add_assignment()} to add
1422an assignment statement, and using @pxref{2b,,gcc_jit_context_zero()} to get
863e76f9 1423the constant value @cite{0} for the relevant type for the right-hand side of
1424the assignment:
1425
1426@example
1427/* sum = 0; */
1428gcc_jit_block_add_assignment (
1429 b_initial, NULL,
1430 sum,
1431 gcc_jit_context_zero (ctxt, the_type));
1432
1433/* i = 0; */
1434gcc_jit_block_add_assignment (
1435 b_initial, NULL,
1436 i,
1437 gcc_jit_context_zero (ctxt, the_type));
1438@end example
1439
1440@noindent
1441
1442We can then terminate the entry block by jumping to the conditional:
1443
1444@example
1445gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond);
1446@end example
1447
1448@noindent
1449
1450The conditional block is equivalent to the line @cite{while (i < n)} from our
1451C example. It contains a single statement: a conditional, which jumps to
1452one of two destination blocks depending on a boolean
1453@pxref{13,,gcc_jit_rvalue *}, in this case the comparison of @cite{i} and @cite{n}.
eac6fba2 1454We build the comparison using @pxref{2c,,gcc_jit_context_new_comparison()}:
863e76f9 1455
1456@example
625691b3 1457/* (i >= n) */
1458 gcc_jit_rvalue *guard =
1459 gcc_jit_context_new_comparison (
1460 ctxt, NULL,
1461 GCC_JIT_COMPARISON_GE,
1462 gcc_jit_lvalue_as_rvalue (i),
1463 gcc_jit_param_as_rvalue (n));
863e76f9 1464@end example
1465
1466@noindent
1467
1468and can then use this to add @cite{b_loop_cond}'s sole statement, via
eac6fba2 1469@pxref{2d,,gcc_jit_block_end_with_conditional()}:
863e76f9 1470
1471@example
625691b3 1472/* Equivalent to:
1473 if (guard)
1474 goto after_loop;
1475 else
1476 goto loop_body; */
1477gcc_jit_block_end_with_conditional (
1478 b_loop_cond, NULL,
1479 guard,
1480 b_after_loop, /* on_true */
1481 b_loop_body); /* on_false */
863e76f9 1482@end example
1483
1484@noindent
1485
1486Next, we populate the body of the loop.
1487
1488The C statement @cite{sum += i * i;} is an assignment operation, where an
1489lvalue is modified "in-place". We use
eac6fba2 1490@pxref{2e,,gcc_jit_block_add_assignment_op()} to handle these operations:
863e76f9 1491
1492@example
1493/* sum += i * i */
1494gcc_jit_block_add_assignment_op (
1495 b_loop_body, NULL,
1496 sum,
1497 GCC_JIT_BINARY_OP_PLUS,
1498 gcc_jit_context_new_binary_op (
1499 ctxt, NULL,
1500 GCC_JIT_BINARY_OP_MULT, the_type,
1501 gcc_jit_lvalue_as_rvalue (i),
1502 gcc_jit_lvalue_as_rvalue (i)));
1503@end example
1504
1505@noindent
1506
1507The @cite{i++} can be thought of as @cite{i += 1}, and can thus be handled in
eac6fba2 1508a similar way. We use @pxref{2f,,gcc_jit_context_one()} to get the constant
863e76f9 1509value @cite{1} (for the relevant type) for the right-hand side
1510of the assignment.
1511
1512@example
1513/* i++ */
1514gcc_jit_block_add_assignment_op (
1515 b_loop_body, NULL,
1516 i,
1517 GCC_JIT_BINARY_OP_PLUS,
1518 gcc_jit_context_one (ctxt, the_type));
1519@end example
1520
1521@noindent
1522
1523@cartouche
1524@quotation Note
1525For numeric constants other than 0 or 1, we could use
eac6fba2 1526@pxref{30,,gcc_jit_context_new_rvalue_from_int()} and
1527@pxref{31,,gcc_jit_context_new_rvalue_from_double()}.
863e76f9 1528@end quotation
1529@end cartouche
1530
1531The loop body completes by jumping back to the conditional:
1532
1533@example
1534gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond);
1535@end example
1536
1537@noindent
1538
1539Finally, we populate the @cite{b_after_loop} block, reached when the loop
1540conditional is false. We want to generate the equivalent of:
1541
1542@example
1543return sum;
1544@end example
1545
1546@noindent
1547
1548so the block is just one statement:
1549
1550@example
1551/* return sum */
1552gcc_jit_block_end_with_return (
1553 b_after_loop,
1554 NULL,
1555 gcc_jit_lvalue_as_rvalue (sum));
1556@end example
1557
1558@noindent
1559
1560@cartouche
1561@quotation Note
1562You can intermingle block creation with statement creation,
1563but given that the terminator statements generally include references
1564to other blocks, I find it's clearer to create all the blocks,
1565@emph{then} all the statements.
1566@end quotation
1567@end cartouche
1568
1569We've finished populating the function. As before, we can now compile it
1570to machine code:
1571
1572@example
1573gcc_jit_result *result;
1574result = gcc_jit_context_compile (ctxt);
1575
1576typedef int (*loop_test_fn_type) (int);
1577loop_test_fn_type loop_test =
1578 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test");
1579if (!loop_test)
1580 goto error;
1581printf ("result: %d", loop_test (10));
1582@end example
1583
1584@noindent
1585
1586@example
1587result: 285
1588@end example
1589
1590@noindent
1591
1592@node Visualizing the control flow graph,Full example<2>,Control flow,Tutorial part 3 Loops and variables
eac6fba2 1593@anchor{intro/tutorial03 visualizing-the-control-flow-graph}@anchor{32}
863e76f9 1594@subsection Visualizing the control flow graph
1595
1596
1597You can see the control flow graph of a function using
eac6fba2 1598@pxref{33,,gcc_jit_function_dump_to_dot()}:
863e76f9 1599
1600@example
1601gcc_jit_function_dump_to_dot (func, "/tmp/sum-of-squares.dot");
1602@end example
1603
1604@noindent
1605
1606giving a .dot file in GraphViz format.
1607
1608You can convert this to an image using @cite{dot}:
1609
1610@example
1611$ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png
1612@end example
1613
1614@noindent
1615
1616or use a viewer (my preferred one is xdot.py; see
1617@indicateurl{https://github.com/jrfonseca/xdot.py}; on Fedora you can
1618install it with @cite{yum install python-xdot}):
1619
1620@quotation
1621
1622
1623@float Figure
1624
1eddded5 1625@image{sum-of-squares1,,,image of a control flow graph,png}
863e76f9 1626
1627@end float
1628
1629@end quotation
1630
1631@node Full example<2>,,Visualizing the control flow graph,Tutorial part 3 Loops and variables
eac6fba2 1632@anchor{intro/tutorial03 full-example}@anchor{34}
863e76f9 1633@subsection Full example
1634
1635
1636@quotation
1637
1638@example
1639/* Usage example for libgccjit.so
f1717362 1640 Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 1641
1642This file is part of GCC.
1643
1644GCC is free software; you can redistribute it and/or modify it
1645under the terms of the GNU General Public License as published by
1646the Free Software Foundation; either version 3, or (at your option)
1647any later version.
1648
1649GCC is distributed in the hope that it will be useful, but
1650WITHOUT ANY WARRANTY; without even the implied warranty of
1651MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1652General Public License for more details.
1653
1654You should have received a copy of the GNU General Public License
1655along with GCC; see the file COPYING3. If not see
1656<http://www.gnu.org/licenses/>. */
1657
1658#include <libgccjit.h>
1659
1660#include <stdlib.h>
1661#include <stdio.h>
1662
1663void
1664create_code (gcc_jit_context *ctxt)
1665@{
1666 /*
1667 Simple sum-of-squares, to test conditionals and looping
1668
1669 int loop_test (int n)
1670 @{
1671 int i;
1672 int sum = 0;
1673 for (i = 0; i < n ; i ++)
1674 @{
1675 sum += i * i;
1676 @}
1677 return sum;
1678 */
1679 gcc_jit_type *the_type =
1680 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
1681 gcc_jit_type *return_type = the_type;
1682
1683 gcc_jit_param *n =
1684 gcc_jit_context_new_param (ctxt, NULL, the_type, "n");
1685 gcc_jit_param *params[1] = @{n@};
1686 gcc_jit_function *func =
1687 gcc_jit_context_new_function (ctxt, NULL,
1688 GCC_JIT_FUNCTION_EXPORTED,
1689 return_type,
1690 "loop_test",
1691 1, params, 0);
1692
1693 /* Build locals: */
1694 gcc_jit_lvalue *i =
1695 gcc_jit_function_new_local (func, NULL, the_type, "i");
1696 gcc_jit_lvalue *sum =
1697 gcc_jit_function_new_local (func, NULL, the_type, "sum");
1698
1699 gcc_jit_block *b_initial =
1700 gcc_jit_function_new_block (func, "initial");
1701 gcc_jit_block *b_loop_cond =
1702 gcc_jit_function_new_block (func, "loop_cond");
1703 gcc_jit_block *b_loop_body =
1704 gcc_jit_function_new_block (func, "loop_body");
1705 gcc_jit_block *b_after_loop =
1706 gcc_jit_function_new_block (func, "after_loop");
1707
1708 /* sum = 0; */
1709 gcc_jit_block_add_assignment (
1710 b_initial, NULL,
1711 sum,
1712 gcc_jit_context_zero (ctxt, the_type));
1713
1714 /* i = 0; */
1715 gcc_jit_block_add_assignment (
1716 b_initial, NULL,
1717 i,
1718 gcc_jit_context_zero (ctxt, the_type));
1719
1720 gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond);
1721
1722 /* if (i >= n) */
1723 gcc_jit_block_end_with_conditional (
1724 b_loop_cond, NULL,
1725 gcc_jit_context_new_comparison (
1726 ctxt, NULL,
1727 GCC_JIT_COMPARISON_GE,
1728 gcc_jit_lvalue_as_rvalue (i),
1729 gcc_jit_param_as_rvalue (n)),
1730 b_after_loop,
1731 b_loop_body);
1732
1733 /* sum += i * i */
1734 gcc_jit_block_add_assignment_op (
1735 b_loop_body, NULL,
1736 sum,
1737 GCC_JIT_BINARY_OP_PLUS,
1738 gcc_jit_context_new_binary_op (
1739 ctxt, NULL,
1740 GCC_JIT_BINARY_OP_MULT, the_type,
1741 gcc_jit_lvalue_as_rvalue (i),
1742 gcc_jit_lvalue_as_rvalue (i)));
1743
1744 /* i++ */
1745 gcc_jit_block_add_assignment_op (
1746 b_loop_body, NULL,
1747 i,
1748 GCC_JIT_BINARY_OP_PLUS,
1749 gcc_jit_context_one (ctxt, the_type));
1750
1751 gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond);
1752
1753 /* return sum */
1754 gcc_jit_block_end_with_return (
1755 b_after_loop,
1756 NULL,
1757 gcc_jit_lvalue_as_rvalue (sum));
1758@}
1759
1760int
1761main (int argc, char **argv)
1762@{
1763 gcc_jit_context *ctxt = NULL;
1764 gcc_jit_result *result = NULL;
1765
1766 /* Get a "context" object for working with the library. */
1767 ctxt = gcc_jit_context_acquire ();
1768 if (!ctxt)
1769 @{
1770 fprintf (stderr, "NULL ctxt");
1771 goto error;
1772 @}
1773
1774 /* Set some options on the context.
1775 Let's see the code being generated, in assembler form. */
1776 gcc_jit_context_set_bool_option (
1777 ctxt,
1778 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
1779 0);
1780
1781 /* Populate the context. */
1782 create_code (ctxt);
1783
1784 /* Compile the code. */
1785 result = gcc_jit_context_compile (ctxt);
1786 if (!result)
1787 @{
1788 fprintf (stderr, "NULL result");
1789 goto error;
1790 @}
1791
1792 /* Extract the generated code from "result". */
1793 typedef int (*loop_test_fn_type) (int);
1794 loop_test_fn_type loop_test =
1795 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test");
1796 if (!loop_test)
1797 @{
1798 fprintf (stderr, "NULL loop_test");
1799 goto error;
1800 @}
1801
1802 /* Run the generated code. */
1803 int val = loop_test (10);
1804 printf("loop_test returned: %d\n", val);
1805
1806 error:
1807 gcc_jit_context_release (ctxt);
1808 gcc_jit_result_release (result);
1809 return 0;
1810@}
1811
1812@end example
1813
1814@noindent
1815@end quotation
1816
1817Building and running it:
1818
1819@example
1820$ gcc \
1821 tut03-sum-of-squares.c \
1822 -o tut03-sum-of-squares \
1823 -lgccjit
1824
1825# Run the built program:
1826$ ./tut03-sum-of-squares
1827loop_test returned: 285
1828@end example
1829
1830@noindent
1831
f1717362 1832@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 1833@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
1834@c
1835@c This is free software: you can redistribute it and/or modify it
1836@c under the terms of the GNU General Public License as published by
1837@c the Free Software Foundation, either version 3 of the License, or
1838@c (at your option) any later version.
1839@c
1840@c This program is distributed in the hope that it will be useful, but
1841@c WITHOUT ANY WARRANTY; without even the implied warranty of
1842@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1843@c General Public License for more details.
1844@c
1845@c You should have received a copy of the GNU General Public License
1846@c along with this program. If not, see
1847@c <http://www.gnu.org/licenses/>.
1848
69834ed9 1849@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
eac6fba2 1850@anchor{intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{35}@anchor{intro/tutorial04 doc}@anchor{36}
863e76f9 1851@section Tutorial part 4: Adding JIT-compilation to a toy interpreter
1852
1853
1854In this example we construct a "toy" interpreter, and add JIT-compilation
1855to it.
1856
1857@menu
1858* Our toy interpreter::
1859* Compiling to machine code::
1860* Setting things up::
1861* Populating the function::
1862* Verifying the control flow graph::
1863* Compiling the context::
1864* Single-stepping through the generated code::
1865* Examining the generated code::
1866* Putting it all together::
1867* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?.
1868
1869@end menu
1870
1871@node Our toy interpreter,Compiling to machine code,,Tutorial part 4 Adding JIT-compilation to a toy interpreter
eac6fba2 1872@anchor{intro/tutorial04 our-toy-interpreter}@anchor{37}
863e76f9 1873@subsection Our toy interpreter
1874
1875
1876It's a stack-based interpreter, and is intended as a (very simple) example
1877of the kind of bytecode interpreter seen in dynamic languages such as
1878Python, Ruby etc.
1879
1880For the sake of simplicity, our toy virtual machine is very limited:
1881
1882@quotation
1883
1884
1885@itemize *
1886
1887@item
1888The only data type is @cite{int}
1889
1890@item
1891It can only work on one function at a time (so that the only
1892function call that can be made is to recurse).
1893
1894@item
1895Functions can only take one parameter.
1896
1897@item
1898Functions have a stack of @cite{int} values.
1899
1900@item
1901We'll implement function call within the interpreter by calling a
1902function in our implementation, rather than implementing our own
1903frame stack.
1904
1905@item
1906The parser is only good enough to get the examples to work.
1907@end itemize
1908@end quotation
1909
1910Naturally, a real interpreter would be much more complicated that this.
1911
1912The following operations are supported:
1913
1914
1915@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxx}
1916@headitem
1917
1918Operation
1919
1920@tab
1921
1922Meaning
1923
1924@tab
1925
1926Old Stack
1927
1928@tab
1929
1930New Stack
1931
1932@item
1933
1934DUP
1935
1936@tab
1937
1938Duplicate top of stack.
1939
1940@tab
1941
1942@code{[..., x]}
1943
1944@tab
1945
1946@code{[..., x, x]}
1947
1948@item
1949
1950ROT
1951
1952@tab
1953
1954Swap top two elements
1955of stack.
1956
1957@tab
1958
1959@code{[..., x, y]}
1960
1961@tab
1962
1963@code{[..., y, x]}
1964
1965@item
1966
1967BINARY_ADD
1968
1969@tab
1970
1971Add the top two elements
1972on the stack.
1973
1974@tab
1975
1976@code{[..., x, y]}
1977
1978@tab
1979
1980@code{[..., (x+y)]}
1981
1982@item
1983
1984BINARY_SUBTRACT
1985
1986@tab
1987
1988Likewise, but subtract.
1989
1990@tab
1991
1992@code{[..., x, y]}
1993
1994@tab
1995
1996@code{[..., (x-y)]}
1997
1998@item
1999
2000BINARY_MULT
2001
2002@tab
2003
2004Likewise, but multiply.
2005
2006@tab
2007
2008@code{[..., x, y]}
2009
2010@tab
2011
2012@code{[..., (x*y)]}
2013
2014@item
2015
2016BINARY_COMPARE_LT
2017
2018@tab
2019
2020Compare the top two
2021elements on the stack
2022and push a nonzero/zero
2023if (x<y).
2024
2025@tab
2026
2027@code{[..., x, y]}
2028
2029@tab
2030
2031@code{[..., (x<y)]}
2032
2033@item
2034
2035RECURSE
2036
2037@tab
2038
2039Recurse, passing the top
2040of the stack, and
2041popping the result.
2042
2043@tab
2044
2045@code{[..., x]}
2046
2047@tab
2048
2049@code{[..., fn(x)]}
2050
2051@item
2052
2053RETURN
2054
2055@tab
2056
2057Return the top of the
2058stack.
2059
2060@tab
2061
2062@code{[x]}
2063
2064@tab
2065
2066@code{[]}
2067
2068@item
2069
2070PUSH_CONST @cite{arg}
2071
2072@tab
2073
2074Push an int const.
2075
2076@tab
2077
2078@code{[...]}
2079
2080@tab
2081
2082@code{[..., arg]}
2083
2084@item
2085
2086JUMP_ABS_IF_TRUE @cite{arg}
2087
2088@tab
2089
2090Pop; if top of stack was
2091nonzero, jump to
2092@code{arg}.
2093
2094@tab
2095
2096@code{[..., x]}
2097
2098@tab
2099
2100@code{[...]}
2101
2102@end multitable
2103
2104
2105Programs can be interpreted, disassembled, and compiled to machine code.
2106
2107The interpreter reads @code{.toy} scripts. Here's what a simple recursive
2108factorial program looks like, the script @code{factorial.toy}.
2109The parser ignores lines beginning with a @cite{#}.
2110
2111@quotation
2112
2113@example
2114# Simple recursive factorial implementation, roughly equivalent to:
2115#
2116# int factorial (int arg)
2117# @{
2118# if (arg < 2)
2119# return arg
2120# return arg * factorial (arg - 1)
2121# @}
2122
2123# Initial state:
2124# stack: [arg]
2125
2126# 0:
2127DUP
2128# stack: [arg, arg]
2129
2130# 1:
2131PUSH_CONST 2
2132# stack: [arg, arg, 2]
2133
2134# 2:
2135BINARY_COMPARE_LT
2136# stack: [arg, (arg < 2)]
2137
2138# 3:
2139JUMP_ABS_IF_TRUE 9
2140# stack: [arg]
2141
2142# 4:
2143DUP
2144# stack: [arg, arg]
2145
2146# 5:
2147PUSH_CONST 1
2148# stack: [arg, arg, 1]
2149
2150# 6:
2151BINARY_SUBTRACT
2152# stack: [arg, (arg - 1)
2153
2154# 7:
2155RECURSE
2156# stack: [arg, factorial(arg - 1)]
2157
2158# 8:
2159BINARY_MULT
2160# stack: [arg * factorial(arg - 1)]
2161
2162# 9:
2163RETURN
2164
2165@end example
2166
2167@noindent
2168@end quotation
2169
2170The interpreter is a simple infinite loop with a big @code{switch} statement
2171based on what the next opcode is:
2172
2173@quotation
2174
2175@example
2176
2177static int
2178toyvm_function_interpret (toyvm_function *fn, int arg, FILE *trace)
2179@{
2180 toyvm_frame frame;
2181#define PUSH(ARG) (toyvm_frame_push (&frame, (ARG)))
2182#define POP(ARG) (toyvm_frame_pop (&frame))
2183
2184 frame.frm_function = fn;
2185 frame.frm_pc = 0;
2186 frame.frm_cur_depth = 0;
2187
2188 PUSH (arg);
2189
2190 while (1)
2191 @{
2192 toyvm_op *op;
2193 int x, y;
2194 assert (frame.frm_pc < fn->fn_num_ops);
2195 op = &fn->fn_ops[frame.frm_pc++];
2196
2197 if (trace)
2198 @{
2199 toyvm_frame_dump_stack (&frame, trace);
2200 toyvm_function_disassemble_op (fn, op, frame.frm_pc, trace);
2201 @}
2202
2203 switch (op->op_opcode)
2204 @{
2205 /* Ops taking no operand. */
2206 case DUP:
2207 x = POP ();
2208 PUSH (x);
2209 PUSH (x);
2210 break;
2211
2212 case ROT:
2213 y = POP ();
2214 x = POP ();
2215 PUSH (y);
2216 PUSH (x);
2217 break;
2218
2219 case BINARY_ADD:
2220 y = POP ();
2221 x = POP ();
2222 PUSH (x + y);
2223 break;
2224
2225 case BINARY_SUBTRACT:
2226 y = POP ();
2227 x = POP ();
2228 PUSH (x - y);
2229 break;
2230
2231 case BINARY_MULT:
2232 y = POP ();
2233 x = POP ();
2234 PUSH (x * y);
2235 break;
2236
2237 case BINARY_COMPARE_LT:
2238 y = POP ();
2239 x = POP ();
2240 PUSH (x < y);
2241 break;
2242
2243 case RECURSE:
2244 x = POP ();
2245 x = toyvm_function_interpret (fn, x, trace);
2246 PUSH (x);
2247 break;
2248
2249 case RETURN:
2250 return POP ();
2251
2252 /* Ops taking an operand. */
2253 case PUSH_CONST:
2254 PUSH (op->op_operand);
2255 break;
2256
2257 case JUMP_ABS_IF_TRUE:
2258 x = POP ();
2259 if (x)
2260 frame.frm_pc = op->op_operand;
2261 break;
2262
2263 default:
2264 assert (0); /* unknown opcode */
2265
2266 @} /* end of switch on opcode */
2267 @} /* end of while loop */
2268
2269#undef PUSH
2270#undef POP
2271@}
2272
2273
2274@end example
2275
2276@noindent
2277@end quotation
2278
2279@node Compiling to machine code,Setting things up,Our toy interpreter,Tutorial part 4 Adding JIT-compilation to a toy interpreter
eac6fba2 2280@anchor{intro/tutorial04 compiling-to-machine-code}@anchor{38}
863e76f9 2281@subsection Compiling to machine code
2282
2283
2284We want to generate machine code that can be cast to this type and
2285then directly executed in-process:
2286
2287@quotation
2288
2289@example
7140b255 2290typedef int (*toyvm_compiled_code) (int);
2291
2292
2293@end example
2294
2295@noindent
2296@end quotation
2297
2298The lifetime of the code is tied to that of a @pxref{16,,gcc_jit_result *}.
2299We'll handle this by bundling them up in a structure, so that we can
eac6fba2 2300clean them up together by calling @pxref{39,,gcc_jit_result_release()}:
7140b255 2301
2302@quotation
2303
2304@example
2305
2306struct toyvm_compiled_function
2307@{
2308 gcc_jit_result *cf_jit_result;
2309 toyvm_compiled_code cf_code;
2310@};
863e76f9 2311
2312
2313@end example
2314
2315@noindent
2316@end quotation
2317
2318Our compiler isn't very sophisticated; it takes the implementation of
2319each opcode above, and maps it directly to the operations supported by
2320the libgccjit API.
2321
2322How should we handle the stack? In theory we could calculate what the
2323stack depth will be at each opcode, and optimize away the stack
2324manipulation "by hand". We'll see below that libgccjit is able to do
2325this for us, so we'll implement stack manipulation
2326in a direct way, by creating a @code{stack} array and @code{stack_depth}
2327variables, local within the generated function, equivalent to this C code:
2328
2329@example
2330int stack_depth;
2331int stack[MAX_STACK_DEPTH];
2332@end example
2333
2334@noindent
2335
2336We'll also have local variables @code{x} and @code{y} for use when implementing
2337the opcodes, equivalent to this:
2338
2339@example
2340int x;
2341int y;
2342@end example
2343
2344@noindent
2345
2346This means our compiler has the following state:
2347
2348@quotation
2349
2350@example
2351
2352struct compilation_state
2353@{
2354 gcc_jit_context *ctxt;
2355
2356 gcc_jit_type *int_type;
2357 gcc_jit_type *bool_type;
2358 gcc_jit_type *stack_type; /* int[MAX_STACK_DEPTH] */
2359
2360 gcc_jit_rvalue *const_one;
2361
2362 gcc_jit_function *fn;
2363 gcc_jit_param *param_arg;
2364 gcc_jit_lvalue *stack;
2365 gcc_jit_lvalue *stack_depth;
2366 gcc_jit_lvalue *x;
2367 gcc_jit_lvalue *y;
2368
2369 gcc_jit_location *op_locs[MAX_OPS];
2370 gcc_jit_block *initial_block;
2371 gcc_jit_block *op_blocks[MAX_OPS];
2372
2373@};
2374
2375
2376@end example
2377
2378@noindent
2379@end quotation
2380
2381@node Setting things up,Populating the function,Compiling to machine code,Tutorial part 4 Adding JIT-compilation to a toy interpreter
eac6fba2 2382@anchor{intro/tutorial04 setting-things-up}@anchor{3a}
863e76f9 2383@subsection Setting things up
2384
2385
2386First we create our types:
2387
2388@quotation
2389
2390@example
2391 state.int_type =
2392 gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_INT);
2393 state.bool_type =
2394 gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_BOOL);
2395 state.stack_type =
2396 gcc_jit_context_new_array_type (state.ctxt, NULL,
2397 state.int_type, MAX_STACK_DEPTH);
2398
2399
2400@end example
2401
2402@noindent
2403@end quotation
2404
2405along with extracting a useful @cite{int} constant:
2406
2407@quotation
2408
2409@example
2410 state.const_one = gcc_jit_context_one (state.ctxt, state.int_type);
2411
2412
2413@end example
2414
2415@noindent
2416@end quotation
2417
2418We'll implement push and pop in terms of the @code{stack} array and
2419@code{stack_depth}. Here are helper functions for adding statements to
2420a block, implementing pushing and popping values:
2421
2422@quotation
2423
2424@example
2425
2426static void
2427add_push (compilation_state *state,
2428 gcc_jit_block *block,
2429 gcc_jit_rvalue *rvalue,
2430 gcc_jit_location *loc)
2431@{
2432 /* stack[stack_depth] = RVALUE */
2433 gcc_jit_block_add_assignment (
2434 block,
2435 loc,
2436 /* stack[stack_depth] */
2437 gcc_jit_context_new_array_access (
2438 state->ctxt,
2439 loc,
2440 gcc_jit_lvalue_as_rvalue (state->stack),
2441 gcc_jit_lvalue_as_rvalue (state->stack_depth)),
2442 rvalue);
2443
2444 /* "stack_depth++;". */
2445 gcc_jit_block_add_assignment_op (
2446 block,
2447 loc,
2448 state->stack_depth,
2449 GCC_JIT_BINARY_OP_PLUS,
2450 state->const_one);
2451@}
2452
2453static void
2454add_pop (compilation_state *state,
2455 gcc_jit_block *block,
2456 gcc_jit_lvalue *lvalue,
2457 gcc_jit_location *loc)
2458@{
2459 /* "--stack_depth;". */
2460 gcc_jit_block_add_assignment_op (
2461 block,
2462 loc,
2463 state->stack_depth,
2464 GCC_JIT_BINARY_OP_MINUS,
2465 state->const_one);
2466
2467 /* "LVALUE = stack[stack_depth];". */
2468 gcc_jit_block_add_assignment (
2469 block,
2470 loc,
2471 lvalue,
2472 /* stack[stack_depth] */
2473 gcc_jit_lvalue_as_rvalue (
2474 gcc_jit_context_new_array_access (
2475 state->ctxt,
2476 loc,
2477 gcc_jit_lvalue_as_rvalue (state->stack),
2478 gcc_jit_lvalue_as_rvalue (state->stack_depth))));
2479@}
2480
2481
2482@end example
2483
2484@noindent
2485@end quotation
2486
2487We will support single-stepping through the generated code in the
eac6fba2 2488debugger, so we need to create @pxref{3b,,gcc_jit_location} instances, one
863e76f9 2489per operation in the source code. These will reference the lines of
2490e.g. @code{factorial.toy}.
2491
2492@quotation
2493
2494@example
2495 for (pc = 0; pc < fn->fn_num_ops; pc++)
2496 @{
2497 toyvm_op *op = &fn->fn_ops[pc];
2498
2499 state.op_locs[pc] = gcc_jit_context_new_location (state.ctxt,
2500 fn->fn_filename,
2501 op->op_linenum,
2502 0); /* column */
2503 @}
2504
2505
2506@end example
2507
2508@noindent
2509@end quotation
2510
2511Let's create the function itself. As usual, we create its parameter
2512first, then use the parameter to create the function:
2513
2514@quotation
2515
2516@example
2517 state.param_arg =
2518 gcc_jit_context_new_param (state.ctxt, state.op_locs[0],
2519 state.int_type, "arg");
2520 state.fn =
2521 gcc_jit_context_new_function (state.ctxt,
2522 state.op_locs[0],
2523 GCC_JIT_FUNCTION_EXPORTED,
2524 state.int_type,
2525 funcname,
2526 1, &state.param_arg, 0);
2527
2528
2529@end example
2530
2531@noindent
2532@end quotation
2533
2534We create the locals within the function.
2535
2536@quotation
2537
2538@example
2539 state.stack =
2540 gcc_jit_function_new_local (state.fn, NULL,
2541 state.stack_type, "stack");
2542 state.stack_depth =
2543 gcc_jit_function_new_local (state.fn, NULL,
2544 state.int_type, "stack_depth");
2545 state.x =
2546 gcc_jit_function_new_local (state.fn, NULL,
2547 state.int_type, "x");
2548 state.y =
2549 gcc_jit_function_new_local (state.fn, NULL,
2550 state.int_type, "y");
2551
2552
2553@end example
2554
2555@noindent
2556@end quotation
2557
2558@node Populating the function,Verifying the control flow graph,Setting things up,Tutorial part 4 Adding JIT-compilation to a toy interpreter
eac6fba2 2559@anchor{intro/tutorial04 populating-the-function}@anchor{3c}
863e76f9 2560@subsection Populating the function
2561
2562
2563There's some one-time initialization, and the API treats the first block
2564you create as the entrypoint of the function, so we need to create that
2565block first:
2566
2567@quotation
2568
2569@example
2570 state.initial_block = gcc_jit_function_new_block (state.fn, "initial");
2571
2572
2573@end example
2574
2575@noindent
2576@end quotation
2577
2578We can now create blocks for each of the operations. Most of these will
2579be consolidated into larger blocks when the optimizer runs.
2580
2581@quotation
2582
2583@example
2584 for (pc = 0; pc < fn->fn_num_ops; pc++)
2585 @{
2586 char buf[16];
2587 sprintf (buf, "instr%i", pc);
2588 state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf);
2589 @}
2590
2591
2592@end example
2593
2594@noindent
2595@end quotation
2596
2597Now that we have a block it can jump to when it's done, we can populate
2598the initial block:
2599
2600@quotation
2601
2602@example
2603
2604 /* "stack_depth = 0;". */
2605 gcc_jit_block_add_assignment (
2606 state.initial_block,
2607 state.op_locs[0],
2608 state.stack_depth,
2609 gcc_jit_context_zero (state.ctxt, state.int_type));
2610
2611 /* "PUSH (arg);". */
2612 add_push (&state,
2613 state.initial_block,
2614 gcc_jit_param_as_rvalue (state.param_arg),
2615 state.op_locs[0]);
2616
2617 /* ...and jump to insn 0. */
2618 gcc_jit_block_end_with_jump (state.initial_block,
2619 state.op_locs[0],
2620 state.op_blocks[0]);
2621
2622
2623@end example
2624
2625@noindent
2626@end quotation
2627
2628We can now populate the blocks for the individual operations. We loop
2629through them, adding instructions to their blocks:
2630
2631@quotation
2632
2633@example
2634 for (pc = 0; pc < fn->fn_num_ops; pc++)
2635 @{
2636 gcc_jit_location *loc = state.op_locs[pc];
2637
2638 gcc_jit_block *block = state.op_blocks[pc];
2639 gcc_jit_block *next_block = (pc < fn->fn_num_ops
2640 ? state.op_blocks[pc + 1]
2641 : NULL);
2642
2643 toyvm_op *op;
2644 op = &fn->fn_ops[pc];
2645
2646
2647@end example
2648
2649@noindent
2650@end quotation
2651
2652We're going to have another big @code{switch} statement for implementing
2653the opcodes, this time for compiling them, rather than interpreting
2654them. It's helpful to have macros for implementing push and pop, so that
2655we can make the @code{switch} statement that's coming up look as much as
2656possible like the one above within the interpreter:
2657
2658@example
2659
2660#define X_EQUALS_POP()\
2661 add_pop (&state, block, state.x, loc)
2662#define Y_EQUALS_POP()\
2663 add_pop (&state, block, state.y, loc)
2664#define PUSH_RVALUE(RVALUE)\
2665 add_push (&state, block, (RVALUE), loc)
2666#define PUSH_X()\
2667 PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.x))
2668#define PUSH_Y() \
2669 PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.y))
2670
2671
2672@end example
2673
2674@noindent
2675
2676@cartouche
2677@quotation Note
2678A particularly clever implementation would have an @emph{identical}
2679@code{switch} statement shared by the interpreter and the compiler, with
2680some preprocessor "magic". We're not doing that here, for the sake
2681of simplicity.
2682@end quotation
2683@end cartouche
2684
2685When I first implemented this compiler, I accidentally missed an edit
2686when copying and pasting the @code{Y_EQUALS_POP} macro, so that popping the
2687stack into @code{y} instead erroneously assigned it to @code{x}, leaving @code{y}
2688uninitialized.
2689
2690To track this kind of thing down, we can use
eac6fba2 2691@pxref{3d,,gcc_jit_block_add_comment()} to add descriptive comments
863e76f9 2692to the internal representation. This is invaluable when looking through
2693the generated IR for, say @code{factorial}:
2694
2695@quotation
2696
2697@example
2698
2699 gcc_jit_block_add_comment (block, loc, opcode_names[op->op_opcode]);
2700
2701
2702@end example
2703
2704@noindent
2705@end quotation
2706
2707We can now write the big @code{switch} statement that implements the
2708individual opcodes, populating the relevant block with statements:
2709
2710@quotation
2711
2712@example
2713
2714 switch (op->op_opcode)
2715 @{
2716 case DUP:
2717 X_EQUALS_POP ();
2718 PUSH_X ();
2719 PUSH_X ();
2720 break;
2721
2722 case ROT:
2723 Y_EQUALS_POP ();
2724 X_EQUALS_POP ();
2725 PUSH_Y ();
2726 PUSH_X ();
2727 break;
2728
2729 case BINARY_ADD:
2730 Y_EQUALS_POP ();
2731 X_EQUALS_POP ();
2732 PUSH_RVALUE (
2733 gcc_jit_context_new_binary_op (
2734 state.ctxt,
2735 loc,
2736 GCC_JIT_BINARY_OP_PLUS,
2737 state.int_type,
2738 gcc_jit_lvalue_as_rvalue (state.x),
2739 gcc_jit_lvalue_as_rvalue (state.y)));
2740 break;
2741
2742 case BINARY_SUBTRACT:
2743 Y_EQUALS_POP ();
2744 X_EQUALS_POP ();
2745 PUSH_RVALUE (
2746 gcc_jit_context_new_binary_op (
2747 state.ctxt,
2748 loc,
2749 GCC_JIT_BINARY_OP_MINUS,
2750 state.int_type,
2751 gcc_jit_lvalue_as_rvalue (state.x),
2752 gcc_jit_lvalue_as_rvalue (state.y)));
2753 break;
2754
2755 case BINARY_MULT:
2756 Y_EQUALS_POP ();
2757 X_EQUALS_POP ();
2758 PUSH_RVALUE (
2759 gcc_jit_context_new_binary_op (
2760 state.ctxt,
2761 loc,
2762 GCC_JIT_BINARY_OP_MULT,
2763 state.int_type,
2764 gcc_jit_lvalue_as_rvalue (state.x),
2765 gcc_jit_lvalue_as_rvalue (state.y)));
2766 break;
2767
2768 case BINARY_COMPARE_LT:
2769 Y_EQUALS_POP ();
2770 X_EQUALS_POP ();
2771 PUSH_RVALUE (
2772 /* cast of bool to int */
2773 gcc_jit_context_new_cast (
2774 state.ctxt,
2775 loc,
2776 /* (x < y) as a bool */
2777 gcc_jit_context_new_comparison (
2778 state.ctxt,
2779 loc,
2780 GCC_JIT_COMPARISON_LT,
2781 gcc_jit_lvalue_as_rvalue (state.x),
2782 gcc_jit_lvalue_as_rvalue (state.y)),
2783 state.int_type));
2784 break;
2785
2786 case RECURSE:
2787 @{
2788 X_EQUALS_POP ();
2789 gcc_jit_rvalue *arg = gcc_jit_lvalue_as_rvalue (state.x);
2790 PUSH_RVALUE (
2791 gcc_jit_context_new_call (
2792 state.ctxt,
2793 loc,
2794 state.fn,
2795 1, &arg));
2796 break;
2797 @}
2798
2799 case RETURN:
2800 X_EQUALS_POP ();
2801 gcc_jit_block_end_with_return (
2802 block,
2803 loc,
2804 gcc_jit_lvalue_as_rvalue (state.x));
2805 break;
2806
2807 /* Ops taking an operand. */
2808 case PUSH_CONST:
2809 PUSH_RVALUE (
2810 gcc_jit_context_new_rvalue_from_int (
2811 state.ctxt,
2812 state.int_type,
2813 op->op_operand));
2814 break;
2815
2816 case JUMP_ABS_IF_TRUE:
2817 X_EQUALS_POP ();
2818 gcc_jit_block_end_with_conditional (
2819 block,
2820 loc,
2821 /* "(bool)x". */
2822 gcc_jit_context_new_cast (
2823 state.ctxt,
2824 loc,
2825 gcc_jit_lvalue_as_rvalue (state.x),
2826 state.bool_type),
2827 state.op_blocks[op->op_operand], /* on_true */
2828 next_block); /* on_false */
2829 break;
2830
2831 default:
2832 assert(0);
2833 @} /* end of switch on opcode */
2834
2835
2836@end example
2837
2838@noindent
2839@end quotation
2840
2841Every block must be terminated, via a call to one of the
2842@code{gcc_jit_block_end_with_} entrypoints. This has been done for two
2843of the opcodes, but we need to do it for the other ones, by jumping
2844to the next block.
2845
2846@quotation
2847
2848@example
2849 if (op->op_opcode != JUMP_ABS_IF_TRUE
2850 && op->op_opcode != RETURN)
2851 gcc_jit_block_end_with_jump (
2852 block,
2853 loc,
2854 next_block);
2855
2856
2857@end example
2858
2859@noindent
2860@end quotation
2861
2862This is analogous to simply incrementing the program counter.
2863
2864@node Verifying the control flow graph,Compiling the context,Populating the function,Tutorial part 4 Adding JIT-compilation to a toy interpreter
eac6fba2 2865@anchor{intro/tutorial04 verifying-the-control-flow-graph}@anchor{3e}
863e76f9 2866@subsection Verifying the control flow graph
2867
2868
2869Having finished looping over the blocks, the context is complete.
2870
2871As before, we can verify that the control flow and statements are sane by
eac6fba2 2872using @pxref{33,,gcc_jit_function_dump_to_dot()}:
863e76f9 2873
2874@example
2875gcc_jit_function_dump_to_dot (state.fn, "/tmp/factorial.dot");
2876@end example
2877
2878@noindent
2879
2880and viewing the result. Note how the label names, comments, and
2881variable names show up in the dump, to make it easier to spot
2882errors in our compiler.
2883
2884@quotation
2885
2886
2887@float Figure
2888
1eddded5 2889@image{factorial1,,,image of a control flow graph,png}
863e76f9 2890
2891@end float
2892
2893@end quotation
2894
2895@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
eac6fba2 2896@anchor{intro/tutorial04 compiling-the-context}@anchor{3f}
863e76f9 2897@subsection Compiling the context
2898
2899
2900Having finished looping over the blocks and populating them with
2901statements, the context is complete.
2902
2903We can now compile it, and extract machine code from the result:
2904
2905@quotation
2906
2907@example
7140b255 2908 gcc_jit_result *jit_result = gcc_jit_context_compile (state.ctxt);
863e76f9 2909 gcc_jit_context_release (state.ctxt);
2910
7140b255 2911 toyvm_compiled_function *toyvm_result =
2912 (toyvm_compiled_function *)calloc (1, sizeof (toyvm_compiled_function));
2913 if (!toyvm_result)
2914 @{
2915 fprintf (stderr, "out of memory allocating toyvm_compiled_function\n");
2916 gcc_jit_result_release (jit_result);
2917 return NULL;
2918 @}
2919
2920 toyvm_result->cf_jit_result = jit_result;
2921 toyvm_result->cf_code =
2922 (toyvm_compiled_code)gcc_jit_result_get_code (jit_result,
2923 funcname);
2924
2925 free (funcname);
2926
2927 return toyvm_result;
2928@}
2929
2930char test[1024];
2931
2932#define CHECK_NON_NULL(PTR) \
2933 do @{ \
2934 if ((PTR) != NULL) \
2935 @{ \
2936 pass ("%s: %s is non-null", test, #PTR); \
2937 @} \
2938 else \
2939 @{ \
2940 fail ("%s: %s is NULL", test, #PTR); \
2941 abort (); \
2942 @} \
2943 @} while (0)
2944
2945#define CHECK_VALUE(ACTUAL, EXPECTED) \
2946 do @{ \
2947 if ((ACTUAL) == (EXPECTED)) \
2948 @{ \
2949 pass ("%s: actual: %s == expected: %s", test, #ACTUAL, #EXPECTED); \
2950 @} \
2951 else \
2952 @{ \
2953 fail ("%s: actual: %s != expected: %s", test, #ACTUAL, #EXPECTED); \
2954 fprintf (stderr, "incorrect value\n"); \
2955 abort (); \
2956 @} \
2957 @} while (0)
2958
2959static void
2960test_script (const char *scripts_dir, const char *script_name, int input,
2961 int expected_result)
2962@{
2963 char *script_path;
2964 toyvm_function *fn;
2965 int interpreted_result;
2966 toyvm_compiled_function *compiled_fn;
2967 toyvm_compiled_code code;
2968 int compiled_result;
2969
2970 snprintf (test, sizeof (test), "toyvm.c: %s", script_name);
2971
2972 script_path = (char *)malloc (strlen (scripts_dir)
2973 + strlen (script_name) + 1);
2974 CHECK_NON_NULL (script_path);
2975 sprintf (script_path, "%s%s", scripts_dir, script_name);
2976
2977 fn = toyvm_function_parse (script_path, script_name);
2978 CHECK_NON_NULL (fn);
2979
2980 interpreted_result = toyvm_function_interpret (fn, input, NULL);
2981 CHECK_VALUE (interpreted_result, expected_result);
2982
2983 compiled_fn = toyvm_function_compile (fn);
2984 CHECK_NON_NULL (compiled_fn);
2985
2986 code = (toyvm_compiled_code)compiled_fn->cf_code;
2987 CHECK_NON_NULL (code);
2988
2989 compiled_result = code (input);
2990 CHECK_VALUE (compiled_result, expected_result);
2991
2992 gcc_jit_result_release (compiled_fn->cf_jit_result);
2993 free (compiled_fn);
2994 free (fn);
2995 free (script_path);
2996@}
2997
2998#define PATH_TO_SCRIPTS ("/jit/docs/examples/tut04-toyvm/")
2999
3000static void
3001test_suite (void)
3002@{
3003 const char *srcdir;
3004 char *scripts_dir;
3005
3006 snprintf (test, sizeof (test), "toyvm.c");
3007
3008 /* We need to locate the test scripts.
3009 Rely on "srcdir" being set in the environment. */
3010
3011 srcdir = getenv ("srcdir");
3012 CHECK_NON_NULL (srcdir);
3013
3014 scripts_dir = (char *)malloc (strlen (srcdir) + strlen(PATH_TO_SCRIPTS)
3015 + 1);
3016 CHECK_NON_NULL (scripts_dir);
3017 sprintf (scripts_dir, "%s%s", srcdir, PATH_TO_SCRIPTS);
3018
3019 test_script (scripts_dir, "factorial.toy", 10, 3628800);
3020 test_script (scripts_dir, "fibonacci.toy", 10, 55);
3021
3022 free (scripts_dir);
3023@}
3024
3025int
3026main (int argc, char **argv)
3027@{
3028 const char *filename = NULL;
3029 toyvm_function *fn = NULL;
3030
3031 /* If called with no args, assume we're being run by the test suite. */
3032 if (argc < 3)
3033 @{
3034 test_suite ();
3035 return 0;
3036 @}
3037
3038 if (argc != 3)
3039 @{
3040 fprintf (stdout,
3041 "%s FILENAME INPUT: Parse and run a .toy file\n",
3042 argv[0]);
3043 exit (1);
3044 @}
3045
3046 filename = argv[1];
3047 fn = toyvm_function_parse (filename, filename);
3048 if (!fn)
3049 exit (1);
3050
3051 if (0)
3052 toyvm_function_disassemble (fn, stdout);
3053
3054 printf ("interpreter result: %d\n",
3055 toyvm_function_interpret (fn, atoi (argv[2]), NULL));
3056
3057 /* JIT-compilation. */
3058 toyvm_compiled_function *compiled_fn
3059 = toyvm_function_compile (fn);
3060
3061 toyvm_compiled_code code = compiled_fn->cf_code;
3062 printf ("compiler result: %d\n",
3063 code (atoi (argv[2])));
3064
3065 gcc_jit_result_release (compiled_fn->cf_jit_result);
3066 free (compiled_fn);
3067
3068 return 0;
3069@}
863e76f9 3070
3071@end example
3072
3073@noindent
3074@end quotation
3075
3076We can now run the result:
3077
3078@quotation
3079
3080@example
7140b255 3081 toyvm_compiled_function *compiled_fn
3082 = toyvm_function_compile (fn);
3083
3084 toyvm_compiled_code code = compiled_fn->cf_code;
863e76f9 3085 printf ("compiler result: %d\n",
3086 code (atoi (argv[2])));
3087
7140b255 3088 gcc_jit_result_release (compiled_fn->cf_jit_result);
3089 free (compiled_fn);
3090
863e76f9 3091
3092@end example
3093
3094@noindent
3095@end quotation
3096
3097@node Single-stepping through the generated code,Examining the generated code,Compiling the context,Tutorial part 4 Adding JIT-compilation to a toy interpreter
eac6fba2 3098@anchor{intro/tutorial04 single-stepping-through-the-generated-code}@anchor{40}
863e76f9 3099@subsection Single-stepping through the generated code
3100
3101
3102It's possible to debug the generated code. To do this we need to both:
3103
3104@quotation
3105
3106
3107@itemize *
3108
3109@item
3110Set up source code locations for our statements, so that we can
3111meaningfully step through the code. We did this above by
eac6fba2 3112calling @pxref{41,,gcc_jit_context_new_location()} and using the
863e76f9 3113results.
3114
3115@item
3116Enable the generation of debugging information, by setting
eac6fba2 3117@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the
863e76f9 3118@pxref{8,,gcc_jit_context} via
eac6fba2 3119@pxref{1b,,gcc_jit_context_set_bool_option()}:
863e76f9 3120
3121@example
3122gcc_jit_context_set_bool_option (
3123 ctxt,
3124 GCC_JIT_BOOL_OPTION_DEBUGINFO,
3125 1);
3126@end example
3127
3128@noindent
3129@end itemize
3130@end quotation
3131
3132Having done this, we can put a breakpoint on the generated function:
3133
3134@example
3135$ gdb --args ./toyvm factorial.toy 10
3136(gdb) break factorial
3137Function "factorial" not defined.
3138Make breakpoint pending on future shared library load? (y or [n]) y
3139Breakpoint 1 (factorial) pending.
3140(gdb) run
3141Breakpoint 1, factorial (arg=10) at factorial.toy:14
314214 DUP
3143@end example
3144
3145@noindent
3146
3147We've set up location information, which references @code{factorial.toy}.
3148This allows us to use e.g. @code{list} to see where we are in the script:
3149
3150@example
3151(gdb) list
31529
315310 # Initial state:
315411 # stack: [arg]
315512
315613 # 0:
315714 DUP
315815 # stack: [arg, arg]
315916
316017 # 1:
316118 PUSH_CONST 2
3162@end example
3163
3164@noindent
3165
3166and to step through the function, examining the data:
3167
3168@example
3169(gdb) n
317018 PUSH_CONST 2
3171(gdb) n
317222 BINARY_COMPARE_LT
3173(gdb) print stack
3174$5 = @{10, 10, 2, 0, -7152, 32767, 0, 0@}
3175(gdb) print stack_depth
3176$6 = 3
3177@end example
3178
3179@noindent
3180
3181You'll see that the parts of the @code{stack} array that haven't been
3182touched yet are uninitialized.
3183
3184@cartouche
3185@quotation Note
3186Turning on optimizations may lead to unpredictable results when
3187stepping through the generated code: the execution may appear to
3188"jump around" the source code. This is analogous to turning up the
3189optimization level in a regular compiler.
3190@end quotation
3191@end cartouche
3192
3193@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
eac6fba2 3194@anchor{intro/tutorial04 examining-the-generated-code}@anchor{43}
863e76f9 3195@subsection Examining the generated code
3196
3197
3198How good is the optimized code?
3199
3200We can turn up optimizations, by calling
eac6fba2 3201@pxref{1e,,gcc_jit_context_set_int_option()} with
3202@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}:
863e76f9 3203
3204@example
3205gcc_jit_context_set_int_option (
3206 ctxt,
3207 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
3208 3);
3209@end example
3210
3211@noindent
3212
3213One of GCC's internal representations is called "gimple". A dump of the
3214initial gimple representation of the code can be seen by setting:
3215
3216@example
3217gcc_jit_context_set_bool_option (ctxt,
3218 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE,
3219 1);
3220@end example
3221
3222@noindent
3223
3224With optimization on and source locations displayed, this gives:
3225
3226@c We'll use "c" for gimple dumps
3227
3228@example
3229factorial (signed int arg)
3230@{
3231 <unnamed type> D.80;
3232 signed int D.81;
3233 signed int D.82;
3234 signed int D.83;
3235 signed int D.84;
3236 signed int D.85;
3237 signed int y;
3238 signed int x;
3239 signed int stack_depth;
3240 signed int stack[8];
3241
3242 try
3243 @{
3244 initial:
3245 stack_depth = 0;
3246 stack[stack_depth] = arg;
3247 stack_depth = stack_depth + 1;
3248 goto instr0;
3249 instr0:
3250 /* DUP */:
3251 stack_depth = stack_depth + -1;
3252 x = stack[stack_depth];
3253 stack[stack_depth] = x;
3254 stack_depth = stack_depth + 1;
3255 stack[stack_depth] = x;
3256 stack_depth = stack_depth + 1;
3257 goto instr1;
3258 instr1:
3259 /* PUSH_CONST */:
3260 stack[stack_depth] = 2;
3261 stack_depth = stack_depth + 1;
3262 goto instr2;
3263
3264 /* etc */
3265@end example
3266
3267@noindent
3268
3269You can see the generated machine code in assembly form via:
3270
3271@example
3272gcc_jit_context_set_bool_option (
3273 ctxt,
3274 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
3275 1);
3276result = gcc_jit_context_compile (ctxt);
3277@end example
3278
3279@noindent
3280
3281which shows that (on this x86_64 box) the compiler has unrolled the loop
3282and is using MMX instructions to perform several multiplications
3283simultaneously:
3284
3285@example
3286 .file "fake.c"
3287 .text
3288.Ltext0:
3289 .p2align 4,,15
3290 .globl factorial
3291 .type factorial, @@function
3292factorial:
3293.LFB0:
3294 .file 1 "factorial.toy"
3295 .loc 1 14 0
3296 .cfi_startproc
3297.LVL0:
3298.L2:
3299 .loc 1 26 0
3300 cmpl $1, %edi
3301 jle .L13
3302 leal -1(%rdi), %edx
3303 movl %edx, %ecx
3304 shrl $2, %ecx
3305 leal 0(,%rcx,4), %esi
3306 testl %esi, %esi
3307 je .L14
3308 cmpl $9, %edx
3309 jbe .L14
3310 leal -2(%rdi), %eax
3311 movl %eax, -16(%rsp)
3312 leal -3(%rdi), %eax
3313 movd -16(%rsp), %xmm0
3314 movl %edi, -16(%rsp)
3315 movl %eax, -12(%rsp)
3316 movd -16(%rsp), %xmm1
3317 xorl %eax, %eax
3318 movl %edx, -16(%rsp)
3319 movd -12(%rsp), %xmm4
3320 movd -16(%rsp), %xmm6
3321 punpckldq %xmm4, %xmm0
3322 movdqa .LC1(%rip), %xmm4
3323 punpckldq %xmm6, %xmm1
3324 punpcklqdq %xmm0, %xmm1
3325 movdqa .LC0(%rip), %xmm0
3326 jmp .L5
3327 # etc - edited for brevity
3328@end example
3329
3330@noindent
3331
3332This is clearly overkill for a function that will likely overflow the
3333@code{int} type before the vectorization is worthwhile - but then again, this
3334is a toy example.
3335
3336Turning down the optimization level to 2:
3337
3338@example
3339gcc_jit_context_set_int_option (
3340 ctxt,
3341 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
3342 3);
3343@end example
3344
3345@noindent
3346
3347yields this code, which is simple enough to quote in its entirety:
3348
3349@example
3350 .file "fake.c"
3351 .text
3352 .p2align 4,,15
3353 .globl factorial
3354 .type factorial, @@function
3355factorial:
3356.LFB0:
3357 .cfi_startproc
3358.L2:
3359 cmpl $1, %edi
3360 jle .L8
3361 movl $1, %edx
3362 jmp .L4
3363 .p2align 4,,10
3364 .p2align 3
3365.L6:
3366 movl %eax, %edi
3367.L4:
3368.L5:
3369 leal -1(%rdi), %eax
3370 imull %edi, %edx
3371 cmpl $1, %eax
3372 jne .L6
3373.L3:
3374.L7:
3375 imull %edx, %eax
3376 ret
3377.L8:
3378 movl %edi, %eax
3379 movl $1, %edx
3380 jmp .L7
3381 .cfi_endproc
3382.LFE0:
3383 .size factorial, .-factorial
3384 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-%@{gcc_release@})"
3385 .section .note.GNU-stack,"",@@progbits
3386@end example
3387
3388@noindent
3389
3390Note that the stack pushing and popping have been eliminated, as has the
3391recursive call (in favor of an iteration).
3392
3393@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
eac6fba2 3394@anchor{intro/tutorial04 putting-it-all-together}@anchor{44}
863e76f9 3395@subsection Putting it all together
3396
3397
3398The complete example can be seen in the source tree at
3399@code{gcc/jit/docs/examples/tut04-toyvm/toyvm.c}
3400
3401along with a Makefile and a couple of sample .toy scripts:
3402
3403@example
3404$ ls -al
3405drwxrwxr-x. 2 david david 4096 Sep 19 17:46 .
3406drwxrwxr-x. 3 david david 4096 Sep 19 15:26 ..
3407-rw-rw-r--. 1 david david 615 Sep 19 12:43 factorial.toy
3408-rw-rw-r--. 1 david david 834 Sep 19 13:08 fibonacci.toy
3409-rw-rw-r--. 1 david david 238 Sep 19 14:22 Makefile
3410-rw-rw-r--. 1 david david 16457 Sep 19 17:07 toyvm.c
3411
3412$ make toyvm
3413g++ -Wall -g -o toyvm toyvm.c -lgccjit
3414
3415$ ./toyvm factorial.toy 10
3416interpreter result: 3628800
3417compiler result: 3628800
3418
3419$ ./toyvm fibonacci.toy 10
3420interpreter result: 55
3421compiler result: 55
3422@end example
3423
3424@noindent
3425
3426@node Behind the curtain How does our code get optimized?,,Putting it all together,Tutorial part 4 Adding JIT-compilation to a toy interpreter
eac6fba2 3427@anchor{intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{45}
863e76f9 3428@subsection Behind the curtain: How does our code get optimized?
3429
3430
3431Our example is done, but you may be wondering about exactly how the
3432compiler turned what we gave it into the machine code seen above.
3433
3434We can examine what the compiler is doing in detail by setting:
3435
3436@example
3437gcc_jit_context_set_bool_option (state.ctxt,
3438 GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING,
3439 1);
3440gcc_jit_context_set_bool_option (state.ctxt,
3441 GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES,
3442 1);
3443@end example
3444
3445@noindent
3446
3447This will dump detailed information about the compiler's state to a
3448directory under @code{/tmp}, and keep it from being cleaned up.
3449
3450The precise names and their formats of these files is subject to change.
3451Higher optimization levels lead to more files.
3452Here's what I saw (edited for brevity; there were almost 200 files):
3453
3454@example
3455intermediate files written to /tmp/libgccjit-KPQbGw
3456$ ls /tmp/libgccjit-KPQbGw/
3457fake.c.000i.cgraph
3458fake.c.000i.type-inheritance
3459fake.c.004t.gimple
3460fake.c.007t.omplower
3461fake.c.008t.lower
3462fake.c.011t.eh
3463fake.c.012t.cfg
3464fake.c.014i.visibility
3465fake.c.015i.early_local_cleanups
3466fake.c.016t.ssa
3467# etc
3468@end example
3469
3470@noindent
3471
3472The gimple code is converted into Static Single Assignment form,
3473with annotations for use when generating the debuginfo:
3474
3475@example
3476$ less /tmp/libgccjit-KPQbGw/fake.c.016t.ssa
3477@end example
3478
3479@noindent
3480
3481@example
3482;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
3483
3484factorial (signed int arg)
3485@{
3486 signed int stack[8];
3487 signed int stack_depth;
3488 signed int x;
3489 signed int y;
3490 <unnamed type> _20;
3491 signed int _21;
3492 signed int _38;
3493 signed int _44;
3494 signed int _51;
3495 signed int _56;
3496
3497initial:
3498 stack_depth_3 = 0;
3499 # DEBUG stack_depth => stack_depth_3
3500 stack[stack_depth_3] = arg_5(D);
3501 stack_depth_7 = stack_depth_3 + 1;
3502 # DEBUG stack_depth => stack_depth_7
3503 # DEBUG instr0 => NULL
3504 # DEBUG /* DUP */ => NULL
3505 stack_depth_8 = stack_depth_7 + -1;
3506 # DEBUG stack_depth => stack_depth_8
3507 x_9 = stack[stack_depth_8];
3508 # DEBUG x => x_9
3509 stack[stack_depth_8] = x_9;
3510 stack_depth_11 = stack_depth_8 + 1;
3511 # DEBUG stack_depth => stack_depth_11
3512 stack[stack_depth_11] = x_9;
3513 stack_depth_13 = stack_depth_11 + 1;
3514 # DEBUG stack_depth => stack_depth_13
3515 # DEBUG instr1 => NULL
3516 # DEBUG /* PUSH_CONST */ => NULL
3517 stack[stack_depth_13] = 2;
3518
3519 /* etc; edited for brevity */
3520@end example
3521
3522@noindent
3523
3524We can perhaps better see the code by turning off
eac6fba2 3525@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to suppress all those @code{DEBUG}
863e76f9 3526statements, giving:
3527
3528@example
3529$ less /tmp/libgccjit-1Hywc0/fake.c.016t.ssa
3530@end example
3531
3532@noindent
3533
3534@example
3535;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
3536
3537factorial (signed int arg)
3538@{
3539 signed int stack[8];
3540 signed int stack_depth;
3541 signed int x;
3542 signed int y;
3543 <unnamed type> _20;
3544 signed int _21;
3545 signed int _38;
3546 signed int _44;
3547 signed int _51;
3548 signed int _56;
3549
3550initial:
3551 stack_depth_3 = 0;
3552 stack[stack_depth_3] = arg_5(D);
3553 stack_depth_7 = stack_depth_3 + 1;
3554 stack_depth_8 = stack_depth_7 + -1;
3555 x_9 = stack[stack_depth_8];
3556 stack[stack_depth_8] = x_9;
3557 stack_depth_11 = stack_depth_8 + 1;
3558 stack[stack_depth_11] = x_9;
3559 stack_depth_13 = stack_depth_11 + 1;
3560 stack[stack_depth_13] = 2;
3561 stack_depth_15 = stack_depth_13 + 1;
3562 stack_depth_16 = stack_depth_15 + -1;
3563 y_17 = stack[stack_depth_16];
3564 stack_depth_18 = stack_depth_16 + -1;
3565 x_19 = stack[stack_depth_18];
3566 _20 = x_19 < y_17;
3567 _21 = (signed int) _20;
3568 stack[stack_depth_18] = _21;
3569 stack_depth_23 = stack_depth_18 + 1;
3570 stack_depth_24 = stack_depth_23 + -1;
3571 x_25 = stack[stack_depth_24];
3572 if (x_25 != 0)
3573 goto <bb 4> (instr9);
3574 else
3575 goto <bb 3> (instr4);
3576
3577instr4:
3578/* DUP */:
3579 stack_depth_26 = stack_depth_24 + -1;
3580 x_27 = stack[stack_depth_26];
3581 stack[stack_depth_26] = x_27;
3582 stack_depth_29 = stack_depth_26 + 1;
3583 stack[stack_depth_29] = x_27;
3584 stack_depth_31 = stack_depth_29 + 1;
3585 stack[stack_depth_31] = 1;
3586 stack_depth_33 = stack_depth_31 + 1;
3587 stack_depth_34 = stack_depth_33 + -1;
3588 y_35 = stack[stack_depth_34];
3589 stack_depth_36 = stack_depth_34 + -1;
3590 x_37 = stack[stack_depth_36];
3591 _38 = x_37 - y_35;
3592 stack[stack_depth_36] = _38;
3593 stack_depth_40 = stack_depth_36 + 1;
3594 stack_depth_41 = stack_depth_40 + -1;
3595 x_42 = stack[stack_depth_41];
3596 _44 = factorial (x_42);
3597 stack[stack_depth_41] = _44;
3598 stack_depth_46 = stack_depth_41 + 1;
3599 stack_depth_47 = stack_depth_46 + -1;
3600 y_48 = stack[stack_depth_47];
3601 stack_depth_49 = stack_depth_47 + -1;
3602 x_50 = stack[stack_depth_49];
3603 _51 = x_50 * y_48;
3604 stack[stack_depth_49] = _51;
3605 stack_depth_53 = stack_depth_49 + 1;
3606
3607 # stack_depth_1 = PHI <stack_depth_24(2), stack_depth_53(3)>
3608instr9:
3609/* RETURN */:
3610 stack_depth_54 = stack_depth_1 + -1;
3611 x_55 = stack[stack_depth_54];
3612 _56 = x_55;
3613 stack =@{v@} @{CLOBBER@};
3614 return _56;
3615
3616@}
3617@end example
3618
3619@noindent
3620
eac6fba2 3621Note in the above how all the @pxref{28,,gcc_jit_block} instances we
863e76f9 3622created have been consolidated into just 3 blocks in GCC's internal
3623representation: @code{initial}, @code{instr4} and @code{instr9}.
3624
3625@menu
3626* Optimizing away stack manipulation::
3627* Elimination of tail recursion::
3628
3629@end menu
3630
3631@node Optimizing away stack manipulation,Elimination of tail recursion,,Behind the curtain How does our code get optimized?
eac6fba2 3632@anchor{intro/tutorial04 optimizing-away-stack-manipulation}@anchor{46}
863e76f9 3633@subsubsection Optimizing away stack manipulation
3634
3635
3636Recall our simple implementation of stack operations. Let's examine
3637how the stack operations are optimized away.
3638
3639After a pass of constant-propagation, the depth of the stack at each
3640opcode can be determined at compile-time:
3641
3642@example
3643$ less /tmp/libgccjit-1Hywc0/fake.c.021t.ccp1
3644@end example
3645
3646@noindent
3647
3648@example
3649;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
3650
3651factorial (signed int arg)
3652@{
3653 signed int stack[8];
3654 signed int stack_depth;
3655 signed int x;
3656 signed int y;
3657 <unnamed type> _20;
3658 signed int _21;
3659 signed int _38;
3660 signed int _44;
3661 signed int _51;
3662
3663initial:
3664 stack[0] = arg_5(D);
3665 x_9 = stack[0];
3666 stack[0] = x_9;
3667 stack[1] = x_9;
3668 stack[2] = 2;
3669 y_17 = stack[2];
3670 x_19 = stack[1];
3671 _20 = x_19 < y_17;
3672 _21 = (signed int) _20;
3673 stack[1] = _21;
3674 x_25 = stack[1];
3675 if (x_25 != 0)
3676 goto <bb 4> (instr9);
3677 else
3678 goto <bb 3> (instr4);
3679
3680instr4:
3681/* DUP */:
3682 x_27 = stack[0];
3683 stack[0] = x_27;
3684 stack[1] = x_27;
3685 stack[2] = 1;
3686 y_35 = stack[2];
3687 x_37 = stack[1];
3688 _38 = x_37 - y_35;
3689 stack[1] = _38;
3690 x_42 = stack[1];
3691 _44 = factorial (x_42);
3692 stack[1] = _44;
3693 y_48 = stack[1];
3694 x_50 = stack[0];
3695 _51 = x_50 * y_48;
3696 stack[0] = _51;
3697
3698instr9:
3699/* RETURN */:
3700 x_55 = stack[0];
3701 x_56 = x_55;
3702 stack =@{v@} @{CLOBBER@};
3703 return x_56;
3704
3705@}
3706@end example
3707
3708@noindent
3709
3710Note how, in the above, all those @code{stack_depth} values are now just
3711constants: we're accessing specific stack locations at each opcode.
3712
3713The "esra" pass ("Early Scalar Replacement of Aggregates") breaks
3714out our "stack" array into individual elements:
3715
3716@example
3717$ less /tmp/libgccjit-1Hywc0/fake.c.024t.esra
3718@end example
3719
3720@noindent
3721
3722@example
3723;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
3724
3725Created a replacement for stack offset: 0, size: 32: stack$0
3726Created a replacement for stack offset: 32, size: 32: stack$1
3727Created a replacement for stack offset: 64, size: 32: stack$2
3728
3729Symbols to be put in SSA form
3730@{ D.89 D.90 D.91 @}
3731Incremental SSA update started at block: 0
3732Number of blocks in CFG: 5
3733Number of blocks to update: 4 ( 80%)
3734
3735
3736factorial (signed int arg)
3737@{
3738 signed int stack$2;
3739 signed int stack$1;
3740 signed int stack$0;
3741 signed int stack[8];
3742 signed int stack_depth;
3743 signed int x;
3744 signed int y;
3745 <unnamed type> _20;
3746 signed int _21;
3747 signed int _38;
3748 signed int _44;
3749 signed int _51;
3750
3751initial:
3752 stack$0_45 = arg_5(D);
3753 x_9 = stack$0_45;
3754 stack$0_39 = x_9;
3755 stack$1_32 = x_9;
3756 stack$2_30 = 2;
3757 y_17 = stack$2_30;
3758 x_19 = stack$1_32;
3759 _20 = x_19 < y_17;
3760 _21 = (signed int) _20;
3761 stack$1_28 = _21;
3762 x_25 = stack$1_28;
3763 if (x_25 != 0)
3764 goto <bb 4> (instr9);
3765 else
3766 goto <bb 3> (instr4);
3767
3768instr4:
3769/* DUP */:
3770 x_27 = stack$0_39;
3771 stack$0_22 = x_27;
3772 stack$1_14 = x_27;
3773 stack$2_12 = 1;
3774 y_35 = stack$2_12;
3775 x_37 = stack$1_14;
3776 _38 = x_37 - y_35;
3777 stack$1_10 = _38;
3778 x_42 = stack$1_10;
3779 _44 = factorial (x_42);
3780 stack$1_6 = _44;
3781 y_48 = stack$1_6;
3782 x_50 = stack$0_22;
3783 _51 = x_50 * y_48;
3784 stack$0_1 = _51;
3785
3786 # stack$0_52 = PHI <stack$0_39(2), stack$0_1(3)>
3787instr9:
3788/* RETURN */:
3789 x_55 = stack$0_52;
3790 x_56 = x_55;
3791 stack =@{v@} @{CLOBBER@};
3792 return x_56;
3793
3794@}
3795@end example
3796
3797@noindent
3798
3799Hence at this point, all those pushes and pops of the stack are now
3800simply assignments to specific temporary variables.
3801
3802After some copy propagation, the stack manipulation has been completely
3803optimized away:
3804
3805@example
3806$ less /tmp/libgccjit-1Hywc0/fake.c.026t.copyprop1
3807@end example
3808
3809@noindent
3810
3811@example
3812;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
3813
3814factorial (signed int arg)
3815@{
3816 signed int stack$2;
3817 signed int stack$1;
3818 signed int stack$0;
3819 signed int stack[8];
3820 signed int stack_depth;
3821 signed int x;
3822 signed int y;
3823 <unnamed type> _20;
3824 signed int _21;
3825 signed int _38;
3826 signed int _44;
3827 signed int _51;
3828
3829initial:
3830 stack$0_39 = arg_5(D);
3831 _20 = arg_5(D) <= 1;
3832 _21 = (signed int) _20;
3833 if (_21 != 0)
3834 goto <bb 4> (instr9);
3835 else
3836 goto <bb 3> (instr4);
3837
3838instr4:
3839/* DUP */:
3840 _38 = arg_5(D) + -1;
3841 _44 = factorial (_38);
3842 _51 = arg_5(D) * _44;
3843 stack$0_1 = _51;
3844
3845 # stack$0_52 = PHI <arg_5(D)(2), _51(3)>
3846instr9:
3847/* RETURN */:
3848 stack =@{v@} @{CLOBBER@};
3849 return stack$0_52;
3850
3851@}
3852@end example
3853
3854@noindent
3855
3856Later on, another pass finally eliminated @code{stack_depth} local and the
3857unused parts of the @cite{stack`} array altogether:
3858
3859@example
3860$ less /tmp/libgccjit-1Hywc0/fake.c.036t.release_ssa
3861@end example
3862
3863@noindent
3864
3865@example
3866;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
3867
3868Released 44 names, 314.29%, removed 44 holes
3869factorial (signed int arg)
3870@{
3871 signed int stack$0;
3872 signed int mult_acc_1;
3873 <unnamed type> _5;
3874 signed int _6;
3875 signed int _7;
3876 signed int mul_tmp_10;
3877 signed int mult_acc_11;
3878 signed int mult_acc_13;
3879
3880 # arg_9 = PHI <arg_8(D)(0)>
3881 # mult_acc_13 = PHI <1(0)>
3882initial:
3883
3884 <bb 5>:
3885 # arg_4 = PHI <arg_9(2), _7(3)>
3886 # mult_acc_1 = PHI <mult_acc_13(2), mult_acc_11(3)>
3887 _5 = arg_4 <= 1;
3888 _6 = (signed int) _5;
3889 if (_6 != 0)
3890 goto <bb 4> (instr9);
3891 else
3892 goto <bb 3> (instr4);
3893
3894instr4:
3895/* DUP */:
3896 _7 = arg_4 + -1;
3897 mult_acc_11 = mult_acc_1 * arg_4;
3898 goto <bb 5>;
3899
3900 # stack$0_12 = PHI <arg_4(5)>
3901instr9:
3902/* RETURN */:
3903 mul_tmp_10 = mult_acc_1 * stack$0_12;
3904 return mul_tmp_10;
3905
3906@}
3907@end example
3908
3909@noindent
3910
3911@node Elimination of tail recursion,,Optimizing away stack manipulation,Behind the curtain How does our code get optimized?
eac6fba2 3912@anchor{intro/tutorial04 elimination-of-tail-recursion}@anchor{47}
863e76f9 3913@subsubsection Elimination of tail recursion
3914
3915
3916Another significant optimization is the detection that the call to
3917@code{factorial} is tail recursion, which can be eliminated in favor of
3918an iteration:
3919
3920@example
3921$ less /tmp/libgccjit-1Hywc0/fake.c.030t.tailr1
3922@end example
3923
3924@noindent
3925
3926@example
3927;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
3928
3929
3930Symbols to be put in SSA form
3931@{ D.88 @}
3932Incremental SSA update started at block: 0
3933Number of blocks in CFG: 5
3934Number of blocks to update: 4 ( 80%)
3935
3936
3937factorial (signed int arg)
3938@{
3939 signed int stack$2;
3940 signed int stack$1;
3941 signed int stack$0;
3942 signed int stack[8];
3943 signed int stack_depth;
3944 signed int x;
3945 signed int y;
3946 signed int mult_acc_1;
3947 <unnamed type> _20;
3948 signed int _21;
3949 signed int _38;
3950 signed int mul_tmp_44;
3951 signed int mult_acc_51;
3952
3953 # arg_5 = PHI <arg_39(D)(0), _38(3)>
3954 # mult_acc_1 = PHI <1(0), mult_acc_51(3)>
3955initial:
3956 _20 = arg_5 <= 1;
3957 _21 = (signed int) _20;
3958 if (_21 != 0)
3959 goto <bb 4> (instr9);
3960 else
3961 goto <bb 3> (instr4);
3962
3963instr4:
3964/* DUP */:
3965 _38 = arg_5 + -1;
3966 mult_acc_51 = mult_acc_1 * arg_5;
3967 goto <bb 2> (initial);
3968
3969 # stack$0_52 = PHI <arg_5(2)>
3970instr9:
3971/* RETURN */:
3972 stack =@{v@} @{CLOBBER@};
3973 mul_tmp_44 = mult_acc_1 * stack$0_52;
3974 return mul_tmp_44;
3975
3976@}
3977@end example
3978
3979@noindent
3980
f1717362 3981@c Copyright (C) 2015-2016 Free Software Foundation, Inc.
69834ed9 3982@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
3983@c
3984@c This is free software: you can redistribute it and/or modify it
3985@c under the terms of the GNU General Public License as published by
3986@c the Free Software Foundation, either version 3 of the License, or
3987@c (at your option) any later version.
3988@c
3989@c This program is distributed in the hope that it will be useful, but
3990@c WITHOUT ANY WARRANTY; without even the implied warranty of
3991@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3992@c General Public License for more details.
3993@c
3994@c You should have received a copy of the GNU General Public License
3995@c along with this program. If not, see
3996@c <http://www.gnu.org/licenses/>.
3997
3998@node Tutorial part 5 Implementing an Ahead-of-Time compiler,,Tutorial part 4 Adding JIT-compilation to a toy interpreter,Tutorial
3999@anchor{intro/tutorial05 doc}@anchor{48}@anchor{intro/tutorial05 tutorial-part-5-implementing-an-ahead-of-time-compiler}@anchor{49}
4000@section Tutorial part 5: Implementing an Ahead-of-Time compiler
4001
4002
4003If you have a pre-existing language frontend that's compatible with
4004libgccjit's license, it's possible to hook it up to libgccjit as a
4005backend. In the previous example we showed
4006how to do that for in-memory JIT-compilation, but libgccjit can also
4007compile code directly to a file, allowing you to implement a more
4008traditional ahead-of-time compiler ("JIT" is something of a misnomer
4009for this use-case).
4010
4011The essential difference is to compile the context using
4012@pxref{4a,,gcc_jit_context_compile_to_file()} rather than
4013@pxref{15,,gcc_jit_context_compile()}.
4014
4015@menu
4016* The "brainf" language::
4017* Converting a brainf script to libgccjit IR::
4018* Compiling a context to a file::
4019* Other forms of ahead-of-time-compilation::
4020
4021@end menu
4022
4023@node The "brainf" language,Converting a brainf script to libgccjit IR,,Tutorial part 5 Implementing an Ahead-of-Time compiler
4024@anchor{intro/tutorial05 the-brainf-language}@anchor{4b}
4025@subsection The "brainf" language
4026
4027
4028In this example we use libgccjit to construct an ahead-of-time compiler
4029for an esoteric programming language that we shall refer to as "brainf".
4030
4031brainf scripts operate on an array of bytes, with a notional data pointer
4032within the array.
4033
4034brainf is hard for humans to read, but it's trivial to write a parser for
4035it, as there is no lexing; just a stream of bytes. The operations are:
4036
4037
4038@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
4039@headitem
4040
4041Character
4042
4043@tab
4044
4045Meaning
4046
4047@item
4048
4049@code{>}
4050
4051@tab
4052
4053@code{idx += 1}
4054
4055@item
4056
4057@code{<}
4058
4059@tab
4060
4061@code{idx -= 1}
4062
4063@item
4064
4065@code{+}
4066
4067@tab
4068
4069@code{data[idx] += 1}
4070
4071@item
4072
4073@code{-}
4074
4075@tab
4076
4077@code{data[idx] -= 1}
4078
4079@item
4080
4081@code{.}
4082
4083@tab
4084
4085@code{output (data[idx])}
4086
4087@item
4088
4089@code{,}
4090
4091@tab
4092
4093@code{data[idx] = input ()}
4094
4095@item
4096
4097@code{[}
4098
4099@tab
4100
4101loop until @code{data[idx] == 0}
4102
4103@item
4104
4105@code{]}
4106
4107@tab
4108
4109end of loop
4110
4111@item
4112
4113Anything else
4114
4115@tab
4116
4117ignored
4118
4119@end multitable
4120
4121
4122Unlike the previous example, we'll implement an ahead-of-time compiler,
4123which reads @code{.bf} scripts and outputs executables (though it would
4124be trivial to have it run them JIT-compiled in-process).
4125
4126Here's what a simple @code{.bf} script looks like:
4127
4128@quotation
4129
4130@example
4131[
4132 Emit the uppercase alphabet
4133]
4134
4135cell 0 = 26
4136++++++++++++++++++++++++++
4137
4138cell 1 = 65
4139>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
4140
4141while cell#0 != 0
4142[
4143 >
4144 . emit cell#1
4145 + increment cell@@1
4146 <- decrement cell@@0
4147]
4148
4149@end example
4150
4151@noindent
4152@end quotation
4153
4154@cartouche
4155@quotation Note
4156This example makes use of whitespace and comments for legibility, but
4157could have been written as:
4158
4159@example
4160++++++++++++++++++++++++++
4161>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
4162[>.+<-]
4163@end example
4164
4165@noindent
4166
4167It's not a particularly useful language, except for providing
4168compiler-writers with a test case that's easy to parse. The point
4169is that you can use @pxref{4a,,gcc_jit_context_compile_to_file()}
4170to use libgccjit as a backend for a pre-existing language frontend
4171(provided that the pre-existing frontend is compatible with libgccjit's
4172license).
4173@end quotation
4174@end cartouche
4175
4176@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
4177@anchor{intro/tutorial05 converting-a-brainf-script-to-libgccjit-ir}@anchor{4c}
4178@subsection Converting a brainf script to libgccjit IR
4179
4180
4181As before we write simple code to populate a @pxref{8,,gcc_jit_context *}.
4182
4183@quotation
4184
4185@example
4186
4187typedef struct bf_compiler
4188@{
4189 const char *filename;
4190 int line;
4191 int column;
4192
4193 gcc_jit_context *ctxt;
4194
4195 gcc_jit_type *void_type;
4196 gcc_jit_type *int_type;
4197 gcc_jit_type *byte_type;
4198 gcc_jit_type *array_type;
4199
4200 gcc_jit_function *func_getchar;
4201 gcc_jit_function *func_putchar;
4202
4203 gcc_jit_function *func;
4204 gcc_jit_block *curblock;
4205
4206 gcc_jit_rvalue *int_zero;
4207 gcc_jit_rvalue *int_one;
4208 gcc_jit_rvalue *byte_zero;
4209 gcc_jit_rvalue *byte_one;
4210 gcc_jit_lvalue *data_cells;
4211 gcc_jit_lvalue *idx;
4212
4213 int num_open_parens;
4214 gcc_jit_block *paren_test[MAX_OPEN_PARENS];
4215 gcc_jit_block *paren_body[MAX_OPEN_PARENS];
4216 gcc_jit_block *paren_after[MAX_OPEN_PARENS];
4217
4218@} bf_compiler;
4219
4220/* Bail out, with a message on stderr. */
4221
4222static void
4223fatal_error (bf_compiler *bfc, const char *msg)
4224@{
4225 fprintf (stderr,
4226 "%s:%i:%i: %s",
4227 bfc->filename, bfc->line, bfc->column, msg);
4228 abort ();
4229@}
4230
4231/* Get "data_cells[idx]" as an lvalue. */
4232
4233static gcc_jit_lvalue *
4234bf_get_current_data (bf_compiler *bfc, gcc_jit_location *loc)
4235@{
4236 return gcc_jit_context_new_array_access (
4237 bfc->ctxt,
4238 loc,
4239 gcc_jit_lvalue_as_rvalue (bfc->data_cells),
4240 gcc_jit_lvalue_as_rvalue (bfc->idx));
4241@}
4242
4243/* Get "data_cells[idx] == 0" as a boolean rvalue. */
4244
4245static gcc_jit_rvalue *
4246bf_current_data_is_zero (bf_compiler *bfc, gcc_jit_location *loc)
4247@{
4248 return gcc_jit_context_new_comparison (
4249 bfc->ctxt,
4250 loc,
4251 GCC_JIT_COMPARISON_EQ,
4252 gcc_jit_lvalue_as_rvalue (bf_get_current_data (bfc, loc)),
4253 bfc->byte_zero);
4254@}
4255
4256/* Compile one bf character. */
4257
4258static void
4259bf_compile_char (bf_compiler *bfc,
4260 unsigned char ch)
4261@{
4262 gcc_jit_location *loc =
4263 gcc_jit_context_new_location (bfc->ctxt,
4264 bfc->filename,
4265 bfc->line,
4266 bfc->column);
4267
4268 /* Turn this on to trace execution, by injecting putchar ()
4269 of each source char. */
4270 if (0)
4271 @{
4272 gcc_jit_rvalue *arg =
4273 gcc_jit_context_new_rvalue_from_int (
4274 bfc->ctxt,
4275 bfc->int_type,
4276 ch);
4277 gcc_jit_rvalue *call =
4278 gcc_jit_context_new_call (bfc->ctxt,
4279 loc,
4280 bfc->func_putchar,
4281 1, &arg);
4282 gcc_jit_block_add_eval (bfc->curblock,
4283 loc,
4284 call);
4285 @}
4286
4287 switch (ch)
4288 @{
4289 case '>':
4290 gcc_jit_block_add_comment (bfc->curblock,
4291 loc,
4292 "'>': idx += 1;");
4293 gcc_jit_block_add_assignment_op (bfc->curblock,
4294 loc,
4295 bfc->idx,
4296 GCC_JIT_BINARY_OP_PLUS,
4297 bfc->int_one);
4298 break;
4299
4300 case '<':
4301 gcc_jit_block_add_comment (bfc->curblock,
4302 loc,
4303 "'<': idx -= 1;");
4304 gcc_jit_block_add_assignment_op (bfc->curblock,
4305 loc,
4306 bfc->idx,
4307 GCC_JIT_BINARY_OP_MINUS,
4308 bfc->int_one);
4309 break;
4310
4311 case '+':
4312 gcc_jit_block_add_comment (bfc->curblock,
4313 loc,
4314 "'+': data[idx] += 1;");
4315 gcc_jit_block_add_assignment_op (bfc->curblock,
4316 loc,
4317 bf_get_current_data (bfc, loc),
4318 GCC_JIT_BINARY_OP_PLUS,
4319 bfc->byte_one);
4320 break;
4321
4322 case '-':
4323 gcc_jit_block_add_comment (bfc->curblock,
4324 loc,
4325 "'-': data[idx] -= 1;");
4326 gcc_jit_block_add_assignment_op (bfc->curblock,
4327 loc,
4328 bf_get_current_data (bfc, loc),
4329 GCC_JIT_BINARY_OP_MINUS,
4330 bfc->byte_one);
4331 break;
4332
4333 case '.':
4334 @{
4335 gcc_jit_rvalue *arg =
4336 gcc_jit_context_new_cast (
4337 bfc->ctxt,
4338 loc,
4339 gcc_jit_lvalue_as_rvalue (bf_get_current_data (bfc, loc)),
4340 bfc->int_type);
4341 gcc_jit_rvalue *call =
4342 gcc_jit_context_new_call (bfc->ctxt,
4343 loc,
4344 bfc->func_putchar,
4345 1, &arg);
4346 gcc_jit_block_add_comment (bfc->curblock,
4347 loc,
4348 "'.': putchar ((int)data[idx]);");
4349 gcc_jit_block_add_eval (bfc->curblock,
4350 loc,
4351 call);
4352 @}
4353 break;
4354
4355 case ',':
4356 @{
4357 gcc_jit_rvalue *call =
4358 gcc_jit_context_new_call (bfc->ctxt,
4359 loc,
4360 bfc->func_getchar,
4361 0, NULL);
4362 gcc_jit_block_add_comment (
4363 bfc->curblock,
4364 loc,
4365 "',': data[idx] = (unsigned char)getchar ();");
4366 gcc_jit_block_add_assignment (bfc->curblock,
4367 loc,
4368 bf_get_current_data (bfc, loc),
4369 gcc_jit_context_new_cast (
4370 bfc->ctxt,
4371 loc,
4372 call,
4373 bfc->byte_type));
4374 @}
4375 break;
4376
4377 case '[':
4378 @{
4379 gcc_jit_block *loop_test =
4380 gcc_jit_function_new_block (bfc->func, NULL);
4381 gcc_jit_block *on_zero =
4382 gcc_jit_function_new_block (bfc->func, NULL);
4383 gcc_jit_block *on_non_zero =
4384 gcc_jit_function_new_block (bfc->func, NULL);
4385
4386 if (bfc->num_open_parens == MAX_OPEN_PARENS)
4387 fatal_error (bfc, "too many open parens");
4388
4389 gcc_jit_block_end_with_jump (
4390 bfc->curblock,
4391 loc,
4392 loop_test);
4393
4394 gcc_jit_block_add_comment (
4395 loop_test,
4396 loc,
4397 "'['");
4398 gcc_jit_block_end_with_conditional (
4399 loop_test,
4400 loc,
4401 bf_current_data_is_zero (bfc, loc),
4402 on_zero,
4403 on_non_zero);
4404 bfc->paren_test[bfc->num_open_parens] = loop_test;
4405 bfc->paren_body[bfc->num_open_parens] = on_non_zero;
4406 bfc->paren_after[bfc->num_open_parens] = on_zero;
4407 bfc->num_open_parens += 1;
4408 bfc->curblock = on_non_zero;
4409 @}
4410 break;
4411
4412 case ']':
4413 @{
4414 gcc_jit_block_add_comment (
4415 bfc->curblock,
4416 loc,
4417 "']'");
4418
4419 if (bfc->num_open_parens == 0)
4420 fatal_error (bfc, "mismatching parens");
4421 bfc->num_open_parens -= 1;
4422 gcc_jit_block_end_with_jump (
4423 bfc->curblock,
4424 loc,
4425 bfc->paren_test[bfc->num_open_parens]);
4426 bfc->curblock = bfc->paren_after[bfc->num_open_parens];
4427 @}
4428 break;
4429
4430 case '\n':
4431 bfc->line +=1;
4432 bfc->column = 0;
4433 break;
4434 @}
4435
4436 if (ch != '\n')
4437 bfc->column += 1;
4438@}
4439
4440/* Compile the given .bf file into a gcc_jit_context, containing a
4441 single "main" function suitable for compiling into an executable. */
4442
4443gcc_jit_context *
4444bf_compile (const char *filename)
4445@{
4446 bf_compiler bfc;
4447 FILE *f_in;
4448 int ch;
4449
4450 memset (&bfc, 0, sizeof (bfc));
4451
4452 bfc.filename = filename;
4453 f_in = fopen (filename, "r");
4454 if (!f_in)
4455 fatal_error (&bfc, "unable to open file");
4456 bfc.line = 1;
4457
4458 bfc.ctxt = gcc_jit_context_acquire ();
4459
4460 gcc_jit_context_set_int_option (
4461 bfc.ctxt,
4462 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
4463 3);
4464 gcc_jit_context_set_bool_option (
4465 bfc.ctxt,
4466 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE,
4467 0);
4468 gcc_jit_context_set_bool_option (
4469 bfc.ctxt,
4470 GCC_JIT_BOOL_OPTION_DEBUGINFO,
4471 1);
4472 gcc_jit_context_set_bool_option (
4473 bfc.ctxt,
4474 GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING,
4475 0);
4476 gcc_jit_context_set_bool_option (
4477 bfc.ctxt,
4478 GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES,
4479 0);
4480
4481 bfc.void_type =
4482 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_VOID);
4483 bfc.int_type =
4484 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_INT);
4485 bfc.byte_type =
4486 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_UNSIGNED_CHAR);
4487 bfc.array_type =
4488 gcc_jit_context_new_array_type (bfc.ctxt,
4489 NULL,
4490 bfc.byte_type,
4491 30000);
4492
4493 bfc.func_getchar =
4494 gcc_jit_context_new_function (bfc.ctxt, NULL,
4495 GCC_JIT_FUNCTION_IMPORTED,
4496 bfc.int_type,
4497 "getchar",
4498 0, NULL,
4499 0);
4500
4501 gcc_jit_param *param_c =
4502 gcc_jit_context_new_param (bfc.ctxt, NULL, bfc.int_type, "c");
4503 bfc.func_putchar =
4504 gcc_jit_context_new_function (bfc.ctxt, NULL,
4505 GCC_JIT_FUNCTION_IMPORTED,
4506 bfc.void_type,
4507 "putchar",
4508 1, &param_c,
4509 0);
4510
4511 bfc.func = make_main (bfc.ctxt);
4512 bfc.curblock =
4513 gcc_jit_function_new_block (bfc.func, "initial");
4514 bfc.int_zero = gcc_jit_context_zero (bfc.ctxt, bfc.int_type);
4515 bfc.int_one = gcc_jit_context_one (bfc.ctxt, bfc.int_type);
4516 bfc.byte_zero = gcc_jit_context_zero (bfc.ctxt, bfc.byte_type);
4517 bfc.byte_one = gcc_jit_context_one (bfc.ctxt, bfc.byte_type);
4518
4519 bfc.data_cells =
4520 gcc_jit_context_new_global (bfc.ctxt, NULL,
4521 GCC_JIT_GLOBAL_INTERNAL,
4522 bfc.array_type,
4523 "data_cells");
4524 bfc.idx =
4525 gcc_jit_function_new_local (bfc.func, NULL,
4526 bfc.int_type,
4527 "idx");
4528
4529 gcc_jit_block_add_comment (bfc.curblock,
4530 NULL,
4531 "idx = 0;");
4532 gcc_jit_block_add_assignment (bfc.curblock,
4533 NULL,
4534 bfc.idx,
4535 bfc.int_zero);
4536
4537 bfc.num_open_parens = 0;
4538
4539 while ( EOF != (ch = fgetc (f_in)))
4540 bf_compile_char (&bfc, (unsigned char)ch);
4541
4542 gcc_jit_block_end_with_return (bfc.curblock, NULL, bfc.int_zero);
4543
4544 fclose (f_in);
4545
4546 return bfc.ctxt;
4547@}
4548
4549
4550@end example
4551
4552@noindent
4553@end quotation
4554
4555@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
4556@anchor{intro/tutorial05 compiling-a-context-to-a-file}@anchor{4d}
4557@subsection Compiling a context to a file
4558
4559
4560Unlike the previous tutorial, this time we'll compile the context
4561directly to an executable, using @pxref{4a,,gcc_jit_context_compile_to_file()}:
4562
4563@example
4564gcc_jit_context_compile_to_file (ctxt,
4565 GCC_JIT_OUTPUT_KIND_EXECUTABLE,
4566 output_file);
4567@end example
4568
4569@noindent
4570
4571Here's the top-level of the compiler, which is what actually calls into
4572@pxref{4a,,gcc_jit_context_compile_to_file()}:
4573
4574@quotation
4575
4576@example
4577
4578int
4579main (int argc, char **argv)
4580@{
4581 const char *input_file;
4582 const char *output_file;
4583 gcc_jit_context *ctxt;
4584 const char *err;
4585
4586 if (argc != 3)
4587 @{
4588 fprintf (stderr, "%s: INPUT_FILE OUTPUT_FILE\n", argv[0]);
4589 return 1;
4590 @}
4591
4592 input_file = argv[1];
4593 output_file = argv[2];
4594 ctxt = bf_compile (input_file);
4595
4596 gcc_jit_context_compile_to_file (ctxt,
4597 GCC_JIT_OUTPUT_KIND_EXECUTABLE,
4598 output_file);
4599
4600 err = gcc_jit_context_get_first_error (ctxt);
4601
4602 if (err)
4603 @{
4604 gcc_jit_context_release (ctxt);
4605 return 1;
4606 @}
4607
4608 gcc_jit_context_release (ctxt);
4609 return 0;
4610@}
4611
4612
4613@end example
4614
4615@noindent
4616@end quotation
4617
4618Note how once the context is populated you could trivially instead compile
4619it to memory using @pxref{15,,gcc_jit_context_compile()} and run it in-process
4620as in the previous tutorial.
4621
4622To create an executable, we need to export a @code{main} function. Here's
4623how to create one from the JIT API:
4624
4625@quotation
4626
4627@example
4628
4629/* Make "main" function:
4630 int
4631 main (int argc, char **argv)
4632 @{
4633 ...
4634 @}
4635*/
4636static gcc_jit_function *
4637make_main (gcc_jit_context *ctxt)
4638@{
4639 gcc_jit_type *int_type =
4640 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
4641 gcc_jit_param *param_argc =
4642 gcc_jit_context_new_param (ctxt, NULL, int_type, "argc");
4643 gcc_jit_type *char_ptr_ptr_type =
4644 gcc_jit_type_get_pointer (
4645 gcc_jit_type_get_pointer (
4646 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR)));
4647 gcc_jit_param *param_argv =
4648 gcc_jit_context_new_param (ctxt, NULL, char_ptr_ptr_type, "argv");
4649 gcc_jit_param *params[2] = @{param_argc, param_argv@};
4650 gcc_jit_function *func_main =
4651 gcc_jit_context_new_function (ctxt, NULL,
4652 GCC_JIT_FUNCTION_EXPORTED,
4653 int_type,
4654 "main",
4655 2, params,
4656 0);
4657 return func_main;
4658@}
4659
4660
4661@end example
4662
4663@noindent
4664@end quotation
4665
4666@cartouche
4667@quotation Note
4668The above implementation ignores @code{argc} and @code{argv}, but you could
4669make use of them by exposing @code{param_argc} and @code{param_argv} to the
4670caller.
4671@end quotation
4672@end cartouche
4673
4674Upon compiling this C code, we obtain a bf-to-machine-code compiler;
4675let's call it @code{bfc}:
4676
4677@example
4678$ gcc \
4679 tut05-bf.c \
4680 -o bfc \
4681 -lgccjit
4682@end example
4683
4684@noindent
4685
4686We can now use @code{bfc} to compile .bf files into machine code executables:
4687
4688@example
4689$ ./bfc \
4690 emit-alphabet.bf \
4691 a.out
4692@end example
4693
4694@noindent
4695
4696which we can run directly:
4697
4698@example
4699$ ./a.out
4700ABCDEFGHIJKLMNOPQRSTUVWXYZ
4701@end example
4702
4703@noindent
4704
4705Success!
4706
4707We can also inspect the generated executable using standard tools:
4708
4709@example
4710$ objdump -d a.out |less
4711@end example
4712
4713@noindent
4714
4715which shows that libgccjit has managed to optimize the function
4716somewhat (for example, the runs of 26 and 65 increment operations
4717have become integer constants 0x1a and 0x41):
4718
4719@example
47200000000000400620 <main>:
4721 400620: 80 3d 39 0a 20 00 00 cmpb $0x0,0x200a39(%rip) # 601060 <data
4722 400627: 74 07 je 400630 <main
4723 400629: eb fe jmp 400629 <main+0x9>
4724 40062b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
4725 400630: 48 83 ec 08 sub $0x8,%rsp
4726 400634: 0f b6 05 26 0a 20 00 movzbl 0x200a26(%rip),%eax # 601061 <data_cells+0x1>
4727 40063b: c6 05 1e 0a 20 00 1a movb $0x1a,0x200a1e(%rip) # 601060 <data_cells>
4728 400642: 8d 78 41 lea 0x41(%rax),%edi
4729 400645: 40 88 3d 15 0a 20 00 mov %dil,0x200a15(%rip) # 601061 <data_cells+0x1>
4730 40064c: 0f 1f 40 00 nopl 0x0(%rax)
4731 400650: 40 0f b6 ff movzbl %dil,%edi
4732 400654: e8 87 fe ff ff callq 4004e0 <putchar@@plt>
4733 400659: 0f b6 05 01 0a 20 00 movzbl 0x200a01(%rip),%eax # 601061 <data_cells+0x1>
4734 400660: 80 2d f9 09 20 00 01 subb $0x1,0x2009f9(%rip) # 601060 <data_cells>
4735 400667: 8d 78 01 lea 0x1(%rax),%edi
4736 40066a: 40 88 3d f0 09 20 00 mov %dil,0x2009f0(%rip) # 601061 <data_cells+0x1>
4737 400671: 75 dd jne 400650 <main+0x30>
4738 400673: 31 c0 xor %eax,%eax
4739 400675: 48 83 c4 08 add $0x8,%rsp
4740 400679: c3 retq
4741 40067a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
4742@end example
4743
4744@noindent
4745
4746We also set up debugging information (via
4747@pxref{41,,gcc_jit_context_new_location()} and
4748@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO}), so it's possible to use @code{gdb}
4749to singlestep through the generated binary and inspect the internal
4750state @code{idx} and @code{data_cells}:
4751
4752@example
4753(gdb) break main
4754Breakpoint 1 at 0x400790
4755(gdb) run
4756Starting program: a.out
4757
4758Breakpoint 1, 0x0000000000400790 in main (argc=1, argv=0x7fffffffe448)
4759(gdb) stepi
47600x0000000000400797 in main (argc=1, argv=0x7fffffffe448)
4761(gdb) stepi
47620x00000000004007a0 in main (argc=1, argv=0x7fffffffe448)
4763(gdb) stepi
47649 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
4765(gdb) list
47664
47675 cell 0 = 26
47686 ++++++++++++++++++++++++++
47697
47708 cell 1 = 65
47719 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
477210
477311 while cell#0 != 0
477412 [
477513 >
4776(gdb) n
47776 ++++++++++++++++++++++++++
4778(gdb) n
47799 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
4780(gdb) p idx
4781$1 = 1
4782(gdb) p data_cells
4783$2 = "\032", '\000' <repeats 29998 times>
4784(gdb) p data_cells[0]
4785$3 = 26 '\032'
4786(gdb) p data_cells[1]
4787$4 = 0 '\000'
4788(gdb) list
47894
47905 cell 0 = 26
47916 ++++++++++++++++++++++++++
47927
47938 cell 1 = 65
47949 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
479510
479611 while cell#0 != 0
479712 [
479813 >
4799@end example
4800
4801@noindent
4802
4803@node Other forms of ahead-of-time-compilation,,Compiling a context to a file,Tutorial part 5 Implementing an Ahead-of-Time compiler
4804@anchor{intro/tutorial05 other-forms-of-ahead-of-time-compilation}@anchor{4e}
4805@subsection Other forms of ahead-of-time-compilation
4806
4807
4808The above demonstrates compiling a @pxref{8,,gcc_jit_context *} directly
4809to an executable. It's also possible to compile it to an object file,
4810and to a dynamic library. See the documentation of
4811@pxref{4a,,gcc_jit_context_compile_to_file()} for more information.
4812
f1717362 4813@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 4814@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
4815@c
4816@c This is free software: you can redistribute it and/or modify it
4817@c under the terms of the GNU General Public License as published by
4818@c the Free Software Foundation, either version 3 of the License, or
4819@c (at your option) any later version.
4820@c
4821@c This program is distributed in the hope that it will be useful, but
4822@c WITHOUT ANY WARRANTY; without even the implied warranty of
4823@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4824@c General Public License for more details.
4825@c
4826@c You should have received a copy of the GNU General Public License
4827@c along with this program. If not, see
4828@c <http://www.gnu.org/licenses/>.
4829
36b809a0 4830@node Topic Reference,C++ bindings for libgccjit,Tutorial,Top
69834ed9 4831@anchor{topics/index doc}@anchor{4f}@anchor{topics/index topic-reference}@anchor{50}
863e76f9 4832@chapter Topic Reference
4833
4834
f1717362 4835@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 4836@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
4837@c
4838@c This is free software: you can redistribute it and/or modify it
4839@c under the terms of the GNU General Public License as published by
4840@c the Free Software Foundation, either version 3 of the License, or
4841@c (at your option) any later version.
4842@c
4843@c This program is distributed in the hope that it will be useful, but
4844@c WITHOUT ANY WARRANTY; without even the implied warranty of
4845@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4846@c General Public License for more details.
4847@c
4848@c You should have received a copy of the GNU General Public License
4849@c along with this program. If not, see
4850@c <http://www.gnu.org/licenses/>.
4851
4852@menu
4853* Compilation contexts::
4854* Objects::
4855* Types::
4856* Expressions::
4857* Creating and using functions::
4858* Source Locations::
69834ed9 4859* Compiling a context::
adb2df55 4860* ABI and API compatibility::
17c0b84b 4861* Performance::
863e76f9 4862
4863Compilation contexts
4864
4865* Lifetime-management::
4866* Thread-safety::
eac6fba2 4867* Error-handling: Error-handling<2>.
863e76f9 4868* Debugging::
4869* Options: Options<2>.
4870
4871Options
4872
4873* String Options::
4874* Boolean options::
4875* Integer options::
adb2df55 4876* Additional command-line options::
863e76f9 4877
4878Types
4879
4880* Standard types::
4881* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile.
4882* Structures and unions::
4883
4884Expressions
4885
4886* Rvalues::
4887* Lvalues::
4888* Working with pointers@comma{} structs and unions: Working with pointers structs and unions.
4889
4890Rvalues
4891
4892* Simple expressions::
4893* Unary Operations::
4894* Binary Operations::
4895* Comparisons::
4896* Function calls::
4897* Type-coercion::
4898
4899Lvalues
4900
4901* Global variables::
4902
4903Creating and using functions
4904
4905* Params::
4906* Functions::
4907* Blocks::
4908* Statements::
4909
4910Source Locations
4911
4912* Faking it::
4913
69834ed9 4914Compiling a context
4915
4916* In-memory compilation::
4917* Ahead-of-time compilation::
4918
adb2df55 4919ABI and API compatibility
4920
4921* ABI symbol tags::
4922
4923ABI symbol tags
4924
4925* LIBGCCJIT_ABI_0::
4926* LIBGCCJIT_ABI_1::
04feb56e 4927* LIBGCCJIT_ABI_2::
a24ef8d2 4928* LIBGCCJIT_ABI_3::
17c0b84b 4929* LIBGCCJIT_ABI_4::
4930
4931Performance
4932
4933* The timing API::
adb2df55 4934
863e76f9 4935@end menu
4936
4937
4938@node Compilation contexts,Objects,,Topic Reference
69834ed9 4939@anchor{topics/contexts compilation-contexts}@anchor{51}@anchor{topics/contexts doc}@anchor{52}
863e76f9 4940@section Compilation contexts
4941
4942
4943@geindex gcc_jit_context (C type)
4944@anchor{topics/contexts gcc_jit_context}@anchor{8}
4945@deffn {C Type} gcc_jit_context
4946@end deffn
4947
4948The top-level of the API is the @pxref{8,,gcc_jit_context} type.
4949
4950A @pxref{8,,gcc_jit_context} instance encapsulates the state of a
4951compilation.
4952
4953You can set up options on it, and add types, functions and code.
4954Invoking @pxref{15,,gcc_jit_context_compile()} on it gives you a
4955@pxref{16,,gcc_jit_result}.
4956
4957@menu
4958* Lifetime-management::
4959* Thread-safety::
eac6fba2 4960* Error-handling: Error-handling<2>.
863e76f9 4961* Debugging::
4962* Options: Options<2>.
4963
4964@end menu
4965
4966@node Lifetime-management,Thread-safety,,Compilation contexts
69834ed9 4967@anchor{topics/contexts lifetime-management}@anchor{53}
863e76f9 4968@subsection Lifetime-management
4969
4970
4971Contexts are the unit of lifetime-management within the API: objects
4972have their lifetime bounded by the context they are created within, and
4973cleanup of such objects is done for you when the context is released.
4974
4975@geindex gcc_jit_context_acquire (C function)
4976@anchor{topics/contexts gcc_jit_context_acquire}@anchor{9}
4977@deffn {C Function} gcc_jit_context *gcc_jit_context_acquire (void)
4978
1b60fb1d 4979This function acquires a new @pxref{8,,gcc_jit_context *} instance,
863e76f9 4980which is independent of any others that may be present within this
4981process.
4982@end deffn
4983
4984@geindex gcc_jit_context_release (C function)
4985@anchor{topics/contexts gcc_jit_context_release}@anchor{c}
4986@deffn {C Function} void gcc_jit_context_release (gcc_jit_context@w{ }*ctxt)
4987
4988This function releases all resources associated with the given context.
4989Both the context itself and all of its @pxref{e,,gcc_jit_object *}
4990instances are cleaned up. It should be called exactly once on a given
4991context.
4992
4993It is invalid to use the context or any of its "contextual" objects
4994after calling this.
4995
4996@example
4997gcc_jit_context_release (ctxt);
4998@end example
4999
5000@noindent
5001@end deffn
5002
5003@geindex gcc_jit_context_new_child_context (C function)
69834ed9 5004@anchor{topics/contexts gcc_jit_context_new_child_context}@anchor{54}
863e76f9 5005@deffn {C Function} gcc_jit_context * gcc_jit_context_new_child_context (gcc_jit_context@w{ }*parent_ctxt)
5006
5007Given an existing JIT context, create a child context.
5008
5009The child inherits a copy of all option-settings from the parent.
5010
5011The child can reference objects created within the parent, but not
5012vice-versa.
5013
5014The lifetime of the child context must be bounded by that of the
5015parent: you should release a child context before releasing the parent
5016context.
5017
5018If you use a function from a parent context within a child context,
5019you have to compile the parent context before you can compile the
5020child context, and the gcc_jit_result of the parent context must
5021outlive the gcc_jit_result of the child context.
5022
5023This allows caching of shared initializations. For example, you could
5024create types and declarations of global functions in a parent context
5025once within a process, and then create child contexts whenever a
5026function or loop becomes hot. Each such child context can be used for
5027JIT-compiling just one function or loop, but can reference types
5028and helper functions created within the parent context.
5029
5030Contexts can be arbitrarily nested, provided the above rules are
5031followed, but it's probably not worth going above 2 or 3 levels, and
5032there will likely be a performance hit for such nesting.
5033@end deffn
5034
eac6fba2 5035@node Thread-safety,Error-handling<2>,Lifetime-management,Compilation contexts
69834ed9 5036@anchor{topics/contexts thread-safety}@anchor{55}
863e76f9 5037@subsection Thread-safety
5038
5039
36b809a0 5040Instances of @pxref{8,,gcc_jit_context *} created via
863e76f9 5041@pxref{9,,gcc_jit_context_acquire()} are independent from each other:
5042only one thread may use a given context at once, but multiple threads
5043could each have their own contexts without needing locks.
5044
69834ed9 5045Contexts created via @pxref{54,,gcc_jit_context_new_child_context()} are
863e76f9 5046related to their parent context. They can be partitioned by their
5047ultimate ancestor into independent "family trees". Only one thread
5048within a process may use a given "family tree" of such contexts at once,
5049and if you're using multiple threads you should provide your own locking
5050around entire such context partitions.
5051
eac6fba2 5052@node Error-handling<2>,Debugging,Thread-safety,Compilation contexts
69834ed9 5053@anchor{topics/contexts error-handling}@anchor{19}@anchor{topics/contexts id1}@anchor{56}
863e76f9 5054@subsection Error-handling
5055
5056
eac6fba2 5057Various kinds of errors are possible when using the API, such as
5058mismatched types in an assignment. You can only compile and get code from
5059a context if no errors occur.
863e76f9 5060
5061Errors are printed on stderr and can be queried using
69834ed9 5062@pxref{57,,gcc_jit_context_get_first_error()}.
eac6fba2 5063
5064They typically contain the name of the API entrypoint where the error
5065occurred, and pertinent information on the problem:
5066
5067@example
5068./buggy-program: error: gcc_jit_block_add_assignment: mismatching types: assignment to i (type: int) from "hello world" (type: const char *)
5069@end example
5070
5071@noindent
5072
5073In general, if an error occurs when using an API entrypoint, the
5074entrypoint returns NULL. You don't have to check everywhere for NULL
5075results, since the API handles a NULL being passed in for any
5076argument by issuing another error. This typically leads to a cascade of
b56bc4a2 5077followup error messages, but is safe (albeit verbose). The first error
5078message is usually the one to pay attention to, since it is likely to
5079be responsible for all of the rest:
863e76f9 5080
5081@geindex gcc_jit_context_get_first_error (C function)
69834ed9 5082@anchor{topics/contexts gcc_jit_context_get_first_error}@anchor{57}
863e76f9 5083@deffn {C Function} const char * gcc_jit_context_get_first_error (gcc_jit_context@w{ }*ctxt)
5084
5085Returns the first error message that occurred on the context.
5086
5087The returned string is valid for the rest of the lifetime of the
5088context.
5089
5090If no errors occurred, this will be NULL.
5091@end deffn
5092
b56bc4a2 5093If you are wrapping the C API for a higher-level language that supports
625691b3 5094exception-handling, you may instead be interested in the last error that
b56bc4a2 5095occurred on the context, so that you can embed this in an exception:
5096
5097@geindex gcc_jit_context_get_last_error (C function)
69834ed9 5098@anchor{topics/contexts gcc_jit_context_get_last_error}@anchor{58}
b56bc4a2 5099@deffn {C Function} const char * gcc_jit_context_get_last_error (gcc_jit_context@w{ }*ctxt)
5100
5101Returns the last error message that occurred on the context.
5102
b56bc4a2 5103If no errors occurred, this will be NULL.
9cca2e95 5104
5105If non-NULL, the returned string is only guaranteed to be valid until
5106the next call to libgccjit relating to this context.
b56bc4a2 5107@end deffn
5108
eac6fba2 5109@node Debugging,Options<2>,Error-handling<2>,Compilation contexts
69834ed9 5110@anchor{topics/contexts debugging}@anchor{59}
863e76f9 5111@subsection Debugging
5112
5113
5114@geindex gcc_jit_context_dump_to_file (C function)
69834ed9 5115@anchor{topics/contexts gcc_jit_context_dump_to_file}@anchor{5a}
863e76f9 5116@deffn {C Function} void gcc_jit_context_dump_to_file (gcc_jit_context@w{ }*ctxt, const char@w{ }*path, int@w{ }update_locations)
5117
5118To help with debugging: dump a C-like representation to the given path,
5119describing what's been set up on the context.
5120
eac6fba2 5121If "update_locations" is true, then also set up @pxref{3b,,gcc_jit_location}
863e76f9 5122information throughout the context, pointing at the dump file as if it
5123were a source file. This may be of use in conjunction with
eac6fba2 5124@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to allow stepping through the
863e76f9 5125code in a debugger.
5126@end deffn
5127
3a9ccc11 5128@geindex gcc_jit_context_set_logfile (C function)
69834ed9 5129@anchor{topics/contexts gcc_jit_context_set_logfile}@anchor{5b}
3a9ccc11 5130@deffn {C Function} void gcc_jit_context_set_logfile (gcc_jit_context@w{ }*ctxt, FILE@w{ }*logfile, int@w{ }flags, int@w{ }verbosity)
5131
5132To help with debugging; enable ongoing logging of the context's
5133activity to the given file.
5134
5135For example, the following will enable logging to stderr.
5136
5137@example
5138gcc_jit_context_set_logfile (ctxt, stderr, 0, 0);
5139@end example
5140
5141@noindent
5142
5143Examples of information logged include:
5144
5145
5146@itemize *
5147
5148@item
5149API calls
5150
5151@item
5152the various steps involved within compilation
5153
5154@item
5155activity on any @pxref{16,,gcc_jit_result} instances created by
5156the context
5157
5158@item
5159activity within any child contexts
5160@end itemize
5161
69834ed9 5162An example of a log can be seen @pxref{5c,,here},
3a9ccc11 5163though the precise format and kinds of information logged is subject
5164to change.
5165
5166The caller remains responsible for closing @cite{logfile}, and it must not
5167be closed until all users are released. In particular, note that
5168child contexts and @pxref{16,,gcc_jit_result} instances created by
5169the context will use the logfile.
5170
5171There may a performance cost for logging.
5172
5173You can turn off logging on @cite{ctxt} by passing @cite{NULL} for @cite{logfile}.
5174Doing so only affects the context; it does not affect child contexts
5175or @pxref{16,,gcc_jit_result} instances already created by
5176the context.
5177
5178The parameters "flags" and "verbosity" are reserved for future
5179expansion, and must be zero for now.
5180@end deffn
5181
69834ed9 5182To contrast the above: @pxref{5a,,gcc_jit_context_dump_to_file()} dumps the
3a9ccc11 5183current state of a context to the given path, whereas
69834ed9 5184@pxref{5b,,gcc_jit_context_set_logfile()} enables on-going logging of
3a9ccc11 5185future activies on a context to the given @cite{FILE *}.
5186
c97b0d1d 5187@geindex gcc_jit_context_dump_reproducer_to_file (C function)
69834ed9 5188@anchor{topics/contexts gcc_jit_context_dump_reproducer_to_file}@anchor{5d}
c97b0d1d 5189@deffn {C Function} void gcc_jit_context_dump_reproducer_to_file (gcc_jit_context@w{ }*ctxt, const char@w{ }*path)
5190
5191Write C source code into @cite{path} that can be compiled into a
5192self-contained executable (i.e. with libgccjit as the only dependency).
5193The generated code will attempt to replay the API calls that have been
5194made into the given context.
5195
5196This may be useful when debugging the library or client code, for
5197reducing a complicated recipe for reproducing a bug into a simpler
5198form. For example, consider client code that parses some source file
5199into some internal representation, and then walks this IR, calling into
5200libgccjit. If this encounters a bug, a call to
5201@cite{gcc_jit_context_dump_reproducer_to_file} will write out C code for
5202a much simpler executable that performs the equivalent calls into
5203libgccjit, without needing the client code and its data.
5204
5205Typically you need to supply @code{-Wno-unused-variable} when
5206compiling the generated file (since the result of each API call is
5207assigned to a unique variable within the generated C source, and not
5208all are necessarily then used).
5209@end deffn
5210
66b69275 5211@geindex gcc_jit_context_enable_dump (C function)
69834ed9 5212@anchor{topics/contexts gcc_jit_context_enable_dump}@anchor{5e}
66b69275 5213@deffn {C Function} void gcc_jit_context_enable_dump (gcc_jit_context@w{ }*ctxt, const char@w{ }*dumpname, char@w{ }**out_ptr)
5214
5215Enable the dumping of a specific set of internal state from the
5216compilation, capturing the result in-memory as a buffer.
5217
5218Parameter "dumpname" corresponds to the equivalent gcc command-line
5219option, without the "-fdump-" prefix.
5220For example, to get the equivalent of @code{-fdump-tree-vrp1},
5221supply @code{"tree-vrp1"}:
5222
5223@example
5224static char *dump_vrp1;
5225
5226void
5227create_code (gcc_jit_context *ctxt)
5228@{
5229 gcc_jit_context_enable_dump (ctxt, "tree-vrp1", &dump_vrp1);
5230 /* (other API calls omitted for brevity) */
5231@}
5232@end example
5233
5234@noindent
5235
5236The context directly stores the dumpname as a @code{(const char *)}, so
5237the passed string must outlive the context.
5238
5239@pxref{15,,gcc_jit_context_compile()} will capture the dump as a
5240dynamically-allocated buffer, writing it to @code{*out_ptr}.
5241
5242The caller becomes responsible for calling:
5243
5244@example
5245free (*out_ptr)
5246@end example
5247
5248@noindent
5249
5250each time that @pxref{15,,gcc_jit_context_compile()} is called.
5251@code{*out_ptr} will be written to, either with the address of a buffer,
5252or with @code{NULL} if an error occurred.
5253
5254@cartouche
5255@quotation Warning
5256This API entrypoint is likely to be less stable than the others.
5257In particular, both the precise dumpnames, and the format and content
5258of the dumps are subject to change.
5259
5260It exists primarily for writing the library's own test suite.
5261@end quotation
5262@end cartouche
5263@end deffn
5264
863e76f9 5265@node Options<2>,,Debugging,Compilation contexts
69834ed9 5266@anchor{topics/contexts options}@anchor{5f}
863e76f9 5267@subsection Options
5268
5269
04feb56e 5270Options present in the initial release of libgccjit were handled using
5271enums, whereas those added subsequently have their own per-option API
5272entrypoints.
5273
5274Adding entrypoints for each new option means that client code that use
5275the new options can be identified directly from binary metadata, which
5276would not be possible if we instead extended the various
5277@code{enum gcc_jit_*_option}.
5278
863e76f9 5279@menu
5280* String Options::
5281* Boolean options::
5282* Integer options::
adb2df55 5283* Additional command-line options::
863e76f9 5284
5285@end menu
5286
5287@node String Options,Boolean options,,Options<2>
69834ed9 5288@anchor{topics/contexts string-options}@anchor{60}
863e76f9 5289@subsubsection String Options
5290
5291
5292@geindex gcc_jit_context_set_str_option (C function)
69834ed9 5293@anchor{topics/contexts gcc_jit_context_set_str_option}@anchor{61}
863e76f9 5294@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)
5295
5296Set a string option of the context.
5297
5298@geindex gcc_jit_str_option (C type)
69834ed9 5299@anchor{topics/contexts gcc_jit_str_option}@anchor{62}
863e76f9 5300@deffn {C Type} enum gcc_jit_str_option
5301@end deffn
5302
1fa42b05 5303The parameter @code{value} can be NULL. If non-NULL, the call takes a
5304copy of the underlying string, so it is valid to pass in a pointer to
5305an on-stack buffer.
5306
04feb56e 5307There is just one string option specified this way:
863e76f9 5308
5309@geindex GCC_JIT_STR_OPTION_PROGNAME (C macro)
69834ed9 5310@anchor{topics/contexts GCC_JIT_STR_OPTION_PROGNAME}@anchor{63}
863e76f9 5311@deffn {C Macro} GCC_JIT_STR_OPTION_PROGNAME
5312
5313The name of the program, for use as a prefix when printing error
5314messages to stderr. If @cite{NULL}, or default, "libgccjit.so" is used.
5315@end deffn
5316@end deffn
5317
5318@node Boolean options,Integer options,String Options,Options<2>
69834ed9 5319@anchor{topics/contexts boolean-options}@anchor{64}
863e76f9 5320@subsubsection Boolean options
5321
5322
5323@geindex gcc_jit_context_set_bool_option (C function)
eac6fba2 5324@anchor{topics/contexts gcc_jit_context_set_bool_option}@anchor{1b}
863e76f9 5325@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)
5326
5327Set a boolean option of the context.
5328Zero is "false" (the default), non-zero is "true".
5329
5330@geindex gcc_jit_bool_option (C type)
69834ed9 5331@anchor{topics/contexts gcc_jit_bool_option}@anchor{65}
863e76f9 5332@deffn {C Type} enum gcc_jit_bool_option
5333@end deffn
5334
5335@geindex GCC_JIT_BOOL_OPTION_DEBUGINFO (C macro)
eac6fba2 5336@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DEBUGINFO}@anchor{42}
863e76f9 5337@deffn {C Macro} GCC_JIT_BOOL_OPTION_DEBUGINFO
5338
5339If true, @pxref{15,,gcc_jit_context_compile()} will attempt to do the right
5340thing so that if you attach a debugger to the process, it will
5341be able to inspect variables and step through your code.
5342
5343Note that you can't step through code unless you set up source
5344location information for the code (by creating and passing in
eac6fba2 5345@pxref{3b,,gcc_jit_location} instances).
863e76f9 5346@end deffn
5347
5348@geindex GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE (C macro)
69834ed9 5349@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE}@anchor{66}
863e76f9 5350@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE
5351
5352If true, @pxref{15,,gcc_jit_context_compile()} will dump its initial
5353"tree" representation of your code to stderr (before any
5354optimizations).
5355
5356Here's some sample output (from the @cite{square} example):
5357
5358@example
5359<statement_list 0x7f4875a62cc0
5360 type <void_type 0x7f4875a64bd0 VOID
5361 align 8 symtab 0 alias set -1 canonical type 0x7f4875a64bd0
5362 pointer_to_this <pointer_type 0x7f4875a64c78>>
5363 side-effects head 0x7f4875a761e0 tail 0x7f4875a761f8 stmts 0x7f4875a62d20 0x7f4875a62d00
5364
5365 stmt <label_expr 0x7f4875a62d20 type <void_type 0x7f4875a64bd0>
5366 side-effects
5367 arg 0 <label_decl 0x7f4875a79080 entry type <void_type 0x7f4875a64bd0>
5368 VOID file (null) line 0 col 0
5369 align 1 context <function_decl 0x7f4875a77500 square>>>
5370 stmt <return_expr 0x7f4875a62d00
5371 type <integer_type 0x7f4875a645e8 public SI
5372 size <integer_cst 0x7f4875a623a0 constant 32>
5373 unit size <integer_cst 0x7f4875a623c0 constant 4>
5374 align 32 symtab 0 alias set -1 canonical type 0x7f4875a645e8 precision 32 min <integer_cst 0x7f4875a62340 -2147483648> max <integer_cst 0x7f4875a62360 2147483647>
5375 pointer_to_this <pointer_type 0x7f4875a6b348>>
5376 side-effects
5377 arg 0 <modify_expr 0x7f4875a72a78 type <integer_type 0x7f4875a645e8>
5378 side-effects arg 0 <result_decl 0x7f4875a7a000 D.54>
5379 arg 1 <mult_expr 0x7f4875a72a50 type <integer_type 0x7f4875a645e8>
5380 arg 0 <parm_decl 0x7f4875a79000 i> arg 1 <parm_decl 0x7f4875a79000 i>>>>>
5381@end example
5382
5383@noindent
5384@end deffn
5385
5386@geindex GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE (C macro)
eac6fba2 5387@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}@anchor{1c}
863e76f9 5388@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE
5389
5390If true, @pxref{15,,gcc_jit_context_compile()} will dump the "gimple"
5391representation of your code to stderr, before any optimizations
5392are performed. The dump resembles C code:
5393
5394@example
5395square (signed int i)
5396@{
5397 signed int D.56;
5398
5399 entry:
5400 D.56 = i * i;
5401 return D.56;
5402@}
5403@end example
5404
5405@noindent
5406@end deffn
5407
5408@geindex GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE (C macro)
eac6fba2 5409@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE}@anchor{1d}
863e76f9 5410@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE
5411
5412If true, @pxref{15,,gcc_jit_context_compile()} will dump the final
5413generated code to stderr, in the form of assembly language:
5414
5415@example
5416 .file "fake.c"
5417 .text
5418 .globl square
5419 .type square, @@function
5420square:
5421.LFB0:
5422 .cfi_startproc
5423 pushq %rbp
5424 .cfi_def_cfa_offset 16
5425 .cfi_offset 6, -16
5426 movq %rsp, %rbp
5427 .cfi_def_cfa_register 6
5428 movl %edi, -4(%rbp)
5429.L2:
5430 movl -4(%rbp), %eax
5431 imull -4(%rbp), %eax
5432 popq %rbp
5433 .cfi_def_cfa 7, 8
5434 ret
5435 .cfi_endproc
5436.LFE0:
5437 .size square, .-square
5438 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.1-%@{gcc_release@})"
5439 .section .note.GNU-stack,"",@@progbits
5440@end example
5441
5442@noindent
5443@end deffn
5444
5445@geindex GCC_JIT_BOOL_OPTION_DUMP_SUMMARY (C macro)
69834ed9 5446@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_SUMMARY}@anchor{67}
863e76f9 5447@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_SUMMARY
5448
5449If true, @pxref{15,,gcc_jit_context_compile()} will print information to stderr
17c0b84b 5450on the actions it is performing.
863e76f9 5451@end deffn
5452
5453@geindex GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING (C macro)
69834ed9 5454@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING}@anchor{68}
863e76f9 5455@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING
5456
5457If true, @pxref{15,,gcc_jit_context_compile()} will dump copious
5458amount of information on what it's doing to various
5459files within a temporary directory. Use
69834ed9 5460@pxref{69,,GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES} (see below) to
863e76f9 5461see the results. The files are intended to be human-readable,
5462but the exact files and their formats are subject to change.
5463@end deffn
5464
5465@geindex GCC_JIT_BOOL_OPTION_SELFCHECK_GC (C macro)
69834ed9 5466@anchor{topics/contexts GCC_JIT_BOOL_OPTION_SELFCHECK_GC}@anchor{6a}
863e76f9 5467@deffn {C Macro} GCC_JIT_BOOL_OPTION_SELFCHECK_GC
5468
5469If true, libgccjit will aggressively run its garbage collector, to
5470shake out bugs (greatly slowing down the compile). This is likely
5471to only be of interest to developers @emph{of} the library. It is
5472used when running the selftest suite.
5473@end deffn
5474
5475@geindex GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES (C macro)
69834ed9 5476@anchor{topics/contexts GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES}@anchor{69}
863e76f9 5477@deffn {C Macro} GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES
5478
5479If true, the @pxref{8,,gcc_jit_context} will not clean up intermediate files
5480written to the filesystem, and will display their location on stderr.
5481@end deffn
5482@end deffn
5483
04feb56e 5484@geindex gcc_jit_context_set_bool_allow_unreachable_blocks (C function)
5485@anchor{topics/contexts gcc_jit_context_set_bool_allow_unreachable_blocks}@anchor{6b}
5486@deffn {C Function} void gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context@w{ }*ctxt, int@w{ }bool_value)
5487
5488By default, libgccjit will issue an error about unreachable blocks
5489within a function.
5490
5491This entrypoint can be used to disable that error.
5492
5493This entrypoint was added in @pxref{6c,,LIBGCCJIT_ABI_2}; you can test for
5494its presence using
5495
5496@example
5497#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks
5498@end example
5499
5500@noindent
5501@end deffn
5502
adb2df55 5503@node Integer options,Additional command-line options,Boolean options,Options<2>
04feb56e 5504@anchor{topics/contexts integer-options}@anchor{6d}
863e76f9 5505@subsubsection Integer options
5506
5507
5508@geindex gcc_jit_context_set_int_option (C function)
eac6fba2 5509@anchor{topics/contexts gcc_jit_context_set_int_option}@anchor{1e}
863e76f9 5510@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)
5511
5512Set an integer option of the context.
5513
5514@geindex gcc_jit_int_option (C type)
04feb56e 5515@anchor{topics/contexts gcc_jit_int_option}@anchor{6e}
863e76f9 5516@deffn {C Type} enum gcc_jit_int_option
5517@end deffn
5518
04feb56e 5519There is just one integer option specified this way:
863e76f9 5520
5521@geindex GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL (C macro)
eac6fba2 5522@anchor{topics/contexts GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}@anchor{1f}
863e76f9 5523@deffn {C Macro} GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL
5524
5525How much to optimize the code.
5526
5527Valid values are 0-3, corresponding to GCC's command-line options
5528-O0 through -O3.
5529
5530The default value is 0 (unoptimized).
5531@end deffn
5532@end deffn
5533
adb2df55 5534@node Additional command-line options,,Integer options,Options<2>
04feb56e 5535@anchor{topics/contexts additional-command-line-options}@anchor{6f}
adb2df55 5536@subsubsection Additional command-line options
5537
5538
5539@geindex gcc_jit_context_add_command_line_option (C function)
04feb56e 5540@anchor{topics/contexts gcc_jit_context_add_command_line_option}@anchor{70}
adb2df55 5541@deffn {C Function} void gcc_jit_context_add_command_line_option (gcc_jit_context@w{ }*ctxt, const char@w{ }*optname)
5542
5543Add an arbitrary gcc command-line option to the context, for use
5544by @pxref{15,,gcc_jit_context_compile()} and
5545@pxref{4a,,gcc_jit_context_compile_to_file()}.
5546
5547The parameter @code{optname} must be non-NULL. The underlying buffer is
5548copied, so that it does not need to outlive the call.
5549
5550Extra options added by @cite{gcc_jit_context_add_command_line_option} are
5551applied @emph{after} the regular options above, potentially overriding them.
5552Options from parent contexts are inherited by child contexts; options
5553from the parent are applied @emph{before} those from the child.
5554
5555For example:
5556
5557@example
5558gcc_jit_context_add_command_line_option (ctxt, "-ffast-math");
5559gcc_jit_context_add_command_line_option (ctxt, "-fverbose-asm");
5560@end example
5561
5562@noindent
5563
5564Note that only some options are likely to be meaningful; there is no
5565"frontend" within libgccjit, so typically only those affecting
5566optimization and code-generation are likely to be useful.
5567
04feb56e 5568This entrypoint was added in @pxref{71,,LIBGCCJIT_ABI_1}; you can test for
adb2df55 5569its presence using
5570
5571@example
5572#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option
5573@end example
5574
5575@noindent
5576@end deffn
5577
f1717362 5578@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 5579@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
5580@c
5581@c This is free software: you can redistribute it and/or modify it
5582@c under the terms of the GNU General Public License as published by
5583@c the Free Software Foundation, either version 3 of the License, or
5584@c (at your option) any later version.
5585@c
5586@c This program is distributed in the hope that it will be useful, but
5587@c WITHOUT ANY WARRANTY; without even the implied warranty of
5588@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5589@c General Public License for more details.
5590@c
5591@c You should have received a copy of the GNU General Public License
5592@c along with this program. If not, see
5593@c <http://www.gnu.org/licenses/>.
5594
5595@node Objects,Types,Compilation contexts,Topic Reference
04feb56e 5596@anchor{topics/objects objects}@anchor{72}@anchor{topics/objects doc}@anchor{73}
863e76f9 5597@section Objects
5598
5599
5600@geindex gcc_jit_object (C type)
5601@anchor{topics/objects gcc_jit_object}@anchor{e}
5602@deffn {C Type} gcc_jit_object
5603@end deffn
5604
5605Almost every entity in the API (with the exception of
5606@pxref{8,,gcc_jit_context *} and @pxref{16,,gcc_jit_result *}) is a
5607"contextual" object, a @pxref{e,,gcc_jit_object *}
5608
5609A JIT object:
5610
5611@quotation
5612
5613
5614@itemize *
5615
5616@item
5617is associated with a @pxref{8,,gcc_jit_context *}.
5618
5619@item
5620is automatically cleaned up for you when its context is released so
5621you don't need to manually track and cleanup all objects, just the
5622contexts.
5623@end itemize
5624@end quotation
5625
5626Although the API is C-based, there is a form of class hierarchy, which
5627looks like this:
5628
5629@example
5630+- gcc_jit_object
5631 +- gcc_jit_location
5632 +- gcc_jit_type
5633 +- gcc_jit_struct
5634 +- gcc_jit_field
5635 +- gcc_jit_function
5636 +- gcc_jit_block
5637 +- gcc_jit_rvalue
5638 +- gcc_jit_lvalue
5639 +- gcc_jit_param
a24ef8d2 5640 +- gcc_jit_case
863e76f9 5641@end example
5642
5643@noindent
5644
5645There are casting methods for upcasting from subclasses to parent classes.
5646For example, @pxref{d,,gcc_jit_type_as_object()}:
5647
5648@example
5649gcc_jit_object *obj = gcc_jit_type_as_object (int_type);
5650@end example
5651
5652@noindent
5653
5654The object "base class" has the following operations:
5655
5656@geindex gcc_jit_object_get_context (C function)
04feb56e 5657@anchor{topics/objects gcc_jit_object_get_context}@anchor{74}
863e76f9 5658@deffn {C Function} gcc_jit_context *gcc_jit_object_get_context (gcc_jit_object@w{ }*obj)
5659
5660Which context is "obj" within?
5661@end deffn
5662
5663@geindex gcc_jit_object_get_debug_string (C function)
5664@anchor{topics/objects gcc_jit_object_get_debug_string}@anchor{f}
5665@deffn {C Function} const char *gcc_jit_object_get_debug_string (gcc_jit_object@w{ }*obj)
5666
5667Generate a human-readable description for the given object.
5668
5669For example,
5670
5671@example
5672printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj));
5673@end example
5674
5675@noindent
5676
5677might give this text on stdout:
5678
5679@example
5680obj: 4.0 * (float)i
5681@end example
5682
5683@noindent
5684
5685@cartouche
5686@quotation Note
5687If you call this on an object, the @cite{const char *} buffer is allocated
5688and generated on the first call for that object, and the buffer will
5689have the same lifetime as the object i.e. it will exist until the
5690object's context is released.
5691@end quotation
5692@end cartouche
5693@end deffn
5694
f1717362 5695@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 5696@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
5697@c
5698@c This is free software: you can redistribute it and/or modify it
5699@c under the terms of the GNU General Public License as published by
5700@c the Free Software Foundation, either version 3 of the License, or
5701@c (at your option) any later version.
5702@c
5703@c This program is distributed in the hope that it will be useful, but
5704@c WITHOUT ANY WARRANTY; without even the implied warranty of
5705@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5706@c General Public License for more details.
5707@c
5708@c You should have received a copy of the GNU General Public License
5709@c along with this program. If not, see
5710@c <http://www.gnu.org/licenses/>.
5711
5712@node Types,Expressions,Objects,Topic Reference
04feb56e 5713@anchor{topics/types doc}@anchor{75}@anchor{topics/types types}@anchor{76}
863e76f9 5714@section Types
5715
5716
5717@geindex gcc_jit_type (C type)
5718@anchor{topics/types gcc_jit_type}@anchor{a}
5719@deffn {C Type} gcc_jit_type
5720
5721gcc_jit_type represents a type within the library.
5722@end deffn
5723
5724@geindex gcc_jit_type_as_object (C function)
5725@anchor{topics/types gcc_jit_type_as_object}@anchor{d}
5726@deffn {C Function} gcc_jit_object *gcc_jit_type_as_object (gcc_jit_type@w{ }*type)
5727
5728Upcast a type to an object.
5729@end deffn
5730
5731Types can be created in several ways:
5732
5733
5734@itemize *
5735
5736@item
5737fundamental types can be accessed using
5738@pxref{b,,gcc_jit_context_get_type()}:
5739
5740@example
5741gcc_jit_type *int_type = gcc_jit_context_get_type (GCC_JIT_TYPE_INT);
5742@end example
5743
5744@noindent
5745
5746See @pxref{b,,gcc_jit_context_get_type()} for the available types.
5747
5748@item
5749derived types can be accessed by using functions such as
04feb56e 5750@pxref{77,,gcc_jit_type_get_pointer()} and @pxref{78,,gcc_jit_type_get_const()}:
863e76f9 5751
5752@example
5753gcc_jit_type *const_int_star = gcc_jit_type_get_pointer (gcc_jit_type_get_const (int_type));
5754gcc_jit_type *int_const_star = gcc_jit_type_get_const (gcc_jit_type_get_pointer (int_type));
5755@end example
5756
5757@noindent
5758
5759@item
5760by creating structures (see below).
5761@end itemize
5762
5763@menu
5764* Standard types::
5765* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile.
5766* Structures and unions::
5767
5768@end menu
5769
5770@node Standard types,Pointers const and volatile,,Types
04feb56e 5771@anchor{topics/types standard-types}@anchor{79}
863e76f9 5772@subsection Standard types
5773
5774
5775@geindex gcc_jit_context_get_type (C function)
5776@anchor{topics/types gcc_jit_context_get_type}@anchor{b}
5777@deffn {C Function} gcc_jit_type *gcc_jit_context_get_type (gcc_jit_context@w{ }*ctxt, enum gcc_jit_types@w{ }type_)
5778
5779Access a specific type. The available types are:
5780
5781
7140b255 5782@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
863e76f9 5783@headitem
5784
5785@cite{enum gcc_jit_types} value
5786
5787@tab
5788
5789Meaning
5790
5791@item
5792
5793@code{GCC_JIT_TYPE_VOID}
5794
5795@tab
5796
5797C's @code{void} type.
5798
5799@item
5800
5801@code{GCC_JIT_TYPE_VOID_PTR}
5802
5803@tab
5804
5805C's @code{void *}.
5806
5807@item
5808
5809@code{GCC_JIT_TYPE_BOOL}
5810
5811@tab
5812
5813C++'s @code{bool} type; also C99's
5814@code{_Bool} type, aka @code{bool} if
5815using stdbool.h.
5816
5817@item
5818
5819@code{GCC_JIT_TYPE_CHAR}
5820
5821@tab
5822
5823C's @code{char} (of some signedness)
5824
5825@item
5826
5827@code{GCC_JIT_TYPE_SIGNED_CHAR}
5828
5829@tab
5830
5831C's @code{signed char}
5832
5833@item
5834
5835@code{GCC_JIT_TYPE_UNSIGNED_CHAR}
5836
5837@tab
5838
5839C's @code{unsigned char}
5840
5841@item
5842
5843@code{GCC_JIT_TYPE_SHORT}
5844
5845@tab
5846
5847C's @code{short} (signed)
5848
5849@item
5850
5851@code{GCC_JIT_TYPE_UNSIGNED_SHORT}
5852
5853@tab
5854
5855C's @code{unsigned short}
5856
5857@item
5858
5859@code{GCC_JIT_TYPE_INT}
5860
5861@tab
5862
5863C's @code{int} (signed)
5864
5865@item
5866
5867@code{GCC_JIT_TYPE_UNSIGNED_INT}
5868
5869@tab
5870
5871C's @code{unsigned int}
5872
5873@item
5874
5875@code{GCC_JIT_TYPE_LONG}
5876
5877@tab
5878
5879C's @code{long} (signed)
5880
5881@item
5882
5883@code{GCC_JIT_TYPE_UNSIGNED_LONG}
5884
5885@tab
5886
5887C's @code{unsigned long}
5888
5889@item
5890
5891@code{GCC_JIT_TYPE_LONG_LONG}
5892
5893@tab
5894
5895C99's @code{long long} (signed)
5896
5897@item
5898
5899@code{GCC_JIT_TYPE_UNSIGNED_LONG_LONG}
5900
5901@tab
5902
5903C99's @code{unsigned long long}
5904
5905@item
5906
5907@code{GCC_JIT_TYPE_FLOAT}
5908
5909@tab
5910
5911@item
5912
5913@code{GCC_JIT_TYPE_DOUBLE}
5914
5915@tab
5916
5917@item
5918
5919@code{GCC_JIT_TYPE_LONG_DOUBLE}
5920
5921@tab
5922
5923@item
5924
5925@code{GCC_JIT_TYPE_CONST_CHAR_PTR}
5926
5927@tab
5928
5929C type: @code{(const char *)}
5930
5931@item
5932
5933@code{GCC_JIT_TYPE_SIZE_T}
5934
5935@tab
5936
5937C's @code{size_t} type
5938
5939@item
5940
5941@code{GCC_JIT_TYPE_FILE_PTR}
5942
5943@tab
5944
5945C type: @code{(FILE *)}
5946
7140b255 5947@item
5948
5949@code{GCC_JIT_TYPE_COMPLEX_FLOAT}
5950
5951@tab
5952
5953C99's @code{_Complex float}
5954
5955@item
5956
5957@code{GCC_JIT_TYPE_COMPLEX_DOUBLE}
5958
5959@tab
5960
5961C99's @code{_Complex double}
5962
5963@item
5964
5965@code{GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE}
5966
5967@tab
5968
5969C99's @code{_Complex long double}
5970
863e76f9 5971@end multitable
5972
5973@end deffn
5974
5975@geindex gcc_jit_context_get_int_type (C function)
04feb56e 5976@anchor{topics/types gcc_jit_context_get_int_type}@anchor{7a}
863e76f9 5977@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)
5978
5979Access the integer type of the given size.
5980@end deffn
5981
5982@node Pointers const and volatile,Structures and unions,Standard types,Types
04feb56e 5983@anchor{topics/types pointers-const-and-volatile}@anchor{7b}
863e76f9 5984@subsection Pointers, @cite{const}, and @cite{volatile}
5985
5986
5987@geindex gcc_jit_type_get_pointer (C function)
04feb56e 5988@anchor{topics/types gcc_jit_type_get_pointer}@anchor{77}
863e76f9 5989@deffn {C Function} gcc_jit_type *gcc_jit_type_get_pointer (gcc_jit_type@w{ }*type)
5990
5991Given type "T", get type "T*".
5992@end deffn
5993
5994@geindex gcc_jit_type_get_const (C function)
04feb56e 5995@anchor{topics/types gcc_jit_type_get_const}@anchor{78}
863e76f9 5996@deffn {C Function} gcc_jit_type *gcc_jit_type_get_const (gcc_jit_type@w{ }*type)
5997
5998Given type "T", get type "const T".
5999@end deffn
6000
6001@geindex gcc_jit_type_get_volatile (C function)
04feb56e 6002@anchor{topics/types gcc_jit_type_get_volatile}@anchor{7c}
863e76f9 6003@deffn {C Function} gcc_jit_type *gcc_jit_type_get_volatile (gcc_jit_type@w{ }*type)
6004
6005Given type "T", get type "volatile T".
6006@end deffn
6007
6008@geindex gcc_jit_context_new_array_type (C function)
04feb56e 6009@anchor{topics/types gcc_jit_context_new_array_type}@anchor{7d}
863e76f9 6010@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)
6011
6012Given type "T", get type "T[N]" (for a constant N).
6013@end deffn
6014
6015@node Structures and unions,,Pointers const and volatile,Types
04feb56e 6016@anchor{topics/types structures-and-unions}@anchor{7e}
863e76f9 6017@subsection Structures and unions
6018
6019
6020@geindex gcc_jit_struct (C type)
04feb56e 6021@anchor{topics/types gcc_jit_struct}@anchor{7f}
863e76f9 6022@deffn {C Type} gcc_jit_struct
6023@end deffn
6024
6025A compound type analagous to a C @cite{struct}.
6026
6027@geindex gcc_jit_field (C type)
04feb56e 6028@anchor{topics/types gcc_jit_field}@anchor{80}
863e76f9 6029@deffn {C Type} gcc_jit_field
6030@end deffn
6031
04feb56e 6032A field within a @pxref{7f,,gcc_jit_struct}.
863e76f9 6033
04feb56e 6034You can model C @cite{struct} types by creating @pxref{7f,,gcc_jit_struct *} and
6035@pxref{80,,gcc_jit_field} instances, in either order:
863e76f9 6036
6037
6038@itemize *
6039
6040@item
6041by creating the fields, then the structure. For example, to model:
6042
6043@example
6044struct coord @{double x; double y; @};
6045@end example
6046
6047@noindent
6048
6049you could call:
6050
6051@example
6052gcc_jit_field *field_x =
6053 gcc_jit_context_new_field (ctxt, NULL, double_type, "x");
6054gcc_jit_field *field_y =
6055 gcc_jit_context_new_field (ctxt, NULL, double_type, "y");
6056gcc_jit_field *fields[2] = @{field_x, field_y@};
6057gcc_jit_struct *coord =
6058 gcc_jit_context_new_struct_type (ctxt, NULL, "coord", 2, fields);
6059@end example
6060
6061@noindent
6062
6063@item
6064by creating the structure, then populating it with fields, typically
6065to allow modelling self-referential structs such as:
6066
6067@example
6068struct node @{ int m_hash; struct node *m_next; @};
6069@end example
6070
6071@noindent
6072
6073like this:
6074
6075@example
6076gcc_jit_type *node =
6077 gcc_jit_context_new_opaque_struct (ctxt, NULL, "node");
6078gcc_jit_type *node_ptr =
6079 gcc_jit_type_get_pointer (node);
6080gcc_jit_field *field_hash =
6081 gcc_jit_context_new_field (ctxt, NULL, int_type, "m_hash");
6082gcc_jit_field *field_next =
6083 gcc_jit_context_new_field (ctxt, NULL, node_ptr, "m_next");
6084gcc_jit_field *fields[2] = @{field_hash, field_next@};
6085gcc_jit_struct_set_fields (node, NULL, 2, fields);
6086@end example
6087
6088@noindent
6089@end itemize
6090
6091@geindex gcc_jit_context_new_field (C function)
04feb56e 6092@anchor{topics/types gcc_jit_context_new_field}@anchor{81}
863e76f9 6093@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)
6094
6095Construct a new field, with the given type and name.
1fa42b05 6096
6097The parameter @code{name} must be non-NULL. The call takes a copy of the
6098underlying string, so it is valid to pass in a pointer to an on-stack
6099buffer.
863e76f9 6100@end deffn
6101
6102@geindex gcc_jit_field_as_object (C function)
04feb56e 6103@anchor{topics/types gcc_jit_field_as_object}@anchor{82}
863e76f9 6104@deffn {C Function} gcc_jit_object * gcc_jit_field_as_object (gcc_jit_field@w{ }*field)
6105
6106Upcast from field to object.
6107@end deffn
6108
6109@geindex gcc_jit_context_new_struct_type (C function)
04feb56e 6110@anchor{topics/types gcc_jit_context_new_struct_type}@anchor{83}
863e76f9 6111@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)
6112
6113@quotation
6114
6115Construct a new struct type, with the given name and fields.
1fa42b05 6116
6117The parameter @code{name} must be non-NULL. The call takes a copy of
6118the underlying string, so it is valid to pass in a pointer to an
6119on-stack buffer.
863e76f9 6120@end quotation
6121@end deffn
6122
6123@geindex gcc_jit_context_new_opaque_struct (C function)
04feb56e 6124@anchor{topics/types gcc_jit_context_new_opaque_struct}@anchor{84}
863e76f9 6125@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)
6126
6127Construct a new struct type, with the given name, but without
6128specifying the fields. The fields can be omitted (in which case the
6129size of the struct is not known), or later specified using
04feb56e 6130@pxref{85,,gcc_jit_struct_set_fields()}.
1fa42b05 6131
6132The parameter @code{name} must be non-NULL. The call takes a copy of
6133the underlying string, so it is valid to pass in a pointer to an
6134on-stack buffer.
863e76f9 6135@end deffn
6136
6137@geindex gcc_jit_struct_as_type (C function)
04feb56e 6138@anchor{topics/types gcc_jit_struct_as_type}@anchor{86}
863e76f9 6139@deffn {C Function} gcc_jit_type * gcc_jit_struct_as_type (gcc_jit_struct@w{ }*struct_type)
6140
6141Upcast from struct to type.
6142@end deffn
6143
6144@geindex gcc_jit_struct_set_fields (C function)
04feb56e 6145@anchor{topics/types gcc_jit_struct_set_fields}@anchor{85}
863e76f9 6146@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)
6147
6148Populate the fields of a formerly-opaque struct type.
6149
6150This can only be called once on a given struct type.
6151@end deffn
6152
eb2d3e4a 6153@geindex gcc_jit_context_new_union_type (C function)
6154@anchor{topics/types gcc_jit_context_new_union_type}@anchor{87}
6155@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)
6156
6157Construct a new union type, with the given name and fields.
6158
6159The parameter @code{name} must be non-NULL. It is copied, so the input
6160buffer does not need to outlive the call.
6161
6162Example of use:
6163
6164@example
6165
6166union int_or_float
6167@{
6168 int as_int;
6169 float as_float;
6170@};
6171
6172void
6173create_code (gcc_jit_context *ctxt, void *user_data)
6174@{
6175 /* Let's try to inject the equivalent of:
6176 float
6177 test_union (int i)
6178 @{
6179 union int_or_float u;
6180 u.as_int = i;
6181 return u.as_float;
6182 @}
6183 */
6184 gcc_jit_type *int_type =
6185 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
6186 gcc_jit_type *float_type =
6187 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT);
6188 gcc_jit_field *as_int =
6189 gcc_jit_context_new_field (ctxt,
6190 NULL,
6191 int_type,
6192 "as_int");
6193 gcc_jit_field *as_float =
6194 gcc_jit_context_new_field (ctxt,
6195 NULL,
6196 float_type,
6197 "as_float");
6198 gcc_jit_field *fields[] = @{as_int, as_float@};
6199 gcc_jit_type *union_type =
6200 gcc_jit_context_new_union_type (ctxt, NULL,
6201 "int_or_float", 2, fields);
6202
6203 /* Build the test function. */
6204 gcc_jit_param *param_i =
6205 gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
6206 gcc_jit_function *test_fn =
6207 gcc_jit_context_new_function (ctxt, NULL,
6208 GCC_JIT_FUNCTION_EXPORTED,
6209 float_type,
6210 "test_union",
6211 1, &param_i,
6212 0);
6213
6214 gcc_jit_lvalue *u =
6215 gcc_jit_function_new_local (test_fn, NULL,
6216 union_type, "u");
6217
6218 gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
6219
6220 /* u.as_int = i; */
6221 gcc_jit_block_add_assignment (
6222 block,
6223 NULL,
6224 /* "u.as_int = ..." */
6225 gcc_jit_lvalue_access_field (u,
6226 NULL,
6227 as_int),
6228 gcc_jit_param_as_rvalue (param_i));
6229
6230 /* return u.as_float; */
6231 gcc_jit_block_end_with_return (
6232 block, NULL,
6233 gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (u),
6234 NULL,
6235 as_float));
6236@}
6237
6238
6239@end example
6240
6241@noindent
6242@end deffn
6243
f1717362 6244@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 6245@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
6246@c
6247@c This is free software: you can redistribute it and/or modify it
6248@c under the terms of the GNU General Public License as published by
6249@c the Free Software Foundation, either version 3 of the License, or
6250@c (at your option) any later version.
6251@c
6252@c This program is distributed in the hope that it will be useful, but
6253@c WITHOUT ANY WARRANTY; without even the implied warranty of
6254@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6255@c General Public License for more details.
6256@c
6257@c You should have received a copy of the GNU General Public License
6258@c along with this program. If not, see
6259@c <http://www.gnu.org/licenses/>.
6260
6261@node Expressions,Creating and using functions,Types,Topic Reference
eb2d3e4a 6262@anchor{topics/expressions expressions}@anchor{88}@anchor{topics/expressions doc}@anchor{89}
863e76f9 6263@section Expressions
6264
6265
6266@menu
6267* Rvalues::
6268* Lvalues::
6269* Working with pointers@comma{} structs and unions: Working with pointers structs and unions.
6270
6271Rvalues
6272
6273* Simple expressions::
6274* Unary Operations::
6275* Binary Operations::
6276* Comparisons::
6277* Function calls::
6278* Type-coercion::
6279
6280Lvalues
6281
6282* Global variables::
6283
6284@end menu
6285
6286
6287@node Rvalues,Lvalues,,Expressions
eb2d3e4a 6288@anchor{topics/expressions rvalues}@anchor{8a}
863e76f9 6289@subsection Rvalues
6290
6291
6292@geindex gcc_jit_rvalue (C type)
6293@anchor{topics/expressions gcc_jit_rvalue}@anchor{13}
6294@deffn {C Type} gcc_jit_rvalue
6295@end deffn
6296
6297A @pxref{13,,gcc_jit_rvalue *} is an expression that can be computed.
6298
6299It can be simple, e.g.:
6300
6301@quotation
6302
6303
6304@itemize *
6305
6306@item
6307an integer value e.g. @cite{0} or @cite{42}
6308
6309@item
6310a string literal e.g. @cite{"Hello world"}
6311
6312@item
6313a variable e.g. @cite{i}. These are also lvalues (see below).
6314@end itemize
6315@end quotation
6316
6317or compound e.g.:
6318
6319@quotation
6320
6321
6322@itemize *
6323
6324@item
6325a unary expression e.g. @cite{!cond}
6326
6327@item
6328a binary expression e.g. @cite{(a + b)}
6329
6330@item
6331a function call e.g. @cite{get_distance (&player_ship@comma{} &target)}
6332
6333@item
6334etc.
6335@end itemize
6336@end quotation
6337
6338Every rvalue has an associated type, and the API will check to ensure
6339that types match up correctly (otherwise the context will emit an error).
6340
6341@geindex gcc_jit_rvalue_get_type (C function)
eb2d3e4a 6342@anchor{topics/expressions gcc_jit_rvalue_get_type}@anchor{8b}
863e76f9 6343@deffn {C Function} gcc_jit_type *gcc_jit_rvalue_get_type (gcc_jit_rvalue@w{ }*rvalue)
6344
6345Get the type of this rvalue.
6346@end deffn
6347
6348@geindex gcc_jit_rvalue_as_object (C function)
6349@anchor{topics/expressions gcc_jit_rvalue_as_object}@anchor{14}
6350@deffn {C Function} gcc_jit_object *gcc_jit_rvalue_as_object (gcc_jit_rvalue@w{ }*rvalue)
6351
6352Upcast the given rvalue to be an object.
6353@end deffn
6354
6355@menu
6356* Simple expressions::
6357* Unary Operations::
6358* Binary Operations::
6359* Comparisons::
6360* Function calls::
6361* Type-coercion::
6362
6363@end menu
6364
6365@node Simple expressions,Unary Operations,,Rvalues
eb2d3e4a 6366@anchor{topics/expressions simple-expressions}@anchor{8c}
863e76f9 6367@subsubsection Simple expressions
6368
6369
6370@geindex gcc_jit_context_new_rvalue_from_int (C function)
eac6fba2 6371@anchor{topics/expressions gcc_jit_context_new_rvalue_from_int}@anchor{30}
863e76f9 6372@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)
6373
6374Given a numeric type (integer or floating point), build an rvalue for
feea5a1f 6375the given constant @code{int} value.
6376@end deffn
6377
6378@geindex gcc_jit_context_new_rvalue_from_long (C function)
eb2d3e4a 6379@anchor{topics/expressions gcc_jit_context_new_rvalue_from_long}@anchor{8d}
feea5a1f 6380@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)
6381
6382Given a numeric type (integer or floating point), build an rvalue for
6383the given constant @code{long} value.
863e76f9 6384@end deffn
6385
6386@geindex gcc_jit_context_zero (C function)
eac6fba2 6387@anchor{topics/expressions gcc_jit_context_zero}@anchor{2b}
863e76f9 6388@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_zero (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type)
6389
6390Given a numeric type (integer or floating point), get the rvalue for
6391zero. Essentially this is just a shortcut for:
6392
6393@example
6394gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0)
6395@end example
6396
6397@noindent
6398@end deffn
6399
6400@geindex gcc_jit_context_one (C function)
eac6fba2 6401@anchor{topics/expressions gcc_jit_context_one}@anchor{2f}
863e76f9 6402@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_one (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type)
6403
6404Given a numeric type (integer or floating point), get the rvalue for
e954f824 6405one. Essentially this is just a shortcut for:
863e76f9 6406
6407@example
6408gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1)
6409@end example
6410
6411@noindent
6412@end deffn
6413
6414@geindex gcc_jit_context_new_rvalue_from_double (C function)
eac6fba2 6415@anchor{topics/expressions gcc_jit_context_new_rvalue_from_double}@anchor{31}
863e76f9 6416@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)
6417
6418Given a numeric type (integer or floating point), build an rvalue for
feea5a1f 6419the given constant @code{double} value.
863e76f9 6420@end deffn
6421
6422@geindex gcc_jit_context_new_rvalue_from_ptr (C function)
eb2d3e4a 6423@anchor{topics/expressions gcc_jit_context_new_rvalue_from_ptr}@anchor{8e}
863e76f9 6424@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)
6425
6426Given a pointer type, build an rvalue for the given address.
6427@end deffn
6428
6429@geindex gcc_jit_context_null (C function)
eb2d3e4a 6430@anchor{topics/expressions gcc_jit_context_null}@anchor{8f}
863e76f9 6431@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_null (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*pointer_type)
6432
6433Given a pointer type, build an rvalue for @code{NULL}. Essentially this
6434is just a shortcut for:
6435
6436@example
6437gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL)
6438@end example
6439
6440@noindent
6441@end deffn
6442
6443@geindex gcc_jit_context_new_string_literal (C function)
eb2d3e4a 6444@anchor{topics/expressions gcc_jit_context_new_string_literal}@anchor{90}
863e76f9 6445@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_string_literal (gcc_jit_context@w{ }*ctxt, const char@w{ }*value)
6446
6447Generate an rvalue for the given NIL-terminated string, of type
6448@code{GCC_JIT_TYPE_CONST_CHAR_PTR}.
1fa42b05 6449
6450The parameter @code{value} must be non-NULL. The call takes a copy of the
6451underlying string, so it is valid to pass in a pointer to an on-stack
6452buffer.
863e76f9 6453@end deffn
6454
6455@node Unary Operations,Binary Operations,Simple expressions,Rvalues
eb2d3e4a 6456@anchor{topics/expressions unary-operations}@anchor{91}
863e76f9 6457@subsubsection Unary Operations
6458
6459
6460@geindex gcc_jit_context_new_unary_op (C function)
eb2d3e4a 6461@anchor{topics/expressions gcc_jit_context_new_unary_op}@anchor{92}
863e76f9 6462@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)
6463
6464Build a unary operation out of an input rvalue.
6465@end deffn
6466
6467@geindex gcc_jit_unary_op (C type)
eb2d3e4a 6468@anchor{topics/expressions gcc_jit_unary_op}@anchor{93}
863e76f9 6469@deffn {C Type} enum gcc_jit_unary_op
6470@end deffn
6471
6472The available unary operations are:
6473
6474
6475@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx}
6476@headitem
6477
6478Unary Operation
6479
6480@tab
6481
6482C equivalent
6483
6484@item
6485
eb2d3e4a 6486@pxref{94,,GCC_JIT_UNARY_OP_MINUS}
863e76f9 6487
6488@tab
6489
6490@cite{-(EXPR)}
6491
6492@item
6493
eb2d3e4a 6494@pxref{95,,GCC_JIT_UNARY_OP_BITWISE_NEGATE}
863e76f9 6495
6496@tab
6497
6498@cite{~(EXPR)}
6499
6500@item
6501
eb2d3e4a 6502@pxref{96,,GCC_JIT_UNARY_OP_LOGICAL_NEGATE}
863e76f9 6503
6504@tab
6505
6506@cite{!(EXPR)}
6507
7fe953b6 6508@item
6509
eb2d3e4a 6510@pxref{97,,GCC_JIT_UNARY_OP_ABS}
7fe953b6 6511
6512@tab
6513
6514@cite{abs (EXPR)}
6515
863e76f9 6516@end multitable
6517
6518
6519@geindex GCC_JIT_UNARY_OP_MINUS (C macro)
eb2d3e4a 6520@anchor{topics/expressions GCC_JIT_UNARY_OP_MINUS}@anchor{94}
863e76f9 6521@deffn {C Macro} GCC_JIT_UNARY_OP_MINUS
6522
6523Negate an arithmetic value; analogous to:
6524
6525@example
6526-(EXPR)
6527@end example
6528
6529@noindent
6530
6531in C.
6532@end deffn
6533
6534@geindex GCC_JIT_UNARY_OP_BITWISE_NEGATE (C macro)
eb2d3e4a 6535@anchor{topics/expressions GCC_JIT_UNARY_OP_BITWISE_NEGATE}@anchor{95}
863e76f9 6536@deffn {C Macro} GCC_JIT_UNARY_OP_BITWISE_NEGATE
6537
6538Bitwise negation of an integer value (one's complement); analogous
6539to:
6540
6541@example
6542~(EXPR)
6543@end example
6544
6545@noindent
6546
6547in C.
6548@end deffn
6549
6550@geindex GCC_JIT_UNARY_OP_LOGICAL_NEGATE (C macro)
eb2d3e4a 6551@anchor{topics/expressions GCC_JIT_UNARY_OP_LOGICAL_NEGATE}@anchor{96}
863e76f9 6552@deffn {C Macro} GCC_JIT_UNARY_OP_LOGICAL_NEGATE
6553
6554Logical negation of an arithmetic or pointer value; analogous to:
6555
6556@example
6557!(EXPR)
6558@end example
6559
6560@noindent
6561
6562in C.
6563@end deffn
6564
7fe953b6 6565@geindex GCC_JIT_UNARY_OP_ABS (C macro)
eb2d3e4a 6566@anchor{topics/expressions GCC_JIT_UNARY_OP_ABS}@anchor{97}
7fe953b6 6567@deffn {C Macro} GCC_JIT_UNARY_OP_ABS
6568
6569Absolute value of an arithmetic expression; analogous to:
6570
6571@example
6572abs (EXPR)
6573@end example
6574
6575@noindent
6576
6577in C.
6578@end deffn
6579
863e76f9 6580@node Binary Operations,Comparisons,Unary Operations,Rvalues
eb2d3e4a 6581@anchor{topics/expressions binary-operations}@anchor{98}
863e76f9 6582@subsubsection Binary Operations
6583
6584
6585@geindex gcc_jit_context_new_binary_op (C function)
6586@anchor{topics/expressions gcc_jit_context_new_binary_op}@anchor{12}
6587@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)
6588
6589Build a binary operation out of two constituent rvalues.
6590@end deffn
6591
6592@geindex gcc_jit_binary_op (C type)
eb2d3e4a 6593@anchor{topics/expressions gcc_jit_binary_op}@anchor{99}
863e76f9 6594@deffn {C Type} enum gcc_jit_binary_op
6595@end deffn
6596
6597The available binary operations are:
6598
6599
6600@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx}
6601@headitem
6602
6603Binary Operation
6604
6605@tab
6606
6607C equivalent
6608
6609@item
6610
eb2d3e4a 6611@pxref{9a,,GCC_JIT_BINARY_OP_PLUS}
863e76f9 6612
6613@tab
6614
6615@cite{x + y}
6616
6617@item
6618
eb2d3e4a 6619@pxref{9b,,GCC_JIT_BINARY_OP_MINUS}
863e76f9 6620
6621@tab
6622
6623@cite{x - y}
6624
6625@item
6626
eb2d3e4a 6627@pxref{9c,,GCC_JIT_BINARY_OP_MULT}
863e76f9 6628
6629@tab
6630
6631@cite{x * y}
6632
6633@item
6634
eb2d3e4a 6635@pxref{9d,,GCC_JIT_BINARY_OP_DIVIDE}
863e76f9 6636
6637@tab
6638
6639@cite{x / y}
6640
6641@item
6642
eb2d3e4a 6643@pxref{9e,,GCC_JIT_BINARY_OP_MODULO}
863e76f9 6644
6645@tab
6646
6647@cite{x % y}
6648
6649@item
6650
eb2d3e4a 6651@pxref{9f,,GCC_JIT_BINARY_OP_BITWISE_AND}
863e76f9 6652
6653@tab
6654
6655@cite{x & y}
6656
6657@item
6658
eb2d3e4a 6659@pxref{a0,,GCC_JIT_BINARY_OP_BITWISE_XOR}
863e76f9 6660
6661@tab
6662
6663@cite{x ^ y}
6664
6665@item
6666
eb2d3e4a 6667@pxref{a1,,GCC_JIT_BINARY_OP_BITWISE_OR}
863e76f9 6668
6669@tab
6670
6671@cite{x | y}
6672
6673@item
6674
eb2d3e4a 6675@pxref{a2,,GCC_JIT_BINARY_OP_LOGICAL_AND}
863e76f9 6676
6677@tab
6678
6679@cite{x && y}
6680
6681@item
6682
eb2d3e4a 6683@pxref{a3,,GCC_JIT_BINARY_OP_LOGICAL_OR}
863e76f9 6684
6685@tab
6686
6687@cite{x || y}
6688
6689@item
6690
eb2d3e4a 6691@pxref{a4,,GCC_JIT_BINARY_OP_LSHIFT}
863e76f9 6692
6693@tab
6694
6695@cite{x << y}
6696
6697@item
6698
eb2d3e4a 6699@pxref{a5,,GCC_JIT_BINARY_OP_RSHIFT}
863e76f9 6700
6701@tab
6702
6703@cite{x >> y}
6704
6705@end multitable
6706
6707
6708@geindex GCC_JIT_BINARY_OP_PLUS (C macro)
eb2d3e4a 6709@anchor{topics/expressions GCC_JIT_BINARY_OP_PLUS}@anchor{9a}
863e76f9 6710@deffn {C Macro} GCC_JIT_BINARY_OP_PLUS
6711
6712Addition of arithmetic values; analogous to:
6713
6714@example
6715(EXPR_A) + (EXPR_B)
6716@end example
6717
6718@noindent
6719
6720in C.
6721
eb2d3e4a 6722For pointer addition, use @pxref{a6,,gcc_jit_context_new_array_access()}.
863e76f9 6723@end deffn
6724
625691b3 6725@geindex GCC_JIT_BINARY_OP_MINUS (C macro)
eb2d3e4a 6726@anchor{topics/expressions GCC_JIT_BINARY_OP_MINUS}@anchor{9b}
625691b3 6727@deffn {C Macro} GCC_JIT_BINARY_OP_MINUS
863e76f9 6728
6729Subtraction of arithmetic values; analogous to:
6730
6731@example
6732(EXPR_A) - (EXPR_B)
6733@end example
6734
6735@noindent
6736
6737in C.
6738@end deffn
6739
6740@geindex GCC_JIT_BINARY_OP_MULT (C macro)
eb2d3e4a 6741@anchor{topics/expressions GCC_JIT_BINARY_OP_MULT}@anchor{9c}
863e76f9 6742@deffn {C Macro} GCC_JIT_BINARY_OP_MULT
6743
6744Multiplication of a pair of arithmetic values; analogous to:
6745
6746@example
6747(EXPR_A) * (EXPR_B)
6748@end example
6749
6750@noindent
6751
6752in C.
6753@end deffn
6754
6755@geindex GCC_JIT_BINARY_OP_DIVIDE (C macro)
eb2d3e4a 6756@anchor{topics/expressions GCC_JIT_BINARY_OP_DIVIDE}@anchor{9d}
863e76f9 6757@deffn {C Macro} GCC_JIT_BINARY_OP_DIVIDE
6758
6759Quotient of division of arithmetic values; analogous to:
6760
6761@example
6762(EXPR_A) / (EXPR_B)
6763@end example
6764
6765@noindent
6766
6767in C.
6768
6769The result type affects the kind of division: if the result type is
6770integer-based, then the result is truncated towards zero, whereas
6771a floating-point result type indicates floating-point division.
6772@end deffn
6773
6774@geindex GCC_JIT_BINARY_OP_MODULO (C macro)
eb2d3e4a 6775@anchor{topics/expressions GCC_JIT_BINARY_OP_MODULO}@anchor{9e}
863e76f9 6776@deffn {C Macro} GCC_JIT_BINARY_OP_MODULO
6777
6778Remainder of division of arithmetic values; analogous to:
6779
6780@example
6781(EXPR_A) % (EXPR_B)
6782@end example
6783
6784@noindent
6785
6786in C.
6787@end deffn
6788
6789@geindex GCC_JIT_BINARY_OP_BITWISE_AND (C macro)
eb2d3e4a 6790@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_AND}@anchor{9f}
863e76f9 6791@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_AND
6792
6793Bitwise AND; analogous to:
6794
6795@example
6796(EXPR_A) & (EXPR_B)
6797@end example
6798
6799@noindent
6800
6801in C.
6802@end deffn
6803
6804@geindex GCC_JIT_BINARY_OP_BITWISE_XOR (C macro)
eb2d3e4a 6805@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_XOR}@anchor{a0}
863e76f9 6806@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_XOR
6807
6808Bitwise exclusive OR; analogous to:
6809
6810@example
6811(EXPR_A) ^ (EXPR_B)
6812@end example
6813
6814@noindent
6815
6816in C.
6817@end deffn
6818
6819@geindex GCC_JIT_BINARY_OP_BITWISE_OR (C macro)
eb2d3e4a 6820@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_OR}@anchor{a1}
863e76f9 6821@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_OR
6822
6823Bitwise inclusive OR; analogous to:
6824
6825@example
6826(EXPR_A) | (EXPR_B)
6827@end example
6828
6829@noindent
6830
6831in C.
6832@end deffn
6833
6834@geindex GCC_JIT_BINARY_OP_LOGICAL_AND (C macro)
eb2d3e4a 6835@anchor{topics/expressions GCC_JIT_BINARY_OP_LOGICAL_AND}@anchor{a2}
863e76f9 6836@deffn {C Macro} GCC_JIT_BINARY_OP_LOGICAL_AND
6837
6838Logical AND; analogous to:
6839
6840@example
6841(EXPR_A) && (EXPR_B)
6842@end example
6843
6844@noindent
6845
6846in C.
6847@end deffn
6848
6849@geindex GCC_JIT_BINARY_OP_LOGICAL_OR (C macro)
eb2d3e4a 6850@anchor{topics/expressions GCC_JIT_BINARY_OP_LOGICAL_OR}@anchor{a3}
863e76f9 6851@deffn {C Macro} GCC_JIT_BINARY_OP_LOGICAL_OR
6852
6853Logical OR; analogous to:
6854
6855@example
6856(EXPR_A) || (EXPR_B)
6857@end example
6858
6859@noindent
6860
6861in C.
6862@end deffn
6863
6864@geindex GCC_JIT_BINARY_OP_LSHIFT (C macro)
eb2d3e4a 6865@anchor{topics/expressions GCC_JIT_BINARY_OP_LSHIFT}@anchor{a4}
863e76f9 6866@deffn {C Macro} GCC_JIT_BINARY_OP_LSHIFT
6867
6868Left shift; analogous to:
6869
6870@example
6871(EXPR_A) << (EXPR_B)
6872@end example
6873
6874@noindent
6875
6876in C.
6877@end deffn
6878
6879@geindex GCC_JIT_BINARY_OP_RSHIFT (C macro)
eb2d3e4a 6880@anchor{topics/expressions GCC_JIT_BINARY_OP_RSHIFT}@anchor{a5}
863e76f9 6881@deffn {C Macro} GCC_JIT_BINARY_OP_RSHIFT
6882
6883Right shift; analogous to:
6884
6885@example
6886(EXPR_A) >> (EXPR_B)
6887@end example
6888
6889@noindent
6890
6891in C.
6892@end deffn
6893
6894@node Comparisons,Function calls,Binary Operations,Rvalues
eb2d3e4a 6895@anchor{topics/expressions comparisons}@anchor{a7}
863e76f9 6896@subsubsection Comparisons
6897
6898
6899@geindex gcc_jit_context_new_comparison (C function)
eac6fba2 6900@anchor{topics/expressions gcc_jit_context_new_comparison}@anchor{2c}
863e76f9 6901@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)
6902
6903Build a boolean rvalue out of the comparison of two other rvalues.
6904@end deffn
6905
6906@geindex gcc_jit_comparison (C type)
eb2d3e4a 6907@anchor{topics/expressions gcc_jit_comparison}@anchor{a8}
863e76f9 6908@deffn {C Type} enum gcc_jit_comparison
6909@end deffn
6910
6911
6912@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx}
6913@headitem
6914
6915Comparison
6916
6917@tab
6918
6919C equivalent
6920
6921@item
6922
6923@code{GCC_JIT_COMPARISON_EQ}
6924
6925@tab
6926
6927@cite{x == y}
6928
6929@item
6930
6931@code{GCC_JIT_COMPARISON_NE}
6932
6933@tab
6934
6935@cite{x != y}
6936
6937@item
6938
6939@code{GCC_JIT_COMPARISON_LT}
6940
6941@tab
6942
6943@cite{x < y}
6944
6945@item
6946
6947@code{GCC_JIT_COMPARISON_LE}
6948
6949@tab
6950
6951@cite{x <= y}
6952
6953@item
6954
6955@code{GCC_JIT_COMPARISON_GT}
6956
6957@tab
6958
6959@cite{x > y}
6960
6961@item
6962
6963@code{GCC_JIT_COMPARISON_GE}
6964
6965@tab
6966
6967@cite{x >= y}
6968
6969@end multitable
6970
6971
6972@node Function calls,Type-coercion,Comparisons,Rvalues
eb2d3e4a 6973@anchor{topics/expressions function-calls}@anchor{a9}
863e76f9 6974@subsubsection Function calls
6975
6976
6977@geindex gcc_jit_context_new_call (C function)
eb2d3e4a 6978@anchor{topics/expressions gcc_jit_context_new_call}@anchor{aa}
863e76f9 6979@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)
6980
6981Given a function and the given table of argument rvalues, construct a
6982call to the function, with the result as an rvalue.
6983
6984@cartouche
6985@quotation Note
eb2d3e4a 6986@pxref{aa,,gcc_jit_context_new_call()} merely builds a
863e76f9 6987@pxref{13,,gcc_jit_rvalue} i.e. an expression that can be evaluated,
6988perhaps as part of a more complicated expression.
6989The call @emph{won't} happen unless you add a statement to a function
6990that evaluates the expression.
6991
6992For example, if you want to call a function and discard the result
6993(or to call a function with @code{void} return type), use
eb2d3e4a 6994@pxref{ab,,gcc_jit_block_add_eval()}:
863e76f9 6995
6996@example
6997/* Add "(void)printf (arg0, arg1);". */
6998gcc_jit_block_add_eval (
6999 block, NULL,
7000 gcc_jit_context_new_call (
7001 ctxt,
7002 NULL,
7003 printf_func,
7004 2, args));
7005@end example
7006
7007@noindent
7008@end quotation
7009@end cartouche
7010@end deffn
7011
7012@node Type-coercion,,Function calls,Rvalues
eb2d3e4a 7013@anchor{topics/expressions type-coercion}@anchor{ac}
863e76f9 7014@subsubsection Type-coercion
7015
7016
7017@geindex gcc_jit_context_new_cast (C function)
eb2d3e4a 7018@anchor{topics/expressions gcc_jit_context_new_cast}@anchor{ad}
863e76f9 7019@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)
7020
7021Given an rvalue of T, construct another rvalue of another type.
7022
7023Currently only a limited set of conversions are possible:
7024
7025@quotation
7026
7027
7028@itemize *
7029
7030@item
7031int <-> float
7032
7033@item
7034int <-> bool
7035
7036@item
7037P* <-> Q*, for pointer types P and Q
7038@end itemize
7039@end quotation
7040@end deffn
7041
7042@node Lvalues,Working with pointers structs and unions,Rvalues,Expressions
eb2d3e4a 7043@anchor{topics/expressions lvalues}@anchor{ae}
863e76f9 7044@subsection Lvalues
7045
7046
7047@geindex gcc_jit_lvalue (C type)
eac6fba2 7048@anchor{topics/expressions gcc_jit_lvalue}@anchor{24}
863e76f9 7049@deffn {C Type} gcc_jit_lvalue
7050@end deffn
7051
7052An lvalue is something that can of the @emph{left}-hand side of an assignment:
7053a storage area (such as a variable). It is also usable as an rvalue,
7054where the rvalue is computed by reading from the storage area.
7055
7056@geindex gcc_jit_lvalue_as_object (C function)
eb2d3e4a 7057@anchor{topics/expressions gcc_jit_lvalue_as_object}@anchor{af}
863e76f9 7058@deffn {C Function} gcc_jit_object * gcc_jit_lvalue_as_object (gcc_jit_lvalue@w{ }*lvalue)
7059
7060Upcast an lvalue to be an object.
7061@end deffn
7062
7063@geindex gcc_jit_lvalue_as_rvalue (C function)
eb2d3e4a 7064@anchor{topics/expressions gcc_jit_lvalue_as_rvalue}@anchor{b0}
863e76f9 7065@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue@w{ }*lvalue)
7066
7067Upcast an lvalue to be an rvalue.
7068@end deffn
7069
7070@geindex gcc_jit_lvalue_get_address (C function)
eb2d3e4a 7071@anchor{topics/expressions gcc_jit_lvalue_get_address}@anchor{b1}
863e76f9 7072@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_get_address (gcc_jit_lvalue@w{ }*lvalue, gcc_jit_location@w{ }*loc)
7073
7074Take the address of an lvalue; analogous to:
7075
7076@example
7077&(EXPR)
7078@end example
7079
7080@noindent
7081
7082in C.
7083@end deffn
7084
7085@menu
7086* Global variables::
7087
7088@end menu
7089
7090@node Global variables,,,Lvalues
eb2d3e4a 7091@anchor{topics/expressions global-variables}@anchor{b2}
863e76f9 7092@subsubsection Global variables
7093
7094
7095@geindex gcc_jit_context_new_global (C function)
eb2d3e4a 7096@anchor{topics/expressions gcc_jit_context_new_global}@anchor{b3}
15b6c83e 7097@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)
863e76f9 7098
7099Add a new global variable of the given type and name to the context.
15b6c83e 7100
1fa42b05 7101The parameter @code{name} must be non-NULL. The call takes a copy of the
7102underlying string, so it is valid to pass in a pointer to an on-stack
7103buffer.
7104
15b6c83e 7105The "kind" parameter determines the visibility of the "global" outside
7106of the @pxref{16,,gcc_jit_result}:
7107
7108@geindex gcc_jit_global_kind (C type)
eb2d3e4a 7109@anchor{topics/expressions gcc_jit_global_kind}@anchor{b4}
15b6c83e 7110@deffn {C Type} enum gcc_jit_global_kind
7111@end deffn
7112
7113@geindex GCC_JIT_GLOBAL_EXPORTED (C macro)
eb2d3e4a 7114@anchor{topics/expressions GCC_JIT_GLOBAL_EXPORTED}@anchor{b5}
15b6c83e 7115@deffn {C Macro} GCC_JIT_GLOBAL_EXPORTED
7116
7117Global is defined by the client code and is visible
7118by name outside of this JIT context via
eb2d3e4a 7119@pxref{b6,,gcc_jit_result_get_global()} (and this value is required for
15b6c83e 7120the global to be accessible via that entrypoint).
7121@end deffn
7122
7123@geindex GCC_JIT_GLOBAL_INTERNAL (C macro)
eb2d3e4a 7124@anchor{topics/expressions GCC_JIT_GLOBAL_INTERNAL}@anchor{b7}
15b6c83e 7125@deffn {C Macro} GCC_JIT_GLOBAL_INTERNAL
7126
7127Global is defined by the client code, but is invisible
7128outside of it. Analogous to a "static" global within a .c file.
7129Specifically, the variable will only be visible within this
7130context and within child contexts.
7131@end deffn
7132
7133@geindex GCC_JIT_GLOBAL_IMPORTED (C macro)
eb2d3e4a 7134@anchor{topics/expressions GCC_JIT_GLOBAL_IMPORTED}@anchor{b8}
15b6c83e 7135@deffn {C Macro} GCC_JIT_GLOBAL_IMPORTED
7136
7137Global is not defined by the client code; we're merely
7138referring to it. Analogous to using an "extern" global from a
7139header file.
7140@end deffn
863e76f9 7141@end deffn
7142
7143@node Working with pointers structs and unions,,Lvalues,Expressions
eb2d3e4a 7144@anchor{topics/expressions working-with-pointers-structs-and-unions}@anchor{b9}
863e76f9 7145@subsection Working with pointers, structs and unions
7146
7147
7148@geindex gcc_jit_rvalue_dereference (C function)
eb2d3e4a 7149@anchor{topics/expressions gcc_jit_rvalue_dereference}@anchor{ba}
863e76f9 7150@deffn {C Function} gcc_jit_lvalue * gcc_jit_rvalue_dereference (gcc_jit_rvalue@w{ }*rvalue, gcc_jit_location@w{ }*loc)
7151
7152Given an rvalue of pointer type @code{T *}, dereferencing the pointer,
7153getting an lvalue of type @code{T}. Analogous to:
7154
7155@example
7156*(EXPR)
7157@end example
7158
7159@noindent
7160
7161in C.
7162@end deffn
7163
7164Field access is provided separately for both lvalues and rvalues.
7165
7166@geindex gcc_jit_lvalue_access_field (C function)
eb2d3e4a 7167@anchor{topics/expressions gcc_jit_lvalue_access_field}@anchor{bb}
863e76f9 7168@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)
7169
7170Given an lvalue of struct or union type, access the given field,
7171getting an lvalue of the field's type. Analogous to:
7172
7173@example
7174(EXPR).field = ...;
7175@end example
7176
7177@noindent
7178
7179in C.
7180@end deffn
7181
7182@geindex gcc_jit_rvalue_access_field (C function)
eb2d3e4a 7183@anchor{topics/expressions gcc_jit_rvalue_access_field}@anchor{bc}
863e76f9 7184@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)
7185
7186Given an rvalue of struct or union type, access the given field
7187as an rvalue. Analogous to:
7188
7189@example
7190(EXPR).field
7191@end example
7192
7193@noindent
7194
7195in C.
7196@end deffn
7197
7198@geindex gcc_jit_rvalue_dereference_field (C function)
eb2d3e4a 7199@anchor{topics/expressions gcc_jit_rvalue_dereference_field}@anchor{bd}
863e76f9 7200@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)
7201
7202Given an rvalue of pointer type @code{T *} where T is of struct or union
7203type, access the given field as an lvalue. Analogous to:
7204
7205@example
7206(EXPR)->field
7207@end example
7208
7209@noindent
7210
7211in C, itself equivalent to @code{(*EXPR).FIELD}.
7212@end deffn
7213
7214@geindex gcc_jit_context_new_array_access (C function)
eb2d3e4a 7215@anchor{topics/expressions gcc_jit_context_new_array_access}@anchor{a6}
863e76f9 7216@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)
7217
7218Given an rvalue of pointer type @code{T *}, get at the element @cite{T} at
7219the given index, using standard C array indexing rules i.e. each
7220increment of @code{index} corresponds to @code{sizeof(T)} bytes.
7221Analogous to:
7222
7223@example
7224PTR[INDEX]
7225@end example
7226
7227@noindent
7228
7229in C (or, indeed, to @code{PTR + INDEX}).
7230@end deffn
7231
f1717362 7232@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 7233@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
7234@c
7235@c This is free software: you can redistribute it and/or modify it
7236@c under the terms of the GNU General Public License as published by
7237@c the Free Software Foundation, either version 3 of the License, or
7238@c (at your option) any later version.
7239@c
7240@c This program is distributed in the hope that it will be useful, but
7241@c WITHOUT ANY WARRANTY; without even the implied warranty of
7242@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7243@c General Public License for more details.
7244@c
7245@c You should have received a copy of the GNU General Public License
7246@c along with this program. If not, see
7247@c <http://www.gnu.org/licenses/>.
7248
7249@node Creating and using functions,Source Locations,Expressions,Topic Reference
eb2d3e4a 7250@anchor{topics/functions doc}@anchor{be}@anchor{topics/functions creating-and-using-functions}@anchor{bf}
863e76f9 7251@section Creating and using functions
7252
7253
7254@menu
7255* Params::
7256* Functions::
7257* Blocks::
7258* Statements::
7259
7260@end menu
7261
7262@node Params,Functions,,Creating and using functions
eb2d3e4a 7263@anchor{topics/functions params}@anchor{c0}
863e76f9 7264@subsection Params
7265
7266
7267@geindex gcc_jit_param (C type)
eac6fba2 7268@anchor{topics/functions gcc_jit_param}@anchor{25}
863e76f9 7269@deffn {C Type} gcc_jit_param
7270
7271A @cite{gcc_jit_param} represents a parameter to a function.
7272@end deffn
7273
7274@geindex gcc_jit_context_new_param (C function)
7275@anchor{topics/functions gcc_jit_context_new_param}@anchor{10}
7276@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)
7277
7278In preparation for creating a function, create a new parameter of the
7279given type and name.
1fa42b05 7280
7281The parameter @code{name} must be non-NULL. The call takes a copy of the
7282underlying string, so it is valid to pass in a pointer to an on-stack
7283buffer.
863e76f9 7284@end deffn
7285
7286Parameters are lvalues, and thus are also rvalues (and objects), so the
7287following upcasts are available:
7288
7289@geindex gcc_jit_param_as_lvalue (C function)
eb2d3e4a 7290@anchor{topics/functions gcc_jit_param_as_lvalue}@anchor{c1}
863e76f9 7291@deffn {C Function} gcc_jit_lvalue * gcc_jit_param_as_lvalue (gcc_jit_param@w{ }*param)
7292
7293Upcasting from param to lvalue.
7294@end deffn
7295
7296@geindex gcc_jit_param_as_rvalue (C function)
eb2d3e4a 7297@anchor{topics/functions gcc_jit_param_as_rvalue}@anchor{c2}
863e76f9 7298@deffn {C Function} gcc_jit_rvalue * gcc_jit_param_as_rvalue (gcc_jit_param@w{ }*param)
7299
7300Upcasting from param to rvalue.
7301@end deffn
7302
7303@geindex gcc_jit_param_as_object (C function)
eb2d3e4a 7304@anchor{topics/functions gcc_jit_param_as_object}@anchor{c3}
863e76f9 7305@deffn {C Function} gcc_jit_object * gcc_jit_param_as_object (gcc_jit_param@w{ }*param)
7306
7307Upcasting from param to object.
7308@end deffn
7309
7310@node Functions,Blocks,Params,Creating and using functions
eb2d3e4a 7311@anchor{topics/functions functions}@anchor{c4}
863e76f9 7312@subsection Functions
7313
7314
7315@geindex gcc_jit_function (C type)
eac6fba2 7316@anchor{topics/functions gcc_jit_function}@anchor{29}
863e76f9 7317@deffn {C Type} gcc_jit_function
7318
7319A @cite{gcc_jit_function} represents a function - either one that we're
7320creating ourselves, or one that we're referencing.
7321@end deffn
7322
7323@geindex gcc_jit_context_new_function (C function)
7324@anchor{topics/functions gcc_jit_context_new_function}@anchor{11}
7325@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)
7326
7327Create a gcc_jit_function with the given name and parameters.
7328
7329@geindex gcc_jit_function_kind (C type)
eb2d3e4a 7330@anchor{topics/functions gcc_jit_function_kind}@anchor{c5}
863e76f9 7331@deffn {C Type} enum gcc_jit_function_kind
7332@end deffn
7333
7334This enum controls the kind of function created, and has the following
7335values:
7336
7337@quotation
7338
7339@geindex GCC_JIT_FUNCTION_EXPORTED (C macro)
eb2d3e4a 7340@anchor{topics/functions GCC_JIT_FUNCTION_EXPORTED}@anchor{c6}
863e76f9 7341@deffn {C Macro} GCC_JIT_FUNCTION_EXPORTED
7342
7343Function is defined by the client code and visible
7344by name outside of the JIT.
97e241d3 7345
7346This value is required if you want to extract machine code
7347for this function from a @pxref{16,,gcc_jit_result} via
7348@pxref{17,,gcc_jit_result_get_code()}.
863e76f9 7349@end deffn
7350
7351@geindex GCC_JIT_FUNCTION_INTERNAL (C macro)
eb2d3e4a 7352@anchor{topics/functions GCC_JIT_FUNCTION_INTERNAL}@anchor{c7}
863e76f9 7353@deffn {C Macro} GCC_JIT_FUNCTION_INTERNAL
7354
7355Function is defined by the client code, but is invisible
7356outside of the JIT. Analogous to a "static" function.
7357@end deffn
7358
7359@geindex GCC_JIT_FUNCTION_IMPORTED (C macro)
eb2d3e4a 7360@anchor{topics/functions GCC_JIT_FUNCTION_IMPORTED}@anchor{c8}
863e76f9 7361@deffn {C Macro} GCC_JIT_FUNCTION_IMPORTED
7362
7363Function is not defined by the client code; we're merely
7364referring to it. Analogous to using an "extern" function from a
7365header file.
7366@end deffn
7367
7368@geindex GCC_JIT_FUNCTION_ALWAYS_INLINE (C macro)
eb2d3e4a 7369@anchor{topics/functions GCC_JIT_FUNCTION_ALWAYS_INLINE}@anchor{c9}
863e76f9 7370@deffn {C Macro} GCC_JIT_FUNCTION_ALWAYS_INLINE
7371
7372Function is only ever inlined into other functions, and is
7373invisible outside of the JIT.
7374
7375Analogous to prefixing with @code{inline} and adding
7376@code{__attribute__((always_inline))}
7377
7378Inlining will only occur when the optimization level is
7379above 0; when optimization is off, this is essentially the
7380same as GCC_JIT_FUNCTION_INTERNAL.
7381@end deffn
7382@end quotation
1fa42b05 7383
7384The parameter @code{name} must be non-NULL. The call takes a copy of the
7385underlying string, so it is valid to pass in a pointer to an on-stack
7386buffer.
863e76f9 7387@end deffn
7388
7389@geindex gcc_jit_context_get_builtin_function (C function)
eb2d3e4a 7390@anchor{topics/functions gcc_jit_context_get_builtin_function}@anchor{ca}
863e76f9 7391@deffn {C Function} gcc_jit_function *gcc_jit_context_get_builtin_function (gcc_jit_context@w{ }*ctxt, const char@w{ }*name)
7392@end deffn
7393
7394@geindex gcc_jit_function_as_object (C function)
eb2d3e4a 7395@anchor{topics/functions gcc_jit_function_as_object}@anchor{cb}
863e76f9 7396@deffn {C Function} gcc_jit_object * gcc_jit_function_as_object (gcc_jit_function@w{ }*func)
7397
7398Upcasting from function to object.
7399@end deffn
7400
7401@geindex gcc_jit_function_get_param (C function)
eb2d3e4a 7402@anchor{topics/functions gcc_jit_function_get_param}@anchor{cc}
863e76f9 7403@deffn {C Function} gcc_jit_param * gcc_jit_function_get_param (gcc_jit_function@w{ }*func, int@w{ }index)
7404
7405Get the param of the given index (0-based).
7406@end deffn
7407
7408@geindex gcc_jit_function_dump_to_dot (C function)
eac6fba2 7409@anchor{topics/functions gcc_jit_function_dump_to_dot}@anchor{33}
863e76f9 7410@deffn {C Function} void gcc_jit_function_dump_to_dot (gcc_jit_function@w{ }*func, const char@w{ }*path)
7411
7412Emit the function in graphviz format to the given path.
7413@end deffn
7414
7415@geindex gcc_jit_function_new_local (C function)
eac6fba2 7416@anchor{topics/functions gcc_jit_function_new_local}@anchor{26}
863e76f9 7417@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)
7418
7419Create a new local variable within the function, of the given type and
7420name.
1fa42b05 7421
7422The parameter @code{name} must be non-NULL. The call takes a copy of the
7423underlying string, so it is valid to pass in a pointer to an on-stack
7424buffer.
863e76f9 7425@end deffn
7426
7427@node Blocks,Statements,Functions,Creating and using functions
eb2d3e4a 7428@anchor{topics/functions blocks}@anchor{cd}
863e76f9 7429@subsection Blocks
7430
7431
7432@geindex gcc_jit_block (C type)
eac6fba2 7433@anchor{topics/functions gcc_jit_block}@anchor{28}
863e76f9 7434@deffn {C Type} gcc_jit_block
7435
7436A @cite{gcc_jit_block} represents a basic block within a function i.e. a
7437sequence of statements with a single entry point and a single exit
7438point.
7439
7440The first basic block that you create within a function will
7441be the entrypoint.
7442
7443Each basic block that you create within a function must be
a24ef8d2 7444terminated, either with a conditional, a jump, a return, or a
7445switch.
863e76f9 7446
7447It's legal to have multiple basic blocks that return within
7448one function.
7449@end deffn
7450
7451@geindex gcc_jit_function_new_block (C function)
eb2d3e4a 7452@anchor{topics/functions gcc_jit_function_new_block}@anchor{ce}
863e76f9 7453@deffn {C Function} gcc_jit_block * gcc_jit_function_new_block (gcc_jit_function@w{ }*func, const char@w{ }*name)
7454
7455Create a basic block of the given name. The name may be NULL, but
7456providing meaningful names is often helpful when debugging: it may
7457show up in dumps of the internal representation, and in error
1fa42b05 7458messages. It is copied, so the input buffer does not need to outlive
7459the call; you can pass in a pointer to an on-stack buffer, e.g.:
7460
7461@example
7462for (pc = 0; pc < fn->fn_num_ops; pc++)
7463 @{
7464 char buf[16];
7465 sprintf (buf, "instr%i", pc);
7466 state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf);
7467 @}
7468@end example
7469
7470@noindent
863e76f9 7471@end deffn
7472
7473@geindex gcc_jit_block_as_object (C function)
eb2d3e4a 7474@anchor{topics/functions gcc_jit_block_as_object}@anchor{cf}
863e76f9 7475@deffn {C Function} gcc_jit_object * gcc_jit_block_as_object (gcc_jit_block@w{ }*block)
7476
7477Upcast from block to object.
7478@end deffn
7479
7480@geindex gcc_jit_block_get_function (C function)
eb2d3e4a 7481@anchor{topics/functions gcc_jit_block_get_function}@anchor{d0}
863e76f9 7482@deffn {C Function} gcc_jit_function * gcc_jit_block_get_function (gcc_jit_block@w{ }*block)
7483
7484Which function is this block within?
7485@end deffn
7486
7487@node Statements,,Blocks,Creating and using functions
eb2d3e4a 7488@anchor{topics/functions statements}@anchor{d1}
863e76f9 7489@subsection Statements
7490
7491
7492@geindex gcc_jit_block_add_eval (C function)
eb2d3e4a 7493@anchor{topics/functions gcc_jit_block_add_eval}@anchor{ab}
863e76f9 7494@deffn {C Function} void gcc_jit_block_add_eval (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*rvalue)
7495
7496Add evaluation of an rvalue, discarding the result
7497(e.g. a function call that "returns" void).
7498
7499This is equivalent to this C code:
7500
7501@example
7502(void)expression;
7503@end example
7504
7505@noindent
7506@end deffn
7507
7508@geindex gcc_jit_block_add_assignment (C function)
eac6fba2 7509@anchor{topics/functions gcc_jit_block_add_assignment}@anchor{2a}
863e76f9 7510@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)
7511
7512Add evaluation of an rvalue, assigning the result to the given
7513lvalue.
7514
7515This is roughly equivalent to this C code:
7516
7517@example
7518lvalue = rvalue;
7519@end example
7520
7521@noindent
7522@end deffn
7523
7524@geindex gcc_jit_block_add_assignment_op (C function)
eac6fba2 7525@anchor{topics/functions gcc_jit_block_add_assignment_op}@anchor{2e}
863e76f9 7526@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)
7527
7528Add evaluation of an rvalue, using the result to modify an
7529lvalue.
7530
7531This is analogous to "+=" and friends:
7532
7533@example
7534lvalue += rvalue;
7535lvalue *= rvalue;
7536lvalue /= rvalue;
7537@end example
7538
7539@noindent
7540
7541etc. For example:
7542
7543@example
7544/* "i++" */
7545gcc_jit_block_add_assignment_op (
7546 loop_body, NULL,
7547 i,
7548 GCC_JIT_BINARY_OP_PLUS,
7549 gcc_jit_context_one (ctxt, int_type));
7550@end example
7551
7552@noindent
7553@end deffn
7554
7555@geindex gcc_jit_block_add_comment (C function)
eac6fba2 7556@anchor{topics/functions gcc_jit_block_add_comment}@anchor{3d}
863e76f9 7557@deffn {C Function} void gcc_jit_block_add_comment (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, const char@w{ }*text)
7558
7559Add a no-op textual comment to the internal representation of the
7560code. It will be optimized away, but will be visible in the dumps
69834ed9 7561seen via @pxref{66,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE}
eac6fba2 7562and @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE},
863e76f9 7563and thus may be of use when debugging how your project's internal
7564representation gets converted to the libgccjit IR.
1fa42b05 7565
7566The parameter @code{text} must be non-NULL. It is copied, so the input
7567buffer does not need to outlive the call. For example:
7568
7569@example
7570char buf[100];
7571snprintf (buf, sizeof (buf),
7572 "op%i: %s",
7573 pc, opcode_names[op->op_opcode]);
7574gcc_jit_block_add_comment (block, loc, buf);
7575@end example
7576
7577@noindent
863e76f9 7578@end deffn
7579
7580@geindex gcc_jit_block_end_with_conditional (C function)
eac6fba2 7581@anchor{topics/functions gcc_jit_block_end_with_conditional}@anchor{2d}
863e76f9 7582@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)
7583
7584Terminate a block by adding evaluation of an rvalue, branching on the
7585result to the appropriate successor block.
7586
7587This is roughly equivalent to this C code:
7588
7589@example
7590if (boolval)
7591 goto on_true;
7592else
7593 goto on_false;
7594@end example
7595
7596@noindent
7597
7598block, boolval, on_true, and on_false must be non-NULL.
7599@end deffn
7600
7601@geindex gcc_jit_block_end_with_jump (C function)
eb2d3e4a 7602@anchor{topics/functions gcc_jit_block_end_with_jump}@anchor{d2}
863e76f9 7603@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)
7604
7605Terminate a block by adding a jump to the given target block.
7606
7607This is roughly equivalent to this C code:
7608
7609@example
7610goto target;
7611@end example
7612
7613@noindent
7614@end deffn
7615
7616@geindex gcc_jit_block_end_with_return (C function)
eb2d3e4a 7617@anchor{topics/functions gcc_jit_block_end_with_return}@anchor{d3}
863e76f9 7618@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)
7619
7620Terminate a block by adding evaluation of an rvalue, returning the value.
7621
7622This is roughly equivalent to this C code:
7623
7624@example
7625return expression;
7626@end example
7627
7628@noindent
7629@end deffn
7630
7631@geindex gcc_jit_block_end_with_void_return (C function)
eb2d3e4a 7632@anchor{topics/functions gcc_jit_block_end_with_void_return}@anchor{d4}
863e76f9 7633@deffn {C Function} void gcc_jit_block_end_with_void_return (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc)
7634
7635Terminate a block by adding a valueless return, for use within a function
7636with "void" return type.
7637
7638This is equivalent to this C code:
7639
7640@example
7641return;
7642@end example
7643
7644@noindent
7645@end deffn
7646
a24ef8d2 7647@geindex gcc_jit_block_end_with_switch (C function)
eb2d3e4a 7648@anchor{topics/functions gcc_jit_block_end_with_switch}@anchor{d5}
a24ef8d2 7649@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)
7650
7651Terminate a block by adding evalation of an rvalue, then performing
7652a multiway branch.
7653
7654This is roughly equivalent to this C code:
7655
7656@example
7657switch (expr)
7658 @{
7659 default:
7660 goto default_block;
7661
7662 case C0.min_value ... C0.max_value:
7663 goto C0.dest_block;
7664
7665 case C1.min_value ... C1.max_value:
7666 goto C1.dest_block;
7667
7668 ...etc...
7669
7670 case C[N - 1].min_value ... C[N - 1].max_value:
7671 goto C[N - 1].dest_block;
7672@}
7673@end example
7674
7675@noindent
7676
7677@code{block}, @code{expr}, @code{default_block} and @code{cases} must all be
7678non-NULL.
7679
7680@code{expr} must be of the same integer type as all of the @code{min_value}
7681and @code{max_value} within the cases.
7682
7683@code{num_cases} must be >= 0.
7684
7685The ranges of the cases must not overlap (or have duplicate
7686values).
7687
7688The API entrypoints relating to switch statements and cases:
7689
7690@quotation
7691
7692
7693@itemize *
7694
7695@item
eb2d3e4a 7696@pxref{d5,,gcc_jit_block_end_with_switch()}
a24ef8d2 7697
7698@item
eb2d3e4a 7699@pxref{d6,,gcc_jit_case_as_object()}
a24ef8d2 7700
7701@item
eb2d3e4a 7702@pxref{d7,,gcc_jit_context_new_case()}
a24ef8d2 7703@end itemize
7704@end quotation
7705
eb2d3e4a 7706were added in @pxref{d8,,LIBGCCJIT_ABI_3}; you can test for their presence
a24ef8d2 7707using
7708
7709@example
7710#ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS
7711@end example
7712
7713@noindent
7714
7715@geindex gcc_jit_case (C type)
eb2d3e4a 7716@anchor{topics/functions gcc_jit_case}@anchor{d9}
a24ef8d2 7717@deffn {C Type} gcc_jit_case
7718@end deffn
7719
7720A @cite{gcc_jit_case} represents a case within a switch statement, and
7721is created within a particular @pxref{8,,gcc_jit_context} using
eb2d3e4a 7722@pxref{d7,,gcc_jit_context_new_case()}.
a24ef8d2 7723
7724Each case expresses a multivalued range of integer values. You
7725can express single-valued cases by passing in the same value for
7726both @cite{min_value} and @cite{max_value}.
7727
7728@geindex gcc_jit_context_new_case (C function)
eb2d3e4a 7729@anchor{topics/functions gcc_jit_context_new_case}@anchor{d7}
a24ef8d2 7730@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)
7731
7732Create a new gcc_jit_case instance for use in a switch statement.
7733@cite{min_value} and @cite{max_value} must be constants of an integer type,
7734which must match that of the expression of the switch statement.
7735
7736@cite{dest_block} must be within the same function as the switch
7737statement.
7738@end deffn
7739
7740@geindex gcc_jit_case_as_object (C function)
eb2d3e4a 7741@anchor{topics/functions gcc_jit_case_as_object}@anchor{d6}
a24ef8d2 7742@deffn {C Function} gcc_jit_object * gcc_jit_case_as_object (gcc_jit_case@w{ }*case_)
7743
7744Upcast from a case to an object.
7745@end deffn
7746
7747Here's an example of creating a switch statement:
7748
7749@quotation
7750
7751@example
7752
7753void
7754create_code (gcc_jit_context *ctxt, void *user_data)
7755@{
7756 /* Let's try to inject the equivalent of:
7757 int
7758 test_switch (int x)
7759 @{
7760 switch (x)
7761 @{
7762 case 0 ... 5:
7763 return 3;
7764
7765 case 25 ... 27:
7766 return 4;
7767
7768 case -42 ... -17:
7769 return 83;
7770
7771 case 40:
7772 return 8;
7773
7774 default:
7775 return 10;
7776 @}
7777 @}
7778 */
7779 gcc_jit_type *t_int =
7780 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
7781 gcc_jit_type *return_type = t_int;
7782 gcc_jit_param *x =
7783 gcc_jit_context_new_param (ctxt, NULL, t_int, "x");
7784 gcc_jit_param *params[1] = @{x@};
7785 gcc_jit_function *func =
7786 gcc_jit_context_new_function (ctxt, NULL,
7787 GCC_JIT_FUNCTION_EXPORTED,
7788 return_type,
7789 "test_switch",
7790 1, params, 0);
7791
7792 gcc_jit_block *b_initial =
7793 gcc_jit_function_new_block (func, "initial");
7794
7795 gcc_jit_block *b_default =
7796 gcc_jit_function_new_block (func, "default");
7797 gcc_jit_block *b_case_0_5 =
7798 gcc_jit_function_new_block (func, "case_0_5");
7799 gcc_jit_block *b_case_25_27 =
7800 gcc_jit_function_new_block (func, "case_25_27");
7801 gcc_jit_block *b_case_m42_m17 =
7802 gcc_jit_function_new_block (func, "case_m42_m17");
7803 gcc_jit_block *b_case_40 =
7804 gcc_jit_function_new_block (func, "case_40");
7805
7806 gcc_jit_case *cases[4] = @{
7807 gcc_jit_context_new_case (
7808 ctxt,
7809 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 0),
7810 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 5),
7811 b_case_0_5),
7812 gcc_jit_context_new_case (
7813 ctxt,
7814 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 25),
7815 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 27),
7816 b_case_25_27),
7817 gcc_jit_context_new_case (
7818 ctxt,
7819 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -42),
7820 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -17),
7821 b_case_m42_m17),
7822 gcc_jit_context_new_case (
7823 ctxt,
7824 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40),
7825 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40),
7826 b_case_40)
7827 @};
7828 gcc_jit_block_end_with_switch (
7829 b_initial, NULL,
7830 gcc_jit_param_as_rvalue (x),
7831 b_default,
7832 4, cases);
7833
7834 gcc_jit_block_end_with_return (
7835 b_case_0_5, NULL,
7836 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3));
7837 gcc_jit_block_end_with_return (
7838 b_case_25_27, NULL,
7839 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 4));
7840 gcc_jit_block_end_with_return (
7841 b_case_m42_m17, NULL,
7842 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 83));
7843 gcc_jit_block_end_with_return (
7844 b_case_40, NULL,
7845 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 8));
7846 gcc_jit_block_end_with_return (
7847 b_default, NULL,
7848 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10));
7849@}
7850
7851
7852@end example
7853
7854@noindent
7855@end quotation
7856@end deffn
7857
f1717362 7858@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 7859@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
7860@c
7861@c This is free software: you can redistribute it and/or modify it
7862@c under the terms of the GNU General Public License as published by
7863@c the Free Software Foundation, either version 3 of the License, or
7864@c (at your option) any later version.
7865@c
7866@c This program is distributed in the hope that it will be useful, but
7867@c WITHOUT ANY WARRANTY; without even the implied warranty of
7868@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7869@c General Public License for more details.
7870@c
7871@c You should have received a copy of the GNU General Public License
7872@c along with this program. If not, see
7873@c <http://www.gnu.org/licenses/>.
7874
69834ed9 7875@node Source Locations,Compiling a context,Creating and using functions,Topic Reference
eb2d3e4a 7876@anchor{topics/locations source-locations}@anchor{da}@anchor{topics/locations doc}@anchor{db}
863e76f9 7877@section Source Locations
7878
7879
7880@geindex gcc_jit_location (C type)
eac6fba2 7881@anchor{topics/locations gcc_jit_location}@anchor{3b}
863e76f9 7882@deffn {C Type} gcc_jit_location
7883
7884A @cite{gcc_jit_location} encapsulates a source code location, so that
7885you can (optionally) associate locations in your language with
7886statements in the JIT-compiled code, allowing the debugger to
7887single-step through your language.
7888
7889@cite{gcc_jit_location} instances are optional: you can always pass NULL to
7890any API entrypoint accepting one.
7891
eac6fba2 7892You can construct them using @pxref{41,,gcc_jit_context_new_location()}.
863e76f9 7893
eac6fba2 7894You need to enable @pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the
863e76f9 7895@pxref{8,,gcc_jit_context} for these locations to actually be usable by
7896the debugger:
7897
7898@example
7899gcc_jit_context_set_bool_option (
7900 ctxt,
7901 GCC_JIT_BOOL_OPTION_DEBUGINFO,
7902 1);
7903@end example
7904
7905@noindent
7906@end deffn
7907
7908@geindex gcc_jit_context_new_location (C function)
eac6fba2 7909@anchor{topics/locations gcc_jit_context_new_location}@anchor{41}
863e76f9 7910@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)
7911
7912Create a @cite{gcc_jit_location} instance representing the given source
7913location.
1fa42b05 7914
7915The parameter @code{filename} must be non-NULL. The call takes a copy of
7916the underlying string, so it is valid to pass in a pointer to an
7917on-stack buffer.
863e76f9 7918@end deffn
7919
7920@menu
7921* Faking it::
7922
7923@end menu
7924
7925@node Faking it,,,Source Locations
eb2d3e4a 7926@anchor{topics/locations faking-it}@anchor{dc}
863e76f9 7927@subsection Faking it
7928
7929
7930If you don't have source code for your internal representation, but need
7931to debug, you can generate a C-like representation of the functions in
69834ed9 7932your context using @pxref{5a,,gcc_jit_context_dump_to_file()}:
863e76f9 7933
7934@example
7935gcc_jit_context_dump_to_file (ctxt, "/tmp/something.c",
7936 1 /* update_locations */);
7937@end example
7938
7939@noindent
7940
7941This will dump C-like code to the given path. If the @cite{update_locations}
7942argument is true, this will also set up @cite{gcc_jit_location} information
7943throughout the context, pointing at the dump file as if it were a source
7944file, giving you @emph{something} you can step through in the debugger.
7945
f1717362 7946@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 7947@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
7948@c
7949@c This is free software: you can redistribute it and/or modify it
7950@c under the terms of the GNU General Public License as published by
7951@c the Free Software Foundation, either version 3 of the License, or
7952@c (at your option) any later version.
7953@c
7954@c This program is distributed in the hope that it will be useful, but
7955@c WITHOUT ANY WARRANTY; without even the implied warranty of
7956@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7957@c General Public License for more details.
7958@c
7959@c You should have received a copy of the GNU General Public License
7960@c along with this program. If not, see
7961@c <http://www.gnu.org/licenses/>.
7962
adb2df55 7963@node Compiling a context,ABI and API compatibility,Source Locations,Topic Reference
eb2d3e4a 7964@anchor{topics/compilation compiling-a-context}@anchor{dd}@anchor{topics/compilation doc}@anchor{de}
69834ed9 7965@section Compiling a context
863e76f9 7966
7967
69834ed9 7968Once populated, a @pxref{8,,gcc_jit_context *} can be compiled to
7969machine code, either in-memory via @pxref{15,,gcc_jit_context_compile()} or
7970to disk via @pxref{4a,,gcc_jit_context_compile_to_file()}.
7971
7972You can compile a context multiple times (using either form of
7973compilation), although any errors that occur on the context will
7974prevent any future compilation of that context.
7975
7976@menu
7977* In-memory compilation::
7978* Ahead-of-time compilation::
7979
7980@end menu
7981
7982@node In-memory compilation,Ahead-of-time compilation,,Compiling a context
eb2d3e4a 7983@anchor{topics/compilation in-memory-compilation}@anchor{df}
69834ed9 7984@subsection In-memory compilation
863e76f9 7985
863e76f9 7986
7987@geindex gcc_jit_context_compile (C function)
69834ed9 7988@anchor{topics/compilation gcc_jit_context_compile}@anchor{15}
863e76f9 7989@deffn {C Function} gcc_jit_result * gcc_jit_context_compile (gcc_jit_context@w{ }*ctxt)
7990
7991This calls into GCC and builds the code, returning a
7992@cite{gcc_jit_result *}.
15b6c83e 7993
625691b3 7994If the result is non-NULL, the caller becomes responsible for
15b6c83e 7995calling @pxref{39,,gcc_jit_result_release()} on it once they're done
7996with it.
863e76f9 7997@end deffn
7998
69834ed9 7999@geindex gcc_jit_result (C type)
8000@anchor{topics/compilation gcc_jit_result}@anchor{16}
8001@deffn {C Type} gcc_jit_result
8002
8003A @cite{gcc_jit_result} encapsulates the result of compiling a context
8004in-memory, and the lifetimes of any machine code functions or globals
9cca2e95 8005that are within the result.
69834ed9 8006@end deffn
8007
863e76f9 8008@geindex gcc_jit_result_get_code (C function)
69834ed9 8009@anchor{topics/compilation gcc_jit_result_get_code}@anchor{17}
863e76f9 8010@deffn {C Function} void * gcc_jit_result_get_code (gcc_jit_result@w{ }*result, const char@w{ }*funcname)
8011
8012Locate a given function within the built machine code.
97e241d3 8013
8014Functions are looked up by name. For this to succeed, a function
8015with a name matching @cite{funcname} must have been created on
8016@cite{result}'s context (or a parent context) via a call to
8017@pxref{11,,gcc_jit_context_new_function()} with @cite{kind}
eb2d3e4a 8018@pxref{c6,,GCC_JIT_FUNCTION_EXPORTED}:
97e241d3 8019
8020@example
8021gcc_jit_context_new_function (ctxt,
8022 any_location, /* or NULL */
8023 /* Required for func to be visible to
8024 gcc_jit_result_get_code: */
8025 GCC_JIT_FUNCTION_EXPORTED,
8026 any_return_type,
8027 /* Must string-compare equal: */
8028 funcname,
8029 /* etc */);
8030@end example
8031
8032@noindent
8033
8034If such a function is not found (or @cite{result} or @cite{funcname} are
8035@code{NULL}), an error message will be emitted on stderr and
8036@code{NULL} will be returned.
8037
8038If the function is found, the result will need to be cast to a
8039function pointer of the correct type before it can be called.
8040
8041Note that the resulting machine code becomes invalid after
8042@pxref{39,,gcc_jit_result_release()} is called on the
15b6c83e 8043@pxref{16,,gcc_jit_result *}; attempting to call it after that may lead
8044to a segmentation fault.
8045@end deffn
8046
8047@geindex gcc_jit_result_get_global (C function)
eb2d3e4a 8048@anchor{topics/compilation gcc_jit_result_get_global}@anchor{b6}
15b6c83e 8049@deffn {C Function} void * gcc_jit_result_get_global (gcc_jit_result@w{ }*result, const char@w{ }*name)
8050
8051Locate a given global within the built machine code.
8052
8053Globals are looked up by name. For this to succeed, a global
8054with a name matching @cite{name} must have been created on
8055@cite{result}'s context (or a parent context) via a call to
eb2d3e4a 8056@pxref{b3,,gcc_jit_context_new_global()} with @cite{kind}
8057@pxref{b5,,GCC_JIT_GLOBAL_EXPORTED}.
15b6c83e 8058
8059If the global is found, the result will need to be cast to a
8060pointer of the correct type before it can be called.
8061
8062This is a @emph{pointer} to the global, so e.g. for an @code{int} this is
8063an @code{int *}.
8064
8065For example, given an @code{int foo;} created this way:
8066
8067@example
8068gcc_jit_lvalue *exported_global =
8069 gcc_jit_context_new_global (ctxt,
8070 any_location, /* or NULL */
8071 GCC_JIT_GLOBAL_EXPORTED,
8072 int_type,
8073 "foo");
8074@end example
8075
8076@noindent
8077
8078we can access it like this:
8079
8080@example
8081int *ptr_to_foo =
8082 (int *)gcc_jit_result_get_global (result, "foo");
8083@end example
8084
8085@noindent
8086
8087If such a global is not found (or @cite{result} or @cite{name} are
8088@code{NULL}), an error message will be emitted on stderr and
8089@code{NULL} will be returned.
8090
8091Note that the resulting address becomes invalid after
8092@pxref{39,,gcc_jit_result_release()} is called on the
8093@pxref{16,,gcc_jit_result *}; attempting to use it after that may lead
97e241d3 8094to a segmentation fault.
863e76f9 8095@end deffn
8096
8097@geindex gcc_jit_result_release (C function)
69834ed9 8098@anchor{topics/compilation gcc_jit_result_release}@anchor{39}
863e76f9 8099@deffn {C Function} void gcc_jit_result_release (gcc_jit_result@w{ }*result)
8100
8101Once we're done with the code, this unloads the built .so file.
8102This cleans up the result; after calling this, it's no longer
15b6c83e 8103valid to use the result, or any code or globals that were obtained
8104by calling @pxref{17,,gcc_jit_result_get_code()} or
eb2d3e4a 8105@pxref{b6,,gcc_jit_result_get_global()} on it.
69834ed9 8106@end deffn
8107
8108@node Ahead-of-time compilation,,In-memory compilation,Compiling a context
eb2d3e4a 8109@anchor{topics/compilation ahead-of-time-compilation}@anchor{e0}
69834ed9 8110@subsection Ahead-of-time compilation
8111
8112
8113Although libgccjit is primarily aimed at just-in-time compilation, it
8114can also be used for implementing more traditional ahead-of-time
8115compilers, via the @pxref{4a,,gcc_jit_context_compile_to_file()}
8116API entrypoint.
8117
8118@geindex gcc_jit_context_compile_to_file (C function)
8119@anchor{topics/compilation gcc_jit_context_compile_to_file}@anchor{4a}
8120@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)
8121
8122Compile the @pxref{8,,gcc_jit_context *} to a file of the given
8123kind.
8124@end deffn
8125
8126@pxref{4a,,gcc_jit_context_compile_to_file()} ignores the suffix of
8127@code{output_path}, and insteads uses the given
8128@code{enum gcc_jit_output_kind} to decide what to do.
8129
8130@cartouche
8131@quotation Note
8132This is different from the @code{gcc} program, which does make use of the
8133suffix of the output file when determining what to do.
8134@end quotation
8135@end cartouche
8136
8137@geindex gcc_jit_output_kind (C type)
eb2d3e4a 8138@anchor{topics/compilation gcc_jit_output_kind}@anchor{e1}
69834ed9 8139@deffn {C Type} enum gcc_jit_output_kind
8140@end deffn
8141
8142The available kinds of output are:
8143
8144
8145@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxx}
8146@headitem
8147
8148Output kind
8149
8150@tab
8151
8152Typical suffix
8153
8154@item
8155
eb2d3e4a 8156@pxref{e2,,GCC_JIT_OUTPUT_KIND_ASSEMBLER}
69834ed9 8157
8158@tab
8159
8160.s
8161
8162@item
8163
eb2d3e4a 8164@pxref{e3,,GCC_JIT_OUTPUT_KIND_OBJECT_FILE}
69834ed9 8165
8166@tab
8167
8168.o
8169
8170@item
8171
eb2d3e4a 8172@pxref{e4,,GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY}
69834ed9 8173
8174@tab
8175
8176.so or .dll
8177
8178@item
8179
eb2d3e4a 8180@pxref{e5,,GCC_JIT_OUTPUT_KIND_EXECUTABLE}
69834ed9 8181
8182@tab
8183
8184None, or .exe
8185
8186@end multitable
8187
8188
8189@geindex GCC_JIT_OUTPUT_KIND_ASSEMBLER (C macro)
eb2d3e4a 8190@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_ASSEMBLER}@anchor{e2}
69834ed9 8191@deffn {C Macro} GCC_JIT_OUTPUT_KIND_ASSEMBLER
8192
8193Compile the context to an assembler file.
8194@end deffn
8195
8196@geindex GCC_JIT_OUTPUT_KIND_OBJECT_FILE (C macro)
eb2d3e4a 8197@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_OBJECT_FILE}@anchor{e3}
69834ed9 8198@deffn {C Macro} GCC_JIT_OUTPUT_KIND_OBJECT_FILE
8199
8200Compile the context to an object file.
8201@end deffn
8202
8203@geindex GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY (C macro)
eb2d3e4a 8204@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY}@anchor{e4}
69834ed9 8205@deffn {C Macro} GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY
8206
8207Compile the context to a dynamic library.
8208
8209There is currently no support for specifying other libraries to link
8210against.
8211@end deffn
8212
8213@geindex GCC_JIT_OUTPUT_KIND_EXECUTABLE (C macro)
eb2d3e4a 8214@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_EXECUTABLE}@anchor{e5}
69834ed9 8215@deffn {C Macro} GCC_JIT_OUTPUT_KIND_EXECUTABLE
8216
8217Compile the context to an executable.
8218
8219There is currently no support for specifying libraries to link
8220against.
863e76f9 8221@end deffn
8222
f1717362 8223@c Copyright (C) 2015-2016 Free Software Foundation, Inc.
adb2df55 8224@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
8225@c
8226@c This is free software: you can redistribute it and/or modify it
8227@c under the terms of the GNU General Public License as published by
8228@c the Free Software Foundation, either version 3 of the License, or
8229@c (at your option) any later version.
8230@c
8231@c This program is distributed in the hope that it will be useful, but
8232@c WITHOUT ANY WARRANTY; without even the implied warranty of
8233@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8234@c General Public License for more details.
8235@c
8236@c You should have received a copy of the GNU General Public License
8237@c along with this program. If not, see
8238@c <http://www.gnu.org/licenses/>.
8239
17c0b84b 8240@node ABI and API compatibility,Performance,Compiling a context,Topic Reference
eb2d3e4a 8241@anchor{topics/compatibility abi-and-api-compatibility}@anchor{e6}@anchor{topics/compatibility doc}@anchor{e7}
adb2df55 8242@section ABI and API compatibility
8243
8244
8245The libgccjit developers strive for ABI and API backward-compatibility:
8246programs built against libgccjit.so stand a good chance of running
8247without recompilation against newer versions of libgccjit.so, and
8248ought to recompile without modification against newer versions of
8249libgccjit.h.
8250
8251@cartouche
8252@quotation Note
8253The libgccjit++.h C++ API is more experimental, and less
8254locked-down at this time.
8255@end quotation
8256@end cartouche
8257
8258API compatibility is achieved by extending the API rather than changing
8259it. For ABI compatiblity, we avoid bumping the SONAME, and instead use
8260symbol versioning to tag each symbol, so that a binary linked against
8261libgccjit.so is tagged according to the symbols that it uses.
8262
04feb56e 8263For example, @pxref{70,,gcc_jit_context_add_command_line_option()} was added in
adb2df55 8264@code{LIBGCCJIT_ABI_1}. If a client program uses it, this can be detected
8265from metadata by using @code{objdump}:
8266
8267@example
8268$ objdump -p testsuite/jit/test-extra-options.c.exe | tail -n 8
8269
8270Version References:
8271 required from libgccjit.so.0:
8272 0x00824161 0x00 04 LIBGCCJIT_ABI_1
8273 0x00824160 0x00 03 LIBGCCJIT_ABI_0
8274 required from libc.so.6:
adb2df55 8275@end example
8276
8277@noindent
8278
8279You can see the symbol tags provided by libgccjit.so using @code{objdump}:
8280
8281@example
8282$ objdump -p libgccjit.so | less
8283[...snip...]
8284Version definitions:
82851 0x01 0x0ff81f20 libgccjit.so.0
82862 0x00 0x00824160 LIBGCCJIT_ABI_0
82873 0x00 0x00824161 LIBGCCJIT_ABI_1
8288 LIBGCCJIT_ABI_0
8289[...snip...]
8290@end example
8291
8292@noindent
8293
8294@menu
8295* ABI symbol tags::
8296
8297ABI symbol tags
8298
8299* LIBGCCJIT_ABI_0::
8300* LIBGCCJIT_ABI_1::
04feb56e 8301* LIBGCCJIT_ABI_2::
a24ef8d2 8302* LIBGCCJIT_ABI_3::
17c0b84b 8303* LIBGCCJIT_ABI_4::
adb2df55 8304
8305@end menu
8306
8307
8308@node ABI symbol tags,,,ABI and API compatibility
eb2d3e4a 8309@anchor{topics/compatibility abi-symbol-tags}@anchor{e8}
adb2df55 8310@subsection ABI symbol tags
8311
8312
8313The initial release of libgccjit (in gcc 5.1) did not use symbol versioning.
8314
8315Newer releases use the following tags.
8316
8317@menu
8318* LIBGCCJIT_ABI_0::
8319* LIBGCCJIT_ABI_1::
04feb56e 8320* LIBGCCJIT_ABI_2::
a24ef8d2 8321* LIBGCCJIT_ABI_3::
17c0b84b 8322* LIBGCCJIT_ABI_4::
adb2df55 8323
8324@end menu
8325
8326@node LIBGCCJIT_ABI_0,LIBGCCJIT_ABI_1,,ABI symbol tags
eb2d3e4a 8327@anchor{topics/compatibility libgccjit-abi-0}@anchor{e9}@anchor{topics/compatibility id1}@anchor{ea}
adb2df55 8328@subsubsection @code{LIBGCCJIT_ABI_0}
8329
8330
8331All entrypoints in the initial release of libgccjit are tagged with
8332@code{LIBGCCJIT_ABI_0}, to signify the transition to symbol versioning.
8333
8334Binaries built against older copies of @code{libgccjit.so} should
8335continue to work, with this being handled transparently by the linker
8336(see this post@footnote{https://gcc.gnu.org/ml/gcc-patches/2015-06/msg02126.html})
8337
04feb56e 8338@node LIBGCCJIT_ABI_1,LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_0,ABI symbol tags
eb2d3e4a 8339@anchor{topics/compatibility libgccjit-abi-1}@anchor{71}@anchor{topics/compatibility id2}@anchor{eb}
adb2df55 8340@subsubsection @code{LIBGCCJIT_ABI_1}
8341
8342
8343@code{LIBGCCJIT_ABI_1} covers the addition of
04feb56e 8344@pxref{70,,gcc_jit_context_add_command_line_option()}
8345
a24ef8d2 8346@node LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_3,LIBGCCJIT_ABI_1,ABI symbol tags
eb2d3e4a 8347@anchor{topics/compatibility libgccjit-abi-2}@anchor{6c}@anchor{topics/compatibility id3}@anchor{ec}
04feb56e 8348@subsubsection @code{LIBGCCJIT_ABI_2}
8349
8350
8351@code{LIBGCCJIT_ABI_2} covers the addition of
8352@pxref{6b,,gcc_jit_context_set_bool_allow_unreachable_blocks()}
adb2df55 8353
17c0b84b 8354@node LIBGCCJIT_ABI_3,LIBGCCJIT_ABI_4,LIBGCCJIT_ABI_2,ABI symbol tags
eb2d3e4a 8355@anchor{topics/compatibility libgccjit-abi-3}@anchor{d8}@anchor{topics/compatibility id4}@anchor{ed}
a24ef8d2 8356@subsubsection @code{LIBGCCJIT_ABI_3}
8357
8358
8359@code{LIBGCCJIT_ABI_3} covers the addition of switch statements via API
8360entrypoints:
8361
8362@quotation
8363
8364
8365@itemize *
8366
8367@item
eb2d3e4a 8368@pxref{d5,,gcc_jit_block_end_with_switch()}
a24ef8d2 8369
8370@item
eb2d3e4a 8371@pxref{d6,,gcc_jit_case_as_object()}
a24ef8d2 8372
8373@item
eb2d3e4a 8374@pxref{d7,,gcc_jit_context_new_case()}
a24ef8d2 8375@end itemize
8376@end quotation
8377
17c0b84b 8378@node LIBGCCJIT_ABI_4,,LIBGCCJIT_ABI_3,ABI symbol tags
8379@anchor{topics/compatibility id5}@anchor{ee}@anchor{topics/compatibility libgccjit-abi-4}@anchor{ef}
8380@subsubsection @code{LIBGCCJIT_ABI_4}
8381
8382
8383@code{LIBGCCJIT_ABI_4} covers the addition of timers via API
8384entrypoints:
8385
8386@quotation
8387
8388
8389@itemize *
8390
8391@item
8392@pxref{f0,,gcc_jit_context_get_timer()}
8393
8394@item
8395@pxref{f1,,gcc_jit_context_set_timer()}
8396
8397@item
8398@pxref{f2,,gcc_jit_timer_new()}
8399
8400@item
8401@pxref{f3,,gcc_jit_timer_release()}
8402
8403@item
8404@pxref{f4,,gcc_jit_timer_push()}
8405
8406@item
8407@pxref{f5,,gcc_jit_timer_pop()}
8408
8409@item
8410@pxref{f6,,gcc_jit_timer_print()}
8411@end itemize
8412@end quotation
8413
f1717362 8414@c Copyright (C) 2015-2016 Free Software Foundation, Inc.
17c0b84b 8415@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
8416@c
8417@c This is free software: you can redistribute it and/or modify it
8418@c under the terms of the GNU General Public License as published by
8419@c the Free Software Foundation, either version 3 of the License, or
8420@c (at your option) any later version.
8421@c
8422@c This program is distributed in the hope that it will be useful, but
8423@c WITHOUT ANY WARRANTY; without even the implied warranty of
8424@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8425@c General Public License for more details.
8426@c
8427@c You should have received a copy of the GNU General Public License
8428@c along with this program. If not, see
8429@c <http://www.gnu.org/licenses/>.
8430
8431@node Performance,,ABI and API compatibility,Topic Reference
8432@anchor{topics/performance performance}@anchor{f7}@anchor{topics/performance doc}@anchor{f8}
8433@section Performance
8434
8435
8436@menu
8437* The timing API::
8438
8439@end menu
8440
8441@node The timing API,,,Performance
8442@anchor{topics/performance the-timing-api}@anchor{f9}
8443@subsection The timing API
8444
8445
8446As of GCC 6, libgccjit exposes a timing API, for printing reports on
8447how long was spent in different parts of code.
8448
8449You can create a @pxref{fa,,gcc_jit_timer} instance, which will
8450measure time spent since its creation. The timer maintains a stack
8451of "timer items": as control flow moves through your code, you can push
8452and pop named items relating to your code onto the stack, and the timer
8453will account the time spent accordingly.
8454
8455You can also asssociate a timer with a @pxref{8,,gcc_jit_context}, in
8456which case the time spent inside compilation will be subdivided.
8457
8458For example, the following code uses a timer, recording client items
8459"create_code", "compile", and "running code":
8460
8461@example
8462/* Create a timer. */
8463gcc_jit_timer *timer = gcc_jit_timer_new ();
8464if (!timer)
8465 @{
8466 error ("gcc_jit_timer_new failed");
8467 return -1;
8468 @}
8469
8470/* Let's repeatedly compile and run some code, accumulating it
8471 all into the timer. */
8472for (int i = 0; i < num_iterations; i++)
8473 @{
8474 /* Create a context and associate it with the timer. */
8475 gcc_jit_context *ctxt = gcc_jit_context_acquire ();
8476 if (!ctxt)
8477 @{
8478 error ("gcc_jit_context_acquire failed");
8479 return -1;
8480 @}
8481 gcc_jit_context_set_timer (ctxt, timer);
8482
8483 /* Populate the context, timing it as client item "create_code". */
8484 gcc_jit_timer_push (timer, "create_code");
8485 create_code (ctxt);
8486 gcc_jit_timer_pop (timer, "create_code");
8487
8488 /* Compile the context, timing it as client item "compile". */
8489 gcc_jit_timer_push (timer, "compile");
8490 result = gcc_jit_context_compile (ctxt);
8491 gcc_jit_timer_pop (timer, "compile");
8492
8493 /* Run the generated code, timing it as client item "running code". */
8494 gcc_jit_timer_push (timer, "running code");
8495 run_the_code (ctxt, result);
8496 gcc_jit_timer_pop (timer, "running code");
8497
8498 /* Clean up. */
8499 gcc_jit_context_release (ctxt);
8500 gcc_jit_result_release (result);
8501@}
8502
8503/* Print the accumulated timings. */
8504gcc_jit_timer_print (timer, stderr);
8505gcc_jit_timer_release (timer);
8506@end example
8507
8508@noindent
8509
8510giving output like this, showing the internal GCC items at the top, then
8511client items, then the total:
8512
8513@example
8514Execution times (seconds)
8515GCC items:
8516 phase setup : 0.29 (14%) usr 0.00 ( 0%) sys 0.32 ( 5%) wall 10661 kB (50%) ggc
8517 phase parsing : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 653 kB ( 3%) ggc
8518 phase finalize : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
8519 dump files : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 0 kB ( 0%) ggc
8520 callgraph construction : 0.02 ( 1%) usr 0.01 ( 6%) sys 0.01 ( 0%) wall 242 kB ( 1%) ggc
8521 callgraph optimization : 0.03 ( 2%) usr 0.00 ( 0%) sys 0.02 ( 0%) wall 142 kB ( 1%) ggc
8522 trivially dead code : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
8523 df scan insns : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 9 kB ( 0%) ggc
8524 df live regs : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 0 kB ( 0%) ggc
8525 inline parameters : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 82 kB ( 0%) ggc
8526 tree CFG cleanup : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
8527 tree PHI insertion : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.02 ( 0%) wall 64 kB ( 0%) ggc
8528 tree SSA other : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 18 kB ( 0%) ggc
8529 expand : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 398 kB ( 2%) ggc
8530 jump : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
8531 loop init : 0.01 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 67 kB ( 0%) ggc
8532 integrated RA : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 2468 kB (12%) ggc
8533 thread pro- & epilogue : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 162 kB ( 1%) ggc
8534 final : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 216 kB ( 1%) ggc
8535 rest of compilation : 1.37 (69%) usr 0.00 ( 0%) sys 1.13 (18%) wall 1391 kB ( 6%) ggc
8536 assemble JIT code : 0.01 ( 1%) usr 0.00 ( 0%) sys 4.04 (66%) wall 0 kB ( 0%) ggc
8537 load JIT result : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
8538 JIT client code : 0.00 ( 0%) usr 0.01 ( 6%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
8539Client items:
8540 create_code : 0.00 ( 0%) usr 0.01 ( 6%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
8541 compile : 0.36 (18%) usr 0.15 (83%) sys 0.86 (14%) wall 14939 kB (70%) ggc
8542 running code : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc
8543 TOTAL : 2.00 0.18 6.12 21444 kB
8544@end example
8545
8546@noindent
8547
8548The exact format is intended to be human-readable, and is subject to change.
8549
8550@geindex LIBGCCJIT_HAVE_TIMING_API (C macro)
8551@anchor{topics/performance LIBGCCJIT_HAVE_TIMING_API}@anchor{fb}
8552@deffn {C Macro} LIBGCCJIT_HAVE_TIMING_API
8553
8554The timer API was added to libgccjit in GCC 6.
8555This macro is only defined in versions of libgccjit.h which have the
8556timer API, and so can be used to guard code that may need to compile
8557against earlier releases:
8558
8559@example
8560#ifdef LIBGCCJIT_HAVE_TIMING_API
8561gcc_jit_timer *t = gcc_jit_timer_new ();
8562gcc_jit_context_set_timer (ctxt, t);
8563#endif
8564@end example
8565
8566@noindent
8567@end deffn
8568
8569@geindex gcc_jit_timer (C type)
8570@anchor{topics/performance gcc_jit_timer}@anchor{fa}
8571@deffn {C Type} gcc_jit_timer
8572@end deffn
8573
8574@geindex gcc_jit_timer_new (C function)
8575@anchor{topics/performance gcc_jit_timer_new}@anchor{f2}
8576@deffn {C Function} gcc_jit_timer * gcc_jit_timer_new (void)
8577
8578Create a @pxref{fa,,gcc_jit_timer} instance, and start timing:
8579
8580@example
8581gcc_jit_timer *t = gcc_jit_timer_new ();
8582@end example
8583
8584@noindent
8585
8586This API entrypoint was added in @pxref{ef,,LIBGCCJIT_ABI_4}; you can test
8587for its presence using
8588
8589@example
8590#ifdef LIBGCCJIT_HAVE_TIMING_API
8591@end example
8592
8593@noindent
8594@end deffn
8595
8596@geindex gcc_jit_timer_release (C function)
8597@anchor{topics/performance gcc_jit_timer_release}@anchor{f3}
8598@deffn {C Function} void gcc_jit_timer_release (gcc_jit_timer@w{ }*timer)
8599
8600Release a @pxref{fa,,gcc_jit_timer} instance:
8601
8602@example
8603gcc_jit_timer_release (t);
8604@end example
8605
8606@noindent
8607
8608This should be called exactly once on a timer.
8609
8610This API entrypoint was added in @pxref{ef,,LIBGCCJIT_ABI_4}; you can test
8611for its presence using
8612
8613@example
8614#ifdef LIBGCCJIT_HAVE_TIMING_API
8615@end example
8616
8617@noindent
8618@end deffn
8619
8620@geindex gcc_jit_context_set_timer (C function)
8621@anchor{topics/performance gcc_jit_context_set_timer}@anchor{f1}
8622@deffn {C Function} void gcc_jit_context_set_timer (gcc_jit_context@w{ }*ctxt, gcc_jit_timer@w{ }*timer)
8623
8624Associate a @pxref{fa,,gcc_jit_timer} instance with a context:
8625
8626@example
8627gcc_jit_context_set_timer (ctxt, t);
8628@end example
8629
8630@noindent
8631
8632A timer instance can be shared between multiple
8633@pxref{8,,gcc_jit_context} instances.
8634
8635Timers have no locking, so if you have a multithreaded program, you
8636must provide your own locks if more than one thread could be working
8637with the same timer via timer-associated contexts.
8638
8639This API entrypoint was added in @pxref{ef,,LIBGCCJIT_ABI_4}; you can test
8640for its presence using
8641
8642@example
8643#ifdef LIBGCCJIT_HAVE_TIMING_API
8644@end example
8645
8646@noindent
8647@end deffn
8648
8649@geindex gcc_jit_context_get_timer (C function)
8650@anchor{topics/performance gcc_jit_context_get_timer}@anchor{f0}
8651@deffn {C Function} gcc_jit_timer *gcc_jit_context_get_timer (gcc_jit_context@w{ }*ctxt)
8652
8653Get the timer associated with a context (if any).
8654
8655This API entrypoint was added in @pxref{ef,,LIBGCCJIT_ABI_4}; you can test
8656for its presence using
8657
8658@example
8659#ifdef LIBGCCJIT_HAVE_TIMING_API
8660@end example
8661
8662@noindent
8663@end deffn
8664
8665@geindex gcc_jit_timer_push (C function)
8666@anchor{topics/performance gcc_jit_timer_push}@anchor{f4}
8667@deffn {C Function} void gcc_jit_timer_push (gcc_jit_timer@w{ }*timer, const char@w{ }*item_name)
8668
8669Push the given item onto the timer's stack:
8670
8671@example
8672gcc_jit_timer_push (t, "running code");
8673run_the_code (ctxt, result);
8674gcc_jit_timer_pop (t, "running code");
8675@end example
8676
8677@noindent
8678
8679This API entrypoint was added in @pxref{ef,,LIBGCCJIT_ABI_4}; you can test
8680for its presence using
8681
8682@example
8683#ifdef LIBGCCJIT_HAVE_TIMING_API
8684@end example
8685
8686@noindent
8687@end deffn
8688
8689@geindex gcc_jit_timer_pop (C function)
8690@anchor{topics/performance gcc_jit_timer_pop}@anchor{f5}
8691@deffn {C Function} void gcc_jit_timer_pop (gcc_jit_timer@w{ }*timer, const char@w{ }*item_name)
8692
8693Pop the top item from the timer's stack.
8694
8695If "item_name" is provided, it must match that of the top item.
8696Alternatively, @code{NULL} can be passed in, to suppress checking.
8697
8698This API entrypoint was added in @pxref{ef,,LIBGCCJIT_ABI_4}; you can test
8699for its presence using
8700
8701@example
8702#ifdef LIBGCCJIT_HAVE_TIMING_API
8703@end example
8704
8705@noindent
8706@end deffn
8707
8708@geindex gcc_jit_timer_print (C function)
8709@anchor{topics/performance gcc_jit_timer_print}@anchor{f6}
8710@deffn {C Function} void gcc_jit_timer_print (gcc_jit_timer@w{ }*timer, FILE@w{ }*f_out)
8711
8712Print timing information to the given stream about activity since
8713the timer was started.
8714
8715This API entrypoint was added in @pxref{ef,,LIBGCCJIT_ABI_4}; you can test
8716for its presence using
8717
8718@example
8719#ifdef LIBGCCJIT_HAVE_TIMING_API
8720@end example
8721
8722@noindent
8723@end deffn
8724
f1717362 8725@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
863e76f9 8726@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
8727@c
8728@c This is free software: you can redistribute it and/or modify it
8729@c under the terms of the GNU General Public License as published by
8730@c the Free Software Foundation, either version 3 of the License, or
8731@c (at your option) any later version.
8732@c
8733@c This program is distributed in the hope that it will be useful, but
8734@c WITHOUT ANY WARRANTY; without even the implied warranty of
8735@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8736@c General Public License for more details.
8737@c
8738@c You should have received a copy of the GNU General Public License
8739@c along with this program. If not, see
8740@c <http://www.gnu.org/licenses/>.
8741
36b809a0 8742@node C++ bindings for libgccjit,Internals,Topic Reference,Top
17c0b84b 8743@anchor{cp/index c-bindings-for-libgccjit}@anchor{fc}@anchor{cp/index doc}@anchor{fd}
36b809a0 8744@chapter C++ bindings for libgccjit
863e76f9 8745
8746
36b809a0 8747This document describes the C++ bindings to
8748libgccjit@footnote{http://gcc.gnu.org/wiki/JIT}, an API for embedding GCC
8749inside programs and libraries.
863e76f9 8750
36b809a0 8751The C++ bindings consist of a single header file @code{libgccjit++.h}.
863e76f9 8752
36b809a0 8753This is a collection of "thin" wrapper classes around the C API.
8754Everything is an inline function, implemented in terms of the C API,
8755so there is nothing extra to link against.
863e76f9 8756
36b809a0 8757Note that libgccjit is currently of "Alpha" quality;
8758the APIs are not yet set in stone, and they shouldn't be used in
8759production yet.
863e76f9 8760
36b809a0 8761Contents:
863e76f9 8762
f1717362 8763@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
36b809a0 8764@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
8765@c
8766@c This is free software: you can redistribute it and/or modify it
8767@c under the terms of the GNU General Public License as published by
8768@c the Free Software Foundation, either version 3 of the License, or
8769@c (at your option) any later version.
8770@c
8771@c This program is distributed in the hope that it will be useful, but
8772@c WITHOUT ANY WARRANTY; without even the implied warranty of
8773@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8774@c General Public License for more details.
8775@c
8776@c You should have received a copy of the GNU General Public License
8777@c along with this program. If not, see
8778@c <http://www.gnu.org/licenses/>.
863e76f9 8779
36b809a0 8780@menu
8781* Tutorial: Tutorial<2>.
8782* Topic Reference: Topic Reference<2>.
863e76f9 8783
36b809a0 8784Tutorial
863e76f9 8785
36b809a0 8786* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world"<2>.
8787* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>.
8788* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>.
8789* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>.
863e76f9 8790
36b809a0 8791Tutorial part 2: Creating a trivial machine code function
863e76f9 8792
36b809a0 8793* Options: Options<3>.
8794* Full example: Full example<3>.
863e76f9 8795
36b809a0 8796Tutorial part 3: Loops and variables
863e76f9 8797
36b809a0 8798* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>.
8799* Control flow: Control flow<2>.
8800* Visualizing the control flow graph: Visualizing the control flow graph<2>.
8801* Full example: Full example<4>.
863e76f9 8802
36b809a0 8803Tutorial part 4: Adding JIT-compilation to a toy interpreter
863e76f9 8804
36b809a0 8805* Our toy interpreter: Our toy interpreter<2>.
8806* Compiling to machine code: Compiling to machine code<2>.
8807* Setting things up: Setting things up<2>.
8808* Populating the function: Populating the function<2>.
8809* Verifying the control flow graph: Verifying the control flow graph<2>.
8810* Compiling the context: Compiling the context<2>.
8811* Single-stepping through the generated code: Single-stepping through the generated code<2>.
8812* Examining the generated code: Examining the generated code<2>.
8813* Putting it all together: Putting it all together<2>.
8814* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>.
863e76f9 8815
36b809a0 8816Behind the curtain: How does our code get optimized?
863e76f9 8817
36b809a0 8818* Optimizing away stack manipulation: Optimizing away stack manipulation<2>.
8819* Elimination of tail recursion: Elimination of tail recursion<2>.
863e76f9 8820
36b809a0 8821Topic Reference
863e76f9 8822
36b809a0 8823* Compilation contexts: Compilation contexts<2>.
8824* Objects: Objects<2>.
8825* Types: Types<2>.
8826* Expressions: Expressions<2>.
8827* Creating and using functions: Creating and using functions<2>.
8828* Source Locations: Source Locations<2>.
69834ed9 8829* Compiling a context: Compiling a context<2>.
863e76f9 8830
36b809a0 8831Compilation contexts
863e76f9 8832
36b809a0 8833* Lifetime-management: Lifetime-management<2>.
8834* Thread-safety: Thread-safety<2>.
8835* Error-handling: Error-handling<3>.
8836* Debugging: Debugging<2>.
8837* Options: Options<4>.
863e76f9 8838
36b809a0 8839Options
863e76f9 8840
e5a6940a 8841* String Options: String Options<2>.
36b809a0 8842* Boolean options: Boolean options<2>.
8843* Integer options: Integer options<2>.
adb2df55 8844* Additional command-line options: Additional command-line options<2>.
863e76f9 8845
36b809a0 8846Types
863e76f9 8847
36b809a0 8848* Standard types: Standard types<2>.
8849* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>.
8850* Structures and unions: Structures and unions<2>.
863e76f9 8851
36b809a0 8852Expressions
863e76f9 8853
36b809a0 8854* Rvalues: Rvalues<2>.
8855* Lvalues: Lvalues<2>.
8856* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>.
863e76f9 8857
36b809a0 8858Rvalues
863e76f9 8859
36b809a0 8860* Simple expressions: Simple expressions<2>.
8861* Unary Operations: Unary Operations<2>.
8862* Binary Operations: Binary Operations<2>.
8863* Comparisons: Comparisons<2>.
8864* Function calls: Function calls<2>.
8865* Type-coercion: Type-coercion<2>.
863e76f9 8866
36b809a0 8867Lvalues
863e76f9 8868
36b809a0 8869* Global variables: Global variables<2>.
863e76f9 8870
36b809a0 8871Creating and using functions
863e76f9 8872
36b809a0 8873* Params: Params<2>.
8874* Functions: Functions<2>.
8875* Blocks: Blocks<2>.
8876* Statements: Statements<2>.
863e76f9 8877
36b809a0 8878Source Locations
863e76f9 8879
36b809a0 8880* Faking it: Faking it<2>.
863e76f9 8881
69834ed9 8882Compiling a context
8883
8884* In-memory compilation: In-memory compilation<2>.
8885* Ahead-of-time compilation: Ahead-of-time compilation<2>.
8886
36b809a0 8887@end menu
863e76f9 8888
863e76f9 8889
36b809a0 8890@node Tutorial<2>,Topic Reference<2>,,C++ bindings for libgccjit
17c0b84b 8891@anchor{cp/intro/index doc}@anchor{fe}@anchor{cp/intro/index tutorial}@anchor{ff}
36b809a0 8892@section Tutorial
863e76f9 8893
863e76f9 8894
f1717362 8895@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
36b809a0 8896@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
8897@c
8898@c This is free software: you can redistribute it and/or modify it
8899@c under the terms of the GNU General Public License as published by
8900@c the Free Software Foundation, either version 3 of the License, or
8901@c (at your option) any later version.
8902@c
8903@c This program is distributed in the hope that it will be useful, but
8904@c WITHOUT ANY WARRANTY; without even the implied warranty of
8905@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8906@c General Public License for more details.
8907@c
8908@c You should have received a copy of the GNU General Public License
8909@c along with this program. If not, see
8910@c <http://www.gnu.org/licenses/>.
863e76f9 8911
57687d8b 8912@menu
36b809a0 8913* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world"<2>.
8914* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>.
8915* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>.
8916* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>.
57687d8b 8917
8918@end menu
8919
36b809a0 8920@node Tutorial part 1 "Hello world"<2>,Tutorial part 2 Creating a trivial machine code function<2>,,Tutorial<2>
17c0b84b 8921@anchor{cp/intro/tutorial01 doc}@anchor{100}@anchor{cp/intro/tutorial01 tutorial-part-1-hello-world}@anchor{101}
36b809a0 8922@subsection Tutorial part 1: "Hello world"
57687d8b 8923
8924
36b809a0 8925Before we look at the details of the API, let's look at building and
8926running programs that use the library.
57687d8b 8927
36b809a0 8928Here's a toy "hello world" program that uses the library's C++ API to
8929synthesize a call to @cite{printf} and uses it to write a message to stdout.
57687d8b 8930
36b809a0 8931Don't worry about the content of the program for now; we'll cover
8932the details in later parts of this tutorial.
8933
8934@quotation
57687d8b 8935
8936@example
36b809a0 8937/* Smoketest example for libgccjit.so C++ API
f1717362 8938 Copyright (C) 2014-2016 Free Software Foundation, Inc.
57687d8b 8939
36b809a0 8940This file is part of GCC.
57687d8b 8941
36b809a0 8942GCC is free software; you can redistribute it and/or modify it
8943under the terms of the GNU General Public License as published by
8944the Free Software Foundation; either version 3, or (at your option)
8945any later version.
57687d8b 8946
36b809a0 8947GCC is distributed in the hope that it will be useful, but
8948WITHOUT ANY WARRANTY; without even the implied warranty of
8949MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8950General Public License for more details.
57687d8b 8951
36b809a0 8952You should have received a copy of the GNU General Public License
8953along with GCC; see the file COPYING3. If not see
8954<http://www.gnu.org/licenses/>. */
57687d8b 8955
36b809a0 8956#include <libgccjit++.h>
8957
8958#include <stdlib.h>
8959#include <stdio.h>
8960
8961static void
8962create_code (gccjit::context ctxt)
8963@{
8964 /* Let's try to inject the equivalent of this C code:
8965 void
8966 greet (const char *name)
8967 @{
8968 printf ("hello %s\n", name);
8969 @}
8970 */
8971 gccjit::type void_type = ctxt.get_type (GCC_JIT_TYPE_VOID);
8972 gccjit::type const_char_ptr_type =
8973 ctxt.get_type (GCC_JIT_TYPE_CONST_CHAR_PTR);
8974 gccjit::param param_name =
8975 ctxt.new_param (const_char_ptr_type, "name");
8976 std::vector<gccjit::param> func_params;
8977 func_params.push_back (param_name);
8978 gccjit::function func =
8979 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
8980 void_type,
8981 "greet",
8982 func_params, 0);
8983
8984 gccjit::param param_format =
8985 ctxt.new_param (const_char_ptr_type, "format");
8986 std::vector<gccjit::param> printf_params;
8987 printf_params.push_back (param_format);
8988 gccjit::function printf_func =
8989 ctxt.new_function (GCC_JIT_FUNCTION_IMPORTED,
8990 ctxt.get_type (GCC_JIT_TYPE_INT),
8991 "printf",
8992 printf_params, 1);
8993
8994 gccjit::block block = func.new_block ();
8995 block.add_eval (ctxt.new_call (printf_func,
8996 ctxt.new_rvalue ("hello %s\n"),
8997 param_name));
8998 block.end_with_return ();
8999@}
9000
9001int
9002main (int argc, char **argv)
9003@{
9004 gccjit::context ctxt;
9005 gcc_jit_result *result;
9006
9007 /* Get a "context" object for working with the library. */
9008 ctxt = gccjit::context::acquire ();
9009
9010 /* Set some options on the context.
9011 Turn this on to see the code being generated, in assembler form. */
9012 ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 0);
9013
9014 /* Populate the context. */
9015 create_code (ctxt);
9016
9017 /* Compile the code. */
9018 result = ctxt.compile ();
9019 if (!result)
9020 @{
9021 fprintf (stderr, "NULL result");
9022 exit (1);
9023 @}
9024
9025 ctxt.release ();
9026
9027 /* Extract the generated code from "result". */
9028 typedef void (*fn_type) (const char *);
9029 fn_type greet =
9030 (fn_type)gcc_jit_result_get_code (result, "greet");
9031 if (!greet)
9032 @{
9033 fprintf (stderr, "NULL greet");
9034 exit (1);
9035 @}
9036
9037 /* Now call the generated function: */
9038 greet ("world");
9039 fflush (stdout);
9040
9041 gcc_jit_result_release (result);
9042 return 0;
9043@}
9044
9045@end example
9046
9047@noindent
9048@end quotation
9049
9050Copy the above to @cite{tut01-hello-world.cc}.
9051
9052Assuming you have the jit library installed, build the test program
9053using:
9054
9055@example
9056$ gcc \
9057 tut01-hello-world.cc \
9058 -o tut01-hello-world \
9059 -lgccjit
9060@end example
9061
9062@noindent
9063
9064You should then be able to run the built program:
9065
9066@example
9067$ ./tut01-hello-world
9068hello world
9069@end example
9070
9071@noindent
9072
f1717362 9073@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
36b809a0 9074@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
9075@c
9076@c This is free software: you can redistribute it and/or modify it
9077@c under the terms of the GNU General Public License as published by
9078@c the Free Software Foundation, either version 3 of the License, or
9079@c (at your option) any later version.
9080@c
9081@c This program is distributed in the hope that it will be useful, but
9082@c WITHOUT ANY WARRANTY; without even the implied warranty of
9083@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9084@c General Public License for more details.
9085@c
9086@c You should have received a copy of the GNU General Public License
9087@c along with this program. If not, see
9088@c <http://www.gnu.org/licenses/>.
9089
9090@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>
17c0b84b 9091@anchor{cp/intro/tutorial02 doc}@anchor{102}@anchor{cp/intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{103}
36b809a0 9092@subsection Tutorial part 2: Creating a trivial machine code function
9093
9094
9095Consider this C function:
9096
9097@example
9098int square (int i)
9099@{
9100 return i * i;
9101@}
9102@end example
9103
9104@noindent
9105
9106How can we construct this at run-time using libgccjit's C++ API?
9107
9108First we need to include the relevant header:
9109
9110@example
9111#include <libgccjit++.h>
9112@end example
9113
9114@noindent
9115
9116All state associated with compilation is associated with a
9117@code{gccjit::context}, which is a thin C++ wrapper around the C API's
9118@pxref{8,,gcc_jit_context *}.
9119
17c0b84b 9120Create one using @pxref{104,,gccjit;;context;;acquire()}:
36b809a0 9121
9122@example
9123gccjit::context ctxt;
9124ctxt = gccjit::context::acquire ();
9125@end example
9126
9127@noindent
9128
9129The JIT library has a system of types. It is statically-typed: every
9130expression is of a specific type, fixed at compile-time. In our example,
9131all of the expressions are of the C @cite{int} type, so let's obtain this from
9132the context, as a @code{gccjit::type}, using
17c0b84b 9133@pxref{105,,gccjit;;context;;get_type()}:
36b809a0 9134
9135@example
9136gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT);
9137@end example
9138
9139@noindent
9140
9141@code{gccjit::type} is an example of a "contextual" object: every
9142entity in the API is associated with a @code{gccjit::context}.
9143
9144Memory management is easy: all such "contextual" objects are automatically
9145cleaned up for you when the context is released, using
17c0b84b 9146@pxref{106,,gccjit;;context;;release()}:
36b809a0 9147
9148@example
9149ctxt.release ();
9150@end example
9151
9152@noindent
9153
9154so you don't need to manually track and cleanup all objects, just the
9155contexts.
9156
9157All of the C++ classes in the API are thin wrappers around pointers to
9158types in the C API.
9159
9160The C++ class hierarchy within the @code{gccjit} namespace looks like this:
9161
9162@example
9163+- object
9164 +- location
9165 +- type
9166 +- struct
9167 +- field
9168 +- function
9169 +- block
9170 +- rvalue
9171 +- lvalue
9172 +- param
9173@end example
9174
9175@noindent
9176
9177One thing you can do with a @code{gccjit::object} is
9178to ask it for a human-readable description as a @code{std::string}, using
17c0b84b 9179@pxref{107,,gccjit;;object;;get_debug_string()}:
36b809a0 9180
9181@example
9182printf ("obj: %s\n", obj.get_debug_string ().c_str ());
9183@end example
9184
9185@noindent
9186
9187giving this text on stdout:
9188
9189@example
9190obj: int
9191@end example
9192
9193@noindent
9194
9195This is invaluable when debugging.
9196
9197Let's create the function. To do so, we first need to construct
9198its single parameter, specifying its type and giving it a name,
17c0b84b 9199using @pxref{108,,gccjit;;context;;new_param()}:
36b809a0 9200
9201@example
9202gccjit::param param_i = ctxt.new_param (int_type, "i");
9203@end example
9204
9205@noindent
9206
9207and we can then make a vector of all of the params of the function,
9208in this case just one:
9209
9210@example
9211std::vector<gccjit::param> params;
9212params.push_back (param_i);
9213@end example
9214
9215@noindent
9216
9217Now we can create the function, using
9218@code{gccjit::context::new_function()}:
9219
9220@example
9221gccjit::function func =
9222 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
9223 int_type,
9224 "square",
9225 params,
9226 0);
9227@end example
9228
9229@noindent
9230
9231To define the code within the function, we must create basic blocks
9232containing statements.
9233
9234Every basic block contains a list of statements, eventually terminated
9235by a statement that either returns, or jumps to another basic block.
9236
9237Our function has no control-flow, so we just need one basic block:
9238
9239@example
9240gccjit::block block = func.new_block ();
9241@end example
9242
9243@noindent
9244
9245Our basic block is relatively simple: it immediately terminates by
9246returning the value of an expression.
9247
17c0b84b 9248We can build the expression using @pxref{109,,gccjit;;context;;new_binary_op()}:
36b809a0 9249
9250@example
9251gccjit::rvalue expr =
9252 ctxt.new_binary_op (
9253 GCC_JIT_BINARY_OP_MULT, int_type,
9254 param_i, param_i);
9255@end example
9256
9257@noindent
9258
9259A @code{gccjit::rvalue} is another example of a
9260@code{gccjit::object} subclass. As before, we can print it with
17c0b84b 9261@pxref{107,,gccjit;;object;;get_debug_string()}.
36b809a0 9262
9263@example
9264printf ("expr: %s\n", expr.get_debug_string ().c_str ());
9265@end example
9266
9267@noindent
9268
9269giving this output:
9270
9271@example
9272expr: i * i
9273@end example
9274
9275@noindent
9276
9277Note that @code{gccjit::rvalue} provides numerous overloaded operators
9278which can be used to dramatically reduce the amount of typing needed.
9279We can build the above binary operation more directly with this one-liner:
9280
9281@example
9282gccjit::rvalue expr = param_i * param_i;
9283@end example
9284
9285@noindent
9286
9287Creating the expression in itself doesn't do anything; we have to add
9288this expression to a statement within the block. In this case, we use it
9289to build a return statement, which terminates the basic block:
9290
9291@example
9292block.end_with_return (expr);
9293@end example
9294
9295@noindent
9296
9297OK, we've populated the context. We can now compile it using
17c0b84b 9298@pxref{10a,,gccjit;;context;;compile()}:
36b809a0 9299
9300@example
9301gcc_jit_result *result;
9302result = ctxt.compile ();
9303@end example
9304
9305@noindent
9306
9307and get a @pxref{16,,gcc_jit_result *}.
9308
9309We can now use @pxref{17,,gcc_jit_result_get_code()} to look up a specific
9310machine code routine within the result, in this case, the function we
9311created above.
9312
9313@example
9314void *fn_ptr = gcc_jit_result_get_code (result, "square");
9315if (!fn_ptr)
9316 @{
9317 fprintf (stderr, "NULL fn_ptr");
9318 goto error;
9319 @}
9320@end example
9321
9322@noindent
9323
9324We can now cast the pointer to an appropriate function pointer type, and
9325then call it:
9326
9327@example
9328typedef int (*fn_type) (int);
9329fn_type square = (fn_type)fn_ptr;
9330printf ("result: %d", square (5));
9331@end example
9332
9333@noindent
9334
9335@example
9336result: 25
9337@end example
9338
9339@noindent
9340
9341@menu
9342* Options: Options<3>.
9343* Full example: Full example<3>.
9344
9345@end menu
9346
9347@node Options<3>,Full example<3>,,Tutorial part 2 Creating a trivial machine code function<2>
17c0b84b 9348@anchor{cp/intro/tutorial02 options}@anchor{10b}
36b809a0 9349@subsubsection Options
9350
9351
9352To get more information on what's going on, you can set debugging flags
17c0b84b 9353on the context using @pxref{10c,,gccjit;;context;;set_bool_option()}.
36b809a0 9354
9355@c (I'm deliberately not mentioning
9356@c :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think
9357@c it's probably more of use to implementors than to users)
9358
9359Setting @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE} will dump a
9360C-like representation to stderr when you compile (GCC's "GIMPLE"
9361representation):
9362
9363@example
9364ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1);
9365result = ctxt.compile ();
9366@end example
9367
9368@noindent
9369
9370@example
9371square (signed int i)
9372@{
9373 signed int D.260;
9374
9375 entry:
9376 D.260 = i * i;
9377 return D.260;
9378@}
9379@end example
9380
9381@noindent
9382
9383We can see the generated machine code in assembler form (on stderr) by
9384setting @pxref{1d,,GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE} on the context
9385before compiling:
9386
9387@example
9388ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1);
9389result = ctxt.compile ();
9390@end example
9391
9392@noindent
9393
9394@example
9395 .file "fake.c"
9396 .text
9397 .globl square
9398 .type square, @@function
9399square:
9400.LFB6:
9401 .cfi_startproc
9402 pushq %rbp
9403 .cfi_def_cfa_offset 16
9404 .cfi_offset 6, -16
9405 movq %rsp, %rbp
9406 .cfi_def_cfa_register 6
9407 movl %edi, -4(%rbp)
9408.L14:
9409 movl -4(%rbp), %eax
9410 imull -4(%rbp), %eax
9411 popq %rbp
9412 .cfi_def_cfa 7, 8
9413 ret
9414 .cfi_endproc
9415.LFE6:
9416 .size square, .-square
9417 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)"
9418 .section .note.GNU-stack,"",@@progbits
9419@end example
9420
9421@noindent
9422
9423By default, no optimizations are performed, the equivalent of GCC's
9424@cite{-O0} option. We can turn things up to e.g. @cite{-O3} by calling
17c0b84b 9425@pxref{10d,,gccjit;;context;;set_int_option()} with
36b809a0 9426@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}:
9427
9428@example
9429ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3);
9430@end example
9431
9432@noindent
9433
9434@example
9435 .file "fake.c"
9436 .text
9437 .p2align 4,,15
9438 .globl square
9439 .type square, @@function
9440square:
9441.LFB7:
9442 .cfi_startproc
9443.L16:
9444 movl %edi, %eax
9445 imull %edi, %eax
9446 ret
9447 .cfi_endproc
9448.LFE7:
9449 .size square, .-square
9450 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)"
9451 .section .note.GNU-stack,"",@@progbits
9452@end example
9453
9454@noindent
9455
9456Naturally this has only a small effect on such a trivial function.
9457
9458@node Full example<3>,,Options<3>,Tutorial part 2 Creating a trivial machine code function<2>
17c0b84b 9459@anchor{cp/intro/tutorial02 full-example}@anchor{10e}
36b809a0 9460@subsubsection Full example
9461
9462
9463Here's what the above looks like as a complete program:
9464
9465@quotation
9466
9467@example
9468/* Usage example for libgccjit.so's C++ API
f1717362 9469 Copyright (C) 2014-2016 Free Software Foundation, Inc.
36b809a0 9470
9471This file is part of GCC.
9472
9473GCC is free software; you can redistribute it and/or modify it
9474under the terms of the GNU General Public License as published by
9475the Free Software Foundation; either version 3, or (at your option)
9476any later version.
9477
9478GCC is distributed in the hope that it will be useful, but
9479WITHOUT ANY WARRANTY; without even the implied warranty of
9480MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9481General Public License for more details.
9482
9483You should have received a copy of the GNU General Public License
9484along with GCC; see the file COPYING3. If not see
9485<http://www.gnu.org/licenses/>. */
9486
9487#include <libgccjit++.h>
9488
9489#include <stdlib.h>
9490#include <stdio.h>
9491
9492void
9493create_code (gccjit::context ctxt)
9494@{
9495 /* Let's try to inject the equivalent of this C code:
9496
9497 int square (int i)
9498 @{
9499 return i * i;
9500 @}
9501 */
9502 gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT);
9503 gccjit::param param_i = ctxt.new_param (int_type, "i");
9504 std::vector<gccjit::param> params;
9505 params.push_back (param_i);
9506 gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
9507 int_type,
9508 "square",
9509 params, 0);
9510
9511 gccjit::block block = func.new_block ();
9512
9513 gccjit::rvalue expr =
9514 ctxt.new_binary_op (GCC_JIT_BINARY_OP_MULT, int_type,
9515 param_i, param_i);
9516
9517 block.end_with_return (expr);
9518@}
9519
9520int
9521main (int argc, char **argv)
9522@{
9523 /* Get a "context" object for working with the library. */
9524 gccjit::context ctxt = gccjit::context::acquire ();
9525
9526 /* Set some options on the context.
9527 Turn this on to see the code being generated, in assembler form. */
9528 ctxt.set_bool_option (
9529 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
9530 0);
9531
9532 /* Populate the context. */
9533 create_code (ctxt);
9534
9535 /* Compile the code. */
9536 gcc_jit_result *result = ctxt.compile ();
9537
9538 /* We're done with the context; we can release it: */
9539 ctxt.release ();
9540
9541 if (!result)
9542 @{
9543 fprintf (stderr, "NULL result");
9544 return 1;
9545 @}
9546
9547 /* Extract the generated code from "result". */
9548 void *fn_ptr = gcc_jit_result_get_code (result, "square");
9549 if (!fn_ptr)
9550 @{
9551 fprintf (stderr, "NULL fn_ptr");
9552 gcc_jit_result_release (result);
9553 return 1;
9554 @}
9555
9556 typedef int (*fn_type) (int);
9557 fn_type square = (fn_type)fn_ptr;
9558 printf ("result: %d\n", square (5));
9559
9560 gcc_jit_result_release (result);
9561 return 0;
9562@}
9563
9564@end example
9565
9566@noindent
9567@end quotation
9568
9569Building and running it:
9570
9571@example
9572$ gcc \
9573 tut02-square.cc \
9574 -o tut02-square \
9575 -lgccjit
9576
9577# Run the built program:
9578$ ./tut02-square
9579result: 25
9580@end example
9581
9582@noindent
9583
f1717362 9584@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
36b809a0 9585@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
9586@c
9587@c This is free software: you can redistribute it and/or modify it
9588@c under the terms of the GNU General Public License as published by
9589@c the Free Software Foundation, either version 3 of the License, or
9590@c (at your option) any later version.
9591@c
9592@c This program is distributed in the hope that it will be useful, but
9593@c WITHOUT ANY WARRANTY; without even the implied warranty of
9594@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9595@c General Public License for more details.
9596@c
9597@c You should have received a copy of the GNU General Public License
9598@c along with this program. If not, see
9599@c <http://www.gnu.org/licenses/>.
9600
9601@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>
17c0b84b 9602@anchor{cp/intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{10f}@anchor{cp/intro/tutorial03 doc}@anchor{110}
36b809a0 9603@subsection Tutorial part 3: Loops and variables
9604
9605
9606Consider this C function:
9607
9608@quotation
9609
9610@example
9611int loop_test (int n)
9612@{
9613 int sum = 0;
9614 for (int i = 0; i < n; i++)
9615 sum += i * i;
9616 return sum;
9617@}
9618@end example
9619
9620@noindent
9621@end quotation
9622
9623This example demonstrates some more features of libgccjit, with local
9624variables and a loop.
9625
9626To break this down into libgccjit terms, it's usually easier to reword
9627the @cite{for} loop as a @cite{while} loop, giving:
9628
9629@quotation
9630
9631@example
9632int loop_test (int n)
9633@{
9634 int sum = 0;
9635 int i = 0;
9636 while (i < n)
9637 @{
9638 sum += i * i;
9639 i++;
9640 @}
9641 return sum;
9642@}
9643@end example
9644
9645@noindent
9646@end quotation
9647
9648Here's what the final control flow graph will look like:
9649
9650@quotation
9651
9652
9653@float Figure
9654
1eddded5 9655@image{sum-of-squares,,,image of a control flow graph,png}
36b809a0 9656
9657@end float
9658
9659@end quotation
9660
9661As before, we include the libgccjit++ header and make a
9662@code{gccjit::context}.
9663
9664@example
9665#include <libgccjit++.h>
9666
9667void test (void)
9668@{
9669 gccjit::context ctxt;
9670 ctxt = gccjit::context::acquire ();
9671@end example
9672
9673@noindent
9674
9675The function works with the C @cite{int} type.
9676
9677In the previous tutorial we acquired this via
9678
9679@example
9680gccjit::type the_type = ctxt.get_type (ctxt, GCC_JIT_TYPE_INT);
9681@end example
9682
9683@noindent
9684
9685though we could equally well make it work on, say, @cite{double}:
9686
9687@example
9688gccjit::type the_type = ctxt.get_type (ctxt, GCC_JIT_TYPE_DOUBLE);
9689@end example
9690
9691@noindent
9692
9693For integer types we can use @code{gccjit::context::get_int_type}
9694to directly bind a specific type:
9695
9696@example
9697gccjit::type the_type = ctxt.get_int_type <int> ();
9698@end example
9699
9700@noindent
9701
9702Let's build the function:
9703
9704@example
9705gcc_jit_param n = ctxt.new_param (the_type, "n");
9706std::vector<gccjit::param> params;
9707params.push_back (n);
9708gccjit::function func =
9709 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
9710 return_type,
9711 "loop_test",
9712 params, 0);
9713@end example
9714
9715@noindent
9716
9717@menu
9718* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>.
9719* Control flow: Control flow<2>.
9720* Visualizing the control flow graph: Visualizing the control flow graph<2>.
9721* Full example: Full example<4>.
9722
9723@end menu
9724
9725@node Expressions lvalues and rvalues<2>,Control flow<2>,,Tutorial part 3 Loops and variables<2>
17c0b84b 9726@anchor{cp/intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{111}
36b809a0 9727@subsubsection Expressions: lvalues and rvalues
9728
9729
9730The base class of expression is the @code{gccjit::rvalue},
9731representing an expression that can be on the @emph{right}-hand side of
9732an assignment: a value that can be computed somehow, and assigned
9733@emph{to} a storage area (such as a variable). It has a specific
9734@code{gccjit::type}.
9735
9736Anothe important class is @code{gccjit::lvalue}.
9737A @code{gccjit::lvalue}. is something that can of the @emph{left}-hand
9738side of an assignment: a storage area (such as a variable).
9739
9740In other words, every assignment can be thought of as:
9741
9742@example
9743LVALUE = RVALUE;
9744@end example
9745
9746@noindent
9747
9748Note that @code{gccjit::lvalue} is a subclass of
9749@code{gccjit::rvalue}, where in an assignment of the form:
9750
9751@example
9752LVALUE_A = LVALUE_B;
9753@end example
9754
9755@noindent
9756
9757the @cite{LVALUE_B} implies reading the current value of that storage
9758area, assigning it into the @cite{LVALUE_A}.
9759
9760So far the only expressions we've seen are from the previous tutorial:
9761
9762
9763@enumerate
9764
9765@item
9766the multiplication @cite{i * i}:
9767@end enumerate
9768
9769@quotation
9770
9771@example
9772gccjit::rvalue expr =
9773 ctxt.new_binary_op (
9774 GCC_JIT_BINARY_OP_MULT, int_type,
9775 param_i, param_i);
9776
9777/* Alternatively, using operator-overloading: */
9778gccjit::rvalue expr = param_i * param_i;
9779@end example
9780
9781@noindent
9782
9783which is a @code{gccjit::rvalue}, and
9784@end quotation
9785
9786
9787@enumerate 2
9788
9789@item
9790the various function parameters: @cite{param_i} and @cite{param_n}, instances of
9791@code{gccjit::param}, which is a subclass of @code{gccjit::lvalue}
9792(and, in turn, of @code{gccjit::rvalue}):
9793we can both read from and write to function parameters within the
9794body of a function.
9795@end enumerate
9796
9797Our new example has a new kind of expression: we have two local
9798variables. We create them by calling
17c0b84b 9799@pxref{112,,gccjit;;function;;new_local()}, supplying a type and a name:
36b809a0 9800
9801@example
9802/* Build locals: */
9803gccjit::lvalue i = func.new_local (the_type, "i");
9804gccjit::lvalue sum = func.new_local (the_type, "sum");
9805@end example
9806
9807@noindent
9808
9809These are instances of @code{gccjit::lvalue} - they can be read from
9810and written to.
9811
9812Note that there is no precanned way to create @emph{and} initialize a variable
9813like in C:
9814
9815@example
9816int i = 0;
9817@end example
9818
9819@noindent
9820
9821Instead, having added the local to the function, we have to separately add
9822an assignment of @cite{0} to @cite{local_i} at the beginning of the function.
9823
9824@node Control flow<2>,Visualizing the control flow graph<2>,Expressions lvalues and rvalues<2>,Tutorial part 3 Loops and variables<2>
17c0b84b 9825@anchor{cp/intro/tutorial03 control-flow}@anchor{113}
36b809a0 9826@subsubsection Control flow
9827
9828
9829This function has a loop, so we need to build some basic blocks to
9830handle the control flow. In this case, we need 4 blocks:
9831
9832
9833@enumerate
9834
9835@item
9836before the loop (initializing the locals)
9837
9838@item
9839the conditional at the top of the loop (comparing @cite{i < n})
9840
9841@item
9842the body of the loop
9843
9844@item
9845after the loop terminates (@cite{return sum})
9846@end enumerate
9847
9848so we create these as @code{gccjit::block} instances within the
9849@code{gccjit::function}:
9850
9851@example
9852gccjit::block b_initial = func.new_block ("initial");
9853gccjit::block b_loop_cond = func.new_block ("loop_cond");
9854gccjit::block b_loop_body = func.new_block ("loop_body");
9855gccjit::block b_after_loop = func.new_block ("after_loop");
9856@end example
9857
9858@noindent
9859
9860We now populate each block with statements.
9861
9862The entry block @cite{b_initial} consists of initializations followed by a jump
9863to the conditional. We assign @cite{0} to @cite{i} and to @cite{sum}, using
17c0b84b 9864@pxref{114,,gccjit;;block;;add_assignment()} to add
9865an assignment statement, and using @pxref{115,,gccjit;;context;;zero()} to get
36b809a0 9866the constant value @cite{0} for the relevant type for the right-hand side of
9867the assignment:
9868
9869@example
9870/* sum = 0; */
9871b_initial.add_assignment (sum, ctxt.zero (the_type));
9872
9873/* i = 0; */
9874b_initial.add_assignment (i, ctxt.zero (the_type));
9875@end example
9876
9877@noindent
9878
9879We can then terminate the entry block by jumping to the conditional:
9880
9881@example
9882b_initial.end_with_jump (b_loop_cond);
9883@end example
9884
9885@noindent
9886
9887The conditional block is equivalent to the line @cite{while (i < n)} from our
9888C example. It contains a single statement: a conditional, which jumps to
9889one of two destination blocks depending on a boolean
9890@code{gccjit::rvalue}, in this case the comparison of @cite{i} and @cite{n}.
9891
17c0b84b 9892We could build the comparison using @pxref{116,,gccjit;;context;;new_comparison()}:
36b809a0 9893
9894@example
9895gccjit::rvalue guard =
9896 ctxt.new_comparison (GCC_JIT_COMPARISON_GE,
9897 i, n);
9898@end example
9899
9900@noindent
9901
9902and can then use this to add @cite{b_loop_cond}'s sole statement, via
17c0b84b 9903@pxref{117,,gccjit;;block;;end_with_conditional()}:
36b809a0 9904
9905@example
625691b3 9906b_loop_cond.end_with_conditional (guard,
9907 b_after_loop, // on_true
9908 b_loop_body); // on_false
36b809a0 9909@end example
9910
9911@noindent
9912
9913However @code{gccjit::rvalue} has overloaded operators for this, so we
9914express the conditional as
9915
9916@example
9917gccjit::rvalue guard = (i >= n);
9918@end example
9919
9920@noindent
9921
625691b3 9922and hence we can write the block more concisely as:
36b809a0 9923
9924@example
9925b_loop_cond.end_with_conditional (
9926 i >= n,
625691b3 9927 b_after_loop, // on_true
9928 b_loop_body); // on_false
36b809a0 9929@end example
9930
9931@noindent
9932
9933Next, we populate the body of the loop.
9934
9935The C statement @cite{sum += i * i;} is an assignment operation, where an
9936lvalue is modified "in-place". We use
17c0b84b 9937@pxref{118,,gccjit;;block;;add_assignment_op()} to handle these operations:
36b809a0 9938
9939@example
9940/* sum += i * i */
9941b_loop_body.add_assignment_op (sum,
9942 GCC_JIT_BINARY_OP_PLUS,
9943 i * i);
9944@end example
9945
9946@noindent
9947
9948The @cite{i++} can be thought of as @cite{i += 1}, and can thus be handled in
9949a similar way. We use @pxref{2f,,gcc_jit_context_one()} to get the constant
9950value @cite{1} (for the relevant type) for the right-hand side
9951of the assignment.
9952
9953@example
9954/* i++ */
9955b_loop_body.add_assignment_op (i,
9956 GCC_JIT_BINARY_OP_PLUS,
9957 ctxt.one (the_type));
9958@end example
9959
9960@noindent
9961
9962@cartouche
9963@quotation Note
9964For numeric constants other than 0 or 1, we could use
17c0b84b 9965@pxref{119,,gccjit;;context;;new_rvalue()}, which has overloads
36b809a0 9966for both @code{int} and @code{double}.
9967@end quotation
9968@end cartouche
9969
9970The loop body completes by jumping back to the conditional:
9971
9972@example
9973b_loop_body.end_with_jump (b_loop_cond);
9974@end example
9975
9976@noindent
9977
9978Finally, we populate the @cite{b_after_loop} block, reached when the loop
9979conditional is false. We want to generate the equivalent of:
9980
9981@example
9982return sum;
9983@end example
9984
9985@noindent
9986
9987so the block is just one statement:
9988
9989@example
9990/* return sum */
9991b_after_loop.end_with_return (sum);
9992@end example
9993
9994@noindent
9995
9996@cartouche
9997@quotation Note
9998You can intermingle block creation with statement creation,
9999but given that the terminator statements generally include references
10000to other blocks, I find it's clearer to create all the blocks,
10001@emph{then} all the statements.
10002@end quotation
10003@end cartouche
10004
10005We've finished populating the function. As before, we can now compile it
10006to machine code:
10007
10008@example
10009gcc_jit_result *result;
10010result = ctxt.compile ();
10011
10012ctxt.release ();
10013
10014if (!result)
10015 @{
10016 fprintf (stderr, "NULL result");
10017 return 1;
10018 @}
10019
10020typedef int (*loop_test_fn_type) (int);
10021loop_test_fn_type loop_test =
10022 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test");
10023if (!loop_test)
10024 @{
10025 fprintf (stderr, "NULL loop_test");
10026 gcc_jit_result_release (result);
10027 return 1;
10028 @}
10029printf ("result: %d", loop_test (10));
10030@end example
10031
10032@noindent
10033
10034@example
10035result: 285
10036@end example
10037
10038@noindent
10039
10040@node Visualizing the control flow graph<2>,Full example<4>,Control flow<2>,Tutorial part 3 Loops and variables<2>
17c0b84b 10041@anchor{cp/intro/tutorial03 visualizing-the-control-flow-graph}@anchor{11a}
36b809a0 10042@subsubsection Visualizing the control flow graph
10043
10044
10045You can see the control flow graph of a function using
17c0b84b 10046@pxref{11b,,gccjit;;function;;dump_to_dot()}:
36b809a0 10047
10048@example
10049func.dump_to_dot ("/tmp/sum-of-squares.dot");
10050@end example
10051
10052@noindent
10053
10054giving a .dot file in GraphViz format.
10055
10056You can convert this to an image using @cite{dot}:
10057
10058@example
10059$ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png
10060@end example
10061
10062@noindent
10063
10064or use a viewer (my preferred one is xdot.py; see
10065@indicateurl{https://github.com/jrfonseca/xdot.py}; on Fedora you can
10066install it with @cite{yum install python-xdot}):
10067
10068@quotation
10069
10070
10071@float Figure
10072
1eddded5 10073@image{sum-of-squares,,,image of a control flow graph,png}
36b809a0 10074
10075@end float
10076
10077@end quotation
10078
10079@node Full example<4>,,Visualizing the control flow graph<2>,Tutorial part 3 Loops and variables<2>
17c0b84b 10080@anchor{cp/intro/tutorial03 full-example}@anchor{11c}
36b809a0 10081@subsubsection Full example
10082
10083
10084@quotation
10085
10086@example
10087/* Usage example for libgccjit.so's C++ API
f1717362 10088 Copyright (C) 2014-2016 Free Software Foundation, Inc.
36b809a0 10089
10090This file is part of GCC.
10091
10092GCC is free software; you can redistribute it and/or modify it
10093under the terms of the GNU General Public License as published by
10094the Free Software Foundation; either version 3, or (at your option)
10095any later version.
10096
10097GCC is distributed in the hope that it will be useful, but
10098WITHOUT ANY WARRANTY; without even the implied warranty of
10099MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10100General Public License for more details.
10101
10102You should have received a copy of the GNU General Public License
10103along with GCC; see the file COPYING3. If not see
10104<http://www.gnu.org/licenses/>. */
10105
10106#include <libgccjit++.h>
10107
10108#include <stdlib.h>
10109#include <stdio.h>
10110
10111void
10112create_code (gccjit::context ctxt)
10113@{
10114 /*
10115 Simple sum-of-squares, to test conditionals and looping
10116
10117 int loop_test (int n)
10118 @{
10119 int i;
10120 int sum = 0;
10121 for (i = 0; i < n ; i ++)
10122 @{
10123 sum += i * i;
10124 @}
10125 return sum;
10126 */
10127 gccjit::type the_type = ctxt.get_int_type <int> ();
10128 gccjit::type return_type = the_type;
10129
10130 gccjit::param n = ctxt.new_param (the_type, "n");
10131 std::vector<gccjit::param> params;
10132 params.push_back (n);
10133 gccjit::function func =
10134 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
10135 return_type,
10136 "loop_test",
10137 params, 0);
10138
10139 /* Build locals: */
10140 gccjit::lvalue i = func.new_local (the_type, "i");
10141 gccjit::lvalue sum = func.new_local (the_type, "sum");
10142
10143 gccjit::block b_initial = func.new_block ("initial");
10144 gccjit::block b_loop_cond = func.new_block ("loop_cond");
10145 gccjit::block b_loop_body = func.new_block ("loop_body");
10146 gccjit::block b_after_loop = func.new_block ("after_loop");
10147
10148 /* sum = 0; */
10149 b_initial.add_assignment (sum, ctxt.zero (the_type));
10150
10151 /* i = 0; */
10152 b_initial.add_assignment (i, ctxt.zero (the_type));
10153
10154 b_initial.end_with_jump (b_loop_cond);
10155
10156 /* if (i >= n) */
10157 b_loop_cond.end_with_conditional (
10158 i >= n,
10159 b_after_loop,
10160 b_loop_body);
10161
10162 /* sum += i * i */
10163 b_loop_body.add_assignment_op (sum,
10164 GCC_JIT_BINARY_OP_PLUS,
10165 i * i);
10166
10167 /* i++ */
10168 b_loop_body.add_assignment_op (i,
10169 GCC_JIT_BINARY_OP_PLUS,
10170 ctxt.one (the_type));
10171
10172 b_loop_body.end_with_jump (b_loop_cond);
10173
10174 /* return sum */
10175 b_after_loop.end_with_return (sum);
10176@}
10177
10178int
10179main (int argc, char **argv)
10180@{
10181 gccjit::context ctxt;
10182 gcc_jit_result *result = NULL;
10183
10184 /* Get a "context" object for working with the library. */
10185 ctxt = gccjit::context::acquire ();
10186
10187 /* Set some options on the context.
10188 Turn this on to see the code being generated, in assembler form. */
10189 ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
10190 0);
10191
10192 /* Populate the context. */
10193 create_code (ctxt);
10194
10195 /* Compile the code. */
10196 result = ctxt.compile ();
10197
10198 ctxt.release ();
10199
10200 if (!result)
10201 @{
10202 fprintf (stderr, "NULL result");
10203 return 1;
10204 @}
10205
10206 /* Extract the generated code from "result". */
10207 typedef int (*loop_test_fn_type) (int);
10208 loop_test_fn_type loop_test =
10209 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test");
10210 if (!loop_test)
10211 @{
10212 fprintf (stderr, "NULL loop_test");
10213 gcc_jit_result_release (result);
10214 return 1;
10215 @}
10216
10217 /* Run the generated code. */
10218 int val = loop_test (10);
10219 printf("loop_test returned: %d\n", val);
10220
10221 gcc_jit_result_release (result);
10222 return 0;
10223@}
10224
10225@end example
10226
10227@noindent
10228@end quotation
10229
10230Building and running it:
10231
10232@example
10233$ gcc \
10234 tut03-sum-of-squares.cc \
10235 -o tut03-sum-of-squares \
10236 -lgccjit
10237
10238# Run the built program:
10239$ ./tut03-sum-of-squares
10240loop_test returned: 285
10241@end example
10242
10243@noindent
10244
f1717362 10245@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
36b809a0 10246@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
10247@c
10248@c This is free software: you can redistribute it and/or modify it
10249@c under the terms of the GNU General Public License as published by
10250@c the Free Software Foundation, either version 3 of the License, or
10251@c (at your option) any later version.
10252@c
10253@c This program is distributed in the hope that it will be useful, but
10254@c WITHOUT ANY WARRANTY; without even the implied warranty of
10255@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10256@c General Public License for more details.
10257@c
10258@c You should have received a copy of the GNU General Public License
10259@c along with this program. If not, see
10260@c <http://www.gnu.org/licenses/>.
10261
10262@node Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>,,Tutorial part 3 Loops and variables<2>,Tutorial<2>
17c0b84b 10263@anchor{cp/intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{11d}@anchor{cp/intro/tutorial04 doc}@anchor{11e}
36b809a0 10264@subsection Tutorial part 4: Adding JIT-compilation to a toy interpreter
10265
10266
10267In this example we construct a "toy" interpreter, and add JIT-compilation
10268to it.
10269
10270@menu
10271* Our toy interpreter: Our toy interpreter<2>.
10272* Compiling to machine code: Compiling to machine code<2>.
10273* Setting things up: Setting things up<2>.
10274* Populating the function: Populating the function<2>.
10275* Verifying the control flow graph: Verifying the control flow graph<2>.
10276* Compiling the context: Compiling the context<2>.
10277* Single-stepping through the generated code: Single-stepping through the generated code<2>.
10278* Examining the generated code: Examining the generated code<2>.
10279* Putting it all together: Putting it all together<2>.
10280* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>.
10281
10282@end menu
10283
10284@node Our toy interpreter<2>,Compiling to machine code<2>,,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
17c0b84b 10285@anchor{cp/intro/tutorial04 our-toy-interpreter}@anchor{11f}
36b809a0 10286@subsubsection Our toy interpreter
10287
10288
10289It's a stack-based interpreter, and is intended as a (very simple) example
10290of the kind of bytecode interpreter seen in dynamic languages such as
10291Python, Ruby etc.
10292
10293For the sake of simplicity, our toy virtual machine is very limited:
10294
10295@quotation
10296
10297
10298@itemize *
10299
10300@item
10301The only data type is @cite{int}
10302
10303@item
10304It can only work on one function at a time (so that the only
10305function call that can be made is to recurse).
10306
10307@item
10308Functions can only take one parameter.
10309
10310@item
10311Functions have a stack of @cite{int} values.
10312
10313@item
10314We'll implement function call within the interpreter by calling a
10315function in our implementation, rather than implementing our own
10316frame stack.
10317
10318@item
10319The parser is only good enough to get the examples to work.
10320@end itemize
10321@end quotation
10322
10323Naturally, a real interpreter would be much more complicated that this.
10324
10325The following operations are supported:
10326
10327
10328@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxx}
10329@headitem
10330
10331Operation
10332
10333@tab
10334
10335Meaning
10336
10337@tab
10338
10339Old Stack
10340
10341@tab
10342
10343New Stack
10344
10345@item
10346
10347DUP
10348
10349@tab
10350
10351Duplicate top of stack.
10352
10353@tab
10354
10355@code{[..., x]}
10356
10357@tab
10358
10359@code{[..., x, x]}
10360
10361@item
10362
10363ROT
10364
10365@tab
10366
10367Swap top two elements
10368of stack.
10369
10370@tab
10371
10372@code{[..., x, y]}
10373
10374@tab
10375
10376@code{[..., y, x]}
10377
10378@item
10379
10380BINARY_ADD
10381
10382@tab
10383
10384Add the top two elements
10385on the stack.
10386
10387@tab
10388
10389@code{[..., x, y]}
10390
10391@tab
10392
10393@code{[..., (x+y)]}
10394
10395@item
10396
10397BINARY_SUBTRACT
10398
10399@tab
10400
10401Likewise, but subtract.
10402
10403@tab
10404
10405@code{[..., x, y]}
10406
10407@tab
10408
10409@code{[..., (x-y)]}
10410
10411@item
10412
10413BINARY_MULT
10414
10415@tab
10416
10417Likewise, but multiply.
10418
10419@tab
10420
10421@code{[..., x, y]}
10422
10423@tab
10424
10425@code{[..., (x*y)]}
10426
10427@item
10428
10429BINARY_COMPARE_LT
10430
10431@tab
10432
10433Compare the top two
10434elements on the stack
10435and push a nonzero/zero
10436if (x<y).
10437
10438@tab
10439
10440@code{[..., x, y]}
10441
10442@tab
10443
10444@code{[..., (x<y)]}
10445
10446@item
10447
10448RECURSE
10449
10450@tab
10451
10452Recurse, passing the top
10453of the stack, and
10454popping the result.
10455
10456@tab
10457
10458@code{[..., x]}
10459
10460@tab
10461
10462@code{[..., fn(x)]}
10463
10464@item
10465
10466RETURN
10467
10468@tab
10469
10470Return the top of the
10471stack.
10472
10473@tab
10474
10475@code{[x]}
10476
10477@tab
10478
10479@code{[]}
10480
10481@item
10482
10483PUSH_CONST @cite{arg}
10484
10485@tab
10486
10487Push an int const.
10488
10489@tab
10490
10491@code{[...]}
10492
10493@tab
10494
10495@code{[..., arg]}
10496
10497@item
10498
10499JUMP_ABS_IF_TRUE @cite{arg}
10500
10501@tab
10502
10503Pop; if top of stack was
10504nonzero, jump to
10505@code{arg}.
10506
10507@tab
10508
10509@code{[..., x]}
10510
10511@tab
10512
10513@code{[...]}
10514
10515@end multitable
10516
10517
10518Programs can be interpreted, disassembled, and compiled to machine code.
10519
10520The interpreter reads @code{.toy} scripts. Here's what a simple recursive
10521factorial program looks like, the script @code{factorial.toy}.
10522The parser ignores lines beginning with a @cite{#}.
10523
10524@quotation
10525
10526@example
10527# Simple recursive factorial implementation, roughly equivalent to:
10528#
10529# int factorial (int arg)
10530# @{
10531# if (arg < 2)
10532# return arg
10533# return arg * factorial (arg - 1)
10534# @}
10535
10536# Initial state:
10537# stack: [arg]
10538
10539# 0:
10540DUP
10541# stack: [arg, arg]
10542
10543# 1:
10544PUSH_CONST 2
10545# stack: [arg, arg, 2]
10546
10547# 2:
10548BINARY_COMPARE_LT
10549# stack: [arg, (arg < 2)]
10550
10551# 3:
10552JUMP_ABS_IF_TRUE 9
10553# stack: [arg]
10554
10555# 4:
10556DUP
10557# stack: [arg, arg]
10558
10559# 5:
10560PUSH_CONST 1
10561# stack: [arg, arg, 1]
10562
10563# 6:
10564BINARY_SUBTRACT
10565# stack: [arg, (arg - 1)
10566
10567# 7:
10568RECURSE
10569# stack: [arg, factorial(arg - 1)]
10570
10571# 8:
10572BINARY_MULT
10573# stack: [arg * factorial(arg - 1)]
10574
10575# 9:
10576RETURN
10577
10578@end example
10579
10580@noindent
10581@end quotation
10582
10583The interpreter is a simple infinite loop with a big @code{switch} statement
10584based on what the next opcode is:
10585
10586@quotation
10587
10588@example
10589
10590int
10591toyvm_function::interpret (int arg, FILE *trace)
10592@{
10593 toyvm_frame frame;
10594#define PUSH(ARG) (frame.push (ARG))
10595#define POP(ARG) (frame.pop ())
10596
10597 frame.frm_function = this;
10598 frame.frm_pc = 0;
10599 frame.frm_cur_depth = 0;
10600
10601 PUSH (arg);
10602
10603 while (1)
10604 @{
10605 toyvm_op *op;
10606 int x, y;
10607 assert (frame.frm_pc < fn_num_ops);
10608 op = &fn_ops[frame.frm_pc++];
10609
10610 if (trace)
10611 @{
10612 frame.dump_stack (trace);
10613 disassemble_op (op, frame.frm_pc, trace);
10614 @}
10615
10616 switch (op->op_opcode)
10617 @{
10618 /* Ops taking no operand. */
10619 case DUP:
10620 x = POP ();
10621 PUSH (x);
10622 PUSH (x);
10623 break;
10624
10625 case ROT:
10626 y = POP ();
10627 x = POP ();
10628 PUSH (y);
10629 PUSH (x);
10630 break;
10631
10632 case BINARY_ADD:
10633 y = POP ();
10634 x = POP ();
10635 PUSH (x + y);
10636 break;
10637
10638 case BINARY_SUBTRACT:
10639 y = POP ();
10640 x = POP ();
10641 PUSH (x - y);
10642 break;
10643
10644 case BINARY_MULT:
10645 y = POP ();
10646 x = POP ();
10647 PUSH (x * y);
10648 break;
10649
10650 case BINARY_COMPARE_LT:
10651 y = POP ();
10652 x = POP ();
10653 PUSH (x < y);
10654 break;
10655
10656 case RECURSE:
10657 x = POP ();
10658 x = interpret (x, trace);
10659 PUSH (x);
10660 break;
10661
10662 case RETURN:
10663 return POP ();
10664
10665 /* Ops taking an operand. */
10666 case PUSH_CONST:
10667 PUSH (op->op_operand);
10668 break;
10669
10670 case JUMP_ABS_IF_TRUE:
10671 x = POP ();
10672 if (x)
10673 frame.frm_pc = op->op_operand;
10674 break;
10675
10676 default:
10677 assert (0); /* unknown opcode */
10678
10679 @} /* end of switch on opcode */
10680 @} /* end of while loop */
10681
10682#undef PUSH
10683#undef POP
10684@}
10685
10686
10687@end example
10688
10689@noindent
10690@end quotation
10691
10692@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>
17c0b84b 10693@anchor{cp/intro/tutorial04 compiling-to-machine-code}@anchor{120}
36b809a0 10694@subsubsection Compiling to machine code
10695
10696
10697We want to generate machine code that can be cast to this type and
10698then directly executed in-process:
10699
10700@quotation
10701
10702@example
10703typedef int (*toyvm_compiled_func) (int);
10704
10705
10706@end example
10707
10708@noindent
10709@end quotation
10710
10711Our compiler isn't very sophisticated; it takes the implementation of
10712each opcode above, and maps it directly to the operations supported by
10713the libgccjit API.
10714
10715How should we handle the stack? In theory we could calculate what the
10716stack depth will be at each opcode, and optimize away the stack
10717manipulation "by hand". We'll see below that libgccjit is able to do
10718this for us, so we'll implement stack manipulation
10719in a direct way, by creating a @code{stack} array and @code{stack_depth}
10720variables, local within the generated function, equivalent to this C code:
10721
10722@example
10723int stack_depth;
10724int stack[MAX_STACK_DEPTH];
10725@end example
10726
10727@noindent
10728
10729We'll also have local variables @code{x} and @code{y} for use when implementing
10730the opcodes, equivalent to this:
10731
10732@example
10733int x;
10734int y;
10735@end example
10736
10737@noindent
10738
10739This means our compiler has the following state:
10740
10741@quotation
10742
10743@example
10744
10745 toyvm_function &toyvmfn;
10746
10747 gccjit::context ctxt;
10748
10749 gccjit::type int_type;
10750 gccjit::type bool_type;
10751 gccjit::type stack_type; /* int[MAX_STACK_DEPTH] */
10752
10753 gccjit::rvalue const_one;
10754
10755 gccjit::function fn;
10756 gccjit::param param_arg;
10757 gccjit::lvalue stack;
10758 gccjit::lvalue stack_depth;
10759 gccjit::lvalue x;
10760 gccjit::lvalue y;
10761
10762 gccjit::location op_locs[MAX_OPS];
10763 gccjit::block initial_block;
10764 gccjit::block op_blocks[MAX_OPS];
10765
10766
10767@end example
10768
10769@noindent
10770@end quotation
10771
10772@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>
17c0b84b 10773@anchor{cp/intro/tutorial04 setting-things-up}@anchor{121}
36b809a0 10774@subsubsection Setting things up
10775
10776
10777First we create our types:
10778
10779@quotation
10780
10781@example
10782
10783void
10784compilation_state::create_types ()
10785@{
10786 /* Create types. */
10787 int_type = ctxt.get_type (GCC_JIT_TYPE_INT);
10788 bool_type = ctxt.get_type (GCC_JIT_TYPE_BOOL);
10789 stack_type = ctxt.new_array_type (int_type, MAX_STACK_DEPTH);
10790
10791
10792@end example
10793
10794@noindent
10795@end quotation
10796
10797along with extracting a useful @cite{int} constant:
10798
10799@quotation
10800
10801@example
10802 const_one = ctxt.one (int_type);
10803
10804@}
10805
10806
10807@end example
10808
10809@noindent
10810@end quotation
10811
10812We'll implement push and pop in terms of the @code{stack} array and
10813@code{stack_depth}. Here are helper functions for adding statements to
10814a block, implementing pushing and popping values:
10815
10816@quotation
10817
10818@example
10819
10820void
10821compilation_state::add_push (gccjit::block block,
10822 gccjit::rvalue rvalue,
10823 gccjit::location loc)
10824@{
10825 /* stack[stack_depth] = RVALUE */
10826 block.add_assignment (
10827 /* stack[stack_depth] */
10828 ctxt.new_array_access (
10829 stack,
10830 stack_depth,
10831 loc),
10832 rvalue,
10833 loc);
10834
10835 /* "stack_depth++;". */
10836 block.add_assignment_op (
10837 stack_depth,
10838 GCC_JIT_BINARY_OP_PLUS,
10839 const_one,
10840 loc);
10841@}
10842
10843void
10844compilation_state::add_pop (gccjit::block block,
10845 gccjit::lvalue lvalue,
10846 gccjit::location loc)
10847@{
10848 /* "--stack_depth;". */
10849 block.add_assignment_op (
10850 stack_depth,
10851 GCC_JIT_BINARY_OP_MINUS,
10852 const_one,
10853 loc);
10854
10855 /* "LVALUE = stack[stack_depth];". */
10856 block.add_assignment (
10857 lvalue,
10858 /* stack[stack_depth] */
10859 ctxt.new_array_access (stack,
10860 stack_depth,
10861 loc),
10862 loc);
10863@}
10864
10865
10866@end example
10867
10868@noindent
10869@end quotation
10870
10871We will support single-stepping through the generated code in the
10872debugger, so we need to create @code{gccjit::location} instances, one
10873per operation in the source code. These will reference the lines of
10874e.g. @code{factorial.toy}.
10875
10876@quotation
10877
10878@example
10879
10880void
10881compilation_state::create_locations ()
10882@{
10883 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++)
10884 @{
10885 toyvm_op *op = &toyvmfn.fn_ops[pc];
10886
10887 op_locs[pc] = ctxt.new_location (toyvmfn.fn_filename,
10888 op->op_linenum,
10889 0); /* column */
10890 @}
10891@}
10892
10893
10894@end example
10895
10896@noindent
10897@end quotation
10898
10899Let's create the function itself. As usual, we create its parameter
10900first, then use the parameter to create the function:
10901
10902@quotation
10903
10904@example
10905
10906void
10907compilation_state::create_function (const char *funcname)
10908@{
10909 std::vector <gccjit::param> params;
10910 param_arg = ctxt.new_param (int_type, "arg", op_locs[0]);
10911 params.push_back (param_arg);
10912 fn = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
10913 int_type,
10914 funcname,
10915 params, 0,
10916 op_locs[0]);
10917
10918
10919@end example
10920
10921@noindent
10922@end quotation
10923
10924We create the locals within the function.
10925
10926@quotation
10927
10928@example
10929 stack = fn.new_local (stack_type, "stack");
10930 stack_depth = fn.new_local (int_type, "stack_depth");
10931 x = fn.new_local (int_type, "x");
10932 y = fn.new_local (int_type, "y");
10933
10934
10935@end example
10936
10937@noindent
10938@end quotation
10939
10940@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>
17c0b84b 10941@anchor{cp/intro/tutorial04 populating-the-function}@anchor{122}
36b809a0 10942@subsubsection Populating the function
10943
10944
10945There's some one-time initialization, and the API treats the first block
10946you create as the entrypoint of the function, so we need to create that
10947block first:
10948
10949@quotation
10950
10951@example
10952 initial_block = fn.new_block ("initial");
10953
10954
10955@end example
10956
10957@noindent
10958@end quotation
10959
10960We can now create blocks for each of the operations. Most of these will
10961be consolidated into larger blocks when the optimizer runs.
10962
10963@quotation
10964
10965@example
10966 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++)
10967 @{
10968 char buf[16];
10969 sprintf (buf, "instr%i", pc);
10970 op_blocks[pc] = fn.new_block (buf);
10971 @}
10972
10973
10974@end example
10975
10976@noindent
10977@end quotation
10978
10979Now that we have a block it can jump to when it's done, we can populate
10980the initial block:
10981
10982@quotation
10983
10984@example
10985
10986 /* "stack_depth = 0;". */
10987 initial_block.add_assignment (stack_depth,
10988 ctxt.zero (int_type),
10989 op_locs[0]);
10990
10991 /* "PUSH (arg);". */
10992 add_push (initial_block,
10993 param_arg,
10994 op_locs[0]);
10995
10996 /* ...and jump to insn 0. */
10997 initial_block.end_with_jump (op_blocks[0],
10998 op_locs[0]);
10999
11000
11001@end example
11002
11003@noindent
11004@end quotation
11005
11006We can now populate the blocks for the individual operations. We loop
11007through them, adding instructions to their blocks:
11008
11009@quotation
11010
11011@example
11012 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++)
11013 @{
11014 gccjit::location loc = op_locs[pc];
11015
11016 gccjit::block block = op_blocks[pc];
11017 gccjit::block next_block = (pc < toyvmfn.fn_num_ops
11018 ? op_blocks[pc + 1]
11019 : NULL);
11020
11021 toyvm_op *op;
11022 op = &toyvmfn.fn_ops[pc];
11023
11024
11025@end example
11026
11027@noindent
11028@end quotation
11029
11030We're going to have another big @code{switch} statement for implementing
11031the opcodes, this time for compiling them, rather than interpreting
11032them. It's helpful to have macros for implementing push and pop, so that
11033we can make the @code{switch} statement that's coming up look as much as
11034possible like the one above within the interpreter:
11035
11036@example
11037
11038#define X_EQUALS_POP()\
11039 add_pop (block, x, loc)
11040#define Y_EQUALS_POP()\
11041 add_pop (block, y, loc)
11042#define PUSH_RVALUE(RVALUE)\
11043 add_push (block, (RVALUE), loc)
11044#define PUSH_X()\
11045 PUSH_RVALUE (x)
11046#define PUSH_Y() \
11047 PUSH_RVALUE (y)
11048
11049
11050@end example
11051
11052@noindent
11053
11054@cartouche
11055@quotation Note
11056A particularly clever implementation would have an @emph{identical}
11057@code{switch} statement shared by the interpreter and the compiler, with
11058some preprocessor "magic". We're not doing that here, for the sake
11059of simplicity.
11060@end quotation
11061@end cartouche
11062
11063When I first implemented this compiler, I accidentally missed an edit
11064when copying and pasting the @code{Y_EQUALS_POP} macro, so that popping the
11065stack into @code{y} instead erroneously assigned it to @code{x}, leaving @code{y}
11066uninitialized.
11067
11068To track this kind of thing down, we can use
17c0b84b 11069@pxref{123,,gccjit;;block;;add_comment()} to add descriptive comments
36b809a0 11070to the internal representation. This is invaluable when looking through
11071the generated IR for, say @code{factorial}:
11072
11073@quotation
11074
11075@example
11076
11077 block.add_comment (opcode_names[op->op_opcode], loc);
11078
11079
11080@end example
11081
11082@noindent
11083@end quotation
11084
11085We can now write the big @code{switch} statement that implements the
11086individual opcodes, populating the relevant block with statements:
11087
11088@quotation
11089
11090@example
11091
11092 switch (op->op_opcode)
11093 @{
11094 case DUP:
11095 X_EQUALS_POP ();
11096 PUSH_X ();
11097 PUSH_X ();
11098 break;
11099
11100 case ROT:
11101 Y_EQUALS_POP ();
11102 X_EQUALS_POP ();
11103 PUSH_Y ();
11104 PUSH_X ();
11105 break;
11106
11107 case BINARY_ADD:
11108 Y_EQUALS_POP ();
11109 X_EQUALS_POP ();
11110 PUSH_RVALUE (
11111 ctxt.new_binary_op (
11112 GCC_JIT_BINARY_OP_PLUS,
11113 int_type,
11114 x, y,
11115 loc));
11116 break;
11117
11118 case BINARY_SUBTRACT:
11119 Y_EQUALS_POP ();
11120 X_EQUALS_POP ();
11121 PUSH_RVALUE (
11122 ctxt.new_binary_op (
11123 GCC_JIT_BINARY_OP_MINUS,
11124 int_type,
11125 x, y,
11126 loc));
11127 break;
11128
11129 case BINARY_MULT:
11130 Y_EQUALS_POP ();
11131 X_EQUALS_POP ();
11132 PUSH_RVALUE (
11133 ctxt.new_binary_op (
11134 GCC_JIT_BINARY_OP_MULT,
11135 int_type,
11136 x, y,
11137 loc));
11138 break;
11139
11140 case BINARY_COMPARE_LT:
11141 Y_EQUALS_POP ();
11142 X_EQUALS_POP ();
11143 PUSH_RVALUE (
11144 /* cast of bool to int */
11145 ctxt.new_cast (
11146 /* (x < y) as a bool */
11147 ctxt.new_comparison (
11148 GCC_JIT_COMPARISON_LT,
11149 x, y,
11150 loc),
11151 int_type,
11152 loc));
11153 break;
11154
11155 case RECURSE:
11156 @{
11157 X_EQUALS_POP ();
11158 PUSH_RVALUE (
11159 ctxt.new_call (
11160 fn,
11161 x,
11162 loc));
11163 break;
11164 @}
11165
11166 case RETURN:
11167 X_EQUALS_POP ();
11168 block.end_with_return (x, loc);
11169 break;
11170
11171 /* Ops taking an operand. */
11172 case PUSH_CONST:
11173 PUSH_RVALUE (
11174 ctxt.new_rvalue (int_type, op->op_operand));
11175 break;
11176
11177 case JUMP_ABS_IF_TRUE:
11178 X_EQUALS_POP ();
11179 block.end_with_conditional (
11180 /* "(bool)x". */
11181 ctxt.new_cast (x, bool_type, loc),
11182 op_blocks[op->op_operand], /* on_true */
11183 next_block, /* on_false */
11184 loc);
11185 break;
11186
11187 default:
11188 assert(0);
11189 @} /* end of switch on opcode */
11190
11191
11192@end example
11193
11194@noindent
11195@end quotation
11196
11197Every block must be terminated, via a call to one of the
11198@code{gccjit::block::end_with_} entrypoints. This has been done for two
11199of the opcodes, but we need to do it for the other ones, by jumping
11200to the next block.
11201
11202@quotation
11203
11204@example
11205 if (op->op_opcode != JUMP_ABS_IF_TRUE
11206 && op->op_opcode != RETURN)
11207 block.end_with_jump (next_block, loc);
11208
11209
11210@end example
11211
11212@noindent
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>
17c0b84b 11218@anchor{cp/intro/tutorial04 verifying-the-control-flow-graph}@anchor{124}
36b809a0 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
17c0b84b 11225using @pxref{11b,,gccjit;;function;;dump_to_dot()}:
36b809a0 11226
11227@example
11228fn.dump_to_dot ("/tmp/factorial.dot");
11229@end example
11230
11231@noindent
11232
11233and viewing the result. Note how the label names, comments, and
11234variable names show up in the dump, to make it easier to spot
11235errors in our compiler.
11236
11237@quotation
11238
11239
11240@float Figure
11241
1eddded5 11242@image{factorial,,,image of a control flow graph,png}
36b809a0 11243
11244@end float
11245
11246@end quotation
11247
11248@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>
17c0b84b 11249@anchor{cp/intro/tutorial04 compiling-the-context}@anchor{125}
36b809a0 11250@subsubsection Compiling the context
11251
11252
11253Having finished looping over the blocks and populating them with
11254statements, the context is complete.
11255
11256We can now compile it, and extract machine code from the result:
11257
11258@quotation
11259
11260@example
11261 gcc_jit_result *result = state.compile ();
11262
11263 return (toyvm_compiled_func)gcc_jit_result_get_code (result, funcname);
11264
11265@end example
11266
11267@noindent
11268@end quotation
11269
11270We can now run the result:
11271
11272@quotation
11273
11274@example
11275 toyvm_compiled_func code = fn->compile ();
11276 printf ("compiler result: %d\n",
11277 code (atoi (argv[2])));
11278
11279
11280@end example
11281
11282@noindent
11283@end quotation
11284
11285@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>
17c0b84b 11286@anchor{cp/intro/tutorial04 single-stepping-through-the-generated-code}@anchor{126}
36b809a0 11287@subsubsection Single-stepping through the generated code
11288
11289
11290It's possible to debug the generated code. To do this we need to both:
11291
11292@quotation
11293
11294
11295@itemize *
11296
11297@item
11298Set up source code locations for our statements, so that we can
11299meaningfully step through the code. We did this above by
17c0b84b 11300calling @pxref{127,,gccjit;;context;;new_location()} and using the
36b809a0 11301results.
11302
11303@item
11304Enable the generation of debugging information, by setting
11305@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the
11306@code{gccjit::context} via
17c0b84b 11307@pxref{10c,,gccjit;;context;;set_bool_option()}:
36b809a0 11308
11309@example
11310ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1);
11311@end example
11312
11313@noindent
11314@end itemize
11315@end quotation
11316
11317Having done this, we can put a breakpoint on the generated function:
11318
11319@example
11320$ gdb --args ./toyvm factorial.toy 10
11321(gdb) break factorial
11322Function "factorial" not defined.
11323Make breakpoint pending on future shared library load? (y or [n]) y
11324Breakpoint 1 (factorial) pending.
11325(gdb) run
11326Breakpoint 1, factorial (arg=10) at factorial.toy:14
1132714 DUP
11328@end example
11329
11330@noindent
11331
11332We've set up location information, which references @code{factorial.toy}.
11333This allows us to use e.g. @code{list} to see where we are in the script:
11334
11335@example
11336(gdb) list
113379
1133810 # Initial state:
1133911 # stack: [arg]
1134012
1134113 # 0:
1134214 DUP
1134315 # stack: [arg, arg]
1134416
1134517 # 1:
1134618 PUSH_CONST 2
11347@end example
11348
11349@noindent
11350
11351and to step through the function, examining the data:
11352
11353@example
11354(gdb) n
1135518 PUSH_CONST 2
11356(gdb) n
1135722 BINARY_COMPARE_LT
11358(gdb) print stack
11359$5 = @{10, 10, 2, 0, -7152, 32767, 0, 0@}
11360(gdb) print stack_depth
11361$6 = 3
11362@end example
11363
11364@noindent
11365
11366You'll see that the parts of the @code{stack} array that haven't been
11367touched yet are uninitialized.
11368
11369@cartouche
11370@quotation Note
11371Turning on optimizations may lead to unpredictable results when
11372stepping through the generated code: the execution may appear to
11373"jump around" the source code. This is analogous to turning up the
11374optimization level in a regular compiler.
11375@end quotation
11376@end cartouche
11377
11378@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>
17c0b84b 11379@anchor{cp/intro/tutorial04 examining-the-generated-code}@anchor{128}
36b809a0 11380@subsubsection Examining the generated code
11381
11382
11383How good is the optimized code?
11384
11385We can turn up optimizations, by calling
17c0b84b 11386@pxref{10d,,gccjit;;context;;set_int_option()} with
36b809a0 11387@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}:
11388
11389@example
11390ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3);
11391@end example
11392
11393@noindent
11394
11395One of GCC's internal representations is called "gimple". A dump of the
11396initial gimple representation of the code can be seen by setting:
11397
11398@example
11399ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1);
11400@end example
11401
11402@noindent
11403
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
11447@noindent
11448
11449You can see the generated machine code in assembly form via:
11450
11451@example
11452ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1);
11453result = ctxt.compile ();
11454@end example
11455
11456@noindent
11457
11458which shows that (on this x86_64 box) the compiler has unrolled the loop
11459and is using MMX instructions to perform several multiplications
11460simultaneously:
11461
11462@example
11463 .file "fake.c"
11464 .text
11465.Ltext0:
11466 .p2align 4,,15
11467 .globl factorial
11468 .type factorial, @@function
11469factorial:
11470.LFB0:
11471 .file 1 "factorial.toy"
11472 .loc 1 14 0
11473 .cfi_startproc
11474.LVL0:
11475.L2:
11476 .loc 1 26 0
11477 cmpl $1, %edi
11478 jle .L13
11479 leal -1(%rdi), %edx
11480 movl %edx, %ecx
11481 shrl $2, %ecx
11482 leal 0(,%rcx,4), %esi
11483 testl %esi, %esi
11484 je .L14
11485 cmpl $9, %edx
11486 jbe .L14
11487 leal -2(%rdi), %eax
11488 movl %eax, -16(%rsp)
11489 leal -3(%rdi), %eax
11490 movd -16(%rsp), %xmm0
11491 movl %edi, -16(%rsp)
11492 movl %eax, -12(%rsp)
11493 movd -16(%rsp), %xmm1
11494 xorl %eax, %eax
11495 movl %edx, -16(%rsp)
11496 movd -12(%rsp), %xmm4
11497 movd -16(%rsp), %xmm6
11498 punpckldq %xmm4, %xmm0
11499 movdqa .LC1(%rip), %xmm4
11500 punpckldq %xmm6, %xmm1
11501 punpcklqdq %xmm0, %xmm1
11502 movdqa .LC0(%rip), %xmm0
11503 jmp .L5
11504 # etc - edited for brevity
11505@end example
11506
11507@noindent
11508
11509This is clearly overkill for a function that will likely overflow the
11510@code{int} type before the vectorization is worthwhile - but then again, this
11511is a toy example.
11512
11513Turning down the optimization level to 2:
11514
11515@example
11516ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 2);
11517@end example
11518
11519@noindent
11520
11521yields this code, which is simple enough to quote in its entirety:
11522
11523@example
11524 .file "fake.c"
11525 .text
11526 .p2align 4,,15
11527 .globl factorial
11528 .type factorial, @@function
11529factorial:
11530.LFB0:
11531 .cfi_startproc
11532.L2:
11533 cmpl $1, %edi
11534 jle .L8
11535 movl $1, %edx
11536 jmp .L4
11537 .p2align 4,,10
11538 .p2align 3
11539.L6:
11540 movl %eax, %edi
11541.L4:
11542.L5:
11543 leal -1(%rdi), %eax
11544 imull %edi, %edx
11545 cmpl $1, %eax
11546 jne .L6
11547.L3:
11548.L7:
11549 imull %edx, %eax
11550 ret
11551.L8:
11552 movl %edi, %eax
11553 movl $1, %edx
11554 jmp .L7
11555 .cfi_endproc
11556.LFE0:
11557 .size factorial, .-factorial
11558 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-%@{gcc_release@})"
11559 .section .note.GNU-stack,"",@@progbits
11560@end example
11561
11562@noindent
11563
11564Note that the stack pushing and popping have been eliminated, as has the
11565recursive call (in favor of an iteration).
11566
11567@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>
17c0b84b 11568@anchor{cp/intro/tutorial04 putting-it-all-together}@anchor{129}
36b809a0 11569@subsubsection Putting it all together
11570
11571
11572The complete example can be seen in the source tree at
11573@code{gcc/jit/docs/examples/tut04-toyvm/toyvm.cc}
11574
11575along with a Makefile and a couple of sample .toy scripts:
11576
11577@example
11578$ ls -al
11579drwxrwxr-x. 2 david david 4096 Sep 19 17:46 .
11580drwxrwxr-x. 3 david david 4096 Sep 19 15:26 ..
11581-rw-rw-r--. 1 david david 615 Sep 19 12:43 factorial.toy
11582-rw-rw-r--. 1 david david 834 Sep 19 13:08 fibonacci.toy
11583-rw-rw-r--. 1 david david 238 Sep 19 14:22 Makefile
11584-rw-rw-r--. 1 david david 16457 Sep 19 17:07 toyvm.cc
11585
11586$ make toyvm
11587g++ -Wall -g -o toyvm toyvm.cc -lgccjit
11588
11589$ ./toyvm factorial.toy 10
11590interpreter result: 3628800
11591compiler result: 3628800
11592
11593$ ./toyvm fibonacci.toy 10
11594interpreter result: 55
11595compiler result: 55
11596@end example
11597
11598@noindent
11599
11600@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>
17c0b84b 11601@anchor{cp/intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{12a}
36b809a0 11602@subsubsection Behind the curtain: How does our code get optimized?
11603
11604
11605Our example is done, but you may be wondering about exactly how the
11606compiler turned what we gave it into the machine code seen above.
11607
11608We can examine what the compiler is doing in detail by setting:
11609
11610@example
11611state.ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 1);
11612state.ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 1);
11613@end example
11614
11615@noindent
11616
11617This will dump detailed information about the compiler's state to a
11618directory under @code{/tmp}, and keep it from being cleaned up.
11619
11620The precise names and their formats of these files is subject to change.
11621Higher optimization levels lead to more files.
11622Here's what I saw (edited for brevity; there were almost 200 files):
11623
11624@example
11625intermediate files written to /tmp/libgccjit-KPQbGw
11626$ ls /tmp/libgccjit-KPQbGw/
11627fake.c.000i.cgraph
11628fake.c.000i.type-inheritance
11629fake.c.004t.gimple
11630fake.c.007t.omplower
11631fake.c.008t.lower
11632fake.c.011t.eh
11633fake.c.012t.cfg
11634fake.c.014i.visibility
11635fake.c.015i.early_local_cleanups
11636fake.c.016t.ssa
11637# etc
11638@end example
11639
11640@noindent
11641
11642The gimple code is converted into Static Single Assignment form,
11643with annotations for use when generating the debuginfo:
11644
11645@example
11646$ less /tmp/libgccjit-KPQbGw/fake.c.016t.ssa
11647@end example
11648
11649@noindent
11650
11651@example
11652;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
11653
11654factorial (signed int arg)
11655@{
11656 signed int stack[8];
11657 signed int stack_depth;
11658 signed int x;
11659 signed int y;
11660 <unnamed type> _20;
11661 signed int _21;
11662 signed int _38;
11663 signed int _44;
11664 signed int _51;
11665 signed int _56;
11666
11667initial:
11668 stack_depth_3 = 0;
11669 # DEBUG stack_depth => stack_depth_3
11670 stack[stack_depth_3] = arg_5(D);
11671 stack_depth_7 = stack_depth_3 + 1;
11672 # DEBUG stack_depth => stack_depth_7
11673 # DEBUG instr0 => NULL
11674 # DEBUG /* DUP */ => NULL
11675 stack_depth_8 = stack_depth_7 + -1;
11676 # DEBUG stack_depth => stack_depth_8
11677 x_9 = stack[stack_depth_8];
11678 # DEBUG x => x_9
11679 stack[stack_depth_8] = x_9;
11680 stack_depth_11 = stack_depth_8 + 1;
11681 # DEBUG stack_depth => stack_depth_11
11682 stack[stack_depth_11] = x_9;
11683 stack_depth_13 = stack_depth_11 + 1;
11684 # DEBUG stack_depth => stack_depth_13
11685 # DEBUG instr1 => NULL
11686 # DEBUG /* PUSH_CONST */ => NULL
11687 stack[stack_depth_13] = 2;
11688
11689 /* etc; edited for brevity */
11690@end example
11691
11692@noindent
11693
11694We can perhaps better see the code by turning off
11695@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to suppress all those @code{DEBUG}
11696statements, giving:
11697
11698@example
11699$ less /tmp/libgccjit-1Hywc0/fake.c.016t.ssa
11700@end example
11701
11702@noindent
11703
11704@example
11705;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
11706
11707factorial (signed int arg)
11708@{
11709 signed int stack[8];
11710 signed int stack_depth;
11711 signed int x;
11712 signed int y;
11713 <unnamed type> _20;
11714 signed int _21;
11715 signed int _38;
11716 signed int _44;
11717 signed int _51;
11718 signed int _56;
11719
11720initial:
11721 stack_depth_3 = 0;
11722 stack[stack_depth_3] = arg_5(D);
11723 stack_depth_7 = stack_depth_3 + 1;
11724 stack_depth_8 = stack_depth_7 + -1;
11725 x_9 = stack[stack_depth_8];
11726 stack[stack_depth_8] = x_9;
11727 stack_depth_11 = stack_depth_8 + 1;
11728 stack[stack_depth_11] = x_9;
11729 stack_depth_13 = stack_depth_11 + 1;
11730 stack[stack_depth_13] = 2;
11731 stack_depth_15 = stack_depth_13 + 1;
11732 stack_depth_16 = stack_depth_15 + -1;
11733 y_17 = stack[stack_depth_16];
11734 stack_depth_18 = stack_depth_16 + -1;
11735 x_19 = stack[stack_depth_18];
11736 _20 = x_19 < y_17;
11737 _21 = (signed int) _20;
11738 stack[stack_depth_18] = _21;
11739 stack_depth_23 = stack_depth_18 + 1;
11740 stack_depth_24 = stack_depth_23 + -1;
11741 x_25 = stack[stack_depth_24];
11742 if (x_25 != 0)
11743 goto <bb 4> (instr9);
11744 else
11745 goto <bb 3> (instr4);
11746
11747instr4:
11748/* DUP */:
11749 stack_depth_26 = stack_depth_24 + -1;
11750 x_27 = stack[stack_depth_26];
11751 stack[stack_depth_26] = x_27;
11752 stack_depth_29 = stack_depth_26 + 1;
11753 stack[stack_depth_29] = x_27;
11754 stack_depth_31 = stack_depth_29 + 1;
11755 stack[stack_depth_31] = 1;
11756 stack_depth_33 = stack_depth_31 + 1;
11757 stack_depth_34 = stack_depth_33 + -1;
11758 y_35 = stack[stack_depth_34];
11759 stack_depth_36 = stack_depth_34 + -1;
11760 x_37 = stack[stack_depth_36];
11761 _38 = x_37 - y_35;
11762 stack[stack_depth_36] = _38;
11763 stack_depth_40 = stack_depth_36 + 1;
11764 stack_depth_41 = stack_depth_40 + -1;
11765 x_42 = stack[stack_depth_41];
11766 _44 = factorial (x_42);
11767 stack[stack_depth_41] = _44;
11768 stack_depth_46 = stack_depth_41 + 1;
11769 stack_depth_47 = stack_depth_46 + -1;
11770 y_48 = stack[stack_depth_47];
11771 stack_depth_49 = stack_depth_47 + -1;
11772 x_50 = stack[stack_depth_49];
11773 _51 = x_50 * y_48;
11774 stack[stack_depth_49] = _51;
11775 stack_depth_53 = stack_depth_49 + 1;
11776
11777 # stack_depth_1 = PHI <stack_depth_24(2), stack_depth_53(3)>
11778instr9:
11779/* RETURN */:
11780 stack_depth_54 = stack_depth_1 + -1;
11781 x_55 = stack[stack_depth_54];
11782 _56 = x_55;
11783 stack =@{v@} @{CLOBBER@};
11784 return _56;
11785
11786@}
11787@end example
11788
11789@noindent
11790
11791Note in the above how all the @code{gccjit::block} instances we
11792created have been consolidated into just 3 blocks in GCC's internal
11793representation: @code{initial}, @code{instr4} and @code{instr9}.
11794
11795@menu
11796* Optimizing away stack manipulation: Optimizing away stack manipulation<2>.
11797* Elimination of tail recursion: Elimination of tail recursion<2>.
11798
11799@end menu
11800
11801@node Optimizing away stack manipulation<2>,Elimination of tail recursion<2>,,Behind the curtain How does our code get optimized?<2>
17c0b84b 11802@anchor{cp/intro/tutorial04 optimizing-away-stack-manipulation}@anchor{12b}
36b809a0 11803@subsubsection Optimizing away stack manipulation
11804
11805
11806Recall our simple implementation of stack operations. Let's examine
11807how the stack operations are optimized away.
11808
11809After a pass of constant-propagation, the depth of the stack at each
11810opcode can be determined at compile-time:
11811
11812@example
11813$ less /tmp/libgccjit-1Hywc0/fake.c.021t.ccp1
11814@end example
11815
11816@noindent
11817
11818@example
11819;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
11820
11821factorial (signed int arg)
11822@{
11823 signed int stack[8];
11824 signed int stack_depth;
11825 signed int x;
11826 signed int y;
11827 <unnamed type> _20;
11828 signed int _21;
11829 signed int _38;
11830 signed int _44;
11831 signed int _51;
11832
11833initial:
11834 stack[0] = arg_5(D);
11835 x_9 = stack[0];
11836 stack[0] = x_9;
11837 stack[1] = x_9;
11838 stack[2] = 2;
11839 y_17 = stack[2];
11840 x_19 = stack[1];
11841 _20 = x_19 < y_17;
11842 _21 = (signed int) _20;
11843 stack[1] = _21;
11844 x_25 = stack[1];
11845 if (x_25 != 0)
11846 goto <bb 4> (instr9);
11847 else
11848 goto <bb 3> (instr4);
11849
11850instr4:
11851/* DUP */:
11852 x_27 = stack[0];
11853 stack[0] = x_27;
11854 stack[1] = x_27;
11855 stack[2] = 1;
11856 y_35 = stack[2];
11857 x_37 = stack[1];
11858 _38 = x_37 - y_35;
11859 stack[1] = _38;
11860 x_42 = stack[1];
11861 _44 = factorial (x_42);
11862 stack[1] = _44;
11863 y_48 = stack[1];
11864 x_50 = stack[0];
11865 _51 = x_50 * y_48;
11866 stack[0] = _51;
11867
11868instr9:
11869/* RETURN */:
11870 x_55 = stack[0];
11871 x_56 = x_55;
11872 stack =@{v@} @{CLOBBER@};
11873 return x_56;
11874
11875@}
11876@end example
11877
11878@noindent
11879
11880Note how, in the above, all those @code{stack_depth} values are now just
11881constants: we're accessing specific stack locations at each opcode.
11882
11883The "esra" pass ("Early Scalar Replacement of Aggregates") breaks
11884out our "stack" array into individual elements:
11885
11886@example
11887$ less /tmp/libgccjit-1Hywc0/fake.c.024t.esra
11888@end example
11889
11890@noindent
11891
11892@example
11893;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
11894
11895Created a replacement for stack offset: 0, size: 32: stack$0
11896Created a replacement for stack offset: 32, size: 32: stack$1
11897Created a replacement for stack offset: 64, size: 32: stack$2
11898
11899Symbols to be put in SSA form
11900@{ D.89 D.90 D.91 @}
11901Incremental SSA update started at block: 0
11902Number of blocks in CFG: 5
11903Number of blocks to update: 4 ( 80%)
11904
11905
11906factorial (signed int arg)
11907@{
11908 signed int stack$2;
11909 signed int stack$1;
11910 signed int stack$0;
11911 signed int stack[8];
11912 signed int stack_depth;
11913 signed int x;
11914 signed int y;
11915 <unnamed type> _20;
11916 signed int _21;
11917 signed int _38;
11918 signed int _44;
11919 signed int _51;
11920
11921initial:
11922 stack$0_45 = arg_5(D);
11923 x_9 = stack$0_45;
11924 stack$0_39 = x_9;
11925 stack$1_32 = x_9;
11926 stack$2_30 = 2;
11927 y_17 = stack$2_30;
11928 x_19 = stack$1_32;
11929 _20 = x_19 < y_17;
11930 _21 = (signed int) _20;
11931 stack$1_28 = _21;
11932 x_25 = stack$1_28;
11933 if (x_25 != 0)
11934 goto <bb 4> (instr9);
11935 else
11936 goto <bb 3> (instr4);
11937
11938instr4:
11939/* DUP */:
11940 x_27 = stack$0_39;
11941 stack$0_22 = x_27;
11942 stack$1_14 = x_27;
11943 stack$2_12 = 1;
11944 y_35 = stack$2_12;
11945 x_37 = stack$1_14;
11946 _38 = x_37 - y_35;
11947 stack$1_10 = _38;
11948 x_42 = stack$1_10;
11949 _44 = factorial (x_42);
11950 stack$1_6 = _44;
11951 y_48 = stack$1_6;
11952 x_50 = stack$0_22;
11953 _51 = x_50 * y_48;
11954 stack$0_1 = _51;
11955
11956 # stack$0_52 = PHI <stack$0_39(2), stack$0_1(3)>
11957instr9:
11958/* RETURN */:
11959 x_55 = stack$0_52;
11960 x_56 = x_55;
11961 stack =@{v@} @{CLOBBER@};
11962 return x_56;
11963
11964@}
11965@end example
11966
11967@noindent
11968
11969Hence at this point, all those pushes and pops of the stack are now
11970simply assignments to specific temporary variables.
11971
11972After some copy propagation, the stack manipulation has been completely
11973optimized away:
11974
11975@example
11976$ less /tmp/libgccjit-1Hywc0/fake.c.026t.copyprop1
11977@end example
11978
11979@noindent
11980
11981@example
11982;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
11983
11984factorial (signed int arg)
11985@{
11986 signed int stack$2;
11987 signed int stack$1;
11988 signed int stack$0;
11989 signed int stack[8];
11990 signed int stack_depth;
11991 signed int x;
11992 signed int y;
11993 <unnamed type> _20;
11994 signed int _21;
11995 signed int _38;
11996 signed int _44;
11997 signed int _51;
11998
11999initial:
12000 stack$0_39 = arg_5(D);
12001 _20 = arg_5(D) <= 1;
12002 _21 = (signed int) _20;
12003 if (_21 != 0)
12004 goto <bb 4> (instr9);
12005 else
12006 goto <bb 3> (instr4);
12007
12008instr4:
12009/* DUP */:
12010 _38 = arg_5(D) + -1;
12011 _44 = factorial (_38);
12012 _51 = arg_5(D) * _44;
12013 stack$0_1 = _51;
12014
12015 # stack$0_52 = PHI <arg_5(D)(2), _51(3)>
12016instr9:
12017/* RETURN */:
12018 stack =@{v@} @{CLOBBER@};
12019 return stack$0_52;
12020
12021@}
12022@end example
12023
12024@noindent
12025
12026Later on, another pass finally eliminated @code{stack_depth} local and the
12027unused parts of the @cite{stack`} array altogether:
12028
12029@example
12030$ less /tmp/libgccjit-1Hywc0/fake.c.036t.release_ssa
12031@end example
12032
12033@noindent
12034
12035@example
12036;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
12037
12038Released 44 names, 314.29%, removed 44 holes
12039factorial (signed int arg)
12040@{
12041 signed int stack$0;
12042 signed int mult_acc_1;
12043 <unnamed type> _5;
12044 signed int _6;
12045 signed int _7;
12046 signed int mul_tmp_10;
12047 signed int mult_acc_11;
12048 signed int mult_acc_13;
12049
12050 # arg_9 = PHI <arg_8(D)(0)>
12051 # mult_acc_13 = PHI <1(0)>
12052initial:
12053
12054 <bb 5>:
12055 # arg_4 = PHI <arg_9(2), _7(3)>
12056 # mult_acc_1 = PHI <mult_acc_13(2), mult_acc_11(3)>
12057 _5 = arg_4 <= 1;
12058 _6 = (signed int) _5;
12059 if (_6 != 0)
12060 goto <bb 4> (instr9);
12061 else
12062 goto <bb 3> (instr4);
12063
12064instr4:
12065/* DUP */:
12066 _7 = arg_4 + -1;
12067 mult_acc_11 = mult_acc_1 * arg_4;
12068 goto <bb 5>;
12069
12070 # stack$0_12 = PHI <arg_4(5)>
12071instr9:
12072/* RETURN */:
12073 mul_tmp_10 = mult_acc_1 * stack$0_12;
12074 return mul_tmp_10;
12075
12076@}
12077@end example
12078
12079@noindent
12080
12081@node Elimination of tail recursion<2>,,Optimizing away stack manipulation<2>,Behind the curtain How does our code get optimized?<2>
17c0b84b 12082@anchor{cp/intro/tutorial04 elimination-of-tail-recursion}@anchor{12c}
36b809a0 12083@subsubsection Elimination of tail recursion
12084
12085
12086Another significant optimization is the detection that the call to
12087@code{factorial} is tail recursion, which can be eliminated in favor of
12088an iteration:
12089
12090@example
12091$ less /tmp/libgccjit-1Hywc0/fake.c.030t.tailr1
12092@end example
12093
12094@noindent
12095
12096@example
12097;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)
12098
12099
12100Symbols to be put in SSA form
12101@{ D.88 @}
12102Incremental SSA update started at block: 0
12103Number of blocks in CFG: 5
12104Number of blocks to update: 4 ( 80%)
12105
12106
12107factorial (signed int arg)
12108@{
12109 signed int stack$2;
12110 signed int stack$1;
12111 signed int stack$0;
12112 signed int stack[8];
12113 signed int stack_depth;
12114 signed int x;
12115 signed int y;
12116 signed int mult_acc_1;
12117 <unnamed type> _20;
12118 signed int _21;
12119 signed int _38;
12120 signed int mul_tmp_44;
12121 signed int mult_acc_51;
12122
12123 # arg_5 = PHI <arg_39(D)(0), _38(3)>
12124 # mult_acc_1 = PHI <1(0), mult_acc_51(3)>
12125initial:
12126 _20 = arg_5 <= 1;
12127 _21 = (signed int) _20;
12128 if (_21 != 0)
12129 goto <bb 4> (instr9);
12130 else
12131 goto <bb 3> (instr4);
12132
12133instr4:
12134/* DUP */:
12135 _38 = arg_5 + -1;
12136 mult_acc_51 = mult_acc_1 * arg_5;
12137 goto <bb 2> (initial);
12138
12139 # stack$0_52 = PHI <arg_5(2)>
12140instr9:
12141/* RETURN */:
12142 stack =@{v@} @{CLOBBER@};
12143 mul_tmp_44 = mult_acc_1 * stack$0_52;
12144 return mul_tmp_44;
12145
12146@}
12147@end example
12148
12149@noindent
12150
f1717362 12151@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
36b809a0 12152@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
12153@c
12154@c This is free software: you can redistribute it and/or modify it
12155@c under the terms of the GNU General Public License as published by
12156@c the Free Software Foundation, either version 3 of the License, or
12157@c (at your option) any later version.
12158@c
12159@c This program is distributed in the hope that it will be useful, but
12160@c WITHOUT ANY WARRANTY; without even the implied warranty of
12161@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12162@c General Public License for more details.
12163@c
12164@c You should have received a copy of the GNU General Public License
12165@c along with this program. If not, see
12166@c <http://www.gnu.org/licenses/>.
12167
12168@node Topic Reference<2>,,Tutorial<2>,C++ bindings for libgccjit
17c0b84b 12169@anchor{cp/topics/index doc}@anchor{12d}@anchor{cp/topics/index topic-reference}@anchor{12e}
36b809a0 12170@section Topic Reference
12171
12172
f1717362 12173@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
36b809a0 12174@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
12175@c
12176@c This is free software: you can redistribute it and/or modify it
12177@c under the terms of the GNU General Public License as published by
12178@c the Free Software Foundation, either version 3 of the License, or
12179@c (at your option) any later version.
12180@c
12181@c This program is distributed in the hope that it will be useful, but
12182@c WITHOUT ANY WARRANTY; without even the implied warranty of
12183@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12184@c General Public License for more details.
12185@c
12186@c You should have received a copy of the GNU General Public License
12187@c along with this program. If not, see
12188@c <http://www.gnu.org/licenses/>.
12189
12190@menu
12191* Compilation contexts: Compilation contexts<2>.
12192* Objects: Objects<2>.
12193* Types: Types<2>.
12194* Expressions: Expressions<2>.
12195* Creating and using functions: Creating and using functions<2>.
12196* Source Locations: Source Locations<2>.
69834ed9 12197* Compiling a context: Compiling a context<2>.
36b809a0 12198
12199Compilation contexts
12200
12201* Lifetime-management: Lifetime-management<2>.
12202* Thread-safety: Thread-safety<2>.
12203* Error-handling: Error-handling<3>.
12204* Debugging: Debugging<2>.
12205* Options: Options<4>.
12206
12207Options
12208
e5a6940a 12209* String Options: String Options<2>.
36b809a0 12210* Boolean options: Boolean options<2>.
12211* Integer options: Integer options<2>.
adb2df55 12212* Additional command-line options: Additional command-line options<2>.
36b809a0 12213
12214Types
12215
12216* Standard types: Standard types<2>.
12217* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>.
12218* Structures and unions: Structures and unions<2>.
12219
12220Expressions
12221
12222* Rvalues: Rvalues<2>.
12223* Lvalues: Lvalues<2>.
12224* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>.
12225
12226Rvalues
12227
12228* Simple expressions: Simple expressions<2>.
12229* Unary Operations: Unary Operations<2>.
12230* Binary Operations: Binary Operations<2>.
12231* Comparisons: Comparisons<2>.
12232* Function calls: Function calls<2>.
12233* Type-coercion: Type-coercion<2>.
12234
12235Lvalues
12236
12237* Global variables: Global variables<2>.
12238
12239Creating and using functions
12240
12241* Params: Params<2>.
12242* Functions: Functions<2>.
12243* Blocks: Blocks<2>.
12244* Statements: Statements<2>.
12245
12246Source Locations
12247
12248* Faking it: Faking it<2>.
12249
69834ed9 12250Compiling a context
12251
12252* In-memory compilation: In-memory compilation<2>.
12253* Ahead-of-time compilation: Ahead-of-time compilation<2>.
12254
36b809a0 12255@end menu
12256
12257
12258@node Compilation contexts<2>,Objects<2>,,Topic Reference<2>
17c0b84b 12259@anchor{cp/topics/contexts compilation-contexts}@anchor{12f}@anchor{cp/topics/contexts doc}@anchor{130}
36b809a0 12260@subsection Compilation contexts
12261
12262
12263@geindex gccjit;;context (C++ class)
17c0b84b 12264@anchor{cp/topics/contexts gccjit context}@anchor{131}
36b809a0 12265@deffn {C++ Class} gccjit::context
12266@end deffn
12267
17c0b84b 12268The top-level of the C++ API is the @pxref{131,,gccjit;;context} type.
36b809a0 12269
17c0b84b 12270A @pxref{131,,gccjit;;context} instance encapsulates the state of a
36b809a0 12271compilation.
12272
12273You can set up options on it, and add types, functions and code.
17c0b84b 12274Invoking @pxref{10a,,gccjit;;context;;compile()} on it gives you a
36b809a0 12275@pxref{16,,gcc_jit_result *}.
12276
12277It is a thin wrapper around the C API's @pxref{8,,gcc_jit_context *}.
12278
12279@menu
12280* Lifetime-management: Lifetime-management<2>.
12281* Thread-safety: Thread-safety<2>.
12282* Error-handling: Error-handling<3>.
12283* Debugging: Debugging<2>.
12284* Options: Options<4>.
12285
12286@end menu
12287
12288@node Lifetime-management<2>,Thread-safety<2>,,Compilation contexts<2>
17c0b84b 12289@anchor{cp/topics/contexts lifetime-management}@anchor{132}
36b809a0 12290@subsubsection Lifetime-management
12291
12292
12293Contexts are the unit of lifetime-management within the API: objects
12294have their lifetime bounded by the context they are created within, and
12295cleanup of such objects is done for you when the context is released.
12296
12297@geindex gccjit;;context;;acquire (C++ function)
17c0b84b 12298@anchor{cp/topics/contexts gccjit context acquire}@anchor{104}
36b809a0 12299@deffn {C++ Function} gccjit::context gccjit::context::acquire ()
12300
17c0b84b 12301This function acquires a new @pxref{131,,gccjit;;context} instance,
36b809a0 12302which is independent of any others that may be present within this
12303process.
12304@end deffn
12305
12306@geindex gccjit;;context;;release (C++ function)
17c0b84b 12307@anchor{cp/topics/contexts gccjit context release}@anchor{106}
36b809a0 12308@deffn {C++ Function} void gccjit::context::release ()
12309
12310This function releases all resources associated with the given context.
12311Both the context itself and all of its @code{gccjit::object *}
12312instances are cleaned up. It should be called exactly once on a given
12313context.
12314
12315It is invalid to use the context or any of its "contextual" objects
12316after calling this.
12317
12318@example
12319ctxt.release ();
12320@end example
12321
12322@noindent
12323@end deffn
12324
12325@geindex gccjit;;context;;new_child_context (C++ function)
17c0b84b 12326@anchor{cp/topics/contexts gccjit context new_child_context}@anchor{133}
36b809a0 12327@deffn {C++ Function} gccjit::context gccjit::context::new_child_context ()
12328
12329Given an existing JIT context, create a child context.
12330
12331The child inherits a copy of all option-settings from the parent.
12332
12333The child can reference objects created within the parent, but not
12334vice-versa.
12335
12336The lifetime of the child context must be bounded by that of the
12337parent: you should release a child context before releasing the parent
12338context.
12339
12340If you use a function from a parent context within a child context,
12341you have to compile the parent context before you can compile the
12342child context, and the gccjit::result of the parent context must
12343outlive the gccjit::result of the child context.
12344
12345This allows caching of shared initializations. For example, you could
12346create types and declarations of global functions in a parent context
12347once within a process, and then create child contexts whenever a
12348function or loop becomes hot. Each such child context can be used for
12349JIT-compiling just one function or loop, but can reference types
12350and helper functions created within the parent context.
12351
12352Contexts can be arbitrarily nested, provided the above rules are
12353followed, but it's probably not worth going above 2 or 3 levels, and
12354there will likely be a performance hit for such nesting.
12355@end deffn
12356
12357@node Thread-safety<2>,Error-handling<3>,Lifetime-management<2>,Compilation contexts<2>
17c0b84b 12358@anchor{cp/topics/contexts thread-safety}@anchor{134}
36b809a0 12359@subsubsection Thread-safety
12360
12361
17c0b84b 12362Instances of @pxref{131,,gccjit;;context} created via
12363@pxref{104,,gccjit;;context;;acquire()} are independent from each other:
36b809a0 12364only one thread may use a given context at once, but multiple threads
12365could each have their own contexts without needing locks.
12366
17c0b84b 12367Contexts created via @pxref{133,,gccjit;;context;;new_child_context()} are
36b809a0 12368related to their parent context. They can be partitioned by their
12369ultimate ancestor into independent "family trees". Only one thread
12370within a process may use a given "family tree" of such contexts at once,
12371and if you're using multiple threads you should provide your own locking
12372around entire such context partitions.
12373
12374@node Error-handling<3>,Debugging<2>,Thread-safety<2>,Compilation contexts<2>
17c0b84b 12375@anchor{cp/topics/contexts error-handling}@anchor{135}
36b809a0 12376@subsubsection Error-handling
12377
12378
12379@c FIXME: How does error-handling work for C++ API?
12380
12381You can only compile and get code from a context if no errors occur.
12382
12383In general, if an error occurs when using an API entrypoint, it returns
12384NULL. You don't have to check everywhere for NULL results, since the
12385API gracefully handles a NULL being passed in for any argument.
12386
12387Errors are printed on stderr and can be queried using
17c0b84b 12388@pxref{136,,gccjit;;context;;get_first_error()}.
36b809a0 12389
12390@geindex gccjit;;context;;get_first_error (C++ function)
17c0b84b 12391@anchor{cp/topics/contexts gccjit context get_first_error__gccjit contextP}@anchor{136}
36b809a0 12392@deffn {C++ Function} const char* gccjit::context::get_first_error (gccjit::context* ctxt)
12393
12394Returns the first error message that occurred on the context.
12395
12396The returned string is valid for the rest of the lifetime of the
12397context.
12398
12399If no errors occurred, this will be NULL.
12400@end deffn
12401
12402@node Debugging<2>,Options<4>,Error-handling<3>,Compilation contexts<2>
17c0b84b 12403@anchor{cp/topics/contexts debugging}@anchor{137}
36b809a0 12404@subsubsection Debugging
12405
12406
12407@geindex gccjit;;context;;dump_to_file (C++ function)
17c0b84b 12408@anchor{cp/topics/contexts gccjit context dump_to_file__ssCR i}@anchor{138}
36b809a0 12409@deffn {C++ Function} void gccjit::context::dump_to_file (const std::string& path, int update_locations)
12410
12411To help with debugging: dump a C-like representation to the given path,
12412describing what's been set up on the context.
12413
17c0b84b 12414If "update_locations" is true, then also set up @pxref{139,,gccjit;;location}
36b809a0 12415information throughout the context, pointing at the dump file as if it
12416were a source file. This may be of use in conjunction with
12417@code{GCCJIT::BOOL_OPTION_DEBUGINFO} to allow stepping through the
12418code in a debugger.
12419@end deffn
12420
c97b0d1d 12421@geindex gccjit;;context;;dump_reproducer_to_file (C++ function)
17c0b84b 12422@anchor{cp/topics/contexts gccjit context dump_reproducer_to_file__gcc_jit_contextP cCP}@anchor{13a}
c97b0d1d 12423@deffn {C++ Function} void gccjit::context::dump_reproducer_to_file (gcc_jit_context* ctxt, const char* path)
12424
12425This is a thin wrapper around the C API
69834ed9 12426@pxref{5d,,gcc_jit_context_dump_reproducer_to_file()}, and hence works the
c97b0d1d 12427same way.
12428
12429Note that the generated source is C code, not C++; this might be of use
12430for seeing what the C++ bindings are doing at the C level.
12431@end deffn
12432
36b809a0 12433@node Options<4>,,Debugging<2>,Compilation contexts<2>
17c0b84b 12434@anchor{cp/topics/contexts options}@anchor{13b}
36b809a0 12435@subsubsection Options
12436
12437
36b809a0 12438@menu
e5a6940a 12439* String Options: String Options<2>.
36b809a0 12440* Boolean options: Boolean options<2>.
12441* Integer options: Integer options<2>.
adb2df55 12442* Additional command-line options: Additional command-line options<2>.
36b809a0 12443
12444@end menu
12445
e5a6940a 12446@node String Options<2>,Boolean options<2>,,Options<4>
17c0b84b 12447@anchor{cp/topics/contexts string-options}@anchor{13c}
e5a6940a 12448@subsubsection String Options
12449
12450
12451@geindex gccjit;;context;;set_str_option (C++ function)
17c0b84b 12452@anchor{cp/topics/contexts gccjit context set_str_option__enum cCP}@anchor{13d}
e5a6940a 12453@deffn {C++ Function} void gccjit::context::set_str_option (enum gcc_jit_str_option, const char* value)
12454
12455Set a string option of the context.
12456
12457This is a thin wrapper around the C API
69834ed9 12458@pxref{61,,gcc_jit_context_set_str_option()}; the options have the same
e5a6940a 12459meaning.
12460@end deffn
12461
12462@node Boolean options<2>,Integer options<2>,String Options<2>,Options<4>
17c0b84b 12463@anchor{cp/topics/contexts boolean-options}@anchor{13e}
36b809a0 12464@subsubsection Boolean options
12465
12466
12467@geindex gccjit;;context;;set_bool_option (C++ function)
17c0b84b 12468@anchor{cp/topics/contexts gccjit context set_bool_option__enum i}@anchor{10c}
36b809a0 12469@deffn {C++ Function} void gccjit::context::set_bool_option (enum gcc_jit_bool_option, int value)
12470
12471Set a boolean option of the context.
12472
12473This is a thin wrapper around the C API
12474@pxref{1b,,gcc_jit_context_set_bool_option()}; the options have the same
12475meaning.
12476@end deffn
12477
04feb56e 12478@geindex gccjit;;context;;set_bool_allow_unreachable_blocks (C++ function)
17c0b84b 12479@anchor{cp/topics/contexts gccjit context set_bool_allow_unreachable_blocks__i}@anchor{13f}
04feb56e 12480@deffn {C++ Function} void gccjit::context::set_bool_allow_unreachable_blocks (int bool_value)
12481
12482By default, libgccjit will issue an error about unreachable blocks
12483within a function.
12484
12485This entrypoint can be used to disable that error; it is a thin wrapper
12486around the C API
12487@pxref{6b,,gcc_jit_context_set_bool_allow_unreachable_blocks()}.
12488
12489This entrypoint was added in @pxref{6c,,LIBGCCJIT_ABI_2}; you can test for
12490its presence using
12491
12492@example
12493#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks
12494@end example
12495
12496@noindent
12497@end deffn
12498
adb2df55 12499@node Integer options<2>,Additional command-line options<2>,Boolean options<2>,Options<4>
17c0b84b 12500@anchor{cp/topics/contexts integer-options}@anchor{140}
36b809a0 12501@subsubsection Integer options
12502
12503
12504@geindex gccjit;;context;;set_int_option (C++ function)
17c0b84b 12505@anchor{cp/topics/contexts gccjit context set_int_option__enum i}@anchor{10d}
36b809a0 12506@deffn {C++ Function} void gccjit::context::set_int_option (enum gcc_jit_int_option, int value)
12507
12508Set an integer option of the context.
12509
12510This is a thin wrapper around the C API
12511@pxref{1e,,gcc_jit_context_set_int_option()}; the options have the same
12512meaning.
12513@end deffn
12514
adb2df55 12515@node Additional command-line options<2>,,Integer options<2>,Options<4>
17c0b84b 12516@anchor{cp/topics/contexts additional-command-line-options}@anchor{141}
adb2df55 12517@subsubsection Additional command-line options
12518
12519
12520@geindex gccjit;;context;;add_command_line_option (C++ function)
17c0b84b 12521@anchor{cp/topics/contexts gccjit context add_command_line_option__cCP}@anchor{142}
adb2df55 12522@deffn {C++ Function} void gccjit::context::add_command_line_option (const char* optname)
12523
12524Add an arbitrary gcc command-line option to the context for use
12525when compiling.
12526
12527This is a thin wrapper around the C API
04feb56e 12528@pxref{70,,gcc_jit_context_add_command_line_option()}.
adb2df55 12529
04feb56e 12530This entrypoint was added in @pxref{71,,LIBGCCJIT_ABI_1}; you can test for
adb2df55 12531its presence using
12532
12533@example
12534#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option
12535@end example
12536
12537@noindent
12538@end deffn
12539
f1717362 12540@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
36b809a0 12541@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
12542@c
12543@c This is free software: you can redistribute it and/or modify it
12544@c under the terms of the GNU General Public License as published by
12545@c the Free Software Foundation, either version 3 of the License, or
12546@c (at your option) any later version.
12547@c
12548@c This program is distributed in the hope that it will be useful, but
12549@c WITHOUT ANY WARRANTY; without even the implied warranty of
12550@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12551@c General Public License for more details.
12552@c
12553@c You should have received a copy of the GNU General Public License
12554@c along with this program. If not, see
12555@c <http://www.gnu.org/licenses/>.
12556
12557@node Objects<2>,Types<2>,Compilation contexts<2>,Topic Reference<2>
17c0b84b 12558@anchor{cp/topics/objects objects}@anchor{143}@anchor{cp/topics/objects doc}@anchor{144}
36b809a0 12559@subsection Objects
12560
12561
12562@geindex gccjit;;object (C++ class)
17c0b84b 12563@anchor{cp/topics/objects gccjit object}@anchor{145}
36b809a0 12564@deffn {C++ Class} gccjit::object
12565@end deffn
12566
12567Almost every entity in the API (with the exception of
17c0b84b 12568@pxref{131,,gccjit;;context} and @pxref{16,,gcc_jit_result *}) is a
12569"contextual" object, a @pxref{145,,gccjit;;object}.
36b809a0 12570
12571A JIT object:
12572
12573@quotation
12574
12575
12576@itemize *
12577
12578@item
17c0b84b 12579is associated with a @pxref{131,,gccjit;;context}.
36b809a0 12580
12581@item
12582is automatically cleaned up for you when its context is released so
12583you don't need to manually track and cleanup all objects, just the
12584contexts.
12585@end itemize
12586@end quotation
12587
12588The C++ class hierarchy within the @code{gccjit} namespace looks like this:
12589
12590@example
12591+- object
12592 +- location
12593 +- type
12594 +- struct
12595 +- field
12596 +- function
12597 +- block
12598 +- rvalue
12599 +- lvalue
12600 +- param
a24ef8d2 12601 +- case_
36b809a0 12602@end example
12603
12604@noindent
12605
17c0b84b 12606The @pxref{145,,gccjit;;object} base class has the following operations:
36b809a0 12607
12608@geindex gccjit;;object;;get_context (C++ function)
17c0b84b 12609@anchor{cp/topics/objects gccjit object get_contextC}@anchor{146}
36b809a0 12610@deffn {C++ Function} gccjit::context gccjit::object::get_context () const
12611
12612Which context is the obj within?
12613@end deffn
12614
12615@geindex gccjit;;object;;get_debug_string (C++ function)
17c0b84b 12616@anchor{cp/topics/objects gccjit object get_debug_stringC}@anchor{107}
36b809a0 12617@deffn {C++ Function} std::string gccjit::object::get_debug_string () const
12618
12619Generate a human-readable description for the given object.
12620
12621For example,
12622
12623@example
12624printf ("obj: %s\n", obj.get_debug_string ().c_str ());
12625@end example
12626
12627@noindent
12628
12629might give this text on stdout:
12630
12631@example
12632obj: 4.0 * (float)i
12633@end example
12634
12635@noindent
12636@end deffn
12637
f1717362 12638@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
36b809a0 12639@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
12640@c
12641@c This is free software: you can redistribute it and/or modify it
12642@c under the terms of the GNU General Public License as published by
12643@c the Free Software Foundation, either version 3 of the License, or
12644@c (at your option) any later version.
12645@c
12646@c This program is distributed in the hope that it will be useful, but
12647@c WITHOUT ANY WARRANTY; without even the implied warranty of
12648@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12649@c General Public License for more details.
12650@c
12651@c You should have received a copy of the GNU General Public License
12652@c along with this program. If not, see
12653@c <http://www.gnu.org/licenses/>.
12654
12655@node Types<2>,Expressions<2>,Objects<2>,Topic Reference<2>
17c0b84b 12656@anchor{cp/topics/types doc}@anchor{147}@anchor{cp/topics/types types}@anchor{148}
36b809a0 12657@subsection Types
12658
12659
12660@geindex gccjit;;type (C++ class)
17c0b84b 12661@anchor{cp/topics/types gccjit type}@anchor{149}
36b809a0 12662@deffn {C++ Class} gccjit::type
12663
12664gccjit::type represents a type within the library. It is a subclass
17c0b84b 12665of @pxref{145,,gccjit;;object}.
36b809a0 12666@end deffn
12667
12668Types can be created in several ways:
12669
12670
12671@itemize *
12672
12673@item
12674fundamental types can be accessed using
17c0b84b 12675@pxref{105,,gccjit;;context;;get_type()}:
36b809a0 12676
12677@example
12678gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT);
12679@end example
12680
12681@noindent
12682
12683or using the @code{gccjit::context::get_int_type} template:
12684
12685@example
12686gccjit::type t = ctxt.get_int_type <unsigned short> ();
12687@end example
12688
12689@noindent
12690
12691See @pxref{b,,gcc_jit_context_get_type()} for the available types.
12692
12693@item
12694derived types can be accessed by using functions such as
17c0b84b 12695@pxref{14a,,gccjit;;type;;get_pointer()} and @pxref{14b,,gccjit;;type;;get_const()}:
36b809a0 12696
12697@example
12698gccjit::type const_int_star = int_type.get_const ().get_pointer ();
12699gccjit::type int_const_star = int_type.get_pointer ().get_const ();
12700@end example
12701
12702@noindent
12703
12704@item
12705by creating structures (see below).
12706@end itemize
12707
12708@menu
12709* Standard types: Standard types<2>.
12710* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>.
12711* Structures and unions: Structures and unions<2>.
12712
12713@end menu
12714
12715@node Standard types<2>,Pointers const and volatile<2>,,Types<2>
17c0b84b 12716@anchor{cp/topics/types standard-types}@anchor{14c}
36b809a0 12717@subsubsection Standard types
12718
12719
12720@geindex gccjit;;context;;get_type (C++ function)
17c0b84b 12721@anchor{cp/topics/types gccjit context get_type__enum}@anchor{105}
36b809a0 12722@deffn {C++ Function} gccjit::type gccjit::context::get_type (enum gcc_jit_types)
12723
12724Access a specific type. This is a thin wrapper around
12725@pxref{b,,gcc_jit_context_get_type()}; the parameter has the same meaning.
12726@end deffn
12727
12728@geindex gccjit;;context;;get_int_type (C++ function)
17c0b84b 12729@anchor{cp/topics/types gccjit context get_int_type__s i}@anchor{14d}
36b809a0 12730@deffn {C++ Function} gccjit::type gccjit::context::get_int_type (size_t num_bytes, int is_signed)
12731
12732Access the integer type of the given size.
12733@end deffn
12734
12735@geindex gccjit;;context;;get_int_type<T> (C++ function)
17c0b84b 12736@anchor{cp/topics/types gccjit context get_int_type T}@anchor{14e}
36b809a0 12737@deffn {C++ Function} gccjit::type gccjit::context::get_int_type<T> ()
12738
12739Access the given integer type. For example, you could map the
12740@code{unsigned short} type into a gccjit::type via:
12741
12742@example
12743gccjit::type t = ctxt.get_int_type <unsigned short> ();
12744@end example
12745
12746@noindent
12747@end deffn
12748
12749@node Pointers const and volatile<2>,Structures and unions<2>,Standard types<2>,Types<2>
17c0b84b 12750@anchor{cp/topics/types pointers-const-and-volatile}@anchor{14f}
36b809a0 12751@subsubsection Pointers, @cite{const}, and @cite{volatile}
12752
12753
12754@geindex gccjit;;type;;get_pointer (C++ function)
17c0b84b 12755@anchor{cp/topics/types gccjit type get_pointer}@anchor{14a}
36b809a0 12756@deffn {C++ Function} gccjit::type gccjit::type::get_pointer ()
12757
12758Given type "T", get type "T*".
12759@end deffn
12760
12761@c FIXME: get_const doesn't seem to exist
12762
12763@geindex gccjit;;type;;get_const (C++ function)
17c0b84b 12764@anchor{cp/topics/types gccjit type get_const}@anchor{14b}
36b809a0 12765@deffn {C++ Function} gccjit::type gccjit::type::get_const ()
12766
12767Given type "T", get type "const T".
12768@end deffn
12769
12770@geindex gccjit;;type;;get_volatile (C++ function)
17c0b84b 12771@anchor{cp/topics/types gccjit type get_volatile}@anchor{150}
36b809a0 12772@deffn {C++ Function} gccjit::type gccjit::type::get_volatile ()
12773
12774Given type "T", get type "volatile T".
12775@end deffn
12776
12777@geindex gccjit;;context;;new_array_type (C++ function)
17c0b84b 12778@anchor{cp/topics/types gccjit context new_array_type__gccjit type i gccjit location}@anchor{151}
36b809a0 12779@deffn {C++ Function} gccjit::type gccjit::context::new_array_type (gccjit::type element_type, int num_elements, gccjit::location loc)
12780
12781Given type "T", get type "T[N]" (for a constant N).
12782Param "loc" is optional.
12783@end deffn
12784
12785@node Structures and unions<2>,,Pointers const and volatile<2>,Types<2>
17c0b84b 12786@anchor{cp/topics/types structures-and-unions}@anchor{152}
36b809a0 12787@subsubsection Structures and unions
12788
12789
12790@geindex gccjit;;struct_ (C++ class)
17c0b84b 12791@anchor{cp/topics/types gccjit struct_}@anchor{153}
36b809a0 12792@deffn {C++ Class} gccjit::struct_
12793@end deffn
12794
12795A compound type analagous to a C @cite{struct}.
12796
17c0b84b 12797@pxref{153,,gccjit;;struct_} is a subclass of @pxref{149,,gccjit;;type} (and thus
12798of @pxref{145,,gccjit;;object} in turn).
36b809a0 12799
12800@geindex gccjit;;field (C++ class)
17c0b84b 12801@anchor{cp/topics/types gccjit field}@anchor{154}
36b809a0 12802@deffn {C++ Class} gccjit::field
12803@end deffn
12804
17c0b84b 12805A field within a @pxref{153,,gccjit;;struct_}.
36b809a0 12806
17c0b84b 12807@pxref{154,,gccjit;;field} is a subclass of @pxref{145,,gccjit;;object}.
36b809a0 12808
17c0b84b 12809You can model C @cite{struct} types by creating @pxref{153,,gccjit;;struct_} and
12810@pxref{154,,gccjit;;field} instances, in either order:
36b809a0 12811
12812
12813@itemize *
12814
12815@item
12816by creating the fields, then the structure. For example, to model:
12817
12818@example
12819struct coord @{double x; double y; @};
12820@end example
12821
12822@noindent
12823
12824you could call:
12825
12826@example
12827gccjit::field field_x = ctxt.new_field (double_type, "x");
12828gccjit::field field_y = ctxt.new_field (double_type, "y");
12829std::vector fields;
12830fields.push_back (field_x);
12831fields.push_back (field_y);
12832gccjit::struct_ coord = ctxt.new_struct_type ("coord", fields);
12833@end example
12834
12835@noindent
12836
12837@item
12838by creating the structure, then populating it with fields, typically
12839to allow modelling self-referential structs such as:
12840
12841@example
12842struct node @{ int m_hash; struct node *m_next; @};
12843@end example
12844
12845@noindent
12846
12847like this:
12848
12849@example
12850gccjit::struct_ node = ctxt.new_opaque_struct_type ("node");
12851gccjit::type node_ptr = node.get_pointer ();
12852gccjit::field field_hash = ctxt.new_field (int_type, "m_hash");
12853gccjit::field field_next = ctxt.new_field (node_ptr, "m_next");
12854std::vector fields;
12855fields.push_back (field_hash);
12856fields.push_back (field_next);
12857node.set_fields (fields);
12858@end example
12859
12860@noindent
12861@end itemize
12862
12863@c FIXME: the above API doesn't seem to exist yet
12864
12865@geindex gccjit;;context;;new_field (C++ function)
17c0b84b 12866@anchor{cp/topics/types gccjit context new_field__gccjit type cCP gccjit location}@anchor{155}
36b809a0 12867@deffn {C++ Function} gccjit::field gccjit::context::new_field (gccjit::type type, const char* name, gccjit::location loc)
12868
12869Construct a new field, with the given type and name.
12870@end deffn
12871
12872@geindex gccjit;;context;;new_struct_type (C++ function)
17c0b84b 12873@anchor{cp/topics/types gccjit context new_struct_type__ssCR std vector field R gccjit location}@anchor{156}
36b809a0 12874@deffn {C++ Function} gccjit::struct_ gccjit::context::new_struct_type (const std::string& name, std::vector<field>& fields, gccjit::location loc)
12875
12876@quotation
12877
12878Construct a new struct type, with the given name and fields.
12879@end quotation
12880@end deffn
12881
12882@geindex gccjit;;context;;new_opaque_struct (C++ function)
17c0b84b 12883@anchor{cp/topics/types gccjit context new_opaque_struct__ssCR gccjit location}@anchor{157}
36b809a0 12884@deffn {C++ Function} gccjit::struct_ gccjit::context::new_opaque_struct (const std::string& name, gccjit::location loc)
12885
12886Construct a new struct type, with the given name, but without
12887specifying the fields. The fields can be omitted (in which case the
12888size of the struct is not known), or later specified using
04feb56e 12889@pxref{85,,gcc_jit_struct_set_fields()}.
36b809a0 12890@end deffn
12891
f1717362 12892@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
36b809a0 12893@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
12894@c
12895@c This is free software: you can redistribute it and/or modify it
12896@c under the terms of the GNU General Public License as published by
12897@c the Free Software Foundation, either version 3 of the License, or
12898@c (at your option) any later version.
12899@c
12900@c This program is distributed in the hope that it will be useful, but
12901@c WITHOUT ANY WARRANTY; without even the implied warranty of
12902@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12903@c General Public License for more details.
12904@c
12905@c You should have received a copy of the GNU General Public License
12906@c along with this program. If not, see
12907@c <http://www.gnu.org/licenses/>.
12908
12909@node Expressions<2>,Creating and using functions<2>,Types<2>,Topic Reference<2>
17c0b84b 12910@anchor{cp/topics/expressions expressions}@anchor{158}@anchor{cp/topics/expressions doc}@anchor{159}
36b809a0 12911@subsection Expressions
12912
12913
12914@menu
12915* Rvalues: Rvalues<2>.
12916* Lvalues: Lvalues<2>.
12917* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>.
12918
12919Rvalues
12920
12921* Simple expressions: Simple expressions<2>.
12922* Unary Operations: Unary Operations<2>.
12923* Binary Operations: Binary Operations<2>.
12924* Comparisons: Comparisons<2>.
12925* Function calls: Function calls<2>.
12926* Type-coercion: Type-coercion<2>.
12927
12928Lvalues
12929
12930* Global variables: Global variables<2>.
12931
12932@end menu
12933
12934
12935@node Rvalues<2>,Lvalues<2>,,Expressions<2>
17c0b84b 12936@anchor{cp/topics/expressions rvalues}@anchor{15a}
36b809a0 12937@subsubsection Rvalues
12938
12939
12940@geindex gccjit;;rvalue (C++ class)
17c0b84b 12941@anchor{cp/topics/expressions gccjit rvalue}@anchor{15b}
36b809a0 12942@deffn {C++ Class} gccjit::rvalue
12943@end deffn
12944
17c0b84b 12945A @pxref{15b,,gccjit;;rvalue} is an expression that can be computed. It is a
12946subclass of @pxref{145,,gccjit;;object}, and is a thin wrapper around
36b809a0 12947@pxref{13,,gcc_jit_rvalue *} from the C API.
12948
12949It can be simple, e.g.:
12950
12951@quotation
12952
12953
12954@itemize *
12955
12956@item
12957an integer value e.g. @cite{0} or @cite{42}
12958
12959@item
12960a string literal e.g. @cite{"Hello world"}
12961
12962@item
12963a variable e.g. @cite{i}. These are also lvalues (see below).
12964@end itemize
12965@end quotation
12966
12967or compound e.g.:
12968
12969@quotation
12970
12971
12972@itemize *
12973
12974@item
12975a unary expression e.g. @cite{!cond}
12976
12977@item
12978a binary expression e.g. @cite{(a + b)}
12979
12980@item
12981a function call e.g. @cite{get_distance (&player_ship@comma{} &target)}
12982
12983@item
12984etc.
12985@end itemize
12986@end quotation
12987
12988Every rvalue has an associated type, and the API will check to ensure
12989that types match up correctly (otherwise the context will emit an error).
12990
12991@geindex gccjit;;rvalue;;get_type (C++ function)
17c0b84b 12992@anchor{cp/topics/expressions gccjit rvalue get_type}@anchor{15c}
36b809a0 12993@deffn {C++ Function} gccjit::type gccjit::rvalue::get_type ()
12994
12995Get the type of this rvalue.
12996@end deffn
12997
12998@menu
12999* Simple expressions: Simple expressions<2>.
13000* Unary Operations: Unary Operations<2>.
13001* Binary Operations: Binary Operations<2>.
13002* Comparisons: Comparisons<2>.
13003* Function calls: Function calls<2>.
13004* Type-coercion: Type-coercion<2>.
13005
13006@end menu
13007
13008@node Simple expressions<2>,Unary Operations<2>,,Rvalues<2>
17c0b84b 13009@anchor{cp/topics/expressions simple-expressions}@anchor{15d}
36b809a0 13010@subsubsection Simple expressions
13011
13012
13013@geindex gccjit;;context;;new_rvalue (C++ function)
17c0b84b 13014@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type iC}@anchor{119}
36b809a0 13015@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, int value) const
13016
13017Given a numeric type (integer or floating point), build an rvalue for
13018the given constant @code{int} value.
13019@end deffn
13020
feea5a1f 13021@geindex gccjit;;context;;new_rvalue (C++ function)
17c0b84b 13022@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type lC}@anchor{15e}
feea5a1f 13023@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, long value) const
13024
13025Given a numeric type (integer or floating point), build an rvalue for
13026the given constant @code{long} value.
13027@end deffn
13028
36b809a0 13029@geindex gccjit;;context;;zero (C++ function)
17c0b84b 13030@anchor{cp/topics/expressions gccjit context zero__gccjit typeC}@anchor{115}
36b809a0 13031@deffn {C++ Function} gccjit::rvalue gccjit::context::zero (gccjit::type numeric_type) const
13032
13033Given a numeric type (integer or floating point), get the rvalue for
13034zero. Essentially this is just a shortcut for:
13035
13036@example
13037ctxt.new_rvalue (numeric_type, 0)
13038@end example
13039
13040@noindent
13041@end deffn
13042
13043@geindex gccjit;;context;;one (C++ function)
17c0b84b 13044@anchor{cp/topics/expressions gccjit context one__gccjit typeC}@anchor{15f}
36b809a0 13045@deffn {C++ Function} gccjit::rvalue gccjit::context::one (gccjit::type numeric_type) const
13046
13047Given a numeric type (integer or floating point), get the rvalue for
e954f824 13048one. Essentially this is just a shortcut for:
36b809a0 13049
13050@example
13051ctxt.new_rvalue (numeric_type, 1)
13052@end example
13053
13054@noindent
13055@end deffn
13056
13057@geindex gccjit;;context;;new_rvalue (C++ function)
17c0b84b 13058@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type doubleC}@anchor{160}
36b809a0 13059@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, double value) const
13060
13061Given a numeric type (integer or floating point), build an rvalue for
feea5a1f 13062the given constant @code{double} value.
36b809a0 13063@end deffn
13064
13065@geindex gccjit;;context;;new_rvalue (C++ function)
17c0b84b 13066@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type voidPC}@anchor{161}
36b809a0 13067@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type pointer_type, void* value) const
13068
13069Given a pointer type, build an rvalue for the given address.
13070@end deffn
13071
13072@geindex gccjit;;context;;new_rvalue (C++ function)
17c0b84b 13073@anchor{cp/topics/expressions gccjit context new_rvalue__ssCRC}@anchor{162}
36b809a0 13074@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (const std::string& value) const
13075
13076Generate an rvalue of type @code{GCC_JIT_TYPE_CONST_CHAR_PTR} for
13077the given string. This is akin to a string literal.
13078@end deffn
13079
13080@node Unary Operations<2>,Binary Operations<2>,Simple expressions<2>,Rvalues<2>
17c0b84b 13081@anchor{cp/topics/expressions unary-operations}@anchor{163}
36b809a0 13082@subsubsection Unary Operations
13083
13084
13085@geindex gccjit;;context;;new_unary_op (C++ function)
17c0b84b 13086@anchor{cp/topics/expressions gccjit context new_unary_op__enum gccjit type gccjit rvalue gccjit location}@anchor{164}
36b809a0 13087@deffn {C++ Function} gccjit::rvalue gccjit::context::new_unary_op (enum gcc_jit_unary_op, gccjit::type result_type, gccjit::rvalue rvalue, gccjit::location loc)
13088
13089Build a unary operation out of an input rvalue.
13090
13091Parameter @code{loc} is optional.
13092
13093This is a thin wrapper around the C API's
eb2d3e4a 13094@pxref{92,,gcc_jit_context_new_unary_op()} and the available unary
36b809a0 13095operations are documented there.
13096@end deffn
13097
13098There are shorter ways to spell the various specific kinds of unary
13099operation:
13100
13101@geindex gccjit;;context;;new_minus (C++ function)
17c0b84b 13102@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit location}@anchor{165}
36b809a0 13103@deffn {C++ Function} gccjit::rvalue gccjit::context::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)
13104
13105Negate an arithmetic value; for example:
13106
13107@example
13108gccjit::rvalue negpi = ctxt.new_minus (t_double, pi);
13109@end example
13110
13111@noindent
13112
13113builds the equivalent of this C expression:
13114
13115@example
13116-pi
13117@end example
13118
13119@noindent
13120@end deffn
13121
13122@geindex new_bitwise_negate (C++ function)
17c0b84b 13123@anchor{cp/topics/expressions new_bitwise_negate__gccjit type gccjit rvalue gccjit location}@anchor{166}
36b809a0 13124@deffn {C++ Function} gccjit::rvalue new_bitwise_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)
13125
13126Bitwise negation of an integer value (one's complement); for example:
13127
13128@example
13129gccjit::rvalue mask = ctxt.new_bitwise_negate (t_int, a);
13130@end example
13131
13132@noindent
13133
13134builds the equivalent of this C expression:
13135
13136@example
13137~a
13138@end example
13139
13140@noindent
13141@end deffn
13142
13143@geindex new_logical_negate (C++ function)
17c0b84b 13144@anchor{cp/topics/expressions new_logical_negate__gccjit type gccjit rvalue gccjit location}@anchor{167}
36b809a0 13145@deffn {C++ Function} gccjit::rvalue new_logical_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)
13146
13147Logical negation of an arithmetic or pointer value; for example:
13148
13149@example
13150gccjit::rvalue guard = ctxt.new_logical_negate (t_bool, cond);
13151@end example
13152
13153@noindent
13154
13155builds the equivalent of this C expression:
13156
13157@example
13158!cond
13159@end example
13160
13161@noindent
13162@end deffn
13163
13164The most concise way to spell them is with overloaded operators:
13165
13166@geindex operator- (C++ function)
17c0b84b 13167@anchor{cp/topics/expressions sub-operator__gccjit rvalue}@anchor{168}
36b809a0 13168@deffn {C++ Function} gccjit::rvalue operator- (gccjit::rvalue a)
13169
13170@example
13171gccjit::rvalue negpi = -pi;
13172@end example
13173
13174@noindent
13175@end deffn
13176
13177@geindex operator~ (C++ function)
17c0b84b 13178@anchor{cp/topics/expressions inv-operator__gccjit rvalue}@anchor{169}
36b809a0 13179@deffn {C++ Function} gccjit::rvalue operator~ (gccjit::rvalue a)
13180
13181@example
13182gccjit::rvalue mask = ~a;
13183@end example
13184
13185@noindent
13186@end deffn
13187
13188@geindex operator! (C++ function)
17c0b84b 13189@anchor{cp/topics/expressions not-operator__gccjit rvalue}@anchor{16a}
36b809a0 13190@deffn {C++ Function} gccjit::rvalue operator! (gccjit::rvalue a)
13191
13192@example
13193gccjit::rvalue guard = !cond;
13194@end example
13195
13196@noindent
13197@end deffn
13198
13199@node Binary Operations<2>,Comparisons<2>,Unary Operations<2>,Rvalues<2>
17c0b84b 13200@anchor{cp/topics/expressions binary-operations}@anchor{16b}
36b809a0 13201@subsubsection Binary Operations
13202
13203
13204@geindex gccjit;;context;;new_binary_op (C++ function)
17c0b84b 13205@anchor{cp/topics/expressions gccjit context new_binary_op__enum gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{109}
36b809a0 13206@deffn {C++ Function} gccjit::rvalue gccjit::context::new_binary_op (enum gcc_jit_binary_op, gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13207
13208Build a binary operation out of two constituent rvalues.
13209
13210Parameter @code{loc} is optional.
13211
13212This is a thin wrapper around the C API's
13213@pxref{12,,gcc_jit_context_new_binary_op()} and the available binary
13214operations are documented there.
13215@end deffn
13216
13217There are shorter ways to spell the various specific kinds of binary
13218operation:
13219
13220@geindex gccjit;;context;;new_plus (C++ function)
17c0b84b 13221@anchor{cp/topics/expressions gccjit context new_plus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{16c}
36b809a0 13222@deffn {C++ Function} gccjit::rvalue gccjit::context::new_plus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13223@end deffn
13224
13225@geindex gccjit;;context;;new_minus (C++ function)
17c0b84b 13226@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{16d}
36b809a0 13227@deffn {C++ Function} gccjit::rvalue gccjit::context::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13228@end deffn
13229
13230@geindex gccjit;;context;;new_mult (C++ function)
17c0b84b 13231@anchor{cp/topics/expressions gccjit context new_mult__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{16e}
36b809a0 13232@deffn {C++ Function} gccjit::rvalue gccjit::context::new_mult (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13233@end deffn
13234
13235@geindex gccjit;;context;;new_divide (C++ function)
17c0b84b 13236@anchor{cp/topics/expressions gccjit context new_divide__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{16f}
36b809a0 13237@deffn {C++ Function} gccjit::rvalue gccjit::context::new_divide (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13238@end deffn
13239
13240@geindex gccjit;;context;;new_modulo (C++ function)
17c0b84b 13241@anchor{cp/topics/expressions gccjit context new_modulo__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{170}
36b809a0 13242@deffn {C++ Function} gccjit::rvalue gccjit::context::new_modulo (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13243@end deffn
13244
13245@geindex gccjit;;context;;new_bitwise_and (C++ function)
17c0b84b 13246@anchor{cp/topics/expressions gccjit context new_bitwise_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{171}
36b809a0 13247@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13248@end deffn
13249
13250@geindex gccjit;;context;;new_bitwise_xor (C++ function)
17c0b84b 13251@anchor{cp/topics/expressions gccjit context new_bitwise_xor__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{172}
36b809a0 13252@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_xor (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13253@end deffn
13254
13255@geindex gccjit;;context;;new_bitwise_or (C++ function)
17c0b84b 13256@anchor{cp/topics/expressions gccjit context new_bitwise_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{173}
36b809a0 13257@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13258@end deffn
13259
13260@geindex gccjit;;context;;new_logical_and (C++ function)
17c0b84b 13261@anchor{cp/topics/expressions gccjit context new_logical_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{174}
36b809a0 13262@deffn {C++ Function} gccjit::rvalue gccjit::context::new_logical_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13263@end deffn
13264
13265@geindex gccjit;;context;;new_logical_or (C++ function)
17c0b84b 13266@anchor{cp/topics/expressions gccjit context new_logical_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{175}
36b809a0 13267@deffn {C++ Function} gccjit::rvalue gccjit::context::new_logical_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13268@end deffn
13269
13270The most concise way to spell them is with overloaded operators:
13271
13272@geindex operator+ (C++ function)
17c0b84b 13273@anchor{cp/topics/expressions add-operator__gccjit rvalue gccjit rvalue}@anchor{176}
36b809a0 13274@deffn {C++ Function} gccjit::rvalue operator+ (gccjit::rvalue a, gccjit::rvalue b)
13275
13276@example
13277gccjit::rvalue sum = a + b;
13278@end example
13279
13280@noindent
13281@end deffn
13282
13283@geindex operator- (C++ function)
17c0b84b 13284@anchor{cp/topics/expressions sub-operator__gccjit rvalue gccjit rvalue}@anchor{177}
36b809a0 13285@deffn {C++ Function} gccjit::rvalue operator- (gccjit::rvalue a, gccjit::rvalue b)
13286
13287@example
13288gccjit::rvalue diff = a - b;
13289@end example
13290
13291@noindent
13292@end deffn
13293
13294@geindex operator* (C++ function)
17c0b84b 13295@anchor{cp/topics/expressions mul-operator__gccjit rvalue gccjit rvalue}@anchor{178}
36b809a0 13296@deffn {C++ Function} gccjit::rvalue operator* (gccjit::rvalue a, gccjit::rvalue b)
13297
13298@example
13299gccjit::rvalue prod = a * b;
13300@end example
13301
13302@noindent
13303@end deffn
13304
13305@geindex operator/ (C++ function)
17c0b84b 13306@anchor{cp/topics/expressions div-operator__gccjit rvalue gccjit rvalue}@anchor{179}
36b809a0 13307@deffn {C++ Function} gccjit::rvalue operator/ (gccjit::rvalue a, gccjit::rvalue b)
13308
13309@example
13310gccjit::rvalue result = a / b;
13311@end example
13312
13313@noindent
13314@end deffn
13315
13316@geindex operator% (C++ function)
17c0b84b 13317@anchor{cp/topics/expressions mod-operator__gccjit rvalue gccjit rvalue}@anchor{17a}
36b809a0 13318@deffn {C++ Function} gccjit::rvalue operator% (gccjit::rvalue a, gccjit::rvalue b)
13319
13320@example
13321gccjit::rvalue mod = a % b;
13322@end example
13323
13324@noindent
13325@end deffn
13326
13327@geindex operator& (C++ function)
17c0b84b 13328@anchor{cp/topics/expressions and-operator__gccjit rvalue gccjit rvalue}@anchor{17b}
36b809a0 13329@deffn {C++ Function} gccjit::rvalue operator& (gccjit::rvalue a, gccjit::rvalue b)
13330
13331@example
13332gccjit::rvalue x = a & b;
13333@end example
13334
13335@noindent
13336@end deffn
13337
13338@geindex operator^ (C++ function)
17c0b84b 13339@anchor{cp/topics/expressions xor-operator__gccjit rvalue gccjit rvalue}@anchor{17c}
36b809a0 13340@deffn {C++ Function} gccjit::rvalue operator^ (gccjit::rvalue a, gccjit::rvalue b)
13341
13342@example
13343gccjit::rvalue x = a ^ b;
13344@end example
13345
13346@noindent
13347@end deffn
13348
13349@geindex operator| (C++ function)
17c0b84b 13350@anchor{cp/topics/expressions or-operator__gccjit rvalue gccjit rvalue}@anchor{17d}
36b809a0 13351@deffn {C++ Function} gccjit::rvalue operator| (gccjit::rvalue a, gccjit::rvalue b)
13352
13353@example
13354gccjit::rvalue x = a | b;
13355@end example
13356
13357@noindent
13358@end deffn
13359
13360@geindex operator&& (C++ function)
17c0b84b 13361@anchor{cp/topics/expressions sand-operator__gccjit rvalue gccjit rvalue}@anchor{17e}
36b809a0 13362@deffn {C++ Function} gccjit::rvalue operator&& (gccjit::rvalue a, gccjit::rvalue b)
13363
13364@example
13365gccjit::rvalue cond = a && b;
13366@end example
13367
13368@noindent
13369@end deffn
13370
13371@geindex operator|| (C++ function)
17c0b84b 13372@anchor{cp/topics/expressions sor-operator__gccjit rvalue gccjit rvalue}@anchor{17f}
36b809a0 13373@deffn {C++ Function} gccjit::rvalue operator|| (gccjit::rvalue a, gccjit::rvalue b)
13374
13375@example
13376gccjit::rvalue cond = a || b;
13377@end example
13378
13379@noindent
13380@end deffn
13381
13382These can of course be combined, giving a terse way to build compound
13383expressions:
13384
13385@quotation
13386
13387@example
13388gccjit::rvalue discriminant = (b * b) - (four * a * c);
13389@end example
13390
13391@noindent
13392@end quotation
13393
13394@node Comparisons<2>,Function calls<2>,Binary Operations<2>,Rvalues<2>
17c0b84b 13395@anchor{cp/topics/expressions comparisons}@anchor{180}
36b809a0 13396@subsubsection Comparisons
13397
13398
13399@geindex gccjit;;context;;new_comparison (C++ function)
17c0b84b 13400@anchor{cp/topics/expressions gccjit context new_comparison__enum gccjit rvalue gccjit rvalue gccjit location}@anchor{116}
36b809a0 13401@deffn {C++ Function} gccjit::rvalue gccjit::context::new_comparison (enum gcc_jit_comparison, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13402
13403Build a boolean rvalue out of the comparison of two other rvalues.
13404
13405Parameter @code{loc} is optional.
13406
13407This is a thin wrapper around the C API's
13408@pxref{2c,,gcc_jit_context_new_comparison()} and the available kinds
13409of comparison are documented there.
13410@end deffn
13411
13412There are shorter ways to spell the various specific kinds of binary
13413operation:
13414
13415@geindex gccjit;;context;;new_eq (C++ function)
17c0b84b 13416@anchor{cp/topics/expressions gccjit context new_eq__gccjit rvalue gccjit rvalue gccjit location}@anchor{181}
36b809a0 13417@deffn {C++ Function} gccjit::rvalue gccjit::context::new_eq (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13418@end deffn
13419
13420@geindex gccjit;;context;;new_ne (C++ function)
17c0b84b 13421@anchor{cp/topics/expressions gccjit context new_ne__gccjit rvalue gccjit rvalue gccjit location}@anchor{182}
36b809a0 13422@deffn {C++ Function} gccjit::rvalue gccjit::context::new_ne (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13423@end deffn
13424
13425@geindex gccjit;;context;;new_lt (C++ function)
17c0b84b 13426@anchor{cp/topics/expressions gccjit context new_lt__gccjit rvalue gccjit rvalue gccjit location}@anchor{183}
36b809a0 13427@deffn {C++ Function} gccjit::rvalue gccjit::context::new_lt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13428@end deffn
13429
13430@geindex gccjit;;context;;new_le (C++ function)
17c0b84b 13431@anchor{cp/topics/expressions gccjit context new_le__gccjit rvalue gccjit rvalue gccjit location}@anchor{184}
36b809a0 13432@deffn {C++ Function} gccjit::rvalue gccjit::context::new_le (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13433@end deffn
13434
13435@geindex gccjit;;context;;new_gt (C++ function)
17c0b84b 13436@anchor{cp/topics/expressions gccjit context new_gt__gccjit rvalue gccjit rvalue gccjit location}@anchor{185}
36b809a0 13437@deffn {C++ Function} gccjit::rvalue gccjit::context::new_gt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13438@end deffn
13439
13440@geindex gccjit;;context;;new_ge (C++ function)
17c0b84b 13441@anchor{cp/topics/expressions gccjit context new_ge__gccjit rvalue gccjit rvalue gccjit location}@anchor{186}
36b809a0 13442@deffn {C++ Function} gccjit::rvalue gccjit::context::new_ge (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
13443@end deffn
13444
13445The most concise way to spell them is with overloaded operators:
13446
13447@geindex operator== (C++ function)
17c0b84b 13448@anchor{cp/topics/expressions eq-operator__gccjit rvalue gccjit rvalue}@anchor{187}
36b809a0 13449@deffn {C++ Function} gccjit::rvalue operator== (gccjit::rvalue a, gccjit::rvalue b)
13450
13451@example
13452gccjit::rvalue cond = (a == ctxt.zero (t_int));
13453@end example
13454
13455@noindent
13456@end deffn
13457
13458@geindex operator!= (C++ function)
17c0b84b 13459@anchor{cp/topics/expressions neq-operator__gccjit rvalue gccjit rvalue}@anchor{188}
36b809a0 13460@deffn {C++ Function} gccjit::rvalue operator!= (gccjit::rvalue a, gccjit::rvalue b)
13461
13462@example
13463gccjit::rvalue cond = (i != j);
13464@end example
13465
13466@noindent
13467@end deffn
13468
13469@geindex operator< (C++ function)
17c0b84b 13470@anchor{cp/topics/expressions lt-operator__gccjit rvalue gccjit rvalue}@anchor{189}
36b809a0 13471@deffn {C++ Function} gccjit::rvalue operator< (gccjit::rvalue a, gccjit::rvalue b)
13472
13473@example
13474gccjit::rvalue cond = i < n;
13475@end example
13476
13477@noindent
13478@end deffn
13479
13480@geindex operator<= (C++ function)
17c0b84b 13481@anchor{cp/topics/expressions lte-operator__gccjit rvalue gccjit rvalue}@anchor{18a}
36b809a0 13482@deffn {C++ Function} gccjit::rvalue operator<= (gccjit::rvalue a, gccjit::rvalue b)
13483
13484@example
13485gccjit::rvalue cond = i <= n;
13486@end example
13487
13488@noindent
13489@end deffn
13490
13491@geindex operator> (C++ function)
17c0b84b 13492@anchor{cp/topics/expressions gt-operator__gccjit rvalue gccjit rvalue}@anchor{18b}
36b809a0 13493@deffn {C++ Function} gccjit::rvalue operator> (gccjit::rvalue a, gccjit::rvalue b)
13494
13495@example
13496gccjit::rvalue cond = (ch > limit);
13497@end example
13498
13499@noindent
13500@end deffn
13501
13502@geindex operator>= (C++ function)
17c0b84b 13503@anchor{cp/topics/expressions gte-operator__gccjit rvalue gccjit rvalue}@anchor{18c}
36b809a0 13504@deffn {C++ Function} gccjit::rvalue operator>= (gccjit::rvalue a, gccjit::rvalue b)
13505
13506@example
13507gccjit::rvalue cond = (score >= ctxt.new_rvalue (t_int, 100));
13508@end example
13509
13510@noindent
13511@end deffn
13512
13513@c TODO: beyond this point
13514
13515@node Function calls<2>,Type-coercion<2>,Comparisons<2>,Rvalues<2>
17c0b84b 13516@anchor{cp/topics/expressions function-calls}@anchor{18d}
36b809a0 13517@subsubsection Function calls
13518
13519
13520@geindex gcc_jit_context_new_call (C++ function)
17c0b84b 13521@anchor{cp/topics/expressions gcc_jit_context_new_call__gcc_jit_contextP gcc_jit_locationP gcc_jit_functionP i gcc_jit_rvaluePP}@anchor{18e}
36b809a0 13522@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)
13523
13524Given a function and the given table of argument rvalues, construct a
13525call to the function, with the result as an rvalue.
13526
13527@cartouche
13528@quotation Note
13529@code{gccjit::context::new_call()} merely builds a
17c0b84b 13530@pxref{15b,,gccjit;;rvalue} i.e. an expression that can be evaluated,
36b809a0 13531perhaps as part of a more complicated expression.
13532The call @emph{won't} happen unless you add a statement to a function
13533that evaluates the expression.
13534
13535For example, if you want to call a function and discard the result
13536(or to call a function with @code{void} return type), use
17c0b84b 13537@pxref{18f,,gccjit;;block;;add_eval()}:
36b809a0 13538
13539@example
13540/* Add "(void)printf (arg0, arg1);". */
13541block.add_eval (ctxt.new_call (printf_func, arg0, arg1));
13542@end example
13543
13544@noindent
13545@end quotation
13546@end cartouche
13547@end deffn
13548
13549@node Type-coercion<2>,,Function calls<2>,Rvalues<2>
17c0b84b 13550@anchor{cp/topics/expressions type-coercion}@anchor{190}
36b809a0 13551@subsubsection Type-coercion
13552
13553
13554@geindex gccjit;;context;;new_cast (C++ function)
17c0b84b 13555@anchor{cp/topics/expressions gccjit context new_cast__gccjit rvalue gccjit type gccjit location}@anchor{191}
36b809a0 13556@deffn {C++ Function} gccjit::rvalue gccjit::context::new_cast (gccjit::rvalue rvalue, gccjit::type type, gccjit::location loc)
13557
13558Given an rvalue of T, construct another rvalue of another type.
13559
13560Currently only a limited set of conversions are possible:
13561
13562@quotation
13563
13564
13565@itemize *
13566
13567@item
13568int <-> float
13569
13570@item
13571int <-> bool
13572
13573@item
13574P* <-> Q*, for pointer types P and Q
13575@end itemize
13576@end quotation
13577@end deffn
13578
13579@node Lvalues<2>,Working with pointers structs and unions<2>,Rvalues<2>,Expressions<2>
17c0b84b 13580@anchor{cp/topics/expressions lvalues}@anchor{192}
36b809a0 13581@subsubsection Lvalues
13582
13583
13584@geindex gccjit;;lvalue (C++ class)
17c0b84b 13585@anchor{cp/topics/expressions gccjit lvalue}@anchor{193}
36b809a0 13586@deffn {C++ Class} gccjit::lvalue
13587@end deffn
13588
13589An lvalue is something that can of the @emph{left}-hand side of an assignment:
13590a storage area (such as a variable). It is a subclass of
17c0b84b 13591@pxref{15b,,gccjit;;rvalue}, where the rvalue is computed by reading from the
36b809a0 13592storage area.
13593
13594It iss a thin wrapper around @pxref{24,,gcc_jit_lvalue *} from the C API.
13595
13596@geindex gccjit;;lvalue;;get_address (C++ function)
17c0b84b 13597@anchor{cp/topics/expressions gccjit lvalue get_address__gccjit location}@anchor{194}
36b809a0 13598@deffn {C++ Function} gccjit::rvalue gccjit::lvalue::get_address (gccjit::location loc)
13599
13600Take the address of an lvalue; analogous to:
13601
13602@example
13603&(EXPR)
13604@end example
13605
13606@noindent
13607
13608in C.
13609
13610Parameter "loc" is optional.
13611@end deffn
13612
13613@menu
13614* Global variables: Global variables<2>.
13615
13616@end menu
13617
13618@node Global variables<2>,,,Lvalues<2>
17c0b84b 13619@anchor{cp/topics/expressions global-variables}@anchor{195}
36b809a0 13620@subsubsection Global variables
13621
13622
13623@geindex gccjit;;context;;new_global (C++ function)
17c0b84b 13624@anchor{cp/topics/expressions gccjit context new_global__enum gccjit type cCP gccjit location}@anchor{196}
15b6c83e 13625@deffn {C++ Function} gccjit::lvalue gccjit::context::new_global (enum gcc_jit_global_kind, gccjit::type type, const char* name, gccjit::location loc)
36b809a0 13626
13627Add a new global variable of the given type and name to the context.
15b6c83e 13628
eb2d3e4a 13629This is a thin wrapper around @pxref{b3,,gcc_jit_context_new_global()} from
15b6c83e 13630the C API; the "kind" parameter has the same meaning as there.
36b809a0 13631@end deffn
13632
13633@node Working with pointers structs and unions<2>,,Lvalues<2>,Expressions<2>
17c0b84b 13634@anchor{cp/topics/expressions working-with-pointers-structs-and-unions}@anchor{197}
36b809a0 13635@subsubsection Working with pointers, structs and unions
13636
13637
13638@geindex gccjit;;rvalue;;dereference (C++ function)
17c0b84b 13639@anchor{cp/topics/expressions gccjit rvalue dereference__gccjit location}@anchor{198}
36b809a0 13640@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::dereference (gccjit::location loc)
13641
13642Given an rvalue of pointer type @code{T *}, dereferencing the pointer,
13643getting an lvalue of type @code{T}. Analogous to:
13644
13645@example
13646*(EXPR)
13647@end example
13648
13649@noindent
13650
13651in C.
13652
13653Parameter "loc" is optional.
13654@end deffn
13655
13656If you don't need to specify the location, this can also be expressed using
13657an overloaded operator:
13658
9bd7a189 13659@geindex gccjit;;rvalue;;operator* (C++ function)
17c0b84b 13660@anchor{cp/topics/expressions gccjit rvalue mul-operator}@anchor{199}
9bd7a189 13661@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::operator* ()
36b809a0 13662
13663@example
13664gccjit::lvalue content = *ptr;
13665@end example
13666
13667@noindent
13668@end deffn
13669
13670Field access is provided separately for both lvalues and rvalues:
13671
13672@geindex gccjit;;lvalue;;access_field (C++ function)
17c0b84b 13673@anchor{cp/topics/expressions gccjit lvalue access_field__gccjit field gccjit location}@anchor{19a}
36b809a0 13674@deffn {C++ Function} gccjit::lvalue gccjit::lvalue::access_field (gccjit::field field, gccjit::location loc)
13675
13676Given an lvalue of struct or union type, access the given field,
13677getting an lvalue of the field's type. Analogous to:
13678
13679@example
13680(EXPR).field = ...;
13681@end example
13682
13683@noindent
13684
13685in C.
13686@end deffn
13687
13688@geindex gccjit;;rvalue;;access_field (C++ function)
17c0b84b 13689@anchor{cp/topics/expressions gccjit rvalue access_field__gccjit field gccjit location}@anchor{19b}
36b809a0 13690@deffn {C++ Function} gccjit::rvalue gccjit::rvalue::access_field (gccjit::field field, gccjit::location loc)
13691
13692Given an rvalue of struct or union type, access the given field
13693as an rvalue. Analogous to:
13694
13695@example
13696(EXPR).field
13697@end example
13698
13699@noindent
13700
13701in C.
13702@end deffn
13703
13704@geindex gccjit;;rvalue;;dereference_field (C++ function)
17c0b84b 13705@anchor{cp/topics/expressions gccjit rvalue dereference_field__gccjit field gccjit location}@anchor{19c}
36b809a0 13706@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::dereference_field (gccjit::field field, gccjit::location loc)
13707
13708Given an rvalue of pointer type @code{T *} where T is of struct or union
13709type, access the given field as an lvalue. Analogous to:
13710
13711@example
13712(EXPR)->field
13713@end example
13714
13715@noindent
13716
13717in C, itself equivalent to @code{(*EXPR).FIELD}.
13718@end deffn
13719
13720@geindex gccjit;;context;;new_array_access (C++ function)
17c0b84b 13721@anchor{cp/topics/expressions gccjit context new_array_access__gccjit rvalue gccjit rvalue gccjit location}@anchor{19d}
36b809a0 13722@deffn {C++ Function} gccjit::lvalue gccjit::context::new_array_access (gccjit::rvalue ptr, gccjit::rvalue index, gccjit::location loc)
13723
13724Given an rvalue of pointer type @code{T *}, get at the element @cite{T} at
13725the given index, using standard C array indexing rules i.e. each
13726increment of @code{index} corresponds to @code{sizeof(T)} bytes.
13727Analogous to:
13728
13729@example
13730PTR[INDEX]
13731@end example
13732
13733@noindent
13734
13735in C (or, indeed, to @code{PTR + INDEX}).
13736
13737Parameter "loc" is optional.
13738@end deffn
13739
17c0b84b 13740For array accesses where you don't need to specify a @pxref{139,,gccjit;;location},
36b809a0 13741two overloaded operators are available:
13742
13743@quotation
13744
13745gccjit::lvalue gccjit::rvalue::operator[] (gccjit::rvalue index)
13746
13747@example
13748gccjit::lvalue element = array[idx];
13749@end example
13750
13751@noindent
13752
13753gccjit::lvalue gccjit::rvalue::operator[] (int index)
13754
13755@example
13756gccjit::lvalue element = array[0];
13757@end example
13758
13759@noindent
13760@end quotation
13761
f1717362 13762@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
36b809a0 13763@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
13764@c
13765@c This is free software: you can redistribute it and/or modify it
13766@c under the terms of the GNU General Public License as published by
13767@c the Free Software Foundation, either version 3 of the License, or
13768@c (at your option) any later version.
13769@c
13770@c This program is distributed in the hope that it will be useful, but
13771@c WITHOUT ANY WARRANTY; without even the implied warranty of
13772@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13773@c General Public License for more details.
13774@c
13775@c You should have received a copy of the GNU General Public License
13776@c along with this program. If not, see
13777@c <http://www.gnu.org/licenses/>.
13778
13779@node Creating and using functions<2>,Source Locations<2>,Expressions<2>,Topic Reference<2>
17c0b84b 13780@anchor{cp/topics/functions doc}@anchor{19e}@anchor{cp/topics/functions creating-and-using-functions}@anchor{19f}
36b809a0 13781@subsection Creating and using functions
13782
13783
13784@menu
13785* Params: Params<2>.
13786* Functions: Functions<2>.
13787* Blocks: Blocks<2>.
13788* Statements: Statements<2>.
13789
13790@end menu
13791
13792@node Params<2>,Functions<2>,,Creating and using functions<2>
17c0b84b 13793@anchor{cp/topics/functions params}@anchor{1a0}
36b809a0 13794@subsubsection Params
13795
13796
13797@geindex gccjit;;param (C++ class)
17c0b84b 13798@anchor{cp/topics/functions gccjit param}@anchor{1a1}
36b809a0 13799@deffn {C++ Class} gccjit::param
13800
13801A @cite{gccjit::param} represents a parameter to a function.
13802@end deffn
13803
13804@geindex gccjit;;context;;new_param (C++ function)
17c0b84b 13805@anchor{cp/topics/functions gccjit context new_param__gccjit type cCP gccjit location}@anchor{108}
36b809a0 13806@deffn {C++ Function} gccjit::param gccjit::context::new_param (gccjit::type type, const char* name, gccjit::location loc)
13807
13808In preparation for creating a function, create a new parameter of the
13809given type and name.
13810@end deffn
13811
17c0b84b 13812@pxref{1a1,,gccjit;;param} is a subclass of @pxref{193,,gccjit;;lvalue} (and thus
13813of @pxref{15b,,gccjit;;rvalue} and @pxref{145,,gccjit;;object}). It is a thin
36b809a0 13814wrapper around the C API's @pxref{25,,gcc_jit_param *}.
13815
13816@node Functions<2>,Blocks<2>,Params<2>,Creating and using functions<2>
17c0b84b 13817@anchor{cp/topics/functions functions}@anchor{1a2}
36b809a0 13818@subsubsection Functions
13819
13820
13821@geindex gccjit;;function (C++ class)
17c0b84b 13822@anchor{cp/topics/functions gccjit function}@anchor{1a3}
36b809a0 13823@deffn {C++ Class} gccjit::function
13824
13825A @cite{gccjit::function} represents a function - either one that we're
13826creating ourselves, or one that we're referencing.
13827@end deffn
13828
9bd7a189 13829@geindex gccjit;;context;;new_function (C++ function)
17c0b84b 13830@anchor{cp/topics/functions gccjit context new_function__enum gccjit type cCP std vector param R i gccjit location}@anchor{1a4}
9bd7a189 13831@deffn {C++ Function} gccjit::function gccjit::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)
36b809a0 13832
13833Create a gcc_jit_function with the given name and parameters.
13834
13835Parameters "is_variadic" and "loc" are optional.
13836
13837This is a wrapper around the C API's @pxref{11,,gcc_jit_context_new_function()}.
13838@end deffn
13839
13840@geindex gccjit;;context;;get_builtin_function (C++ function)
17c0b84b 13841@anchor{cp/topics/functions gccjit context get_builtin_function__cCP}@anchor{1a5}
36b809a0 13842@deffn {C++ Function} gccjit::function gccjit::context::get_builtin_function (const char* name)
13843
13844This is a wrapper around the C API's
eb2d3e4a 13845@pxref{ca,,gcc_jit_context_get_builtin_function()}.
36b809a0 13846@end deffn
13847
13848@geindex gccjit;;function;;get_param (C++ function)
17c0b84b 13849@anchor{cp/topics/functions gccjit function get_param__iC}@anchor{1a6}
36b809a0 13850@deffn {C++ Function} gccjit::param gccjit::function::get_param (int index) const
13851
13852Get the param of the given index (0-based).
13853@end deffn
13854
13855@geindex gccjit;;function;;dump_to_dot (C++ function)
17c0b84b 13856@anchor{cp/topics/functions gccjit function dump_to_dot__cCP}@anchor{11b}
36b809a0 13857@deffn {C++ Function} void gccjit::function::dump_to_dot (const char* path)
13858
13859Emit the function in graphviz format to the given path.
13860@end deffn
13861
13862@geindex gccjit;;function;;new_local (C++ function)
17c0b84b 13863@anchor{cp/topics/functions gccjit function new_local__gccjit type cCP gccjit location}@anchor{112}
36b809a0 13864@deffn {C++ Function} gccjit::lvalue gccjit::function::new_local (gccjit::type type, const char* name, gccjit::location loc)
13865
13866Create a new local variable within the function, of the given type and
13867name.
13868@end deffn
13869
13870@node Blocks<2>,Statements<2>,Functions<2>,Creating and using functions<2>
17c0b84b 13871@anchor{cp/topics/functions blocks}@anchor{1a7}
36b809a0 13872@subsubsection Blocks
13873
13874
13875@geindex gccjit;;block (C++ class)
17c0b84b 13876@anchor{cp/topics/functions gccjit block}@anchor{1a8}
36b809a0 13877@deffn {C++ Class} gccjit::block
13878
13879A @cite{gccjit::block} represents a basic block within a function i.e. a
13880sequence of statements with a single entry point and a single exit
13881point.
13882
17c0b84b 13883@pxref{1a8,,gccjit;;block} is a subclass of @pxref{145,,gccjit;;object}.
36b809a0 13884
13885The first basic block that you create within a function will
13886be the entrypoint.
13887
13888Each basic block that you create within a function must be
a24ef8d2 13889terminated, either with a conditional, a jump, a return, or
13890a switch.
36b809a0 13891
13892It's legal to have multiple basic blocks that return within
13893one function.
13894@end deffn
13895
13896@geindex gccjit;;function;;new_block (C++ function)
17c0b84b 13897@anchor{cp/topics/functions gccjit function new_block__cCP}@anchor{1a9}
36b809a0 13898@deffn {C++ Function} gccjit::block gccjit::function::new_block (const char* name)
13899
13900Create a basic block of the given name. The name may be NULL, but
13901providing meaningful names is often helpful when debugging: it may
13902show up in dumps of the internal representation, and in error
13903messages.
13904@end deffn
13905
13906@node Statements<2>,,Blocks<2>,Creating and using functions<2>
17c0b84b 13907@anchor{cp/topics/functions statements}@anchor{1aa}
36b809a0 13908@subsubsection Statements
13909
13910
13911@geindex gccjit;;block;;add_eval (C++ function)
17c0b84b 13912@anchor{cp/topics/functions gccjit block add_eval__gccjit rvalue gccjit location}@anchor{18f}
36b809a0 13913@deffn {C++ Function} void gccjit::block::add_eval (gccjit::rvalue rvalue, gccjit::location loc)
13914
13915Add evaluation of an rvalue, discarding the result
13916(e.g. a function call that "returns" void).
13917
13918This is equivalent to this C code:
13919
13920@example
13921(void)expression;
13922@end example
13923
13924@noindent
13925@end deffn
13926
13927@geindex gccjit;;block;;add_assignment (C++ function)
17c0b84b 13928@anchor{cp/topics/functions gccjit block add_assignment__gccjit lvalue gccjit rvalue gccjit location}@anchor{114}
36b809a0 13929@deffn {C++ Function} void gccjit::block::add_assignment (gccjit::lvalue lvalue, gccjit::rvalue rvalue, gccjit::location loc)
13930
13931Add evaluation of an rvalue, assigning the result to the given
13932lvalue.
13933
13934This is roughly equivalent to this C code:
13935
13936@example
13937lvalue = rvalue;
13938@end example
13939
13940@noindent
13941@end deffn
13942
13943@geindex gccjit;;block;;add_assignment_op (C++ function)
17c0b84b 13944@anchor{cp/topics/functions gccjit block add_assignment_op__gccjit lvalue enum gccjit rvalue gccjit location}@anchor{118}
36b809a0 13945@deffn {C++ Function} void gccjit::block::add_assignment_op (gccjit::lvalue lvalue, enum gcc_jit_binary_op, gccjit::rvalue rvalue, gccjit::location loc)
13946
13947Add evaluation of an rvalue, using the result to modify an
13948lvalue.
13949
13950This is analogous to "+=" and friends:
13951
13952@example
13953lvalue += rvalue;
13954lvalue *= rvalue;
13955lvalue /= rvalue;
13956@end example
13957
13958@noindent
13959
13960etc. For example:
13961
13962@example
13963/* "i++" */
13964loop_body.add_assignment_op (
13965 i,
13966 GCC_JIT_BINARY_OP_PLUS,
13967 ctxt.one (int_type));
13968@end example
13969
13970@noindent
13971@end deffn
13972
13973@geindex gccjit;;block;;add_comment (C++ function)
17c0b84b 13974@anchor{cp/topics/functions gccjit block add_comment__cCP gccjit location}@anchor{123}
36b809a0 13975@deffn {C++ Function} void gccjit::block::add_comment (const char* text, gccjit::location loc)
13976
13977Add a no-op textual comment to the internal representation of the
13978code. It will be optimized away, but will be visible in the dumps
69834ed9 13979seen via @pxref{66,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE}
36b809a0 13980and @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE},
13981and thus may be of use when debugging how your project's internal
13982representation gets converted to the libgccjit IR.
13983
13984Parameter "loc" is optional.
13985@end deffn
13986
13987@geindex gccjit;;block;;end_with_conditional (C++ function)
17c0b84b 13988@anchor{cp/topics/functions gccjit block end_with_conditional__gccjit rvalue gccjit block gccjit block gccjit location}@anchor{117}
36b809a0 13989@deffn {C++ Function} void gccjit::block::end_with_conditional (gccjit::rvalue boolval, gccjit::block on_true, gccjit::block on_false, gccjit::location loc)
13990
13991Terminate a block by adding evaluation of an rvalue, branching on the
13992result to the appropriate successor block.
13993
13994This is roughly equivalent to this C code:
13995
13996@example
13997if (boolval)
13998 goto on_true;
13999else
14000 goto on_false;
14001@end example
14002
14003@noindent
14004
14005block, boolval, on_true, and on_false must be non-NULL.
14006@end deffn
14007
14008@geindex gccjit;;block;;end_with_jump (C++ function)
17c0b84b 14009@anchor{cp/topics/functions gccjit block end_with_jump__gccjit block gccjit location}@anchor{1ab}
36b809a0 14010@deffn {C++ Function} void gccjit::block::end_with_jump (gccjit::block target, gccjit::location loc)
14011
14012Terminate a block by adding a jump to the given target block.
14013
14014This is roughly equivalent to this C code:
14015
14016@example
14017goto target;
14018@end example
14019
14020@noindent
14021@end deffn
14022
14023@geindex gccjit;;block;;end_with_return (C++ function)
17c0b84b 14024@anchor{cp/topics/functions gccjit block end_with_return__gccjit rvalue gccjit location}@anchor{1ac}
36b809a0 14025@deffn {C++ Function} void gccjit::block::end_with_return (gccjit::rvalue rvalue, gccjit::location loc)
14026
14027Terminate a block.
14028
14029Both params are optional.
14030
14031An rvalue must be provided for a function returning non-void, and
14032must not be provided by a function "returning" @cite{void}.
14033
14034If an rvalue is provided, the block is terminated by evaluating the
14035rvalue and returning the value.
14036
14037This is roughly equivalent to this C code:
14038
14039@example
14040return expression;
14041@end example
14042
14043@noindent
14044
14045If an rvalue is not provided, the block is terminated by adding a
14046valueless return, for use within a function with "void" return type.
14047
14048This is equivalent to this C code:
14049
14050@example
14051return;
14052@end example
14053
14054@noindent
14055@end deffn
14056
a24ef8d2 14057@geindex gccjit;;block;;end_with_switch (C++ function)
17c0b84b 14058@anchor{cp/topics/functions gccjit block end_with_switch__gccjit rvalue gccjit block std vector gccjit case_ gccjit location}@anchor{1ad}
a24ef8d2 14059@deffn {C++ Function} void gccjit::block::end_with_switch (gccjit::rvalue expr, gccjit::block default_block, std::vector<gccjit::case_> cases, gccjit::location loc)
14060
14061Terminate a block by adding evalation of an rvalue, then performing
14062a multiway branch.
14063
14064This is roughly equivalent to this C code:
14065
14066@example
14067switch (expr)
14068 @{
14069 default:
14070 goto default_block;
14071
14072 case C0.min_value ... C0.max_value:
14073 goto C0.dest_block;
14074
14075 case C1.min_value ... C1.max_value:
14076 goto C1.dest_block;
14077
14078 ...etc...
14079
14080 case C[N - 1].min_value ... C[N - 1].max_value:
14081 goto C[N - 1].dest_block;
14082@}
14083@end example
14084
14085@noindent
14086
14087@code{expr} must be of the same integer type as all of the @code{min_value}
14088and @code{max_value} within the cases.
14089
14090The ranges of the cases must not overlap (or have duplicate
14091values).
14092
14093The API entrypoints relating to switch statements and cases:
14094
14095@quotation
14096
14097
14098@itemize *
14099
14100@item
17c0b84b 14101@pxref{1ad,,gccjit;;block;;end_with_switch()}
a24ef8d2 14102
14103@item
17c0b84b 14104@pxref{1ae,,gccjit;;context;;new_case()}
a24ef8d2 14105@end itemize
14106@end quotation
14107
eb2d3e4a 14108were added in @pxref{d8,,LIBGCCJIT_ABI_3}; you can test for their presence
a24ef8d2 14109using
14110
14111@example
14112#ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS
14113@end example
14114
14115@noindent
14116
14117@geindex gccjit;;block;;end_with_switch;;gccjit;;case_ (C++ class)
17c0b84b 14118@anchor{cp/topics/functions gccjit block end_with_switch gccjit case_}@anchor{1af}
a24ef8d2 14119@deffn {C++ Class} gccjit::case_
14120@end deffn
14121
14122A @cite{gccjit::case_} represents a case within a switch statement, and
17c0b84b 14123is created within a particular @pxref{131,,gccjit;;context} using
14124@pxref{1ae,,gccjit;;context;;new_case()}. It is a subclass of
14125@pxref{145,,gccjit;;object}.
a24ef8d2 14126
14127Each case expresses a multivalued range of integer values. You
14128can express single-valued cases by passing in the same value for
14129both @cite{min_value} and @cite{max_value}.
14130
14131@geindex gccjit;;block;;end_with_switch;;gccjit;;context;;new_case (C++ function)
17c0b84b 14132@anchor{cp/topics/functions gccjit block end_with_switch gccjit context new_case__gccjit rvalue gccjit rvalue gccjit block}@anchor{1ae}
a24ef8d2 14133@deffn {C++ Function} gccjit::case_* gccjit::context::new_case (gccjit::rvalue min_value, gccjit::rvalue max_value, gccjit::block dest_block)
14134
14135Create a new gccjit::case for use in a switch statement.
14136@cite{min_value} and @cite{max_value} must be constants of an integer type,
14137which must match that of the expression of the switch statement.
14138
14139@cite{dest_block} must be within the same function as the switch
14140statement.
14141@end deffn
14142
14143Here's an example of creating a switch statement:
14144
14145@quotation
14146
14147@example
14148
14149void
14150create_code (gcc_jit_context *c_ctxt, void *user_data)
14151@{
14152 /* Let's try to inject the equivalent of:
14153 int
14154 test_switch (int x)
14155 @{
14156 switch (x)
14157 @{
14158 case 0 ... 5:
14159 return 3;
14160
14161 case 25 ... 27:
14162 return 4;
14163
14164 case -42 ... -17:
14165 return 83;
14166
14167 case 40:
14168 return 8;
14169
14170 default:
14171 return 10;
14172 @}
14173 @}
14174 */
14175 gccjit::context ctxt (c_ctxt);
14176 gccjit::type t_int = ctxt.get_type (GCC_JIT_TYPE_INT);
14177 gccjit::type return_type = t_int;
14178 gccjit::param x = ctxt.new_param (t_int, "x");
14179 std::vector <gccjit::param> params;
14180 params.push_back (x);
14181 gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
14182 return_type,
14183 "test_switch",
14184 params, 0);
14185
14186 gccjit::block b_initial = func.new_block ("initial");
14187
14188 gccjit::block b_default = func.new_block ("default");
14189 gccjit::block b_case_0_5 = func.new_block ("case_0_5");
14190 gccjit::block b_case_25_27 = func.new_block ("case_25_27");
14191 gccjit::block b_case_m42_m17 = func.new_block ("case_m42_m17");
14192 gccjit::block b_case_40 = func.new_block ("case_40");
14193
14194 std::vector <gccjit::case_> cases;
14195 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 0),
14196 ctxt.new_rvalue (t_int, 5),
14197 b_case_0_5));
14198 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 25),
14199 ctxt.new_rvalue (t_int, 27),
14200 b_case_25_27));
14201 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, -42),
14202 ctxt.new_rvalue (t_int, -17),
14203 b_case_m42_m17));
14204 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 40),
14205 ctxt.new_rvalue (t_int, 40),
14206 b_case_40));
14207 b_initial.end_with_switch (x,
14208 b_default,
14209 cases);
14210
14211 b_case_0_5.end_with_return (ctxt.new_rvalue (t_int, 3));
14212 b_case_25_27.end_with_return (ctxt.new_rvalue (t_int, 4));
14213 b_case_m42_m17.end_with_return (ctxt.new_rvalue (t_int, 83));
14214 b_case_40.end_with_return (ctxt.new_rvalue (t_int, 8));
14215 b_default.end_with_return (ctxt.new_rvalue (t_int, 10));
14216@}
14217
14218
14219@end example
14220
14221@noindent
14222@end quotation
14223@end deffn
14224
f1717362 14225@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
36b809a0 14226@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
14227@c
14228@c This is free software: you can redistribute it and/or modify it
14229@c under the terms of the GNU General Public License as published by
14230@c the Free Software Foundation, either version 3 of the License, or
14231@c (at your option) any later version.
14232@c
14233@c This program is distributed in the hope that it will be useful, but
14234@c WITHOUT ANY WARRANTY; without even the implied warranty of
14235@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14236@c General Public License for more details.
14237@c
14238@c You should have received a copy of the GNU General Public License
14239@c along with this program. If not, see
14240@c <http://www.gnu.org/licenses/>.
14241
69834ed9 14242@node Source Locations<2>,Compiling a context<2>,Creating and using functions<2>,Topic Reference<2>
17c0b84b 14243@anchor{cp/topics/locations source-locations}@anchor{1b0}@anchor{cp/topics/locations doc}@anchor{1b1}
36b809a0 14244@subsection Source Locations
14245
14246
14247@geindex gccjit;;location (C++ class)
17c0b84b 14248@anchor{cp/topics/locations gccjit location}@anchor{139}
36b809a0 14249@deffn {C++ Class} gccjit::location
14250
14251A @cite{gccjit::location} encapsulates a source code location, so that
14252you can (optionally) associate locations in your language with
14253statements in the JIT-compiled code, allowing the debugger to
14254single-step through your language.
14255
14256@cite{gccjit::location} instances are optional: you can always omit them
14257from any C++ API entrypoint accepting one.
14258
17c0b84b 14259You can construct them using @pxref{127,,gccjit;;context;;new_location()}.
36b809a0 14260
14261You need to enable @pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the
17c0b84b 14262@pxref{131,,gccjit;;context} for these locations to actually be usable by
36b809a0 14263the debugger:
14264
14265@example
14266ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1);
14267@end example
14268
14269@noindent
14270@end deffn
14271
14272@geindex gccjit;;context;;new_location (C++ function)
17c0b84b 14273@anchor{cp/topics/locations gccjit context new_location__cCP i i}@anchor{127}
36b809a0 14274@deffn {C++ Function} gccjit::location gccjit::context::new_location (const char* filename, int line, int column)
14275
14276Create a @cite{gccjit::location} instance representing the given source
14277location.
14278@end deffn
14279
14280@menu
14281* Faking it: Faking it<2>.
14282
14283@end menu
14284
14285@node Faking it<2>,,,Source Locations<2>
17c0b84b 14286@anchor{cp/topics/locations faking-it}@anchor{1b2}
36b809a0 14287@subsubsection Faking it
14288
14289
14290If you don't have source code for your internal representation, but need
14291to debug, you can generate a C-like representation of the functions in
17c0b84b 14292your context using @pxref{138,,gccjit;;context;;dump_to_file()}:
36b809a0 14293
14294@example
14295ctxt.dump_to_file ("/tmp/something.c",
14296 1 /* update_locations */);
14297@end example
14298
14299@noindent
14300
14301This will dump C-like code to the given path. If the @cite{update_locations}
14302argument is true, this will also set up @cite{gccjit::location} information
14303throughout the context, pointing at the dump file as if it were a source
14304file, giving you @emph{something} you can step through in the debugger.
14305
f1717362 14306@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
36b809a0 14307@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
14308@c
14309@c This is free software: you can redistribute it and/or modify it
14310@c under the terms of the GNU General Public License as published by
14311@c the Free Software Foundation, either version 3 of the License, or
14312@c (at your option) any later version.
14313@c
14314@c This program is distributed in the hope that it will be useful, but
14315@c WITHOUT ANY WARRANTY; without even the implied warranty of
14316@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14317@c General Public License for more details.
14318@c
14319@c You should have received a copy of the GNU General Public License
14320@c along with this program. If not, see
14321@c <http://www.gnu.org/licenses/>.
14322
69834ed9 14323@node Compiling a context<2>,,Source Locations<2>,Topic Reference<2>
17c0b84b 14324@anchor{cp/topics/compilation compiling-a-context}@anchor{1b3}@anchor{cp/topics/compilation doc}@anchor{1b4}
69834ed9 14325@subsection Compiling a context
36b809a0 14326
14327
17c0b84b 14328Once populated, a @pxref{131,,gccjit;;context} can be compiled to
14329machine code, either in-memory via @pxref{10a,,gccjit;;context;;compile()} or
14330to disk via @pxref{1b5,,gccjit;;context;;compile_to_file()}.
69834ed9 14331
14332You can compile a context multiple times (using either form of
14333compilation), although any errors that occur on the context will
14334prevent any future compilation of that context.
14335
14336@menu
14337* In-memory compilation: In-memory compilation<2>.
14338* Ahead-of-time compilation: Ahead-of-time compilation<2>.
14339
14340@end menu
14341
14342@node In-memory compilation<2>,Ahead-of-time compilation<2>,,Compiling a context<2>
17c0b84b 14343@anchor{cp/topics/compilation in-memory-compilation}@anchor{1b6}
69834ed9 14344@subsubsection In-memory compilation
36b809a0 14345
36b809a0 14346
14347@geindex gccjit;;context;;compile (C++ function)
17c0b84b 14348@anchor{cp/topics/compilation gccjit context compile}@anchor{10a}
69834ed9 14349@deffn {C++ Function} gcc_jit_result* gccjit::context::compile ()
36b809a0 14350
14351This calls into GCC and builds the code, returning a
14352@cite{gcc_jit_result *}.
69834ed9 14353
14354This is a thin wrapper around the
14355@pxref{15,,gcc_jit_context_compile()} API entrypoint.
36b809a0 14356@end deffn
14357
69834ed9 14358@node Ahead-of-time compilation<2>,,In-memory compilation<2>,Compiling a context<2>
17c0b84b 14359@anchor{cp/topics/compilation ahead-of-time-compilation}@anchor{1b7}
69834ed9 14360@subsubsection Ahead-of-time compilation
36b809a0 14361
36b809a0 14362
69834ed9 14363Although libgccjit is primarily aimed at just-in-time compilation, it
14364can also be used for implementing more traditional ahead-of-time
17c0b84b 14365compilers, via the @pxref{1b5,,gccjit;;context;;compile_to_file()} method.
36b809a0 14366
69834ed9 14367@geindex gccjit;;context;;compile_to_file (C++ function)
17c0b84b 14368@anchor{cp/topics/compilation gccjit context compile_to_file__enum cCP}@anchor{1b5}
69834ed9 14369@deffn {C++ Function} void gccjit::context::compile_to_file (enum gcc_jit_output_kind, const char* output_path)
14370
17c0b84b 14371Compile the @pxref{131,,gccjit;;context} to a file of the given
69834ed9 14372kind.
14373
14374This is a thin wrapper around the
14375@pxref{4a,,gcc_jit_context_compile_to_file()} API entrypoint.
36b809a0 14376@end deffn
14377
f1717362 14378@c Copyright (C) 2014-2016 Free Software Foundation, Inc.
36b809a0 14379@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
14380@c
14381@c This is free software: you can redistribute it and/or modify it
14382@c under the terms of the GNU General Public License as published by
14383@c the Free Software Foundation, either version 3 of the License, or
14384@c (at your option) any later version.
14385@c
14386@c This program is distributed in the hope that it will be useful, but
14387@c WITHOUT ANY WARRANTY; without even the implied warranty of
14388@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14389@c General Public License for more details.
14390@c
14391@c You should have received a copy of the GNU General Public License
14392@c along with this program. If not, see
14393@c <http://www.gnu.org/licenses/>.
14394
14395@node Internals,Indices and tables,C++ bindings for libgccjit,Top
17c0b84b 14396@anchor{internals/index internals}@anchor{1b8}@anchor{internals/index doc}@anchor{1b9}
36b809a0 14397@chapter Internals
14398
14399
14400@menu
14401* Working on the JIT library::
14402* Running the test suite::
14403* Environment variables::
9dba8b1d 14404* Packaging notes::
36b809a0 14405* Overview of code structure::
c97b0d1d 14406* Design notes::
bc06177c 14407* Submitting patches::
36b809a0 14408
14409@end menu
14410
14411@node Working on the JIT library,Running the test suite,,Internals
17c0b84b 14412@anchor{internals/index working-on-the-jit-library}@anchor{1ba}
36b809a0 14413@section Working on the JIT library
14414
14415
14416Having checked out the source code (to "src"), you can configure and build
14417the JIT library like this:
14418
14419@example
14420mkdir build
14421mkdir install
14422PREFIX=$(pwd)/install
14423cd build
14424../src/configure \
14425 --enable-host-shared \
6bc0fa45 14426 --enable-languages=jit,c++ \
36b809a0 14427 --disable-bootstrap \
14428 --enable-checking=release \
14429 --prefix=$PREFIX
14430nice make -j4 # altering the "4" to however many cores you have
14431@end example
14432
14433@noindent
14434
14435This should build a libgccjit.so within jit/build/gcc:
14436
14437@example
14438[build] $ file gcc/libgccjit.so*
14439gcc/libgccjit.so: symbolic link to `libgccjit.so.0'
14440gcc/libgccjit.so.0: symbolic link to `libgccjit.so.0.0.1'
14441gcc/libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped
14442@end example
14443
14444@noindent
14445
14446Here's what those configuration options mean:
14447
14448@geindex command line option; --enable-host-shared
17c0b84b 14449@anchor{internals/index cmdoption--enable-host-shared}@anchor{1bb}
36b809a0 14450@deffn {Option} --enable-host-shared
14451
14452Configuring with this option means that the compiler is built as
14453position-independent code, which incurs a slight performance hit,
14454but it necessary for a shared library.
14455@end deffn
14456
6bc0fa45 14457@geindex command line option; --enable-languages=jit@comma{}c++
17c0b84b 14458@anchor{internals/index cmdoption--enable-languages}@anchor{1bc}
6bc0fa45 14459@deffn {Option} --enable-languages=jit,c++
36b809a0 14460
14461This specifies which frontends to build. The JIT library looks like
14462a frontend to the rest of the code.
6bc0fa45 14463
14464The C++ portion of the JIT test suite requires the C++ frontend to be
14465enabled at configure-time, or you may see errors like this when
14466running the test suite:
14467
14468@example
14469xgcc: error: /home/david/jit/src/gcc/testsuite/jit.dg/test-quadratic.cc: C++ compiler not installed on this system
14470c++: error trying to exec 'cc1plus': execvp: No such file or directory
14471@end example
14472
14473@noindent
36b809a0 14474@end deffn
14475
14476@geindex command line option; --disable-bootstrap
17c0b84b 14477@anchor{internals/index cmdoption--disable-bootstrap}@anchor{1bd}
36b809a0 14478@deffn {Option} --disable-bootstrap
14479
14480For hacking on the "jit" subdirectory, performing a full
14481bootstrap can be overkill, since it's unused by a bootstrap. However,
14482when submitting patches, you should remove this option, to ensure that
14483the compiler can still bootstrap itself.
14484@end deffn
14485
14486@geindex command line option; --enable-checking=release
17c0b84b 14487@anchor{internals/index cmdoption--enable-checking}@anchor{1be}
36b809a0 14488@deffn {Option} --enable-checking=release
14489
14490The compile can perform extensive self-checking as it runs, useful when
14491debugging, but slowing things down.
14492
14493For maximum speed, configure with @code{--enable-checking=release} to
14494disable this self-checking.
14495@end deffn
14496
14497@node Running the test suite,Environment variables,Working on the JIT library,Internals
17c0b84b 14498@anchor{internals/index running-the-test-suite}@anchor{1bf}
36b809a0 14499@section Running the test suite
14500
14501
14502@example
14503[build] $ cd gcc
14504[gcc] $ make check-jit RUNTESTFLAGS="-v -v -v"
14505@end example
14506
14507@noindent
14508
14509A summary of the tests can then be seen in:
14510
14511@example
14512jit/build/gcc/testsuite/jit/jit.sum
14513@end example
14514
14515@noindent
14516
14517and detailed logs in:
14518
14519@example
14520jit/build/gcc/testsuite/jit/jit.log
14521@end example
14522
14523@noindent
14524
14525The test executables can be seen as:
14526
14527@example
14528jit/build/gcc/testsuite/jit/*.exe
14529@end example
14530
14531@noindent
14532
14533which can be run independently.
14534
14535You can compile and run individual tests by passing "jit.exp=TESTNAME" to RUNTESTFLAGS e.g.:
14536
14537@example
14538[gcc] $ make check-jit RUNTESTFLAGS="-v -v -v jit.exp=test-factorial.c"
14539@end example
14540
14541@noindent
14542
14543and once a test has been compiled, you can debug it directly:
14544
14545@example
14546[gcc] $ PATH=.:$PATH \
14547 LD_LIBRARY_PATH=. \
14548 LIBRARY_PATH=. \
14549 gdb --args \
1eddded5 14550 testsuite/jit/test-factorial.c.exe
36b809a0 14551@end example
14552
14553@noindent
14554
14555@menu
14556* Running under valgrind::
14557
14558@end menu
14559
14560@node Running under valgrind,,,Running the test suite
17c0b84b 14561@anchor{internals/index running-under-valgrind}@anchor{1c0}
36b809a0 14562@subsection Running under valgrind
14563
14564
14565The jit testsuite detects if RUN_UNDER_VALGRIND is present in the
14566environment (with any value). If it is present, it runs the test client
14567code under valgrind@footnote{http://valgrind.org},
14568specifcally, the default
14569memcheck@footnote{http://valgrind.org/docs/manual/mc-manual.html}
14570tool with
14571--leak-check=full@footnote{http://valgrind.org/docs/manual/mc-manual.html#opt.leak-check}.
14572
14573It automatically parses the output from valgrind, injecting XFAIL results if
14574any issues are found, or PASS results if the output is clean. The output
14575is saved to @code{TESTNAME.exe.valgrind.txt}.
14576
14577For example, the following invocation verbosely runs the testcase
14578@code{test-sum-of-squares.c} under valgrind, showing an issue:
14579
14580@example
14581$ RUN_UNDER_VALGRIND= \
14582 make check-jit \
14583 RUNTESTFLAGS="-v -v -v jit.exp=test-sum-of-squares.c"
14584
14585(...verbose log contains detailed valgrind errors, if any...)
14586
14587 === jit Summary ===
14588
14589# of expected passes 28
14590# of expected failures 2
14591
14592$ less testsuite/jit/jit.sum
14593(...other results...)
1eddded5 14594XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: definitely lost: 8 bytes in 1 blocks
14595XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: unsuppressed errors: 1
36b809a0 14596(...other results...)
14597
1eddded5 14598$ less testsuite/jit/test-sum-of-squares.c.exe.valgrind.txt
36b809a0 14599(...shows full valgrind report for this test case...)
57687d8b 14600@end example
14601
14602@noindent
14603
14604When running under valgrind, it's best to have configured gcc with
14605@code{--enable-valgrind-annotations}, which automatically suppresses
14606various known false positives.
14607
9dba8b1d 14608@node Environment variables,Packaging notes,Running the test suite,Internals
17c0b84b 14609@anchor{internals/index environment-variables}@anchor{1c1}
863e76f9 14610@section Environment variables
14611
14612
14613When running client code against a locally-built libgccjit, three
14614environment variables need to be set up:
14615
14616@geindex environment variable; LD_LIBRARY_PATH
17c0b84b 14617@anchor{internals/index envvar-LD_LIBRARY_PATH}@anchor{1c2}
863e76f9 14618@deffn {Environment Variable} LD_LIBRARY_PATH
14619
14620@quotation
14621
14622@cite{libgccjit.so} is dynamically linked into client code, so if running
14623against a locally-built library, @code{LD_LIBRARY_PATH} needs to be set
14624up appropriately. The library can be found within the "gcc"
14625subdirectory of the build tree:
14626@end quotation
14627
14628@example
14629$ file libgccjit.so*
14630libgccjit.so: symbolic link to `libgccjit.so.0'
14631libgccjit.so.0: symbolic link to `libgccjit.so.0.0.1'
14632libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, not stripped
14633@end example
14634
14635@noindent
14636@end deffn
14637
14638@geindex environment variable; PATH
17c0b84b 14639@anchor{internals/index envvar-PATH}@anchor{1c3}
863e76f9 14640@deffn {Environment Variable} PATH
14641
14642The library uses a driver executable for converting from .s assembler
14643files to .so shared libraries. Specifically, it looks for a name
14644expanded from
14645@code{$@{target_noncanonical@}-gcc-$@{gcc_BASEVER@}$@{exeext@}}
14646such as @code{x86_64-unknown-linux-gnu-gcc-5.0.0}.
14647
14648Hence @code{PATH} needs to include a directory where the library can
14649locate this executable.
14650
14651The executable is normally installed to the installation bindir
14652(e.g. /usr/bin), but a copy is also created within the "gcc"
14653subdirectory of the build tree for running the testsuite, and for ease
14654of development.
14655@end deffn
14656
14657@geindex environment variable; LIBRARY_PATH
17c0b84b 14658@anchor{internals/index envvar-LIBRARY_PATH}@anchor{1c4}
863e76f9 14659@deffn {Environment Variable} LIBRARY_PATH
14660
14661The driver executable invokes the linker, and the latter needs to locate
14662support libraries needed by the generated code, or you will see errors
14663like:
14664
14665@example
14666ld: cannot find crtbeginS.o: No such file or directory
14667ld: cannot find -lgcc
14668ld: cannot find -lgcc_s
14669@end example
14670
14671@noindent
14672
14673Hence if running directly from a locally-built copy (without installing),
14674@code{LIBRARY_PATH} needs to contain the "gcc" subdirectory of the build
14675tree.
14676@end deffn
14677
14678For example, to run a binary that uses the library against a non-installed
14679build of the library in LIBGCCJIT_BUILD_DIR you need an invocation of the
14680client code like this, to preprend the dir to each of the environment
14681variables:
14682
14683@example
14684$ LD_LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LD_LIBRARY_PATH) \
14685 PATH=$(LIBGCCJIT_BUILD_DIR):$(PATH) \
14686 LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LIBRARY_PATH) \
14687 ./jit-hello-world
14688hello world
14689@end example
14690
14691@noindent
14692
9dba8b1d 14693@node Packaging notes,Overview of code structure,Environment variables,Internals
17c0b84b 14694@anchor{internals/index packaging-notes}@anchor{1c5}
9dba8b1d 14695@section Packaging notes
14696
14697
17c0b84b 14698The configure-time option @pxref{1bb,,--enable-host-shared} is needed when
9dba8b1d 14699building the jit in order to get position-independent code. This will
14700slow down the regular compiler by a few percent. Hence when packaging gcc
14701with libgccjit, please configure and build twice:
14702
14703@quotation
14704
14705
14706@itemize *
14707
14708@item
17c0b84b 14709once without @pxref{1bb,,--enable-host-shared} for most languages, and
9dba8b1d 14710
14711@item
17c0b84b 14712once with @pxref{1bb,,--enable-host-shared} for the jit
9dba8b1d 14713@end itemize
14714@end quotation
14715
14716For example:
14717
14718@example
14719# Configure and build with --enable-host-shared
14720# for the jit:
14721mkdir configuration-for-jit
14722pushd configuration-for-jit
14723$(SRCDIR)/configure \
14724 --enable-host-shared \
14725 --enable-languages=jit \
14726 --prefix=$(DESTDIR)
14727make
14728popd
14729
14730# Configure and build *without* --enable-host-shared
14731# for maximum speed:
14732mkdir standard-configuration
14733pushd standard-configuration
14734$(SRCDIR)/configure \
14735 --enable-languages=all \
14736 --prefix=$(DESTDIR)
14737make
14738popd
14739
14740# Both of the above are configured to install to $(DESTDIR)
14741# Install the configuration with --enable-host-shared first
14742# *then* the one without, so that the faster build
14743# of "cc1" et al overwrites the slower build.
14744pushd configuration-for-jit
14745make install
14746popd
14747
14748pushd standard-configuration
14749make install
14750popd
14751@end example
14752
14753@noindent
14754
14755@node Overview of code structure,Design notes,Packaging notes,Internals
17c0b84b 14756@anchor{internals/index overview-of-code-structure}@anchor{1c6}
863e76f9 14757@section Overview of code structure
14758
14759
bc06177c 14760The library is implemented in C++. The source files have the @code{.c}
14761extension for legacy reasons.
14762
863e76f9 14763
14764@itemize *
14765
14766@item
14767@code{libgccjit.c} implements the API entrypoints. It performs error
14768checking, then calls into classes of the gcc::jit::recording namespace
14769within @code{jit-recording.c} and @code{jit-recording.h}.
14770
14771@item
14772The gcc::jit::recording classes (within @code{jit-recording.c} and
14773@code{jit-recording.h}) record the API calls that are made:
14774
14775@quotation
14776
14777@example
14778
14779 /* Indentation indicates inheritance: */
14780 class context;
863e76f9 14781 class memento;
14782 class string;
14783 class location;
14784 class type;
14785 class function_type;
14786 class compound_type;
14787 class struct_;
14788 class union_;
14789 class field;
14790 class fields;
14791 class function;
14792 class block;
14793 class rvalue;
14794 class lvalue;
14795 class local;
14796 class global;
14797 class param;
14798 class statement;
a24ef8d2 14799 class case_;
863e76f9 14800
14801
14802@end example
14803
14804@noindent
14805@end quotation
14806
14807@item
14808When the context is compiled, the gcc::jit::playback classes (within
14809@code{jit-playback.c} and @code{jit-playback.h}) replay the API calls
14810within langhook:parse_file:
14811
14812@quotation
14813
14814@example
14815
14816 /* Indentation indicates inheritance: */
14817 class context;
14818 class wrapper;
14819 class type;
14820 class compound_type;
14821 class field;
14822 class function;
14823 class block;
14824 class rvalue;
14825 class lvalue;
14826 class param;
14827 class source_file;
14828 class source_line;
14829 class location;
a24ef8d2 14830 class case_;
863e76f9 14831
14832
14833@end example
14834
14835@noindent
14836
14837@example
14838Client Code . Generated . libgccjit.so
14839 . code .
14840 . . JIT API . JIT "Frontend". (libbackend.a)
14841....................................................................................
14842 │ . . . .
14843 ──────────────────────────> . .
14844 . . │ . .
14845 . . V . .
14846 . . ──> libgccjit.c .
14847 . . │ (error-checking).
14848 . . │ .
14849 . . ──> jit-recording.c
14850 . . (record API calls)
14851 . . <─────── .
14852 . . │ . .
14853 <─────────────────────────── . .
14854 │ . . . .
14855 │ . . . .
14856 V . . gcc_jit_context_compile .
14857 ──────────────────────────> . .
66b69275 14858 . . │ start of recording::context::compile ()
863e76f9 14859 . . │ . .
66b69275 14860 . . │ start of playback::context::compile ()
14861 . . │ (create tempdir) .
14862 . . │ . .
57687d8b 14863 . . │ ACQUIRE MUTEX .
14864 . . │ . .
863e76f9 14865 . . V───────────────────────> toplev::main (for now)
14866 . . . . │
14867 . . . . (various code)
14868 . . . . │
14869 . . . . V
14870 . . . <───────────────── langhook:parse_file
14871 . . . │ .
14872 . . . │ (jit_langhook_parse_file)
14873 . . . │ .
14874..........................................│..................VVVVVVVVVVVVV...
14875 . . . │ . No GC in here
14876 . . . │ jit-playback.c
14877 . . . │ (playback of API calls)
14878 . . . ───────────────> creation of functions,
14879 . . . . types, expression trees
14880 . . . <──────────────── etc
14881 . . . │(handle_locations: add locations to
14882 . . . │ linemap and associate them with trees)
14883 . . . │ .
14884 . . . │ . No GC in here
14885..........................................│..................AAAAAAAAAAAAA...
14886 . . . │ for each function
14887 . . . ──> postprocess
14888 . . . │ .
14889 . . . ────────────> cgraph_finalize_function
14890 . . . <────────────
14891 . . . <── .
14892 . . . │ .
14893 . . . ──────────────────> (end of
14894 . . . . │ langhook_parse_file)
14895 . . . . │
14896 . . . . (various code)
14897 . . . . │
14898 . . . . ↓
14899 . . . <───────────────── langhook:write_globals
14900 . . . │ .
14901 . . . │ (jit_langhook_write_globals)
14902 . . . │ .
14903 . . . │ .
14904 . . . ──────────────────> finalize_compilation_unit
14905 . . . . │
14906 . . . . (the middle─end and backend)
14907 . . . . ↓
14908 . . <───────────────────────────── end of toplev::main
863e76f9 14909 . . │ . .
66b69275 14910 . . V───────────────────────> toplev::finalize
14911 . . . . │ (purge internal state)
14912 . . <──────────────────────── end of toplev::finalize
14913 . . │ . .
69834ed9 14914 . . V─> playback::context::postprocess:
14915 . . │ . .
14916 . . │ (assuming an in-memory compile):
14917 . . │ . .
14918 . . │ . Convert assembler to DSO ("fake.so")
14919 . . │ . .
14920 . . │ . Load DSO (dlopen "fake.so")
14921 . . │ . .
14922 . . │ . Bundle it up in a jit::result
14923 . . <── . .
66b69275 14924 . . │ . .
57687d8b 14925 . . │ RELEASE MUTEX .
14926 . . │ . .
66b69275 14927 . . │ end of playback::context::compile ()
14928 . . │ . .
14929 . . │ playback::context dtor
14930 . . ──> . .
dba7c78e 14931 . . │ Normally we cleanup the tempdir here:
66b69275 14932 . . │ ("fake.so" is unlinked from the
14933 . . │ filesystem at this point)
dba7c78e 14934 . . │ If the client code requested debuginfo, the
14935 . . │ cleanup happens later (in gcc_jit_result_release)
14936 . . │ to make it easier on the debugger (see PR jit/64206)
66b69275 14937 . . <── . .
14938 . . │ . .
66b69275 14939 . . │ end of recording::context::compile ()
863e76f9 14940 <─────────────────────────── . .
14941 │ . . . .
66b69275 14942 V . . gcc_jit_result_get_code .
14943 ──────────────────────────> . .
14944 . . │ dlsym () within loaded DSO
14945 <─────────────────────────── . .
863e76f9 14946 Get (void*). . . .
14947 │ . . . .
14948 │ Call it . . . .
14949 ───────────────> . . .
14950 . │ . . .
14951 . │ . . .
14952 <─────────────── . . .
14953 │ . . . .
66b69275 14954etc│ . . . .
14955 │ . . . .
14956 V . . gcc_jit_result_release .
14957 ──────────────────────────> . .
14958 . . │ dlclose () the loaded DSO
14959 . . │ (code becomes uncallable)
dba7c78e 14960 . . │ . .
14961 . . │ If the client code requested debuginfo, then
14962 . . │ cleanup of the tempdir was delayed.
14963 . . │ If that was the case, clean it up now.
66b69275 14964 <─────────────────────────── . .
863e76f9 14965 │ . . . .
863e76f9 14966
14967@end example
14968
14969@noindent
14970@end quotation
14971@end itemize
14972
14973Here is a high-level summary from @code{jit-common.h}:
14974
14975@quotation
14976
14977In order to allow jit objects to be usable outside of a compile
14978whilst working with the existing structure of GCC's code the
14979C API is implemented in terms of a gcc::jit::recording::context,
14980which records the calls made to it.
14981
14982When a gcc_jit_context is compiled, the recording context creates a
14983playback context. The playback context invokes the bulk of the GCC
14984code, and within the "frontend" parsing hook, plays back the recorded
14985API calls, creating GCC tree objects.
14986
14987So there are two parallel families of classes: those relating to
14988recording, and those relating to playback:
14989
14990
14991@itemize *
14992
14993@item
14994Visibility: recording objects are exposed back to client code,
14995whereas playback objects are internal to the library.
14996
14997@item
14998Lifetime: recording objects have a lifetime equal to that of the
14999recording context that created them, whereas playback objects only
15000exist within the frontend hook.
15001
15002@item
15003Memory allocation: recording objects are allocated by the recording
15004context, and automatically freed by it when the context is released,
15005whereas playback objects are allocated within the GC heap, and
15006garbage-collected; they can own GC-references.
15007
15008@item
15009Integration with rest of GCC: recording objects are unrelated to the
15010rest of GCC, whereas playback objects are wrappers around "tree"
15011instances. Hence you can't ask a recording rvalue or lvalue what its
15012type is, whereas you can for a playback rvalue of lvalue (since it
15013can work with the underlying GCC tree nodes).
15014
15015@item
15016Instancing: There can be multiple recording contexts "alive" at once
15017(albeit it only one compiling at once), whereas there can only be one
15018playback context alive at one time (since it interacts with the GC).
15019@end itemize
15020
15021Ultimately if GCC could support multiple GC heaps and contexts, and
15022finer-grained initialization, then this recording vs playback
15023distinction could be eliminated.
15024
15025During a playback, we associate objects from the recording with
15026their counterparts during this playback. For simplicity, we store this
15027within the recording objects, as @code{void *m_playback_obj}, casting it to
15028the appropriate playback object subclass. For these casts to make
15029sense, the two class hierarchies need to have the same structure.
15030
15031Note that the playback objects that @code{m_playback_obj} points to are
15032GC-allocated, but the recording objects don't own references:
15033these associations only exist within a part of the code where
15034the GC doesn't collect, and are set back to NULL before the GC can
15035run.
15036@end quotation
69834ed9 15037@anchor{internals/index example-of-log-file}@anchor{5c}
3a9ccc11 15038Another way to understand the structure of the code is to enable logging,
69834ed9 15039via @pxref{5b,,gcc_jit_context_set_logfile()}. Here is an example of a log
3a9ccc11 15040generated via this call:
15041
15042@example
8ece6e0e 15043JIT: libgccjit (GCC) version 6.0.0 20150723 (experimental) (x86_64-unknown-linux-gnu)
b86fa9da 15044JIT: 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
3a9ccc11 15045JIT: entering: gcc_jit_context_set_str_option
2c845fbc 15046JIT: GCC_JIT_STR_OPTION_PROGNAME: "./test-hello-world.c.exe"
3a9ccc11 15047JIT: exiting: gcc_jit_context_set_str_option
15048JIT: entering: gcc_jit_context_set_int_option
2c845fbc 15049JIT: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL: 3
3a9ccc11 15050JIT: exiting: gcc_jit_context_set_int_option
15051JIT: entering: gcc_jit_context_set_bool_option
2c845fbc 15052JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO: true
3a9ccc11 15053JIT: exiting: gcc_jit_context_set_bool_option
15054JIT: entering: gcc_jit_context_set_bool_option
2c845fbc 15055JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE: false
3a9ccc11 15056JIT: exiting: gcc_jit_context_set_bool_option
15057JIT: entering: gcc_jit_context_set_bool_option
2c845fbc 15058JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE: false
3a9ccc11 15059JIT: exiting: gcc_jit_context_set_bool_option
15060JIT: entering: gcc_jit_context_set_bool_option
2c845fbc 15061JIT: GCC_JIT_BOOL_OPTION_SELFCHECK_GC: true
3a9ccc11 15062JIT: exiting: gcc_jit_context_set_bool_option
15063JIT: entering: gcc_jit_context_set_bool_option
2c845fbc 15064JIT: GCC_JIT_BOOL_OPTION_DUMP_SUMMARY: false
3a9ccc11 15065JIT: exiting: gcc_jit_context_set_bool_option
15066JIT: entering: gcc_jit_context_get_type
15067JIT: exiting: gcc_jit_context_get_type
15068JIT: entering: gcc_jit_context_get_type
15069JIT: exiting: gcc_jit_context_get_type
15070JIT: entering: gcc_jit_context_new_param
15071JIT: exiting: gcc_jit_context_new_param
15072JIT: entering: gcc_jit_context_new_function
15073JIT: exiting: gcc_jit_context_new_function
15074JIT: entering: gcc_jit_context_new_param
15075JIT: exiting: gcc_jit_context_new_param
15076JIT: entering: gcc_jit_context_get_type
15077JIT: exiting: gcc_jit_context_get_type
15078JIT: entering: gcc_jit_context_new_function
15079JIT: exiting: gcc_jit_context_new_function
15080JIT: entering: gcc_jit_context_new_string_literal
15081JIT: exiting: gcc_jit_context_new_string_literal
15082JIT: entering: gcc_jit_function_new_block
15083JIT: exiting: gcc_jit_function_new_block
15084JIT: entering: gcc_jit_block_add_comment
15085JIT: exiting: gcc_jit_block_add_comment
15086JIT: entering: gcc_jit_context_new_call
15087JIT: exiting: gcc_jit_context_new_call
15088JIT: entering: gcc_jit_block_add_eval
15089JIT: exiting: gcc_jit_block_add_eval
15090JIT: entering: gcc_jit_block_end_with_void_return
15091JIT: exiting: gcc_jit_block_end_with_void_return
69834ed9 15092JIT: entering: gcc_jit_context_dump_reproducer_to_file
15093JIT: entering: void gcc::jit::recording::context::dump_reproducer_to_file(const char*)
15094JIT: exiting: void gcc::jit::recording::context::dump_reproducer_to_file(const char*)
15095JIT: exiting: gcc_jit_context_dump_reproducer_to_file
3a9ccc11 15096JIT: entering: gcc_jit_context_compile
69834ed9 15097JIT: in-memory compile of ctxt: 0x1283e20
3a9ccc11 15098JIT: entering: gcc::jit::result* gcc::jit::recording::context::compile()
2c845fbc 15099JIT: GCC_JIT_STR_OPTION_PROGNAME: "./test-hello-world.c.exe"
15100JIT: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL: 3
15101JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO: true
15102JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE: false
15103JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE: false
15104JIT: GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE: false
15105JIT: GCC_JIT_BOOL_OPTION_DUMP_SUMMARY: false
15106JIT: GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING: false
15107JIT: GCC_JIT_BOOL_OPTION_SELFCHECK_GC: true
15108JIT: GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES: false
8ece6e0e 15109JIT: gcc_jit_context_set_bool_allow_unreachable_blocks: false
3a9ccc11 15110JIT: entering: void gcc::jit::recording::context::validate()
15111JIT: exiting: void gcc::jit::recording::context::validate()
15112JIT: entering: gcc::jit::playback::context::context(gcc::jit::recording::context*)
15113JIT: exiting: gcc::jit::playback::context::context(gcc::jit::recording::context*)
69834ed9 15114JIT: entering: gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*)
15115JIT: exiting: gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*)
15116JIT: entering: void gcc::jit::playback::context::compile()
dba7c78e 15117JIT: entering: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int)
15118JIT: exiting: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int)
15119JIT: entering: bool gcc::jit::tempdir::create()
15120JIT: m_path_template: /tmp/libgccjit-XXXXXX
15121JIT: m_path_tempdir: /tmp/libgccjit-CKq1M9
15122JIT: exiting: bool gcc::jit::tempdir::create()
3a9ccc11 15123JIT: entering: void gcc::jit::playback::context::acquire_mutex()
15124JIT: exiting: void gcc::jit::playback::context::acquire_mutex()
cbbb2345 15125JIT: entering: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*)
15126JIT: reusing cached configure-time options
15127JIT: configure_time_options[0]: -mtune=generic
15128JIT: configure_time_options[1]: -march=x86-64
15129JIT: exiting: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*)
3a9ccc11 15130JIT: entering: toplev::main
15131JIT: argv[0]: ./test-hello-world.c.exe
15132JIT: argv[1]: /tmp/libgccjit-CKq1M9/fake.c
15133JIT: argv[2]: -fPIC
15134JIT: argv[3]: -O3
15135JIT: argv[4]: -g
15136JIT: argv[5]: -quiet
15137JIT: argv[6]: --param
15138JIT: argv[7]: ggc-min-expand=0
15139JIT: argv[8]: --param
15140JIT: argv[9]: ggc-min-heapsize=0
cbbb2345 15141JIT: argv[10]: -mtune=generic
15142JIT: argv[11]: -march=x86-64
3a9ccc11 15143JIT: entering: bool jit_langhook_init()
15144JIT: exiting: bool jit_langhook_init()
15145JIT: entering: void gcc::jit::playback::context::replay()
15146JIT: entering: void gcc::jit::recording::context::replay_into(gcc::jit::replayer*)
15147JIT: exiting: void gcc::jit::recording::context::replay_into(gcc::jit::replayer*)
15148JIT: entering: void gcc::jit::recording::context::disassociate_from_playback()
15149JIT: exiting: void gcc::jit::recording::context::disassociate_from_playback()
15150JIT: entering: void gcc::jit::playback::context::handle_locations()
15151JIT: exiting: void gcc::jit::playback::context::handle_locations()
15152JIT: entering: void gcc::jit::playback::function::build_stmt_list()
15153JIT: exiting: void gcc::jit::playback::function::build_stmt_list()
15154JIT: entering: void gcc::jit::playback::function::build_stmt_list()
15155JIT: exiting: void gcc::jit::playback::function::build_stmt_list()
15156JIT: entering: void gcc::jit::playback::function::postprocess()
15157JIT: exiting: void gcc::jit::playback::function::postprocess()
15158JIT: entering: void gcc::jit::playback::function::postprocess()
15159JIT: exiting: void gcc::jit::playback::function::postprocess()
15160JIT: exiting: void gcc::jit::playback::context::replay()
3a9ccc11 15161JIT: exiting: toplev::main
15162JIT: entering: void gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*)
15163JIT: exiting: void gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*)
15164JIT: entering: toplev::finalize
15165JIT: exiting: toplev::finalize
69834ed9 15166JIT: entering: virtual void gcc::jit::playback::compile_to_memory::postprocess(const char*)
15167JIT: entering: void gcc::jit::playback::context::convert_to_dso(const char*)
15168JIT: entering: void gcc::jit::playback::context::invoke_driver(const char*, const char*, const char*, timevar_id_t, bool, bool)
8ece6e0e 15169JIT: entering: void gcc::jit::playback::context::add_multilib_driver_arguments(vec<char*>*)
15170JIT: exiting: void gcc::jit::playback::context::add_multilib_driver_arguments(vec<char*>*)
15171JIT: argv[0]: x86_64-unknown-linux-gnu-gcc-6.0.0
15172JIT: argv[1]: -m64
15173JIT: argv[2]: -shared
15174JIT: argv[3]: /tmp/libgccjit-CKq1M9/fake.s
15175JIT: argv[4]: -o
15176JIT: argv[5]: /tmp/libgccjit-CKq1M9/fake.so
15177JIT: argv[6]: -fno-use-linker-plugin
15178JIT: argv[7]: (null)
69834ed9 15179JIT: exiting: void gcc::jit::playback::context::invoke_driver(const char*, const char*, const char*, timevar_id_t, bool, bool)
15180JIT: exiting: void gcc::jit::playback::context::convert_to_dso(const char*)
15181JIT: entering: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso()
15182JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO was set: handing over tempdir to jit::result
15183JIT: entering: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*)
15184JIT: exiting: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*)
15185JIT: exiting: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso()
15186JIT: exiting: virtual void gcc::jit::playback::compile_to_memory::postprocess(const char*)
3a9ccc11 15187JIT: entering: void gcc::jit::playback::context::release_mutex()
15188JIT: exiting: void gcc::jit::playback::context::release_mutex()
69834ed9 15189JIT: exiting: void gcc::jit::playback::context::compile()
3a9ccc11 15190JIT: entering: gcc::jit::playback::context::~context()
15191JIT: exiting: gcc::jit::playback::context::~context()
15192JIT: exiting: gcc::jit::result* gcc::jit::recording::context::compile()
15193JIT: gcc_jit_context_compile: returning (gcc_jit_result *)0x12f75d0
15194JIT: exiting: gcc_jit_context_compile
15195JIT: entering: gcc_jit_result_get_code
15196JIT: locating fnname: hello_world
15197JIT: entering: void* gcc::jit::result::get_code(const char*)
15198JIT: exiting: void* gcc::jit::result::get_code(const char*)
15199JIT: gcc_jit_result_get_code: returning (void *)0x7ff6b8cd87f0
15200JIT: exiting: gcc_jit_result_get_code
15201JIT: entering: gcc_jit_context_release
15202JIT: deleting ctxt: 0x1283e20
15203JIT: entering: gcc::jit::recording::context::~context()
15204JIT: exiting: gcc::jit::recording::context::~context()
15205JIT: exiting: gcc_jit_context_release
15206JIT: entering: gcc_jit_result_release
15207JIT: deleting result: 0x12f75d0
15208JIT: entering: virtual gcc::jit::result::~result()
dba7c78e 15209JIT: entering: gcc::jit::tempdir::~tempdir()
15210JIT: unlinking .s file: /tmp/libgccjit-CKq1M9/fake.s
15211JIT: unlinking .so file: /tmp/libgccjit-CKq1M9/fake.so
15212JIT: removing tempdir: /tmp/libgccjit-CKq1M9
15213JIT: exiting: gcc::jit::tempdir::~tempdir()
3a9ccc11 15214JIT: exiting: virtual gcc::jit::result::~result()
15215JIT: exiting: gcc_jit_result_release
15216JIT: gcc::jit::logger::~logger()
15217
15218@end example
15219
15220@noindent
863e76f9 15221
bc06177c 15222@node Design notes,Submitting patches,Overview of code structure,Internals
17c0b84b 15223@anchor{internals/index design-notes}@anchor{1c7}
c97b0d1d 15224@section Design notes
15225
15226
15227It should not be possible for client code to cause an internal compiler
15228error. If this @emph{does} happen, the root cause should be isolated (perhaps
69834ed9 15229using @pxref{5d,,gcc_jit_context_dump_reproducer_to_file()}) and the cause
c97b0d1d 15230should be rejected via additional checking. The checking ideally should
15231be within the libgccjit API entrypoints in libgccjit.c, since this is as
15232close as possible to the error; failing that, a good place is within
15233@code{recording::context::validate ()} in jit-recording.c.
15234
bc06177c 15235@node Submitting patches,,Design notes,Internals
17c0b84b 15236@anchor{internals/index submitting-patches}@anchor{1c8}
bc06177c 15237@section Submitting patches
15238
15239
15240Please read the contribution guidelines for gcc at
15241@indicateurl{https://gcc.gnu.org/contribute.html}.
15242
15243Patches for the jit should be sent to both the
15244@email{gcc-patches@@gcc.gnu.org} and @email{jit@@gcc.gnu.org} mailing lists,
15245with "jit" and "PATCH" in the Subject line.
15246
15247You don't need to do a full bootstrap for code that just touches the
15248@code{jit} and @code{testsuite/jit.dg} subdirectories. However, please run
15249@code{make check-jit} before submitting the patch, and mention the results
15250in your email (along with the host triple that the tests were run on).
15251
15252A good patch should contain the information listed in the
15253gcc contribution guide linked to above; for a @code{jit} patch, the patch
15254shold contain:
15255
15256@quotation
15257
15258
15259@itemize *
15260
15261@item
15262the code itself (for example, a new API entrypoint will typically
15263touch @code{libgccjit.h} and @code{.c}, along with support code in
15264@code{jit-recording.[ch]} and @code{jit-playback.[ch]} as appropriate)
15265
15266@item
15267test coverage
15268
15269@item
15270documentation for the C API
15271
15272@item
15273documentation for the C++ API
15274@end itemize
15275@end quotation
15276
15277A patch that adds new API entrypoints should also contain:
15278
15279@quotation
15280
15281
15282@itemize *
15283
15284@item
15285a feature macro in @code{libgccjit.h} so that client code that doesn't
15286use a "configure" mechanism can still easily detect the presence of
15287the entrypoint. See e.g. @code{LIBGCCJIT_HAVE_SWITCH_STATEMENTS} (for
15288a category of entrypoints) and
15289@code{LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks}
15290(for an individual entrypoint).
15291
15292@item
15293a new ABI tag containing the new symbols (in @code{libgccjit.map}), so
15294that we can detect client code that uses them
15295
15296@item
15297Support for @pxref{5d,,gcc_jit_context_dump_reproducer_to_file()}. Most
15298jit testcases attempt to dump their contexts to a .c file; @code{jit.exp}
15299then sanity-checks the generated c by compiling them (though
15300not running them). A new API entrypoint
15301needs to "know" how to write itself back out to C (by implementing
15302@code{gcc::jit::recording::memento::write_reproducer} for the appropriate
15303@code{memento} subclass).
15304
15305@item
15306C++ bindings for the new entrypoints (see @code{libgccjit++.h}); ideally
15307with test coverage, though the C++ API test coverage is admittedly
15308spotty at the moment
15309
15310@item
15311documentation for the new C entrypoints
15312
15313@item
15314documentation for the new C++ entrypoints
15315
15316@item
15317documentation for the new ABI tag (see @code{topics/compatibility.rst}).
15318@end itemize
15319@end quotation
15320
15321Depending on the patch you can either extend an existing test case, or
15322add a new test case. If you add an entirely new testcase: @code{jit.exp}
15323expects jit testcases to begin with @code{test-}, or @code{test-error-} (for a
15324testcase that generates an error on a @pxref{8,,gcc_jit_context}).
15325
15326Every new testcase that doesn't generate errors should also touch
15327@code{gcc/testsuite/jit.dg/all-non-failing-tests.h}:
15328
15329@quotation
15330
15331
15332@itemize *
15333
15334@item
15335Testcases that don't generate errors should ideally be added to the
15336@code{testcases} array in that file; this means that, in addition
15337to being run standalone, they also get run within
15338@code{test-combination.c} (which runs all successful tests inside one
15339big @pxref{8,,gcc_jit_context}), and @code{test-threads.c} (which runs all
15340successful tests in one process, each one running in a different
15341thread on a different @pxref{8,,gcc_jit_context}).
15342
15343@cartouche
15344@quotation Note
15345Given that exported functions within a @pxref{8,,gcc_jit_context}
15346must have unique names, and most testcases are run within
15347@code{test-combination.c}, this means that every jit-compiled test
15348function typically needs a name that's unique across the entire
15349test suite.
15350@end quotation
15351@end cartouche
15352
15353@item
15354Testcases that aren't to be added to the @code{testcases} array should
15355instead add a comment to the file clarifying why they're not in that
15356array. See the file for examples.
15357@end itemize
15358@end quotation
15359
15360Typically a patch that touches the .rst documentation will also need the
15361texinfo to be regenerated. You can do this with
15362Sphinx 1.0@footnote{http://sphinx-doc.org/} or later by
15363running @code{make texinfo} within @code{SRCDIR/gcc/jit/docs}. Don't do this
15364within the patch sent to the mailing list; it can often be relatively
15365large and inconsequential (e.g. anchor renumbering), rather like generated
15366"configure" changes from configure.ac. You can regenerate it when
15367committing to svn.
15368
863e76f9 15369@node Indices and tables,Index,Internals,Top
17c0b84b 15370@anchor{index indices-and-tables}@anchor{1c9}
863e76f9 15371@unnumbered Indices and tables
15372
15373
15374
15375@itemize *
15376
15377@item
15378@emph{genindex}
15379
15380@item
15381@emph{modindex}
15382
15383@item
15384@emph{search}
15385@end itemize
15386
15387@c Some notes:
15388@c
15389@c The Sphinx C domain appears to lack explicit support for enum values,
15390@c so I've been using :c:macro: for them.
15391@c
15392@c See http://sphinx-doc.org/domains.html#the-c-domain
15393
15394@node Index,,Indices and tables,Top
15395@unnumbered Index
15396
15397
15398@printindex ge
15399
15400@c %**end of body
15401@bye