@@ -2983,15 +2983,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
2983
2983
this ->visit_expr (*x.m_value );
2984
2984
llvm::Value* value_list = tmp;
2985
2985
ptr_loads = ptr_loads_copy;
2986
- if (ASR::is_a<ASR::FunctionCall_t>(*x.m_value )) {
2987
- builder->CreateStore (value_list, target_list);
2988
- } else {
2989
- ASR::List_t* value_asr_list = ASR::down_cast<ASR::List_t>(
2990
- ASRUtils::expr_type (x.m_value ));
2991
- std::string value_type_code = ASRUtils::get_type_code (value_asr_list->m_type );
2992
- list_api->list_deepcopy (value_list, target_list,
2993
- value_asr_list, *module );
2994
- }
2986
+ ASR::List_t* value_asr_list = ASR::down_cast<ASR::List_t>(
2987
+ ASRUtils::expr_type (x.m_value ));
2988
+ std::string value_type_code = ASRUtils::get_type_code (value_asr_list->m_type );
2989
+ list_api->list_deepcopy (value_list, target_list,
2990
+ value_asr_list, *module );
2995
2991
return ;
2996
2992
} else if ( is_target_tuple && is_value_tuple ) {
2997
2993
uint64_t ptr_loads_copy = ptr_loads;
@@ -3023,15 +3019,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
3023
3019
this ->visit_expr (*x.m_target );
3024
3020
llvm::Value* target_tuple = tmp;
3025
3021
ptr_loads = ptr_loads_copy;
3026
- if ( ASR::is_a<ASR::FunctionCall_t>(*x.m_value ) ) {
3027
- builder->CreateStore (value_tuple, target_tuple);
3028
- } else {
3029
- ASR::Tuple_t* value_tuple_type = ASR::down_cast<ASR::Tuple_t>(asr_value_type);
3030
- std::string type_code = ASRUtils::get_type_code (value_tuple_type->m_type ,
3031
- value_tuple_type->n_type );
3032
- tuple_api->tuple_deepcopy (value_tuple, target_tuple,
3033
- value_tuple_type, *module );
3034
- }
3022
+ ASR::Tuple_t* value_tuple_type = ASR::down_cast<ASR::Tuple_t>(asr_value_type);
3023
+ std::string type_code = ASRUtils::get_type_code (value_tuple_type->m_type ,
3024
+ value_tuple_type->n_type );
3025
+ tuple_api->tuple_deepcopy (value_tuple, target_tuple,
3026
+ value_tuple_type, *module );
3035
3027
}
3036
3028
return ;
3037
3029
}
@@ -5222,6 +5214,41 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
5222
5214
tmp = builder->CreateOr (arg1, arg2);
5223
5215
}
5224
5216
5217
+ llvm::Value* CreatePointerToStructReturnValue (llvm::FunctionType* fnty,
5218
+ llvm::Value* return_value,
5219
+ ASR::ttype_t * asr_return_type) {
5220
+ if ( !LLVM::is_llvm_struct (asr_return_type) ) {
5221
+ return return_value;
5222
+ }
5223
+
5224
+ // Call to LLVM APIs not needed to fetch the return type of the function.
5225
+ // We can use asr_return_type as well but anyways for compactness I did it here.
5226
+ llvm::Value* pointer_to_struct = builder->CreateAlloca (fnty->getReturnType (), nullptr );
5227
+ LLVM::CreateStore (*builder, return_value, pointer_to_struct);
5228
+ return pointer_to_struct;
5229
+ }
5230
+
5231
+ llvm::Value* CreateCallUtil (llvm::FunctionType* fnty, llvm::Value* fn,
5232
+ std::vector<llvm::Value*>& args,
5233
+ ASR::ttype_t * asr_return_type) {
5234
+ llvm::Value* return_value = builder->CreateCall (fnty, fn, args);
5235
+ return CreatePointerToStructReturnValue (fnty, return_value,
5236
+ asr_return_type);
5237
+ }
5238
+
5239
+ llvm::Value* CreateCallUtil (llvm::FunctionType* fnty, llvm::Function* fn,
5240
+ std::vector<llvm::Value*>& args,
5241
+ ASR::ttype_t * asr_return_type) {
5242
+ llvm::Value* return_value = builder->CreateCall (fn, args);
5243
+ return CreatePointerToStructReturnValue (fnty, return_value,
5244
+ asr_return_type);
5245
+ }
5246
+
5247
+ llvm::Value* CreateCallUtil (llvm::Function* fn, std::vector<llvm::Value*>& args,
5248
+ ASR::ttype_t * asr_return_type) {
5249
+ return CreateCallUtil (fn->getFunctionType (), fn, args, asr_return_type);
5250
+ }
5251
+
5225
5252
void visit_FunctionCall (const ASR::FunctionCall_t &x) {
5226
5253
if ( ASRUtils::is_intrinsic_optimization (x.m_name ) ) {
5227
5254
ASR::Function_t* routine = ASR::down_cast<ASR::Function_t>(
@@ -5306,7 +5333,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
5306
5333
llvm::FunctionType* fntype = llvm_symtab_fn[h]->getFunctionType ();
5307
5334
std::string m_name = std::string (((ASR::Function_t*)(&(x.m_name ->base )))->m_name );
5308
5335
args = convert_call_args (x, m_name);
5309
- tmp = builder-> CreateCall (fntype, fn, args);
5336
+ tmp = CreateCallUtil (fntype, fn, args, x. m_type );
5310
5337
} else if (llvm_symtab_fn.find (h) == llvm_symtab_fn.end ()) {
5311
5338
throw CodeGenError (" Function code not generated for '"
5312
5339
+ std::string (s->m_name ) + " '" );
@@ -5315,8 +5342,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
5315
5342
std::string m_name = std::string (((ASR::Function_t*)(&(x.m_name ->base )))->m_name );
5316
5343
std::vector<llvm::Value *> args2 = convert_call_args (x, m_name);
5317
5344
args.insert (args.end (), args2.begin (), args2.end ());
5345
+ ASR::ttype_t *return_var_type0 = EXPR2VAR (s->m_return_var )->m_type ;
5318
5346
if (s->m_abi == ASR::abiType::BindC) {
5319
- ASR::ttype_t *return_var_type0 = EXPR2VAR (s->m_return_var )->m_type ;
5320
5347
if (is_a<ASR::Complex_t>(*return_var_type0)) {
5321
5348
int a_kind = down_cast<ASR::Complex_t>(return_var_type0)->m_kind ;
5322
5349
if (a_kind == 8 ) {
@@ -5337,6 +5364,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
5337
5364
}
5338
5365
} else {
5339
5366
tmp = builder->CreateCall (fn, args);
5367
+ tmp = CreateCallUtil (fn, args, return_var_type0);
5340
5368
}
5341
5369
}
5342
5370
if (s->m_abi == ASR::abiType::BindC) {
0 commit comments