This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Re: Stage 3 RFC: using "jit" for ahead-of-time compilation


On Thu, 2015-01-15 at 22:50 +0100, Richard Biener wrote:
> On January 15, 2015 9:05:59 PM CET, David Malcolm <dmalcolm@redhat.com> wrote:
> >Release managers: given that this only touches the jit, and that the
> >jit
> >is off by default, any objections if I go ahead and commit this?
> >It's a late-breaking feature, but the jit as a whole is new, and
> >I think the following is a big win, so I'd like to proceed with this in
> >stage 3 (i.e. in the next 24 hours).  There are docs and testcases.
> >
> >New jit API entrypoint: gcc_jit_context_compile_to_file
> >
> >This patch adds a way to use libgccjit for ahead-of-time compilation.
> >I noticed that given the postprocessing steps the jit has to take to
> >turn the .s file into in-memory code (invoke driver to convert to
> >a .so and then dlopen), that it's not much of a leap to support
> >compiling the .s file into objects, dynamic libraries, and executables.
> >
> >Doing so seems like a big win from a feature standpoint: people with
> >pre-existing frontend code who want a backend can then plug in
> >libgccjit
> >and have a compiler, without needing to write it as a GCC frontend, or
> >use LLVM.
> 
> Note that you should make them aware of our runtime license with
> respect to the eligible compilation process.  Which means this is not
> a way to implement proprietary front ends.
> 
> Richard.

IANAL, but as I understand things, the runtime license is an additional
grant of rights that covers certain components of GCC that bear the GCC
Runtime Library Exception, allowing them to be used in certain
additional ways beyond regular GPLv3-compliance.

libgccjit doesn't have that exception; it's GPLv3.

Perhaps an argument could be made for libgccjit to have the exception,
if the FSF think that that would better serve the FSF's mission; right
now, I'm merely trying to provide a technical means to modularity.

Assuming the above is correct, anything linked against it needs to be
GPLv3-compatible.  Hence any such frontend linked against libgccjit
would need to be GPLv3-compatible.

Attached is a patch (on top of the proposed one below), to clarify the
wording in the new tutorial a little, to remind people that such linking
needs to be license-compatible (without actually spelling out what the
license is, though it's visible at the top of the public header file,
libgccjit.h, as GPLv3 or later without the runtime library exception).

Are the combined patches OK by you?

Thanks
Dave


> >"jit" becomes something of a misnomer for this use-case.
> >
> >As an experiment, I used this technique to add a compiler for the
> >language I'll refer to as "brainf" (ahem), and wrote this up for the
> >libgccjit tutorial (it's all in the patch); prebuilt HTML can be seen
> >at:
> >https://dmalcolm.fedorapeople.org/gcc/libgccjit-api-docs-wip/intro/tutorial05.html
> >
> >The main things that are missing are:
> > * specifying libraries to link against (Uli had some ideas about this)
> >  * cross-compilation support (needs some deeper work, especially the
> >    test suite, so deferrable to gcc 6, I guess)
> >but the feature is useful with the patch as-is.
> >
> >The new test cases take jit.sum's # of expected passes
> >from 7514 to 7571.
> >
> >gcc/jit/ChangeLog:
> >	* docs/cp/topics/results.rst: Rename to...
> >	* docs/cp/topics/compilation.rst: ...this, and add section on
> >	ahead-of-time compilation.
> >	* docs/cp/topics/index.rst: Update for renaming of results.rst
> >	to compilation.rst.
> >	* docs/examples/emit-alphabet.bf: New file, a sample "brainf"
> >	script.
> >	* docs/examples/tut05-bf.c: New file, implementing a compiler
> >	for "brainf".
> >	* docs/internals/test-hello-world.exe.log.txt: Update to reflect
> >	changes to logger output.
> >	* docs/intro/index.rst: Add tutorial05.rst
> >	* docs/intro/tutorial05.rst: New file.
> >	* docs/topics/results.rst: Rename to...
> >	* docs/topics/compilation.rst: ...this, and add section on
> >	ahead-of-time compilation.
> >	* docs/topics/index.rst: Update for renaming of results.rst to
> >	compilation.rst.
> >	* jit-playback.c (gcc::jit::playback::context::compile): Convert
> >	return type from result * to void.  Move the code to convert to
> >	dso and dlopen the result to a new pure virtual "postprocess"
> >	method.
> >	(gcc::jit::playback::compile_to_memory::compile_to_memory): New
> >	function.
> >	(gcc::jit::playback::compile_to_memory::postprocess): New
> >	function, based on playback::context::compile.
> >	(gcc::jit::playback::compile_to_file::compile_to_file): New
> >	function.
> >	(gcc::jit::playback::compile_to_file::postprocess): New function.
> >	(gcc::jit::playback::compile_to_file::copy_file): New function.
> >	(gcc::jit::playback::context::convert_to_dso): Move internals
> >	to...
> >	(gcc::jit::playback::context::invoke_driver): New method.  Add
> >	"-shared" and "-c" options to driver's argv as needed.
> >	* jit-playback.h: Include "timevar.h".
> >	(gcc::jit::playback::context::compile): Convert return type from
> >	result * to void.
> >	(gcc::jit::playback::context::postprocess): New pure virtual
> >	function, making this an abstract base class.
> >	(gcc::jit::playback::context::get_tempdir): New accessor.
> >	(gcc::jit::playback::context::invoke_driver): New function.
> >	(class gcc::jit::playback::compile_to_memory): New subclass of
> >	playback::context.
> >	(class gcc::jit::playback::compile_to_file): Likewise.
> >	* jit-recording.c (gcc::jit::recording::context::compile): Use a
> >	playback::compile_to_memory, and extract its result.
> >	(gcc::jit::recording::context::compile_to_file): New function.
> >	* jit-recording.h (gcc::jit::recording::context::compile_to_file):
> >	New function.
> >	* libgccjit++.h (gccjit::context::compile_to_file): New method.
> >	* libgccjit.c (gcc_jit_context_compile): Update log message to
> >	clarify that this is an in-memory compile.
> >	(gcc_jit_context_compile_to_file): New function.
> >	* libgccjit.h (gcc_jit_context): Clarify that you can compile
> >	a context more than once, and that you can compile to a file
> >	as well as to memory.
> >	(gcc_jit_result): Clarify that this is the result of an
> >	in-memory compilation.
> >	(gcc_jit_context_compile): Clarify that you can compile, and that
> >	this is an in-memory compilation.
> >	(enum gcc_jit_output_kind): New enum.
> >	(gcc_jit_context_compile_to_file): New function.
> >	(gcc_jit_context_enable_dump): Clarify comment to cover both forms
> >	of compilation.
> >	* libgccjit.map (gcc_jit_context_compile_to_file): New API
> >	entrypoint.
> >	* notes.txt: Update to show the playback::context::postprocess
> >	virtual function.
> >
> >gcc/testsuite/ChangeLog:
> >	* jit.dg/harness.h: Include <unistd.h>.
> >	(CHECK_NO_ERRORS): New.
> >	(verify_code): Wrap prototype in #ifndef TEST_COMPILING_TO_FILE.
> >	(test_jit): Support new macro TEST_COMPILING_TO_FILE for exercising
> >	gcc_jit_context_compile_to_file.
> >	* jit.dg/jit.exp (fixed_host_execute): Fix the code for passing on
> >	args to the spawned executable.
> >	(jit-expand-vars): New function.
> >	(jit-exe-params): New variable.
> >	(dg-jit-set-exe-params): New function.
> >	(jit-dg-test): Detect testcases that use
> >	jit-verify-compile-to-file and call jit-setup-compile-to-file.
> >	Set arguments of spawned process to jit-exe-params.
> >	(jit-get-output-filename): New function.
> >	(jit-setup-compile-to-file): New function.
> >	(jit-verify-compile-to-file): New function.
> >	(jit-run-executable): New function.
> >	(jit-verify-executable): New function.
> >	* jit.dg/test-compile-to-assembler.c: New testcase.
> >	* jit.dg/test-compile-to-dynamic-library.c: New testcase.
> >	* jit.dg/test-compile-to-executable.c: New testcase.
> >	* jit.dg/test-compile-to-object.c: New testcase.
> >---
> > gcc/jit/docs/cp/topics/compilation.rst             |  58 +++
> > gcc/jit/docs/cp/topics/index.rst                   |   4 +-
> > gcc/jit/docs/cp/topics/results.rst                 |  48 ---
> > gcc/jit/docs/examples/emit-alphabet.bf             |  17 +
> >gcc/jit/docs/examples/tut05-bf.c                   | 446
> >+++++++++++++++++++++
> > .../docs/internals/test-hello-world.exe.log.txt    |  48 ++-
> > gcc/jit/docs/intro/index.rst                       |   3 +-
> > gcc/jit/docs/intro/tutorial05.rst                  | 253 ++++++++++++
> > gcc/jit/docs/topics/compilation.rst                | 199 +++++++++
> > gcc/jit/docs/topics/index.rst                      |   4 +-
> > gcc/jit/docs/topics/results.rst                    | 127 ------
> >gcc/jit/jit-playback.c                             | 308 +++++++++++++-
> > gcc/jit/jit-playback.h                             |  54 ++-
> > gcc/jit/jit-recording.c                            |  40 +-
> > gcc/jit/jit-recording.h                            |   4 +
> > gcc/jit/libgccjit++.h                              |  12 +
> > gcc/jit/libgccjit.c                                |  31 +-
> > gcc/jit/libgccjit.h                                |  58 ++-
> > gcc/jit/libgccjit.map                              |   1 +
> > gcc/jit/notes.txt                                  |  13 +-
> > gcc/testsuite/jit.dg/harness.h                     |  29 +-
> > gcc/testsuite/jit.dg/jit.exp                       | 209 +++++++++-
> > gcc/testsuite/jit.dg/test-compile-to-assembler.c   |  65 +++
> > .../jit.dg/test-compile-to-dynamic-library.c       |  65 +++
> > gcc/testsuite/jit.dg/test-compile-to-executable.c  | 110 +++++
> > gcc/testsuite/jit.dg/test-compile-to-object.c      |  65 +++
> > 26 files changed, 2026 insertions(+), 245 deletions(-)
> > create mode 100644 gcc/jit/docs/cp/topics/compilation.rst
> > delete mode 100644 gcc/jit/docs/cp/topics/results.rst
> > create mode 100644 gcc/jit/docs/examples/emit-alphabet.bf
> > create mode 100644 gcc/jit/docs/examples/tut05-bf.c
> > create mode 100644 gcc/jit/docs/intro/tutorial05.rst
> > create mode 100644 gcc/jit/docs/topics/compilation.rst
> > delete mode 100644 gcc/jit/docs/topics/results.rst
> > create mode 100644 gcc/testsuite/jit.dg/test-compile-to-assembler.c
> >create mode 100644
> >gcc/testsuite/jit.dg/test-compile-to-dynamic-library.c
> > create mode 100644 gcc/testsuite/jit.dg/test-compile-to-executable.c
> > create mode 100644 gcc/testsuite/jit.dg/test-compile-to-object.c
> >
> >diff --git a/gcc/jit/docs/cp/topics/compilation.rst
> >b/gcc/jit/docs/cp/topics/compilation.rst
> >new file mode 100644
> >index 0000000..05917e8
> >--- /dev/null
> >+++ b/gcc/jit/docs/cp/topics/compilation.rst
> >@@ -0,0 +1,58 @@
> >+.. Copyright (C) 2014-2015 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:: cpp
> >+
> >+Compiling a context
> >+===================
> >+
> >+Once populated, a :class:`gccjit::context` can be compiled to
> >+machine code, either in-memory via :func:`gccjit::context::compile` or
> >+to disk via :func:`gccjit::context::compile_to_file`.
> >+
> >+You can compile a context multiple times (using either form of
> >+compilation), although any errors that occur on the context will
> >+prevent any future compilation of that context.
> >+
> >+In-memory compilation
> >+*********************
> >+
> >+.. function:: gcc_jit_result *\
> >+              gccjit::context::compile ()
> >+
> >+   This calls into GCC and builds the code, returning a
> >+   `gcc_jit_result *`.
> >+
> >+   This is a thin wrapper around the
> >+   :c:func:`gcc_jit_context_compile` API entrypoint.
> >+
> >+Ahead-of-time compilation
> >+*************************
> >+
> >+Although libgccjit is primarily aimed at just-in-time compilation, it
> >+can also be used for implementing more traditional ahead-of-time
> >+compilers, via the :func:`gccjit::context::compile_to_file` method.
> >+
> >+.. function:: void \
> >+              gccjit::context::compile_to_file (enum
> >gcc_jit_output_kind,\
> >+                                                const char
> >*output_path)
> >+
> >+   Compile the :class:`gccjit::context` to a file of the given
> >+   kind.
> >+
> >+   This is a thin wrapper around the
> >+   :c:func:`gcc_jit_context_compile_to_file` API entrypoint.
> >diff --git a/gcc/jit/docs/cp/topics/index.rst
> >b/gcc/jit/docs/cp/topics/index.rst
> >index a129137..4ebb623 100644
> >--- a/gcc/jit/docs/cp/topics/index.rst
> >+++ b/gcc/jit/docs/cp/topics/index.rst
> >@@ -1,4 +1,4 @@
> >-.. Copyright (C) 2014 Free Software Foundation, Inc.
> >+.. Copyright (C) 2014-2015 Free Software Foundation, Inc.
> >    Originally contributed by David Malcolm <dmalcolm@redhat.com>
> > 
> >    This is free software: you can redistribute it and/or modify it
> >@@ -27,4 +27,4 @@ Topic Reference
> >    expressions.rst
> >    functions.rst
> >    locations.rst
> >-   results.rst
> >+   compilation.rst
> >diff --git a/gcc/jit/docs/cp/topics/results.rst
> >b/gcc/jit/docs/cp/topics/results.rst
> >deleted file mode 100644
> >index 18200ac..0000000
> >--- a/gcc/jit/docs/cp/topics/results.rst
> >+++ /dev/null
> >@@ -1,48 +0,0 @@
> >-.. 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:: cpp
> >-
> >-Compilation results
> >-===================
> >-
> >-.. type:: gcc_jit_result
> >-
> >-  A `gcc_jit_result` encapsulates the result of compiling a context.
> >-
> >-.. function:: gcc_jit_result *\
> >-              gccjit::context::compile ()
> >-
> >-   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.
> >diff --git a/gcc/jit/docs/examples/emit-alphabet.bf
> >b/gcc/jit/docs/examples/emit-alphabet.bf
> >new file mode 100644
> >index 0000000..6863273
> >--- /dev/null
> >+++ b/gcc/jit/docs/examples/emit-alphabet.bf
> >@@ -0,0 +1,17 @@
> >+[
> >+  Emit the uppercase alphabet
> >+]
> >+
> >+cell 0 = 26
> >+++++++++++++++++++++++++++
> >+
> >+cell 1 = 65
> >+>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
> >+
> >+while cell#0 != 0
> >+[
> >+ >
> >+ .      emit cell#1
> >+ +      increment cell@1
> >+ <-     decrement cell@0
> >+]
> >diff --git a/gcc/jit/docs/examples/tut05-bf.c
> >b/gcc/jit/docs/examples/tut05-bf.c
> >new file mode 100644
> >index 0000000..f948ede
> >--- /dev/null
> >+++ b/gcc/jit/docs/examples/tut05-bf.c
> >@@ -0,0 +1,446 @@
> >+/* A compiler for the "bf" language.  */
> >+
> >+#include <stdlib.h>
> >+#include <string.h>
> >+#include <errno.h>
> >+
> >+#include "libgccjit.h"
> >+
> >+/* Make "main" function:
> >+     int
> >+     main (int argc, char **argv)
> >+     {
> >+       ...
> >+     }
> >+*/
> >+static gcc_jit_function *
> >+make_main (gcc_jit_context *ctxt)
> >+{
> >+  gcc_jit_type *int_type =
> >+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
> >+  gcc_jit_param *param_argc =
> >+    gcc_jit_context_new_param (ctxt, NULL, int_type, "argc");
> >+  gcc_jit_type *char_ptr_ptr_type =
> >+    gcc_jit_type_get_pointer (
> >+      gcc_jit_type_get_pointer (
> >+	gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR)));
> >+  gcc_jit_param *param_argv =
> >+    gcc_jit_context_new_param (ctxt, NULL, char_ptr_ptr_type, "argv");
> >+  gcc_jit_param *params[2] = {param_argc, param_argv};
> >+  gcc_jit_function *func_main =
> >+    gcc_jit_context_new_function (ctxt, NULL,
> >+				  GCC_JIT_FUNCTION_EXPORTED,
> >+				  int_type,
> >+				  "main",
> >+				  2, params,
> >+				  0);
> >+  return func_main;
> >+}
> >+
> >+#define MAX_OPEN_PARENS 16
> >+
> >+typedef struct bf_compiler
> >+{
> >+  const char *filename;
> >+  int line;
> >+  int column;
> >+
> >+  gcc_jit_context *ctxt;
> >+
> >+  gcc_jit_type *void_type;
> >+  gcc_jit_type *int_type;
> >+  gcc_jit_type *byte_type;
> >+  gcc_jit_type *array_type;
> >+
> >+  gcc_jit_function *func_getchar;
> >+  gcc_jit_function *func_putchar;
> >+
> >+  gcc_jit_function *func;
> >+  gcc_jit_block *curblock;
> >+
> >+  gcc_jit_rvalue *int_zero;
> >+  gcc_jit_rvalue *int_one;
> >+  gcc_jit_rvalue *byte_zero;
> >+  gcc_jit_rvalue *byte_one;
> >+  gcc_jit_lvalue *data_cells;
> >+  gcc_jit_lvalue *idx;
> >+
> >+  int num_open_parens;
> >+  gcc_jit_block *paren_test[MAX_OPEN_PARENS];
> >+  gcc_jit_block *paren_body[MAX_OPEN_PARENS];
> >+  gcc_jit_block *paren_after[MAX_OPEN_PARENS];
> >+
> >+} bf_compiler;
> >+
> >+/* Bail out, with a message on stderr.  */
> >+
> >+static void
> >+fatal_error (bf_compiler *bfc, const char *msg)
> >+{
> >+  fprintf (stderr,
> >+	   "%s:%i:%i: %s",
> >+	   bfc->filename, bfc->line, bfc->column, msg);
> >+  abort ();
> >+}
> >+
> >+/* Get "data_cells[idx]" as an lvalue.  */
> >+
> >+static gcc_jit_lvalue *
> >+bf_get_current_data (bf_compiler *bfc, gcc_jit_location *loc)
> >+{
> >+  return gcc_jit_context_new_array_access (
> >+    bfc->ctxt,
> >+    loc,
> >+    gcc_jit_lvalue_as_rvalue (bfc->data_cells),
> >+    gcc_jit_lvalue_as_rvalue (bfc->idx));
> >+}
> >+
> >+/* Get "data_cells[idx] == 0" as a boolean rvalue.  */
> >+
> >+static gcc_jit_rvalue *
> >+bf_current_data_is_zero (bf_compiler *bfc, gcc_jit_location *loc)
> >+{
> >+  return gcc_jit_context_new_comparison (
> >+    bfc->ctxt,
> >+    loc,
> >+    GCC_JIT_COMPARISON_EQ,
> >+    gcc_jit_lvalue_as_rvalue (bf_get_current_data (bfc, loc)),
> >+    bfc->byte_zero);
> >+}
> >+
> >+/* Compile one bf character.  */
> >+
> >+static void
> >+bf_compile_char (bf_compiler *bfc,
> >+		 unsigned char ch)
> >+{
> >+  gcc_jit_location *loc =
> >+    gcc_jit_context_new_location (bfc->ctxt,
> >+				  bfc->filename,
> >+				  bfc->line,
> >+				  bfc->column);
> >+
> >+  /* Turn this on to trace execution, by injecting putchar ()
> >+     of each source char. */
> >+  if (0)
> >+    {
> >+      gcc_jit_rvalue *arg =
> >+	gcc_jit_context_new_rvalue_from_int (
> >+					     bfc->ctxt,
> >+					     bfc->int_type,
> >+					     ch);
> >+      gcc_jit_rvalue *call =
> >+	gcc_jit_context_new_call (bfc->ctxt,
> >+				  loc,
> >+				  bfc->func_putchar,
> >+				  1, &arg);
> >+      gcc_jit_block_add_eval (bfc->curblock,
> >+			      loc,
> >+			      call);
> >+    }
> >+
> >+  switch (ch)
> >+    {
> >+      case '>':
> >+	gcc_jit_block_add_comment (bfc->curblock,
> >+				   loc,
> >+				   "'>': idx += 1;");
> >+	gcc_jit_block_add_assignment_op (bfc->curblock,
> >+					 loc,
> >+					 bfc->idx,
> >+					 GCC_JIT_BINARY_OP_PLUS,
> >+					 bfc->int_one);
> >+	break;
> >+
> >+      case '<':
> >+	gcc_jit_block_add_comment (bfc->curblock,
> >+				   loc,
> >+				   "'<': idx -= 1;");
> >+	gcc_jit_block_add_assignment_op (bfc->curblock,
> >+					 loc,
> >+					 bfc->idx,
> >+					 GCC_JIT_BINARY_OP_MINUS,
> >+					 bfc->int_one);
> >+	break;
> >+
> >+      case '+':
> >+	gcc_jit_block_add_comment (bfc->curblock,
> >+				   loc,
> >+				   "'+': data[idx] += 1;");
> >+	gcc_jit_block_add_assignment_op (bfc->curblock,
> >+					 loc,
> >+					 bf_get_current_data (bfc, loc),
> >+					 GCC_JIT_BINARY_OP_PLUS,
> >+					 bfc->byte_one);
> >+	break;
> >+
> >+      case '-':
> >+	gcc_jit_block_add_comment (bfc->curblock,
> >+				   loc,
> >+				   "'-': data[idx] -= 1;");
> >+	gcc_jit_block_add_assignment_op (bfc->curblock,
> >+					 loc,
> >+					 bf_get_current_data (bfc, loc),
> >+					 GCC_JIT_BINARY_OP_MINUS,
> >+					 bfc->byte_one);
> >+	break;
> >+
> >+      case '.':
> >+	{
> >+	  gcc_jit_rvalue *arg =
> >+	    gcc_jit_context_new_cast (
> >+	      bfc->ctxt,
> >+	      loc,
> >+	      gcc_jit_lvalue_as_rvalue (bf_get_current_data (bfc, loc)),
> >+	      bfc->int_type);
> >+	  gcc_jit_rvalue *call =
> >+	    gcc_jit_context_new_call (bfc->ctxt,
> >+				      loc,
> >+				      bfc->func_putchar,
> >+				      1, &arg);
> >+	  gcc_jit_block_add_comment (bfc->curblock,
> >+				     loc,
> >+				     "'.': putchar ((int)data[idx]);");
> >+	  gcc_jit_block_add_eval (bfc->curblock,
> >+				  loc,
> >+				  call);
> >+	}
> >+	break;
> >+
> >+      case ',':
> >+	{
> >+	  gcc_jit_rvalue *call =
> >+	    gcc_jit_context_new_call (bfc->ctxt,
> >+				      loc,
> >+				      bfc->func_getchar,
> >+				      0, NULL);
> >+	  gcc_jit_block_add_comment (
> >+	    bfc->curblock,
> >+	    loc,
> >+	    "',': data[idx] = (unsigned char)getchar ();");
> >+	  gcc_jit_block_add_assignment (bfc->curblock,
> >+					loc,
> >+					bf_get_current_data (bfc, loc),
> >+					gcc_jit_context_new_cast (
> >+					  bfc->ctxt,
> >+					  loc,
> >+					  call,
> >+					  bfc->byte_type));
> >+	}
> >+	break;
> >+
> >+      case '[':
> >+	{
> >+	  gcc_jit_block *loop_test =
> >+	    gcc_jit_function_new_block (bfc->func, NULL);
> >+	  gcc_jit_block *on_zero =
> >+	    gcc_jit_function_new_block (bfc->func, NULL);
> >+	  gcc_jit_block *on_non_zero =
> >+	    gcc_jit_function_new_block (bfc->func, NULL);
> >+
> >+	  if (bfc->num_open_parens == MAX_OPEN_PARENS)
> >+	    fatal_error (bfc, "too many open parens");
> >+
> >+	  gcc_jit_block_end_with_jump (
> >+	    bfc->curblock,
> >+	    loc,
> >+	    loop_test);
> >+
> >+	  gcc_jit_block_add_comment (
> >+	    loop_test,
> >+	    loc,
> >+	    "'['");
> >+	  gcc_jit_block_end_with_conditional (
> >+	    loop_test,
> >+	    loc,
> >+	    bf_current_data_is_zero (bfc, loc),
> >+	    on_zero,
> >+	    on_non_zero);
> >+	  bfc->paren_test[bfc->num_open_parens] = loop_test;
> >+	  bfc->paren_body[bfc->num_open_parens] = on_non_zero;
> >+	  bfc->paren_after[bfc->num_open_parens] = on_zero;
> >+	  bfc->num_open_parens += 1;
> >+	  bfc->curblock = on_non_zero;
> >+	}
> >+	break;
> >+
> >+      case ']':
> >+	{
> >+	  gcc_jit_block_add_comment (
> >+	    bfc->curblock,
> >+	    loc,
> >+	    "']'");
> >+
> >+	  if (bfc->num_open_parens == 0)
> >+	    fatal_error (bfc, "mismatching parens");
> >+	  bfc->num_open_parens -= 1;
> >+	  gcc_jit_block_end_with_jump (
> >+	    bfc->curblock,
> >+	    loc,
> >+	    bfc->paren_test[bfc->num_open_parens]);
> >+	  bfc->curblock = bfc->paren_after[bfc->num_open_parens];
> >+	}
> >+	break;
> >+
> >+    case '\n':
> >+      bfc->line +=1;
> >+      bfc->column = 0;
> >+      break;
> >+    }
> >+
> >+  if (ch != '\n')
> >+    bfc->column += 1;
> >+}
> >+
> >+/* Compile the given .bf file into a gcc_jit_context, containing a
> >+   single "main" function suitable for compiling into an executable. 
> >*/
> >+
> >+gcc_jit_context *
> >+bf_compile (const char *filename)
> >+{
> >+  bf_compiler bfc;
> >+  FILE *f_in;
> >+  int ch;
> >+
> >+  memset (&bfc, 0, sizeof (bfc));
> >+
> >+  bfc.filename = filename;
> >+  f_in = fopen (filename, "r");
> >+  if (!f_in)
> >+    fatal_error (&bfc, "unable to open file");
> >+  bfc.line = 1;
> >+
> >+  bfc.ctxt = gcc_jit_context_acquire ();
> >+
> >+  gcc_jit_context_set_int_option (
> >+    bfc.ctxt,
> >+    GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
> >+    3);
> >+  gcc_jit_context_set_bool_option (
> >+    bfc.ctxt,
> >+    GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE,
> >+    0);
> >+  gcc_jit_context_set_bool_option (
> >+    bfc.ctxt,
> >+    GCC_JIT_BOOL_OPTION_DEBUGINFO,
> >+    1);
> >+  gcc_jit_context_set_bool_option (
> >+    bfc.ctxt,
> >+    GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING,
> >+    0);
> >+  gcc_jit_context_set_bool_option (
> >+    bfc.ctxt,
> >+    GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES,
> >+    0);
> >+
> >+  bfc.void_type =
> >+    gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_VOID);
> >+  bfc.int_type =
> >+    gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_INT);
> >+  bfc.byte_type =
> >+    gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_UNSIGNED_CHAR);
> >+  bfc.array_type =
> >+    gcc_jit_context_new_array_type (bfc.ctxt,
> >+				    NULL,
> >+				    bfc.byte_type,
> >+				    30000);
> >+
> >+  bfc.func_getchar =
> >+    gcc_jit_context_new_function (bfc.ctxt, NULL,
> >+				  GCC_JIT_FUNCTION_IMPORTED,
> >+				  bfc.int_type,
> >+				  "getchar",
> >+				  0, NULL,
> >+				  0);
> >+
> >+  gcc_jit_param *param_c =
> >+    gcc_jit_context_new_param (bfc.ctxt, NULL, bfc.int_type, "c");
> >+  bfc.func_putchar =
> >+    gcc_jit_context_new_function (bfc.ctxt, NULL,
> >+				  GCC_JIT_FUNCTION_IMPORTED,
> >+				  bfc.void_type,
> >+				  "putchar",
> >+				  1, &param_c,
> >+				  0);
> >+
> >+  bfc.func = make_main (bfc.ctxt);
> >+   bfc.curblock =
> >+    gcc_jit_function_new_block (bfc.func, "initial");
> >+  bfc.int_zero = gcc_jit_context_zero (bfc.ctxt, bfc.int_type);
> >+  bfc.int_one = gcc_jit_context_one (bfc.ctxt, bfc.int_type);
> >+  bfc.byte_zero = gcc_jit_context_zero (bfc.ctxt, bfc.byte_type);
> >+  bfc.byte_one = gcc_jit_context_one (bfc.ctxt, bfc.byte_type);
> >+
> >+  bfc.data_cells =
> >+    gcc_jit_context_new_global (bfc.ctxt, NULL,
> >+				 GCC_JIT_GLOBAL_INTERNAL,
> >+				 bfc.array_type,
> >+				 "data_cells");
> >+  bfc.idx =
> >+    gcc_jit_function_new_local (bfc.func, NULL,
> >+				bfc.int_type,
> >+				"idx");
> >+
> >+  gcc_jit_block_add_comment (bfc.curblock,
> >+			     NULL,
> >+			     "idx = 0;");
> >+  gcc_jit_block_add_assignment (bfc.curblock,
> >+				NULL,
> >+				bfc.idx,
> >+				bfc.int_zero);
> >+
> >+  bfc.num_open_parens = 0;
> >+
> >+  while ( EOF != (ch = fgetc (f_in)))
> >+    bf_compile_char (&bfc, (unsigned char)ch);
> >+
> >+  gcc_jit_block_end_with_return (bfc.curblock, NULL, bfc.int_zero);
> >+
> >+  fclose (f_in);
> >+
> >+  return bfc.ctxt;
> >+}
> >+
> >+/* Entrypoint to the compiler.  */
> >+
> >+int
> >+main (int argc, char **argv)
> >+{
> >+  const char *input_file;
> >+  const char *output_file;
> >+  gcc_jit_context *ctxt;
> >+  const char *err;
> >+
> >+  if (argc != 3)
> >+    {
> >+      fprintf (stderr, "%s: INPUT_FILE OUTPUT_FILE\n", argv[0]);
> >+      return 1;
> >+    }
> >+
> >+  input_file = argv[1];
> >+  output_file = argv[2];
> >+  ctxt = bf_compile (input_file);
> >+
> >+  gcc_jit_context_compile_to_file (ctxt,
> >+				   GCC_JIT_OUTPUT_KIND_EXECUTABLE,
> >+				   output_file);
> >+
> >+  err = gcc_jit_context_get_first_error (ctxt);
> >+
> >+  if (err)
> >+    {
> >+      gcc_jit_context_release (ctxt);
> >+      return 1;
> >+    }
> >+
> >+  gcc_jit_context_release (ctxt);
> >+  return 0;
> >+}
> >+
> >+/* Use the built compiler to compile the example to an executable:
> >+
> >+     { dg-jit-set-exe-params
> >SRCDIR/gcc/jit/docs/examples/emit-alphabet.bf emit-alphabet.bf.exe }
> >+
> >+   Then run the executable, and verify that it emits the alphabet:
> >+
> >+     { dg-final { jit-run-executable emit-alphabet.bf.exe
> >"ABCDEFGHIJKLMNOPQRSTUVWXYZ" } } */
> >diff --git a/gcc/jit/docs/internals/test-hello-world.exe.log.txt
> >b/gcc/jit/docs/internals/test-hello-world.exe.log.txt
> >index 113dc35..205b6b4 100644
> >--- a/gcc/jit/docs/internals/test-hello-world.exe.log.txt
> >+++ b/gcc/jit/docs/internals/test-hello-world.exe.log.txt
> >@@ -38,14 +38,20 @@ JIT: entering: gcc_jit_block_add_eval
> > JIT: exiting: gcc_jit_block_add_eval
> > JIT: entering: gcc_jit_block_end_with_void_return
> > JIT: exiting: gcc_jit_block_end_with_void_return
> >+JIT: entering: gcc_jit_context_dump_reproducer_to_file
> >+JIT:  entering: void
> >gcc::jit::recording::context::dump_reproducer_to_file(const char*)
> >+JIT:  exiting: void
> >gcc::jit::recording::context::dump_reproducer_to_file(const char*)
> >+JIT: exiting: gcc_jit_context_dump_reproducer_to_file
> > JIT: entering: gcc_jit_context_compile
> >-JIT:  compiling ctxt: 0x1283e20
> >+JIT:  in-memory compile of ctxt: 0x1283e20
> >JIT:  entering: gcc::jit::result*
> >gcc::jit::recording::context::compile()
> > JIT:   entering: void gcc::jit::recording::context::validate()
> > JIT:   exiting: void gcc::jit::recording::context::validate()
> >JIT:   entering:
> >gcc::jit::playback::context::context(gcc::jit::recording::context*)
> >JIT:   exiting:
> >gcc::jit::playback::context::context(gcc::jit::recording::context*)
> >-JIT:   entering: gcc::jit::result*
> >gcc::jit::playback::context::compile()
> >+JIT:   entering:
> >gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*)
> >+JIT:   exiting:
> >gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*)
> >+JIT:   entering: void gcc::jit::playback::context::compile()
> > JIT:    entering: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int)
> > JIT:    exiting: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int)
> > JIT:    entering: bool gcc::jit::tempdir::create()
> >@@ -86,29 +92,37 @@ JIT:      entering: void
> >gcc::jit::playback::function::postprocess()
> > JIT:      exiting: void gcc::jit::playback::function::postprocess()
> > JIT:     exiting: void gcc::jit::playback::context::replay()
> > JIT:     entering: void jit_langhook_write_globals()
> >+JIT:      entering: void
> >gcc::jit::playback::context::write_global_decls_1()
> >+JIT:      exiting: void
> >gcc::jit::playback::context::write_global_decls_1()
> >+JIT:      entering: void
> >gcc::jit::playback::context::write_global_decls_2()
> >+JIT:      exiting: void
> >gcc::jit::playback::context::write_global_decls_2()
> > JIT:     exiting: void jit_langhook_write_globals()
> > JIT:    exiting: toplev::main
> >JIT:    entering: void
> >gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*)
> >JIT:    exiting: void
> >gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*)
> > JIT:    entering: toplev::finalize
> > JIT:    exiting: toplev::finalize
> >-JIT:    entering: void
> >gcc::jit::playback::context::convert_to_dso(const char*)
> >-JIT:     argv[0]: x86_64-unknown-linux-gnu-gcc-5.0.0
> >-JIT:     argv[1]: -shared
> >-JIT:     argv[2]: /tmp/libgccjit-CKq1M9/fake.s
> >-JIT:     argv[3]: -o
> >-JIT:     argv[4]: /tmp/libgccjit-CKq1M9/fake.so
> >-JIT:     argv[5]: -fno-use-linker-plugin
> >-JIT:     argv[6]: (null)
> >-JIT:    exiting: void
> >gcc::jit::playback::context::convert_to_dso(const char*)
> >-JIT:    entering: gcc::jit::result*
> >gcc::jit::playback::context::dlopen_built_dso()
> >-JIT:     GCC_JIT_BOOL_OPTION_DEBUGINFO was set: handing over tempdir
> >to jit::result
> >-JIT:     entering: gcc::jit::result::result(gcc::jit::logger*, void*,
> >gcc::jit::tempdir*)
> >-JIT:     exiting: gcc::jit::result::result(gcc::jit::logger*, void*,
> >gcc::jit::tempdir*)
> >-JIT:    exiting: gcc::jit::result*
> >gcc::jit::playback::context::dlopen_built_dso()
> >+JIT:    entering: virtual void
> >gcc::jit::playback::compile_to_memory::postprocess(const char*)
> >+JIT:     entering: void
> >gcc::jit::playback::context::convert_to_dso(const char*)
> >+JIT:      entering: void
> >gcc::jit::playback::context::invoke_driver(const char*, const char*,
> >const char*, timevar_id_t, bool, bool)
> >+JIT:       argv[0]: x86_64-unknown-linux-gnu-gcc-5.0.0
> >+JIT:       argv[1]: -shared
> >+JIT:       argv[2]: /tmp/libgccjit-CKq1M9/fake.s
> >+JIT:       argv[3]: -o
> >+JIT:       argv[4]: /tmp/libgccjit-CKq1M9/fake.so
> >+JIT:       argv[5]: -fno-use-linker-plugin
> >+JIT:       argv[6]: (null)
> >+JIT:      exiting: void
> >gcc::jit::playback::context::invoke_driver(const char*, const char*,
> >const char*, timevar_id_t, bool, bool)
> >+JIT:     exiting: void
> >gcc::jit::playback::context::convert_to_dso(const char*)
> >+JIT:     entering: gcc::jit::result*
> >gcc::jit::playback::context::dlopen_built_dso()
> >+JIT:      GCC_JIT_BOOL_OPTION_DEBUGINFO was set: handing over tempdir
> >to jit::result
> >+JIT:      entering: gcc::jit::result::result(gcc::jit::logger*, void*,
> >gcc::jit::tempdir*)
> >+JIT:      exiting: gcc::jit::result::result(gcc::jit::logger*, void*,
> >gcc::jit::tempdir*)
> >+JIT:     exiting: gcc::jit::result*
> >gcc::jit::playback::context::dlopen_built_dso()
> >+JIT:    exiting: virtual void
> >gcc::jit::playback::compile_to_memory::postprocess(const char*)
> > JIT:    entering: void gcc::jit::playback::context::release_mutex()
> > JIT:    exiting: void gcc::jit::playback::context::release_mutex()
> >-JIT:   exiting: gcc::jit::result*
> >gcc::jit::playback::context::compile()
> >+JIT:   exiting: void gcc::jit::playback::context::compile()
> > JIT:   entering: gcc::jit::playback::context::~context()
> > JIT:   exiting: gcc::jit::playback::context::~context()
> >JIT:  exiting: gcc::jit::result*
> >gcc::jit::recording::context::compile()
> >diff --git a/gcc/jit/docs/intro/index.rst
> >b/gcc/jit/docs/intro/index.rst
> >index d3bcec9..0f51777 100644
> >--- a/gcc/jit/docs/intro/index.rst
> >+++ b/gcc/jit/docs/intro/index.rst
> >@@ -1,4 +1,4 @@
> >-.. Copyright (C) 2014 Free Software Foundation, Inc.
> >+.. Copyright (C) 2014-2015 Free Software Foundation, Inc.
> >    Originally contributed by David Malcolm <dmalcolm@redhat.com>
> > 
> >    This is free software: you can redistribute it and/or modify it
> >@@ -25,3 +25,4 @@ Tutorial
> >    tutorial02.rst
> >    tutorial03.rst
> >    tutorial04.rst
> >+   tutorial05.rst
> >diff --git a/gcc/jit/docs/intro/tutorial05.rst
> >b/gcc/jit/docs/intro/tutorial05.rst
> >new file mode 100644
> >index 0000000..865a550
> >--- /dev/null
> >+++ b/gcc/jit/docs/intro/tutorial05.rst
> >@@ -0,0 +1,253 @@
> >+.. Copyright (C) 2015 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 5: Implementing an Ahead-of-Time compiler
> >+-------------------------------------------------------
> >+
> >+If you have a pre-existing language frontend, it's possible to hook
> >+it up to libgccjit as a backend.  In the previous example we showed
> >+how to do that for in-memory JIT-compilation, but libgccjit can also
> >+compile code directly to a file, allowing you to implement a more
> >+traditional ahead-of-time compil
> 
> 

commit 653799d3e851c6bab1991e3e518ca8f40ae78fd7
Author: David Malcolm <dmalcolm@redhat.com>
Date:   Fri Jan 16 13:54:52 2015 -0500

    Remind people of licensing in the new tutorial
    
    gcc/jit/ChangeLog:
    	* docs/intro/tutorial05.rst: Mention the need for
    	license-compatibility in the couple of places that talk
    	about linking libgccjit to a pre-existing frontend.

diff --git a/gcc/jit/docs/intro/tutorial05.rst b/gcc/jit/docs/intro/tutorial05.rst
index 865a550..0de21a2 100644
--- a/gcc/jit/docs/intro/tutorial05.rst
+++ b/gcc/jit/docs/intro/tutorial05.rst
@@ -18,8 +18,9 @@
 Tutorial part 5: Implementing an Ahead-of-Time compiler
 -------------------------------------------------------
 
-If you have a pre-existing language frontend, it's possible to hook
-it up to libgccjit as a backend.  In the previous example we showed
+If you have a pre-existing language frontend that's compatible with
+libgccjit's license, it's possible to hook it up to libgccjit as a
+backend.  In the previous example we showed
 how to do that for in-memory JIT-compilation, but libgccjit can also
 compile code directly to a file, allowing you to implement a more
 traditional ahead-of-time compiler ("JIT" is something of a misnomer
@@ -76,7 +77,9 @@ Here's what a simple ``.bf`` script looks like:
    It's not a particularly useful language, except for providing
    compiler-writers with a test case that's easy to parse.  The point
    is that you can use :c:func:`gcc_jit_context_compile_to_file`
-   to use libgccjit as a backend for a pre-existing language frontend.
+   to use libgccjit as a backend for a pre-existing language frontend
+   (provided that the pre-existing frontend is compatible with libgccjit's
+   license).
 
 Converting a brainf script to libgccjit IR
 ******************************************

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]