Alien-LibJIT

 view release on metacpan or  search on metacpan

libjit/doc/libjit.texi  view on Meta::CPAN

@code{jit_function_set_on_demand_compiler} to set a new on-demand
compiler that performs greater levels of optimization.

If you no longer intend to recompile the function, you should call
@code{jit_function_clear_recompilable} so that @code{libjit} can
manage the function more efficiently from then on.

The exact conditions under which a function should be recompiled
are not specified by @code{libjit}.  It may be because the function
has been called several times and has reached some threshold.
Or it may be because some other function that it calls has become a
candidate for inlining.  It is up to the front end to decide when
recompilation is warranted, usually based on language-specific
heuristics.

@c -----------------------------------------------------------------------

@node Tutorial 4, Tutorial 5, Tutorial 3, Tutorials
@section Tutorial 4 - mul_add, C++ version
@cindex mul_add C++ tutorial

While @code{libjit} can be easily accessed from C++ programs using
the C API's, you may instead wish to use an API that better reflects
the C++ programming paradigm.  We demonstrate how to do this by rewriting
Tutorial 3 using the @code{libjitplus} library.

@noindent
To use the @code{libjitplus} library, we first include
the @code{<jit/jit-plus.h>} file:

@example
#include <jit/jit-plus.h>
@end example

This file incorporates all of the definitions from @code{<jit/jit.h>},
so you have full access to the underlying C API if you need it.

This time, instead of building the @code{mul_add} function with
@code{jit_function_create} and friends, we define a class to represent it:

@example
class mul_add_function : public jit_function
@{
public:
    mul_add_function(jit_context& context) : jit_function(context)
    @{
        create();
        set_recompilable();
    @}

    virtual void build();

protected:
    virtual jit_type_t create_signature();
@};
@end example

Where we used @code{jit_function_t} and @code{jit_context_t} before,
we now use the C++ @code{jit_function} and @code{jit_context} classes.

In our constructor, we attach ourselves to the context and then call
the @code{create()} method.  This is in turn will call our overridden
virtual method @code{create_signature()} to obtain the signature:

@example
jit_type_t mul_add_function::create_signature()
@{
    // Return type, followed by three parameters,
    // terminated with "end_params".
    return signature_helper
        (jit_type_int, jit_type_int, jit_type_int,
         jit_type_int, end_params);
@}
@end example

The @code{signature_helper()} method is provided for your convenience,
to help with building function signatures.  You can create your own
signature manually using @code{jit_type_create_signature} if you wish.

The final thing we do in the constructor is call @code{set_recompilable()}
to mark the @code{mul_add} function as recompilable, just as we did in
Tutorial 3.

The C++ library will create the function as compilable on-demand for
us, so we don't have to do that explicitly.  But we do have to override
the virtual @code{build()} method to build the function's body on-demand:

@example
void mul_add_function::build()
@{
    jit_value x = get_param(0);
    jit_value y = get_param(1);
    jit_value z = get_param(2);

    insn_return(x * y + z);
@}
@end example

This is similar to the first version that we wrote in Tutorial 1.
Instructions are created with @code{insn_*} methods that correspond
to their @code{jit_insn_*} counterparts in the C library.

One of the nice things about the C++ API compared to the C API is that we
can use overloaded operators to manipulate @code{jit_value} objects.
This can simplify the function build process considerably when we
have lots of expressions to compile.  We could have used @code{insn_mul}
and @code{insn_add} instead in this example and the result would have
been the same.

Now that we have our @code{mul_add_function} class, we can create
an instance of the function and apply it as follows:

@example
jit_context context;
mul_add_function mul_add(context);

jit_int arg1 = 3;
jit_int arg2 = 5;
jit_int arg3 = 2;
jit_int args[3];
args[0] = &arg1;



( run in 1.454 second using v1.01-cache-2.11-cpan-2398b32b56e )