@@ -1,3 +1,23 @@
+2014-09-17 David Malcolm <dmalcolm@redhat.com>
+
+ * docs/Makefile: New file.
+ * docs/conf.py: New file.
+ * docs/examples/install-hello-world.c: New file.
+ * docs/examples/tut01-square.c: New file.
+ * docs/examples/tut02-sum-of-squares.c: New file.
+ * docs/index.rst: New file.
+ * docs/intro/install.rst: New file.
+ * docs/intro/sum-of-squares.png: New file.
+ * docs/intro/tutorial01.rst: New file.
+ * docs/intro/tutorial02.rst: New file.
+ * docs/topics/contexts.rst: New file.
+ * docs/topics/expressions.rst: New file.
+ * docs/topics/functions.rst: New file.
+ * docs/topics/locations.rst: New file.
+ * docs/topics/objects.rst: New file.
+ * docs/topics/results.rst: New file.
+ * docs/topics/types.rst: New file.
+
2014-09-11 David Malcolm <dmalcolm@redhat.com>
* TODO.rst (Initial Release): Update for addition of myself as
new file mode 100644
@@ -0,0 +1,153 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ -rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/libgccjit.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/libgccjit.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/libgccjit"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/libgccjit"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
new file mode 100644
@@ -0,0 +1,242 @@
+# -*- coding: utf-8 -*-
+#
+# libgccjit documentation build configuration file, created by
+# sphinx-quickstart on Wed Jul 30 13:39:01 2014.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = []
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'libgccjit'
+copyright = u'2014, Free Software Foundation'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0.1'
+# The full version, including alpha/beta/rc tags.
+release = '0.1'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'libgccjitdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+ ('index', 'libgccjit.tex', u'libgccjit Documentation',
+ u'David Malcolm', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'libgccjit', u'libgccjit Documentation',
+ [u'David Malcolm'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output ------------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ ('index', 'libgccjit', u'libgccjit Documentation',
+ u'David Malcolm', 'libgccjit', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
new file mode 100644
@@ -0,0 +1,103 @@
+#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);
+}
new file mode 100644
@@ -0,0 +1,87 @@
+#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);
+}
new file mode 100644
@@ -0,0 +1,152 @@
+#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);
+}
new file mode 100644
@@ -0,0 +1,57 @@
+.. Copyright (C) 2014 Free Software Foundation, Inc.
+ Originally contributed by David Malcolm <dmalcolm@redhat.com>
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+
+libgccjit
+=========
+
+Contents:
+
+.. toctree::
+ :maxdepth: 2
+
+ intro/install.rst
+ intro/tutorial01.rst
+ intro/tutorial02.rst
+ topics/contexts.rst
+ topics/objects.rst
+ topics/types.rst
+ topics/expressions.rst
+ topics/functions.rst
+ topics/locations.rst
+ topics/results.rst
+
+This document describes `libgccjit <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.
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
+.. Some notes:
+
+ The Sphinx C domain appears to lack explicit support for enum values,
+ so I've been using :c:macro: for them.
+
+ See http://sphinx-doc.org/domains.html#the-c-domain
new file mode 100644
@@ -0,0 +1,179 @@
+.. Copyright (C) 2014 Free Software Foundation, Inc.
+ Originally contributed by David Malcolm <dmalcolm@redhat.com>
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+
+.. default-domain:: c
+
+Getting Started
+---------------
+
+Installation via packages
+=========================
+
+It's easiest to use pre-built packages of the library.
+
+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 https://copr.fedoraproject.org/coprs/dmalcolm/libgccjit/
+for information on subscribing to the appropriate repository for
+your system. Having done this,
+
+.. code-block:: bash
+
+ sudo yum install libgccjit-devel
+
+should give you both the JIT library (`libgccjit`) and the header files
+needed to develop against it (`libgccjit-devel`)::
+
+ [david@c64 ~]$ 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
+ [david@c64 ~]$ 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
+
+
+Other distributions
+*******************
+
+Prebuilt packages for other distributions would be most welcome; please
+contact the `jit mailing list`_.
+
+
+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).
+
+The code can currently be seen within the git branch "dmalcolm/jit" here:
+ http://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/dmalcolm/jit
+
+The following will check out a copy of the appropriate branch, to the
+"jit/src" subdirectory:
+
+.. code-block:: bash
+
+ mkdir jit
+ cd jit
+ git clone \
+ -b dmalcolm/jit \
+ git://gcc.gnu.org/git/gcc.git \
+ src
+
+The source tree currently occupies about 2.8G of disk space.
+
+To build it (within the "jit/build" subdirectory, installing to
+"jit/install"):
+
+.. code-block:: bash
+
+ 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
+
+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::
+
+ [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
+
+Note that this is a branch of GCC, so if it fails to build, you might want
+to consult the `general GCC FAQ <https://gcc.gnu.org/wiki/FAQ>`_ for some
+common issues, before checking on the `jit mailing list`_.
+
+.. _jit mailing list: https://gcc.gnu.org/ml/jit/
+
+You should then be able to install it (to the `--prefix` specified
+earlier) via:
+
+.. code-block:: bash
+
+ make install
+
+On my laptop this uses a further 0.4G of disk space.
+
+You should be able to see the header files within the `include`
+subdirectory of the installation prefix::
+
+ $ 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
+
+and the library within the `lib` subdirectory::
+
+ $ 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
+
+
+"Hello world"
+=============
+
+Here's a trivial "hello world" program that uses the library to synthesize
+a call to `printf` and use it to write a message to stdout.
+
+ .. literalinclude:: ../examples/install-hello-world.c
+ :language: c
+
+Copy it to `jit-hello-world.c`.
+
+To build it with prebuilt packages, use::
+
+ $ gcc \
+ jit-hello-world.c \
+ -o jit-hello-world \
+ -lgccjit
+
+ # Run the built program:
+ $ ./jit-hello-world
+ hello world
+
+
+If building against an locally-built install (to $PREFIX), specify the
+include and library paths with -I and -L::
+
+ $ gcc \
+ jit-hello-world.c \
+ -o jit-hello-world \
+ -lgccjit \
+ -I$PREFIX/include -L$PREFIX/lib
+
+and when running, specify the dynamic linkage path via LD_LIBRARY_PATH::
+
+ $ LD_LIBRARY_PATH=$PREFIX/lib ./jit-hello-world
+ hello world
new file mode 100644
GIT binary patch
literal 22839
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
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,349 @@
+.. Copyright (C) 2014 Free Software Foundation, Inc.
+ Originally contributed by David Malcolm <dmalcolm@redhat.com>
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+
+.. default-domain:: c
+
+Tutorial part 1: Creating a trivial machine code function
+---------------------------------------------------------
+
+Consider this C function:
+
+.. code-block:: c
+
+ int square (int i)
+ {
+ return i * i;
+ }
+
+How can we construct this at run-time using libgccjit?
+
+.. FIXME
+
+First we need to include the relevant header:
+
+.. code-block:: c
+
+ #include "libgccjit.h"
+
+All state associated with compilation is associated with a
+:c:type:`gcc_jit_context *`.
+
+Create one using :c:func:`gcc_jit_context_acquire`:
+
+.. code-block:: c
+
+ gcc_jit_context *ctxt;
+ ctxt = gcc_jit_context_acquire ();
+
+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 `int` type, so let's obtain this from
+the context, as a :c:type:`gcc_jit_type *`, using
+:c:func:`gcc_jit_context_get_type`:
+
+.. code-block:: c
+
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+
+:c:type:`gcc_jit_type *` is an example of a "contextual" object: every
+entity in the API is associated with a :c:type:`gcc_jit_context *`.
+
+Memory management is easy: all such "contextual" objects are automatically
+cleaned up for you when the context is released, using
+:c:func:`gcc_jit_context_release`:
+
+.. code-block:: c
+
+ gcc_jit_context_release (ctxt);
+
+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::
+
+ +- 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
+
+There are casting methods for upcasting from subclasses to parent classes.
+For example, :c:func:`gcc_jit_type_as_object`:
+
+.. code-block:: c
+
+ gcc_jit_object *obj = gcc_jit_type_as_object (int_type);
+
+One thing you can do with a :c:type:`gcc_jit_object *` is
+to ask it for a human-readable description, using
+:c:func:`gcc_jit_object_get_debug_string`:
+
+.. code-block:: c
+
+ printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj));
+
+giving this text on stdout:
+
+.. code-block:: bash
+
+ obj: int
+
+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 :c:func:`gcc_jit_context_new_param`:
+
+.. code-block:: c
+
+ gcc_jit_param *param_i =
+ gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
+
+Now we can create the function, using
+:c:func:`gcc_jit_context_new_function`:
+
+.. code-block:: c
+
+ gcc_jit_function *func =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ int_type,
+ "square",
+ 1, ¶m_i,
+ 0);
+
+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:
+
+.. code-block:: c
+
+ gcc_jit_block *block = gcc_jit_function_new_block (func, NULL);
+
+Our basic block is relatively simple: it immediately terminates by
+returning the value of an expression.
+
+We can build the expression using :c:func:`gcc_jit_context_new_binary_op`:
+
+.. code-block:: c
+
+ 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));
+
+A :c:type:`gcc_jit_rvalue *` is another example of a
+:c:type:`gcc_jit_object *` subclass. We can upcast it using
+:c:func:`gcc_jit_rvalue_as_object` and as before print it with
+:c:func:`gcc_jit_object_get_debug_string`.
+
+.. code-block:: c
+
+ printf ("expr: %s\n",
+ gcc_jit_object_get_debug_string (
+ gcc_jit_rvalue_as_object (expr)));
+
+giving this output:
+
+.. code-block:: bash
+
+ expr: i * i
+
+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:
+
+.. code-block:: c
+
+ gcc_jit_block_end_with_return (block, NULL, expr);
+
+OK, we've populated the context. We can now compile it using
+:c:func:`gcc_jit_context_compile`:
+
+.. code-block:: c
+
+ gcc_jit_result *result;
+ result = gcc_jit_context_compile (ctxt);
+
+and get a :c:type:`gcc_jit_result *`.
+
+We can now use :c:func:`gcc_jit_result_get_code` to look up a specific
+machine code routine within the result, in this case, the function we
+created above.
+
+.. code-block:: c
+
+ void *fn_ptr = gcc_jit_result_get_code (result, "square");
+ if (!fn_ptr)
+ {
+ fprintf (stderr, "NULL fn_ptr");
+ goto error;
+ }
+
+We can now cast the pointer to an appropriate function pointer type, and
+then call it:
+
+.. code-block:: c
+
+ typedef int (*fn_type) (int);
+ fn_type square = (fn_type)fn_ptr;
+ printf ("result: %d", square (5));
+
+.. code-block:: bash
+
+ result: 25
+
+
+Options
+*******
+
+To get more information on what's going on, you can set debugging flags
+on the context using :c:func:`gcc_jit_context_set_bool_option`.
+
+.. (I'm deliberately not mentioning
+ :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think
+ it's probably more of use to implementors than to users)
+
+Setting :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE` will dump a
+C-like representation to stderr when you compile (GCC's "GIMPLE"
+representation):
+
+.. code-block:: c
+
+ gcc_jit_context_set_bool_option (
+ ctxt,
+ GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE,
+ 1);
+ result = gcc_jit_context_compile (ctxt);
+
+.. code-block:: c
+
+ square (signed int i)
+ {
+ signed int D.260;
+
+ entry:
+ D.260 = i * i;
+ return D.260;
+ }
+
+We can see the generated machine code in assembler form (on stderr) by
+setting :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE` on the context
+before compiling:
+
+.. code-block:: c
+
+ gcc_jit_context_set_bool_option (
+ ctxt,
+ GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE,
+ 1);
+ result = gcc_jit_context_compile (ctxt);
+
+.. code-block:: asm
+
+ .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
+
+By default, no optimizations are performed, the equivalent of GCC's
+`-O0` option. We can turn things up to e.g. `-O3` by calling
+:c:func:`gcc_jit_context_set_int_option` with
+:c:macro:`GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL`:
+
+.. code-block:: c
+
+ gcc_jit_context_set_int_option (
+ ctxt,
+ GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
+ 3);
+
+.. code-block:: asm
+
+ .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
+
+Naturally this has only a small effect on such a trivial function.
+
+
+Full example
+************
+
+Here's what the above looks like as a complete program:
+
+ .. literalinclude:: ../examples/tut01-square.c
+ :lines: 1-
+ :language: c
+
+Building and running it::
+
+ $ gcc \
+ tut01-square.c \
+ -o tut01-square \
+ -lgccjit
+
+ # Run the built program:
+ $ ./tut01-square
+ result: 25
new file mode 100644
@@ -0,0 +1,376 @@
+.. Copyright (C) 2014 Free Software Foundation, Inc.
+ Originally contributed by David Malcolm <dmalcolm@redhat.com>
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+
+Tutorial part 2: Loops and variables
+------------------------------------
+Consider this C function:
+
+ .. code-block:: c
+
+ int loop_test (int n)
+ {
+ int sum = 0;
+ for (int i = 0; i < n; i++)
+ sum += i * i;
+ return sum;
+ }
+
+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 `for` loop as a `while` loop, giving:
+
+ .. code-block:: c
+
+ int loop_test (int n)
+ {
+ int sum = 0;
+ int i = 0;
+ while (i < n)
+ {
+ sum += i * i;
+ i++;
+ }
+ return sum;
+ }
+
+Here's what the final control flow graph will look like:
+
+ .. figure:: sum-of-squares.png
+ :alt: image of a control flow graph
+
+As before, we include the libgccjit header and make a
+:c:type:`gcc_jit_context *`.
+
+.. code-block:: c
+
+ #include "libgccjit.h"
+
+ void test (void)
+ {
+ gcc_jit_context *ctxt;
+ ctxt = gcc_jit_context_acquire ();
+
+The function works with the C `int` type:
+
+.. code-block:: c
+
+ gcc_jit_type *the_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_type *return_type = the_type;
+
+though we could equally well make it work on, say, `double`:
+
+.. code-block:: c
+
+ gcc_jit_type *the_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE);
+
+Let's build the function:
+
+.. code-block:: c
+
+ 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);
+
+Expressions: lvalues and rvalues
+********************************
+
+The base class of expression is the :c:type:`gcc_jit_rvalue *`,
+representing an expression that can be on the *right*-hand side of
+an assignment: a value that can be computed somehow, and assigned
+*to* a storage area (such as a variable). It has a specific
+:c:type:`gcc_jit_type *`.
+
+Anothe important class is :c:type:`gcc_jit_lvalue *`.
+A :c:type:`gcc_jit_lvalue *`. is something that can of the *left*-hand
+side of an assignment: a storage area (such as a variable).
+
+In other words, every assignment can be thought of as:
+
+.. code-block:: c
+
+ LVALUE = RVALUE;
+
+Note that :c:type:`gcc_jit_lvalue *` is a subclass of
+:c:type:`gcc_jit_rvalue *`, where in an assignment of the form:
+
+.. code-block:: c
+
+ LVALUE_A = LVALUE_B;
+
+the `LVALUE_B` implies reading the current value of that storage
+area, assigning it into the `LVALUE_A`.
+
+So far the only expressions we've seen are `i * i`:
+
+.. code-block:: c
+
+ 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));
+
+which is a :c:type:`gcc_jit_rvalue *`, and the various function
+parameters: `param_i` and `param_n`, instances of
+:c:type:`gcc_jit_param *`, which is a subclass of
+:c:type:`gcc_jit_lvalue *` (and, in turn, of :c:type:`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 :c:func:`gcc_jit_function_new_local`, supplying a type and a
+name:
+
+.. code-block:: c
+
+ /* 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");
+
+These are instances of :c:type:`gcc_jit_lvalue *` - they can be read from
+and written to.
+
+Note that there is no precanned way to create *and* initialize a variable
+like in C:
+
+.. code-block:: c
+
+ int i = 0;
+
+Instead, having added the local to the function, we have to separately add
+an assignment of `0` to `local_i` at the beginning of the function.
+
+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:
+
+1. before the loop (initializing the locals)
+2. the conditional at the top of the loop (comparing `i < n`)
+3. the body of the loop
+4. after the loop terminates (`return sum`)
+
+so we create these as :c:type:`gcc_jit_block *` instances within the
+:c:type:`gcc_jit_function *`:
+
+.. code-block:: c
+
+ 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");
+
+We now populate each block with statements.
+
+The entry block `b_initial` consists of initializations followed by a jump
+to the conditional. We assign `0` to `i` and to `sum`, using
+:c:func:`gcc_jit_block_add_assignment` to add
+an assignment statement, and using :c:func:`gcc_jit_context_zero` to get
+the constant value `0` for the relevant type for the right-hand side of
+the assignment:
+
+.. code-block:: c
+
+ /* 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));
+
+We can then terminate the entry block by jumping to the conditional:
+
+.. code-block:: c
+
+ gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond);
+
+The conditional block is equivalent to the line `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
+:c:type:`gcc_jit_rvalue *`, in this case the comparison of `i` and `n`.
+We build the comparison using :c:func:`gcc_jit_context_new_comparison`:
+
+.. code-block:: c
+
+ 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));
+
+and can then use this to add `b_loop_cond`'s sole statement, via
+:c:func:`gcc_jit_block_end_with_conditional`:
+
+.. code-block:: c
+
+ gcc_jit_block_end_with_conditional (b_loop_cond, NULL, guard);
+
+Next, we populate the body of the loop.
+
+The C statement `sum += i * i;` is an assignment operation, where an
+lvalue is modified "in-place". We use
+:c:func:`gcc_jit_block_add_assignment_op` to handle these operations:
+
+.. code-block:: c
+
+ /* 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)));
+
+The `i++` can be thought of as `i += 1`, and can thus be handled in
+a similar way. We use :c:func:`gcc_jit_context_one` to get the constant
+value `1` (for the relevant type) for the right-hand side
+of the assignment.
+
+.. code-block:: c
+
+ /* i++ */
+ gcc_jit_block_add_assignment_op (
+ b_loop_body, NULL,
+ i,
+ GCC_JIT_BINARY_OP_PLUS,
+ gcc_jit_context_one (ctxt, the_type));
+
+.. note::
+
+ For numeric constants other than 0 or 1, we could use
+ :c:func:`gcc_jit_context_new_rvalue_from_int` and
+ :c:func:`gcc_jit_context_new_rvalue_from_double`.
+
+The loop body completes by jumping back to the conditional:
+
+.. code-block:: c
+
+ gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond);
+
+Finally, we populate the `b_after_loop` block, reached when the loop
+conditional is false. We want to generate the equivalent of:
+
+.. code-block:: c
+
+ return sum;
+
+so the block is just one statement:
+
+.. code-block:: c
+
+ /* return sum */
+ gcc_jit_block_end_with_return (
+ b_after_loop,
+ NULL,
+ gcc_jit_lvalue_as_rvalue (sum));
+
+.. 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,
+ *then* all the statements.
+
+We've finished populating the function. As before, we can now compile it
+to machine code:
+
+.. code-block:: c
+
+ 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));
+
+.. code-block:: bash
+
+ result: 285
+
+
+Visualizing the control flow graph
+**********************************
+
+You can see the control flow graph of a function using
+:c:func:`gcc_jit_function_dump_to_dot`:
+
+.. code-block:: c
+
+ gcc_jit_function_dump_to_dot (func, "/tmp/sum-of-squares.dot");
+
+giving a .dot file in GraphViz format.
+
+You can convert this to an image using `dot`:
+
+.. code-block:: bash
+
+ $ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png
+
+or use a viewer (my preferred one is xdot.py; see
+https://github.com/jrfonseca/xdot.py; on Fedora you can
+install it with `yum install python-xdot`):
+
+ .. figure:: sum-of-squares.png
+ :alt: image of a control flow graph
+
+Full example
+************
+
+ .. literalinclude:: ../examples/tut02-sum-of-squares.c
+ :lines: 1-
+ :language: c
+
+Building and running it::
+
+ $ gcc \
+ tut02-sum-of-squares.c \
+ -o tut02-sum-of-squares \
+ -lgccjit
+
+ # Run the built program:
+ $ ./tut02-sum-of-squares
+ loop_test returned: 285
new file mode 100644
@@ -0,0 +1,305 @@
+.. Copyright (C) 2014 Free Software Foundation, Inc.
+ Originally contributed by David Malcolm <dmalcolm@redhat.com>
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+
+.. default-domain:: c
+
+Compilation contexts
+====================
+
+.. type:: gcc_jit_context
+
+The top-level of the API is the :c:type:`gcc_jit_context` type.
+
+A :c:type:`gcc_jit_context` instance encapsulates the state of a
+compilation.
+
+You can set up options on it, and add types, functions and code.
+Invoking :c:func:`gcc_jit_context_compile` on it gives you a
+:c:type:`gcc_jit_result`.
+
+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.
+
+.. function:: gcc_jit_context *gcc_jit_context_acquire (void)
+
+ This function acquires a new :c:type:`gcc_jit_object *` instance,
+ which is independent of any others that may be present within this
+ process.
+
+.. function:: void gcc_jit_context_release (gcc_jit_context *ctxt)
+
+ This function releases all resources associated with the given context.
+ Both the context itself and all of its :c:type:`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.
+
+ .. code-block:: c
+
+ gcc_jit_context_release (ctxt);
+
+.. function:: gcc_jit_context * gcc_jit_context_new_child_context (gcc_jit_context *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.
+
+
+Thread-safety
+-------------
+Instances of :c:type:`gcc_jit_object *` created via
+:c:func:`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 :c:func:`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.
+
+
+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
+:c:func:`gcc_jit_context_get_first_error`.
+
+.. function:: const char *\
+ gcc_jit_context_get_first_error (gcc_jit_context *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.
+
+Debugging
+---------
+
+.. function:: void\
+ gcc_jit_context_dump_to_file (gcc_jit_context *ctxt,\
+ const char *path,\
+ int 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 :type:`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
+ :macro:`GCC_JIT_BOOL_OPTION_DEBUGINFO` to allow stepping through the
+ code in a debugger.
+
+
+Options
+-------
+
+String Options
+**************
+
+.. function:: void gcc_jit_context_set_str_option(gcc_jit_context *ctxt, \
+ enum gcc_jit_str_option opt, \
+ const char *value)
+
+ Set a string option of the context.
+
+ There is currently just one string option:
+
+ .. describe:: GCC_JIT_STR_OPTION_PROGNAME
+
+ The name of the program, for use as a prefix when printing error
+ messages to stderr. If `NULL`, or default, "libgccjit.so" is used.
+
+Boolean options
+***************
+
+.. function:: void gcc_jit_context_set_bool_option(gcc_jit_context *ctxt, \
+ enum gcc_jit_bool_option opt, \
+ int value)
+
+ Set a boolean option of the context.
+ Zero is "false" (the default), non-zero is "true".
+
+ .. macro:: GCC_JIT_BOOL_OPTION_DEBUGINFO
+
+ If true, :func:`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
+ :type:`gcc_jit_location` instances).
+
+ .. macro:: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE
+
+ If true, :func:`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 `square` 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>>>>>
+
+ .. macro:: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE
+
+ If true, :func:`gcc_jit_context_compile` will dump the "gimple"
+ representation of your code to stderr, before any optimizations
+ are performed. The dump resembles C code::
+
+ square (signed int i)
+ {
+ signed int D.56;
+
+ entry:
+ D.56 = i * i;
+ return D.56;
+ }
+
+ .. macro:: GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE
+
+ If true, :func:`gcc_jit_context_compile` will dump the final
+ generated code to stderr, in the form of assembly language::
+
+ .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
+
+
+ .. macro:: GCC_JIT_BOOL_OPTION_DUMP_SUMMARY
+
+ If true, :func:`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.
+
+ .. macro:: GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING
+
+ If true, :func:`gcc_jit_context_compile` will dump copious
+ amount of information on what it's doing to various
+ files within a temporary directory. Use
+ :macro:`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.
+
+ .. 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 *of* the library. It is
+ used when running the selftest suite.
+
+ .. macro:: GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES
+
+ If true, the :type:`gcc_jit_context` will not clean up intermediate files
+ written to the filesystem, and will display their location on stderr.
+
+Integer options
+***************
+
+.. function:: void gcc_jit_context_set_int_option (gcc_jit_context *ctxt, \
+ enum gcc_jit_int_option opt, \
+ int value)
+
+ Set an integer option of the context.
+
+ There is currently just one integer option:
+
+ .. 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).
new file mode 100644
@@ -0,0 +1,463 @@
+.. Copyright (C) 2014 Free Software Foundation, Inc.
+ Originally contributed by David Malcolm <dmalcolm@redhat.com>
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+
+.. default-domain:: c
+
+Expressions
+===========
+
+Rvalues
+-------
+.. type:: gcc_jit_rvalue
+
+A :c:type:`gcc_jit_rvalue *` is an expression that can be computed.
+
+It can be simple, e.g.:
+
+ * an integer value e.g. `0` or `42`
+ * a string literal e.g. `"Hello world"`
+ * a variable e.g. `i`. These are also lvalues (see below).
+
+or compound e.g.:
+
+ * a unary expression e.g. `!cond`
+ * a binary expression e.g. `(a + b)`
+ * a function call e.g. `get_distance (&player_ship, &target)`
+ * etc.
+
+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).
+
+.. function:: gcc_jit_type *gcc_jit_rvalue_get_type (gcc_jit_rvalue *rvalue)
+
+ Get the type of this rvalue.
+
+.. function:: gcc_jit_object *gcc_jit_rvalue_as_object (gcc_jit_rvalue *rvalue)
+
+ Upcast the given rvalue to be an object.
+
+
+Simple expressions
+******************
+
+.. function:: gcc_jit_rvalue *\
+ gcc_jit_context_new_rvalue_from_int (gcc_jit_context *ctxt, \
+ gcc_jit_type *numeric_type, \
+ int value)
+
+ Given a numeric type (integer or floating point), build an rvalue for
+ the given constant value.
+
+.. function:: gcc_jit_rvalue *gcc_jit_context_zero (gcc_jit_context *ctxt, \
+ gcc_jit_type *numeric_type)
+
+ Given a numeric type (integer or floating point), get the rvalue for
+ zero. Essentially this is just a shortcut for::
+
+ gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0);
+
+.. function:: gcc_jit_rvalue *gcc_jit_context_one (gcc_jit_context *ctxt, \
+ gcc_jit_type *numeric_type)
+
+ Given a numeric type (integer or floating point), get the rvalue for
+ zero. Essentially this is just a shortcut for::
+
+ gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1)
+
+.. function:: gcc_jit_rvalue *\
+ gcc_jit_context_new_rvalue_from_double (gcc_jit_context *ctxt, \
+ gcc_jit_type *numeric_type, \
+ double value)
+
+ Given a numeric type (integer or floating point), build an rvalue for
+ the given constant value.
+
+.. function:: gcc_jit_rvalue *\
+ gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context *ctxt, \
+ gcc_jit_type *pointer_type, \
+ void *value)
+
+ Given a pointer type, build an rvalue for the given address.
+
+.. function:: gcc_jit_rvalue *gcc_jit_context_null (gcc_jit_context *ctxt, \
+ gcc_jit_type *pointer_type)
+
+ Given a pointer type, build an rvalue for ``NULL``. Essentially this
+ is just a shortcut for::
+
+ gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL)
+
+.. function:: gcc_jit_rvalue *\
+ gcc_jit_context_new_string_literal (gcc_jit_context *ctxt, \
+ const char *value)
+
+ Generate an rvalue for the given NIL-terminated string, of type
+ :c:data:`GCC_JIT_TYPE_CONST_CHAR_PTR`.
+
+
+Unary Operations
+****************
+
+.. function:: gcc_jit_rvalue * \
+ gcc_jit_context_new_unary_op (gcc_jit_context *ctxt, \
+ gcc_jit_location *loc, \
+ enum gcc_jit_unary_op op, \
+ gcc_jit_type *result_type, \
+ gcc_jit_rvalue *rvalue)
+
+ Build a unary operation out of an input rvalue.
+
+.. type:: enum gcc_jit_unary_op
+
+The available unary operations are:
+
+========================================== ============
+Unary Operation C equivalent
+========================================== ============
+:c:macro:`GCC_JIT_UNARY_OP_MINUS` `-(EXPR)`
+:c:macro:`GCC_JIT_UNARY_OP_BITWISE_NEGATE` `~(EXPR)`
+:c:macro:`GCC_JIT_UNARY_OP_LOGICAL_NEGATE` `!(EXPR)`
+========================================== ============
+
+.. c:macro:: GCC_JIT_UNARY_OP_MINUS
+
+ Negate an arithmetic value; analogous to:
+
+ .. code-block:: c
+
+ -(EXPR)
+
+ in C.
+
+.. c:macro:: GCC_JIT_UNARY_OP_BITWISE_NEGATE
+
+ Bitwise negation of an integer value (one's complement); analogous
+ to:
+
+ .. code-block:: c
+
+ ~(EXPR)
+
+ in C.
+
+.. c:macro:: GCC_JIT_UNARY_OP_LOGICAL_NEGATE
+
+ Logical negation of an arithmetic or pointer value; analogous to:
+
+ .. code-block:: c
+
+ !(EXPR)
+
+ in C.
+
+Binary Operations
+*****************
+
+.. function:: gcc_jit_rvalue *gcc_jit_context_new_binary_op (gcc_jit_context *ctxt, \
+ gcc_jit_location *loc, \
+ enum gcc_jit_binary_op op, \
+ gcc_jit_type *result_type, \
+ gcc_jit_rvalue *a, gcc_jit_rvalue *b)
+
+ Build a binary operation out of two constituent rvalues.
+
+.. type:: enum gcc_jit_binary_op
+
+The available binary operations are:
+
+======================================== ============
+Binary Operation C equivalent
+======================================== ============
+:c:macro:`GCC_JIT_BINARY_OP_PLUS` `x + y`
+:c:macro:`GCC_JIT_BINARY_OP_MINUS` `x - y`
+:c:macro:`GCC_JIT_BINARY_OP_MULT` `x * y`
+:c:macro:`GCC_JIT_BINARY_OP_DIVIDE` `x / y`
+:c:macro:`GCC_JIT_BINARY_OP_MODULO` `x % y`
+:c:macro:`GCC_JIT_BINARY_OP_BITWISE_AND` `x & y`
+:c:macro:`GCC_JIT_BINARY_OP_BITWISE_XOR` `x ^ y`
+:c:macro:`GCC_JIT_BINARY_OP_BITWISE_OR` `x | y`
+:c:macro:`GCC_JIT_BINARY_OP_LOGICAL_AND` `x && y`
+:c:macro:`GCC_JIT_BINARY_OP_LOGICAL_OR` `x || y`
+======================================== ============
+
+.. c:macro:: GCC_JIT_BINARY_OP_PLUS
+
+ Addition of arithmetic values; analogous to:
+
+ .. code-block:: c
+
+ (EXPR_A) + (EXPR_B)
+
+ in C.
+
+ For pointer addition, use :c:func:`gcc_jit_context_new_array_access`.
+
+.. c:macro:: GCC_JIT_BINARY_OP_MINUS`
+
+ Subtraction of arithmetic values; analogous to:
+
+ .. code-block:: c
+
+ (EXPR_A) - (EXPR_B)
+
+ in C.
+
+.. c:macro:: GCC_JIT_BINARY_OP_MULT
+
+ Multiplication of a pair of arithmetic values; analogous to:
+
+ .. code-block:: c
+
+ (EXPR_A) * (EXPR_B)
+
+ in C.
+
+.. c:macro:: GCC_JIT_BINARY_OP_DIVIDE
+
+ Quotient of division of arithmetic values; analogous to:
+
+ .. code-block:: c
+
+ (EXPR_A) / (EXPR_B)
+
+ 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.
+
+.. c:macro:: GCC_JIT_BINARY_OP_MODULO
+
+ Remainder of division of arithmetic values; analogous to:
+
+ .. code-block:: c
+
+ (EXPR_A) % (EXPR_B)
+
+ in C.
+
+.. c:macro:: GCC_JIT_BINARY_OP_BITWISE_AND
+
+ Bitwise AND; analogous to:
+
+ .. code-block:: c
+
+ (EXPR_A) & (EXPR_B)
+
+ in C.
+
+.. c:macro:: GCC_JIT_BINARY_OP_BITWISE_XOR
+
+ Bitwise exclusive OR; analogous to:
+
+ .. code-block:: c
+
+ (EXPR_A) ^ (EXPR_B)
+
+ in C.
+
+.. c:macro:: GCC_JIT_BINARY_OP_BITWISE_OR
+
+ Bitwise inclusive OR; analogous to:
+
+ .. code-block:: c
+
+ (EXPR_A) | (EXPR_B)
+
+ in C.
+
+.. c:macro:: GCC_JIT_BINARY_OP_LOGICAL_AND
+
+ Logical AND; analogous to:
+
+ .. code-block:: c
+
+ (EXPR_A) && (EXPR_B)
+
+ in C.
+
+.. c:macro:: GCC_JIT_BINARY_OP_LOGICAL_OR
+
+ Logical OR; analogous to:
+
+ .. code-block:: c
+
+ (EXPR_A) || (EXPR_B)
+
+ in C.
+
+Comparisons
+***********
+
+.. function:: gcc_jit_rvalue *\
+ gcc_jit_context_new_comparison (gcc_jit_context *ctxt,\
+ gcc_jit_location *loc,\
+ enum gcc_jit_comparison op,\
+ gcc_jit_rvalue *a, gcc_jit_rvalue *b)
+
+ Build a boolean rvalue out of the comparison of two other rvalues.
+
+.. type:: enum gcc_jit_comparison
+
+======================================= ============
+Comparison C equivalent
+======================================= ============
+:c:macro:`GCC_JIT_COMPARISON_EQ` `x == y`
+:c:macro:`GCC_JIT_COMPARISON_NE` `x != y`
+:c:macro:`GCC_JIT_COMPARISON_LT` `x < y`
+:c:macro:`GCC_JIT_COMPARISON_LE` `x <= y`
+:c:macro:`GCC_JIT_COMPARISON_GT` `x > y`
+:c:macro:`GCC_JIT_COMPARISON_GE` `x >= y`
+======================================= ============
+
+
+Function calls
+**************
+.. function:: gcc_jit_rvalue *\
+ gcc_jit_context_new_call (gcc_jit_context *ctxt,\
+ gcc_jit_location *loc,\
+ gcc_jit_function *func,\
+ int numargs , gcc_jit_rvalue **args)
+
+ Given a function and the given table of argument rvalues, construct a
+ call to the function, with the result as an rvalue.
+
+Type-coercion
+*************
+
+.. function:: gcc_jit_rvalue *\
+ gcc_jit_context_new_cast (gcc_jit_context *ctxt,\
+ gcc_jit_location *loc,\
+ gcc_jit_rvalue *rvalue,\
+ gcc_jit_type *type)
+
+ Given an rvalue of T, construct another rvalue of another type.
+
+ Currently only a limited set of conversions are possible:
+
+ * int <-> float
+ * int <-> bool
+
+Lvalues
+-------
+
+.. type:: gcc_jit_lvalue
+
+An lvalue is something that can of the *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.
+
+.. function:: gcc_jit_object *\
+ gcc_jit_lvalue_as_object (gcc_jit_lvalue *lvalue)
+
+ Upcast an lvalue to be an object.
+
+.. function:: gcc_jit_rvalue *\
+ gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue *lvalue)
+
+ Upcast an lvalue to be an rvalue.
+
+.. function:: gcc_jit_rvalue *\
+ gcc_jit_lvalue_get_address (gcc_jit_lvalue *lvalue,\
+ gcc_jit_location *loc)
+
+ Take the address of an lvalue; analogous to:
+
+ .. code-block:: c
+
+ &(EXPR)
+
+ in C.
+
+Global variables
+****************
+
+.. function:: gcc_jit_lvalue *\
+ gcc_jit_context_new_global (gcc_jit_context *ctxt,\
+ gcc_jit_location *loc,\
+ gcc_jit_type *type,\
+ const char *name)
+
+ Add a new global variable of the given type and name to the context.
+
+
+Working with pointers, structs and unions
+-----------------------------------------
+
+.. function:: gcc_jit_lvalue *\
+ gcc_jit_rvalue_dereference (gcc_jit_rvalue *rvalue,\
+ gcc_jit_location *loc)
+
+ Given an rvalue of pointer type ``T *``, dereferencing the pointer,
+ getting an lvalue of type ``T``. Analogous to::
+
+ *(EXPR)
+
+ in C.
+
+Field access is provided separately for both lvalues and rvalues.
+
+.. function:: gcc_jit_lvalue *\
+ gcc_jit_lvalue_access_field (gcc_jit_lvalue *struct_,\
+ gcc_jit_location *loc,\
+ gcc_jit_field *field)
+
+ Given an lvalue of struct or union type, access the given field,
+ getting an lvalue of the field's type. Analogous to::
+
+ (EXPR).field = ...;
+
+ in C.
+
+.. function:: gcc_jit_rvalue *\
+ gcc_jit_rvalue_access_field (gcc_jit_rvalue *struct_,\
+ gcc_jit_location *loc,\
+ gcc_jit_field *field)
+
+ Given an rvalue of struct or union type, access the given field
+ as an rvalue. Analogous to::
+
+ (EXPR).field
+
+ in C.
+
+.. function:: gcc_jit_lvalue *\
+ gcc_jit_rvalue_dereference_field (gcc_jit_rvalue *ptr,\
+ gcc_jit_location *loc,\
+ gcc_jit_field *field)
+
+ Given an rvalue of pointer type ``T *`` where T is of struct or union
+ type, access the given field as an lvalue. Analogous to::
+
+ (EXPR)->field
+
+ in C, itself equivalent to ``(*EXPR).FIELD``.
+
+.. function:: gcc_jit_lvalue *\
+ gcc_jit_context_new_array_access (gcc_jit_context *ctxt,\
+ gcc_jit_location *loc,\
+ gcc_jit_rvalue *ptr,\
+ gcc_jit_rvalue *index)
+
+ Given an rvalue of pointer type ``T *``, get at the element `T` at
+ the given index, using standard C array indexing rules i.e. each
+ increment of ``index`` corresponds to ``sizeof(T)`` bytes.
+ Analogous to::
+
+ PTR[INDEX]
+
+ in C (or, indeed, to ``PTR + INDEX``).
new file mode 100644
@@ -0,0 +1,288 @@
+.. Copyright (C) 2014 Free Software Foundation, Inc.
+ Originally contributed by David Malcolm <dmalcolm@redhat.com>
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+
+.. default-domain:: c
+
+Creating and using functions
+================================
+
+Params
+------
+.. type:: gcc_jit_param
+
+ A `gcc_jit_param` represents a parameter to a function.
+
+.. function:: gcc_jit_param *\
+ gcc_jit_context_new_param (gcc_jit_context *ctxt,\
+ gcc_jit_location *loc,\
+ gcc_jit_type *type,\
+ const char *name)
+
+ In preparation for creating a function, create a new parameter of the
+ given type and name.
+
+Parameters are lvalues, and thus are also rvalues (and objects), so the
+following upcasts are available:
+
+.. function:: gcc_jit_lvalue *\
+ gcc_jit_param_as_lvalue (gcc_jit_param *param)
+
+ Upcasting from param to lvalue.
+
+.. function:: gcc_jit_rvalue *\
+ gcc_jit_param_as_rvalue (gcc_jit_param *param)
+
+ Upcasting from param to rvalue.
+
+.. function:: gcc_jit_object *\
+ gcc_jit_param_as_object (gcc_jit_param *param)
+
+ Upcasting from param to object.
+
+
+Functions
+---------
+
+.. type:: gcc_jit_function
+
+ A `gcc_jit_function` represents a function - either one that we're
+ creating ourselves, or one that we're referencing.
+
+.. function:: gcc_jit_function *\
+ gcc_jit_context_new_function (gcc_jit_context *ctxt,\
+ gcc_jit_location *loc,\
+ enum gcc_jit_function_kind kind,\
+ gcc_jit_type *return_type,\
+ const char *name,\
+ int num_params,\
+ gcc_jit_param **params,\
+ int is_variadic)
+
+ Create a gcc_jit_function with the given name and parameters.
+
+ .. type:: enum gcc_jit_function_kind
+
+ This enum controls the kind of function created, and has the following
+ values:
+
+ .. macro:: GCC_JIT_FUNCTION_EXPORTED
+
+ Function is defined by the client code and visible
+ by name outside of the JIT.
+
+ .. macro:: GCC_JIT_FUNCTION_INTERNAL
+
+ Function is defined by the client code, but is invisible
+ outside of the JIT. Analogous to a "static" function.
+
+ .. 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.
+
+ .. 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 ``inline`` and adding
+ ``__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.
+
+.. function:: gcc_jit_function *\
+ gcc_jit_context_get_builtin_function (gcc_jit_context *ctxt,\
+ const char *name)
+
+.. function:: gcc_jit_object *\
+ gcc_jit_function_as_object (gcc_jit_function *func)
+
+ Upcasting from function to object.
+
+.. function:: gcc_jit_param *\
+ gcc_jit_function_get_param (gcc_jit_function *func, int index)
+
+ Get the param of the given index (0-based).
+
+.. function:: void \
+ gcc_jit_function_dump_to_dot (gcc_jit_function *func,\
+ const char *path)
+
+ Emit the function in graphviz format to the given path.
+
+.. function:: gcc_jit_lvalue *\
+ gcc_jit_function_new_local (gcc_jit_function *func,\
+ gcc_jit_location *loc,\
+ gcc_jit_type *type,\
+ const char *name)
+
+ Create a new local variable within the function, of the given type and
+ name.
+
+
+Blocks
+------
+.. type:: gcc_jit_block
+
+ A `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.
+
+.. function:: gcc_jit_block *\
+ gcc_jit_function_new_block (gcc_jit_function *func,\
+ const char *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.
+
+.. function:: gcc_jit_object *\
+ gcc_jit_block_as_object (gcc_jit_block *block)
+
+ Upcast from block to object.
+
+.. function:: gcc_jit_function *\
+ gcc_jit_block_get_function (gcc_jit_block *block)
+
+ Which function is this block within?
+
+
+Statements
+----------
+
+.. function:: void\
+ gcc_jit_block_add_eval (gcc_jit_block *block,\
+ gcc_jit_location *loc,\
+ gcc_jit_rvalue *rvalue)
+
+ Add evaluation of an rvalue, discarding the result
+ (e.g. a function call that "returns" void).
+
+ This is equivalent to this C code::
+
+ (void)expression;
+
+.. function:: void\
+ gcc_jit_block_add_assignment (gcc_jit_block *block,\
+ gcc_jit_location *loc,\
+ gcc_jit_lvalue *lvalue,\
+ gcc_jit_rvalue *rvalue)
+
+ Add evaluation of an rvalue, assigning the result to the given
+ lvalue.
+
+ This is roughly equivalent to this C code::
+
+ lvalue = rvalue;
+
+.. function:: void\
+ gcc_jit_block_add_assignment_op (gcc_jit_block *block,\
+ gcc_jit_location *loc,\
+ gcc_jit_lvalue *lvalue,\
+ enum gcc_jit_binary_op op,\
+ gcc_jit_rvalue *rvalue)
+
+ Add evaluation of an rvalue, using the result to modify an
+ lvalue.
+
+ This is analogous to "+=" and friends::
+
+ lvalue += rvalue;
+ lvalue *= rvalue;
+ lvalue /= rvalue;
+
+ etc.
+
+.. function:: void\
+ gcc_jit_block_add_comment (gcc_jit_block *block,\
+ gcc_jit_location *loc,\
+ const char *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 :macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE`
+ and :macro:`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.
+
+.. function:: void\
+ gcc_jit_block_end_with_conditional (gcc_jit_block *block,\
+ gcc_jit_location *loc,\
+ gcc_jit_rvalue *boolval,\
+ gcc_jit_block *on_true,\
+ gcc_jit_block *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::
+
+ if (boolval)
+ goto on_true;
+ else
+ goto on_false;
+
+ block, boolval, on_true, and on_false must be non-NULL.
+
+.. function:: void\
+ gcc_jit_block_end_with_jump (gcc_jit_block *block,\
+ gcc_jit_location *loc,\
+ gcc_jit_block *target)
+
+
+ Terminate a block by adding a jump to the given target block.
+
+ This is roughly equivalent to this C code::
+
+ goto target;
+
+.. function:: void\
+ gcc_jit_block_end_with_return (gcc_jit_block *block,\
+ gcc_jit_location *loc,\
+ gcc_jit_rvalue *rvalue)
+
+
+ Terminate a block by adding evaluation of an rvalue, returning the value.
+
+ This is roughly equivalent to this C code::
+
+ return expression;
+
+.. function:: void\
+ gcc_jit_block_end_with_void_return (gcc_jit_block *block,\
+ gcc_jit_location *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::
+
+ return;
new file mode 100644
@@ -0,0 +1,65 @@
+.. Copyright (C) 2014 Free Software Foundation, Inc.
+ Originally contributed by David Malcolm <dmalcolm@redhat.com>
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+
+.. default-domain:: c
+
+Source Locations
+================
+
+.. type:: gcc_jit_location
+
+ A `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.
+
+ `gcc_jit_location` instances are optional: you can always pass NULL to
+ any API entrypoint accepting one.
+
+ You can construct them using :c:func:`gcc_jit_context_new_location`.
+
+ You need to enable :c:macro:`GCC_JIT_BOOL_OPTION_DEBUGINFO` on the
+ :c:type:`gcc_jit_context` for these locations to actually be usable by
+ the debugger::
+
+ gcc_jit_context_set_bool_option (
+ ctxt,
+ GCC_JIT_BOOL_OPTION_DEBUGINFO,
+ 1);
+
+.. function:: gcc_jit_location *\
+ gcc_jit_context_new_location (gcc_jit_context *ctxt,\
+ const char *filename,\
+ int line,\
+ int column)
+
+ Create a `gcc_jit_location` instance representing the given source
+ location.
+
+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 :c:func:`gcc_jit_context_dump_to_file()`::
+
+ gcc_jit_context_dump_to_file (ctxt, "/tmp/something.c",
+ 1 /* update_locations */);
+
+This will dump C-like code to the given path. If the `update_locations`
+argument is true, this will also set up `gcc_jit_location` information
+throughout the context, pointing at the dump file as if it were a source
+file, giving you *something* you can step through in the debugger.
new file mode 100644
@@ -0,0 +1,86 @@
+.. Copyright (C) 2014 Free Software Foundation, Inc.
+ Originally contributed by David Malcolm <dmalcolm@redhat.com>
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+
+.. default-domain:: c
+
+Objects
+=======
+
+.. type:: gcc_jit_object
+
+Almost every entity in the API (with the exception of
+:c:type:`gcc_jit_context *` and :c:type:`gcc_jit_result *`) is a
+"contextual" object, a :c:type:`gcc_jit_object *`
+
+A JIT object:
+
+ * is associated with a :c:type:`gcc_jit_context *`.
+
+ * 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.
+
+Although the API is C-based, there is a form of class hierarchy, which
+looks like this::
+
+ +- 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
+
+There are casting methods for upcasting from subclasses to parent classes.
+For example, :c:func:`gcc_jit_type_as_object`:
+
+.. code-block:: c
+
+ gcc_jit_object *obj = gcc_jit_type_as_object (int_type);
+
+The object "base class" has the following operations:
+
+.. function:: gcc_jit_context *gcc_jit_object_get_context (gcc_jit_object *obj)
+
+ Which context is "obj" within?
+
+
+.. function:: const char *gcc_jit_object_get_debug_string (gcc_jit_object *obj)
+
+ Generate a human-readable description for the given object.
+
+ For example,
+
+ .. code-block:: c
+
+ printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj));
+
+ might give this text on stdout:
+
+ .. code-block:: bash
+
+ obj: 4.0 * (float)i
+
+ .. note::
+
+ If you call this on an object, the `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.
new file mode 100644
@@ -0,0 +1,48 @@
+.. Copyright (C) 2014 Free Software Foundation, Inc.
+ Originally contributed by David Malcolm <dmalcolm@redhat.com>
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+
+.. default-domain:: c
+
+Compilation results
+===================
+
+.. type:: gcc_jit_result
+
+ A `gcc_jit_result` encapsulates the result of compiling a context.
+
+.. function:: gcc_jit_result *\
+ gcc_jit_context_compile (gcc_jit_context *ctxt)
+
+ This calls into GCC and builds the code, returning a
+ `gcc_jit_result *`.
+
+
+.. function:: void *\
+ gcc_jit_result_get_code (gcc_jit_result *result,\
+ const char *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.
+
+
+.. function:: void\
+ gcc_jit_result_release (gcc_jit_result *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.
new file mode 100644
@@ -0,0 +1,209 @@
+.. Copyright (C) 2014 Free Software Foundation, Inc.
+ Originally contributed by David Malcolm <dmalcolm@redhat.com>
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+
+.. default-domain:: c
+
+Types
+=====
+
+.. c:type:: gcc_jit_type
+
+ gcc_jit_type represents a type within the library.
+
+.. function:: gcc_jit_object *gcc_jit_type_as_object (gcc_jit_type *type)
+
+ Upcast a type to an object.
+
+Types can be created in several ways:
+
+* fundamental types can be accessed using
+ :func:`gcc_jit_context_get_type`::
+
+ gcc_jit_type *int_type = gcc_jit_context_get_type (GCC_JIT_TYPE_INT);
+
+ See :func:`gcc_jit_context_get_type` for the available types.
+
+* derived types can be accessed by using functions such as
+ :func:`gcc_jit_type_get_pointer` and :func:`gcc_jit_type_get_const`::
+
+ 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));
+
+* by creating structures (see below).
+
+Standard types
+--------------
+
+.. function:: gcc_jit_type *gcc_jit_context_get_type (gcc_jit_context *ctxt, \
+ enum gcc_jit_types type_)
+
+ Access a specific type. The available types are:
+
+ ========================================= ================================
+ `enum gcc_jit_types` value Meaning
+ ========================================= ================================
+ :c:data:`GCC_JIT_TYPE_VOID` C's ``void`` type.
+ :c:data:`GCC_JIT_TYPE_VOID_PTR` C's ``void *``.
+ :c:data:`GCC_JIT_TYPE_BOOL` C++'s ``bool`` type; also C99's
+ ``_Bool`` type, aka ``bool`` if
+ using stdbool.h.
+ :c:data:`GCC_JIT_TYPE_CHAR` C's ``char`` (of some signedness)
+ :c:data:`GCC_JIT_TYPE_SIGNED_CHAR` C's ``signed char``
+ :c:data:`GCC_JIT_TYPE_UNSIGNED_CHAR` C's ``unsigned char``
+ :c:data:`GCC_JIT_TYPE_SHORT` C's ``short`` (signed)
+ :c:data:`GCC_JIT_TYPE_UNSIGNED_SHORT` C's ``unsigned short``
+ :c:data:`GCC_JIT_TYPE_INT` C's ``int`` (signed)
+ :c:data:`GCC_JIT_TYPE_UNSIGNED_INT` C's ``unsigned int``
+ :c:data:`GCC_JIT_TYPE_LONG` C's ``long`` (signed)
+ :c:data:`GCC_JIT_TYPE_UNSIGNED_LONG` C's ``unsigned long``
+ :c:data:`GCC_JIT_TYPE_LONG_LONG` C99's ``long long`` (signed)
+ :c:data:`GCC_JIT_TYPE_UNSIGNED_LONG_LONG` C99's ``unsigned long long``
+ :c:data:`GCC_JIT_TYPE_FLOAT`
+ :c:data:`GCC_JIT_TYPE_DOUBLE`
+ :c:data:`GCC_JIT_TYPE_LONG_DOUBLE`
+ :c:data:`GCC_JIT_TYPE_CONST_CHAR_PTR` C type: ``(const char *)``
+ :c:data:`GCC_JIT_TYPE_SIZE_T` C's ``size_t`` type
+ :c:data:`GCC_JIT_TYPE_FILE_PTR` C type: ``(FILE *)``
+ ========================================= ================================
+
+.. function:: gcc_jit_type *\
+ gcc_jit_context_get_int_type (gcc_jit_context *ctxt, \
+ int num_bytes, int is_signed)
+
+ Access the integer type of the given size.
+
+
+Pointers, `const`, and `volatile`
+---------------------------------
+
+.. function:: gcc_jit_type *gcc_jit_type_get_pointer (gcc_jit_type *type)
+
+ Given type "T", get type "T*".
+
+.. function:: gcc_jit_type *gcc_jit_type_get_const (gcc_jit_type *type)
+
+ Given type "T", get type "const T".
+
+.. function:: gcc_jit_type *gcc_jit_type_get_volatile (gcc_jit_type *type)
+
+ Given type "T", get type "volatile T".
+
+.. function:: gcc_jit_type *\
+ gcc_jit_context_new_array_type (gcc_jit_context *ctxt, \
+ gcc_jit_location *loc, \
+ gcc_jit_type *element_type, \
+ int num_elements)
+
+ Given type "T", get type "T[N]" (for a constant N).
+
+
+Structures and unions
+---------------------
+
+.. c:type:: gcc_jit_struct
+
+A compound type analagous to a C `struct`.
+
+.. c:type:: gcc_jit_field
+
+A field within a :c:type:`gcc_jit_struct`.
+
+You can model C `struct` types by creating :c:type:`gcc_jit_struct *` and
+:c:type:`gcc_jit_field` instances, in either order:
+
+* by creating the fields, then the structure. For example, to model:
+
+ .. code-block:: c
+
+ struct coord {double x; double y; };
+
+ you could call::
+
+ 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);
+
+* by creating the structure, then populating it with fields, typically
+ to allow modelling self-referential structs such as:
+
+ .. code-block:: c
+
+ struct node { int m_hash; struct node *m_next; };
+
+ like this::
+
+ 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);
+
+.. function:: gcc_jit_field *\
+ gcc_jit_context_new_field (gcc_jit_context *ctxt,\
+ gcc_jit_location *loc,\
+ gcc_jit_type *type,\
+ const char *name)
+
+ Construct a new field, with the given type and name.
+
+.. function:: gcc_jit_object *\
+ gcc_jit_field_as_object (gcc_jit_field *field)
+
+ Upcast from field to object.
+
+.. function:: gcc_jit_struct *\
+ gcc_jit_context_new_struct_type (gcc_jit_context *ctxt,\
+ gcc_jit_location *loc,\
+ const char *name,\
+ int num_fields,\
+ gcc_jit_field **fields)
+
+ Construct a new struct type, with the given name and fields.
+
+.. function:: gcc_jit_struct *\
+ gcc_jit_context_new_opaque_struct (gcc_jit_context *ctxt,\
+ gcc_jit_location *loc,\
+ const char *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
+ :c:func:`gcc_jit_struct_set_fields`.
+
+.. function:: gcc_jit_type *\
+ gcc_jit_struct_as_type (gcc_jit_struct *struct_type)
+
+ Upcast from struct to type.
+
+.. function:: void\
+ gcc_jit_struct_set_fields (gcc_jit_struct *struct_type,\
+ gcc_jit_location *loc,\
+ int num_fields,\
+ gcc_jit_field **fields)
+
+ Populate the fields of a formerly-opaque struct type.
+
+ This can only be called once on a given struct type.