Skip to content

Commit 99864c1

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 584cf5a commit 99864c1

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
@@ -1131,10 +1131,19 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
11311131

11321132
void visit_ListConstant(const ASR::ListConstant_t& x) {
11331133
ASR::List_t* list_type = ASR::down_cast<ASR::List_t>(x.m_type);
1134-
llvm::Type* llvm_el_type = get_el_type(list_type->m_type);
1134+
bool is_array_type_local = false, is_malloc_array_type_local = false;
1135+
bool is_list_local = false;
1136+
ASR::dimension_t* m_dims_local = nullptr;
1137+
int n_dims_local = -1, a_kind_local = -1;
1138+
llvm::Type* llvm_el_type = get_type_from_ttype_t(list_type->m_type,
1139+
ASR::storage_typeType::Default, is_array_type_local,
1140+
is_malloc_array_type_local, is_list_local, m_dims_local,
1141+
n_dims_local, a_kind_local);
11351142
std::string type_code = ASRUtils::get_type_code(list_type->m_type);
11361143
int32_t type_size = -1;
1137-
if( ASR::is_a<ASR::Character_t>(*list_type->m_type) ) {
1144+
if( ASR::is_a<ASR::Character_t>(*list_type->m_type) ||
1145+
LLVM::is_llvm_struct(list_type->m_type) ||
1146+
ASR::is_a<ASR::Complex_t>(*list_type->m_type) ) {
11381147
llvm::DataLayout data_layout(module.get());
11391148
type_size = data_layout.getTypeAllocSize(llvm_el_type);
11401149
} else {
@@ -2603,6 +2612,31 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
26032612
return_type = tuple_api->get_tuple_type(type_code, llvm_el_types);
26042613
break;
26052614
}
2615+
case (ASR::ttypeType::List) : {
2616+
bool is_array_type = false, is_malloc_array_type = false;
2617+
bool is_list = true;
2618+
ASR::dimension_t *m_dims = nullptr;
2619+
ASR::storage_typeType m_storage = ASR::storage_typeType::Default;
2620+
int n_dims = 0, a_kind = -1;
2621+
ASR::List_t* asr_list = ASR::down_cast<ASR::List_t>(return_var_type0);
2622+
llvm::Type* el_llvm_type = get_type_from_ttype_t(asr_list->m_type, m_storage,
2623+
is_array_type,
2624+
is_malloc_array_type,
2625+
is_list, m_dims, n_dims,
2626+
a_kind);
2627+
int32_t type_size = -1;
2628+
if( LLVM::is_llvm_struct(asr_list->m_type) ||
2629+
ASR::is_a<ASR::Character_t>(*asr_list->m_type) ||
2630+
ASR::is_a<ASR::Complex_t>(*asr_list->m_type) ) {
2631+
llvm::DataLayout data_layout(module.get());
2632+
type_size = data_layout.getTypeAllocSize(el_llvm_type);
2633+
} else {
2634+
type_size = a_kind;
2635+
}
2636+
std::string el_type_code = ASRUtils::get_type_code(asr_list->m_type);
2637+
return_type = list_api->get_list_type(el_llvm_type, el_type_code, type_size);
2638+
break;
2639+
}
26062640
default :
26072641
LFORTRAN_ASSERT(false);
26082642
throw CodeGenError("Type not implemented");
@@ -3003,15 +3037,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
30033037
this->visit_expr(*x.m_target);
30043038
llvm::Value* target_tuple = tmp;
30053039
ptr_loads = ptr_loads_copy;
3006-
if( ASR::is_a<ASR::FunctionCall_t>(*x.m_value) ) {
3007-
builder->CreateStore(value_tuple, target_tuple);
3008-
} else {
3009-
ASR::Tuple_t* value_tuple_type = ASR::down_cast<ASR::Tuple_t>(asr_value_type);
3010-
std::string type_code = ASRUtils::get_type_code(value_tuple_type->m_type,
3011-
value_tuple_type->n_type);
3012-
tuple_api->tuple_deepcopy(value_tuple, target_tuple,
3013-
value_tuple_type, *module);
3014-
}
3040+
ASR::Tuple_t* value_tuple_type = ASR::down_cast<ASR::Tuple_t>(asr_value_type);
3041+
std::string type_code = ASRUtils::get_type_code(value_tuple_type->m_type,
3042+
value_tuple_type->n_type);
3043+
tuple_api->tuple_deepcopy(value_tuple, target_tuple,
3044+
value_tuple_type, *module);
30153045
}
30163046
return ;
30173047
}
@@ -5202,6 +5232,33 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
52025232
tmp = builder->CreateOr(arg1, arg2);
52035233
}
52045234

5235+
llvm::Value* CreatePointerToStructReturnValue(llvm::FunctionType* fnty,
5236+
llvm::Value* return_value,
5237+
ASR::ttype_t* asr_return_type) {
5238+
if( !LLVM::is_llvm_struct(asr_return_type) ) {
5239+
return return_value;
5240+
}
5241+
5242+
// Call to LLVM APIs not needed to fetch the return type of the function.
5243+
// We can use asr_return_type as well but anyways for compactness I did it here.
5244+
llvm::Value* pointer_to_struct = builder->CreateAlloca(fnty->getReturnType(), nullptr);
5245+
LLVM::CreateStore(*builder, return_value, pointer_to_struct);
5246+
return pointer_to_struct;
5247+
}
5248+
5249+
llvm::Value* CreateCallUtil(llvm::FunctionType* fnty, llvm::Function* fn,
5250+
std::vector<llvm::Value*>& args,
5251+
ASR::ttype_t* asr_return_type) {
5252+
llvm::Value* return_value = builder->CreateCall(fn, args);
5253+
return CreatePointerToStructReturnValue(fnty, return_value,
5254+
asr_return_type);
5255+
}
5256+
5257+
llvm::Value* CreateCallUtil(llvm::Function* fn, std::vector<llvm::Value*>& args,
5258+
ASR::ttype_t* asr_return_type) {
5259+
return CreateCallUtil(fn->getFunctionType(), fn, args, asr_return_type);
5260+
}
5261+
52055262
void visit_FunctionCall(const ASR::FunctionCall_t &x) {
52065263
if( ASRUtils::is_intrinsic_optimization(x.m_name) ) {
52075264
ASR::Function_t* routine = ASR::down_cast<ASR::Function_t>(
@@ -5295,8 +5352,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
52955352
std::string m_name = std::string(((ASR::Function_t*)(&(x.m_name->base)))->m_name);
52965353
std::vector<llvm::Value *> args2 = convert_call_args(x, m_name);
52975354
args.insert(args.end(), args2.begin(), args2.end());
5355+
ASR::ttype_t *return_var_type0 = EXPR2VAR(s->m_return_var)->m_type;
52985356
if (s->m_abi == ASR::abiType::BindC) {
5299-
ASR::ttype_t *return_var_type0 = EXPR2VAR(s->m_return_var)->m_type;
53005357
if (is_a<ASR::Complex_t>(*return_var_type0)) {
53015358
int a_kind = down_cast<ASR::Complex_t>(return_var_type0)->m_kind;
53025359
if (a_kind == 8) {
@@ -5316,7 +5373,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
53165373
tmp = builder->CreateCall(fn, args);
53175374
}
53185375
} else {
5319-
tmp = builder->CreateCall(fn, args);
5376+
tmp = CreateCallUtil(fn, args, return_var_type0);
53205377
}
53215378
}
53225379
if (s->m_abi == ASR::abiType::BindC) {

0 commit comments

Comments
 (0)