@@ -792,13 +792,17 @@ int emit_llvm(const std::string &infile,
792
792
return 0 ;
793
793
}
794
794
795
- int compile_python_to_object_file (
795
+ /*
796
+ Compiles python to object file, if `to_jit` is false
797
+ otherwise execute python code using llvm JIT
798
+ */
799
+ int compile_python_using_llvm (
796
800
const std::string &infile,
797
801
const std::string &outfile,
798
802
const std::string &runtime_library_dir,
799
803
LCompilers::PassManager& pass_manager,
800
804
CompilerOptions &compiler_options,
801
- bool time_report, bool arg_c=false )
805
+ bool time_report, bool arg_c=false , bool to_jit= false )
802
806
{
803
807
Allocator al (4 *1024 );
804
808
LCompilers::diag::Diagnostics diagnostics;
@@ -869,7 +873,6 @@ int compile_python_to_object_file(
869
873
}
870
874
LCompilers::PythonCompiler fe (compiler_options);
871
875
LCompilers::LLVMEvaluator e (compiler_options.target );
872
- std::unique_ptr<LCompilers::LLVMModule> m;
873
876
auto asr_to_llvm_start = std::chrono::high_resolution_clock::now ();
874
877
LCompilers::Result<std::unique_ptr<LCompilers::LLVMModule>>
875
878
res = fe.get_llvm3 (*asr, pass_manager, diagnostics, infile);
@@ -882,12 +885,55 @@ int compile_python_to_object_file(
882
885
print_time_report (times, time_report);
883
886
return 3 ;
884
887
}
885
- m = std::move (res.result );
886
- auto llvm_start = std::chrono::high_resolution_clock::now ();
887
- e.save_object_file (*(m->m_m ), outfile);
888
- auto llvm_end = std::chrono::high_resolution_clock::now ();
889
- times.push_back (std::make_pair (" LLVM to binary" , std::chrono::duration<double , std::milli>(llvm_end - llvm_start).count ()));
890
- print_time_report (times, time_report);
888
+ std::unique_ptr<LCompilers::LLVMModule> m = std::move (res.result );
889
+
890
+ if (to_jit) {
891
+ LCompilers::LPython::DynamicLibrary cpython_lib;
892
+ LCompilers::LPython::DynamicLibrary symengine_lib;
893
+
894
+ if (compiler_options.enable_cpython ) {
895
+ LCompilers::LPython::open_cpython_library (cpython_lib);
896
+ }
897
+ if (compiler_options.enable_symengine ) {
898
+ LCompilers::LPython::open_symengine_library (symengine_lib);
899
+ }
900
+
901
+ auto llvm_start = std::chrono::high_resolution_clock::now ();
902
+
903
+ bool call_init = false ;
904
+ bool call_stmts = false ;
905
+ if (m->get_return_type (" __module___main_____main__global_init" ) == " void" ) {
906
+ call_init = true ;
907
+ }
908
+ if (m->get_return_type (" __module___main_____main__global_stmts" ) == " void" ) {
909
+ call_stmts = true ;
910
+ }
911
+
912
+ e.add_module (std::move (m));
913
+ if (call_init) {
914
+ e.voidfn (" __module___main_____main__global_init" );
915
+ }
916
+ if (call_stmts) {
917
+ e.voidfn (" __module___main_____main__global_stmts" );
918
+ }
919
+
920
+ if (compiler_options.enable_cpython ) {
921
+ LCompilers::LPython::close_cpython_library (cpython_lib);
922
+ }
923
+ if (compiler_options.enable_symengine ) {
924
+ LCompilers::LPython::close_symengine_library (symengine_lib);
925
+ }
926
+
927
+ auto llvm_end = std::chrono::high_resolution_clock::now ();
928
+ times.push_back (std::make_pair (" LLVM JIT execution" , std::chrono::duration<double , std::milli>(llvm_end - llvm_start).count ()));
929
+ print_time_report (times, time_report);
930
+ } else {
931
+ auto llvm_start = std::chrono::high_resolution_clock::now ();
932
+ e.save_object_file (*(m->m_m ), outfile);
933
+ auto llvm_end = std::chrono::high_resolution_clock::now ();
934
+ times.push_back (std::make_pair (" LLVM to binary" , std::chrono::duration<double , std::milli>(llvm_end - llvm_start).count ()));
935
+ print_time_report (times, time_report);
936
+ }
891
937
return 0 ;
892
938
}
893
939
@@ -1560,6 +1606,7 @@ int main(int argc, char *argv[])
1560
1606
bool print_rtl_header_dir = false ;
1561
1607
bool print_rtl_dir = false ;
1562
1608
bool separate_compilation = false ;
1609
+ bool to_jit = false ;
1563
1610
1564
1611
std::string arg_fmt_file;
1565
1612
// int arg_fmt_indent = 4;
@@ -1593,6 +1640,7 @@ int main(int argc, char *argv[])
1593
1640
app.add_option (" -I" , compiler_options.import_paths , " Specify the paths"
1594
1641
" to look for the module" )->allow_extra_args (false );
1595
1642
// app.add_option("-J", arg_J, "Where to save mod files");
1643
+ app.add_flag (" --jit" , to_jit, " Execute the program using just-in-time (JIT) compiler" );
1596
1644
app.add_flag (" -g" , compiler_options.emit_debug_info , " Compile with debugging information" );
1597
1645
app.add_flag (" --debug-with-line-column" , compiler_options.emit_debug_line_column ,
1598
1646
" Convert the linear location info into line + column in the debugging information" );
@@ -1894,10 +1942,10 @@ int main(int argc, char *argv[])
1894
1942
}
1895
1943
}
1896
1944
1897
- if (arg_c) {
1945
+ if (arg_c && !to_jit ) {
1898
1946
if (backend == Backend::llvm) {
1899
1947
#ifdef HAVE_LFORTRAN_LLVM
1900
- return compile_python_to_object_file (arg_file, outfile, runtime_library_dir, lpython_pass_manager, compiler_options, time_report,
1948
+ return compile_python_using_llvm (arg_file, outfile, runtime_library_dir, lpython_pass_manager, compiler_options, time_report,
1901
1949
arg_c);
1902
1950
#else
1903
1951
std::cerr << " The -c option requires the LLVM backend to be enabled. Recompile with `WITH_LLVM=yes`." << std::endl;
@@ -1911,6 +1959,23 @@ int main(int argc, char *argv[])
1911
1959
if (endswith (arg_file, " .py" ))
1912
1960
{
1913
1961
int err = 0 ;
1962
+ if (to_jit) {
1963
+ #ifdef HAVE_LFORTRAN_LLVM
1964
+ if (backend != Backend::llvm) {
1965
+ std::cerr << " JIT option is only available with LLVM backend" << std::endl;
1966
+ return 1 ;
1967
+ }
1968
+ compiler_options.emit_debug_info = false ;
1969
+ compiler_options.emit_debug_line_column = false ;
1970
+ compiler_options.generate_object_code = false ;
1971
+ return compile_python_using_llvm (arg_file, " " , runtime_library_dir,
1972
+ lpython_pass_manager, compiler_options, time_report, false , true );
1973
+ #else
1974
+ std::cerr << " Just-In-Time Compilation of Python files requires the LLVM backend to be enabled."
1975
+ " Recompile with `WITH_LLVM=yes`." << std::endl;
1976
+ return 1 ;
1977
+ #endif
1978
+ }
1914
1979
if (backend == Backend::x86) {
1915
1980
err = compile_to_binary_x86 (arg_file, outfile,
1916
1981
runtime_library_dir, compiler_options, time_report);
@@ -1931,7 +1996,7 @@ int main(int argc, char *argv[])
1931
1996
} else if (backend == Backend::llvm) {
1932
1997
#ifdef HAVE_LFORTRAN_LLVM
1933
1998
std::string tmp_o = outfile + " .tmp.o" ;
1934
- err = compile_python_to_object_file (arg_file, tmp_o, runtime_library_dir,
1999
+ err = compile_python_using_llvm (arg_file, tmp_o, runtime_library_dir,
1935
2000
lpython_pass_manager, compiler_options, time_report);
1936
2001
if (err != 0 ) return err;
1937
2002
err = link_executable ({tmp_o}, outfile, runtime_library_dir,
0 commit comments