index.rst revision 1.1
1.. Copyright (C) 2014-2015 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 290* ``libgccjit.c`` implements the API entrypoints. It performs error 291 checking, then calls into classes of the gcc::jit::recording namespace 292 within ``jit-recording.c`` and ``jit-recording.h``. 293 294* The gcc::jit::recording classes (within ``jit-recording.c`` and 295 ``jit-recording.h``) record the API calls that are made: 296 297 .. literalinclude:: ../../jit-common.h 298 :start-after: /* Recording types. */ 299 :end-before: /* End of recording types. */ 300 :language: c++ 301 302* When the context is compiled, the gcc::jit::playback classes (within 303 ``jit-playback.c`` and ``jit-playback.h``) replay the API calls 304 within langhook:parse_file: 305 306 .. literalinclude:: ../../jit-common.h 307 :start-after: /* Playback types. */ 308 :end-before: /* End of playback types. */ 309 :language: c++ 310 311 .. literalinclude:: ../../notes.txt 312 :lines: 1- 313 314Here is a high-level summary from ``jit-common.h``: 315 316.. include:: ../../jit-common.h 317 :start-after: This comment is included by the docs. 318 :end-before: End of comment for inclusion in the docs. */ 319 320.. _example-of-log-file: 321 322Another way to understand the structure of the code is to enable logging, 323via :c:func:`gcc_jit_context_set_logfile`. Here is an example of a log 324generated via this call: 325 326.. literalinclude:: test-hello-world.exe.log.txt 327 :lines: 1- 328 329Design notes 330------------ 331It should not be possible for client code to cause an internal compiler 332error. If this *does* happen, the root cause should be isolated (perhaps 333using :c:func:`gcc_jit_context_dump_reproducer_to_file`) and the cause 334should be rejected via additional checking. The checking ideally should 335be within the libgccjit API entrypoints in libgccjit.c, since this is as 336close as possible to the error; failing that, a good place is within 337``recording::context::validate ()`` in jit-recording.c. 338