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