Start working on the new jit system.

[COMPILER]
* NEW: Start working on the new jit system.

[GB.JIT]
* NEW: Rename the component as 'gb.jit.llvm'.
This commit is contained in:
gambas 2018-05-17 01:13:56 +02:00
parent f87cd1025b
commit f39f7063ef
45 changed files with 292 additions and 81 deletions

View file

@ -34,7 +34,7 @@ SUBDIRS = \
@gmp_dir@ \ @gmp_dir@ \
@ncurses_dir@ \ @ncurses_dir@ \
@media_dir@ \ @media_dir@ \
@jit_dir@ \ @jitllvm_dir@ \
@httpd_dir@ \ @httpd_dir@ \
@openssl_dir@ \ @openssl_dir@ \
@openal_dir@ \ @openal_dir@ \

View file

@ -46,7 +46,7 @@ GB_CONFIG_SUBDIRS(gsl, gb.gsl)
GB_CONFIG_SUBDIRS(gmp, gb.gmp) GB_CONFIG_SUBDIRS(gmp, gb.gmp)
GB_CONFIG_SUBDIRS(ncurses, gb.ncurses) GB_CONFIG_SUBDIRS(ncurses, gb.ncurses)
GB_CONFIG_SUBDIRS(media, gb.media) GB_CONFIG_SUBDIRS(media, gb.media)
GB_CONFIG_SUBDIRS(jit, gb.jit) GB_CONFIG_SUBDIRS(jitllvm, gb.jit.llvm)
GB_CONFIG_SUBDIRS(httpd, gb.httpd) GB_CONFIG_SUBDIRS(httpd, gb.httpd)
GB_CONFIG_SUBDIRS(openssl, gb.openssl) GB_CONFIG_SUBDIRS(openssl, gb.openssl)
GB_CONFIG_SUBDIRS(openal, gb.openal) GB_CONFIG_SUBDIRS(openal, gb.openal)

View file

@ -1,3 +1,3 @@
ACLOCAL_AMFLAGS = -I m4 --install ACLOCAL_AMFLAGS = -I m4 --install
SUBDIRS = @JIT_DIR@ SUBDIRS = @JITLLVM_DIR@
EXTRA_DIST = reconf gambas.h gb*.h EXTRA_DIST = reconf gambas.h gb*.h

View file

@ -1,10 +1,10 @@
dnl ---- configure.ac for gb.jit dnl ---- configure.ac for gb.jit
m4_include([../version.m4]) m4_include([../version.m4])
AC_INIT(gambas3-gb-jit, GB_VERSION, GB_MAIL, [], GB_URL) AC_INIT(gambas3-gb-jit-llvm, GB_VERSION, GB_MAIL, [], GB_URL)
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
GB_INIT(gb.jit) GB_INIT(gb.jit.llvm)
AC_PROG_LIBTOOL AC_PROG_LIBTOOL
min_llvm_version=3.1 min_llvm_version=3.1
@ -17,7 +17,7 @@ if test "x$LLVM_CONFIG" = x; then
fi fi
if test "x$LLVM_CONFIG" = xno; then if test "x$LLVM_CONFIG" = xno; then
touch DISABLED DISABLED.gb.jit touch DISABLED DISABLED.gb.jit.llvm
else else
AC_MSG_CHECKING([for LLVM, version between $min_llvm_version and $max_llvm_version]) AC_MSG_CHECKING([for LLVM, version between $min_llvm_version and $max_llvm_version])
@ -35,14 +35,14 @@ else
else else
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
touch DISABLED DISABLED.gb.jit touch DISABLED DISABLED.gb.jit.llvm
fi fi
fi fi
dnl [GB_FIND(libLLVM-$LLVM_VERSION.$SHLIBEXT, `$LLVM_CONFIG --prefix` /usr/lib/llvm* /usr/local /usr, lib)], dnl [GB_FIND(libLLVM-$LLVM_VERSION.$SHLIBEXT, `$LLVM_CONFIG --prefix` /usr/lib/llvm* /usr/local /usr, lib)],
GB_COMPONENT( GB_COMPONENT(
jit, JIT, gb.jit, [src], jitllvm, JITLLVM, gb.jit.llvm, [src],
[GB_FIND(llvm/ExecutionEngine/JIT.h llvm/Config/llvm-config.h llvm-c/Core.h, `$LLVM_CONFIG --prefix` /usr/lib/llvm* /usr/local /usr, include)], [GB_FIND(llvm/ExecutionEngine/JIT.h llvm/Config/llvm-config.h llvm-c/Core.h, `$LLVM_CONFIG --prefix` /usr/lib/llvm* /usr/local /usr, include)],
[], [],
[$C_LIB `$LLVM_CONFIG --ldflags` $LLVM_LIBS], [$C_LIB `$LLVM_CONFIG --ldflags` $LLVM_LIBS],

View file

@ -0,0 +1,34 @@
COMPONENT = gb.jit.llvm
include $(top_srcdir)/component.am
gblib_LTLIBRARIES = gb.jit.llvm.la
noinst_LTLIBRARIES = libjit.llvm.la
libjit_llvm_la_LIBADD =
libjit_llvm_la_LDFLAGS = -module @LD_FLAGS@
libjit_llvm_la_CPPFLAGS = @JITLLVM_INC@
libjit_llvm_la_CXXFLAGS = $(AM_CFLAGS) -std=gnu++0x -fno-exceptions -fno-rtti
gb_jit_llvm_la_LIBADD = libjit.la @JITLLVM_LIB@
gb_jit_llvm_la_LDFLAGS = -module @LD_FLAGS@ @JITLLVM_LDFLAGS@
gb_jit_llvm_la_CPPFLAGS = @JITLLVM_INC@
gb_jit_llvm_la_CXXFLAGS = $(AM_CXXFLAGS) -std=gnu++0x -fno-exceptions
libjit_llvm_la_SOURCES = \
jit_gambas_pass.cpp \
jit_gambas_pass.h
gb_jit_llvm_la_SOURCES = \
gb.jit.h \
jit_api.cpp \
jit_codegen_conv.h \
jit_codegen.cpp \
jit_compile.cpp \
jit_conv.cpp \
jit_expressions.cpp \
jit.h \
jit_read.cpp \
jit_runtime.c \
jit_runtime.h \
main.cpp \
main.h

View file

@ -0,0 +1,5 @@
[Component]
Key=gb.jit.llvm
Name=Gambas JIT Compiler based on LLVM
Author=Emil Lenngren
Hidden=True

View file

@ -1,34 +0,0 @@
COMPONENT = gb.jit
include $(top_srcdir)/component.am
gblib_LTLIBRARIES = gb.jit.la
noinst_LTLIBRARIES = libjit.la
libjit_la_LIBADD =
libjit_la_LDFLAGS = -module @LD_FLAGS@
libjit_la_CPPFLAGS = @JIT_INC@
libjit_la_CXXFLAGS = $(AM_CFLAGS) -std=gnu++0x -fno-exceptions -fno-rtti
gb_jit_la_LIBADD = libjit.la @JIT_LIB@
gb_jit_la_LDFLAGS = -module @LD_FLAGS@ @JIT_LDFLAGS@
gb_jit_la_CPPFLAGS = @JIT_INC@
gb_jit_la_CXXFLAGS = $(AM_CXXFLAGS) -std=gnu++0x -fno-exceptions
libjit_la_SOURCES = \
jit_gambas_pass.cpp \
jit_gambas_pass.h
gb_jit_la_SOURCES = \
gb.jit.h \
jit_api.cpp \
jit_codegen_conv.h \
jit_codegen.cpp \
jit_compile.cpp \
jit_conv.cpp \
jit_expressions.cpp \
jit.h \
jit_read.cpp \
jit_runtime.c \
jit_runtime.h \
main.cpp \
main.h

View file

@ -1,5 +0,0 @@
[Component]
Key=gb.jit
Name=Gambas JIT Compiler
Author=Emil Lenngren
Hidden=True

View file

@ -36,6 +36,7 @@ gbc3_SOURCES = \
gbc_pcode.c \ gbc_pcode.c \
gb_file.h gb_file.c \ gb_file.h gb_file.c \
gbc_form.h gbc_form.c gbc_form_webpage.c \ gbc_form.h gbc_form.c gbc_form_webpage.c \
gbc_jit.h gbc_jit.c \
gb_str.h gb_str.c \ gb_str.h gb_str.c \
gbc_chown.h gbc_chown.c \ gbc_chown.h gbc_chown.c \
gb_common.c \ gb_common.c \

View file

@ -28,6 +28,7 @@
#include <stdio.h> #include <stdio.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdarg.h> #include <stdarg.h>
#include <ctype.h>
#include "gb_common.h" #include "gb_common.h"
#include "gb_error.h" #include "gb_error.h"
@ -96,4 +97,35 @@ char *STR_cat(const char *str, ...)
return cpy; return cpy;
} }
char *STR_upper(const char *str)
{
char *s;
char *p;
p = s = STR_copy(str);
while (*p)
{
*p = toupper(*p);
p++;
}
return s;
}
char *STR_lower(const char *str)
{
char *s;
char *p;
p = s = STR_copy(str);
while (*p)
{
*p = tolower(*p);
p++;
}
return s;
}

View file

@ -30,6 +30,8 @@ char *STR_copy(const char *str);
char *STR_copy_len(const char *str, int len); char *STR_copy_len(const char *str, int len);
char *STR_cat(const char *str, ...); char *STR_cat(const char *str, ...);
char *STR_add(char *d, const char *s); char *STR_add(char *d, const char *s);
char *STR_upper(const char *str);
char *STR_lower(const char *str);
#define STR_free(_str) IFREE(_str) #define STR_free(_str) IFREE(_str)

View file

@ -202,7 +202,8 @@ typedef
unsigned nocreate : 1; // class cannot be instantiated unsigned nocreate : 1; // class cannot be instantiated
unsigned all_fast : 1; // all methods have the Fast option (JIT) unsigned all_fast : 1; // all methods have the Fast option (JIT)
unsigned has_static : 1; // has static methods, properties or variables unsigned has_static : 1; // has static methods, properties or variables
unsigned _reserved : 10; unsigned has_fast : 1; // has at least one fast method
unsigned _reserved : 9;
VARIABLE *stat; // static variables VARIABLE *stat; // static variables
VARIABLE *dyn; // dynamic variables VARIABLE *dyn; // dynamic variables
CONSTANT *constant; // constants CONSTANT *constant; // constants

View file

@ -688,7 +688,9 @@ static bool header_function(TRANS_FUNC *func)
if (is_static) TYPE_set_flag(&func->type, TF_STATIC); if (is_static) TYPE_set_flag(&func->type, TF_STATIC);
if (is_public) TYPE_set_flag(&func->type, TF_PUBLIC); if (is_public) TYPE_set_flag(&func->type, TF_PUBLIC);
func->fast = is_fast; func->fast = is_fast || JOB->class->all_fast;
if (func->fast)
JOB->class->has_fast = TRUE;
// Check special methods // Check special methods
@ -887,7 +889,6 @@ static bool header_option(void)
{ {
JOB->current++; JOB->current++;
JOB->class->all_fast = TRUE; JOB->class->all_fast = TRUE;
return TRUE; return TRUE;
} }

112
main/gbc/gbc_jit.c Normal file
View file

@ -0,0 +1,112 @@
/***************************************************************************
gbc_jit.c
(c) 2000-2018 Benoît Minisini <g4mba5@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
***************************************************************************/
#define __GBC_JIT_C
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include "gb_file.h"
#include "gb_str.h"
#include "gb_error.h"
#include "gbc_compile.h"
#include "gbc_chown.h"
#include "gbc_class.h"
#include "gbc_jit.h"
static FILE *_file = NULL;
static char *_prefix;
void JIT_begin(void)
{
const char *path;
if (_file)
return;
if (mkdir(".jit", 0777) == 0)
FILE_set_owner(".jit", COMP_project);
_prefix = STR_lower(JOB->class->name);
path = FILE_cat(".jit", _prefix, NULL);
path = FILE_set_ext(path, "c");
_file = fopen(path, "w");
if (!_file)
THROW("Cannot create file: &1", path);
}
void JIT_end(void)
{
if (!_file)
return;
fclose(_file);
_file = NULL;
STR_free(_prefix);
}
void JIT_declare_func(FUNCTION *func)
{
char *name = STR_lower(TABLE_get_symbol_name(JOB->class->table, func->name));
if (!TYPE_is_public(func->type))
JIT_print("static ");
JIT_print("void %s_%s();\n", _prefix, name);
STR_free(name);
}
void JIT_begin_func(FUNCTION *func)
{
const char *fname = TABLE_get_symbol_name(JOB->class->table, func->name);
char *name = STR_lower(fname);
JIT_section(fname);
if (!TYPE_is_public(func->type))
JIT_print("static ");
JIT_print("void %s_%s(ushort code)\n{\n", _prefix, name);
STR_free(name);
}
void JIT_end_func(void)
{
JIT_print("}\n");
}
void JIT_print(const char *str, ...)
{
va_list args;
va_start(args, str);
vfprintf(_file, str, args);
}
void JIT_section(const char *str)
{
JIT_print("\n// %s\n\n", str);
}

38
main/gbc/gbc_jit.h Normal file
View file

@ -0,0 +1,38 @@
/***************************************************************************
gbc_jit.h
(c) 2000-2018 Benoît Minisini <g4mba5@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
***************************************************************************/
#ifndef __GBC_JIT_H
#define __GBC_JIT_H
#include "gbc_class.h"
void JIT_begin(void);
void JIT_end(void);
void JIT_declare_func(FUNCTION *func);
void JIT_begin_func(FUNCTION *func);
void JIT_end_func(void);
void JIT_print(const char *str, ...);
void JIT_section(const char *str);
#endif

View file

@ -1151,10 +1151,8 @@ char *OUTPUT_get_file(const char *file)
{ {
char *output; char *output;
char *p; char *p;
//char *dir;
char *name; char *name;
//dir = STR_copy(FILE_get_dir(file));
name = STR_copy(FILE_get_name(file)); name = STR_copy(FILE_get_name(file));
for (p = name; *p; p++) for (p = name; *p; p++)

View file

@ -31,12 +31,13 @@
#include "gb_error.h" #include "gb_error.h"
#include "gbc_compile.h" #include "gbc_compile.h"
#include "gbc_trans.h" #include "gbc_trans.h"
#include "gbc_jit.h"
#include "gb_code.h" #include "gb_code.h"
#include "gb_limit.h" #include "gb_limit.h"
/*#define DEBUG*/ /*#define DEBUG*/
static FUNCTION *func; static FUNCTION *_func;
static CLASS_SYMBOL *add_local(int sym_index, TYPE type, int value, bool used) static CLASS_SYMBOL *add_local(int sym_index, TYPE type, int value, bool used)
{ {
@ -44,10 +45,10 @@ static CLASS_SYMBOL *add_local(int sym_index, TYPE type, int value, bool used)
PARAM *loc; PARAM *loc;
bool warnings = JOB->warnings; bool warnings = JOB->warnings;
if (ARRAY_count(func->local) >= MAX_LOCAL_SYMBOL) if (ARRAY_count(_func->local) >= MAX_LOCAL_SYMBOL)
THROW("Too many local variables"); THROW("Too many local variables");
loc = ARRAY_add(&func->local); loc = ARRAY_add(&_func->local);
loc->index = sym_index; loc->index = sym_index;
loc->type = type; loc->type = type;
loc->value = value; loc->value = value;
@ -72,10 +73,10 @@ static void create_local_from_param()
JOB->line--; // For line number of declaration JOB->line--; // For line number of declaration
for (i = 0; i < func->nparam; i++) for (i = 0; i < _func->nparam; i++)
{ {
if (TYPE_get_id(func->param[i].type) != T_VOID) if (TYPE_get_id(_func->param[i].type) != T_VOID)
add_local(func->param[i].index, func->param[i].type, (i - func->nparam), func->param[i].ignore); add_local(_func->param[i].index, _func->param[i].type, (i - _func->nparam), _func->param[i].ignore);
} }
JOB->line++; JOB->line++;
@ -86,9 +87,9 @@ static void remove_local()
int i; int i;
CLASS_SYMBOL *sym; CLASS_SYMBOL *sym;
for (i = 0; i < ARRAY_count(func->local); i++) for (i = 0; i < ARRAY_count(_func->local); i++)
{ {
sym = CLASS_get_symbol(JOB->class, func->local[i].index); sym = CLASS_get_symbol(JOB->class, _func->local[i].index);
if (!sym->local_used) if (!sym->local_used)
{ {
@ -169,7 +170,7 @@ static bool TRANS_local(void)
no_warning = FALSE; no_warning = FALSE;
sym_index = PATTERN_index(*pattern); sym_index = PATTERN_index(*pattern);
sym = add_local(sym_index, decl.type, func->nlocal, FALSE); sym = add_local(sym_index, decl.type, _func->nlocal, FALSE);
pattern++; pattern++;
if (no_warning) if (no_warning)
@ -178,11 +179,11 @@ static bool TRANS_local(void)
JOB->warnings = save_warnings; JOB->warnings = save_warnings;
} }
func->nlocal++; _func->nlocal++;
if (TRANS_init_var(&decl)) if (TRANS_init_var(&decl))
{ {
CODE_pop_local(func->nlocal - 1); CODE_pop_local(_func->nlocal - 1);
sym->local_assigned = TRUE; sym->local_assigned = TRUE;
} }
@ -197,7 +198,7 @@ static bool TRANS_local(void)
/*if (!many) /*if (!many)
{ {
if (TRANS_init_var(&decl)) if (TRANS_init_var(&decl))
CODE_pop_local(func->nlocal - 1); CODE_pop_local(_func->nlocal - 1);
}*/ }*/
if (!TRANS_is(RS_COMMA)) if (!TRANS_is(RS_COMMA))
@ -310,7 +311,7 @@ void TRANS_statement(void)
static void translate_body() static void translate_body()
{ {
PATTERN *look; PATTERN *look;
bool is_proc = (TYPE_get_id(func->type) == T_VOID); bool is_proc = (TYPE_get_id(_func->type) == T_VOID);
bool test_newline; bool test_newline;
//int line = JOB->line - 1; //int line = JOB->line - 1;
bool just_got_select = FALSE; bool just_got_select = FALSE;
@ -545,28 +546,44 @@ static void trans_call(const char *name, int nparam)
void TRANS_code(void) void TRANS_code(void)
{ {
int i; int i;
bool fast;
if (JOB->class->has_fast)
{
JIT_begin();
JIT_section("Declarations");
for (i = 0; i < ARRAY_count(JOB->class->function); i++)
{
_func = &JOB->class->function[i];
if (!_func->start || !_func->fast)
continue;
JIT_declare_func(_func);
}
}
for (i = 0; i < ARRAY_count(JOB->class->function); i++) for (i = 0; i < ARRAY_count(JOB->class->function); i++)
{ {
func = &JOB->class->function[i]; _func = &JOB->class->function[i];
fast = _func->fast;
CODE_begin_function(func);
CODE_begin_function(_func);
if (JOB->verbose) if (JOB->verbose)
printf("Compiling %s()...\n", TABLE_get_symbol_name(JOB->class->table, func->name)); printf("Compiling %s()...\n", TABLE_get_symbol_name(JOB->class->table, _func->name));
/* Do not debug implicit or generated functions */ /* Do not debug implicit or generated functions */
if (!func->start || func->name == NO_SYMBOL || TABLE_get_symbol_name(JOB->class->table, func->name)[0] == '@') if (!_func->start || _func->name == NO_SYMBOL || TABLE_get_symbol_name(JOB->class->table, _func->name)[0] == '@')
JOB->nobreak = TRUE; JOB->nobreak = TRUE;
else else
JOB->nobreak = FALSE; JOB->nobreak = FALSE;
JOB->line = func->line; JOB->line = _func->line;
JOB->current = func->start; JOB->current = _func->start;
JOB->func = func; JOB->func = _func;
/* fonction implicite ? */ /* fonction implicite ? */
if (!func->start) if (!_func->start)
{ {
if ((i == FUNC_INIT_DYNAMIC) && (JOB->form != NULL)) if ((i == FUNC_INIT_DYNAMIC) && (JOB->form != NULL))
{ {
@ -578,9 +595,12 @@ void TRANS_code(void)
FUNCTION_add_last_pos_line(); FUNCTION_add_last_pos_line();
CODE_op(C_RETURN, 0, 0, TRUE); CODE_op(C_RETURN, 0, 0, TRUE);
if (JOB->verbose) if (JOB->verbose)
CODE_dump(func->code, func->ncode); CODE_dump(_func->code, _func->ncode);
continue; continue;
} }
if (fast)
JIT_begin_func(_func);
create_local_from_param(); create_local_from_param();
@ -588,22 +608,28 @@ void TRANS_code(void)
CODE_return(2); // Return from function, ignore Gosub stack CODE_return(2); // Return from function, ignore Gosub stack
CODE_end_function(func); CODE_end_function(_func);
FUNCTION_add_last_pos_line(); FUNCTION_add_last_pos_line();
func->stack = func->nlocal + func->nctrl + CODE_stack_usage; _func->stack = _func->nlocal + _func->nctrl + CODE_stack_usage;
if (JOB->verbose) if (JOB->verbose)
{ {
CODE_dump(func->code, func->ncode); CODE_dump(_func->code, _func->ncode);
printf("%d local(s) %d control(s) ", func->nlocal, func->nctrl); printf("%d local(s) %d control(s) ", _func->nlocal, _func->nctrl);
printf("%d stack\n", func->stack); printf("%d stack\n", _func->stack);
printf("\n"); printf("\n");
} }
remove_local(); remove_local();
if (fast)
JIT_end_func();
} }
if (fast)
JIT_end();
CLASS_check_properties(JOB->class); CLASS_check_properties(JOB->class);
CLASS_check_unused_global(JOB->class); CLASS_check_unused_global(JOB->class);

View file

@ -31,7 +31,7 @@
#include "gbx_object.h" #include "gbx_object.h"
#include "gbx_exec.h" #include "gbx_exec.h"
#include "../../gb.jit/src/gb.jit.h" #include "../../gb.jit.llvm/src/gb.jit.h"
#ifndef __GBX_JIT_C #ifndef __GBX_JIT_C