Skip to content

Commit 71e062e

Browse files
Following changes have been made,
1. Generate correct LLVM type for ListConstant 2. Handle lists as return type Co-authored-by: Smit Lunagariya <smitlunagariya.mat18@itbhu.ac.in>
1 parent fac8de7 commit 71e062e

File tree

1 file changed

+70
-13
lines changed

1 file changed

+70
-13
lines changed

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 70 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,10 +1134,19 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
11341134

11351135
void visit_ListConstant(const ASR::ListConstant_t& x) {
11361136
ASR::List_t* list_type = ASR::down_cast<ASR::List_t>(x.m_type);
1137-
llvm::Type* llvm_el_type = get_el_type(list_type->m_type);
1137+
bool is_array_type_local = false, is_malloc_array_type_local = false;
1138+
bool is_list_local = false;
1139+
ASR::dimension_t* m_dims_local = nullptr;
1140+
int n_dims_local = -1, a_kind_local = -1;
1141+
llvm::Type* llvm_el_type = get_type_from_ttype_t(list_type->m_type,
1142+
ASR::storage_typeType::Default, is_array_type_local,
1143+
is_malloc_array_type_local, is_list_local, m_dims_local,
1144+
n_dims_local, a_kind_local);
11381145
std::string type_code = ASRUtils::get_type_code(list_type->m_type);
11391146
int32_t type_size = -1;
1140-
if( ASR::is_a<ASR::Character_t>(*list_type->m_type) ) {
1147+
if( ASR::is_a<ASR::Character_t>(*list_type->m_type) ||
1148+
LLVM::is_llvm_struct(list_type->m_type) ||
1149+
ASR::is_a<ASR::Complex_t>(*list_type->m_type) ) {
11411150
llvm::DataLayout data_layout(module.get());
11421151
type_size = data_layout.getTypeAllocSize(llvm_el_type);
11431152
} else {
@@ -2720,6 +2729,31 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
27202729
return_type = tuple_api->get_tuple_type(type_code, llvm_el_types);
27212730
break;
27222731
}
2732+
case (ASR::ttypeType::List) : {
2733+
bool is_array_type = false, is_malloc_array_type = false;
2734+
bool is_list = true;
2735+
ASR::dimension_t *m_dims = nullptr;
2736+
ASR::storage_typeType m_storage = ASR::storage_typeType::Default;
2737+
int n_dims = 0, a_kind = -1;
2738+
ASR::List_t* asr_list = ASR::down_cast<ASR::List_t>(return_var_type0);
2739+
llvm::Type* el_llvm_type = get_type_from_ttype_t(asr_list->m_type, m_storage,
2740+
is_array_type,
2741+
is_malloc_array_type,
2742+
is_list, m_dims, n_dims,
2743+
a_kind);
2744+
int32_t type_size = -1;
2745+
if( LLVM::is_llvm_struct(asr_list->m_type) ||
2746+
ASR::is_a<ASR::Character_t>(*asr_list->m_type) ||
2747+
ASR::is_a<ASR::Complex_t>(*asr_list->m_type) ) {
2748+
llvm::DataLayout data_layout(module.get());
2749+
type_size = data_layout.getTypeAllocSize(el_llvm_type);
2750+
} else {
2751+
type_size = a_kind;
2752+
}
2753+
std::string el_type_code = ASRUtils::get_type_code(asr_list->m_type);
2754+
return_type = list_api->get_list_type(el_llvm_type, el_type_code, type_size);
2755+
break;
2756+
}
27232757
default :
27242758
LFORTRAN_ASSERT(false);
27252759
throw CodeGenError("Type not implemented");
@@ -3122,15 +3156,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
31223156
this->visit_expr(*x.m_target);
31233157
llvm::Value* target_tuple = tmp;
31243158
ptr_loads = ptr_loads_copy;
3125-
if( ASR::is_a<ASR::FunctionCall_t>(*x.m_value) ) {
3126-
builder->CreateStore(value_tuple, target_tuple);
3127-
} else {
3128-
ASR::Tuple_t* value_tuple_type = ASR::down_cast<ASR::Tuple_t>(asr_value_type);
3129-
std::string type_code = ASRUtils::get_type_code(value_tuple_type->m_type,
3130-
value_tuple_type->n_type);
3131-
tuple_api->tuple_deepcopy(value_tuple, target_tuple,
3132-
value_tuple_type, *module);
3133-
}
3159+
ASR::Tuple_t* value_tuple_type = ASR::down_cast<ASR::Tuple_t>(asr_value_type);
3160+
std::string type_code = ASRUtils::get_type_code(value_tuple_type->m_type,
3161+
value_tuple_type->n_type);
3162+
tuple_api->tuple_deepcopy(value_tuple, target_tuple,
3163+
value_tuple_type, *module);
31343164
}
31353165
return ;
31363166
} else if( is_target_dict && is_value_dict ) {
@@ -5333,6 +5363,33 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
53335363
tmp = builder->CreateOr(arg1, arg2);
53345364
}
53355365

5366+
llvm::Value* CreatePointerToStructReturnValue(llvm::FunctionType* fnty,
5367+
llvm::Value* return_value,
5368+
ASR::ttype_t* asr_return_type) {
5369+
if( !LLVM::is_llvm_struct(asr_return_type) ) {
5370+
return return_value;
5371+
}
5372+
5373+
// Call to LLVM APIs not needed to fetch the return type of the function.
5374+
// We can use asr_return_type as well but anyways for compactness I did it here.
5375+
llvm::Value* pointer_to_struct = builder->CreateAlloca(fnty->getReturnType(), nullptr);
5376+
LLVM::CreateStore(*builder, return_value, pointer_to_struct);
5377+
return pointer_to_struct;
5378+
}
5379+
5380+
llvm::Value* CreateCallUtil(llvm::FunctionType* fnty, llvm::Function* fn,
5381+
std::vector<llvm::Value*>& args,
5382+
ASR::ttype_t* asr_return_type) {
5383+
llvm::Value* return_value = builder->CreateCall(fn, args);
5384+
return CreatePointerToStructReturnValue(fnty, return_value,
5385+
asr_return_type);
5386+
}
5387+
5388+
llvm::Value* CreateCallUtil(llvm::Function* fn, std::vector<llvm::Value*>& args,
5389+
ASR::ttype_t* asr_return_type) {
5390+
return CreateCallUtil(fn->getFunctionType(), fn, args, asr_return_type);
5391+
}
5392+
53365393
void visit_FunctionCall(const ASR::FunctionCall_t &x) {
53375394
if( ASRUtils::is_intrinsic_optimization(x.m_name) ) {
53385395
ASR::Function_t* routine = ASR::down_cast<ASR::Function_t>(
@@ -5426,8 +5483,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
54265483
std::string m_name = std::string(((ASR::Function_t*)(&(x.m_name->base)))->m_name);
54275484
std::vector<llvm::Value *> args2 = convert_call_args(x, m_name);
54285485
args.insert(args.end(), args2.begin(), args2.end());
5486+
ASR::ttype_t *return_var_type0 = EXPR2VAR(s->m_return_var)->m_type;
54295487
if (s->m_abi == ASR::abiType::BindC) {
5430-
ASR::ttype_t *return_var_type0 = EXPR2VAR(s->m_return_var)->m_type;
54315488
if (is_a<ASR::Complex_t>(*return_var_type0)) {
54325489
int a_kind = down_cast<ASR::Complex_t>(return_var_type0)->m_kind;
54335490
if (a_kind == 8) {
@@ -5447,7 +5504,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
54475504
tmp = builder->CreateCall(fn, args);
54485505
}
54495506
} else {
5450-
tmp = builder->CreateCall(fn, args);
5507+
tmp = CreateCallUtil(fn, args, return_var_type0);
54515508
}
54525509
}
54535510
if (s->m_abi == ASR::abiType::BindC) {

0 commit comments

Comments
 (0)