calling inline functions from JIT-ed code
Basile Starynkevitch
basile@starynkevitch.net
Sun Jan 1 00:00:00 GMT 2017
Hello All,
(assume that I am using -in a few weeks- GCC8 on Debian/Sid/x86-64 if
details matter)
I would like to JIT compile using libgccjit some code in my language
implementation.
If you really want to know which one, look on my github project
https://github.com/bstarynk/bismon but we could more easily reason about
JIT-compiling for GUILE 2.2 (so I am referring to header files from the
guile-2.2-dev Debian package).
In such a situation, it is often the case that we already have several
inline functions related to short basic operations in that interpreter
or language implementation. In particular the basic cons operation (to
build a GUILE cons pair) is implemented by a call to the following
inlined function (near line 170 of file
/usr/include/guile/2.2/libguile/gc-inline.h)
static inline SCM
scm_inline_cons (scm_i_thread *thread, SCM x, SCM y)
{
 return scm_inline_cell (thread, SCM_UNPACK (x), SCM_UNPACK (y));
}
My question is how to be sure that libgccjit is generating a call to
that inlined function.
A possible (still not implemented) approach in the future might be to be
able to get a gcc_jit_context from some pre-compiled preprocessor header
file, but AFAIU we don't have that (and I guess it is very difficult to
implement). So in that ideal world we would just call an hypothetical
function like
gcc_jit_context* gcc_jit_context_new_from_precompiled_header(const
char*filepath);
IIRC, I remembered having vaguely expressed a similar wish in
https://gcc.gnu.org/ml/jit/2015-q4/msg00001.html and in
https://gcc.gnu.org/ml/jit/2015-q2/msg00093.html
My feeling is that might not be really needed, if we could use Link Time
Optimization. So we might perhaps compile all GUILE inline functions,
perhaps by compiling with gcc -O2 -flto a simple C file myjitguile.c
containing (after the appropriate GUILE includes) simplistic wrappers like:
SCM myjit_scm_cons(void*th, void*x, void*y) { return scm_inline_cons
((scp__i_thread*)th, (SCM)(x), (SCM)(y)); }
But then I am stuck on the detailed steps. My current thinking is that:
1. I should compile that myjitguile.c using gcc -O2 -flto -fPIC
myjitguile.c -o myjitguile.pic.o
2. I should create a gcc_jit_context and fill it with the declarations
of all functions from myjitguile.c; this could be tedious if that file
is big enough; perhaps coding a specialized GCC plugin to help in that
might be worthwhile (that plugin will extract the declarations of
mygitguile.c and put them into some persistent file or database, to be
later read by the JIT-ing code to fill that gcc_jit_context).
3. I should fill that gcc_jit_context with my new JIT-ed code, with
"ordinary" calls to functions named like myjit_scm_cons
4. Once that gcc_jit_context is complete, I need t compile it with -O2
-flto -fPIC. I don't know how exactly to do that, but I am guessing that
I need to call both gcc_jit_context_add_command_line_option and
gcc_jit_context_set_int_option but I don't understand when should I call
these. Is it at that step 4 or at step 2?
5. Should I call gcc_jit_context_compile_to_file followed by dlopen or
gcc_jit_context_compile ? Conceptually, I just want to JIT compile to
memory, so ideally I would like to avoid writing files?
6. Should I fork some gcc linking process? Which one exactly?
Regards.
--
Basile STARYNKEVITCH ==http://starynkevitch.net/Basile
opinions are mine only - les opinions sont seulement miennes
Bourg La Reine, France
More information about the Jit
mailing list