12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274 |
- /* A pure C API to enable client code to embed GCC as a JIT-compiler.
- Copyright (C) 2013-2015 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_field
- +- gcc_jit_function
- +- gcc_jit_block
- +- gcc_jit_rvalue
- +- gcc_jit_lvalue
- +- gcc_jit_param
- +- gcc_jit_case
- */
- 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 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;
- /* 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
- /* 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
- /* 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
- };
- 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);
- /* 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);
- /* 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);
- /* 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
- };
- /* 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);
- /* 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);
- 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);
- 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);
- #ifdef __cplusplus
- }
- #endif /* __cplusplus */
- #endif /* LIBGCCJIT_H */
|