Skip to content

Commit

Permalink
changes made according to code review
Browse files Browse the repository at this point in the history
  • Loading branch information
Vipul-Cariappa committed Jul 5, 2024
1 parent b88d1bf commit c5d256e
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 63 deletions.
4 changes: 2 additions & 2 deletions src/bin/lpython.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1006,14 +1006,14 @@ int interactive_python_repl(
}
break;
}
case (LCompilers::PythonCompiler::EvalResult::structt) : {
case (LCompilers::PythonCompiler::EvalResult::struct_type) : {
if (verbose) {
std::cout << "Return type: "
<< LCompilers::ASRUtils::get_type_code(r.structure.ttype)
<< std::endl;
}
if (verbose) section("Result:");
std::cout << fe.string_aggregate_type(r) << std::endl;
std::cout << fe.aggregate_type_to_string(r) << std::endl;
break;
}
case (LCompilers::PythonCompiler::EvalResult::none) : {
Expand Down
21 changes: 0 additions & 21 deletions src/libasr/pass/global_stmts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,27 +102,6 @@ void pass_wrap_global_stmts(Allocator &al,
unit.m_symtab->add_symbol(global_underscore_name, down_cast<ASR::symbol_t>(global_underscore));
ASR::stmt_t* asr_stmt = ASRUtils::STMT(ASR::make_Assignment_t(al, loc, global_underscore_ref, return_var_ref, nullptr));
body.push_back(al, asr_stmt);

// if ((type->type == ASR::ttypeType::Tuple) ||
// (type->type == ASR::ttypeType::List)) {
// s.from_str(al, fn_name_s + std::to_string(idx));
// var_name = s.c_str(al);

// ASR::ttype_t *type_pointer = ASRUtils::TYPE(ASR::make_Pointer_t(al, loc, type));
// ASR::expr_t *value = EXPR(ASR::make_GetPointer_t(al, loc, global_underscore_ref, type_pointer, nullptr));

// return_var = ASR::make_Variable_t(al, loc,
// fn_scope, var_name, nullptr, 0, ASRUtils::intent_local, nullptr, nullptr,
// ASR::storage_typeType::Default, type_pointer,
// nullptr, ASR::abiType::BindC,
// ASR::Public, ASR::presenceType::Required, false);
// return_var_ref = EXPR(ASR::make_Var_t(al, loc, down_cast<ASR::symbol_t>(return_var)));
// ASR::stmt_t* asr_stmt = ASRUtils::STMT(ASR::make_Assignment_t(al, loc, return_var_ref, value, nullptr));
// body.push_back(al, asr_stmt);
// idx++;
// return_var_ref = nullptr;
// return_var = nullptr;
// }
}

ASR::asr_t *fn = ASRUtils::make_Function_t_util(
Expand Down
71 changes: 41 additions & 30 deletions src/lpython/python_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,35 +127,19 @@ Result<PythonCompiler::EvalResult> PythonCompiler::evaluate(
call_run_fn = true;
}

llvm::Type *type = nullptr;
ASR::symbol_t *f = symbol_table->get_symbol("_" + run_fn);
if ((return_type == "struct") && (f)) {
llvm::Function *fn = m->get_function(run_fn);
type = fn->getReturnType();
LCOMPILERS_ASSERT(type->isStructTy())
ASR::symbol_t *global_underscore_sym = symbol_table->get_symbol("_" + run_fn);
if ((return_type == "struct") && (global_underscore_sym)) {
// we compute the offsets of the struct's attribute here
// we will be using it later in aggregate_type_to_string to print the struct

const llvm::DataLayout &dl = e->get_jit_data_layout();
size_t elements_count = type->getStructNumElements();
LCompilers::Vec<size_t> offsets;
offsets.reserve(al, elements_count);
for (size_t i = 0; i < elements_count; i++) {
size_t offset = dl.getStructLayout((llvm::StructType*)type)->getElementOffset(i);
offsets.push_back(al, offset);
}
result.structure.offsets = offsets.p;
// we compute the offsets here instead of computing it in aggregate_type_to_string
// because once we call `e->add_module`, internally LLVM may deallocate all the
// type info after compiling the IR into machine code

result.structure.ttype = ASR::down_cast<ASR::Variable_t>(f)->m_type;
if (result.structure.ttype->type == ASR::ttypeType::List) {
type = type->getStructElementType(2);
LCOMPILERS_ASSERT(type->isPointerTy())
result.structure.element_size = e->get_jit_data_layout().getTypeAllocSize(
#if LLVM_VERSION_MAJOR >= 14
type->getNonOpaquePointerElementType()
#else
type->getPointerElementType()
#endif
);
}
llvm::Function *fn = m->get_function(run_fn);
llvm::Type *llvm_type = fn->getReturnType();
LCOMPILERS_ASSERT(llvm_type->isStructTy())
compute_offsets(llvm_type, global_underscore_sym, result);
}

e->add_module(std::move(m));
Expand Down Expand Up @@ -247,11 +231,11 @@ Result<PythonCompiler::EvalResult> PythonCompiler::evaluate(
result.b = r;
} else if (return_type == "struct") {
e->execfn<void>(run_fn);
if (f) {
if (global_underscore_sym) {
void *r = (void*)e->get_symbol_address("_" + run_fn);
LCOMPILERS_ASSERT(r)
result.structure.structure = r;
result.type = EvalResult::structt;
result.type = EvalResult::struct_type;
}
} else if (return_type == "void") {
e->execfn<void>(run_fn);
Expand Down Expand Up @@ -362,7 +346,7 @@ Result<std::unique_ptr<LLVMModule>> PythonCompiler::get_llvm3(

void print_type(ASR::ttype_t *t, void *data, std::string &result);

std::string PythonCompiler::string_aggregate_type(const struct EvalResult &r) {
std::string PythonCompiler::aggregate_type_to_string(const struct EvalResult &r) {
ASR::ttype_t *asr_type = r.structure.ttype;
void *data = r.structure.structure;
size_t *offsets = r.structure.offsets;
Expand Down Expand Up @@ -392,6 +376,33 @@ std::string PythonCompiler::string_aggregate_type(const struct EvalResult &r) {
return result;
}

void PythonCompiler::compute_offsets(llvm::Type *type, ASR::symbol_t *asr_type, EvalResult &result) {
LCOMPILERS_ASSERT(type->isStructTy())

const llvm::DataLayout &dl = e->get_jit_data_layout();
size_t elements_count = type->getStructNumElements();
LCompilers::Vec<size_t> offsets;
offsets.reserve(al, elements_count);
for (size_t i = 0; i < elements_count; i++) {
size_t offset = dl.getStructLayout((llvm::StructType*)type)->getElementOffset(i);
offsets.push_back(al, offset);
}
result.structure.offsets = offsets.p;

result.structure.ttype = ASR::down_cast<ASR::Variable_t>(asr_type)->m_type;
if (result.structure.ttype->type == ASR::ttypeType::List) {
type = type->getStructElementType(2);
LCOMPILERS_ASSERT(type->isPointerTy())
result.structure.element_size = e->get_jit_data_layout().getTypeAllocSize(
#if LLVM_VERSION_MAJOR >= 14
type->getNonOpaquePointerElementType()
#else
type->getPointerElementType()
#endif
);
}
}

void print_type(ASR::ttype_t *t, void *data, std::string &result) {
switch (t->type) {
case ASR::ttypeType::Logical:
Expand Down
11 changes: 9 additions & 2 deletions src/lpython/python_evaluator.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
#include <libasr/diagnostics.h>
#include <libasr/pass/pass_manager.h>

namespace llvm {
class Type;
}

namespace LCompilers {

class LLVMModule;
Expand Down Expand Up @@ -51,7 +55,7 @@ class PythonCompiler
complex8,
boolean,
string,
structt,
struct_type,
statement,
none
} type;
Expand Down Expand Up @@ -95,7 +99,10 @@ class PythonCompiler
LCompilers::PassManager& lpm, diag::Diagnostics &diagnostics,
const std::string &infile);

std::string string_aggregate_type(const struct EvalResult &r);
std::string aggregate_type_to_string(const struct EvalResult &r);

private:
void compute_offsets(llvm::Type *type, ASR::symbol_t *asr_type, EvalResult &result);

private:
Allocator al;
Expand Down
16 changes: 8 additions & 8 deletions src/lpython/tests/test_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1479,31 +1479,31 @@ TEST_CASE("PythonCompiler lists") {

r = e.evaluate2("[1, 2, 3]");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::structt);
CHECK(r.result.type == PythonCompiler::EvalResult::struct_type);
CHECK(LCompilers::ASRUtils::get_type_code(r.result.structure.ttype) == "list[i32]");
CHECK(e.string_aggregate_type(r.result) == "[1, 2, 3]");
CHECK(e.aggregate_type_to_string(r.result) == "[1, 2, 3]");

r = e.evaluate2("[u8(1), u8(2), u8(3)] + [u8(1), u8(2), u8(3)]");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::structt);
CHECK(r.result.type == PythonCompiler::EvalResult::struct_type);
CHECK(LCompilers::ASRUtils::get_type_code(r.result.structure.ttype) == "list[u8]");
CHECK(e.string_aggregate_type(r.result) == "[1, 2, 3, 1, 2, 3]");
CHECK(e.aggregate_type_to_string(r.result) == "[1, 2, 3, 1, 2, 3]");

r = e.evaluate2("x: list[f64] = [1.5, 2.5, 3.5]");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::statement);

r = e.evaluate2("x + [4.5]");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::structt);
CHECK(r.result.type == PythonCompiler::EvalResult::struct_type);
CHECK(LCompilers::ASRUtils::get_type_code(r.result.structure.ttype) == "list[r64]");
CHECK(e.string_aggregate_type(r.result) == "[1.500000, 2.500000, 3.500000, 4.500000]");
CHECK(e.aggregate_type_to_string(r.result) == "[1.500000, 2.500000, 3.500000, 4.500000]");

r = e.evaluate2("[\"lfortran\", \"lpython\", \"lc\"]");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::structt);
CHECK(r.result.type == PythonCompiler::EvalResult::struct_type);
CHECK(LCompilers::ASRUtils::get_type_code(r.result.structure.ttype) == "list[str]");
CHECK(e.string_aggregate_type(r.result) == "[\"lfortran\", \"lpython\", \"lc\"]");
CHECK(e.aggregate_type_to_string(r.result) == "[\"lfortran\", \"lpython\", \"lc\"]");
}

TEST_CASE("PythonCompiler asr verify 1") {
Expand Down

0 comments on commit c5d256e

Please sign in to comment.