@@ -792,13 +792,17 @@ int emit_llvm(const std::string &infile,
792792 return 0 ;
793793}
794794
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 (
796800 const std::string &infile,
797801 const std::string &outfile,
798802 const std::string &runtime_library_dir,
799803 LCompilers::PassManager& pass_manager,
800804 CompilerOptions &compiler_options,
801- bool time_report, bool arg_c=false )
805+ bool time_report, bool arg_c=false , bool to_jit= false )
802806{
803807 Allocator al (4 *1024 );
804808 LCompilers::diag::Diagnostics diagnostics;
@@ -869,7 +873,6 @@ int compile_python_to_object_file(
869873 }
870874 LCompilers::PythonCompiler fe (compiler_options);
871875 LCompilers::LLVMEvaluator e (compiler_options.target );
872- std::unique_ptr<LCompilers::LLVMModule> m;
873876 auto asr_to_llvm_start = std::chrono::high_resolution_clock::now ();
874877 LCompilers::Result<std::unique_ptr<LCompilers::LLVMModule>>
875878 res = fe.get_llvm3 (*asr, pass_manager, diagnostics, infile);
@@ -882,12 +885,55 @@ int compile_python_to_object_file(
882885 print_time_report (times, time_report);
883886 return 3 ;
884887 }
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+ }
891937 return 0 ;
892938}
893939
@@ -1560,6 +1606,7 @@ int main(int argc, char *argv[])
15601606 bool print_rtl_header_dir = false ;
15611607 bool print_rtl_dir = false ;
15621608 bool separate_compilation = false ;
1609+ bool to_jit = false ;
15631610
15641611 std::string arg_fmt_file;
15651612 // int arg_fmt_indent = 4;
@@ -1593,6 +1640,7 @@ int main(int argc, char *argv[])
15931640 app.add_option (" -I" , compiler_options.import_paths , " Specify the paths"
15941641 " to look for the module" )->allow_extra_args (false );
15951642 // 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" );
15961644 app.add_flag (" -g" , compiler_options.emit_debug_info , " Compile with debugging information" );
15971645 app.add_flag (" --debug-with-line-column" , compiler_options.emit_debug_line_column ,
15981646 " Convert the linear location info into line + column in the debugging information" );
@@ -1894,10 +1942,10 @@ int main(int argc, char *argv[])
18941942 }
18951943 }
18961944
1897- if (arg_c) {
1945+ if (arg_c && !to_jit ) {
18981946 if (backend == Backend::llvm) {
18991947#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,
19011949 arg_c);
19021950#else
19031951 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[])
19111959 if (endswith (arg_file, " .py" ))
19121960 {
19131961 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+ }
19141979 if (backend == Backend::x86) {
19151980 err = compile_to_binary_x86 (arg_file, outfile,
19161981 runtime_library_dir, compiler_options, time_report);
@@ -1931,7 +1996,7 @@ int main(int argc, char *argv[])
19311996 } else if (backend == Backend::llvm) {
19321997#ifdef HAVE_LFORTRAN_LLVM
19331998 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,
19352000 lpython_pass_manager, compiler_options, time_report);
19362001 if (err != 0 ) return err;
19372002 err = link_executable ({tmp_o}, outfile, runtime_library_dir,
0 commit comments