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 )