From affec92ce4891c873a73123d6d6e9947f35e6774 Mon Sep 17 00:00:00 2001 From: advik Date: Tue, 30 Jul 2024 15:49:33 +0530 Subject: [PATCH 1/3] Add freeing of heap structures at the end of scopes --- src/libasr/codegen/asr_to_llvm.cpp | 48 ++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index 5f94cfd379..9433ab924e 100644 --- a/src/libasr/codegen/asr_to_llvm.cpp +++ b/src/libasr/codegen/asr_to_llvm.cpp @@ -202,6 +202,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor std::unique_ptr set_api_sc; std::unique_ptr arr_descr; std::vector heap_arrays; + std::map lists; + std::map dictionaries; + std::map sets; std::map strings_to_be_allocated; // (array, size) Vec strings_to_be_deallocated; @@ -1120,6 +1123,18 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor // } } + inline void free_heap_structures() { + for (auto &value : lists) { + llvm_utils->free_data(value.first, value.second, module.get()); + } + for (auto &value : dictionaries) { + llvm_utils->free_data(value.first, value.second, module.get()); + } + for (auto &value : sets) { + llvm_utils->free_data(value.first, value.second, module.get()); + } + } + llvm::Function* _Allocate(bool realloc_lhs) { std::string func_name = "_lfortran_alloc"; if( realloc_lhs ) { @@ -1274,6 +1289,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm::Type* const_list_type = list_api->get_list_type(llvm_el_type, type_code, type_size); llvm::Value* const_list = builder0.CreateAlloca(const_list_type, nullptr, "const_list"); list_api->list_init(type_code, const_list, *module, x.n_args, x.n_args); + lists[const_list] = x.m_type; int64_t ptr_loads_copy = ptr_loads; for( size_t i = 0; i < x.n_args; i++ ) { if (is_argument_of_type_CPtr(x.m_args[i])) { @@ -1300,6 +1316,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor std::string key_type_code = ASRUtils::get_type_code(x_dict->m_key_type); std::string value_type_code = ASRUtils::get_type_code(x_dict->m_value_type); llvm_utils->dict_api->dict_init(key_type_code, value_type_code, const_dict, module.get(), x.n_keys); + dictionaries[const_dict] = x.m_type; int64_t ptr_loads_key = !LLVM::is_llvm_struct(x_dict->m_key_type); int64_t ptr_loads_value = !LLVM::is_llvm_struct(x_dict->m_value_type); int64_t ptr_loads_copy = ptr_loads; @@ -1325,6 +1342,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm_utils->set_set_api(x_set); std::string el_type_code = ASRUtils::get_type_code(x_set->m_type); llvm_utils->set_api->set_init(el_type_code, const_set, module.get(), x.n_elements); + sets[const_set] = x.m_type; int64_t ptr_loads_el = !LLVM::is_llvm_struct(x_set->m_type); int64_t ptr_loads_copy = ptr_loads; ptr_loads = ptr_loads_el; @@ -2270,6 +2288,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor ptr_loads = 1; list_api->list_repeat_copy(repeat_list, left, right, left_len, module.get()); ptr_loads = ptr_loads_copy; + lists[repeat_list] = x.m_type; tmp = repeat_list; } @@ -3185,6 +3204,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor loop_or_block_end.clear(); loop_or_block_end_names.clear(); heap_arrays.clear(); + lists.clear(); + dictionaries.clear(); + sets.clear(); strings_to_be_deallocated.reserve(al, 1); SymbolTable* current_scope_copy = current_scope; current_scope = x.m_symtab; @@ -3260,6 +3282,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor LLVM::lfortran_free(context, *module, *builder, value); } call_lcompilers_free_strings(); + free_heap_structures(); llvm::Value *ret_val2 = llvm::ConstantInt::get(context, llvm::APInt(32, 0)); @@ -3277,6 +3300,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor loop_or_block_end.clear(); loop_or_block_end_names.clear(); heap_arrays.clear(); + lists.clear(); + dictionaries.clear(); + sets.clear(); strings_to_be_deallocated.reserve(al, 1); } @@ -3875,6 +3901,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor ASR::List_t* asr_list = ASR::down_cast(v->m_type); std::string type_code = ASRUtils::get_type_code(asr_list->m_type); list_api->list_init(type_code, ptr, *module); + lists[ptr] = asr_list->m_type; } } } @@ -3955,6 +3982,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor loop_or_block_end.clear(); loop_or_block_end_names.clear(); heap_arrays.clear(); + lists.clear(); + dictionaries.clear(); + sets.clear(); strings_to_be_deallocated.reserve(al, 1); SymbolTable* current_scope_copy = current_scope; current_scope = x.m_symtab; @@ -3989,6 +4019,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor loop_or_block_end.clear(); loop_or_block_end_names.clear(); heap_arrays.clear(); + sets.clear(); + dictionaries.clear(); + lists.clear(); strings_to_be_deallocated.reserve(al, 1); } @@ -4139,6 +4172,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor ret_val2 = tmp; } } + free_heap_structures(); for( auto& value: heap_arrays ) { LLVM::lfortran_free(context, *module, *builder, value); } @@ -4146,6 +4180,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor builder->CreateRet(ret_val2); } else { start_new_block(proc_return); + free_heap_structures(); for( auto& value: heap_arrays ) { LLVM::lfortran_free(context, *module, *builder, value); } @@ -5416,6 +5451,15 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor std::vector heap_arrays_copy; heap_arrays_copy = heap_arrays; heap_arrays.clear(); + std::map lists_copy; + lists_copy = lists; + lists.clear(); + std::map dictionaries_copy; + dictionaries_copy = dictionaries; + dictionaries.clear(); + std::map sets_copy; + sets_copy = sets; + sets.clear(); if( x.m_label != -1 ) { if( llvm_goto_targets.find(x.m_label) == llvm_goto_targets.end() ) { llvm::BasicBlock *new_target = llvm::BasicBlock::Create(context, "goto_target"); @@ -5456,7 +5500,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor for( auto& value: heap_arrays ) { LLVM::lfortran_free(context, *module, *builder, value); } + free_heap_structures(); heap_arrays = heap_arrays_copy; + lists = lists_copy; + dictionaries = dictionaries_copy; + sets = sets_copy; if (block_terminator == nullptr) { // The previous block is not terminated --- terminate it by jumping // to blockend From 58066c35cd31ec1f6e1f7f018e8ce6133b04ab86 Mon Sep 17 00:00:00 2001 From: advik Date: Tue, 30 Jul 2024 16:56:22 +0530 Subject: [PATCH 2/3] Add assigned structures to tracer maps --- src/libasr/codegen/asr_to_llvm.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index 9433ab924e..b8838c449b 100644 --- a/src/libasr/codegen/asr_to_llvm.cpp +++ b/src/libasr/codegen/asr_to_llvm.cpp @@ -4846,6 +4846,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor list_api->list_deepcopy(value_list, target_list, value_asr_list, module.get(), name2memidx); + lists[target_list] = ASRUtils::expr_type(x.m_target); return ; } else if( is_target_tuple && is_value_tuple ) { int64_t ptr_loads_copy = ptr_loads; @@ -4914,6 +4915,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm_utils->set_dict_api(value_dict_type); llvm_utils->dict_api->dict_deepcopy(value_dict, target_dict, value_dict_type, module.get(), name2memidx); + dictionaries[target_dict] = ASRUtils::expr_type(x.m_target); return ; } else if( is_target_set && is_value_set ) { int64_t ptr_loads_copy = ptr_loads; @@ -4927,6 +4929,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm_utils->set_set_api(value_set_type); llvm_utils->set_api->set_deepcopy(value_set, target_set, value_set_type, module.get(), name2memidx); + sets[target_set] = ASRUtils::expr_type(x.m_target); return ; } else if( is_target_struct && is_value_struct ) { int64_t ptr_loads_copy = ptr_loads; From 757181c01b535a9c950cd90b36e56652b3f7a603 Mon Sep 17 00:00:00 2001 From: advik Date: Fri, 9 Aug 2024 17:45:39 +0530 Subject: [PATCH 3/3] Remove return value freeing --- src/libasr/codegen/asr_to_llvm.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index b8838c449b..e12fd4e87b 100644 --- a/src/libasr/codegen/asr_to_llvm.cpp +++ b/src/libasr/codegen/asr_to_llvm.cpp @@ -3793,6 +3793,14 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } } + if (ASR::is_a(*v->m_type)) { + lists[ptr] = v->m_type; + } else if (ASR::is_a(*v->m_type)) { + dictionaries[ptr] = v->m_type; + } else if (ASR::is_a(*v->m_type)) { + sets[ptr] = v->m_type; + } + llvm_symtab[h] = ptr; if( (ASRUtils::is_array(v->m_type) && ((ASRUtils::extract_physical_type(v->m_type) == ASR::array_physical_typeType::DescriptorArray) || @@ -3901,7 +3909,6 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor ASR::List_t* asr_list = ASR::down_cast(v->m_type); std::string type_code = ASRUtils::get_type_code(asr_list->m_type); list_api->list_init(type_code, ptr, *module); - lists[ptr] = asr_list->m_type; } } } @@ -4172,6 +4179,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor ret_val2 = tmp; } } + lists.erase(ret_val); + dictionaries.erase(ret_val); + sets.erase(ret_val); free_heap_structures(); for( auto& value: heap_arrays ) { LLVM::lfortran_free(context, *module, *builder, value); @@ -4846,7 +4856,6 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor list_api->list_deepcopy(value_list, target_list, value_asr_list, module.get(), name2memidx); - lists[target_list] = ASRUtils::expr_type(x.m_target); return ; } else if( is_target_tuple && is_value_tuple ) { int64_t ptr_loads_copy = ptr_loads; @@ -4915,7 +4924,6 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm_utils->set_dict_api(value_dict_type); llvm_utils->dict_api->dict_deepcopy(value_dict, target_dict, value_dict_type, module.get(), name2memidx); - dictionaries[target_dict] = ASRUtils::expr_type(x.m_target); return ; } else if( is_target_set && is_value_set ) { int64_t ptr_loads_copy = ptr_loads; @@ -4929,7 +4937,6 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm_utils->set_set_api(value_set_type); llvm_utils->set_api->set_deepcopy(value_set, target_set, value_set_type, module.get(), name2memidx); - sets[target_set] = ASRUtils::expr_type(x.m_target); return ; } else if( is_target_struct && is_value_struct ) { int64_t ptr_loads_copy = ptr_loads;