| /* A pure C API to enable client code to embed GCC as a JIT-compiler. |
| Copyright (C) 2013-2022 Free Software Foundation, Inc. |
| |
| This file is part of GCC. |
| |
| GCC is free software; you can redistribute it and/or modify it |
| under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3, or (at your option) |
| any later version. |
| |
| GCC is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GCC; see the file COPYING3. If not see |
| <http://www.gnu.org/licenses/>. */ |
| |
| #ifndef LIBGCCJIT_H |
| #define LIBGCCJIT_H |
| |
| #include <stdio.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif /* __cplusplus */ |
| |
| /********************************************************************** |
| Data structures. |
| **********************************************************************/ |
| /* All structs within the API are opaque. */ |
| |
| /* A gcc_jit_context encapsulates the state of a compilation. |
| You can set up options on it, and add types, functions and code, using |
| the API below. |
| |
| Invoking gcc_jit_context_compile on it gives you a gcc_jit_result * |
| (or NULL), representing in-memory machine code. |
| |
| You can call gcc_jit_context_compile repeatedly on one context, giving |
| multiple independent results. |
| |
| Similarly, you can call gcc_jit_context_compile_to_file on a context |
| to compile to disk. |
| |
| Eventually you can call gcc_jit_context_release to clean up the |
| context; any in-memory results created from it are still usable, and |
| should be cleaned up via gcc_jit_result_release. */ |
| typedef struct gcc_jit_context gcc_jit_context; |
| |
| /* A gcc_jit_result encapsulates the result of an in-memory compilation. */ |
| typedef struct gcc_jit_result gcc_jit_result; |
| |
| /* An object created within a context. Such objects are automatically |
| cleaned up when the context is released. |
| |
| The class hierarchy looks like this: |
| |
| +- gcc_jit_object |
| +- gcc_jit_location |
| +- gcc_jit_type |
| +- gcc_jit_struct |
| +- gcc_jit_function_type |
| +- gcc_jit_vector_type |
| +- gcc_jit_field |
| +- gcc_jit_function |
| +- gcc_jit_block |
| +- gcc_jit_rvalue |
| +- gcc_jit_lvalue |
| +- gcc_jit_param |
| +- gcc_jit_case |
| +- gcc_jit_extended_asm |
| */ |
| typedef struct gcc_jit_object gcc_jit_object; |
| |
| /* A gcc_jit_location encapsulates a source code location, so that |
| you can (optionally) associate locations in your language with |
| statements in the JIT-compiled code, allowing the debugger to |
| single-step through your language. |
| |
| Note that to do so, you also need to enable |
| GCC_JIT_BOOL_OPTION_DEBUGINFO |
| on the gcc_jit_context. |
| |
| gcc_jit_location instances are optional; you can always pass |
| NULL. */ |
| typedef struct gcc_jit_location gcc_jit_location; |
| |
| /* A gcc_jit_type encapsulates a type e.g. "int" or a "struct foo*". */ |
| typedef struct gcc_jit_type gcc_jit_type; |
| |
| /* A gcc_jit_field encapsulates a field within a struct; it is used |
| when creating a struct type (using gcc_jit_context_new_struct_type). |
| Fields cannot be shared between structs. */ |
| typedef struct gcc_jit_field gcc_jit_field; |
| |
| /* A gcc_jit_struct encapsulates a struct type, either one that we have |
| the layout for, or an opaque type. */ |
| typedef struct gcc_jit_struct gcc_jit_struct; |
| |
| /* A gcc_jit_function_type encapsulates a function type. */ |
| typedef struct gcc_jit_function_type gcc_jit_function_type; |
| |
| /* A gcc_jit_vector_type encapsulates a vector type. */ |
| typedef struct gcc_jit_vector_type gcc_jit_vector_type; |
| |
| /* A gcc_jit_function encapsulates a function: either one that you're |
| creating yourself, or a reference to one that you're dynamically |
| linking to within the rest of the process. */ |
| typedef struct gcc_jit_function gcc_jit_function; |
| |
| /* A gcc_jit_block encapsulates a "basic block" of statements within a |
| function (i.e. with one entry point and one exit point). |
| |
| Every block within a function must be terminated with a conditional, |
| a branch, or a return. |
| |
| The blocks within a function form a directed graph. |
| |
| The entrypoint to the function is the first block created within |
| it. |
| |
| All of the blocks in a function must be reachable via some path from |
| the first block. |
| |
| It's OK to have more than one "return" from a function (i.e. multiple |
| blocks that terminate by returning). */ |
| typedef struct gcc_jit_block gcc_jit_block; |
| |
| /* A gcc_jit_rvalue is an expression within your code, with some type. */ |
| typedef struct gcc_jit_rvalue gcc_jit_rvalue; |
| |
| /* A gcc_jit_lvalue is a storage location within your code (e.g. a |
| variable, a parameter, etc). It is also a gcc_jit_rvalue; use |
| gcc_jit_lvalue_as_rvalue to cast. */ |
| typedef struct gcc_jit_lvalue gcc_jit_lvalue; |
| |
| /* A gcc_jit_param is a function parameter, used when creating a |
| gcc_jit_function. It is also a gcc_jit_lvalue (and thus also an |
| rvalue); use gcc_jit_param_as_lvalue to convert. */ |
| typedef struct gcc_jit_param gcc_jit_param; |
| |
| /* A gcc_jit_case is for use when building multiway branches via |
| gcc_jit_block_end_with_switch and represents a range of integer |
| values (or an individual integer value) together with an associated |
| destination block. */ |
| typedef struct gcc_jit_case gcc_jit_case; |
| |
| /* A gcc_jit_extended_asm represents an assembly language statement, |
| analogous to an extended "asm" statement in GCC's C front-end: a series |
| of low-level instructions inside a function that convert inputs to |
| outputs. */ |
| typedef struct gcc_jit_extended_asm gcc_jit_extended_asm; |
| |
| /* Acquire a JIT-compilation context. */ |
| extern gcc_jit_context * |
| gcc_jit_context_acquire (void); |
| |
| /* Release the context. After this call, it's no longer valid to use |
| the ctxt. */ |
| extern void |
| gcc_jit_context_release (gcc_jit_context *ctxt); |
| |
| /* Options present in the initial release of libgccjit. |
| These were handled using enums. */ |
| |
| /* Options taking string values. */ |
| enum gcc_jit_str_option |
| { |
| /* The name of the program, for use as a prefix when printing error |
| messages to stderr. If NULL, or default, "libgccjit.so" is used. */ |
| GCC_JIT_STR_OPTION_PROGNAME, |
| |
| GCC_JIT_NUM_STR_OPTIONS |
| }; |
| |
| /* Options taking int values. */ |
| enum gcc_jit_int_option |
| { |
| /* How much to optimize the code. |
| Valid values are 0-3, corresponding to GCC's command-line options |
| -O0 through -O3. |
| |
| The default value is 0 (unoptimized). */ |
| GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, |
| |
| GCC_JIT_NUM_INT_OPTIONS |
| }; |
| |
| /* Options taking boolean values. |
| These all default to "false". */ |
| enum gcc_jit_bool_option |
| { |
| /* If true, gcc_jit_context_compile will attempt to do the right |
| thing so that if you attach a debugger to the process, it will |
| be able to inspect variables and step through your code. |
| |
| Note that you can't step through code unless you set up source |
| location information for the code (by creating and passing in |
| gcc_jit_location instances). */ |
| GCC_JIT_BOOL_OPTION_DEBUGINFO, |
| |
| /* If true, gcc_jit_context_compile will dump its initial "tree" |
| representation of your code to stderr (before any |
| optimizations). */ |
| GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE, |
| |
| /* If true, gcc_jit_context_compile will dump the "gimple" |
| representation of your code to stderr, before any optimizations |
| are performed. The dump resembles C code. */ |
| GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, |
| |
| /* If true, gcc_jit_context_compile will dump the final |
| generated code to stderr, in the form of assembly language. */ |
| GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, |
| |
| /* If true, gcc_jit_context_compile will print information to stderr |
| on the actions it is performing, followed by a profile showing |
| the time taken and memory usage of each phase. |
| */ |
| GCC_JIT_BOOL_OPTION_DUMP_SUMMARY, |
| |
| /* If true, gcc_jit_context_compile will dump copious |
| amount of information on what it's doing to various |
| files within a temporary directory. Use |
| GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES (see below) to |
| see the results. The files are intended to be human-readable, |
| but the exact files and their formats are subject to change. |
| */ |
| GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, |
| |
| /* If true, libgccjit will aggressively run its garbage collector, to |
| shake out bugs (greatly slowing down the compile). This is likely |
| to only be of interest to developers *of* the library. It is |
| used when running the selftest suite. */ |
| GCC_JIT_BOOL_OPTION_SELFCHECK_GC, |
| |
| /* If true, gcc_jit_context_release will not clean up |
| intermediate files written to the filesystem, and will display |
| their location on stderr. */ |
| GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, |
| |
| GCC_JIT_NUM_BOOL_OPTIONS |
| }; |
| |
| /* Set a string option on the given context. |
| |
| The context takes a copy of the string, so the |
| (const char *) buffer is not needed anymore after the call |
| returns. */ |
| extern void |
| gcc_jit_context_set_str_option (gcc_jit_context *ctxt, |
| enum gcc_jit_str_option opt, |
| const char *value); |
| |
| /* Set an int option on the given context. */ |
| extern void |
| gcc_jit_context_set_int_option (gcc_jit_context *ctxt, |
| enum gcc_jit_int_option opt, |
| int value); |
| |
| /* Set a boolean option on the given context. |
| |
| Zero is "false" (the default), non-zero is "true". */ |
| extern void |
| gcc_jit_context_set_bool_option (gcc_jit_context *ctxt, |
| enum gcc_jit_bool_option opt, |
| int value); |
| |
| /* Options added after the initial release of libgccjit. |
| These are handled by providing an entrypoint per option, |
| rather than by extending the enum gcc_jit_*_option, |
| so that client code that use these new options can be identified |
| from binary metadata. */ |
| |
| /* By default, libgccjit will issue an error about unreachable blocks |
| within a function. |
| |
| This option can be used to disable that error. |
| |
| 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 |
| */ |
| |
| extern void |
| gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context *ctxt, |
| int bool_value); |
| |
| /* Pre-canned feature macro to indicate the presence of |
| gcc_jit_context_set_bool_allow_unreachable_blocks. This can be |
| tested for with #ifdef. */ |
| #define LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks |
| |
| /* By default, libgccjit will print errors to stderr. |
| |
| This option can be used to disable the printing. |
| |
| This entrypoint was added in LIBGCCJIT_ABI_23; you can test for |
| its presence using |
| #ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_print_errors_to_stderr |
| */ |
| |
| extern void |
| gcc_jit_context_set_bool_print_errors_to_stderr (gcc_jit_context *ctxt, |
| int enabled); |
| |
| /* Pre-canned feature macro to indicate the presence of |
| gcc_jit_context_set_bool_print_errors_to_stderr. This can be |
| tested for with #ifdef. */ |
| #define LIBGCCJIT_HAVE_gcc_jit_context_set_bool_print_errors_to_stderr |
| |
| /* Implementation detail: |
| 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. |
| |
| 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 |
| */ |
| |
| extern void |
| gcc_jit_context_set_bool_use_external_driver (gcc_jit_context *ctxt, |
| int bool_value); |
| |
| /* Pre-canned feature macro to indicate the presence of |
| gcc_jit_context_set_bool_use_external_driver. This can be |
| tested for with #ifdef. */ |
| #define LIBGCCJIT_HAVE_gcc_jit_context_set_bool_use_external_driver |
| |
| /* Add an arbitrary gcc command-line option to the context. |
| The context takes a copy of the string, so the |
| (const char *) optname is not needed anymore after the call |
| returns. |
| |
| Note that only some options are likely to be meaningful; there is no |
| "frontend" within libgccjit, so typically only those affecting |
| optimization and code-generation are likely to be useful. |
| |
| 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 |
| */ |
| |
| extern void |
| gcc_jit_context_add_command_line_option (gcc_jit_context *ctxt, |
| const char *optname); |
| |
| /* Pre-canned feature-test macro for detecting the presence of |
| gcc_jit_context_add_command_line_option within libgccjit.h. */ |
| |
| #define LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option |
| |
| /* Add an arbitrary gcc driver option to the context. |
| The context takes a copy of the string, so the |
| (const char *) optname is not needed anymore after the call |
| returns. |
| |
| Note that only some options are likely to be meaningful; there is no |
| "frontend" within libgccjit, so typically only those affecting |
| assembler and linker are likely to be useful. |
| |
| This entrypoint was added in LIBGCCJIT_ABI_11; you can test for |
| its presence using |
| #ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option |
| */ |
| extern void |
| gcc_jit_context_add_driver_option (gcc_jit_context *ctxt, |
| const char *optname); |
| |
| /* Pre-canned feature-test macro for detecting the presence of |
| gcc_jit_context_add_driver_option within libgccjit.h. */ |
| |
| #define LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option |
| |
| /* Compile the context to in-memory machine code. |
| |
| This can be called more that once on a given context, |
| although any errors that occur will block further compilation. */ |
| |
| extern gcc_jit_result * |
| gcc_jit_context_compile (gcc_jit_context *ctxt); |
| |
| /* Kinds of ahead-of-time compilation, for use with |
| gcc_jit_context_compile_to_file. */ |
| |
| enum gcc_jit_output_kind |
| { |
| /* Compile the context to an assembler file. */ |
| GCC_JIT_OUTPUT_KIND_ASSEMBLER, |
| |
| /* Compile the context to an object file. */ |
| GCC_JIT_OUTPUT_KIND_OBJECT_FILE, |
| |
| /* Compile the context to a dynamic library. */ |
| GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY, |
| |
| /* Compile the context to an executable. */ |
| GCC_JIT_OUTPUT_KIND_EXECUTABLE |
| }; |
| |
| /* Compile the context to a file of the given kind. |
| |
| This can be called more that once on a given context, |
| although any errors that occur will block further compilation. */ |
| |
| extern void |
| gcc_jit_context_compile_to_file (gcc_jit_context *ctxt, |
| enum gcc_jit_output_kind output_kind, |
| const char *output_path); |
| |
| /* 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 gcc_jit_location |
| information throughout the context, pointing at the dump file as if it |
| were a source file. This may be of use in conjunction with |
| GCC_JIT_BOOL_OPTION_DEBUGINFO to allow stepping through the code in a |
| debugger. */ |
| extern void |
| gcc_jit_context_dump_to_file (gcc_jit_context *ctxt, |
| const char *path, |
| int update_locations); |
| |
| /* To help with debugging; enable ongoing logging of the context's |
| activity to the given FILE *. |
| |
| The caller remains responsible for closing "logfile". |
| |
| Params "flags" and "verbosity" are reserved for future use, and |
| must both be 0 for now. */ |
| extern void |
| gcc_jit_context_set_logfile (gcc_jit_context *ctxt, |
| FILE *logfile, |
| int flags, |
| int verbosity); |
| |
| /* To be called after any API call, this gives the first error message |
| that occurred on the context. |
| |
| The returned string is valid for the rest of the lifetime of the |
| context. |
| |
| If no errors occurred, this will be NULL. */ |
| extern const char * |
| gcc_jit_context_get_first_error (gcc_jit_context *ctxt); |
| |
| /* To be called after any API call, this gives the last error message |
| that occurred on the context. |
| |
| If no errors occurred, this will be NULL. |
| |
| If non-NULL, the returned string is only guaranteed to be valid until |
| the next call to libgccjit relating to this context. */ |
| extern const char * |
| gcc_jit_context_get_last_error (gcc_jit_context *ctxt); |
| |
| /* Locate a given function within the built machine code. |
| This will need to be cast to a function pointer of the |
| correct type before it can be called. */ |
| extern void * |
| gcc_jit_result_get_code (gcc_jit_result *result, |
| const char *funcname); |
| |
| /* Locate a given global within the built machine code. |
| It must have been created using GCC_JIT_GLOBAL_EXPORTED. |
| This is a ptr to the global, so e.g. for an int this is an int *. */ |
| extern void * |
| gcc_jit_result_get_global (gcc_jit_result *result, |
| const char *name); |
| |
| /* Once we're done with the code, this unloads the built .so file. |
| This cleans up the result; after calling this, it's no longer |
| valid to use the result. */ |
| extern void |
| gcc_jit_result_release (gcc_jit_result *result); |
| |
| |
| /********************************************************************** |
| Functions for creating "contextual" objects. |
| |
| All objects created by these functions share the lifetime of the context |
| they are created within, and are automatically cleaned up for you when |
| you call gcc_jit_context_release on the context. |
| |
| Note that this means you can't use references to them after you've |
| released their context. |
| |
| All (const char *) string arguments passed to these functions are |
| copied, so you don't need to keep them around. |
| |
| You create code by adding a sequence of statements to blocks. |
| **********************************************************************/ |
| |
| /********************************************************************** |
| The base class of "contextual" object. |
| **********************************************************************/ |
| /* Which context is "obj" within? */ |
| extern gcc_jit_context * |
| gcc_jit_object_get_context (gcc_jit_object *obj); |
| |
| /* Get a human-readable description of this object. |
| The string buffer is created the first time this is called on a given |
| object, and persists until the object's context is released. */ |
| extern const char * |
| gcc_jit_object_get_debug_string (gcc_jit_object *obj); |
| |
| /********************************************************************** |
| Debugging information. |
| **********************************************************************/ |
| |
| /* Creating source code locations for use by the debugger. |
| Line and column numbers are 1-based. */ |
| extern gcc_jit_location * |
| gcc_jit_context_new_location (gcc_jit_context *ctxt, |
| const char *filename, |
| int line, |
| int column); |
| |
| /* Upcasting from location to object. */ |
| extern gcc_jit_object * |
| gcc_jit_location_as_object (gcc_jit_location *loc); |
| |
| |
| /********************************************************************** |
| Types. |
| **********************************************************************/ |
| |
| /* Upcasting from type to object. */ |
| extern gcc_jit_object * |
| gcc_jit_type_as_object (gcc_jit_type *type); |
| |
| /* Access to specific types. */ |
| enum gcc_jit_types |
| { |
| /* C's "void" type. */ |
| GCC_JIT_TYPE_VOID, |
| |
| /* "void *". */ |
| GCC_JIT_TYPE_VOID_PTR, |
| |
| /* C++'s bool type; also C99's "_Bool" type, aka "bool" if using |
| stdbool.h. */ |
| GCC_JIT_TYPE_BOOL, |
| |
| /* Various integer types. */ |
| |
| /* C's "char" (of some signedness) and the variants where the |
| signedness is specified. */ |
| GCC_JIT_TYPE_CHAR, |
| GCC_JIT_TYPE_SIGNED_CHAR, |
| GCC_JIT_TYPE_UNSIGNED_CHAR, |
| |
| /* C's "short" and "unsigned short". */ |
| GCC_JIT_TYPE_SHORT, /* signed */ |
| GCC_JIT_TYPE_UNSIGNED_SHORT, |
| |
| /* C's "int" and "unsigned int". */ |
| GCC_JIT_TYPE_INT, /* signed */ |
| GCC_JIT_TYPE_UNSIGNED_INT, |
| |
| /* C's "long" and "unsigned long". */ |
| GCC_JIT_TYPE_LONG, /* signed */ |
| GCC_JIT_TYPE_UNSIGNED_LONG, |
| |
| /* C99's "long long" and "unsigned long long". */ |
| GCC_JIT_TYPE_LONG_LONG, /* signed */ |
| GCC_JIT_TYPE_UNSIGNED_LONG_LONG, |
| |
| /* Floating-point types */ |
| |
| GCC_JIT_TYPE_FLOAT, |
| GCC_JIT_TYPE_DOUBLE, |
| GCC_JIT_TYPE_LONG_DOUBLE, |
| |
| /* C type: (const char *). */ |
| GCC_JIT_TYPE_CONST_CHAR_PTR, |
| |
| /* The C "size_t" type. */ |
| GCC_JIT_TYPE_SIZE_T, |
| |
| /* C type: (FILE *) */ |
| GCC_JIT_TYPE_FILE_PTR, |
| |
| /* Complex numbers. */ |
| GCC_JIT_TYPE_COMPLEX_FLOAT, |
| GCC_JIT_TYPE_COMPLEX_DOUBLE, |
| GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE, |
| |
| /* Sized integer types. */ |
| GCC_JIT_TYPE_UINT8_T, |
| GCC_JIT_TYPE_UINT16_T, |
| GCC_JIT_TYPE_UINT32_T, |
| GCC_JIT_TYPE_UINT64_T, |
| GCC_JIT_TYPE_UINT128_T, |
| GCC_JIT_TYPE_INT8_T, |
| GCC_JIT_TYPE_INT16_T, |
| GCC_JIT_TYPE_INT32_T, |
| GCC_JIT_TYPE_INT64_T, |
| GCC_JIT_TYPE_INT128_T |
| }; |
| |
| extern gcc_jit_type * |
| gcc_jit_context_get_type (gcc_jit_context *ctxt, |
| enum gcc_jit_types type_); |
| |
| /* Get the integer type of the given size and signedness. */ |
| extern gcc_jit_type * |
| gcc_jit_context_get_int_type (gcc_jit_context *ctxt, |
| int num_bytes, int is_signed); |
| |
| /* Constructing new types. */ |
| |
| /* Given type "T", get type "T*". */ |
| extern gcc_jit_type * |
| gcc_jit_type_get_pointer (gcc_jit_type *type); |
| |
| /* Given type "T", get type "const T". */ |
| extern gcc_jit_type * |
| gcc_jit_type_get_const (gcc_jit_type *type); |
| |
| /* Given type "T", get type "volatile T". */ |
| extern gcc_jit_type * |
| gcc_jit_type_get_volatile (gcc_jit_type *type); |
| |
| #define LIBGCCJIT_HAVE_SIZED_INTEGERS |
| |
| /* Given types LTYPE and RTYPE, return non-zero if they are compatible. |
| This API entrypoint was added in LIBGCCJIT_ABI_20; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_SIZED_INTEGERS */ |
| extern int |
| gcc_jit_compatible_types (gcc_jit_type *ltype, |
| gcc_jit_type *rtype); |
| |
| /* Given type "T", get its size. |
| This API entrypoint was added in LIBGCCJIT_ABI_20; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_SIZED_INTEGERS */ |
| extern ssize_t |
| gcc_jit_type_get_size (gcc_jit_type *type); |
| |
| /* Given type "T", get type "T[N]" (for a constant N). */ |
| extern gcc_jit_type * |
| gcc_jit_context_new_array_type (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| gcc_jit_type *element_type, |
| int num_elements); |
| |
| /* Struct-handling. */ |
| |
| /* Create a field, for use within a struct or union. */ |
| extern gcc_jit_field * |
| gcc_jit_context_new_field (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| gcc_jit_type *type, |
| const char *name); |
| |
| #define LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield |
| |
| /* Create a bit field, for use within a struct or union. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_12; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield |
| */ |
| extern gcc_jit_field * |
| gcc_jit_context_new_bitfield (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| gcc_jit_type *type, |
| int width, |
| const char *name); |
| |
| /* Upcasting from field to object. */ |
| extern gcc_jit_object * |
| gcc_jit_field_as_object (gcc_jit_field *field); |
| |
| /* Create a struct type from an array of fields. */ |
| extern gcc_jit_struct * |
| gcc_jit_context_new_struct_type (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| const char *name, |
| int num_fields, |
| gcc_jit_field **fields); |
| |
| /* Create an opaque struct type. */ |
| extern gcc_jit_struct * |
| gcc_jit_context_new_opaque_struct (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| const char *name); |
| |
| /* Upcast a struct to a type. */ |
| extern gcc_jit_type * |
| gcc_jit_struct_as_type (gcc_jit_struct *struct_type); |
| |
| /* Populating the fields of a formerly-opaque struct type. |
| This can only be called once on a given struct type. */ |
| extern void |
| gcc_jit_struct_set_fields (gcc_jit_struct *struct_type, |
| gcc_jit_location *loc, |
| int num_fields, |
| gcc_jit_field **fields); |
| |
| /* Get a field by index. */ |
| extern gcc_jit_field * |
| gcc_jit_struct_get_field (gcc_jit_struct *struct_type, |
| size_t index); |
| |
| /* Get the number of fields. */ |
| extern size_t |
| gcc_jit_struct_get_field_count (gcc_jit_struct *struct_type); |
| |
| /* Unions work similarly to structs. */ |
| extern gcc_jit_type * |
| gcc_jit_context_new_union_type (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| const char *name, |
| int num_fields, |
| gcc_jit_field **fields); |
| |
| /* Function pointers. */ |
| |
| extern gcc_jit_type * |
| gcc_jit_context_new_function_ptr_type (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| gcc_jit_type *return_type, |
| int num_params, |
| gcc_jit_type **param_types, |
| int is_variadic); |
| |
| /********************************************************************** |
| Constructing functions. |
| **********************************************************************/ |
| /* Create a function param. */ |
| extern gcc_jit_param * |
| gcc_jit_context_new_param (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| gcc_jit_type *type, |
| const char *name); |
| |
| /* Upcasting from param to object. */ |
| extern gcc_jit_object * |
| gcc_jit_param_as_object (gcc_jit_param *param); |
| |
| /* Upcasting from param to lvalue. */ |
| extern gcc_jit_lvalue * |
| gcc_jit_param_as_lvalue (gcc_jit_param *param); |
| |
| /* Upcasting from param to rvalue. */ |
| extern gcc_jit_rvalue * |
| gcc_jit_param_as_rvalue (gcc_jit_param *param); |
| |
| /* Kinds of function. */ |
| enum gcc_jit_function_kind |
| { |
| /* Function is defined by the client code and visible |
| by name outside of the JIT. */ |
| GCC_JIT_FUNCTION_EXPORTED, |
| |
| /* Function is defined by the client code, but is invisible |
| outside of the JIT. Analogous to a "static" function. */ |
| GCC_JIT_FUNCTION_INTERNAL, |
| |
| /* Function is not defined by the client code; we're merely |
| referring to it. Analogous to using an "extern" function from a |
| header file. */ |
| GCC_JIT_FUNCTION_IMPORTED, |
| |
| /* Function is only ever inlined into other functions, and is |
| invisible outside of the JIT. |
| |
| Analogous to prefixing with "inline" and adding |
| __attribute__((always_inline)). |
| |
| Inlining will only occur when the optimization level is |
| above 0; when optimization is off, this is essentially the |
| same as GCC_JIT_FUNCTION_INTERNAL. */ |
| GCC_JIT_FUNCTION_ALWAYS_INLINE |
| }; |
| |
| /* Thread local storage model. */ |
| enum gcc_jit_tls_model |
| { |
| GCC_JIT_TLS_MODEL_NONE, |
| GCC_JIT_TLS_MODEL_GLOBAL_DYNAMIC, |
| GCC_JIT_TLS_MODEL_LOCAL_DYNAMIC, |
| GCC_JIT_TLS_MODEL_INITIAL_EXEC, |
| GCC_JIT_TLS_MODEL_LOCAL_EXEC, |
| }; |
| |
| /* Create a function. */ |
| extern gcc_jit_function * |
| gcc_jit_context_new_function (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| enum gcc_jit_function_kind kind, |
| gcc_jit_type *return_type, |
| const char *name, |
| int num_params, |
| gcc_jit_param **params, |
| int is_variadic); |
| |
| /* Create a reference to a builtin function (sometimes called |
| intrinsic functions). */ |
| extern gcc_jit_function * |
| gcc_jit_context_get_builtin_function (gcc_jit_context *ctxt, |
| const char *name); |
| |
| /* Upcasting from function to object. */ |
| extern gcc_jit_object * |
| gcc_jit_function_as_object (gcc_jit_function *func); |
| |
| /* Get a specific param of a function by index. */ |
| extern gcc_jit_param * |
| gcc_jit_function_get_param (gcc_jit_function *func, int index); |
| |
| /* Emit the function in graphviz format. */ |
| extern void |
| gcc_jit_function_dump_to_dot (gcc_jit_function *func, |
| const char *path); |
| |
| /* Create a block. |
| |
| The name can be NULL, or you can give it a meaningful name, which |
| may show up in dumps of the internal representation, and in error |
| messages. */ |
| extern gcc_jit_block * |
| gcc_jit_function_new_block (gcc_jit_function *func, |
| const char *name); |
| |
| /* Upcasting from block to object. */ |
| extern gcc_jit_object * |
| gcc_jit_block_as_object (gcc_jit_block *block); |
| |
| /* Which function is this block within? */ |
| extern gcc_jit_function * |
| gcc_jit_block_get_function (gcc_jit_block *block); |
| |
| /********************************************************************** |
| lvalues, rvalues and expressions. |
| **********************************************************************/ |
| enum gcc_jit_global_kind |
| { |
| /* Global is defined by the client code and visible |
| by name outside of this JIT context via gcc_jit_result_get_global. */ |
| GCC_JIT_GLOBAL_EXPORTED, |
| |
| /* Global is defined by the client code, but is invisible |
| outside of this JIT context. Analogous to a "static" global. */ |
| GCC_JIT_GLOBAL_INTERNAL, |
| |
| /* Global is not defined by the client code; we're merely |
| referring to it. Analogous to using an "extern" global from a |
| header file. */ |
| GCC_JIT_GLOBAL_IMPORTED |
| }; |
| |
| extern gcc_jit_lvalue * |
| gcc_jit_context_new_global (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| enum gcc_jit_global_kind kind, |
| gcc_jit_type *type, |
| const char *name); |
| |
| #define LIBGCCJIT_HAVE_CTORS |
| |
| /* Create a constructor for a struct as an rvalue. |
| |
| Returns NULL on error. The two parameter arrays are copied and |
| do not have to outlive the context. |
| |
| `type` specifies what the constructor will build and has to be |
| a struct. |
| |
| `num_values` specifies the number of elements in `values`. |
| |
| `fields` need to have the same length as `values`, or be NULL. |
| |
| If `fields` is null, the values are applied in definition order. |
| |
| Otherwise, each field in `fields` specifies which field in the struct to |
| set to the corresponding value in `values`. `fields` and `values` |
| are paired by index. |
| |
| Each value has to have the same unqualified type as the field |
| it is applied to. |
| |
| A NULL value element in `values` is a shorthand for zero initialization |
| of the corresponding field. |
| |
| The fields in `fields` have to be in definition order, but there |
| can be gaps. Any field in the struct that is not specified in |
| `fields` will be zeroed. |
| |
| The fields in `fields` need to be the same objects that were used |
| to create the struct. |
| |
| If `num_values` is 0, the array parameters will be |
| ignored and zero initialization will be used. |
| |
| The constructor rvalue can be used for assignment to locals. |
| It can be used to initialize global variables with |
| gcc_jit_global_set_initializer_rvalue. It can also be used as a |
| temporary value for function calls and return values. |
| |
| The constructor can contain nested constructors. |
| |
| This entrypoint was added in LIBGCCJIT_ABI_19; you can test for its |
| presence using: |
| #ifdef LIBGCCJIT_HAVE_CTORS |
| */ |
| |
| extern gcc_jit_rvalue * |
| gcc_jit_context_new_struct_constructor (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| gcc_jit_type *type, |
| size_t num_values, |
| gcc_jit_field **fields, |
| gcc_jit_rvalue **values); |
| |
| /* Create a constructor for a union as an rvalue. |
| |
| Returns NULL on error. |
| |
| `type` specifies what the constructor will build and has to be |
| an union. |
| |
| `field` specifies which field to set. If it is NULL, the first |
| field in the union will be set. `field` need to be the same |
| object that were used to create the union. |
| |
| `value` specifies what value to set the corresponding field to. |
| If `value` is NULL, zero initialization will be used. |
| |
| Each value has to have the same unqualified type as the field |
| it is applied to. |
| |
| `field` need to be the same objects that were used |
| to create the union. |
| |
| The constructor rvalue can be used for assignment to locals. |
| It can be used to initialize global variables with |
| gcc_jit_global_set_initializer_rvalue. It can also be used as a |
| temporary value for function calls and return values. |
| |
| The constructor can contain nested constructors. |
| |
| This entrypoint was added in LIBGCCJIT_ABI_19; you can test for its |
| presence using: |
| #ifdef LIBGCCJIT_HAVE_CTORS |
| */ |
| |
| extern gcc_jit_rvalue * |
| gcc_jit_context_new_union_constructor (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| gcc_jit_type *type, |
| gcc_jit_field *field, |
| gcc_jit_rvalue *value); |
| |
| /* Create a constructor for an array as an rvalue. |
| |
| Returns NULL on error. `values` are copied and |
| do not have to outlive the context. |
| |
| `type` specifies what the constructor will build and has to be |
| an array. |
| |
| `num_values` specifies the number of elements in `values` and |
| it can't have more elements than the array type. |
| |
| Each value in `values` sets the corresponding value in the array. |
| If the array type itself has more elements than `values`, the |
| left-over elements will be zeroed. |
| |
| Each value in `values` need to be the same unqualified type as the |
| array type's element type. |
| |
| If `num_values` is 0, the `values` parameter will be |
| ignored and zero initialization will be used. |
| |
| Note that a string literal rvalue can't be used to construct a char |
| array. It needs one rvalue for each char. |
| |
| This entrypoint was added in LIBGCCJIT_ABI_19; you can test for its |
| presence using: |
| #ifdef LIBGCCJIT_HAVE_CTORS |
| */ |
| |
| extern gcc_jit_rvalue * |
| gcc_jit_context_new_array_constructor (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| gcc_jit_type *type, |
| size_t num_values, |
| gcc_jit_rvalue **values); |
| |
| /* Set the initial value of a global of any type with an rvalue. |
| |
| The rvalue needs to be a constant expression, e.g. no function calls. |
| |
| The global can't have the 'kind' GCC_JIT_GLOBAL_IMPORTED. |
| |
| Use together with gcc_jit_context_new_constructor () to |
| initialize structs, unions and arrays. |
| |
| On success, returns the 'global' parameter unchanged. Otherwise, NULL. |
| |
| 'values' is copied and does not have to outlive the context. |
| |
| This entrypoint was added in LIBGCCJIT_ABI_19; you can test for its |
| presence using: |
| #ifdef LIBGCCJIT_HAVE_CTORS |
| */ |
| |
| extern gcc_jit_lvalue * |
| gcc_jit_global_set_initializer_rvalue (gcc_jit_lvalue *global, |
| gcc_jit_rvalue *init_value); |
| |
| #define LIBGCCJIT_HAVE_gcc_jit_global_set_initializer |
| |
| /* Set an initial value for a global, which must be an array of |
| integral type. Return the global itself. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_14; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_gcc_jit_global_set_initializer |
| */ |
| |
| extern gcc_jit_lvalue * |
| gcc_jit_global_set_initializer (gcc_jit_lvalue *global, |
| const void *blob, |
| size_t num_bytes); |
| |
| /* Upcasting. */ |
| extern gcc_jit_object * |
| gcc_jit_lvalue_as_object (gcc_jit_lvalue *lvalue); |
| |
| extern gcc_jit_rvalue * |
| gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue *lvalue); |
| |
| extern gcc_jit_object * |
| gcc_jit_rvalue_as_object (gcc_jit_rvalue *rvalue); |
| |
| extern gcc_jit_type * |
| gcc_jit_rvalue_get_type (gcc_jit_rvalue *rvalue); |
| |
| /* Integer constants. */ |
| extern gcc_jit_rvalue * |
| gcc_jit_context_new_rvalue_from_int (gcc_jit_context *ctxt, |
| gcc_jit_type *numeric_type, |
| int value); |
| |
| extern gcc_jit_rvalue * |
| gcc_jit_context_new_rvalue_from_long (gcc_jit_context *ctxt, |
| gcc_jit_type *numeric_type, |
| long value); |
| |
| extern gcc_jit_rvalue * |
| gcc_jit_context_zero (gcc_jit_context *ctxt, |
| gcc_jit_type *numeric_type); |
| |
| extern gcc_jit_rvalue * |
| gcc_jit_context_one (gcc_jit_context *ctxt, |
| gcc_jit_type *numeric_type); |
| |
| /* Floating-point constants. */ |
| extern gcc_jit_rvalue * |
| gcc_jit_context_new_rvalue_from_double (gcc_jit_context *ctxt, |
| gcc_jit_type *numeric_type, |
| double value); |
| |
| /* Pointers. */ |
| extern gcc_jit_rvalue * |
| gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context *ctxt, |
| gcc_jit_type *pointer_type, |
| void *value); |
| |
| extern gcc_jit_rvalue * |
| gcc_jit_context_null (gcc_jit_context *ctxt, |
| gcc_jit_type *pointer_type); |
| |
| /* String literals. */ |
| extern gcc_jit_rvalue * |
| gcc_jit_context_new_string_literal (gcc_jit_context *ctxt, |
| const char *value); |
| |
| enum gcc_jit_unary_op |
| { |
| /* Negate an arithmetic value; analogous to: |
| -(EXPR) |
| in C. */ |
| GCC_JIT_UNARY_OP_MINUS, |
| |
| /* Bitwise negation of an integer value (one's complement); analogous |
| to: |
| ~(EXPR) |
| in C. */ |
| GCC_JIT_UNARY_OP_BITWISE_NEGATE, |
| |
| /* Logical negation of an arithmetic or pointer value; analogous to: |
| !(EXPR) |
| in C. */ |
| GCC_JIT_UNARY_OP_LOGICAL_NEGATE, |
| |
| /* Absolute value of an arithmetic expression; analogous to: |
| abs (EXPR) |
| in C. */ |
| GCC_JIT_UNARY_OP_ABS |
| |
| }; |
| |
| extern gcc_jit_rvalue * |
| gcc_jit_context_new_unary_op (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| enum gcc_jit_unary_op op, |
| gcc_jit_type *result_type, |
| gcc_jit_rvalue *rvalue); |
| |
| enum gcc_jit_binary_op |
| { |
| /* Addition of arithmetic values; analogous to: |
| (EXPR_A) + (EXPR_B) |
| in C. |
| For pointer addition, use gcc_jit_context_new_array_access. */ |
| GCC_JIT_BINARY_OP_PLUS, |
| |
| /* Subtraction of arithmetic values; analogous to: |
| (EXPR_A) - (EXPR_B) |
| in C. */ |
| GCC_JIT_BINARY_OP_MINUS, |
| |
| /* Multiplication of a pair of arithmetic values; analogous to: |
| (EXPR_A) * (EXPR_B) |
| in C. */ |
| GCC_JIT_BINARY_OP_MULT, |
| |
| /* Quotient of division of arithmetic values; analogous to: |
| (EXPR_A) / (EXPR_B) |
| in C. |
| The result type affects the kind of division: if the result type is |
| integer-based, then the result is truncated towards zero, whereas |
| a floating-point result type indicates floating-point division. */ |
| GCC_JIT_BINARY_OP_DIVIDE, |
| |
| /* Remainder of division of arithmetic values; analogous to: |
| (EXPR_A) % (EXPR_B) |
| in C. */ |
| GCC_JIT_BINARY_OP_MODULO, |
| |
| /* Bitwise AND; analogous to: |
| (EXPR_A) & (EXPR_B) |
| in C. */ |
| GCC_JIT_BINARY_OP_BITWISE_AND, |
| |
| /* Bitwise exclusive OR; analogous to: |
| (EXPR_A) ^ (EXPR_B) |
| in C. */ |
| GCC_JIT_BINARY_OP_BITWISE_XOR, |
| |
| /* Bitwise inclusive OR; analogous to: |
| (EXPR_A) | (EXPR_B) |
| in C. */ |
| GCC_JIT_BINARY_OP_BITWISE_OR, |
| |
| /* Logical AND; analogous to: |
| (EXPR_A) && (EXPR_B) |
| in C. */ |
| GCC_JIT_BINARY_OP_LOGICAL_AND, |
| |
| /* Logical OR; analogous to: |
| (EXPR_A) || (EXPR_B) |
| in C. */ |
| GCC_JIT_BINARY_OP_LOGICAL_OR, |
| |
| /* Left shift; analogous to: |
| (EXPR_A) << (EXPR_B) |
| in C. */ |
| GCC_JIT_BINARY_OP_LSHIFT, |
| |
| /* Right shift; analogous to: |
| (EXPR_A) >> (EXPR_B) |
| in C. */ |
| GCC_JIT_BINARY_OP_RSHIFT |
| }; |
| |
| extern gcc_jit_rvalue * |
| gcc_jit_context_new_binary_op (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| enum gcc_jit_binary_op op, |
| gcc_jit_type *result_type, |
| gcc_jit_rvalue *a, gcc_jit_rvalue *b); |
| |
| /* (Comparisons are treated as separate from "binary_op" to save |
| you having to specify the result_type). */ |
| |
| enum gcc_jit_comparison |
| { |
| /* (EXPR_A) == (EXPR_B). */ |
| GCC_JIT_COMPARISON_EQ, |
| |
| /* (EXPR_A) != (EXPR_B). */ |
| GCC_JIT_COMPARISON_NE, |
| |
| /* (EXPR_A) < (EXPR_B). */ |
| GCC_JIT_COMPARISON_LT, |
| |
| /* (EXPR_A) <=(EXPR_B). */ |
| GCC_JIT_COMPARISON_LE, |
| |
| /* (EXPR_A) > (EXPR_B). */ |
| GCC_JIT_COMPARISON_GT, |
| |
| /* (EXPR_A) >= (EXPR_B). */ |
| GCC_JIT_COMPARISON_GE |
| }; |
| |
| extern gcc_jit_rvalue * |
| gcc_jit_context_new_comparison (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| enum gcc_jit_comparison op, |
| gcc_jit_rvalue *a, gcc_jit_rvalue *b); |
| |
| /* Function calls. */ |
| |
| /* Call of a specific function. */ |
| extern gcc_jit_rvalue * |
| gcc_jit_context_new_call (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| gcc_jit_function *func, |
| int numargs , gcc_jit_rvalue **args); |
| |
| /* Call through a function pointer. */ |
| extern gcc_jit_rvalue * |
| gcc_jit_context_new_call_through_ptr (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| gcc_jit_rvalue *fn_ptr, |
| int numargs, gcc_jit_rvalue **args); |
| |
| /* Type-coercion. |
| |
| Currently only a limited set of conversions are possible: |
| int <-> float |
| int <-> bool */ |
| extern gcc_jit_rvalue * |
| gcc_jit_context_new_cast (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| gcc_jit_rvalue *rvalue, |
| gcc_jit_type *type); |
| |
| #define LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast |
| |
| /* Reinterpret a value as another type. |
| |
| The types must be of the same size. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_21; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast */ |
| extern gcc_jit_rvalue * |
| gcc_jit_context_new_bitcast (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| gcc_jit_rvalue *rvalue, |
| gcc_jit_type *type); |
| |
| #define LIBGCCJIT_HAVE_ALIGNMENT |
| |
| /* Set the alignment of a variable. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_24; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_ALIGNMENT */ |
| extern void |
| gcc_jit_lvalue_set_alignment (gcc_jit_lvalue *lvalue, |
| unsigned bytes); |
| |
| /* Get the alignment of a variable. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_24; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_ALIGNMENT */ |
| extern unsigned |
| gcc_jit_lvalue_get_alignment (gcc_jit_lvalue *lvalue); |
| |
| extern gcc_jit_lvalue * |
| gcc_jit_context_new_array_access (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| gcc_jit_rvalue *ptr, |
| gcc_jit_rvalue *index); |
| |
| /* Field access is provided separately for both lvalues and rvalues. */ |
| |
| /* Accessing a field of an lvalue of struct type, analogous to: |
| (EXPR).field = ...; |
| in C. */ |
| extern gcc_jit_lvalue * |
| gcc_jit_lvalue_access_field (gcc_jit_lvalue *struct_or_union, |
| gcc_jit_location *loc, |
| gcc_jit_field *field); |
| |
| /* Accessing a field of an rvalue of struct type, analogous to: |
| (EXPR).field |
| in C. */ |
| extern gcc_jit_rvalue * |
| gcc_jit_rvalue_access_field (gcc_jit_rvalue *struct_or_union, |
| gcc_jit_location *loc, |
| gcc_jit_field *field); |
| |
| /* Accessing a field of an rvalue of pointer type, analogous to: |
| (EXPR)->field |
| in C, itself equivalent to (*EXPR).FIELD */ |
| extern gcc_jit_lvalue * |
| gcc_jit_rvalue_dereference_field (gcc_jit_rvalue *ptr, |
| gcc_jit_location *loc, |
| gcc_jit_field *field); |
| |
| /* Dereferencing a pointer; analogous to: |
| *(EXPR) |
| */ |
| extern gcc_jit_lvalue * |
| gcc_jit_rvalue_dereference (gcc_jit_rvalue *rvalue, |
| gcc_jit_location *loc); |
| |
| /* Taking the address of an lvalue; analogous to: |
| &(EXPR) |
| in C. */ |
| extern gcc_jit_rvalue * |
| gcc_jit_lvalue_get_address (gcc_jit_lvalue *lvalue, |
| gcc_jit_location *loc); |
| |
| #define LIBGCCJIT_HAVE_gcc_jit_lvalue_set_tls_model |
| |
| /* Set the thread-local storage model of a global variable |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_17; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_tls_model */ |
| extern void |
| gcc_jit_lvalue_set_tls_model (gcc_jit_lvalue *lvalue, |
| enum gcc_jit_tls_model model); |
| |
| #define LIBGCCJIT_HAVE_gcc_jit_lvalue_set_link_section |
| |
| /* Set the link section of a global variable; analogous to: |
| __attribute__((section(".section_name"))) |
| in C. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_18; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_link_section |
| */ |
| extern void |
| gcc_jit_lvalue_set_link_section (gcc_jit_lvalue *lvalue, |
| const char *section_name); |
| |
| #define LIBGCCJIT_HAVE_gcc_jit_lvalue_set_register_name |
| |
| /* Make this variable a register variable and set its register name. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_22; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_register_name |
| */ |
| void |
| gcc_jit_lvalue_set_register_name (gcc_jit_lvalue *lvalue, |
| const char *reg_name); |
| |
| extern gcc_jit_lvalue * |
| gcc_jit_function_new_local (gcc_jit_function *func, |
| gcc_jit_location *loc, |
| gcc_jit_type *type, |
| const char *name); |
| |
| /********************************************************************** |
| Statement-creation. |
| **********************************************************************/ |
| |
| /* Add evaluation of an rvalue, discarding the result |
| (e.g. a function call that "returns" void). |
| |
| This is equivalent to this C code: |
| |
| (void)expression; |
| */ |
| extern void |
| gcc_jit_block_add_eval (gcc_jit_block *block, |
| gcc_jit_location *loc, |
| gcc_jit_rvalue *rvalue); |
| |
| /* Add evaluation of an rvalue, assigning the result to the given |
| lvalue. |
| |
| This is roughly equivalent to this C code: |
| |
| lvalue = rvalue; |
| */ |
| extern void |
| gcc_jit_block_add_assignment (gcc_jit_block *block, |
| gcc_jit_location *loc, |
| gcc_jit_lvalue *lvalue, |
| gcc_jit_rvalue *rvalue); |
| |
| /* Add evaluation of an rvalue, using the result to modify an |
| lvalue. |
| |
| This is analogous to "+=" and friends: |
| |
| lvalue += rvalue; |
| lvalue *= rvalue; |
| lvalue /= rvalue; |
| etc */ |
| extern void |
| gcc_jit_block_add_assignment_op (gcc_jit_block *block, |
| gcc_jit_location *loc, |
| gcc_jit_lvalue *lvalue, |
| enum gcc_jit_binary_op op, |
| gcc_jit_rvalue *rvalue); |
| |
| /* Add a no-op textual comment to the internal representation of the |
| code. It will be optimized away, but will be visible in the dumps |
| seen via |
| GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE |
| and |
| GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, |
| and thus may be of use when debugging how your project's internal |
| representation gets converted to the libgccjit IR. */ |
| extern void |
| gcc_jit_block_add_comment (gcc_jit_block *block, |
| gcc_jit_location *loc, |
| const char *text); |
| |
| /* Terminate a block by adding evaluation of an rvalue, branching on the |
| result to the appropriate successor block. |
| |
| This is roughly equivalent to this C code: |
| |
| if (boolval) |
| goto on_true; |
| else |
| goto on_false; |
| |
| block, boolval, on_true, and on_false must be non-NULL. */ |
| extern void |
| gcc_jit_block_end_with_conditional (gcc_jit_block *block, |
| gcc_jit_location *loc, |
| gcc_jit_rvalue *boolval, |
| gcc_jit_block *on_true, |
| gcc_jit_block *on_false); |
| |
| /* Terminate a block by adding a jump to the given target block. |
| |
| This is roughly equivalent to this C code: |
| |
| goto target; |
| */ |
| extern void |
| gcc_jit_block_end_with_jump (gcc_jit_block *block, |
| gcc_jit_location *loc, |
| gcc_jit_block *target); |
| |
| /* Terminate a block by adding evaluation of an rvalue, returning the value. |
| |
| This is roughly equivalent to this C code: |
| |
| return expression; |
| */ |
| extern void |
| gcc_jit_block_end_with_return (gcc_jit_block *block, |
| gcc_jit_location *loc, |
| gcc_jit_rvalue *rvalue); |
| |
| /* Terminate a block by adding a valueless return, for use within a function |
| with "void" return type. |
| |
| This is equivalent to this C code: |
| |
| return; |
| */ |
| extern void |
| gcc_jit_block_end_with_void_return (gcc_jit_block *block, |
| gcc_jit_location *loc); |
| |
| /* Create a new gcc_jit_case instance for use in a switch statement. |
| min_value and max_value must be constants of integer type. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_3; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS |
| */ |
| extern gcc_jit_case * |
| gcc_jit_context_new_case (gcc_jit_context *ctxt, |
| gcc_jit_rvalue *min_value, |
| gcc_jit_rvalue *max_value, |
| gcc_jit_block *dest_block); |
| |
| /* Upcasting from case to object. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_3; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS |
| */ |
| |
| extern gcc_jit_object * |
| gcc_jit_case_as_object (gcc_jit_case *case_); |
| |
| /* Terminate a block by adding evalation of an rvalue, then performing |
| a multiway branch. |
| |
| This is roughly equivalent to this C code: |
| |
| switch (expr) |
| { |
| default: |
| goto default_block; |
| |
| case C0.min_value ... C0.max_value: |
| goto C0.dest_block; |
| |
| case C1.min_value ... C1.max_value: |
| goto C1.dest_block; |
| |
| ...etc... |
| |
| case C[N - 1].min_value ... C[N - 1].max_value: |
| goto C[N - 1].dest_block; |
| } |
| |
| block, expr, default_block and cases must all be non-NULL. |
| |
| expr must be of the same integer type as all of the min_value |
| and max_value within the cases. |
| |
| num_cases must be >= 0. |
| |
| The ranges of the cases must not overlap (or have duplicate |
| values). |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_3; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS |
| */ |
| |
| extern void |
| gcc_jit_block_end_with_switch (gcc_jit_block *block, |
| gcc_jit_location *loc, |
| gcc_jit_rvalue *expr, |
| gcc_jit_block *default_block, |
| int num_cases, |
| gcc_jit_case **cases); |
| |
| /* Pre-canned feature macro to indicate the presence of |
| gcc_jit_block_end_with_switch, gcc_jit_case_as_object, and |
| gcc_jit_context_new_case. |
| |
| This can be tested for with #ifdef. */ |
| #define LIBGCCJIT_HAVE_SWITCH_STATEMENTS |
| |
| /********************************************************************** |
| Nested contexts. |
| **********************************************************************/ |
| |
| /* 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 gcc_jit_result of the parent context must |
| outlive the gcc_jit_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. */ |
| |
| extern gcc_jit_context * |
| gcc_jit_context_new_child_context (gcc_jit_context *parent_ctxt); |
| |
| /********************************************************************** |
| Implementation support. |
| **********************************************************************/ |
| |
| /* Write C source code into "path" that can be compiled into a |
| self-contained executable (i.e. with libgccjit as the only dependency). |
| The generated code will attempt to replay the API calls that have been |
| made into the given context. |
| |
| This may be useful when debugging the library or client code, for |
| reducing a complicated recipe for reproducing a bug into a simpler |
| form. |
| |
| Typically you need to supply the option "-Wno-unused-variable" when |
| compiling the generated file (since the result of each API call is |
| assigned to a unique variable within the generated C source, and not |
| all are necessarily then used). */ |
| |
| extern void |
| gcc_jit_context_dump_reproducer_to_file (gcc_jit_context *ctxt, |
| const char *path); |
| |
| /* Enable the dumping of a specific set of internal state from the |
| compilation, capturing the result in-memory as a buffer. |
| |
| Parameter "dumpname" corresponds to the equivalent gcc command-line |
| option, without the "-fdump-" prefix. |
| For example, to get the equivalent of "-fdump-tree-vrp1", supply |
| "tree-vrp1". |
| The context directly stores the dumpname as a (const char *), so the |
| passed string must outlive the context. |
| |
| gcc_jit_context_compile and gcc_jit_context_to_file |
| will capture the dump as a dynamically-allocated buffer, writing |
| it to ``*out_ptr``. |
| |
| The caller becomes responsible for calling |
| free (*out_ptr) |
| each time that gcc_jit_context_compile or gcc_jit_context_to_file |
| are called. *out_ptr will be written to, either with the address of a |
| buffer, or with NULL if an error occurred. |
| |
| This API entrypoint is likely to be less stable than the others. |
| In particular, both the precise dumpnames, and the format and content |
| of the dumps are subject to change. |
| |
| It exists primarily for writing the library's own test suite. */ |
| |
| extern void |
| gcc_jit_context_enable_dump (gcc_jit_context *ctxt, |
| const char *dumpname, |
| char **out_ptr); |
| |
| /********************************************************************** |
| Timing support. |
| **********************************************************************/ |
| |
| /* The timing API was added in LIBGCCJIT_ABI_4; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_TIMING_API |
| */ |
| #define LIBGCCJIT_HAVE_TIMING_API |
| |
| typedef struct gcc_jit_timer gcc_jit_timer; |
| |
| /* Create a gcc_jit_timer instance, and start timing. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_4; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_TIMING_API |
| */ |
| extern gcc_jit_timer * |
| gcc_jit_timer_new (void); |
| |
| /* Release a gcc_jit_timer instance. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_4; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_TIMING_API |
| */ |
| extern void |
| gcc_jit_timer_release (gcc_jit_timer *timer); |
| |
| /* Associate a gcc_jit_timer instance with a context. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_4; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_TIMING_API |
| */ |
| extern void |
| gcc_jit_context_set_timer (gcc_jit_context *ctxt, |
| gcc_jit_timer *timer); |
| |
| /* Get the timer associated with a context (if any). |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_4; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_TIMING_API |
| */ |
| |
| extern gcc_jit_timer * |
| gcc_jit_context_get_timer (gcc_jit_context *ctxt); |
| |
| /* Push the given item onto the timing stack. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_4; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_TIMING_API |
| */ |
| |
| extern void |
| gcc_jit_timer_push (gcc_jit_timer *timer, |
| const char *item_name); |
| |
| /* Pop the top item from the timing stack. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_4; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_TIMING_API |
| */ |
| |
| extern void |
| gcc_jit_timer_pop (gcc_jit_timer *timer, |
| const char *item_name); |
| |
| /* Print timing information to the given stream about activity since |
| the timer was started. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_4; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_TIMING_API |
| */ |
| |
| extern void |
| gcc_jit_timer_print (gcc_jit_timer *timer, |
| FILE *f_out); |
| |
| |
| #define LIBGCCJIT_HAVE_gcc_jit_rvalue_set_bool_require_tail_call |
| |
| /* Mark/clear a call as needing tail-call optimization. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_6; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_gcc_jit_rvalue_set_bool_require_tail_call |
| */ |
| extern void |
| gcc_jit_rvalue_set_bool_require_tail_call (gcc_jit_rvalue *call, |
| int require_tail_call); |
| |
| #define LIBGCCJIT_HAVE_gcc_jit_type_get_aligned |
| |
| /* Given type "T", get type: |
| |
| T __attribute__ ((aligned (ALIGNMENT_IN_BYTES))) |
| |
| The alignment must be a power of two. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_7; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_gcc_jit_type_get_aligned |
| */ |
| extern gcc_jit_type * |
| gcc_jit_type_get_aligned (gcc_jit_type *type, |
| size_t alignment_in_bytes); |
| |
| #define LIBGCCJIT_HAVE_gcc_jit_type_get_vector |
| |
| /* Given type "T", get type: |
| |
| T __attribute__ ((vector_size (sizeof(T) * num_units)) |
| |
| T must be integral/floating point; num_units must be a power of two. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_8; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_gcc_jit_type_get_vector |
| */ |
| extern gcc_jit_type * |
| gcc_jit_type_get_vector (gcc_jit_type *type, size_t num_units); |
| |
| |
| #define LIBGCCJIT_HAVE_gcc_jit_function_get_address |
| |
| /* Get the address of a function as an rvalue, of function pointer |
| type. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_9; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_gcc_jit_function_get_address |
| */ |
| extern gcc_jit_rvalue * |
| gcc_jit_function_get_address (gcc_jit_function *fn, |
| gcc_jit_location *loc); |
| |
| |
| #define LIBGCCJIT_HAVE_gcc_jit_context_new_rvalue_from_vector |
| |
| /* Build a vector rvalue from an array of elements. |
| |
| "vec_type" should be a vector type, created using gcc_jit_type_get_vector. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_10; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_rvalue_from_vector |
| */ |
| extern gcc_jit_rvalue * |
| gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| gcc_jit_type *vec_type, |
| size_t num_elements, |
| gcc_jit_rvalue **elements); |
| |
| #define LIBGCCJIT_HAVE_gcc_jit_version |
| |
| /* Functions to retrieve libgccjit version. |
| Analogous to __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__ in C code. |
| |
| These API entrypoints were added in LIBGCCJIT_ABI_13; you can test for their |
| presence using |
| #ifdef LIBGCCJIT_HAVE_gcc_jit_version |
| */ |
| extern int |
| gcc_jit_version_major (void); |
| extern int |
| gcc_jit_version_minor (void); |
| extern int |
| gcc_jit_version_patchlevel (void); |
| |
| /********************************************************************** |
| Asm support. |
| **********************************************************************/ |
| |
| /* Functions for adding inline assembler code, analogous to GCC's |
| "extended asm" syntax. |
| |
| See https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html |
| |
| These API entrypoints were added in LIBGCCJIT_ABI_15; you can test for their |
| presence using |
| #ifdef LIBGCCJIT_HAVE_ASM_STATEMENTS |
| */ |
| |
| #define LIBGCCJIT_HAVE_ASM_STATEMENTS |
| |
| /* Create a gcc_jit_extended_asm for an extended asm statement |
| with no control flow (i.e. without the goto qualifier). |
| |
| The asm_template parameter corresponds to the AssemblerTemplate |
| within C's extended asm syntax. It must be non-NULL. */ |
| |
| extern gcc_jit_extended_asm * |
| gcc_jit_block_add_extended_asm (gcc_jit_block *block, |
| gcc_jit_location *loc, |
| const char *asm_template); |
| |
| /* Create a gcc_jit_extended_asm for an extended asm statement |
| that may perform jumps, and use it to terminate the given block. |
| This is equivalent to the "goto" qualifier in C's extended asm |
| syntax. */ |
| |
| extern gcc_jit_extended_asm * |
| gcc_jit_block_end_with_extended_asm_goto (gcc_jit_block *block, |
| gcc_jit_location *loc, |
| const char *asm_template, |
| int num_goto_blocks, |
| gcc_jit_block **goto_blocks, |
| gcc_jit_block *fallthrough_block); |
| |
| /* Upcasting from extended asm to object. */ |
| |
| extern gcc_jit_object * |
| gcc_jit_extended_asm_as_object (gcc_jit_extended_asm *ext_asm); |
| |
| /* Set whether the gcc_jit_extended_asm has side-effects, equivalent to |
| the "volatile" qualifier in C's extended asm syntax. */ |
| |
| extern void |
| gcc_jit_extended_asm_set_volatile_flag (gcc_jit_extended_asm *ext_asm, |
| int flag); |
| |
| /* Set the equivalent of the "inline" qualifier in C's extended asm |
| syntax. */ |
| |
| extern void |
| gcc_jit_extended_asm_set_inline_flag (gcc_jit_extended_asm *ext_asm, |
| int flag); |
| |
| /* Add an output operand to the extended asm statement. |
| "asm_symbolic_name" can be NULL. |
| "constraint" and "dest" must be non-NULL. |
| This function can't be called on an "asm goto" as such instructions |
| can't have outputs */ |
| |
| extern void |
| gcc_jit_extended_asm_add_output_operand (gcc_jit_extended_asm *ext_asm, |
| const char *asm_symbolic_name, |
| const char *constraint, |
| gcc_jit_lvalue *dest); |
| |
| /* Add an input operand to the extended asm statement. |
| "asm_symbolic_name" can be NULL. |
| "constraint" and "src" must be non-NULL. */ |
| |
| extern void |
| gcc_jit_extended_asm_add_input_operand (gcc_jit_extended_asm *ext_asm, |
| const char *asm_symbolic_name, |
| const char *constraint, |
| gcc_jit_rvalue *src); |
| |
| /* Add "victim" to the list of registers clobbered by the extended |
| asm statement. It must be non-NULL. */ |
| |
| extern void |
| gcc_jit_extended_asm_add_clobber (gcc_jit_extended_asm *ext_asm, |
| const char *victim); |
| |
| /* Add "asm_stmts", a set of top-level asm statements, analogous to |
| those created by GCC's "basic" asm syntax in C at file scope. */ |
| |
| extern void |
| gcc_jit_context_add_top_level_asm (gcc_jit_context *ctxt, |
| gcc_jit_location *loc, |
| const char *asm_stmts); |
| |
| #define LIBGCCJIT_HAVE_REFLECTION |
| |
| /* Reflection functions to get the number of parameters, return type of |
| a function and whether a type is a bool from the C API. |
| |
| This API entrypoint was added in LIBGCCJIT_ABI_16; you can test for its |
| presence using |
| #ifdef LIBGCCJIT_HAVE_REFLECTION |
| */ |
| /* Get the return type of a function. */ |
| extern gcc_jit_type * |
| gcc_jit_function_get_return_type (gcc_jit_function *func); |
| |
| /* Get the number of params of a function. */ |
| extern size_t |
| gcc_jit_function_get_param_count (gcc_jit_function *func); |
| |
| /* Get the element type of an array type or NULL if it's not an array. */ |
| extern gcc_jit_type * |
| gcc_jit_type_dyncast_array (gcc_jit_type *type); |
| |
| /* Return non-zero if the type is a bool. */ |
| extern int |
| gcc_jit_type_is_bool (gcc_jit_type *type); |
| |
| /* Return the function type if it is one or NULL. */ |
| extern gcc_jit_function_type * |
| gcc_jit_type_dyncast_function_ptr_type (gcc_jit_type *type); |
| |
| /* Given a function type, return its return type. */ |
| extern gcc_jit_type * |
| gcc_jit_function_type_get_return_type (gcc_jit_function_type *function_type); |
| |
| /* Given a function type, return its number of parameters. */ |
| extern size_t |
| gcc_jit_function_type_get_param_count (gcc_jit_function_type *function_type); |
| |
| /* Given a function type, return the type of the specified parameter. */ |
| extern gcc_jit_type * |
| gcc_jit_function_type_get_param_type (gcc_jit_function_type *function_type, |
| size_t index); |
| |
| /* Return non-zero if the type is an integral. */ |
| extern int |
| gcc_jit_type_is_integral (gcc_jit_type *type); |
| |
| /* Return the type pointed by the pointer type or NULL if it's not a |
| * pointer. */ |
| extern gcc_jit_type * |
| gcc_jit_type_is_pointer (gcc_jit_type *type); |
| |
| /* Given a type, return a dynamic cast to a vector type or NULL. */ |
| extern gcc_jit_vector_type * |
| gcc_jit_type_dyncast_vector (gcc_jit_type *type); |
| |
| /* Given a type, return a dynamic cast to a struct type or NULL. */ |
| extern gcc_jit_struct * |
| gcc_jit_type_is_struct (gcc_jit_type *type); |
| |
| /* Given a vector type, return the number of units it contains. */ |
| extern size_t |
| gcc_jit_vector_type_get_num_units (gcc_jit_vector_type *vector_type); |
| |
| /* Given a vector type, return the type of its elements. */ |
| extern gcc_jit_type * |
| gcc_jit_vector_type_get_element_type (gcc_jit_vector_type *vector_type); |
| |
| /* Given a type, return the unqualified type, removing "const", "volatile" |
| * and alignment qualifiers. */ |
| extern gcc_jit_type * |
| gcc_jit_type_unqualified (gcc_jit_type *type); |
| |
| #ifdef __cplusplus |
| } |
| #endif /* __cplusplus */ |
| |
| #endif /* LIBGCCJIT_H */ |