131
|
1 .. Copyright (C) 2014-2018 Free Software Foundation, Inc.
|
111
|
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
|
|
18 .. default-domain:: c
|
|
19
|
|
20 Compilation contexts
|
|
21 ====================
|
|
22
|
|
23 .. type:: gcc_jit_context
|
|
24
|
|
25 The top-level of the API is the :c:type:`gcc_jit_context` type.
|
|
26
|
|
27 A :c:type:`gcc_jit_context` instance encapsulates the state of a
|
|
28 compilation.
|
|
29
|
|
30 You can set up options on it, and add types, functions and code.
|
|
31 Invoking :c:func:`gcc_jit_context_compile` on it gives you a
|
|
32 :c:type:`gcc_jit_result`.
|
|
33
|
|
34 Lifetime-management
|
|
35 -------------------
|
|
36 Contexts are the unit of lifetime-management within the API: objects
|
|
37 have their lifetime bounded by the context they are created within, and
|
|
38 cleanup of such objects is done for you when the context is released.
|
|
39
|
|
40 .. function:: gcc_jit_context *gcc_jit_context_acquire (void)
|
|
41
|
|
42 This function acquires a new :c:type:`gcc_jit_context *` instance,
|
|
43 which is independent of any others that may be present within this
|
|
44 process.
|
|
45
|
|
46 .. function:: void gcc_jit_context_release (gcc_jit_context *ctxt)
|
|
47
|
|
48 This function releases all resources associated with the given context.
|
|
49 Both the context itself and all of its :c:type:`gcc_jit_object *`
|
|
50 instances are cleaned up. It should be called exactly once on a given
|
|
51 context.
|
|
52
|
|
53 It is invalid to use the context or any of its "contextual" objects
|
|
54 after calling this.
|
|
55
|
|
56 .. code-block:: c
|
|
57
|
|
58 gcc_jit_context_release (ctxt);
|
|
59
|
|
60 .. function:: gcc_jit_context * gcc_jit_context_new_child_context (gcc_jit_context *parent_ctxt)
|
|
61
|
|
62 Given an existing JIT context, create a child context.
|
|
63
|
|
64 The child inherits a copy of all option-settings from the parent.
|
|
65
|
|
66 The child can reference objects created within the parent, but not
|
|
67 vice-versa.
|
|
68
|
|
69 The lifetime of the child context must be bounded by that of the
|
|
70 parent: you should release a child context before releasing the parent
|
|
71 context.
|
|
72
|
|
73 If you use a function from a parent context within a child context,
|
|
74 you have to compile the parent context before you can compile the
|
|
75 child context, and the gcc_jit_result of the parent context must
|
|
76 outlive the gcc_jit_result of the child context.
|
|
77
|
|
78 This allows caching of shared initializations. For example, you could
|
|
79 create types and declarations of global functions in a parent context
|
|
80 once within a process, and then create child contexts whenever a
|
|
81 function or loop becomes hot. Each such child context can be used for
|
|
82 JIT-compiling just one function or loop, but can reference types
|
|
83 and helper functions created within the parent context.
|
|
84
|
|
85 Contexts can be arbitrarily nested, provided the above rules are
|
|
86 followed, but it's probably not worth going above 2 or 3 levels, and
|
|
87 there will likely be a performance hit for such nesting.
|
|
88
|
|
89
|
|
90 Thread-safety
|
|
91 -------------
|
|
92 Instances of :c:type:`gcc_jit_context *` created via
|
|
93 :c:func:`gcc_jit_context_acquire` are independent from each other:
|
|
94 only one thread may use a given context at once, but multiple threads
|
|
95 could each have their own contexts without needing locks.
|
|
96
|
|
97 Contexts created via :c:func:`gcc_jit_context_new_child_context` are
|
|
98 related to their parent context. They can be partitioned by their
|
|
99 ultimate ancestor into independent "family trees". Only one thread
|
|
100 within a process may use a given "family tree" of such contexts at once,
|
|
101 and if you're using multiple threads you should provide your own locking
|
|
102 around entire such context partitions.
|
|
103
|
|
104 .. _error-handling:
|
|
105
|
|
106 Error-handling
|
|
107 --------------
|
|
108 Various kinds of errors are possible when using the API, such as
|
|
109 mismatched types in an assignment. You can only compile and get code from
|
|
110 a context if no errors occur.
|
|
111
|
|
112 Errors are printed on stderr and can be queried using
|
|
113 :c:func:`gcc_jit_context_get_first_error`.
|
|
114
|
|
115 They typically contain the name of the API entrypoint where the error
|
|
116 occurred, and pertinent information on the problem:
|
|
117
|
|
118 .. code-block:: console
|
|
119
|
|
120 ./buggy-program: error: gcc_jit_block_add_assignment: mismatching types: assignment to i (type: int) from "hello world" (type: const char *)
|
|
121
|
|
122 In general, if an error occurs when using an API entrypoint, the
|
|
123 entrypoint returns NULL. You don't have to check everywhere for NULL
|
|
124 results, since the API handles a NULL being passed in for any
|
|
125 argument by issuing another error. This typically leads to a cascade of
|
|
126 followup error messages, but is safe (albeit verbose). The first error
|
|
127 message is usually the one to pay attention to, since it is likely to
|
|
128 be responsible for all of the rest:
|
|
129
|
|
130 .. function:: const char *\
|
|
131 gcc_jit_context_get_first_error (gcc_jit_context *ctxt)
|
|
132
|
|
133 Returns the first error message that occurred on the context.
|
|
134
|
|
135 The returned string is valid for the rest of the lifetime of the
|
|
136 context.
|
|
137
|
|
138 If no errors occurred, this will be NULL.
|
|
139
|
|
140 If you are wrapping the C API for a higher-level language that supports
|
|
141 exception-handling, you may instead be interested in the last error that
|
|
142 occurred on the context, so that you can embed this in an exception:
|
|
143
|
|
144 .. function:: const char *\
|
|
145 gcc_jit_context_get_last_error (gcc_jit_context *ctxt)
|
|
146
|
|
147 Returns the last error message that occurred on the context.
|
|
148
|
|
149 If no errors occurred, this will be NULL.
|
|
150
|
|
151 If non-NULL, the returned string is only guaranteed to be valid until
|
|
152 the next call to libgccjit relating to this context.
|
|
153
|
|
154 Debugging
|
|
155 ---------
|
|
156
|
|
157 .. function:: void\
|
|
158 gcc_jit_context_dump_to_file (gcc_jit_context *ctxt,\
|
|
159 const char *path,\
|
|
160 int update_locations)
|
|
161
|
|
162 To help with debugging: dump a C-like representation to the given path,
|
|
163 describing what's been set up on the context.
|
|
164
|
|
165 If "update_locations" is true, then also set up :type:`gcc_jit_location`
|
|
166 information throughout the context, pointing at the dump file as if it
|
|
167 were a source file. This may be of use in conjunction with
|
|
168 :macro:`GCC_JIT_BOOL_OPTION_DEBUGINFO` to allow stepping through the
|
|
169 code in a debugger.
|
|
170
|
|
171 .. function:: void\
|
|
172 gcc_jit_context_set_logfile (gcc_jit_context *ctxt,\
|
|
173 FILE *logfile,\
|
|
174 int flags,\
|
|
175 int verbosity)
|
|
176
|
|
177 To help with debugging; enable ongoing logging of the context's
|
|
178 activity to the given file.
|
|
179
|
|
180 For example, the following will enable logging to stderr.
|
|
181
|
|
182 .. code-block:: c
|
|
183
|
|
184 gcc_jit_context_set_logfile (ctxt, stderr, 0, 0);
|
|
185
|
|
186 Examples of information logged include:
|
|
187
|
|
188 * API calls
|
|
189
|
|
190 * the various steps involved within compilation
|
|
191
|
|
192 * activity on any :c:type:`gcc_jit_result` instances created by
|
|
193 the context
|
|
194
|
|
195 * activity within any child contexts
|
|
196
|
|
197 An example of a log can be seen :ref:`here <example-of-log-file>`,
|
|
198 though the precise format and kinds of information logged is subject
|
|
199 to change.
|
|
200
|
|
201 The caller remains responsible for closing `logfile`, and it must not
|
|
202 be closed until all users are released. In particular, note that
|
|
203 child contexts and :c:type:`gcc_jit_result` instances created by
|
|
204 the context will use the logfile.
|
|
205
|
|
206 There may a performance cost for logging.
|
|
207
|
|
208 You can turn off logging on `ctxt` by passing `NULL` for `logfile`.
|
|
209 Doing so only affects the context; it does not affect child contexts
|
|
210 or :c:type:`gcc_jit_result` instances already created by
|
|
211 the context.
|
|
212
|
|
213 The parameters "flags" and "verbosity" are reserved for future
|
|
214 expansion, and must be zero for now.
|
|
215
|
|
216 To contrast the above: :c:func:`gcc_jit_context_dump_to_file` dumps the
|
|
217 current state of a context to the given path, whereas
|
|
218 :c:func:`gcc_jit_context_set_logfile` enables on-going logging of
|
|
219 future activies on a context to the given `FILE *`.
|
|
220
|
|
221
|
|
222 .. function:: void\
|
|
223 gcc_jit_context_dump_reproducer_to_file (gcc_jit_context *ctxt,\
|
|
224 const char *path)
|
|
225
|
|
226 Write C source code into `path` that can be compiled into a
|
|
227 self-contained executable (i.e. with libgccjit as the only dependency).
|
|
228 The generated code will attempt to replay the API calls that have been
|
|
229 made into the given context.
|
|
230
|
|
231 This may be useful when debugging the library or client code, for
|
|
232 reducing a complicated recipe for reproducing a bug into a simpler
|
|
233 form. For example, consider client code that parses some source file
|
|
234 into some internal representation, and then walks this IR, calling into
|
|
235 libgccjit. If this encounters a bug, a call to
|
|
236 `gcc_jit_context_dump_reproducer_to_file` will write out C code for
|
|
237 a much simpler executable that performs the equivalent calls into
|
|
238 libgccjit, without needing the client code and its data.
|
|
239
|
|
240 Typically you need to supply :option:`-Wno-unused-variable` when
|
|
241 compiling the generated file (since the result of each API call is
|
|
242 assigned to a unique variable within the generated C source, and not
|
|
243 all are necessarily then used).
|
|
244
|
|
245 .. function:: void\
|
|
246 gcc_jit_context_enable_dump (gcc_jit_context *ctxt,\
|
|
247 const char *dumpname, \
|
|
248 char **out_ptr)
|
|
249
|
|
250 Enable the dumping of a specific set of internal state from the
|
|
251 compilation, capturing the result in-memory as a buffer.
|
|
252
|
|
253 Parameter "dumpname" corresponds to the equivalent gcc command-line
|
|
254 option, without the "-fdump-" prefix.
|
|
255 For example, to get the equivalent of :option:`-fdump-tree-vrp1`,
|
|
256 supply ``"tree-vrp1"``:
|
|
257
|
|
258 .. code-block:: c
|
|
259
|
|
260 static char *dump_vrp1;
|
|
261
|
|
262 void
|
|
263 create_code (gcc_jit_context *ctxt)
|
|
264 {
|
|
265 gcc_jit_context_enable_dump (ctxt, "tree-vrp1", &dump_vrp1);
|
|
266 /* (other API calls omitted for brevity) */
|
|
267 }
|
|
268
|
|
269 The context directly stores the dumpname as a ``(const char *)``, so
|
|
270 the passed string must outlive the context.
|
|
271
|
|
272 :func:`gcc_jit_context_compile` will capture the dump as a
|
|
273 dynamically-allocated buffer, writing it to ``*out_ptr``.
|
|
274
|
|
275 The caller becomes responsible for calling:
|
|
276
|
|
277 .. code-block:: c
|
|
278
|
|
279 free (*out_ptr)
|
|
280
|
|
281 each time that :func:`gcc_jit_context_compile` is called.
|
|
282 ``*out_ptr`` will be written to, either with the address of a buffer,
|
|
283 or with ``NULL`` if an error occurred.
|
|
284
|
|
285 .. warning::
|
|
286
|
|
287 This API entrypoint is likely to be less stable than the others.
|
|
288 In particular, both the precise dumpnames, and the format and content
|
|
289 of the dumps are subject to change.
|
|
290
|
|
291 It exists primarily for writing the library's own test suite.
|
|
292
|
|
293 Options
|
|
294 -------
|
|
295
|
|
296 Options present in the initial release of libgccjit were handled using
|
|
297 enums, whereas those added subsequently have their own per-option API
|
|
298 entrypoints.
|
|
299
|
|
300 Adding entrypoints for each new option means that client code that use
|
|
301 the new options can be identified directly from binary metadata, which
|
|
302 would not be possible if we instead extended the various
|
|
303 ``enum gcc_jit_*_option``.
|
|
304
|
|
305 String Options
|
|
306 **************
|
|
307
|
|
308 .. function:: void gcc_jit_context_set_str_option(gcc_jit_context *ctxt, \
|
|
309 enum gcc_jit_str_option opt, \
|
|
310 const char *value)
|
|
311
|
|
312 Set a string option of the context.
|
|
313
|
|
314 .. type:: enum gcc_jit_str_option
|
|
315
|
|
316 The parameter ``value`` can be NULL. If non-NULL, the call takes a
|
|
317 copy of the underlying string, so it is valid to pass in a pointer to
|
|
318 an on-stack buffer.
|
|
319
|
|
320 There is just one string option specified this way:
|
|
321
|
|
322 .. macro:: GCC_JIT_STR_OPTION_PROGNAME
|
|
323
|
|
324 The name of the program, for use as a prefix when printing error
|
|
325 messages to stderr. If `NULL`, or default, "libgccjit.so" is used.
|
|
326
|
|
327 Boolean options
|
|
328 ***************
|
|
329
|
|
330 .. function:: void gcc_jit_context_set_bool_option(gcc_jit_context *ctxt, \
|
|
331 enum gcc_jit_bool_option opt, \
|
|
332 int value)
|
|
333
|
|
334 Set a boolean option of the context.
|
|
335 Zero is "false" (the default), non-zero is "true".
|
|
336
|
|
337 .. type:: enum gcc_jit_bool_option
|
|
338
|
|
339 .. macro:: GCC_JIT_BOOL_OPTION_DEBUGINFO
|
|
340
|
|
341 If true, :func:`gcc_jit_context_compile` will attempt to do the right
|
|
342 thing so that if you attach a debugger to the process, it will
|
|
343 be able to inspect variables and step through your code.
|
|
344
|
|
345 Note that you can't step through code unless you set up source
|
|
346 location information for the code (by creating and passing in
|
|
347 :type:`gcc_jit_location` instances).
|
|
348
|
|
349 .. macro:: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE
|
|
350
|
|
351 If true, :func:`gcc_jit_context_compile` will dump its initial
|
|
352 "tree" representation of your code to stderr (before any
|
|
353 optimizations).
|
|
354
|
|
355 Here's some sample output (from the `square` example)::
|
|
356
|
|
357 <statement_list 0x7f4875a62cc0
|
|
358 type <void_type 0x7f4875a64bd0 VOID
|
|
359 align 8 symtab 0 alias set -1 canonical type 0x7f4875a64bd0
|
|
360 pointer_to_this <pointer_type 0x7f4875a64c78>>
|
|
361 side-effects head 0x7f4875a761e0 tail 0x7f4875a761f8 stmts 0x7f4875a62d20 0x7f4875a62d00
|
|
362
|
|
363 stmt <label_expr 0x7f4875a62d20 type <void_type 0x7f4875a64bd0>
|
|
364 side-effects
|
|
365 arg 0 <label_decl 0x7f4875a79080 entry type <void_type 0x7f4875a64bd0>
|
|
366 VOID file (null) line 0 col 0
|
|
367 align 1 context <function_decl 0x7f4875a77500 square>>>
|
|
368 stmt <return_expr 0x7f4875a62d00
|
|
369 type <integer_type 0x7f4875a645e8 public SI
|
|
370 size <integer_cst 0x7f4875a623a0 constant 32>
|
|
371 unit size <integer_cst 0x7f4875a623c0 constant 4>
|
|
372 align 32 symtab 0 alias set -1 canonical type 0x7f4875a645e8 precision 32 min <integer_cst 0x7f4875a62340 -2147483648> max <integer_cst 0x7f4875a62360 2147483647>
|
|
373 pointer_to_this <pointer_type 0x7f4875a6b348>>
|
|
374 side-effects
|
|
375 arg 0 <modify_expr 0x7f4875a72a78 type <integer_type 0x7f4875a645e8>
|
|
376 side-effects arg 0 <result_decl 0x7f4875a7a000 D.54>
|
|
377 arg 1 <mult_expr 0x7f4875a72a50 type <integer_type 0x7f4875a645e8>
|
|
378 arg 0 <parm_decl 0x7f4875a79000 i> arg 1 <parm_decl 0x7f4875a79000 i>>>>>
|
|
379
|
|
380 .. macro:: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE
|
|
381
|
|
382 If true, :func:`gcc_jit_context_compile` will dump the "gimple"
|
|
383 representation of your code to stderr, before any optimizations
|
|
384 are performed. The dump resembles C code:
|
|
385
|
|
386 .. code-block:: c
|
|
387
|
|
388 square (signed int i)
|
|
389 {
|
|
390 signed int D.56;
|
|
391
|
|
392 entry:
|
|
393 D.56 = i * i;
|
|
394 return D.56;
|
|
395 }
|
|
396
|
|
397 .. macro:: GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE
|
|
398
|
|
399 If true, :func:`gcc_jit_context_compile` will dump the final
|
|
400 generated code to stderr, in the form of assembly language:
|
|
401
|
|
402 .. code-block:: gas
|
|
403
|
|
404 .file "fake.c"
|
|
405 .text
|
|
406 .globl square
|
|
407 .type square, @function
|
|
408 square:
|
|
409 .LFB0:
|
|
410 .cfi_startproc
|
|
411 pushq %rbp
|
|
412 .cfi_def_cfa_offset 16
|
|
413 .cfi_offset 6, -16
|
|
414 movq %rsp, %rbp
|
|
415 .cfi_def_cfa_register 6
|
|
416 movl %edi, -4(%rbp)
|
|
417 .L2:
|
|
418 movl -4(%rbp), %eax
|
|
419 imull -4(%rbp), %eax
|
|
420 popq %rbp
|
|
421 .cfi_def_cfa 7, 8
|
|
422 ret
|
|
423 .cfi_endproc
|
|
424 .LFE0:
|
|
425 .size square, .-square
|
|
426 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.1-%{gcc_release})"
|
|
427 .section .note.GNU-stack,"",@progbits
|
|
428
|
|
429
|
|
430 .. macro:: GCC_JIT_BOOL_OPTION_DUMP_SUMMARY
|
|
431
|
|
432 If true, :func:`gcc_jit_context_compile` will print information to stderr
|
|
433 on the actions it is performing.
|
|
434
|
|
435 .. macro:: GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING
|
|
436
|
|
437 If true, :func:`gcc_jit_context_compile` will dump copious
|
|
438 amount of information on what it's doing to various
|
|
439 files within a temporary directory. Use
|
|
440 :macro:`GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES` (see below) to
|
|
441 see the results. The files are intended to be human-readable,
|
|
442 but the exact files and their formats are subject to change.
|
|
443
|
|
444 .. macro:: GCC_JIT_BOOL_OPTION_SELFCHECK_GC
|
|
445
|
|
446 If true, libgccjit will aggressively run its garbage collector, to
|
|
447 shake out bugs (greatly slowing down the compile). This is likely
|
|
448 to only be of interest to developers *of* the library. It is
|
|
449 used when running the selftest suite.
|
|
450
|
|
451 .. macro:: GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES
|
|
452
|
|
453 If true, the :type:`gcc_jit_context` will not clean up intermediate files
|
|
454 written to the filesystem, and will display their location on stderr.
|
|
455
|
|
456 .. function:: void \
|
|
457 gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context *ctxt, \
|
|
458 int bool_value)
|
|
459
|
|
460 By default, libgccjit will issue an error about unreachable blocks
|
|
461 within a function.
|
|
462
|
|
463 This entrypoint can be used to disable that error.
|
|
464
|
|
465 This entrypoint was added in :ref:`LIBGCCJIT_ABI_2`; you can test for
|
|
466 its presence using
|
|
467
|
|
468 .. code-block:: c
|
|
469
|
|
470 #ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks
|
|
471
|
|
472 .. function:: void \
|
|
473 gcc_jit_context_set_bool_use_external_driver (gcc_jit_context *ctxt, \
|
|
474 int bool_value)
|
|
475
|
|
476 libgccjit internally generates assembler, and uses "driver" code
|
|
477 for converting it to other formats (e.g. shared libraries).
|
|
478
|
|
479 By default, libgccjit will use an embedded copy of the driver
|
|
480 code.
|
|
481
|
|
482 This option can be used to instead invoke an external driver executable
|
|
483 as a subprocess.
|
|
484
|
|
485 This entrypoint was added in :ref:`LIBGCCJIT_ABI_5`; you can test for
|
|
486 its presence using
|
|
487
|
|
488 .. code-block:: c
|
|
489
|
|
490 #ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_use_external_driver
|
|
491
|
|
492 Integer options
|
|
493 ***************
|
|
494
|
|
495 .. function:: void gcc_jit_context_set_int_option (gcc_jit_context *ctxt, \
|
|
496 enum gcc_jit_int_option opt, \
|
|
497 int value)
|
|
498
|
|
499 Set an integer option of the context.
|
|
500
|
|
501 .. type:: enum gcc_jit_int_option
|
|
502
|
|
503 There is just one integer option specified this way:
|
|
504
|
|
505 .. macro:: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL
|
|
506
|
|
507 How much to optimize the code.
|
|
508
|
|
509 Valid values are 0-3, corresponding to GCC's command-line options
|
|
510 -O0 through -O3.
|
|
511
|
|
512 The default value is 0 (unoptimized).
|
|
513
|
|
514 Additional command-line options
|
|
515 *******************************
|
|
516
|
|
517 .. function:: void gcc_jit_context_add_command_line_option (gcc_jit_context *ctxt,\
|
|
518 const char *optname)
|
|
519
|
|
520 Add an arbitrary gcc command-line option to the context, for use
|
|
521 by :func:`gcc_jit_context_compile` and
|
|
522 :func:`gcc_jit_context_compile_to_file`.
|
|
523
|
|
524 The parameter ``optname`` must be non-NULL. The underlying buffer is
|
|
525 copied, so that it does not need to outlive the call.
|
|
526
|
|
527 Extra options added by `gcc_jit_context_add_command_line_option` are
|
|
528 applied *after* the regular options above, potentially overriding them.
|
|
529 Options from parent contexts are inherited by child contexts; options
|
|
530 from the parent are applied *before* those from the child.
|
|
531
|
|
532 For example:
|
|
533
|
|
534 .. code-block:: c
|
|
535
|
|
536 gcc_jit_context_add_command_line_option (ctxt, "-ffast-math");
|
|
537 gcc_jit_context_add_command_line_option (ctxt, "-fverbose-asm");
|
|
538
|
|
539 Note that only some options are likely to be meaningful; there is no
|
|
540 "frontend" within libgccjit, so typically only those affecting
|
|
541 optimization and code-generation are likely to be useful.
|
|
542
|
|
543 This entrypoint was added in :ref:`LIBGCCJIT_ABI_1`; you can test for
|
|
544 its presence using
|
|
545
|
|
546 .. code-block:: c
|
|
547
|
|
548 #ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option
|