Committed to branch dmalcolm/jit: Sphinx is not a blessed dependency, so checkin a copy of the built .texi file for people who want .texi docs without needing to install sphinx.
This is generated by running "make texinfo" in the gcc/jit/docs directory. gcc/jit/ChangeLog.jit: * docs/_build/texinfo/Makefile: New file, generated by Sphinx, by running "make texinfo" in docs directory. * docs/_build/texinfo/libgccjit.texi: Likewise. * docs/_build/texinfo/sum-of-squares.png: Likewise. --- gcc/jit/ChangeLog.jit | 7 + gcc/jit/docs/_build/texinfo/Makefile | 50 + gcc/jit/docs/_build/texinfo/libgccjit.texi | 3997 ++++++++++++++++++++++++ gcc/jit/docs/_build/texinfo/sum-of-squares.png | Bin 0 -> 22839 bytes 4 files changed, 4054 insertions(+) create mode 100644 gcc/jit/docs/_build/texinfo/Makefile create mode 100644 gcc/jit/docs/_build/texinfo/libgccjit.texi create mode 100644 gcc/jit/docs/_build/texinfo/sum-of-squares.png diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit index 06734db..45fee00 100644 --- a/gcc/jit/ChangeLog.jit +++ b/gcc/jit/ChangeLog.jit @@ -1,5 +1,12 @@ 2014-09-18 David Malcolm <dmalc...@redhat.com> + * docs/_build/texinfo/Makefile: New file, generated by Sphinx, by + running "make texinfo" in docs directory. + * docs/_build/texinfo/libgccjit.texi: Likewise. + * docs/_build/texinfo/sum-of-squares.png: Likewise. + +2014-09-18 David Malcolm <dmalc...@redhat.com> + * docs/conf.py (Options for HTML output): Update html_theme from "default" to "pyramid". diff --git a/gcc/jit/docs/_build/texinfo/Makefile b/gcc/jit/docs/_build/texinfo/Makefile new file mode 100644 index 0000000..87e3048 --- /dev/null +++ b/gcc/jit/docs/_build/texinfo/Makefile @@ -0,0 +1,50 @@ +# Makefile for Sphinx Texinfo output + +infodir ?= /usr/share/info + +MAKEINFO = makeinfo --no-split +MAKEINFO_html = makeinfo --no-split --html +MAKEINFO_plaintext = makeinfo --no-split --plaintext +TEXI2PDF = texi2pdf --batch --expand +INSTALL_INFO = install-info + +ALLDOCS = $(basename $(wildcard *.texi)) + +all: info +info: $(addsuffix .info,$(ALLDOCS)) +plaintext: $(addsuffix .txt,$(ALLDOCS)) +html: $(addsuffix .html,$(ALLDOCS)) +pdf: $(addsuffix .pdf,$(ALLDOCS)) + +install-info: info + for f in *.info; do \ + cp -t $(infodir) "$$f" && \ + $(INSTALL_INFO) --info-dir=$(infodir) "$$f" ; \ + done + +uninstall-info: info + for f in *.info; do \ + rm -f "$(infodir)/$$f" ; \ + $(INSTALL_INFO) --delete --info-dir=$(infodir) "$$f" ; \ + done + +%.info: %.texi + $(MAKEINFO) -o '$@' '$<' + +%.txt: %.texi + $(MAKEINFO_plaintext) -o '$@' '$<' + +%.html: %.texi + $(MAKEINFO_html) -o '$@' '$<' + +%.pdf: %.texi + -$(TEXI2PDF) '$<' + -$(TEXI2PDF) '$<' + -$(TEXI2PDF) '$<' + +clean: + -rm -f *.info *.pdf *.txt *.html + -rm -f *.log *.ind *.aux *.toc *.syn *.idx *.out *.ilg *.pla *.ky *.pg + -rm -f *.vr *.tp *.fn *.fns *.def *.defs *.cp *.cps *.ge *.ges *.mo + +.PHONY: all info plaintext html pdf install-info uninstall-info clean diff --git a/gcc/jit/docs/_build/texinfo/libgccjit.texi b/gcc/jit/docs/_build/texinfo/libgccjit.texi new file mode 100644 index 0000000..f4904d7 --- /dev/null +++ b/gcc/jit/docs/_build/texinfo/libgccjit.texi @@ -0,0 +1,3997 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename libgccjit.info +@documentencoding UTF-8 +@ifinfo +@*Generated by Sphinx 1.1.3.@* +@end ifinfo +@settitle libgccjit Documentation +@defindex ge +@paragraphindent 2 +@exampleindent 4 +@afourlatex +@dircategory Miscellaneous +@direntry +* libgccjit: (libgccjit.info). One line description of project. +@end direntry + +@c %**end of header + +@copying +@quotation +libgccjit 0.1, September 18, 2014 + +David Malcolm + +Copyright @copyright{} 2014, Free Software Foundation +@end quotation + +@end copying + +@titlepage +@title libgccjit Documentation +@insertcopying +@end titlepage +@contents + +@c %** start of user preamble + +@c %** end of user preamble + +@ifnottex +@node Top +@top libgccjit Documentation +@insertcopying +@end ifnottex + +@c %**start of body +@anchor{index doc}@anchor{0} +@c Copyright (C) 2014 Free Software Foundation, Inc. +@c Originally contributed by David Malcolm <dmalc...@redhat.com> +@c +@c This is free software: you can redistribute it and/or modify it +@c under the terms of the GNU General Public License as published by +@c the Free Software Foundation, either version 3 of the License, or +@c (at your option) any later version. +@c +@c This program is distributed in the hope that it will be useful, but +@c WITHOUT ANY WARRANTY; without even the implied warranty of +@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +@c General Public License for more details. +@c +@c You should have received a copy of the GNU General Public License +@c along with this program. If not, see +@c <http://www.gnu.org/licenses/>. + +Contents: + +@c Copyright (C) 2014 Free Software Foundation, Inc. +@c Originally contributed by David Malcolm <dmalc...@redhat.com> +@c +@c This is free software: you can redistribute it and/or modify it +@c under the terms of the GNU General Public License as published by +@c the Free Software Foundation, either version 3 of the License, or +@c (at your option) any later version. +@c +@c This program is distributed in the hope that it will be useful, but +@c WITHOUT ANY WARRANTY; without even the implied warranty of +@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +@c General Public License for more details. +@c +@c You should have received a copy of the GNU General Public License +@c along with this program. If not, see +@c <http://www.gnu.org/licenses/>. + +@menu +* Getting Started:: +* Tutorial part 1; Creating a trivial machine code function: Tutorial part 1 Creating a trivial machine code function. +* Tutorial part 2; Loops and variables: Tutorial part 2 Loops and variables. +* Compilation contexts:: +* Objects:: +* Types:: +* Expressions:: +* Creating and using functions:: +* Source Locations:: +* Compilation results:: +* Indices and tables:: +* Index:: + +@detailmenu + --- The Detailed Node Listing --- + +Getting Started + +* Installation via packages:: +* Installation from source:: +* "Hello world":: + +Installation via packages + +* Fedora and RHEL:: +* Other distributions:: + +Tutorial part 1: Creating a trivial machine code function + +* Options:: +* Full example:: + +Tutorial part 2: Loops and variables + +* Expressions; lvalues and rvalues: Expressions lvalues and rvalues. +* Control flow:: +* Visualizing the control flow graph:: +* Full example: Full example<2>. + +Compilation contexts + +* Lifetime-management:: +* Thread-safety:: +* Error-handling:: +* Debugging:: +* Options: Options<2>. + +Options + +* String Options:: +* Boolean options:: +* Integer options:: + +Types + +* Standard types:: +* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile. +* Structures and unions:: + +Expressions + +* Rvalues:: +* Lvalues:: +* Working with pointers@comma{} structs and unions: Working with pointers structs and unions. + +Rvalues + +* Simple expressions:: +* Unary Operations:: +* Binary Operations:: +* Comparisons:: +* Function calls:: +* Type-coercion:: + +Lvalues + +* Global variables:: + +Creating and using functions + +* Params:: +* Functions:: +* Blocks:: +* Statements:: + +Source Locations + +* Faking it:: + +@end detailmenu +@end menu + + +@node Getting Started,Tutorial part 1 Creating a trivial machine code function,Top,Top +@anchor{intro/install libgccjit}@anchor{1}@anchor{intro/install getting-started}@anchor{2}@anchor{intro/install doc}@anchor{3} +@chapter Getting Started + + +@menu +* Installation via packages:: +* Installation from source:: +* "Hello world":: + +Installation via packages + +* Fedora and RHEL:: +* Other distributions:: + +@end menu + + +@node Installation via packages,Installation from source,,Getting Started +@anchor{intro/install installation-via-packages}@anchor{4} +@section Installation via packages + + +It's easiest to use pre-built packages of the library. + +@menu +* Fedora and RHEL:: +* Other distributions:: + +@end menu + +@node Fedora and RHEL,Other distributions,,Installation via packages +@anchor{intro/install fedora-and-rhel}@anchor{5} +@subsection Fedora and RHEL + + +RPM packages of libgccjit (and its Python 2 and 3 bindings) are +available for Fedora and RHEL, for i386 and x86_64. + +These currently should be treated as experimental. + +See @indicateurl{https://copr.fedoraproject.org/coprs/dmalcolm/libgccjit/} +for information on subscribing to the appropriate repository for +your system. Having done this, + +@example +sudo yum install libgccjit-devel +@end example + +@noindent + +should give you both the JIT library (@cite{libgccjit}) and the header files +needed to develop against it (@cite{libgccjit-devel}): + +@example +$ rpm -qlv libgccjit +lrwxrwxrwx 1 root root 18 Aug 12 07:56 /usr/lib64/libgccjit.so.0 -> libgccjit.so.0.0.1 +-rwxr-xr-x 1 root root 14463448 Aug 12 07:57 /usr/lib64/libgccjit.so.0.0.1 +$ rpm -qlv libgccjit-devel +-rwxr-xr-x 1 root root 37654 Aug 12 07:56 /usr/include/libgccjit++.h +-rwxr-xr-x 1 root root 28967 Aug 12 07:56 /usr/include/libgccjit.h +lrwxrwxrwx 1 root root 14 Aug 12 07:56 /usr/lib64/libgccjit.so -> libgccjit.so.0 +@end example + +@noindent + +@node Other distributions,,Fedora and RHEL,Installation via packages +@anchor{intro/install other-distributions}@anchor{6} +@subsection Other distributions + + +Prebuilt packages for other distributions would be most welcome; please +contact the jit mailing list@footnote{https://gcc.gnu.org/ml/jit/}. + +@node Installation from source,"Hello world",Installation via packages,Getting Started +@anchor{intro/install installation-from-source}@anchor{7} +@section Installation from source + + +If pre-built packages are not available, you can built the library from +source. Doing so currently requires about 4.2G of drive space (for +the combination of the source tree, the build directory, and the +installation path). + + +@table @asis + +@item The code can currently be seen within the git branch "dmalcolm/jit" here: + +@indicateurl{http://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/dmalcolm/jit} +@end table + +The following will check out a copy of the appropriate branch, to the +"jit/src" subdirectory: + +@example +mkdir jit +cd jit +git clone \ + -b dmalcolm/jit \ + git://gcc.gnu.org/git/gcc.git \ + src +@end example + +@noindent + +The source tree currently occupies about 2.8G of disk space. + +To build it (within the "jit/build" subdirectory, installing to +"jit/install"): + +@example +mkdir build +mkdir install +PREFIX=$(pwd)/install +cd build +../src/configure \ + --enable-host-shared \ + --enable-languages=jit \ + --disable-bootstrap \ + --enable-checking=release \ + --prefix=$PREFIX +nice make -j4 # altering the "4" to however many cores you have +@end example + +@noindent + +On my 4-core laptop this takes 17 minutes and 1.1G of disk space +(it's much faster with many cores and a corresponding -j setting). + +This should build a libgccjit.so within jit/build/gcc: + +@example +[build] $ file gcc/libgccjit.so* +gcc/libgccjit.so: symbolic link to `libgccjit.so.0' +gcc/libgccjit.so.0: symbolic link to `libgccjit.so.0.0.1' +gcc/libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped +@end example + +@noindent + +Note that this is a branch of GCC, so if it fails to build, you might want +to consult the general GCC FAQ@footnote{https://gcc.gnu.org/wiki/FAQ} for some +common issues, before checking on the jit mailing list@footnote{https://gcc.gnu.org/ml/jit/}. + +You should then be able to install it (to the @cite{--prefix} specified +earlier) via: + +@example +make install +@end example + +@noindent + +On my laptop this uses a further 0.4G of disk space. + +You should be able to see the header files within the @cite{include} +subdirectory of the installation prefix: + +@example +$ find $PREFIX/include +/home/david/gcc-jit/install/include +/home/david/gcc-jit/install/include/libgccjit.h +/home/david/gcc-jit/install/include/libgccjit++.h +@end example + +@noindent + +and the library within the @cite{lib} subdirectory: + +@example +$ find $PREFIX/lib/libgccjit.* +/home/david/gcc-jit/install/lib/libgccjit.so +/home/david/gcc-jit/install/lib/libgccjit.so.0 +/home/david/gcc-jit/install/lib/libgccjit.so.0.0.1 +@end example + +@noindent + +@node "Hello world",,Installation from source,Getting Started +@anchor{intro/install hello-world}@anchor{8} +@section "Hello world" + + +Here's a trivial "hello world" program that uses the library to synthesize +a call to @cite{printf} and use it to write a message to stdout. + +@quotation + +@example +#include <libgccjit.h> + +#include <stdlib.h> +#include <stdio.h> + +static void +create_code (gcc_jit_context *ctxt) +@{ + /* Let's try to inject the equivalent of: + void + greet (const char *name) + @{ + printf ("hello %s\n", name); + @} + */ + gcc_jit_type *void_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); + gcc_jit_type *const_char_ptr_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR); + gcc_jit_param *param_name = + gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name"); + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + void_type, + "greet", + 1, ¶m_name, + 0); + + gcc_jit_param *param_format = + gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format"); + gcc_jit_function *printf_func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_IMPORTED, + gcc_jit_context_get_type ( + ctxt, GCC_JIT_TYPE_INT), + "printf", + 1, ¶m_format, + 1); + gcc_jit_rvalue *args[2]; + args[0] = gcc_jit_context_new_string_literal (ctxt, "hello %s\n"); + args[1] = gcc_jit_param_as_rvalue (param_name); + + gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); + + gcc_jit_block_add_eval ( + block, NULL, + gcc_jit_context_new_call (ctxt, + NULL, + printf_func, + 2, args)); + gcc_jit_block_end_with_void_return (block, NULL); +@} + +int +main (int argc, char **argv) +@{ + gcc_jit_context *ctxt; + gcc_jit_result *result; + + /* Get a "context" object for working with the library. */ + ctxt = gcc_jit_context_acquire (); + if (!ctxt) + @{ + fprintf (stderr, "NULL ctxt"); + exit (1); + @} + + /* Set some options on the context. + Let's see the code being generated, in assembler form. */ + gcc_jit_context_set_bool_option ( + ctxt, + GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, + 0); + + /* Populate the context. */ + create_code (ctxt); + + /* Compile the code. */ + result = gcc_jit_context_compile (ctxt); + if (!result) + @{ + fprintf (stderr, "NULL result"); + exit (1); + @} + + /* Extract the generated code from "result". */ + typedef void (*fn_type) (const char *); + fn_type greet = + (fn_type)gcc_jit_result_get_code (result, "greet"); + if (!greet) + @{ + fprintf (stderr, "NULL greet"); + exit (1); + @} + + /* Now call the generated function: */ + greet ("world"); + fflush (stdout); + + gcc_jit_context_release (ctxt); + gcc_jit_result_release (result); + return 0; +@} + +@end example + +@noindent +@end quotation + +Copy it to @cite{jit-hello-world.c}. + +To build it with prebuilt packages, use: + +@example +$ gcc \ + jit-hello-world.c \ + -o jit-hello-world \ + -lgccjit + +# Run the built program: +$ ./jit-hello-world +hello world +@end example + +@noindent + +If building against an locally-built install (to $PREFIX), specify the +include and library paths with -I and -L: + +@example +$ gcc \ + jit-hello-world.c \ + -o jit-hello-world \ + -lgccjit \ + -I$PREFIX/include -L$PREFIX/lib +@end example + +@noindent + +and when running, specify the dynamic linkage path via LD_LIBRARY_PATH: + +@example +$ LD_LIBRARY_PATH=$PREFIX/lib ./jit-hello-world +hello world +@end example + +@noindent + +@c Copyright (C) 2014 Free Software Foundation, Inc. +@c Originally contributed by David Malcolm <dmalc...@redhat.com> +@c +@c This is free software: you can redistribute it and/or modify it +@c under the terms of the GNU General Public License as published by +@c the Free Software Foundation, either version 3 of the License, or +@c (at your option) any later version. +@c +@c This program is distributed in the hope that it will be useful, but +@c WITHOUT ANY WARRANTY; without even the implied warranty of +@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +@c General Public License for more details. +@c +@c You should have received a copy of the GNU General Public License +@c along with this program. If not, see +@c <http://www.gnu.org/licenses/>. + +@node Tutorial part 1 Creating a trivial machine code function,Tutorial part 2 Loops and variables,Getting Started,Top +@anchor{intro/tutorial01 tutorial-part-1-creating-a-trivial-machine-code-function}@anchor{9}@anchor{intro/tutorial01 doc}@anchor{a} +@chapter Tutorial part 1: Creating a trivial machine code function + + +Consider this C function: + +@example +int square (int i) +@{ + return i * i; +@} +@end example + +@noindent + +How can we construct this at run-time using libgccjit? + +@c FIXME + +First we need to include the relevant header: + +@example +#include "libgccjit.h" +@end example + +@noindent + +All state associated with compilation is associated with a +@pxref{b,,gcc_jit_context *}. + +Create one using @pxref{c,,gcc_jit_context_acquire()}: + +@example +gcc_jit_context *ctxt; +ctxt = gcc_jit_context_acquire (); +@end example + +@noindent + +The JIT library has a system of types. It is statically-typed: every +expression is of a specific type, fixed at compile-time. In our example, +all of the expressions are of the C @cite{int} type, so let's obtain this from +the context, as a @pxref{d,,gcc_jit_type *}, using +@pxref{e,,gcc_jit_context_get_type()}: + +@example +gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); +@end example + +@noindent + +@pxref{d,,gcc_jit_type *} is an example of a "contextual" object: every +entity in the API is associated with a @pxref{b,,gcc_jit_context *}. + +Memory management is easy: all such "contextual" objects are automatically +cleaned up for you when the context is released, using +@pxref{f,,gcc_jit_context_release()}: + +@example +gcc_jit_context_release (ctxt); +@end example + +@noindent + +so you don't need to manually track and cleanup all objects, just the +contexts. + +Although the API is C-based, there is a form of class hierarchy, which +looks like this: + +@example ++- gcc_jit_object + +- gcc_jit_location + +- gcc_jit_type + +- gcc_jit_struct + +- gcc_jit_field + +- gcc_jit_function + +- gcc_jit_block + +- gcc_jit_rvalue + +- gcc_jit_lvalue + +- gcc_jit_param +@end example + +@noindent + +There are casting methods for upcasting from subclasses to parent classes. +For example, @pxref{10,,gcc_jit_type_as_object()}: + +@example +gcc_jit_object *obj = gcc_jit_type_as_object (int_type); +@end example + +@noindent + +One thing you can do with a @pxref{11,,gcc_jit_object *} is +to ask it for a human-readable description, using +@pxref{12,,gcc_jit_object_get_debug_string()}: + +@example +printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj)); +@end example + +@noindent + +giving this text on stdout: + +@example +obj: int +@end example + +@noindent + +This is invaluable when debugging. + +Let's create the function. To do so, we first need to construct +its single parameter, specifying its type and giving it a name, +using @pxref{13,,gcc_jit_context_new_param()}: + +@example +gcc_jit_param *param_i = + gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); +@end example + +@noindent + +Now we can create the function, using +@pxref{14,,gcc_jit_context_new_function()}: + +@example +gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + int_type, + "square", + 1, ¶m_i, + 0); +@end example + +@noindent + +To define the code within the function, we must create basic blocks +containing statements. + +Every basic block contains a list of statements, eventually terminated +by a statement that either returns, or jumps to another basic block. + +Our function has no control-flow, so we just need one basic block: + +@example +gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); +@end example + +@noindent + +Our basic block is relatively simple: it immediately terminates by +returning the value of an expression. + +We can build the expression using @pxref{15,,gcc_jit_context_new_binary_op()}: + +@example +gcc_jit_rvalue *expr = + gcc_jit_context_new_binary_op ( + ctxt, NULL, + GCC_JIT_BINARY_OP_MULT, int_type, + gcc_jit_param_as_rvalue (param_i), + gcc_jit_param_as_rvalue (param_i)); +@end example + +@noindent + +A @pxref{16,,gcc_jit_rvalue *} is another example of a +@pxref{11,,gcc_jit_object *} subclass. We can upcast it using +@pxref{17,,gcc_jit_rvalue_as_object()} and as before print it with +@pxref{12,,gcc_jit_object_get_debug_string()}. + +@example +printf ("expr: %s\n", + gcc_jit_object_get_debug_string ( + gcc_jit_rvalue_as_object (expr))); +@end example + +@noindent + +giving this output: + +@example +expr: i * i +@end example + +@noindent + +Creating the expression in itself doesn't do anything; we have to add +this expression to a statement within the block. In this case, we use it +to build a return statement, which terminates the basic block: + +@example +gcc_jit_block_end_with_return (block, NULL, expr); +@end example + +@noindent + +OK, we've populated the context. We can now compile it using +@pxref{18,,gcc_jit_context_compile()}: + +@example +gcc_jit_result *result; +result = gcc_jit_context_compile (ctxt); +@end example + +@noindent + +and get a @pxref{19,,gcc_jit_result *}. + +We can now use @pxref{1a,,gcc_jit_result_get_code()} to look up a specific +machine code routine within the result, in this case, the function we +created above. + +@example +void *fn_ptr = gcc_jit_result_get_code (result, "square"); +if (!fn_ptr) + @{ + fprintf (stderr, "NULL fn_ptr"); + goto error; + @} +@end example + +@noindent + +We can now cast the pointer to an appropriate function pointer type, and +then call it: + +@example +typedef int (*fn_type) (int); +fn_type square = (fn_type)fn_ptr; +printf ("result: %d", square (5)); +@end example + +@noindent + +@example +result: 25 +@end example + +@noindent + +@menu +* Options:: +* Full example:: + +@end menu + +@node Options,Full example,,Tutorial part 1 Creating a trivial machine code function +@anchor{intro/tutorial01 options}@anchor{1b} +@section Options + + +To get more information on what's going on, you can set debugging flags +on the context using @pxref{1c,,gcc_jit_context_set_bool_option()}. + +@c (I'm deliberately not mentioning +@c :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think +@c it's probably more of use to implementors than to users) + +Setting @pxref{1d,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE} will dump a +C-like representation to stderr when you compile (GCC's "GIMPLE" +representation): + +@example +gcc_jit_context_set_bool_option ( + ctxt, + GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, + 1); +result = gcc_jit_context_compile (ctxt); +@end example + +@noindent + +@example +square (signed int i) +@{ + signed int D.260; + + entry: + D.260 = i * i; + return D.260; +@} +@end example + +@noindent + +We can see the generated machine code in assembler form (on stderr) by +setting @pxref{1e,,GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE} on the context +before compiling: + +@example +gcc_jit_context_set_bool_option ( + ctxt, + GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, + 1); +result = gcc_jit_context_compile (ctxt); +@end example + +@noindent + +@example + .file "fake.c" + .text + .globl square + .type square, @@function +square: +.LFB6: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -4(%rbp) +.L14: + movl -4(%rbp), %eax + imull -4(%rbp), %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE6: + .size square, .-square + .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" + .section .note.GNU-stack,"",@@progbits +@end example + +@noindent + +By default, no optimizations are performed, the equivalent of GCC's +@cite{-O0} option. We can turn things up to e.g. @cite{-O3} by calling +@pxref{1f,,gcc_jit_context_set_int_option()} with +@pxref{20,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: + +@example +gcc_jit_context_set_int_option ( + ctxt, + GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, + 3); +@end example + +@noindent + +@example + .file "fake.c" + .text + .p2align 4,,15 + .globl square + .type square, @@function +square: +.LFB7: + .cfi_startproc +.L16: + movl %edi, %eax + imull %edi, %eax + ret + .cfi_endproc +.LFE7: + .size square, .-square + .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" + .section .note.GNU-stack,"",@@progbits +@end example + +@noindent + +Naturally this has only a small effect on such a trivial function. + +@node Full example,,Options,Tutorial part 1 Creating a trivial machine code function +@anchor{intro/tutorial01 full-example}@anchor{21} +@section Full example + + +Here's what the above looks like as a complete program: + +@quotation + +@example +#include <libgccjit.h> + +#include <stdlib.h> +#include <stdio.h> + +void +create_code (gcc_jit_context *ctxt) +@{ + /* Let's try to inject the equivalent of: + + int square (int i) + @{ + return i * i; + @} + */ + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_param *param_i = + gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + int_type, + "square", + 1, ¶m_i, + 0); + + gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); + + gcc_jit_rvalue *expr = + gcc_jit_context_new_binary_op ( + ctxt, NULL, + GCC_JIT_BINARY_OP_MULT, int_type, + gcc_jit_param_as_rvalue (param_i), + gcc_jit_param_as_rvalue (param_i)); + + gcc_jit_block_end_with_return (block, NULL, expr); +@} + +int +main (int argc, char **argv) +@{ + gcc_jit_context *ctxt = NULL; + gcc_jit_result *result = NULL; + + /* Get a "context" object for working with the library. */ + ctxt = gcc_jit_context_acquire (); + if (!ctxt) + @{ + fprintf (stderr, "NULL ctxt"); + goto error; + @} + + /* Set some options on the context. + Let's see the code being generated, in assembler form. */ + gcc_jit_context_set_bool_option ( + ctxt, + GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, + 0); + + /* Populate the context. */ + create_code (ctxt); + + /* Compile the code. */ + result = gcc_jit_context_compile (ctxt); + if (!result) + @{ + fprintf (stderr, "NULL result"); + goto error; + @} + + /* Extract the generated code from "result". */ + void *fn_ptr = gcc_jit_result_get_code (result, "square"); + if (!fn_ptr) + @{ + fprintf (stderr, "NULL fn_ptr"); + goto error; + @} + + typedef int (*fn_type) (int); + fn_type square = (fn_type)fn_ptr; + printf ("result: %d", square (5)); + + error: + gcc_jit_context_release (ctxt); + gcc_jit_result_release (result); + return 0; +@} + +@end example + +@noindent +@end quotation + +Building and running it: + +@example +$ gcc \ + tut01-square.c \ + -o tut01-square \ + -lgccjit + +# Run the built program: +$ ./tut01-square +result: 25 +@end example + +@noindent + +@c Copyright (C) 2014 Free Software Foundation, Inc. +@c Originally contributed by David Malcolm <dmalc...@redhat.com> +@c +@c This is free software: you can redistribute it and/or modify it +@c under the terms of the GNU General Public License as published by +@c the Free Software Foundation, either version 3 of the License, or +@c (at your option) any later version. +@c +@c This program is distributed in the hope that it will be useful, but +@c WITHOUT ANY WARRANTY; without even the implied warranty of +@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +@c General Public License for more details. +@c +@c You should have received a copy of the GNU General Public License +@c along with this program. If not, see +@c <http://www.gnu.org/licenses/>. + +@node Tutorial part 2 Loops and variables,Compilation contexts,Tutorial part 1 Creating a trivial machine code function,Top +@anchor{intro/tutorial02 tutorial-part-2-loops-and-variables}@anchor{22}@anchor{intro/tutorial02 doc}@anchor{23} +@chapter Tutorial part 2: Loops and variables + + +Consider this C function: + +@quotation + +@example +int loop_test (int n) +@{ + int sum = 0; + for (int i = 0; i < n; i++) + sum += i * i; + return sum; +@} +@end example + +@noindent +@end quotation + +This example demonstrates some more features of libgccjit, with local +variables and a loop. + +To break this down into libgccjit terms, it's usually easier to reword +the @cite{for} loop as a @cite{while} loop, giving: + +@quotation + +@example +int loop_test (int n) +@{ + int sum = 0; + int i = 0; + while (i < n) + @{ + sum += i * i; + i++; + @} + return sum; +@} +@end example + +@noindent +@end quotation + +Here's what the final control flow graph will look like: + +@quotation + + +@float Figure + +@image{sum-of-squares,,,image of a control flow graph,png} + +@end float + +@end quotation + +As before, we include the libgccjit header and make a +@pxref{b,,gcc_jit_context *}. + +@example +#include "libgccjit.h" + +void test (void) +@{ + gcc_jit_context *ctxt; + ctxt = gcc_jit_context_acquire (); +@end example + +@noindent + +The function works with the C @cite{int} type: + +@example +gcc_jit_type *the_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); +gcc_jit_type *return_type = the_type; +@end example + +@noindent + +though we could equally well make it work on, say, @cite{double}: + +@example +gcc_jit_type *the_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE); +@end example + +@noindent + +Let's build the function: + +@example +gcc_jit_param *n = + gcc_jit_context_new_param (ctxt, NULL, the_type, "n"); +gcc_jit_param *params[1] = @{n@}; +gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + return_type, + "loop_test", + 1, params, 0); +@end example + +@noindent + +@menu +* Expressions; lvalues and rvalues: Expressions lvalues and rvalues. +* Control flow:: +* Visualizing the control flow graph:: +* Full example: Full example<2>. + +@end menu + +@node Expressions lvalues and rvalues,Control flow,,Tutorial part 2 Loops and variables +@anchor{intro/tutorial02 expressions-lvalues-and-rvalues}@anchor{24} +@section Expressions: lvalues and rvalues + + +The base class of expression is the @pxref{16,,gcc_jit_rvalue *}, +representing an expression that can be on the @emph{right}-hand side of +an assignment: a value that can be computed somehow, and assigned +@emph{to} a storage area (such as a variable). It has a specific +@pxref{d,,gcc_jit_type *}. + +Anothe important class is @pxref{25,,gcc_jit_lvalue *}. +A @pxref{25,,gcc_jit_lvalue *}. is something that can of the @emph{left}-hand +side of an assignment: a storage area (such as a variable). + +In other words, every assignment can be thought of as: + +@example +LVALUE = RVALUE; +@end example + +@noindent + +Note that @pxref{25,,gcc_jit_lvalue *} is a subclass of +@pxref{16,,gcc_jit_rvalue *}, where in an assignment of the form: + +@example +LVALUE_A = LVALUE_B; +@end example + +@noindent + +the @cite{LVALUE_B} implies reading the current value of that storage +area, assigning it into the @cite{LVALUE_A}. + +So far the only expressions we've seen are @cite{i * i}: + +@example +gcc_jit_rvalue *expr = + gcc_jit_context_new_binary_op ( + ctxt, NULL, + GCC_JIT_BINARY_OP_MULT, int_type, + gcc_jit_param_as_rvalue (param_i), + gcc_jit_param_as_rvalue (param_i)); +@end example + +@noindent + +which is a @pxref{16,,gcc_jit_rvalue *}, and the various function +parameters: @cite{param_i} and @cite{param_n}, instances of +@pxref{26,,gcc_jit_param *}, which is a subclass of +@pxref{25,,gcc_jit_lvalue *} (and, in turn, of @pxref{16,,gcc_jit_rvalue *}): +we can both read from and write to function parameters within the +body of a function. + +Our new example has a couple of local variables. We create them by +calling @pxref{27,,gcc_jit_function_new_local()}, supplying a type and a +name: + +@example +/* Build locals: */ +gcc_jit_lvalue *i = + gcc_jit_function_new_local (func, NULL, the_type, "i"); +gcc_jit_lvalue *sum = + gcc_jit_function_new_local (func, NULL, the_type, "sum"); +@end example + +@noindent + +These are instances of @pxref{25,,gcc_jit_lvalue *} - they can be read from +and written to. + +Note that there is no precanned way to create @emph{and} initialize a variable +like in C: + +@example +int i = 0; +@end example + +@noindent + +Instead, having added the local to the function, we have to separately add +an assignment of @cite{0} to @cite{local_i} at the beginning of the function. + +@node Control flow,Visualizing the control flow graph,Expressions lvalues and rvalues,Tutorial part 2 Loops and variables +@anchor{intro/tutorial02 control-flow}@anchor{28} +@section Control flow + + +This function has a loop, so we need to build some basic blocks to +handle the control flow. In this case, we need 4 blocks: + + +@enumerate + +@item +before the loop (initializing the locals) + +@item +the conditional at the top of the loop (comparing @cite{i < n}) + +@item +the body of the loop + +@item +after the loop terminates (@cite{return sum}) +@end enumerate + +so we create these as @pxref{29,,gcc_jit_block *} instances within the +@pxref{2a,,gcc_jit_function *}: + +@example +gcc_jit_block *b_initial = + gcc_jit_function_new_block (func, "initial"); +gcc_jit_block *b_loop_cond = + gcc_jit_function_new_block (func, "loop_cond"); +gcc_jit_block *b_loop_body = + gcc_jit_function_new_block (func, "loop_body"); +gcc_jit_block *b_after_loop = + gcc_jit_function_new_block (func, "after_loop"); +@end example + +@noindent + +We now populate each block with statements. + +The entry block @cite{b_initial} consists of initializations followed by a jump +to the conditional. We assign @cite{0} to @cite{i} and to @cite{sum}, using +@pxref{2b,,gcc_jit_block_add_assignment()} to add +an assignment statement, and using @pxref{2c,,gcc_jit_context_zero()} to get +the constant value @cite{0} for the relevant type for the right-hand side of +the assignment: + +@example +/* sum = 0; */ +gcc_jit_block_add_assignment ( + b_initial, NULL, + sum, + gcc_jit_context_zero (ctxt, the_type)); + +/* i = 0; */ +gcc_jit_block_add_assignment ( + b_initial, NULL, + i, + gcc_jit_context_zero (ctxt, the_type)); +@end example + +@noindent + +We can then terminate the entry block by jumping to the conditional: + +@example +gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond); +@end example + +@noindent + +The conditional block is equivalent to the line @cite{while (i < n)} from our +C example. It contains a single statement: a conditional, which jumps to +one of two destination blocks depending on a boolean +@pxref{16,,gcc_jit_rvalue *}, in this case the comparison of @cite{i} and @cite{n}. +We build the comparison using @pxref{2d,,gcc_jit_context_new_comparison()}: + +@example +gcc_jit_rvalue *guard = + gcc_jit_context_new_comparison ( + ctxt, NULL, + GCC_JIT_COMPARISON_GE, + gcc_jit_lvalue_as_rvalue (i), + gcc_jit_param_as_rvalue (n)); +@end example + +@noindent + +and can then use this to add @cite{b_loop_cond}'s sole statement, via +@pxref{2e,,gcc_jit_block_end_with_conditional()}: + +@example +gcc_jit_block_end_with_conditional (b_loop_cond, NULL, guard); +@end example + +@noindent + +Next, we populate the body of the loop. + +The C statement @cite{sum += i * i;} is an assignment operation, where an +lvalue is modified "in-place". We use +@pxref{2f,,gcc_jit_block_add_assignment_op()} to handle these operations: + +@example +/* sum += i * i */ +gcc_jit_block_add_assignment_op ( + b_loop_body, NULL, + sum, + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_context_new_binary_op ( + ctxt, NULL, + GCC_JIT_BINARY_OP_MULT, the_type, + gcc_jit_lvalue_as_rvalue (i), + gcc_jit_lvalue_as_rvalue (i))); +@end example + +@noindent + +The @cite{i++} can be thought of as @cite{i += 1}, and can thus be handled in +a similar way. We use @pxref{30,,gcc_jit_context_one()} to get the constant +value @cite{1} (for the relevant type) for the right-hand side +of the assignment. + +@example +/* i++ */ +gcc_jit_block_add_assignment_op ( + b_loop_body, NULL, + i, + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_context_one (ctxt, the_type)); +@end example + +@noindent + +@cartouche +@quotation Note +For numeric constants other than 0 or 1, we could use +@pxref{31,,gcc_jit_context_new_rvalue_from_int()} and +@pxref{32,,gcc_jit_context_new_rvalue_from_double()}. +@end quotation +@end cartouche + +The loop body completes by jumping back to the conditional: + +@example +gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond); +@end example + +@noindent + +Finally, we populate the @cite{b_after_loop} block, reached when the loop +conditional is false. We want to generate the equivalent of: + +@example +return sum; +@end example + +@noindent + +so the block is just one statement: + +@example +/* return sum */ +gcc_jit_block_end_with_return ( + b_after_loop, + NULL, + gcc_jit_lvalue_as_rvalue (sum)); +@end example + +@noindent + +@cartouche +@quotation Note +You can intermingle block creation with statement creation, +but given that the terminator statements generally include references +to other blocks, I find it's clearer to create all the blocks, +@emph{then} all the statements. +@end quotation +@end cartouche + +We've finished populating the function. As before, we can now compile it +to machine code: + +@example +gcc_jit_result *result; +result = gcc_jit_context_compile (ctxt); + +typedef int (*loop_test_fn_type) (int); +loop_test_fn_type loop_test = + (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); +if (!loop_test) + goto error; +printf ("result: %d", loop_test (10)); +@end example + +@noindent + +@example +result: 285 +@end example + +@noindent + +@node Visualizing the control flow graph,Full example<2>,Control flow,Tutorial part 2 Loops and variables +@anchor{intro/tutorial02 visualizing-the-control-flow-graph}@anchor{33} +@section Visualizing the control flow graph + + +You can see the control flow graph of a function using +@pxref{34,,gcc_jit_function_dump_to_dot()}: + +@example +gcc_jit_function_dump_to_dot (func, "/tmp/sum-of-squares.dot"); +@end example + +@noindent + +giving a .dot file in GraphViz format. + +You can convert this to an image using @cite{dot}: + +@example +$ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png +@end example + +@noindent + +or use a viewer (my preferred one is xdot.py; see +@indicateurl{https://github.com/jrfonseca/xdot.py}; on Fedora you can +install it with @cite{yum install python-xdot}): + +@quotation + + +@float Figure + +@image{sum-of-squares,,,image of a control flow graph,png} + +@end float + +@end quotation + +@node Full example<2>,,Visualizing the control flow graph,Tutorial part 2 Loops and variables +@anchor{intro/tutorial02 full-example}@anchor{35} +@section Full example + + +@quotation + +@example +#include <libgccjit.h> + +#include <stdlib.h> +#include <stdio.h> + +void +create_code (gcc_jit_context *ctxt) +@{ + /* + Simple sum-of-squares, to test conditionals and looping + + int loop_test (int n) + @{ + int i; + int sum = 0; + for (i = 0; i < n ; i ++) + @{ + sum += i * i; + @} + return sum; + */ + gcc_jit_type *the_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *return_type = the_type; + + gcc_jit_param *n = + gcc_jit_context_new_param (ctxt, NULL, the_type, "n"); + gcc_jit_param *params[1] = @{n@}; + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + return_type, + "loop_test", + 1, params, 0); + + /* Build locals: */ + gcc_jit_lvalue *i = + gcc_jit_function_new_local (func, NULL, the_type, "i"); + gcc_jit_lvalue *sum = + gcc_jit_function_new_local (func, NULL, the_type, "sum"); + + gcc_jit_block *b_initial = + gcc_jit_function_new_block (func, "initial"); + gcc_jit_block *b_loop_cond = + gcc_jit_function_new_block (func, "loop_cond"); + gcc_jit_block *b_loop_body = + gcc_jit_function_new_block (func, "loop_body"); + gcc_jit_block *b_after_loop = + gcc_jit_function_new_block (func, "after_loop"); + + /* sum = 0; */ + gcc_jit_block_add_assignment ( + b_initial, NULL, + sum, + gcc_jit_context_zero (ctxt, the_type)); + + /* i = 0; */ + gcc_jit_block_add_assignment ( + b_initial, NULL, + i, + gcc_jit_context_zero (ctxt, the_type)); + + gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond); + + /* if (i >= n) */ + gcc_jit_block_end_with_conditional ( + b_loop_cond, NULL, + gcc_jit_context_new_comparison ( + ctxt, NULL, + GCC_JIT_COMPARISON_GE, + gcc_jit_lvalue_as_rvalue (i), + gcc_jit_param_as_rvalue (n)), + b_after_loop, + b_loop_body); + + /* sum += i * i */ + gcc_jit_block_add_assignment_op ( + b_loop_body, NULL, + sum, + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_context_new_binary_op ( + ctxt, NULL, + GCC_JIT_BINARY_OP_MULT, the_type, + gcc_jit_lvalue_as_rvalue (i), + gcc_jit_lvalue_as_rvalue (i))); + + /* i++ */ + gcc_jit_block_add_assignment_op ( + b_loop_body, NULL, + i, + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_context_one (ctxt, the_type)); + + gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond); + + /* return sum */ + gcc_jit_block_end_with_return ( + b_after_loop, + NULL, + gcc_jit_lvalue_as_rvalue (sum)); +@} + +int +main (int argc, char **argv) +@{ + gcc_jit_context *ctxt = NULL; + gcc_jit_result *result = NULL; + + /* Get a "context" object for working with the library. */ + ctxt = gcc_jit_context_acquire (); + if (!ctxt) + @{ + fprintf (stderr, "NULL ctxt"); + goto error; + @} + + /* Set some options on the context. + Let's see the code being generated, in assembler form. */ + gcc_jit_context_set_bool_option ( + ctxt, + GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, + 0); + + /* Populate the context. */ + create_code (ctxt); + + /* Compile the code. */ + result = gcc_jit_context_compile (ctxt); + if (!result) + @{ + fprintf (stderr, "NULL result"); + goto error; + @} + + /* Extract the generated code from "result". */ + typedef int (*loop_test_fn_type) (int); + loop_test_fn_type loop_test = + (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); + if (!loop_test) + @{ + fprintf (stderr, "NULL loop_test"); + goto error; + @} + + /* Run the generated code. */ + int val = loop_test (10); + printf("loop_test returned: %d\n", val); + + error: + gcc_jit_context_release (ctxt); + gcc_jit_result_release (result); + return 0; +@} + +@end example + +@noindent +@end quotation + +Building and running it: + +@example +$ gcc \ + tut02-sum-of-squares.c \ + -o tut02-sum-of-squares \ + -lgccjit + +# Run the built program: +$ ./tut02-sum-of-squares +loop_test returned: 285 +@end example + +@noindent + +@c Copyright (C) 2014 Free Software Foundation, Inc. +@c Originally contributed by David Malcolm <dmalc...@redhat.com> +@c +@c This is free software: you can redistribute it and/or modify it +@c under the terms of the GNU General Public License as published by +@c the Free Software Foundation, either version 3 of the License, or +@c (at your option) any later version. +@c +@c This program is distributed in the hope that it will be useful, but +@c WITHOUT ANY WARRANTY; without even the implied warranty of +@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +@c General Public License for more details. +@c +@c You should have received a copy of the GNU General Public License +@c along with this program. If not, see +@c <http://www.gnu.org/licenses/>. + +@node Compilation contexts,Objects,Tutorial part 2 Loops and variables,Top +@anchor{topics/contexts compilation-contexts}@anchor{36}@anchor{topics/contexts doc}@anchor{37} +@chapter Compilation contexts + + +@geindex gcc_jit_context (C type) +@anchor{topics/contexts gcc_jit_context}@anchor{b} +@deffn {C Type} gcc_jit_context +@end deffn + +The top-level of the API is the @pxref{b,,gcc_jit_context} type. + +A @pxref{b,,gcc_jit_context} instance encapsulates the state of a +compilation. + +You can set up options on it, and add types, functions and code. +Invoking @pxref{18,,gcc_jit_context_compile()} on it gives you a +@pxref{19,,gcc_jit_result}. + +@menu +* Lifetime-management:: +* Thread-safety:: +* Error-handling:: +* Debugging:: +* Options: Options<2>. + +@end menu + +@node Lifetime-management,Thread-safety,,Compilation contexts +@anchor{topics/contexts lifetime-management}@anchor{38} +@section Lifetime-management + + +Contexts are the unit of lifetime-management within the API: objects +have their lifetime bounded by the context they are created within, and +cleanup of such objects is done for you when the context is released. + +@geindex gcc_jit_context_acquire (C function) +@anchor{topics/contexts gcc_jit_context_acquire}@anchor{c} +@deffn {C Function} gcc_jit_context *gcc_jit_context_acquire (void) + +This function acquires a new @pxref{11,,gcc_jit_object *} instance, +which is independent of any others that may be present within this +process. +@end deffn + +@geindex gcc_jit_context_release (C function) +@anchor{topics/contexts gcc_jit_context_release}@anchor{f} +@deffn {C Function} void gcc_jit_context_release (gcc_jit_context@w{ }*ctxt) + +This function releases all resources associated with the given context. +Both the context itself and all of its @pxref{11,,gcc_jit_object *} +instances are cleaned up. It should be called exactly once on a given +context. + +It is invalid to use the context or any of its "contextual" objects +after calling this. + +@example +gcc_jit_context_release (ctxt); +@end example + +@noindent +@end deffn + +@geindex gcc_jit_context_new_child_context (C function) +@anchor{topics/contexts gcc_jit_context_new_child_context}@anchor{39} +@deffn {C Function} gcc_jit_context * gcc_jit_context_new_child_context (gcc_jit_context@w{ }*parent_ctxt) + +Given an existing JIT context, create a child context. + +The child inherits a copy of all option-settings from the parent. + +The child can reference objects created within the parent, but not +vice-versa. + +The lifetime of the child context must be bounded by that of the +parent: you should release a child context before releasing the parent +context. + +If you use a function from a parent context within a child context, +you have to compile the parent context before you can compile the +child context, and the gcc_jit_result of the parent context must +outlive the gcc_jit_result of the child context. + +This allows caching of shared initializations. For example, you could +create types and declarations of global functions in a parent context +once within a process, and then create child contexts whenever a +function or loop becomes hot. Each such child context can be used for +JIT-compiling just one function or loop, but can reference types +and helper functions created within the parent context. + +Contexts can be arbitrarily nested, provided the above rules are +followed, but it's probably not worth going above 2 or 3 levels, and +there will likely be a performance hit for such nesting. +@end deffn + +@node Thread-safety,Error-handling,Lifetime-management,Compilation contexts +@anchor{topics/contexts thread-safety}@anchor{3a} +@section Thread-safety + + +Instances of @pxref{11,,gcc_jit_object *} created via +@pxref{c,,gcc_jit_context_acquire()} are independent from each other: +only one thread may use a given context at once, but multiple threads +could each have their own contexts without needing locks. + +Contexts created via @pxref{39,,gcc_jit_context_new_child_context()} are +related to their parent context. They can be partitioned by their +ultimate ancestor into independent "family trees". Only one thread +within a process may use a given "family tree" of such contexts at once, +and if you're using multiple threads you should provide your own locking +around entire such context partitions. + +@node Error-handling,Debugging,Thread-safety,Compilation contexts +@anchor{topics/contexts error-handling}@anchor{3b} +@section Error-handling + + +You can only compile and get code from a context if no errors occur. + +In general, if an error occurs when using an API entrypoint, it returns +NULL. You don't have to check everywhere for NULL results, since the +API gracefully handles a NULL being passed in for any argument. + +Errors are printed on stderr and can be queried using +@pxref{3c,,gcc_jit_context_get_first_error()}. + +@geindex gcc_jit_context_get_first_error (C function) +@anchor{topics/contexts gcc_jit_context_get_first_error}@anchor{3c} +@deffn {C Function} const char * gcc_jit_context_get_first_error (gcc_jit_context@w{ }*ctxt) + +Returns the first error message that occurred on the context. + +The returned string is valid for the rest of the lifetime of the +context. + +If no errors occurred, this will be NULL. +@end deffn + +@node Debugging,Options<2>,Error-handling,Compilation contexts +@anchor{topics/contexts debugging}@anchor{3d} +@section Debugging + + +@geindex gcc_jit_context_dump_to_file (C function) +@anchor{topics/contexts gcc_jit_context_dump_to_file}@anchor{3e} +@deffn {C Function} void gcc_jit_context_dump_to_file (gcc_jit_context@w{ }*ctxt, const char@w{ }*path, int@w{ }update_locations) + +To help with debugging: dump a C-like representation to the given path, +describing what's been set up on the context. + +If "update_locations" is true, then also set up @pxref{3f,,gcc_jit_location} +information throughout the context, pointing at the dump file as if it +were a source file. This may be of use in conjunction with +@pxref{40,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to allow stepping through the +code in a debugger. +@end deffn + +@node Options<2>,,Debugging,Compilation contexts +@anchor{topics/contexts options}@anchor{41} +@section Options + + +@menu +* String Options:: +* Boolean options:: +* Integer options:: + +@end menu + +@node String Options,Boolean options,,Options<2> +@anchor{topics/contexts string-options}@anchor{42} +@subsection String Options + + +@geindex gcc_jit_context_set_str_option (C function) +@anchor{topics/contexts gcc_jit_context_set_str_option}@anchor{43} +@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) + +Set a string option of the context. + +@geindex gcc_jit_str_option (C type) +@anchor{topics/contexts gcc_jit_str_option}@anchor{44} +@deffn {C Type} enum gcc_jit_str_option +@end deffn + +There is currently just one string option: + +@geindex GCC_JIT_STR_OPTION_PROGNAME (C macro) +@anchor{topics/contexts GCC_JIT_STR_OPTION_PROGNAME}@anchor{45} +@deffn {C Macro} GCC_JIT_STR_OPTION_PROGNAME + +The name of the program, for use as a prefix when printing error +messages to stderr. If @cite{NULL}, or default, "libgccjit.so" is used. +@end deffn +@end deffn + +@node Boolean options,Integer options,String Options,Options<2> +@anchor{topics/contexts boolean-options}@anchor{46} +@subsection Boolean options + + +@geindex gcc_jit_context_set_bool_option (C function) +@anchor{topics/contexts gcc_jit_context_set_bool_option}@anchor{1c} +@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) + +Set a boolean option of the context. +Zero is "false" (the default), non-zero is "true". + +@geindex gcc_jit_bool_option (C type) +@anchor{topics/contexts gcc_jit_bool_option}@anchor{47} +@deffn {C Type} enum gcc_jit_bool_option +@end deffn + +@geindex GCC_JIT_BOOL_OPTION_DEBUGINFO (C macro) +@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DEBUGINFO}@anchor{40} +@deffn {C Macro} GCC_JIT_BOOL_OPTION_DEBUGINFO + +If true, @pxref{18,,gcc_jit_context_compile()} will attempt to do the right +thing so that if you attach a debugger to the process, it will +be able to inspect variables and step through your code. + +Note that you can't step through code unless you set up source +location information for the code (by creating and passing in +@pxref{3f,,gcc_jit_location} instances). +@end deffn + +@geindex GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE (C macro) +@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE}@anchor{48} +@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE + +If true, @pxref{18,,gcc_jit_context_compile()} will dump its initial +"tree" representation of your code to stderr (before any +optimizations). + +Here's some sample output (from the @cite{square} example): + +@example +<statement_list 0x7f4875a62cc0 + type <void_type 0x7f4875a64bd0 VOID + align 8 symtab 0 alias set -1 canonical type 0x7f4875a64bd0 + pointer_to_this <pointer_type 0x7f4875a64c78>> + side-effects head 0x7f4875a761e0 tail 0x7f4875a761f8 stmts 0x7f4875a62d20 0x7f4875a62d00 + + stmt <label_expr 0x7f4875a62d20 type <void_type 0x7f4875a64bd0> + side-effects + arg 0 <label_decl 0x7f4875a79080 entry type <void_type 0x7f4875a64bd0> + VOID file (null) line 0 col 0 + align 1 context <function_decl 0x7f4875a77500 square>>> + stmt <return_expr 0x7f4875a62d00 + type <integer_type 0x7f4875a645e8 public SI + size <integer_cst 0x7f4875a623a0 constant 32> + unit size <integer_cst 0x7f4875a623c0 constant 4> + align 32 symtab 0 alias set -1 canonical type 0x7f4875a645e8 precision 32 min <integer_cst 0x7f4875a62340 -2147483648> max <integer_cst 0x7f4875a62360 2147483647> + pointer_to_this <pointer_type 0x7f4875a6b348>> + side-effects + arg 0 <modify_expr 0x7f4875a72a78 type <integer_type 0x7f4875a645e8> + side-effects arg 0 <result_decl 0x7f4875a7a000 D.54> + arg 1 <mult_expr 0x7f4875a72a50 type <integer_type 0x7f4875a645e8> + arg 0 <parm_decl 0x7f4875a79000 i> arg 1 <parm_decl 0x7f4875a79000 i>>>>> +@end example + +@noindent +@end deffn + +@geindex GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE (C macro) +@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}@anchor{1d} +@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE + +If true, @pxref{18,,gcc_jit_context_compile()} will dump the "gimple" +representation of your code to stderr, before any optimizations +are performed. The dump resembles C code: + +@example +square (signed int i) +@{ + signed int D.56; + + entry: + D.56 = i * i; + return D.56; +@} +@end example + +@noindent +@end deffn + +@geindex GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE (C macro) +@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE}@anchor{1e} +@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE + +If true, @pxref{18,,gcc_jit_context_compile()} will dump the final +generated code to stderr, in the form of assembly language: + +@example + .file "fake.c" + .text + .globl square + .type square, @@function +square: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -4(%rbp) +.L2: + movl -4(%rbp), %eax + imull -4(%rbp), %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size square, .-square + .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.1-%@{gcc_release@})" + .section .note.GNU-stack,"",@@progbits +@end example + +@noindent +@end deffn + +@geindex GCC_JIT_BOOL_OPTION_DUMP_SUMMARY (C macro) +@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_SUMMARY}@anchor{49} +@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_SUMMARY + +If true, @pxref{18,,gcc_jit_context_compile()} will print information to stderr +on the actions it is performing, followed by a profile showing +the time taken and memory usage of each phase. +@end deffn + +@geindex GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING (C macro) +@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING}@anchor{4a} +@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING + +If true, @pxref{18,,gcc_jit_context_compile()} will dump copious +amount of information on what it's doing to various +files within a temporary directory. Use +@pxref{4b,,GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES} (see below) to +see the results. The files are intended to be human-readable, +but the exact files and their formats are subject to change. +@end deffn + +@geindex GCC_JIT_BOOL_OPTION_SELFCHECK_GC (C macro) +@anchor{topics/contexts GCC_JIT_BOOL_OPTION_SELFCHECK_GC}@anchor{4c} +@deffn {C Macro} GCC_JIT_BOOL_OPTION_SELFCHECK_GC + +If true, libgccjit will aggressively run its garbage collector, to +shake out bugs (greatly slowing down the compile). This is likely +to only be of interest to developers @emph{of} the library. It is +used when running the selftest suite. +@end deffn + +@geindex GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES (C macro) +@anchor{topics/contexts GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES}@anchor{4b} +@deffn {C Macro} GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES + +If true, the @pxref{b,,gcc_jit_context} will not clean up intermediate files +written to the filesystem, and will display their location on stderr. +@end deffn +@end deffn + +@node Integer options,,Boolean options,Options<2> +@anchor{topics/contexts integer-options}@anchor{4d} +@subsection Integer options + + +@geindex gcc_jit_context_set_int_option (C function) +@anchor{topics/contexts gcc_jit_context_set_int_option}@anchor{1f} +@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) + +Set an integer option of the context. + +@geindex gcc_jit_int_option (C type) +@anchor{topics/contexts gcc_jit_int_option}@anchor{4e} +@deffn {C Type} enum gcc_jit_int_option +@end deffn + +There is currently just one integer option: + +@geindex GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL (C macro) +@anchor{topics/contexts GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}@anchor{20} +@deffn {C Macro} GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL + +How much to optimize the code. + +Valid values are 0-3, corresponding to GCC's command-line options +-O0 through -O3. + +The default value is 0 (unoptimized). +@end deffn +@end deffn + +@c Copyright (C) 2014 Free Software Foundation, Inc. +@c Originally contributed by David Malcolm <dmalc...@redhat.com> +@c +@c This is free software: you can redistribute it and/or modify it +@c under the terms of the GNU General Public License as published by +@c the Free Software Foundation, either version 3 of the License, or +@c (at your option) any later version. +@c +@c This program is distributed in the hope that it will be useful, but +@c WITHOUT ANY WARRANTY; without even the implied warranty of +@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +@c General Public License for more details. +@c +@c You should have received a copy of the GNU General Public License +@c along with this program. If not, see +@c <http://www.gnu.org/licenses/>. + +@node Objects,Types,Compilation contexts,Top +@anchor{topics/objects objects}@anchor{4f}@anchor{topics/objects doc}@anchor{50} +@chapter Objects + + +@geindex gcc_jit_object (C type) +@anchor{topics/objects gcc_jit_object}@anchor{11} +@deffn {C Type} gcc_jit_object +@end deffn + +Almost every entity in the API (with the exception of +@pxref{b,,gcc_jit_context *} and @pxref{19,,gcc_jit_result *}) is a +"contextual" object, a @pxref{11,,gcc_jit_object *} + +A JIT object: + +@quotation + + +@itemize * + +@item +is associated with a @pxref{b,,gcc_jit_context *}. + +@item +is automatically cleaned up for you when its context is released so +you don't need to manually track and cleanup all objects, just the +contexts. +@end itemize +@end quotation + +Although the API is C-based, there is a form of class hierarchy, which +looks like this: + +@example ++- gcc_jit_object + +- gcc_jit_location + +- gcc_jit_type + +- gcc_jit_struct + +- gcc_jit_field + +- gcc_jit_function + +- gcc_jit_block + +- gcc_jit_rvalue + +- gcc_jit_lvalue + +- gcc_jit_param +@end example + +@noindent + +There are casting methods for upcasting from subclasses to parent classes. +For example, @pxref{10,,gcc_jit_type_as_object()}: + +@example +gcc_jit_object *obj = gcc_jit_type_as_object (int_type); +@end example + +@noindent + +The object "base class" has the following operations: + +@geindex gcc_jit_object_get_context (C function) +@anchor{topics/objects gcc_jit_object_get_context}@anchor{51} +@deffn {C Function} gcc_jit_context *gcc_jit_object_get_context (gcc_jit_object@w{ }*obj) + +Which context is "obj" within? +@end deffn + +@geindex gcc_jit_object_get_debug_string (C function) +@anchor{topics/objects gcc_jit_object_get_debug_string}@anchor{12} +@deffn {C Function} const char *gcc_jit_object_get_debug_string (gcc_jit_object@w{ }*obj) + +Generate a human-readable description for the given object. + +For example, + +@example +printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj)); +@end example + +@noindent + +might give this text on stdout: + +@example +obj: 4.0 * (float)i +@end example + +@noindent + +@cartouche +@quotation Note +If you call this on an object, the @cite{const char *} buffer is allocated +and generated on the first call for that object, and the buffer will +have the same lifetime as the object i.e. it will exist until the +object's context is released. +@end quotation +@end cartouche +@end deffn + +@c Copyright (C) 2014 Free Software Foundation, Inc. +@c Originally contributed by David Malcolm <dmalc...@redhat.com> +@c +@c This is free software: you can redistribute it and/or modify it +@c under the terms of the GNU General Public License as published by +@c the Free Software Foundation, either version 3 of the License, or +@c (at your option) any later version. +@c +@c This program is distributed in the hope that it will be useful, but +@c WITHOUT ANY WARRANTY; without even the implied warranty of +@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +@c General Public License for more details. +@c +@c You should have received a copy of the GNU General Public License +@c along with this program. If not, see +@c <http://www.gnu.org/licenses/>. + +@node Types,Expressions,Objects,Top +@anchor{topics/types doc}@anchor{52}@anchor{topics/types types}@anchor{53} +@chapter Types + + +@geindex gcc_jit_type (C type) +@anchor{topics/types gcc_jit_type}@anchor{d} +@deffn {C Type} gcc_jit_type + +gcc_jit_type represents a type within the library. +@end deffn + +@geindex gcc_jit_type_as_object (C function) +@anchor{topics/types gcc_jit_type_as_object}@anchor{10} +@deffn {C Function} gcc_jit_object *gcc_jit_type_as_object (gcc_jit_type@w{ }*type) + +Upcast a type to an object. +@end deffn + +Types can be created in several ways: + + +@itemize * + +@item +fundamental types can be accessed using +@pxref{e,,gcc_jit_context_get_type()}: + +@example +gcc_jit_type *int_type = gcc_jit_context_get_type (GCC_JIT_TYPE_INT); +@end example + +@noindent + +See @pxref{e,,gcc_jit_context_get_type()} for the available types. + +@item +derived types can be accessed by using functions such as +@pxref{54,,gcc_jit_type_get_pointer()} and @pxref{55,,gcc_jit_type_get_const()}: + +@example +gcc_jit_type *const_int_star = gcc_jit_type_get_pointer (gcc_jit_type_get_const (int_type)); +gcc_jit_type *int_const_star = gcc_jit_type_get_const (gcc_jit_type_get_pointer (int_type)); +@end example + +@noindent + +@item +by creating structures (see below). +@end itemize + +@menu +* Standard types:: +* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile. +* Structures and unions:: + +@end menu + +@node Standard types,Pointers const and volatile,,Types +@anchor{topics/types standard-types}@anchor{56} +@section Standard types + + +@geindex gcc_jit_context_get_type (C function) +@anchor{topics/types gcc_jit_context_get_type}@anchor{e} +@deffn {C Function} gcc_jit_type *gcc_jit_context_get_type (gcc_jit_context@w{ }*ctxt, enum gcc_jit_types@w{ }type_) + +Access a specific type. The available types are: + + +@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} +@headitem + +@cite{enum gcc_jit_types} value + +@tab + +Meaning + +@item + +@code{GCC_JIT_TYPE_VOID} + +@tab + +C's @code{void} type. + +@item + +@code{GCC_JIT_TYPE_VOID_PTR} + +@tab + +C's @code{void *}. + +@item + +@code{GCC_JIT_TYPE_BOOL} + +@tab + +C++'s @code{bool} type; also C99's +@code{_Bool} type, aka @code{bool} if +using stdbool.h. + +@item + +@code{GCC_JIT_TYPE_CHAR} + +@tab + +C's @code{char} (of some signedness) + +@item + +@code{GCC_JIT_TYPE_SIGNED_CHAR} + +@tab + +C's @code{signed char} + +@item + +@code{GCC_JIT_TYPE_UNSIGNED_CHAR} + +@tab + +C's @code{unsigned char} + +@item + +@code{GCC_JIT_TYPE_SHORT} + +@tab + +C's @code{short} (signed) + +@item + +@code{GCC_JIT_TYPE_UNSIGNED_SHORT} + +@tab + +C's @code{unsigned short} + +@item + +@code{GCC_JIT_TYPE_INT} + +@tab + +C's @code{int} (signed) + +@item + +@code{GCC_JIT_TYPE_UNSIGNED_INT} + +@tab + +C's @code{unsigned int} + +@item + +@code{GCC_JIT_TYPE_LONG} + +@tab + +C's @code{long} (signed) + +@item + +@code{GCC_JIT_TYPE_UNSIGNED_LONG} + +@tab + +C's @code{unsigned long} + +@item + +@code{GCC_JIT_TYPE_LONG_LONG} + +@tab + +C99's @code{long long} (signed) + +@item + +@code{GCC_JIT_TYPE_UNSIGNED_LONG_LONG} + +@tab + +C99's @code{unsigned long long} + +@item + +@code{GCC_JIT_TYPE_FLOAT} + +@tab + +@item + +@code{GCC_JIT_TYPE_DOUBLE} + +@tab + +@item + +@code{GCC_JIT_TYPE_LONG_DOUBLE} + +@tab + +@item + +@code{GCC_JIT_TYPE_CONST_CHAR_PTR} + +@tab + +C type: @code{(const char *)} + +@item + +@code{GCC_JIT_TYPE_SIZE_T} + +@tab + +C's @code{size_t} type + +@item + +@code{GCC_JIT_TYPE_FILE_PTR} + +@tab + +C type: @code{(FILE *)} + +@end multitable + +@end deffn + +@geindex gcc_jit_context_get_int_type (C function) +@anchor{topics/types gcc_jit_context_get_int_type}@anchor{57} +@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) + +Access the integer type of the given size. +@end deffn + +@node Pointers const and volatile,Structures and unions,Standard types,Types +@anchor{topics/types pointers-const-and-volatile}@anchor{58} +@section Pointers, @cite{const}, and @cite{volatile} + + +@geindex gcc_jit_type_get_pointer (C function) +@anchor{topics/types gcc_jit_type_get_pointer}@anchor{54} +@deffn {C Function} gcc_jit_type *gcc_jit_type_get_pointer (gcc_jit_type@w{ }*type) + +Given type "T", get type "T*". +@end deffn + +@geindex gcc_jit_type_get_const (C function) +@anchor{topics/types gcc_jit_type_get_const}@anchor{55} +@deffn {C Function} gcc_jit_type *gcc_jit_type_get_const (gcc_jit_type@w{ }*type) + +Given type "T", get type "const T". +@end deffn + +@geindex gcc_jit_type_get_volatile (C function) +@anchor{topics/types gcc_jit_type_get_volatile}@anchor{59} +@deffn {C Function} gcc_jit_type *gcc_jit_type_get_volatile (gcc_jit_type@w{ }*type) + +Given type "T", get type "volatile T". +@end deffn + +@geindex gcc_jit_context_new_array_type (C function) +@anchor{topics/types gcc_jit_context_new_array_type}@anchor{5a} +@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) + +Given type "T", get type "T[N]" (for a constant N). +@end deffn + +@node Structures and unions,,Pointers const and volatile,Types +@anchor{topics/types structures-and-unions}@anchor{5b} +@section Structures and unions + + +@geindex gcc_jit_struct (C type) +@anchor{topics/types gcc_jit_struct}@anchor{5c} +@deffn {C Type} gcc_jit_struct +@end deffn + +A compound type analagous to a C @cite{struct}. + +@geindex gcc_jit_field (C type) +@anchor{topics/types gcc_jit_field}@anchor{5d} +@deffn {C Type} gcc_jit_field +@end deffn + +A field within a @pxref{5c,,gcc_jit_struct}. + +You can model C @cite{struct} types by creating @pxref{5c,,gcc_jit_struct *} and +@pxref{5d,,gcc_jit_field} instances, in either order: + + +@itemize * + +@item +by creating the fields, then the structure. For example, to model: + +@example +struct coord @{double x; double y; @}; +@end example + +@noindent + +you could call: + +@example +gcc_jit_field *field_x = + gcc_jit_context_new_field (ctxt, NULL, double_type, "x"); +gcc_jit_field *field_y = + gcc_jit_context_new_field (ctxt, NULL, double_type, "y"); +gcc_jit_field *fields[2] = @{field_x, field_y@}; +gcc_jit_struct *coord = + gcc_jit_context_new_struct_type (ctxt, NULL, "coord", 2, fields); +@end example + +@noindent + +@item +by creating the structure, then populating it with fields, typically +to allow modelling self-referential structs such as: + +@example +struct node @{ int m_hash; struct node *m_next; @}; +@end example + +@noindent + +like this: + +@example +gcc_jit_type *node = + gcc_jit_context_new_opaque_struct (ctxt, NULL, "node"); +gcc_jit_type *node_ptr = + gcc_jit_type_get_pointer (node); +gcc_jit_field *field_hash = + gcc_jit_context_new_field (ctxt, NULL, int_type, "m_hash"); +gcc_jit_field *field_next = + gcc_jit_context_new_field (ctxt, NULL, node_ptr, "m_next"); +gcc_jit_field *fields[2] = @{field_hash, field_next@}; +gcc_jit_struct_set_fields (node, NULL, 2, fields); +@end example + +@noindent +@end itemize + +@geindex gcc_jit_context_new_field (C function) +@anchor{topics/types gcc_jit_context_new_field}@anchor{5e} +@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) + +Construct a new field, with the given type and name. +@end deffn + +@geindex gcc_jit_field_as_object (C function) +@anchor{topics/types gcc_jit_field_as_object}@anchor{5f} +@deffn {C Function} gcc_jit_object * gcc_jit_field_as_object (gcc_jit_field@w{ }*field) + +Upcast from field to object. +@end deffn + +@geindex gcc_jit_context_new_struct_type (C function) +@anchor{topics/types gcc_jit_context_new_struct_type}@anchor{60} +@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) + +@quotation + +Construct a new struct type, with the given name and fields. +@end quotation +@end deffn + +@geindex gcc_jit_context_new_opaque_struct (C function) +@anchor{topics/types gcc_jit_context_new_opaque_struct}@anchor{61} +@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) + +Construct a new struct type, with the given name, but without +specifying the fields. The fields can be omitted (in which case the +size of the struct is not known), or later specified using +@pxref{62,,gcc_jit_struct_set_fields()}. +@end deffn + +@geindex gcc_jit_struct_as_type (C function) +@anchor{topics/types gcc_jit_struct_as_type}@anchor{63} +@deffn {C Function} gcc_jit_type * gcc_jit_struct_as_type (gcc_jit_struct@w{ }*struct_type) + +Upcast from struct to type. +@end deffn + +@geindex gcc_jit_struct_set_fields (C function) +@anchor{topics/types gcc_jit_struct_set_fields}@anchor{62} +@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) + +Populate the fields of a formerly-opaque struct type. + +This can only be called once on a given struct type. +@end deffn + +@c Copyright (C) 2014 Free Software Foundation, Inc. +@c Originally contributed by David Malcolm <dmalc...@redhat.com> +@c +@c This is free software: you can redistribute it and/or modify it +@c under the terms of the GNU General Public License as published by +@c the Free Software Foundation, either version 3 of the License, or +@c (at your option) any later version. +@c +@c This program is distributed in the hope that it will be useful, but +@c WITHOUT ANY WARRANTY; without even the implied warranty of +@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +@c General Public License for more details. +@c +@c You should have received a copy of the GNU General Public License +@c along with this program. If not, see +@c <http://www.gnu.org/licenses/>. + +@node Expressions,Creating and using functions,Types,Top +@anchor{topics/expressions expressions}@anchor{64}@anchor{topics/expressions doc}@anchor{65} +@chapter Expressions + + +@menu +* Rvalues:: +* Lvalues:: +* Working with pointers@comma{} structs and unions: Working with pointers structs and unions. + +Rvalues + +* Simple expressions:: +* Unary Operations:: +* Binary Operations:: +* Comparisons:: +* Function calls:: +* Type-coercion:: + +Lvalues + +* Global variables:: + +@end menu + + +@node Rvalues,Lvalues,,Expressions +@anchor{topics/expressions rvalues}@anchor{66} +@section Rvalues + + +@geindex gcc_jit_rvalue (C type) +@anchor{topics/expressions gcc_jit_rvalue}@anchor{16} +@deffn {C Type} gcc_jit_rvalue +@end deffn + +A @pxref{16,,gcc_jit_rvalue *} is an expression that can be computed. + +It can be simple, e.g.: + +@quotation + + +@itemize * + +@item +an integer value e.g. @cite{0} or @cite{42} + +@item +a string literal e.g. @cite{"Hello world"} + +@item +a variable e.g. @cite{i}. These are also lvalues (see below). +@end itemize +@end quotation + +or compound e.g.: + +@quotation + + +@itemize * + +@item +a unary expression e.g. @cite{!cond} + +@item +a binary expression e.g. @cite{(a + b)} + +@item +a function call e.g. @cite{get_distance (&player_ship@comma{} &target)} + +@item +etc. +@end itemize +@end quotation + +Every rvalue has an associated type, and the API will check to ensure +that types match up correctly (otherwise the context will emit an error). + +@geindex gcc_jit_rvalue_get_type (C function) +@anchor{topics/expressions gcc_jit_rvalue_get_type}@anchor{67} +@deffn {C Function} gcc_jit_type *gcc_jit_rvalue_get_type (gcc_jit_rvalue@w{ }*rvalue) + +Get the type of this rvalue. +@end deffn + +@geindex gcc_jit_rvalue_as_object (C function) +@anchor{topics/expressions gcc_jit_rvalue_as_object}@anchor{17} +@deffn {C Function} gcc_jit_object *gcc_jit_rvalue_as_object (gcc_jit_rvalue@w{ }*rvalue) + +Upcast the given rvalue to be an object. +@end deffn + +@menu +* Simple expressions:: +* Unary Operations:: +* Binary Operations:: +* Comparisons:: +* Function calls:: +* Type-coercion:: + +@end menu + +@node Simple expressions,Unary Operations,,Rvalues +@anchor{topics/expressions simple-expressions}@anchor{68} +@subsection Simple expressions + + +@geindex gcc_jit_context_new_rvalue_from_int (C function) +@anchor{topics/expressions gcc_jit_context_new_rvalue_from_int}@anchor{31} +@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) + +Given a numeric type (integer or floating point), build an rvalue for +the given constant value. +@end deffn + +@geindex gcc_jit_context_zero (C function) +@anchor{topics/expressions gcc_jit_context_zero}@anchor{2c} +@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_zero (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type) + +Given a numeric type (integer or floating point), get the rvalue for +zero. Essentially this is just a shortcut for: + +@example +gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0) +@end example + +@noindent +@end deffn + +@geindex gcc_jit_context_one (C function) +@anchor{topics/expressions gcc_jit_context_one}@anchor{30} +@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_one (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type) + +Given a numeric type (integer or floating point), get the rvalue for +zero. Essentially this is just a shortcut for: + +@example +gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1) +@end example + +@noindent +@end deffn + +@geindex gcc_jit_context_new_rvalue_from_double (C function) +@anchor{topics/expressions gcc_jit_context_new_rvalue_from_double}@anchor{32} +@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) + +Given a numeric type (integer or floating point), build an rvalue for +the given constant value. +@end deffn + +@geindex gcc_jit_context_new_rvalue_from_ptr (C function) +@anchor{topics/expressions gcc_jit_context_new_rvalue_from_ptr}@anchor{69} +@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) + +Given a pointer type, build an rvalue for the given address. +@end deffn + +@geindex gcc_jit_context_null (C function) +@anchor{topics/expressions gcc_jit_context_null}@anchor{6a} +@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_null (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*pointer_type) + +Given a pointer type, build an rvalue for @code{NULL}. Essentially this +is just a shortcut for: + +@example +gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL) +@end example + +@noindent +@end deffn + +@geindex gcc_jit_context_new_string_literal (C function) +@anchor{topics/expressions gcc_jit_context_new_string_literal}@anchor{6b} +@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_string_literal (gcc_jit_context@w{ }*ctxt, const char@w{ }*value) + +Generate an rvalue for the given NIL-terminated string, of type +@code{GCC_JIT_TYPE_CONST_CHAR_PTR}. +@end deffn + +@node Unary Operations,Binary Operations,Simple expressions,Rvalues +@anchor{topics/expressions unary-operations}@anchor{6c} +@subsection Unary Operations + + +@geindex gcc_jit_context_new_unary_op (C function) +@anchor{topics/expressions gcc_jit_context_new_unary_op}@anchor{6d} +@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) + +Build a unary operation out of an input rvalue. +@end deffn + +@geindex gcc_jit_unary_op (C type) +@anchor{topics/expressions gcc_jit_unary_op}@anchor{6e} +@deffn {C Type} enum gcc_jit_unary_op +@end deffn + +The available unary operations are: + + +@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} +@headitem + +Unary Operation + +@tab + +C equivalent + +@item + +@pxref{6f,,GCC_JIT_UNARY_OP_MINUS} + +@tab + +@cite{-(EXPR)} + +@item + +@pxref{70,,GCC_JIT_UNARY_OP_BITWISE_NEGATE} + +@tab + +@cite{~(EXPR)} + +@item + +@pxref{71,,GCC_JIT_UNARY_OP_LOGICAL_NEGATE} + +@tab + +@cite{!(EXPR)} + +@end multitable + + +@geindex GCC_JIT_UNARY_OP_MINUS (C macro) +@anchor{topics/expressions GCC_JIT_UNARY_OP_MINUS}@anchor{6f} +@deffn {C Macro} GCC_JIT_UNARY_OP_MINUS + +Negate an arithmetic value; analogous to: + +@example +-(EXPR) +@end example + +@noindent + +in C. +@end deffn + +@geindex GCC_JIT_UNARY_OP_BITWISE_NEGATE (C macro) +@anchor{topics/expressions GCC_JIT_UNARY_OP_BITWISE_NEGATE}@anchor{70} +@deffn {C Macro} GCC_JIT_UNARY_OP_BITWISE_NEGATE + +Bitwise negation of an integer value (one's complement); analogous +to: + +@example +~(EXPR) +@end example + +@noindent + +in C. +@end deffn + +@geindex GCC_JIT_UNARY_OP_LOGICAL_NEGATE (C macro) +@anchor{topics/expressions GCC_JIT_UNARY_OP_LOGICAL_NEGATE}@anchor{71} +@deffn {C Macro} GCC_JIT_UNARY_OP_LOGICAL_NEGATE + +Logical negation of an arithmetic or pointer value; analogous to: + +@example +!(EXPR) +@end example + +@noindent + +in C. +@end deffn + +@node Binary Operations,Comparisons,Unary Operations,Rvalues +@anchor{topics/expressions binary-operations}@anchor{72} +@subsection Binary Operations + + +@geindex gcc_jit_context_new_binary_op (C function) +@anchor{topics/expressions gcc_jit_context_new_binary_op}@anchor{15} +@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) + +Build a binary operation out of two constituent rvalues. +@end deffn + +@geindex gcc_jit_binary_op (C type) +@anchor{topics/expressions gcc_jit_binary_op}@anchor{73} +@deffn {C Type} enum gcc_jit_binary_op +@end deffn + +The available binary operations are: + + +@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} +@headitem + +Binary Operation + +@tab + +C equivalent + +@item + +@pxref{74,,GCC_JIT_BINARY_OP_PLUS} + +@tab + +@cite{x + y} + +@item + +@code{GCC_JIT_BINARY_OP_MINUS} + +@tab + +@cite{x - y} + +@item + +@pxref{75,,GCC_JIT_BINARY_OP_MULT} + +@tab + +@cite{x * y} + +@item + +@pxref{76,,GCC_JIT_BINARY_OP_DIVIDE} + +@tab + +@cite{x / y} + +@item + +@pxref{77,,GCC_JIT_BINARY_OP_MODULO} + +@tab + +@cite{x % y} + +@item + +@pxref{78,,GCC_JIT_BINARY_OP_BITWISE_AND} + +@tab + +@cite{x & y} + +@item + +@pxref{79,,GCC_JIT_BINARY_OP_BITWISE_XOR} + +@tab + +@cite{x ^ y} + +@item + +@pxref{7a,,GCC_JIT_BINARY_OP_BITWISE_OR} + +@tab + +@cite{x | y} + +@item + +@pxref{7b,,GCC_JIT_BINARY_OP_LOGICAL_AND} + +@tab + +@cite{x && y} + +@item + +@pxref{7c,,GCC_JIT_BINARY_OP_LOGICAL_OR} + +@tab + +@cite{x || y} + +@end multitable + + +@geindex GCC_JIT_BINARY_OP_PLUS (C macro) +@anchor{topics/expressions GCC_JIT_BINARY_OP_PLUS}@anchor{74} +@deffn {C Macro} GCC_JIT_BINARY_OP_PLUS + +Addition of arithmetic values; analogous to: + +@example +(EXPR_A) + (EXPR_B) +@end example + +@noindent + +in C. + +For pointer addition, use @pxref{7d,,gcc_jit_context_new_array_access()}. +@end deffn + + +@deffn {C Macro} GCC_JIT_BINARY_OP_MINUS` + +Subtraction of arithmetic values; analogous to: + +@example +(EXPR_A) - (EXPR_B) +@end example + +@noindent + +in C. +@end deffn + +@geindex GCC_JIT_BINARY_OP_MULT (C macro) +@anchor{topics/expressions GCC_JIT_BINARY_OP_MULT}@anchor{75} +@deffn {C Macro} GCC_JIT_BINARY_OP_MULT + +Multiplication of a pair of arithmetic values; analogous to: + +@example +(EXPR_A) * (EXPR_B) +@end example + +@noindent + +in C. +@end deffn + +@geindex GCC_JIT_BINARY_OP_DIVIDE (C macro) +@anchor{topics/expressions GCC_JIT_BINARY_OP_DIVIDE}@anchor{76} +@deffn {C Macro} GCC_JIT_BINARY_OP_DIVIDE + +Quotient of division of arithmetic values; analogous to: + +@example +(EXPR_A) / (EXPR_B) +@end example + +@noindent + +in C. + +The result type affects the kind of division: if the result type is +integer-based, then the result is truncated towards zero, whereas +a floating-point result type indicates floating-point division. +@end deffn + +@geindex GCC_JIT_BINARY_OP_MODULO (C macro) +@anchor{topics/expressions GCC_JIT_BINARY_OP_MODULO}@anchor{77} +@deffn {C Macro} GCC_JIT_BINARY_OP_MODULO + +Remainder of division of arithmetic values; analogous to: + +@example +(EXPR_A) % (EXPR_B) +@end example + +@noindent + +in C. +@end deffn + +@geindex GCC_JIT_BINARY_OP_BITWISE_AND (C macro) +@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_AND}@anchor{78} +@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_AND + +Bitwise AND; analogous to: + +@example +(EXPR_A) & (EXPR_B) +@end example + +@noindent + +in C. +@end deffn + +@geindex GCC_JIT_BINARY_OP_BITWISE_XOR (C macro) +@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_XOR}@anchor{79} +@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_XOR + +Bitwise exclusive OR; analogous to: + +@example +(EXPR_A) ^ (EXPR_B) +@end example + +@noindent + +in C. +@end deffn + +@geindex GCC_JIT_BINARY_OP_BITWISE_OR (C macro) +@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_OR}@anchor{7a} +@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_OR + +Bitwise inclusive OR; analogous to: + +@example +(EXPR_A) | (EXPR_B) +@end example + +@noindent + +in C. +@end deffn + +@geindex GCC_JIT_BINARY_OP_LOGICAL_AND (C macro) +@anchor{topics/expressions GCC_JIT_BINARY_OP_LOGICAL_AND}@anchor{7b} +@deffn {C Macro} GCC_JIT_BINARY_OP_LOGICAL_AND + +Logical AND; analogous to: + +@example +(EXPR_A) && (EXPR_B) +@end example + +@noindent + +in C. +@end deffn + +@geindex GCC_JIT_BINARY_OP_LOGICAL_OR (C macro) +@anchor{topics/expressions GCC_JIT_BINARY_OP_LOGICAL_OR}@anchor{7c} +@deffn {C Macro} GCC_JIT_BINARY_OP_LOGICAL_OR + +Logical OR; analogous to: + +@example +(EXPR_A) || (EXPR_B) +@end example + +@noindent + +in C. +@end deffn + +@node Comparisons,Function calls,Binary Operations,Rvalues +@anchor{topics/expressions comparisons}@anchor{7e} +@subsection Comparisons + + +@geindex gcc_jit_context_new_comparison (C function) +@anchor{topics/expressions gcc_jit_context_new_comparison}@anchor{2d} +@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) + +Build a boolean rvalue out of the comparison of two other rvalues. +@end deffn + +@geindex gcc_jit_comparison (C type) +@anchor{topics/expressions gcc_jit_comparison}@anchor{7f} +@deffn {C Type} enum gcc_jit_comparison +@end deffn + + +@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} +@headitem + +Comparison + +@tab + +C equivalent + +@item + +@code{GCC_JIT_COMPARISON_EQ} + +@tab + +@cite{x == y} + +@item + +@code{GCC_JIT_COMPARISON_NE} + +@tab + +@cite{x != y} + +@item + +@code{GCC_JIT_COMPARISON_LT} + +@tab + +@cite{x < y} + +@item + +@code{GCC_JIT_COMPARISON_LE} + +@tab + +@cite{x <= y} + +@item + +@code{GCC_JIT_COMPARISON_GT} + +@tab + +@cite{x > y} + +@item + +@code{GCC_JIT_COMPARISON_GE} + +@tab + +@cite{x >= y} + +@end multitable + + +@node Function calls,Type-coercion,Comparisons,Rvalues +@anchor{topics/expressions function-calls}@anchor{80} +@subsection Function calls + + +@geindex gcc_jit_context_new_call (C function) +@anchor{topics/expressions gcc_jit_context_new_call}@anchor{81} +@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) + +Given a function and the given table of argument rvalues, construct a +call to the function, with the result as an rvalue. +@end deffn + +@node Type-coercion,,Function calls,Rvalues +@anchor{topics/expressions type-coercion}@anchor{82} +@subsection Type-coercion + + +@geindex gcc_jit_context_new_cast (C function) +@anchor{topics/expressions gcc_jit_context_new_cast}@anchor{83} +@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) + +Given an rvalue of T, construct another rvalue of another type. + +Currently only a limited set of conversions are possible: + +@quotation + + +@itemize * + +@item +int <-> float + +@item +int <-> bool +@end itemize +@end quotation +@end deffn + +@node Lvalues,Working with pointers structs and unions,Rvalues,Expressions +@anchor{topics/expressions lvalues}@anchor{84} +@section Lvalues + + +@geindex gcc_jit_lvalue (C type) +@anchor{topics/expressions gcc_jit_lvalue}@anchor{25} +@deffn {C Type} gcc_jit_lvalue +@end deffn + +An lvalue is something that can of the @emph{left}-hand side of an assignment: +a storage area (such as a variable). It is also usable as an rvalue, +where the rvalue is computed by reading from the storage area. + +@geindex gcc_jit_lvalue_as_object (C function) +@anchor{topics/expressions gcc_jit_lvalue_as_object}@anchor{85} +@deffn {C Function} gcc_jit_object * gcc_jit_lvalue_as_object (gcc_jit_lvalue@w{ }*lvalue) + +Upcast an lvalue to be an object. +@end deffn + +@geindex gcc_jit_lvalue_as_rvalue (C function) +@anchor{topics/expressions gcc_jit_lvalue_as_rvalue}@anchor{86} +@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue@w{ }*lvalue) + +Upcast an lvalue to be an rvalue. +@end deffn + +@geindex gcc_jit_lvalue_get_address (C function) +@anchor{topics/expressions gcc_jit_lvalue_get_address}@anchor{87} +@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_get_address (gcc_jit_lvalue@w{ }*lvalue, gcc_jit_location@w{ }*loc) + +Take the address of an lvalue; analogous to: + +@example +&(EXPR) +@end example + +@noindent + +in C. +@end deffn + +@menu +* Global variables:: + +@end menu + +@node Global variables,,,Lvalues +@anchor{topics/expressions global-variables}@anchor{88} +@subsection Global variables + + +@geindex gcc_jit_context_new_global (C function) +@anchor{topics/expressions gcc_jit_context_new_global}@anchor{89} +@deffn {C Function} gcc_jit_lvalue * gcc_jit_context_new_global (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, const char@w{ }*name) + +Add a new global variable of the given type and name to the context. +@end deffn + +@node Working with pointers structs and unions,,Lvalues,Expressions +@anchor{topics/expressions working-with-pointers-structs-and-unions}@anchor{8a} +@section Working with pointers, structs and unions + + +@geindex gcc_jit_rvalue_dereference (C function) +@anchor{topics/expressions gcc_jit_rvalue_dereference}@anchor{8b} +@deffn {C Function} gcc_jit_lvalue * gcc_jit_rvalue_dereference (gcc_jit_rvalue@w{ }*rvalue, gcc_jit_location@w{ }*loc) + +Given an rvalue of pointer type @code{T *}, dereferencing the pointer, +getting an lvalue of type @code{T}. Analogous to: + +@example +*(EXPR) +@end example + +@noindent + +in C. +@end deffn + +Field access is provided separately for both lvalues and rvalues. + +@geindex gcc_jit_lvalue_access_field (C function) +@anchor{topics/expressions gcc_jit_lvalue_access_field}@anchor{8c} +@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) + +Given an lvalue of struct or union type, access the given field, +getting an lvalue of the field's type. Analogous to: + +@example +(EXPR).field = ...; +@end example + +@noindent + +in C. +@end deffn + +@geindex gcc_jit_rvalue_access_field (C function) +@anchor{topics/expressions gcc_jit_rvalue_access_field}@anchor{8d} +@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) + +Given an rvalue of struct or union type, access the given field +as an rvalue. Analogous to: + +@example +(EXPR).field +@end example + +@noindent + +in C. +@end deffn + +@geindex gcc_jit_rvalue_dereference_field (C function) +@anchor{topics/expressions gcc_jit_rvalue_dereference_field}@anchor{8e} +@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) + +Given an rvalue of pointer type @code{T *} where T is of struct or union +type, access the given field as an lvalue. Analogous to: + +@example +(EXPR)->field +@end example + +@noindent + +in C, itself equivalent to @code{(*EXPR).FIELD}. +@end deffn + +@geindex gcc_jit_context_new_array_access (C function) +@anchor{topics/expressions gcc_jit_context_new_array_access}@anchor{7d} +@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) + +Given an rvalue of pointer type @code{T *}, get at the element @cite{T} at +the given index, using standard C array indexing rules i.e. each +increment of @code{index} corresponds to @code{sizeof(T)} bytes. +Analogous to: + +@example +PTR[INDEX] +@end example + +@noindent + +in C (or, indeed, to @code{PTR + INDEX}). +@end deffn + +@c Copyright (C) 2014 Free Software Foundation, Inc. +@c Originally contributed by David Malcolm <dmalc...@redhat.com> +@c +@c This is free software: you can redistribute it and/or modify it +@c under the terms of the GNU General Public License as published by +@c the Free Software Foundation, either version 3 of the License, or +@c (at your option) any later version. +@c +@c This program is distributed in the hope that it will be useful, but +@c WITHOUT ANY WARRANTY; without even the implied warranty of +@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +@c General Public License for more details. +@c +@c You should have received a copy of the GNU General Public License +@c along with this program. If not, see +@c <http://www.gnu.org/licenses/>. + +@node Creating and using functions,Source Locations,Expressions,Top +@anchor{topics/functions doc}@anchor{8f}@anchor{topics/functions creating-and-using-functions}@anchor{90} +@chapter Creating and using functions + + +@menu +* Params:: +* Functions:: +* Blocks:: +* Statements:: + +@end menu + +@node Params,Functions,,Creating and using functions +@anchor{topics/functions params}@anchor{91} +@section Params + + +@geindex gcc_jit_param (C type) +@anchor{topics/functions gcc_jit_param}@anchor{26} +@deffn {C Type} gcc_jit_param + +A @cite{gcc_jit_param} represents a parameter to a function. +@end deffn + +@geindex gcc_jit_context_new_param (C function) +@anchor{topics/functions gcc_jit_context_new_param}@anchor{13} +@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) + +In preparation for creating a function, create a new parameter of the +given type and name. +@end deffn + +Parameters are lvalues, and thus are also rvalues (and objects), so the +following upcasts are available: + +@geindex gcc_jit_param_as_lvalue (C function) +@anchor{topics/functions gcc_jit_param_as_lvalue}@anchor{92} +@deffn {C Function} gcc_jit_lvalue * gcc_jit_param_as_lvalue (gcc_jit_param@w{ }*param) + +Upcasting from param to lvalue. +@end deffn + +@geindex gcc_jit_param_as_rvalue (C function) +@anchor{topics/functions gcc_jit_param_as_rvalue}@anchor{93} +@deffn {C Function} gcc_jit_rvalue * gcc_jit_param_as_rvalue (gcc_jit_param@w{ }*param) + +Upcasting from param to rvalue. +@end deffn + +@geindex gcc_jit_param_as_object (C function) +@anchor{topics/functions gcc_jit_param_as_object}@anchor{94} +@deffn {C Function} gcc_jit_object * gcc_jit_param_as_object (gcc_jit_param@w{ }*param) + +Upcasting from param to object. +@end deffn + +@node Functions,Blocks,Params,Creating and using functions +@anchor{topics/functions functions}@anchor{95} +@section Functions + + +@geindex gcc_jit_function (C type) +@anchor{topics/functions gcc_jit_function}@anchor{2a} +@deffn {C Type} gcc_jit_function + +A @cite{gcc_jit_function} represents a function - either one that we're +creating ourselves, or one that we're referencing. +@end deffn + +@geindex gcc_jit_context_new_function (C function) +@anchor{topics/functions gcc_jit_context_new_function}@anchor{14} +@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) + +Create a gcc_jit_function with the given name and parameters. + +@geindex gcc_jit_function_kind (C type) +@anchor{topics/functions gcc_jit_function_kind}@anchor{96} +@deffn {C Type} enum gcc_jit_function_kind +@end deffn + +This enum controls the kind of function created, and has the following +values: + +@quotation + +@geindex GCC_JIT_FUNCTION_EXPORTED (C macro) +@anchor{topics/functions GCC_JIT_FUNCTION_EXPORTED}@anchor{97} +@deffn {C Macro} GCC_JIT_FUNCTION_EXPORTED + +Function is defined by the client code and visible +by name outside of the JIT. +@end deffn + +@geindex GCC_JIT_FUNCTION_INTERNAL (C macro) +@anchor{topics/functions GCC_JIT_FUNCTION_INTERNAL}@anchor{98} +@deffn {C Macro} GCC_JIT_FUNCTION_INTERNAL + +Function is defined by the client code, but is invisible +outside of the JIT. Analogous to a "static" function. +@end deffn + +@geindex GCC_JIT_FUNCTION_IMPORTED (C macro) +@anchor{topics/functions GCC_JIT_FUNCTION_IMPORTED}@anchor{99} +@deffn {C Macro} GCC_JIT_FUNCTION_IMPORTED + +Function is not defined by the client code; we're merely +referring to it. Analogous to using an "extern" function from a +header file. +@end deffn + +@geindex GCC_JIT_FUNCTION_ALWAYS_INLINE (C macro) +@anchor{topics/functions GCC_JIT_FUNCTION_ALWAYS_INLINE}@anchor{9a} +@deffn {C Macro} GCC_JIT_FUNCTION_ALWAYS_INLINE + +Function is only ever inlined into other functions, and is +invisible outside of the JIT. + +Analogous to prefixing with @code{inline} and adding +@code{__attribute__((always_inline))} + +Inlining will only occur when the optimization level is +above 0; when optimization is off, this is essentially the +same as GCC_JIT_FUNCTION_INTERNAL. +@end deffn +@end quotation +@end deffn + +@geindex gcc_jit_context_get_builtin_function (C function) +@anchor{topics/functions gcc_jit_context_get_builtin_function}@anchor{9b} +@deffn {C Function} gcc_jit_function *gcc_jit_context_get_builtin_function (gcc_jit_context@w{ }*ctxt, const char@w{ }*name) +@end deffn + +@geindex gcc_jit_function_as_object (C function) +@anchor{topics/functions gcc_jit_function_as_object}@anchor{9c} +@deffn {C Function} gcc_jit_object * gcc_jit_function_as_object (gcc_jit_function@w{ }*func) + +Upcasting from function to object. +@end deffn + +@geindex gcc_jit_function_get_param (C function) +@anchor{topics/functions gcc_jit_function_get_param}@anchor{9d} +@deffn {C Function} gcc_jit_param * gcc_jit_function_get_param (gcc_jit_function@w{ }*func, int@w{ }index) + +Get the param of the given index (0-based). +@end deffn + +@geindex gcc_jit_function_dump_to_dot (C function) +@anchor{topics/functions gcc_jit_function_dump_to_dot}@anchor{34} +@deffn {C Function} void gcc_jit_function_dump_to_dot (gcc_jit_function@w{ }*func, const char@w{ }*path) + +Emit the function in graphviz format to the given path. +@end deffn + +@geindex gcc_jit_function_new_local (C function) +@anchor{topics/functions gcc_jit_function_new_local}@anchor{27} +@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) + +Create a new local variable within the function, of the given type and +name. +@end deffn + +@node Blocks,Statements,Functions,Creating and using functions +@anchor{topics/functions blocks}@anchor{9e} +@section Blocks + + +@geindex gcc_jit_block (C type) +@anchor{topics/functions gcc_jit_block}@anchor{29} +@deffn {C Type} gcc_jit_block + +A @cite{gcc_jit_block} represents a basic block within a function i.e. a +sequence of statements with a single entry point and a single exit +point. + +The first basic block that you create within a function will +be the entrypoint. + +Each basic block that you create within a function must be +terminated, either with a conditional, a jump, or a return. + +It's legal to have multiple basic blocks that return within +one function. +@end deffn + +@geindex gcc_jit_function_new_block (C function) +@anchor{topics/functions gcc_jit_function_new_block}@anchor{9f} +@deffn {C Function} gcc_jit_block * gcc_jit_function_new_block (gcc_jit_function@w{ }*func, const char@w{ }*name) + +Create a basic block of the given name. The name may be NULL, but +providing meaningful names is often helpful when debugging: it may +show up in dumps of the internal representation, and in error +messages. +@end deffn + +@geindex gcc_jit_block_as_object (C function) +@anchor{topics/functions gcc_jit_block_as_object}@anchor{a0} +@deffn {C Function} gcc_jit_object * gcc_jit_block_as_object (gcc_jit_block@w{ }*block) + +Upcast from block to object. +@end deffn + +@geindex gcc_jit_block_get_function (C function) +@anchor{topics/functions gcc_jit_block_get_function}@anchor{a1} +@deffn {C Function} gcc_jit_function * gcc_jit_block_get_function (gcc_jit_block@w{ }*block) + +Which function is this block within? +@end deffn + +@node Statements,,Blocks,Creating and using functions +@anchor{topics/functions statements}@anchor{a2} +@section Statements + + +@geindex gcc_jit_block_add_eval (C function) +@anchor{topics/functions gcc_jit_block_add_eval}@anchor{a3} +@deffn {C Function} void gcc_jit_block_add_eval (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*rvalue) + +Add evaluation of an rvalue, discarding the result +(e.g. a function call that "returns" void). + +This is equivalent to this C code: + +@example +(void)expression; +@end example + +@noindent +@end deffn + +@geindex gcc_jit_block_add_assignment (C function) +@anchor{topics/functions gcc_jit_block_add_assignment}@anchor{2b} +@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) + +Add evaluation of an rvalue, assigning the result to the given +lvalue. + +This is roughly equivalent to this C code: + +@example +lvalue = rvalue; +@end example + +@noindent +@end deffn + +@geindex gcc_jit_block_add_assignment_op (C function) +@anchor{topics/functions gcc_jit_block_add_assignment_op}@anchor{2f} +@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) + +Add evaluation of an rvalue, using the result to modify an +lvalue. + +This is analogous to "+=" and friends: + +@example +lvalue += rvalue; +lvalue *= rvalue; +lvalue /= rvalue; +@end example + +@noindent + +etc. +@end deffn + +@geindex gcc_jit_block_add_comment (C function) +@anchor{topics/functions gcc_jit_block_add_comment}@anchor{a4} +@deffn {C Function} void gcc_jit_block_add_comment (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, const char@w{ }*text) + +Add a no-op textual comment to the internal representation of the +code. It will be optimized away, but will be visible in the dumps +seen via @pxref{48,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE} +and @pxref{1d,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}, +and thus may be of use when debugging how your project's internal +representation gets converted to the libgccjit IR. +@end deffn + +@geindex gcc_jit_block_end_with_conditional (C function) +@anchor{topics/functions gcc_jit_block_end_with_conditional}@anchor{2e} +@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) + +Terminate a block by adding evaluation of an rvalue, branching on the +result to the appropriate successor block. + +This is roughly equivalent to this C code: + +@example +if (boolval) + goto on_true; +else + goto on_false; +@end example + +@noindent + +block, boolval, on_true, and on_false must be non-NULL. +@end deffn + +@geindex gcc_jit_block_end_with_jump (C function) +@anchor{topics/functions gcc_jit_block_end_with_jump}@anchor{a5} +@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) + +Terminate a block by adding a jump to the given target block. + +This is roughly equivalent to this C code: + +@example +goto target; +@end example + +@noindent +@end deffn + +@geindex gcc_jit_block_end_with_return (C function) +@anchor{topics/functions gcc_jit_block_end_with_return}@anchor{a6} +@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) + +Terminate a block by adding evaluation of an rvalue, returning the value. + +This is roughly equivalent to this C code: + +@example +return expression; +@end example + +@noindent +@end deffn + +@geindex gcc_jit_block_end_with_void_return (C function) +@anchor{topics/functions gcc_jit_block_end_with_void_return}@anchor{a7} +@deffn {C Function} void gcc_jit_block_end_with_void_return (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc) + +Terminate a block by adding a valueless return, for use within a function +with "void" return type. + +This is equivalent to this C code: + +@example +return; +@end example + +@noindent +@end deffn + +@c Copyright (C) 2014 Free Software Foundation, Inc. +@c Originally contributed by David Malcolm <dmalc...@redhat.com> +@c +@c This is free software: you can redistribute it and/or modify it +@c under the terms of the GNU General Public License as published by +@c the Free Software Foundation, either version 3 of the License, or +@c (at your option) any later version. +@c +@c This program is distributed in the hope that it will be useful, but +@c WITHOUT ANY WARRANTY; without even the implied warranty of +@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +@c General Public License for more details. +@c +@c You should have received a copy of the GNU General Public License +@c along with this program. If not, see +@c <http://www.gnu.org/licenses/>. + +@node Source Locations,Compilation results,Creating and using functions,Top +@anchor{topics/locations source-locations}@anchor{a8}@anchor{topics/locations doc}@anchor{a9} +@chapter Source Locations + + +@geindex gcc_jit_location (C type) +@anchor{topics/locations gcc_jit_location}@anchor{3f} +@deffn {C Type} gcc_jit_location + +A @cite{gcc_jit_location} encapsulates a source code location, so that +you can (optionally) associate locations in your language with +statements in the JIT-compiled code, allowing the debugger to +single-step through your language. + +@cite{gcc_jit_location} instances are optional: you can always pass NULL to +any API entrypoint accepting one. + +You can construct them using @pxref{aa,,gcc_jit_context_new_location()}. + +You need to enable @pxref{40,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the +@pxref{b,,gcc_jit_context} for these locations to actually be usable by +the debugger: + +@example +gcc_jit_context_set_bool_option ( + ctxt, + GCC_JIT_BOOL_OPTION_DEBUGINFO, + 1); +@end example + +@noindent +@end deffn + +@geindex gcc_jit_context_new_location (C function) +@anchor{topics/locations gcc_jit_context_new_location}@anchor{aa} +@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) + +Create a @cite{gcc_jit_location} instance representing the given source +location. +@end deffn + +@menu +* Faking it:: + +@end menu + +@node Faking it,,,Source Locations +@anchor{topics/locations faking-it}@anchor{ab} +@section Faking it + + +If you don't have source code for your internal representation, but need +to debug, you can generate a C-like representation of the functions in +your context using @pxref{3e,,gcc_jit_context_dump_to_file()}: + +@example +gcc_jit_context_dump_to_file (ctxt, "/tmp/something.c", + 1 /* update_locations */); +@end example + +@noindent + +This will dump C-like code to the given path. If the @cite{update_locations} +argument is true, this will also set up @cite{gcc_jit_location} information +throughout the context, pointing at the dump file as if it were a source +file, giving you @emph{something} you can step through in the debugger. + +@c Copyright (C) 2014 Free Software Foundation, Inc. +@c Originally contributed by David Malcolm <dmalc...@redhat.com> +@c +@c This is free software: you can redistribute it and/or modify it +@c under the terms of the GNU General Public License as published by +@c the Free Software Foundation, either version 3 of the License, or +@c (at your option) any later version. +@c +@c This program is distributed in the hope that it will be useful, but +@c WITHOUT ANY WARRANTY; without even the implied warranty of +@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +@c General Public License for more details. +@c +@c You should have received a copy of the GNU General Public License +@c along with this program. If not, see +@c <http://www.gnu.org/licenses/>. + +@node Compilation results,Indices and tables,Source Locations,Top +@anchor{topics/results compilation-results}@anchor{ac}@anchor{topics/results doc}@anchor{ad} +@chapter Compilation results + + +@geindex gcc_jit_result (C type) +@anchor{topics/results gcc_jit_result}@anchor{19} +@deffn {C Type} gcc_jit_result + +A @cite{gcc_jit_result} encapsulates the result of compiling a context. +@end deffn + +@geindex gcc_jit_context_compile (C function) +@anchor{topics/results gcc_jit_context_compile}@anchor{18} +@deffn {C Function} gcc_jit_result * gcc_jit_context_compile (gcc_jit_context@w{ }*ctxt) + +This calls into GCC and builds the code, returning a +@cite{gcc_jit_result *}. +@end deffn + +@geindex gcc_jit_result_get_code (C function) +@anchor{topics/results gcc_jit_result_get_code}@anchor{1a} +@deffn {C Function} void * gcc_jit_result_get_code (gcc_jit_result@w{ }*result, const char@w{ }*funcname) + +Locate a given function within the built machine code. +This will need to be cast to a function pointer of the +correct type before it can be called. +@end deffn + +@geindex gcc_jit_result_release (C function) +@anchor{topics/results gcc_jit_result_release}@anchor{ae} +@deffn {C Function} void gcc_jit_result_release (gcc_jit_result@w{ }*result) + +Once we're done with the code, this unloads the built .so file. +This cleans up the result; after calling this, it's no longer +valid to use the result. +@end deffn + +This document describes libgccjit@footnote{http://gcc.gnu.org/wiki/JIT}, an API +for embedding GCC inside programs and libraries. + +Note that libgccjit is currently of "Alpha" quality; +the APIs are not yet set in stone, and they shouldn't be used in +production yet. + +@node Indices and tables,Index,Compilation results,Top +@anchor{index indices-and-tables}@anchor{af} +@unnumbered Indices and tables + + + +@itemize * + +@item +@emph{genindex} + +@item +@emph{modindex} + +@item +@emph{search} +@end itemize + +@c Some notes: +@c +@c The Sphinx C domain appears to lack explicit support for enum values, +@c so I've been using :c:macro: for them. +@c +@c See http://sphinx-doc.org/domains.html#the-c-domain + +@node Index,,Indices and tables,Top +@unnumbered Index + + +@printindex ge + +@c %**end of body +@bye diff --git a/gcc/jit/docs/_build/texinfo/sum-of-squares.png b/gcc/jit/docs/_build/texinfo/sum-of-squares.png new file mode 100644 index 0000000000000000000000000000000000000000..7a3b4afff38e2f365ef2a09df997cb98d032fbcb GIT binary patch literal 22839 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 literal 0 HcmV?d00001 -- 1.7.11.7