Compilation contexts¶
-
class
gccjit
::
context
¶
The top-level of the C++ API is the gccjit::context
type.
A gccjit::context
instance encapsulates the state of a
compilation.
You can set up options on it, and add types, functions and code.
Invoking gccjit::context::compile()
on it gives you a
gcc_jit_result *
.
It is a thin wrapper around the C API’s gcc_jit_context *
.
Lifetime-management¶
Contexts are the unit of lifetime-management within the API: objects have their lifetime bounded by the context they are created within, and cleanup of such objects is done for you when the context is released.
-
gccjit::context
gccjit::context
::
acquire
()¶ This function acquires a new
gccjit::context
instance, which is independent of any others that may be present within this process.
-
void
gccjit::context
::
release
()¶ This function releases all resources associated with the given context. Both the context itself and all of its
gccjit::object *
instances are cleaned up. It should be called exactly once on a given context.It is invalid to use the context or any of its “contextual” objects after calling this.
ctxt.release ();
-
gccjit::context
gccjit::context
::
new_child_context
()¶ Given an existing JIT context, create a child context.
The child inherits a copy of all option-settings from the parent.
The child can reference objects created within the parent, but not vice-versa.
The lifetime of the child context must be bounded by that of the parent: you should release a child context before releasing the parent context.
If you use a function from a parent context within a child context, you have to compile the parent context before you can compile the child context, and the gccjit::result of the parent context must outlive the gccjit::result of the child context.
This allows caching of shared initializations. For example, you could create types and declarations of global functions in a parent context once within a process, and then create child contexts whenever a function or loop becomes hot. Each such child context can be used for JIT-compiling just one function or loop, but can reference types and helper functions created within the parent context.
Contexts can be arbitrarily nested, provided the above rules are followed, but it’s probably not worth going above 2 or 3 levels, and there will likely be a performance hit for such nesting.
Thread-safety¶
Instances of gccjit::context
created via
gccjit::context::acquire()
are independent from each other:
only one thread may use a given context at once, but multiple threads
could each have their own contexts without needing locks.
Contexts created via gccjit::context::new_child_context()
are
related to their parent context. They can be partitioned by their
ultimate ancestor into independent “family trees”. Only one thread
within a process may use a given “family tree” of such contexts at once,
and if you’re using multiple threads you should provide your own locking
around entire such context partitions.
Error-handling¶
You can only compile and get code from a context if no errors occur.
In general, if an error occurs when using an API entrypoint, it returns NULL. You don’t have to check everywhere for NULL results, since the API gracefully handles a NULL being passed in for any argument.
Errors are printed on stderr and can be queried using
gccjit::context::get_first_error()
.
Debugging¶
-
void
gccjit::context
::
dump_to_file
(const std::string &path, int update_locations)¶ To help with debugging: dump a C-like representation to the given path, describing what’s been set up on the context.
If “update_locations” is true, then also set up
gccjit::location
information throughout the context, pointing at the dump file as if it were a source file. This may be of use in conjunction withGCCJIT::BOOL_OPTION_DEBUGINFO
to allow stepping through the code in a debugger.
-
void
gccjit::context
::
dump_reproducer_to_file
(gcc_jit_context *ctxt, const char *path)¶ This is a thin wrapper around the C API
gcc_jit_context_dump_reproducer_to_file()
, and hence works the same way.Note that the generated source is C code, not C++; this might be of use for seeing what the C++ bindings are doing at the C level.
Options¶
String Options¶
-
void
gccjit::context
::
set_str_option
(enum gcc_jit_str_option, const char *value)¶ Set a string option of the context.
This is a thin wrapper around the C API
gcc_jit_context_set_str_option()
; the options have the same meaning.
Boolean options¶
-
void
gccjit::context
::
set_bool_option
(enum gcc_jit_bool_option, int value)¶ Set a boolean option of the context.
This is a thin wrapper around the C API
gcc_jit_context_set_bool_option()
; the options have the same meaning.
-
void
gccjit::context
::
set_bool_allow_unreachable_blocks
(int bool_value)¶ By default, libgccjit will issue an error about unreachable blocks within a function.
This entrypoint can be used to disable that error; it is a thin wrapper around the C API
gcc_jit_context_set_bool_allow_unreachable_blocks()
.This entrypoint was added in LIBGCCJIT_ABI_2; you can test for its presence using
#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks
-
void
gccjit::context
::
set_bool_use_external_driver
(int bool_value)¶ libgccjit internally generates assembler, and uses “driver” code for converting it to other formats (e.g. shared libraries).
By default, libgccjit will use an embedded copy of the driver code.
This option can be used to instead invoke an external driver executable as a subprocess; it is a thin wrapper around the C API
gcc_jit_context_set_bool_use_external_driver()
.This entrypoint was added in LIBGCCJIT_ABI_5; you can test for its presence using
#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_use_external_driver
Integer options¶
-
void
gccjit::context
::
set_int_option
(enum gcc_jit_int_option, int value)¶ Set an integer option of the context.
This is a thin wrapper around the C API
gcc_jit_context_set_int_option()
; the options have the same meaning.
Additional command-line options¶
-
void
gccjit::context
::
add_command_line_option
(const char *optname)¶ Add an arbitrary gcc command-line option to the context for use when compiling.
This is a thin wrapper around the C API
gcc_jit_context_add_command_line_option()
.This entrypoint was added in LIBGCCJIT_ABI_1; you can test for its presence using
#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option