Alien-LibJIT

 view release on metacpan or  search on metacpan

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

    temp2 = jit_insn_add(function, temp1, z);

    jit_insn_return(function, temp2);
    return 1;
@}
@end example

When the on-demand compiler returns, @code{libjit} will call
@code{jit_function_compile} and then jump to the newly compiled code.
Upon the second and subsequent calls to the function, @code{libjit}
will bypass the on-demand compiler and call the compiled code directly.
Note that in case of on-demand compilation @code{libjit} automatically
locks and unlocks the corresponding context with
@code{jit_context_build_start} and @code{jit_context_build_end} calls.

Sometimes you may wish to force a commonly used function to
be recompiled, so that you can apply additional optimization.
To do this, you must set the "recompilable" flag just after the
function is first created:

@example
jit_function_t function;
...
function = jit_function_create(context, signature);
jit_function_set_recompilable(function);
jit_function_set_on_demand_compiler(function, compile_mul_add);
@end example

Once the function is compiled (either on-demand or up-front) its
intermediate representation built by @code{libjit} is discarded.
To force the function to be recompiled you need to build it again
and call @code{jit_function_compile} after that.  As always when
the function is built and compiled manually it is necessary
to take care of context locking:

@example
jit_context_build_start(context);
jit_function_get_on_demand_compiler(function)(function);
jit_function_compile(function);
jit_context_build_end(context);
@end example

After this, any existing references to the function will be redirected
to the new version.  However, if some thread is currently executing the
previous version, then it will keep doing so until the previous version
exits.  Only after that will subsequent calls go to the new version.

In this tutorial, we use the same on-demand compiler when we
recompile @code{mul_add}.  In a real program, you would probably call
@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);



( run in 0.946 second using v1.01-cache-2.11-cpan-524268b4103 )