1.. Copyright (C) 2014-2016 Free Software Foundation, Inc.
2   Originally contributed by David Malcolm <dmalcolm@redhat.com>
3
4   This is free software: you can redistribute it and/or modify it
5   under the terms of the GNU General Public License as published by
6   the Free Software Foundation, either version 3 of the License, or
7   (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program.  If not, see
16   <http://www.gnu.org/licenses/>.
17
18Internals
19=========
20
21Working on the JIT library
22--------------------------
23Having checked out the source code (to "src"), you can configure and build
24the JIT library like this:
25
26.. code-block:: bash
27
28  mkdir build
29  mkdir install
30  PREFIX=$(pwd)/install
31  cd build
32  ../src/configure \
33     --enable-host-shared \
34     --enable-languages=jit,c++ \
35     --disable-bootstrap \
36     --enable-checking=release \
37     --prefix=$PREFIX
38  nice make -j4 # altering the "4" to however many cores you have
39
40This should build a libgccjit.so within jit/build/gcc:
41
42.. code-block:: console
43
44 [build] $ file gcc/libgccjit.so*
45 gcc/libgccjit.so:       symbolic link to `libgccjit.so.0'
46 gcc/libgccjit.so.0:     symbolic link to `libgccjit.so.0.0.1'
47 gcc/libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped
48
49Here's what those configuration options mean:
50
51.. option:: --enable-host-shared
52
53  Configuring with this option means that the compiler is built as
54  position-independent code, which incurs a slight performance hit,
55  but it necessary for a shared library.
56
57.. option:: --enable-languages=jit,c++
58
59  This specifies which frontends to build.  The JIT library looks like
60  a frontend to the rest of the code.
61
62  The C++ portion of the JIT test suite requires the C++ frontend to be
63  enabled at configure-time, or you may see errors like this when
64  running the test suite:
65
66  .. code-block:: console
67
68    xgcc: error: /home/david/jit/src/gcc/testsuite/jit.dg/test-quadratic.cc: C++ compiler not installed on this system
69    c++: error trying to exec 'cc1plus': execvp: No such file or directory
70
71.. option:: --disable-bootstrap
72
73  For hacking on the "jit" subdirectory, performing a full
74  bootstrap can be overkill, since it's unused by a bootstrap.  However,
75  when submitting patches, you should remove this option, to ensure that
76  the compiler can still bootstrap itself.
77
78.. option:: --enable-checking=release
79
80  The compile can perform extensive self-checking as it runs, useful when
81  debugging, but slowing things down.
82
83  For maximum speed, configure with ``--enable-checking=release`` to
84  disable this self-checking.
85
86Running the test suite
87----------------------
88
89.. code-block:: console
90
91  [build] $ cd gcc
92  [gcc] $ make check-jit RUNTESTFLAGS="-v -v -v"
93
94A summary of the tests can then be seen in:
95
96.. code-block:: console
97
98  jit/build/gcc/testsuite/jit/jit.sum
99
100and detailed logs in:
101
102.. code-block:: console
103
104  jit/build/gcc/testsuite/jit/jit.log
105
106The test executables can be seen as:
107
108.. code-block:: console
109
110  jit/build/gcc/testsuite/jit/*.exe
111
112which can be run independently.
113
114You can compile and run individual tests by passing "jit.exp=TESTNAME" to RUNTESTFLAGS e.g.:
115
116.. code-block:: console
117
118   [gcc] $ make check-jit RUNTESTFLAGS="-v -v -v jit.exp=test-factorial.c"
119
120and once a test has been compiled, you can debug it directly:
121
122.. code-block:: console
123
124   [gcc] $ PATH=.:$PATH \
125           LD_LIBRARY_PATH=. \
126           LIBRARY_PATH=. \
127             gdb --args \
128               testsuite/jit/test-factorial.c.exe
129
130Running under valgrind
131**********************
132
133The jit testsuite detects if RUN_UNDER_VALGRIND is present in the
134environment (with any value).  If it is present, it runs the test client
135code under `valgrind <http://valgrind.org>`_,
136specifcally, the default
137`memcheck <http://valgrind.org/docs/manual/mc-manual.html>`_
138tool with
139`--leak-check=full
140<http://valgrind.org/docs/manual/mc-manual.html#opt.leak-check>`_.
141
142It automatically parses the output from valgrind, injecting XFAIL results if
143any issues are found, or PASS results if the output is clean.  The output
144is saved to ``TESTNAME.exe.valgrind.txt``.
145
146For example, the following invocation verbosely runs the testcase
147``test-sum-of-squares.c`` under valgrind, showing an issue:
148
149.. code-block:: console
150
151  $ RUN_UNDER_VALGRIND= \
152      make check-jit \
153        RUNTESTFLAGS="-v -v -v jit.exp=test-sum-of-squares.c"
154
155  (...verbose log contains detailed valgrind errors, if any...)
156
157                  === jit Summary ===
158
159  # of expected passes            28
160  # of expected failures          2
161
162  $ less testsuite/jit/jit.sum
163  (...other results...)
164  XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: definitely lost: 8 bytes in 1 blocks
165  XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: unsuppressed errors: 1
166  (...other results...)
167
168  $ less testsuite/jit/test-sum-of-squares.c.exe.valgrind.txt
169  (...shows full valgrind report for this test case...)
170
171When running under valgrind, it's best to have configured gcc with
172:option:`--enable-valgrind-annotations`, which automatically suppresses
173various known false positives.
174
175Environment variables
176---------------------
177When running client code against a locally-built libgccjit, three
178environment variables need to be set up:
179
180.. envvar:: LD_LIBRARY_PATH
181
182   `libgccjit.so` is dynamically linked into client code, so if running
183   against a locally-built library, ``LD_LIBRARY_PATH`` needs to be set
184   up appropriately.  The library can be found within the "gcc"
185   subdirectory of the build tree:
186
187  .. code-block:: console
188
189    $ file libgccjit.so*
190    libgccjit.so:       symbolic link to `libgccjit.so.0'
191    libgccjit.so.0:     symbolic link to `libgccjit.so.0.0.1'
192    libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, not stripped
193
194.. envvar:: PATH
195
196  The library uses a driver executable for converting from .s assembler
197  files to .so shared libraries.  Specifically, it looks for a name
198  expanded from
199  ``${target_noncanonical}-gcc-${gcc_BASEVER}${exeext}``
200  such as ``x86_64-unknown-linux-gnu-gcc-5.0.0``.
201
202  Hence ``PATH`` needs to include a directory where the library can
203  locate this executable.
204
205  The executable is normally installed to the installation bindir
206  (e.g. /usr/bin), but a copy is also created within the "gcc"
207  subdirectory of the build tree for running the testsuite, and for ease
208  of development.
209
210.. envvar:: LIBRARY_PATH
211
212  The driver executable invokes the linker, and the latter needs to locate
213  support libraries needed by the generated code, or you will see errors
214  like:
215
216  .. code-block:: console
217
218    ld: cannot find crtbeginS.o: No such file or directory
219    ld: cannot find -lgcc
220    ld: cannot find -lgcc_s
221
222  Hence if running directly from a locally-built copy (without installing),
223  ``LIBRARY_PATH`` needs to contain the "gcc" subdirectory of the build
224  tree.
225
226For example, to run a binary that uses the library against a non-installed
227build of the library in LIBGCCJIT_BUILD_DIR you need an invocation of the
228client code like this, to preprend the dir to each of the environment
229variables:
230
231.. code-block:: console
232
233  $ LD_LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LD_LIBRARY_PATH) \
234    PATH=$(LIBGCCJIT_BUILD_DIR):$(PATH) \
235    LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LIBRARY_PATH) \
236      ./jit-hello-world
237  hello world
238
239Packaging notes
240---------------
241The configure-time option :option:`--enable-host-shared` is needed when
242building the jit in order to get position-independent code.  This will
243slow down the regular compiler by a few percent.  Hence when packaging gcc
244with libgccjit, please configure and build twice:
245
246  * once without :option:`--enable-host-shared` for most languages, and
247
248  * once with :option:`--enable-host-shared` for the jit
249
250For example:
251
252.. code-block:: bash
253
254  # Configure and build with --enable-host-shared
255  # for the jit:
256  mkdir configuration-for-jit
257  pushd configuration-for-jit
258  $(SRCDIR)/configure \
259    --enable-host-shared \
260    --enable-languages=jit \
261    --prefix=$(DESTDIR)
262  make
263  popd
264
265  # Configure and build *without* --enable-host-shared
266  # for maximum speed:
267  mkdir standard-configuration
268  pushd standard-configuration
269  $(SRCDIR)/configure \
270    --enable-languages=all \
271    --prefix=$(DESTDIR)
272  make
273  popd
274
275  # Both of the above are configured to install to $(DESTDIR)
276  # Install the configuration with --enable-host-shared first
277  # *then* the one without, so that the faster build
278  # of "cc1" et al overwrites the slower build.
279  pushd configuration-for-jit
280  make install
281  popd
282
283  pushd standard-configuration
284  make install
285  popd
286
287Overview of code structure
288--------------------------
289
290The library is implemented in C++.  The source files have the ``.c``
291extension for legacy reasons.
292
293* ``libgccjit.c`` implements the API entrypoints.  It performs error
294  checking, then calls into classes of the gcc::jit::recording namespace
295  within ``jit-recording.c`` and ``jit-recording.h``.
296
297* The gcc::jit::recording classes (within ``jit-recording.c`` and
298  ``jit-recording.h``) record the API calls that are made:
299
300   .. literalinclude:: ../../jit-common.h
301    :start-after: /* Recording types.  */
302    :end-before: /* End of recording types. */
303    :language: c++
304
305* When the context is compiled, the gcc::jit::playback classes (within
306  ``jit-playback.c`` and ``jit-playback.h``) replay the API calls
307  within langhook:parse_file:
308
309   .. literalinclude:: ../../jit-common.h
310    :start-after: /* Playback types.  */
311    :end-before: /* End of playback types. */
312    :language: c++
313
314   .. literalinclude:: ../../notes.txt
315    :lines: 1-
316
317Here is a high-level summary from ``jit-common.h``:
318
319.. include:: ../../jit-common.h
320  :start-after: This comment is included by the docs.
321  :end-before: End of comment for inclusion in the docs.  */
322
323.. _example-of-log-file:
324
325Another way to understand the structure of the code is to enable logging,
326via :c:func:`gcc_jit_context_set_logfile`.  Here is an example of a log
327generated via this call:
328
329.. literalinclude:: test-hello-world.exe.log.txt
330    :lines: 1-
331
332Design notes
333------------
334It should not be possible for client code to cause an internal compiler
335error.  If this *does* happen, the root cause should be isolated (perhaps
336using :c:func:`gcc_jit_context_dump_reproducer_to_file`) and the cause
337should be rejected via additional checking.  The checking ideally should
338be within the libgccjit API entrypoints in libgccjit.c, since this is as
339close as possible to the error; failing that, a good place is within
340``recording::context::validate ()`` in jit-recording.c.
341
342Submitting patches
343------------------
344Please read the contribution guidelines for gcc at
345https://gcc.gnu.org/contribute.html.
346
347Patches for the jit should be sent to both the
348gcc-patches@gcc.gnu.org and jit@gcc.gnu.org mailing lists,
349with "jit" and "PATCH" in the Subject line.
350
351You don't need to do a full bootstrap for code that just touches the
352``jit`` and ``testsuite/jit.dg`` subdirectories.  However, please run
353``make check-jit`` before submitting the patch, and mention the results
354in your email (along with the host triple that the tests were run on).
355
356A good patch should contain the information listed in the
357gcc contribution guide linked to above; for a ``jit`` patch, the patch
358shold contain:
359
360  * the code itself (for example, a new API entrypoint will typically
361    touch ``libgccjit.h`` and ``.c``, along with support code in
362    ``jit-recording.[ch]`` and ``jit-playback.[ch]`` as appropriate)
363
364  * test coverage
365
366  * documentation for the C API
367
368  * documentation for the C++ API
369
370A patch that adds new API entrypoints should also contain:
371
372  * a feature macro in ``libgccjit.h`` so that client code that doesn't
373    use a "configure" mechanism can still easily detect the presence of
374    the entrypoint.  See e.g. ``LIBGCCJIT_HAVE_SWITCH_STATEMENTS`` (for
375    a category of entrypoints) and
376    ``LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks``
377    (for an individual entrypoint).
378
379  * a new ABI tag containing the new symbols (in ``libgccjit.map``), so
380    that we can detect client code that uses them
381
382  * Support for :c:func:`gcc_jit_context_dump_reproducer_to_file`.  Most
383    jit testcases attempt to dump their contexts to a .c file; ``jit.exp``
384    then sanity-checks the generated c by compiling them (though
385    not running them).   A new API entrypoint
386    needs to "know" how to write itself back out to C (by implementing
387    ``gcc::jit::recording::memento::write_reproducer`` for the appropriate
388    ``memento`` subclass).
389
390  * C++ bindings for the new entrypoints (see ``libgccjit++.h``); ideally
391    with test coverage, though the C++ API test coverage is admittedly
392    spotty at the moment
393
394  * documentation for the new C entrypoints
395
396  * documentation for the new C++ entrypoints
397
398  * documentation for the new ABI tag (see ``topics/compatibility.rst``).
399
400Depending on the patch you can either extend an existing test case, or
401add a new test case.  If you add an entirely new testcase: ``jit.exp``
402expects jit testcases to begin with ``test-``, or ``test-error-`` (for a
403testcase that generates an error on a :c:type:`gcc_jit_context`).
404
405Every new testcase that doesn't generate errors should also touch
406``gcc/testsuite/jit.dg/all-non-failing-tests.h``:
407
408  * Testcases that don't generate errors should ideally be added to the
409    ``testcases`` array in that file; this means that, in addition
410    to being run standalone, they also get run within
411    ``test-combination.c`` (which runs all successful tests inside one
412    big :c:type:`gcc_jit_context`), and ``test-threads.c`` (which runs all
413    successful tests in one process, each one running in a different
414    thread on a different :c:type:`gcc_jit_context`).
415
416    .. note::
417
418       Given that exported functions within a :c:type:`gcc_jit_context`
419       must have unique names, and most testcases are run within
420       ``test-combination.c``, this means that every jit-compiled test
421       function typically needs a name that's unique across the entire
422       test suite.
423
424  * Testcases that aren't to be added to the ``testcases`` array should
425    instead add a comment to the file clarifying why they're not in that
426    array. See the file for examples.
427
428Typically a patch that touches the .rst documentation will also need the
429texinfo to be regenerated.  You can do this with
430`Sphinx 1.0 <http://sphinx-doc.org/>`_ or later by
431running ``make texinfo`` within ``SRCDIR/gcc/jit/docs``.   Don't do this
432within the patch sent to the mailing list; it can often be relatively
433large and inconsequential (e.g. anchor renumbering), rather like generated
434"configure" changes from configure.ac.  You can regenerate it when
435committing to svn.
436