diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index 5f94cfd379..e12fd4e87b 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); } @@ -3767,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) || @@ -3955,6 +3989,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 +4026,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 +4179,10 @@ 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); } @@ -4146,6 +4190,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 +5461,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 +5510,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