A gcc_jit_param represents a parameter to a function.
In preparation for creating a function, create a new parameter of the given type and name.
The parameter name must be non-NULL. The call takes a copy of the underlying string, so it is valid to pass in a pointer to an on-stack buffer.
Parameters are lvalues, and thus are also rvalues (and objects), so the following upcasts are available:
Upcasting from param to lvalue.
Upcasting from param to rvalue.
Upcasting from param to object.
A gcc_jit_function represents a function - either one that we’re creating ourselves, or one that we’re referencing.
Create a gcc_jit_function with the given name and parameters.
This enum controls the kind of function created, and has the following values:
- GCC_JIT_FUNCTION_EXPORTED¶
Function is defined by the client code and visible by name outside of the JIT.
This value is required if you want to extract machine code for this function from a gcc_jit_result via gcc_jit_result_get_code().
- GCC_JIT_FUNCTION_INTERNAL¶
Function is defined by the client code, but is invisible outside of the JIT. Analogous to a “static” function.
- GCC_JIT_FUNCTION_IMPORTED¶
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_ALWAYS_INLINE¶
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.
The parameter name must be non-NULL. The call takes a copy of the underlying string, so it is valid to pass in a pointer to an on-stack buffer.
Upcasting from function to object.
Get the param of the given index (0-based).
Emit the function in graphviz format to the given path.
Create a new local variable within the function, of the given type and name.
The parameter name must be non-NULL. The call takes a copy of the underlying string, so it is valid to pass in a pointer to an on-stack buffer.
A gcc_jit_block represents a basic block within a function i.e. a sequence of statements with a single entry point and a single exit point.
The first basic block that you create within a function will be the entrypoint.
Each basic block that you create within a function must be terminated, either with a conditional, a jump, a return, or a switch.
It’s legal to have multiple basic blocks that return within one function.
Create a basic block of the given name. The name may be NULL, but providing meaningful names is often helpful when debugging: it may show up in dumps of the internal representation, and in error messages. It is copied, so the input buffer does not need to outlive the call; you can pass in a pointer to an on-stack buffer, e.g.:
for (pc = 0; pc < fn->fn_num_ops; pc++)
{
char buf[16];
sprintf (buf, "instr%i", pc);
state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf);
}
Upcast from block to object.
Which function is this block within?
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;
Add evaluation of an rvalue, assigning the result to the given lvalue.
This is roughly equivalent to this C code:
lvalue = 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. For example:
/* "i++" */
gcc_jit_block_add_assignment_op (
loop_body, NULL,
i,
GCC_JIT_BINARY_OP_PLUS,
gcc_jit_context_one (ctxt, int_type));
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.
The parameter text must be non-NULL. It is copied, so the input buffer does not need to outlive the call. For example:
char buf[100];
snprintf (buf, sizeof (buf),
"op%i: %s",
pc, opcode_names[op->op_opcode]);
gcc_jit_block_add_comment (block, loc, buf);
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.
Terminate a block by adding a jump to the given target block.
This is roughly equivalent to this C code:
goto target;
Terminate a block by adding evaluation of an rvalue, returning the value.
This is roughly equivalent to this C code:
return expression;
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;
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).
The API entrypoints relating to switch statements and cases:
were added in LIBGCCJIT_ABI_3; you can test for their presence using
#ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS
A gcc_jit_case represents a case within a switch statement, and is created within a particular gcc_jit_context using gcc_jit_context_new_case().
Each case expresses a multivalued range of integer values. You can express single-valued cases by passing in the same value for both min_value and max_value.
Create a new gcc_jit_case instance for use in a switch statement. min_value and max_value must be constants of an integer type, which must match that of the expression of the switch statement.
dest_block must be within the same function as the switch statement.
Upcast from a case to an object.
Here’s an example of creating a switch statement: