Skip to content

Commit e04c568

Browse files
Fix ASR verify pass error while using Interactive (#2706)
* skipping function verification of Interactive ABI * function verify checks for empty body * intrinsic function's body & dependency left unchanged * Fix ASR verify pass error while using Interactive * updated tests * fix typos * update cmake to copy runtime python files to build dir * fix test for the changes in main * fix indentation for windows * fix for windows * undo indentations * indentation fix
1 parent 521941a commit e04c568

File tree

9 files changed

+202
-46
lines changed

9 files changed

+202
-46
lines changed

CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,20 @@ if (WITH_LCOMPILERS_FAST_ALLOC)
120120
add_definitions("-DLCOMPILERS_FAST_ALLOC=1")
121121
endif()
122122

123+
# copy runtime files
124+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/lpython/lpython.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/lpython/lpython.py")
125+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/cmath.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/cmath.py")
126+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/lpython_builtin.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/lpython_builtin.py")
127+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/lpython_intrinsic_numpy.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/lpython_intrinsic_numpy.py")
128+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/lpython_parser.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/lpython_parser.py")
129+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/math.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/math.py")
130+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/os.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/os.py")
131+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/platform.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/platform.py")
132+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/random.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/random.py")
133+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/statistics.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/statistics.py")
134+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/sys.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/sys.py")
135+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/time.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/time.py")
136+
123137
# LLVM
124138
set(WITH_LLVM no CACHE BOOL "Build with LLVM support")
125139
set(WITH_TARGET_AARCH64 no CACHE BOOL "Enable target AARCH64")

src/libasr/asr_scopes.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <libasr/asr_scopes.h>
55
#include <libasr/asr_utils.h>
6+
#include <libasr/pass/pass_utils.h>
67

78
std::string lcompilers_unique_ID;
89

@@ -39,9 +40,13 @@ void SymbolTable::mark_all_variables_external(Allocator &al) {
3940
case (ASR::symbolType::Function) : {
4041
ASR::Function_t *v = ASR::down_cast<ASR::Function_t>(a.second);
4142
ASR::FunctionType_t* v_func_type = ASR::down_cast<ASR::FunctionType_t>(v->m_function_signature);
42-
v_func_type->m_abi = ASR::abiType::Interactive;
43-
v->m_body = nullptr;
44-
v->n_body = 0;
43+
if (v_func_type->m_abi != ASR::abiType::Interactive) {
44+
v_func_type->m_abi = ASR::abiType::Interactive;
45+
v->m_body = nullptr;
46+
v->n_body = 0;
47+
PassUtils::UpdateDependenciesVisitor ud(al);
48+
ud.visit_Function(*v);
49+
}
4550
break;
4651
}
4752
case (ASR::symbolType::Module) : {

src/libasr/asr_verify.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,11 @@ class VerifyVisitor : public BaseWalkVisitor<VerifyVisitor>
420420
}
421421

422422
void visit_Function(const Function_t &x) {
423+
ASR::FunctionType_t* x_func_type = ASR::down_cast<ASR::FunctionType_t>(x.m_function_signature);
424+
if (x_func_type->m_abi == abiType::Interactive) {
425+
require(x.n_body == 0,
426+
"The Function::n_body should be 0 if abi set to Interactive");
427+
}
423428
std::vector<std::string> function_dependencies_copy = function_dependencies;
424429
function_dependencies.clear();
425430
function_dependencies.reserve(x.n_dependencies);

src/libasr/codegen/KaleidoscopeJIT.h

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
#include "llvm/IR/LLVMContext.h"
2727
#include <memory>
2828

29+
#if LLVM_VERSION_MAJOR >= 13
30+
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
31+
#endif
32+
2933
#if LLVM_VERSION_MAJOR >= 16
3034
# define RM_OPTIONAL_TYPE std::optional
3135
#else
@@ -37,77 +41,76 @@ namespace orc {
3741

3842
class KaleidoscopeJIT {
3943
private:
40-
ExecutionSession ES;
44+
std::unique_ptr<ExecutionSession> ES;
4145
RTDyldObjectLinkingLayer ObjectLayer;
4246
IRCompileLayer CompileLayer;
4347

4448
DataLayout DL;
4549
MangleAndInterner Mangle;
46-
ThreadSafeContext Ctx;
4750
JITDylib &JITDL;
4851

49-
TargetMachine *TM;
50-
5152
public:
52-
KaleidoscopeJIT(JITTargetMachineBuilder JTMB, DataLayout DL)
53+
KaleidoscopeJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB, DataLayout DL)
5354
:
54-
#if LLVM_VERSION_MAJOR >= 13
55-
ES(cantFail(SelfExecutorProcessControl::Create())),
56-
#endif
57-
ObjectLayer(ES,
55+
ES(std::move(ES)),
56+
ObjectLayer(*this->ES,
5857
[]() { return std::make_unique<SectionMemoryManager>(); }),
59-
CompileLayer(ES, ObjectLayer, std::make_unique<ConcurrentIRCompiler>(ConcurrentIRCompiler(std::move(JTMB)))),
60-
DL(std::move(DL)), Mangle(ES, this->DL),
61-
Ctx(std::make_unique<LLVMContext>()),
58+
CompileLayer(*this->ES, ObjectLayer, std::make_unique<ConcurrentIRCompiler>(std::move(JTMB))),
59+
DL(std::move(DL)), Mangle(*this->ES, this->DL),
6260
JITDL(
6361
#if LLVM_VERSION_MAJOR >= 11
6462
cantFail
6563
#endif
66-
(ES.createJITDylib("Main"))) {
64+
(this->ES->createJITDylib("Main"))) {
6765
JITDL.addGenerator(
6866
cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess(
6967
DL.getGlobalPrefix())));
70-
71-
std::string Error;
72-
auto TargetTriple = sys::getDefaultTargetTriple();
73-
auto Target = TargetRegistry::lookupTarget(TargetTriple, Error);
74-
if (!Target) {
75-
throw std::runtime_error("Failed to lookup the target");
68+
if (JTMB.getTargetTriple().isOSBinFormatCOFF()) {
69+
ObjectLayer.setOverrideObjectFlagsWithResponsibilityFlags(true);
70+
ObjectLayer.setAutoClaimResponsibilityForObjectSymbols(true);
7671
}
77-
auto CPU = "generic";
78-
auto Features = "";
79-
TargetOptions opt;
80-
auto RM = RM_OPTIONAL_TYPE<Reloc::Model>();
81-
TM = Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM);
8272
}
8373

8474
static Expected<std::unique_ptr<KaleidoscopeJIT>> Create() {
85-
auto JTMB = JITTargetMachineBuilder::detectHost();
75+
#if LLVM_VERSION_MAJOR >= 13
76+
auto EPC = SelfExecutorProcessControl::Create();
77+
if (!EPC)
78+
return EPC.takeError();
8679

87-
if (!JTMB)
88-
return JTMB.takeError();
80+
auto ES = std::make_unique<ExecutionSession>(std::move(*EPC));
8981

90-
auto DL = JTMB->getDefaultDataLayoutForTarget();
82+
JITTargetMachineBuilder JTMB(
83+
ES->getExecutorProcessControl().getTargetTriple());
84+
#else
85+
auto ES = std::make_unique<ExecutionSession>();
86+
87+
auto JTMB_P = JITTargetMachineBuilder::detectHost();
88+
if (!JTMB_P)
89+
return JTMB_P.takeError();
90+
91+
auto JTMB = *JTMB_P;
92+
#endif
93+
94+
auto DL = JTMB.getDefaultDataLayoutForTarget();
9195
if (!DL)
9296
return DL.takeError();
9397

94-
return std::make_unique<KaleidoscopeJIT>(std::move(*JTMB), std::move(*DL));
98+
return std::make_unique<KaleidoscopeJIT>(std::move(ES), std::move(JTMB),
99+
std::move(*DL));
95100
}
96101

97102
const DataLayout &getDataLayout() const { return DL; }
98103

99-
LLVMContext &getContext() { return *Ctx.getContext(); }
100-
101-
Error addModule(std::unique_ptr<Module> M) {
102-
return CompileLayer.add(JITDL,
103-
ThreadSafeModule(std::move(M), Ctx));
104+
Error addModule(std::unique_ptr<Module> M, std::unique_ptr<LLVMContext> &Ctx) {
105+
auto res = CompileLayer.add(JITDL,
106+
ThreadSafeModule(std::move(M), std::move(Ctx)));
107+
Ctx = std::make_unique<LLVMContext>();
108+
return res;
104109
}
105110

106111
Expected<JITEvaluatedSymbol> lookup(StringRef Name) {
107-
return ES.lookup({&JITDL}, Mangle(Name.str()));
112+
return ES->lookup({&JITDL}, Mangle(Name.str()));
108113
}
109-
110-
TargetMachine &getTargetMachine() { return *TM; }
111114
};
112115

113116
} // end namespace orc

src/libasr/codegen/evaluator.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ std::unique_ptr<llvm::Module> LLVMEvaluator::parse_module(const std::string &sou
212212
throw LCompilersException("parse_module(): module failed verification.");
213213
};
214214
module->setTargetTriple(target_triple);
215-
module->setDataLayout(jit->getTargetMachine().createDataLayout());
215+
module->setDataLayout(jit->getDataLayout());
216216
return module;
217217
}
218218

@@ -234,7 +234,7 @@ void LLVMEvaluator::add_module(std::unique_ptr<llvm::Module> mod) {
234234
// cases when the Module was constructed directly, not via parse_module().
235235
mod->setTargetTriple(target_triple);
236236
mod->setDataLayout(jit->getDataLayout());
237-
llvm::Error err = jit->addModule(std::move(mod));
237+
llvm::Error err = jit->addModule(std::move(mod), context);
238238
if (err) {
239239
llvm::SmallVector<char, 128> buf;
240240
llvm::raw_svector_ostream dest(buf);
@@ -288,7 +288,7 @@ std::string LLVMEvaluator::get_asm(llvm::Module &m)
288288
llvm::CodeGenFileType ft = llvm::CGFT_AssemblyFile;
289289
llvm::SmallVector<char, 128> buf;
290290
llvm::raw_svector_ostream dest(buf);
291-
if (jit->getTargetMachine().addPassesToEmitFile(pass, dest, nullptr, ft)) {
291+
if (TM->addPassesToEmitFile(pass, dest, nullptr, ft)) {
292292
throw std::runtime_error("TargetMachine can't emit a file of this type");
293293
}
294294
pass.run(m);

src/libasr/string_utils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ std::string read_file(const std::string &filename)
116116
std::vector<char> bytes(filesize);
117117
ifs.read(&bytes[0], filesize);
118118

119-
return std::string(&bytes[0], filesize);
119+
return replace(std::string(&bytes[0], filesize), "\r\n", "\n");
120120
}
121121

122122
std::string parent_path(const std::string &path) {

src/lpython/tests/test_llvm.cpp

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,25 @@ TEST_CASE("PythonCompiler 1") {
624624
CHECK(r.result.i32 == 1);
625625
}
626626

627+
TEST_CASE("PythonCompiler 2") {
628+
CompilerOptions cu;
629+
cu.po.disable_main = true;
630+
cu.emit_debug_line_column = false;
631+
cu.generate_object_code = false;
632+
cu.interactive = true;
633+
cu.po.runtime_library_dir = LCompilers::LPython::get_runtime_library_dir();
634+
PythonCompiler e(cu);
635+
LCompilers::Result<PythonCompiler::EvalResult>
636+
637+
r = e.evaluate2("i: i32 = 3 % 2");
638+
CHECK(r.ok);
639+
CHECK(r.result.type == PythonCompiler::EvalResult::none);
640+
r = e.evaluate2("i");
641+
CHECK(r.ok);
642+
CHECK(r.result.type == PythonCompiler::EvalResult::integer4);
643+
CHECK(r.result.i32 == 1);
644+
}
645+
627646
TEST_CASE("PythonCompiler i32 expressions") {
628647
CompilerOptions cu;
629648
cu.po.disable_main = true;
@@ -845,6 +864,7 @@ TEST_CASE("PythonCompiler u32 declaration") {
845864
r = e.evaluate2("i: u32");
846865
CHECK(r.ok);
847866
CHECK(r.result.type == PythonCompiler::EvalResult::none);
867+
848868
r = e.evaluate2("i = u32(5)");
849869
CHECK(r.ok);
850870
CHECK(r.result.type == PythonCompiler::EvalResult::statement);
@@ -1358,3 +1378,113 @@ def my_concat(x: str, y: str) -> str:
13581378
CHECK(r.result.type == PythonCompiler::EvalResult::string);
13591379
CHECK(std::strcmp(r.result.str, "Python REPL") == 0);
13601380
}
1381+
1382+
TEST_CASE("PythonCompiler asr verify 1") {
1383+
CompilerOptions cu;
1384+
cu.po.disable_main = true;
1385+
cu.emit_debug_line_column = false;
1386+
cu.generate_object_code = false;
1387+
cu.interactive = true;
1388+
cu.po.runtime_library_dir = LCompilers::LPython::get_runtime_library_dir();
1389+
PythonCompiler e(cu);
1390+
LCompilers::Result<PythonCompiler::EvalResult>
1391+
1392+
r = e.evaluate2("i: i32 = 3 % 2");
1393+
CHECK(r.ok);
1394+
CHECK(r.result.type == PythonCompiler::EvalResult::none);
1395+
r = e.evaluate2("i");
1396+
CHECK(r.ok);
1397+
CHECK(r.result.type == PythonCompiler::EvalResult::integer4);
1398+
CHECK(r.result.i32 == 1);
1399+
}
1400+
1401+
TEST_CASE("PythonCompiler asr verify 2") {
1402+
CompilerOptions cu;
1403+
cu.po.disable_main = true;
1404+
cu.emit_debug_line_column = false;
1405+
cu.generate_object_code = false;
1406+
cu.interactive = true;
1407+
cu.po.runtime_library_dir = LCompilers::LPython::get_runtime_library_dir();
1408+
PythonCompiler e(cu);
1409+
LCompilers::Result<PythonCompiler::EvalResult>
1410+
r = e.evaluate2(R"(
1411+
def is_even(x: i32) -> i32:
1412+
if x % 2 == 0:
1413+
return 1
1414+
return 0
1415+
)");
1416+
CHECK(r.ok);
1417+
CHECK(r.result.type == PythonCompiler::EvalResult::none);
1418+
r = e.evaluate2("is_even(4)");
1419+
CHECK(r.ok);
1420+
CHECK(r.result.type == PythonCompiler::EvalResult::integer4);
1421+
CHECK(r.result.i32 == 1);
1422+
r = e.evaluate2("is_even(3)");
1423+
CHECK(r.ok);
1424+
CHECK(r.result.type == PythonCompiler::EvalResult::integer4);
1425+
CHECK(r.result.i32 == 0);
1426+
}
1427+
1428+
TEST_CASE("PythonCompiler asr verify 3") {
1429+
CompilerOptions cu;
1430+
cu.po.disable_main = true;
1431+
cu.emit_debug_line_column = false;
1432+
cu.generate_object_code = false;
1433+
cu.interactive = true;
1434+
cu.po.runtime_library_dir = LCompilers::LPython::get_runtime_library_dir();
1435+
PythonCompiler e(cu);
1436+
LCompilers::Result<PythonCompiler::EvalResult>
1437+
1438+
r = e.evaluate2(R"(
1439+
def addi(x: i32, y: i32) -> i32:
1440+
return x + y
1441+
)");
1442+
CHECK(r.ok);
1443+
CHECK(r.result.type == PythonCompiler::EvalResult::none);
1444+
r = e.evaluate2(R"(
1445+
def subi(x: i32, y: i32) -> i32:
1446+
return addi(x, -y)
1447+
)");
1448+
CHECK(r.ok);
1449+
CHECK(r.result.type == PythonCompiler::EvalResult::none);
1450+
r = e.evaluate2("addi(2, 3)");
1451+
CHECK(r.ok);
1452+
CHECK(r.result.type == PythonCompiler::EvalResult::integer4);
1453+
CHECK(r.result.i32 == 5);
1454+
r = e.evaluate2("subi(2, 3)");
1455+
CHECK(r.ok);
1456+
CHECK(r.result.type == PythonCompiler::EvalResult::integer4);
1457+
CHECK(r.result.i32 == -1);
1458+
}
1459+
1460+
TEST_CASE("PythonCompiler asr verify 4") {
1461+
CompilerOptions cu;
1462+
cu.po.disable_main = true;
1463+
cu.emit_debug_line_column = false;
1464+
cu.generate_object_code = false;
1465+
cu.interactive = true;
1466+
cu.po.runtime_library_dir = LCompilers::LPython::get_runtime_library_dir();
1467+
PythonCompiler e(cu);
1468+
LCompilers::Result<PythonCompiler::EvalResult>
1469+
1470+
r = e.evaluate2(R"(
1471+
def addr(x: f64, y: f64) -> f64:
1472+
return x + y
1473+
)");
1474+
CHECK(r.ok);
1475+
CHECK(r.result.type == PythonCompiler::EvalResult::none);
1476+
r = e.evaluate2(R"(
1477+
def subr(x: f64, y: f64) -> f64:
1478+
return addr(x, -y)
1479+
)");
1480+
CHECK(r.ok);
1481+
CHECK(r.result.type == PythonCompiler::EvalResult::none);
1482+
r = e.evaluate2("addr(2.5, 3.5)");
1483+
CHECK(r.ok);
1484+
CHECK(r.result.type == PythonCompiler::EvalResult::real8);
1485+
CHECK(r.result.f64 == 6);
1486+
r = e.evaluate2("subr(2.5, 3.5)");
1487+
CHECK(r.ok);
1488+
CHECK(r.result.type == PythonCompiler::EvalResult::real8);
1489+
CHECK(r.result.f64 == -1);
1490+
}

src/runtime/lpython_builtin.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1143,4 +1143,3 @@ def list(s: str) -> list[str]:
11431143
for i in range(len(s)):
11441144
l.append(s[i])
11451145
return l
1146-

src/runtime/platform.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ def python_implementation() -> str:
22
return "LPython"
33

44
def python_version() -> str:
5-
return __LPYTHON_VERSION__
5+
return __LPYTHON_VERSION__

0 commit comments

Comments
 (0)