Skip to content

Commit ad9c9e9

Browse files
authored
Merge pull request #999 from czgdp1807/mod01
Saving LPython's intrinsic modules as ``pyc`` files
2 parents dabd06a + b924d1d commit ad9c9e9

9 files changed

+203
-70
lines changed

CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ set(WITH_LFORTRAN_BINARY_MODFILES YES
8080
set(WITH_RUNTIME_LIBRARY YES
8181
CACHE BOOL "Compile and install the runtime library")
8282

83+
set(WITH_INTRINSIC_MODULES no
84+
CACHE BOOL "Compile intrinsic modules to .pyc (ASR) at build time")
85+
8386
# Find ZLIB with our custom finder before including LLVM since the finder for LLVM
8487
# might search for ZLIB again and find the shared libraries instead of the static ones
8588
find_package(StaticZLIB REQUIRED)

src/bin/CMakeLists.txt

+28
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,31 @@ set_target_properties(lpython PROPERTIES
5757
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/$<0:>
5858
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/$<0:>
5959
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/$<0:>)
60+
61+
if (WITH_INTRINSIC_MODULES)
62+
macro(LPYTHON_COMPILE_MODULE name)
63+
add_custom_command(
64+
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/../runtime/${name}.pyc
65+
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/lpython
66+
ARGS --disable-main -c ${CMAKE_CURRENT_SOURCE_DIR}/../runtime/${name}.py -o ${name}.o
67+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../runtime
68+
DEPENDS lpython ${CMAKE_CURRENT_SOURCE_DIR}/../runtime/${name}.py ${ARGN}
69+
COMMENT "LPython Compiling ${name}.py")
70+
endmacro(LPYTHON_COMPILE_MODULE)
71+
72+
LPYTHON_COMPILE_MODULE(lpython_intrinsic_numpy)
73+
LPYTHON_COMPILE_MODULE(lpython_builtin)
74+
75+
add_custom_target(lpython_intrinsics
76+
ALL
77+
DEPENDS
78+
${CMAKE_CURRENT_BINARY_DIR}/../runtime/lpython_intrinsic_numpy.pyc
79+
${CMAKE_CURRENT_BINARY_DIR}/../runtime/lpython_builtin.pyc
80+
)
81+
82+
install(
83+
FILES ${CMAKE_CURRENT_BINARY_DIR}/../runtime/lpython_intrinsic_numpy.pyc
84+
${CMAKE_CURRENT_BINARY_DIR}/../runtime/lpython_builtin.pyc
85+
DESTINATION share/lfortran/lib
86+
)
87+
endif()

src/bin/lpython.cpp

+11-3
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ int compile_python_to_object_file(
512512
const std::string &runtime_library_dir,
513513
LCompilers::PassManager& pass_manager,
514514
CompilerOptions &compiler_options,
515-
bool time_report)
515+
bool time_report, bool arg_c=false)
516516
{
517517
Allocator al(4*1024);
518518
LFortran::diag::Diagnostics diagnostics;
@@ -540,7 +540,8 @@ int compile_python_to_object_file(
540540
diagnostics.diagnostics.clear();
541541
auto ast_to_asr_start = std::chrono::high_resolution_clock::now();
542542
LFortran::Result<LFortran::ASR::TranslationUnit_t*>
543-
r1 = LFortran::LPython::python_ast_to_asr(al, *ast, diagnostics, true,
543+
r1 = LFortran::LPython::python_ast_to_asr(al, *ast, diagnostics,
544+
!(arg_c && compiler_options.disable_main),
544545
compiler_options.disable_main, compiler_options.symtab_only, infile);
545546
auto ast_to_asr_end = std::chrono::high_resolution_clock::now();
546547
times.push_back(std::make_pair("AST to ASR", std::chrono::duration<double, std::milli>(ast_to_asr_end - ast_to_asr_start).count()));
@@ -551,6 +552,12 @@ int compile_python_to_object_file(
551552
return 2;
552553
}
553554
LFortran::ASR::TranslationUnit_t* asr = r1.result;
555+
if( compiler_options.disable_main ) {
556+
int err = LFortran::LPython::save_pyc_files(*asr, infile);
557+
if( err ) {
558+
return err;
559+
}
560+
}
554561
diagnostics.diagnostics.clear();
555562

556563
// ASR -> LLVM
@@ -1065,7 +1072,8 @@ int main(int argc, char *argv[])
10651072
if (arg_c) {
10661073
if (backend == Backend::llvm) {
10671074
#ifdef HAVE_LFORTRAN_LLVM
1068-
return compile_python_to_object_file(arg_file, outfile, runtime_library_dir, lpython_pass_manager, compiler_options, time_report);
1075+
return compile_python_to_object_file(arg_file, outfile, runtime_library_dir, lpython_pass_manager, compiler_options, time_report,
1076+
arg_c);
10691077
#else
10701078
std::cerr << "The -c option requires the LLVM backend to be enabled. Recompile with `WITH_LLVM=yes`." << std::endl;
10711079
return 1;

src/libasr/modfile.cpp

+51-23
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,8 @@ namespace LFortran {
1212

1313
const std::string lfortran_modfile_type_string = "LFortran Modfile";
1414

15-
// The save_modfile() and load_modfile() must stay consistent. What is saved
16-
// must be loaded in exactly the same order.
17-
18-
/*
19-
Saves the module into a binary stream.
20-
21-
That stream can be saved to a mod file by the caller.
22-
The sections in the file/stream are saved using write_string(), so they
23-
can be efficiently read by the loader and ignored if needed.
24-
25-
Comments below show some possible future improvements to the mod format.
26-
*/
27-
std::string save_modfile(const ASR::TranslationUnit_t &m) {
28-
LFORTRAN_ASSERT(m.m_global_scope->get_scope().size()== 1);
29-
for (auto &a : m.m_global_scope->get_scope()) {
30-
LFORTRAN_ASSERT(ASR::is_a<ASR::Module_t>(*a.second));
31-
if ((bool&)a) { } // Suppress unused warning in Release mode
32-
}
33-
#ifdef WITH_LFORTRAN_BINARY_MODFILES
15+
inline void save_asr(const ASR::TranslationUnit_t &m, std::string& asr_string) {
16+
#ifdef WITH_LFORTRAN_BINARY_MODFILES
3417
BinaryWriter b;
3518
#else
3619
TextWriter b;
@@ -54,11 +37,40 @@ std::string save_modfile(const ASR::TranslationUnit_t &m) {
5437
// Full ASR:
5538
b.write_string(serialize(m));
5639

57-
return b.get_str();
40+
asr_string = b.get_str();
5841
}
5942

60-
ASR::TranslationUnit_t* load_modfile(Allocator &al, const std::string &s,
61-
bool load_symtab_id, SymbolTable &symtab) {
43+
// The save_modfile() and load_modfile() must stay consistent. What is saved
44+
// must be loaded in exactly the same order.
45+
46+
/*
47+
Saves the module into a binary stream.
48+
49+
That stream can be saved to a mod file by the caller.
50+
The sections in the file/stream are saved using write_string(), so they
51+
can be efficiently read by the loader and ignored if needed.
52+
53+
Comments below show some possible future improvements to the mod format.
54+
*/
55+
std::string save_modfile(const ASR::TranslationUnit_t &m) {
56+
LFORTRAN_ASSERT(m.m_global_scope->get_scope().size()== 1);
57+
for (auto &a : m.m_global_scope->get_scope()) {
58+
LFORTRAN_ASSERT(ASR::is_a<ASR::Module_t>(*a.second));
59+
if ((bool&)a) { } // Suppress unused warning in Release mode
60+
}
61+
62+
std::string asr_string;
63+
save_asr(m, asr_string);
64+
return asr_string;
65+
}
66+
67+
std::string save_pycfile(const ASR::TranslationUnit_t &m) {
68+
std::string asr_string;
69+
save_asr(m, asr_string);
70+
return asr_string;
71+
}
72+
73+
inline void load_serialised_asr(const std::string &s, std::string& asr_binary) {
6274
#ifdef WITH_LFORTRAN_BINARY_MODFILES
6375
BinaryReader b(s);
6476
#else
@@ -72,11 +84,27 @@ ASR::TranslationUnit_t* load_modfile(Allocator &al, const std::string &s,
7284
if (version != LFORTRAN_VERSION) {
7385
throw LCompilersException("Incompatible format: LFortran Modfile was generated using version '" + version + "', but current LFortran version is '" + LFORTRAN_VERSION + "'");
7486
}
75-
std::string asr_binary = b.read_string();
87+
asr_binary = b.read_string();
88+
}
89+
90+
ASR::TranslationUnit_t* load_modfile(Allocator &al, const std::string &s,
91+
bool load_symtab_id, SymbolTable &symtab) {
92+
std::string asr_binary;
93+
load_serialised_asr(s, asr_binary);
7694
ASR::asr_t *asr = deserialize_asr(al, asr_binary, load_symtab_id, symtab);
7795

7896
ASR::TranslationUnit_t *tu = ASR::down_cast2<ASR::TranslationUnit_t>(asr);
7997
return tu;
8098
}
8199

100+
ASR::TranslationUnit_t* load_pycfile(Allocator &al, const std::string &s,
101+
bool load_symtab_id) {
102+
std::string asr_binary;
103+
load_serialised_asr(s, asr_binary);
104+
ASR::asr_t *asr = deserialize_asr(al, asr_binary, load_symtab_id);
105+
106+
ASR::TranslationUnit_t *tu = ASR::down_cast2<ASR::TranslationUnit_t>(asr);
107+
return tu;
108+
}
109+
82110
} // namespace LFortran

src/libasr/modfile.h

+5
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,15 @@ namespace LFortran {
88
// Save a module to a modfile
99
std::string save_modfile(const ASR::TranslationUnit_t &m);
1010

11+
std::string save_pycfile(const ASR::TranslationUnit_t &m);
12+
1113
// Load a module from a modfile
1214
ASR::TranslationUnit_t* load_modfile(Allocator &al, const std::string &s,
1315
bool load_symtab_id, SymbolTable &symtab);
1416

17+
ASR::TranslationUnit_t* load_pycfile(Allocator &al, const std::string &s,
18+
bool load_symtab_id);
19+
1520
}
1621

1722
#endif // LFORTRAN_MODFILE_H

src/libasr/serialization.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,12 @@ void fix_external_symbols(ASR::TranslationUnit_t &unit,
307307
}
308308

309309
ASR::asr_t* deserialize_asr(Allocator &al, const std::string &s,
310-
bool load_symtab_id, SymbolTable &external_symtab) {
310+
bool load_symtab_id, SymbolTable & /*external_symtab*/) {
311+
return deserialize_asr(al, s, load_symtab_id);
312+
}
313+
314+
ASR::asr_t* deserialize_asr(Allocator &al, const std::string &s,
315+
bool load_symtab_id) {
311316
ASRDeserializationVisitor v(al, s, load_symtab_id);
312317
ASR::asr_t *node = v.deserialize_node();
313318
ASR::TranslationUnit_t *tu = ASR::down_cast2<ASR::TranslationUnit_t>(node);
@@ -319,9 +324,6 @@ ASR::asr_t* deserialize_asr(Allocator &al, const std::string &s,
319324

320325
LFORTRAN_ASSERT(asr_verify(*tu, false));
321326

322-
// Suppress a warning for now
323-
if ((bool&)external_symtab) {}
324-
325327
return node;
326328
}
327329

src/libasr/serialization.h

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ namespace LFortran {
99
std::string serialize(const ASR::TranslationUnit_t &unit);
1010
ASR::asr_t* deserialize_asr(Allocator &al, const std::string &s,
1111
bool load_symtab_id, SymbolTable &symtab);
12+
ASR::asr_t* deserialize_asr(Allocator &al, const std::string &s,
13+
bool load_symtab_id);
1214

1315
void fix_external_symbols(ASR::TranslationUnit_t &unit,
1416
SymbolTable &external_symtab);

0 commit comments

Comments
 (0)