Skip to content

Commit

Permalink
Changes for supporting global array pointers in LLVM (lcompilers#1705)
Browse files Browse the repository at this point in the history
* Changes from lfortran/lfortran#1540

* Add header gaurds in src/libasr/pass/intrinsic_function_registry.h
  • Loading branch information
czgdp1807 authored Apr 13, 2023
1 parent 82a8376 commit a1fff8b
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 7 deletions.
12 changes: 12 additions & 0 deletions src/libasr/asr_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -1589,6 +1589,12 @@ static inline bool is_fixed_size_array(ASR::dimension_t* m_dims, size_t n_dims)
return true;
}

static inline bool is_fixed_size_array(ASR::ttype_t* type) {
ASR::dimension_t* m_dims = nullptr;
size_t n_dims = ASRUtils::extract_dimensions_from_ttype(type, m_dims);
return ASRUtils::is_fixed_size_array(m_dims, n_dims);
}

static inline int64_t get_fixed_size_of_array(ASR::dimension_t* m_dims, size_t n_dims) {
if( n_dims == 0 ) {
return 0;
Expand Down Expand Up @@ -2350,6 +2356,12 @@ static inline bool is_dimension_empty(ASR::dimension_t* dims, size_t n) {
return false;
}

static inline bool is_data_only_array(ASR::ttype_t* type, ASR::abiType abi) {
ASR::dimension_t* m_dims = nullptr;
size_t n_dims = ASRUtils::extract_dimensions_from_ttype(type, m_dims);
return (abi == ASR::abiType::BindC || !ASRUtils::is_dimension_empty(m_dims, n_dims));
}

static inline void insert_module_dependency(ASR::symbol_t* a,
Allocator& al, SetChar& module_dependencies) {
if( ASR::is_a<ASR::ExternalSymbol_t>(*a) ) {
Expand Down
32 changes: 25 additions & 7 deletions src/libasr/codegen/asr_to_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2014,8 +2014,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
bool is_argument = false;
llvm::Value* array = nullptr;
bool is_data_only = false;
ASR::Variable_t *v = nullptr;
if( ASR::is_a<ASR::Var_t>(*x.m_v) ) {
ASR::Variable_t *v = ASRUtils::EXPR2VAR(x.m_v);
v = ASRUtils::EXPR2VAR(x.m_v);
if( ASR::is_a<ASR::Struct_t>(*ASRUtils::get_contained_type(v->m_type)) ) {
ASR::Struct_t* der_type = ASR::down_cast<ASR::Struct_t>(
ASRUtils::get_contained_type(v->m_type));
Expand Down Expand Up @@ -2114,7 +2115,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
bool is_polymorphic = current_select_type_block_type != nullptr;
tmp = arr_descr->get_single_element(array, indices, x.n_args,
is_data_only,
ASRUtils::is_fixed_size_array(m_dims, n_dims) && is_bindc_array,
ASRUtils::is_fixed_size_array(m_dims, n_dims)
&& (is_bindc_array ||
(v && ASR::is_a<ASR::Module_t>(*ASRUtils::get_asr_owner(&(v->base))) ) ),
llvm_diminfo.p, is_polymorphic, current_select_type_block_type);
}
}
Expand Down Expand Up @@ -3664,20 +3667,20 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
bool is_list = false;
ASR::dimension_t* m_dims = nullptr;
llvm::Type* key_llvm_type = get_type_from_ttype_t(asr_dict->m_key_type, m_storage,
is_array_type,
is_array_type,
is_malloc_array_type,
is_list, m_dims, n_dims,
a_kind, m_abi);
llvm::Type* value_llvm_type = get_type_from_ttype_t(asr_dict->m_value_type, m_storage,
is_array_type,
is_array_type,
is_malloc_array_type,
is_list, m_dims, n_dims,
a_kind, m_abi);
int32_t key_type_size = get_type_size(asr_dict->m_key_type, key_llvm_type, a_kind);
int32_t value_type_size = get_type_size(asr_dict->m_value_type, value_llvm_type, a_kind);
set_dict_api(asr_dict);
type = llvm_utils->dict_api->get_dict_type(key_type_code, value_type_code,
key_type_size, value_type_size,
type = llvm_utils->dict_api->get_dict_type(key_type_code, value_type_code,
key_type_size, value_type_size,
key_llvm_type, value_llvm_type)->getPointerTo();
break;
}
Expand Down Expand Up @@ -4128,7 +4131,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
ASR::Dict_t* asr_dict = ASR::down_cast<ASR::Dict_t>(return_var_type0);
std::string key_type_code = ASRUtils::get_type_code(asr_dict->m_key_type);
std::string value_type_code = ASRUtils::get_type_code(asr_dict->m_value_type);

bool is_local_array_type = false, is_local_malloc_array_type = false;
bool is_local_list = false;
ASR::dimension_t* local_m_dims = nullptr;
Expand Down Expand Up @@ -7143,6 +7146,13 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
if (llvm_symtab.find(h) != llvm_symtab.end()) {
tmp = llvm_symtab[h];
bool is_data_only_array = false;
bool is_pointer_to_non_pointer = false;
if( orig_arg &&
!ASR::is_a<ASR::Pointer_t>(*orig_arg->m_type) &&
ASR::is_a<ASR::Pointer_t>(*arg->m_type) ) {
tmp = LLVM::CreateLoad(*builder, tmp);
is_pointer_to_non_pointer = true;
}
ASR::dimension_t* dims_arg = nullptr;
size_t n_arg = ASRUtils::extract_dimensions_from_ttype(arg->m_type, dims_arg);
if( ASRUtils::is_arg_dummy(arg->m_intent) &&
Expand Down Expand Up @@ -7260,6 +7270,14 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
tmp = target;
}
}
} else if( ASRUtils::get_asr_owner(&(arg->base)) &&
ASR::is_a<ASR::Module_t>(*ASRUtils::get_asr_owner(&(arg->base))) &&
ASRUtils::is_array(arg->m_type) ) {
if( is_pointer_to_non_pointer && orig_arg &&
ASRUtils::is_data_only_array(orig_arg->m_type, orig_arg->m_abi) ) {
tmp = arr_descr->get_pointer_to_data(tmp);
tmp = LLVM::CreateLoad(*builder, tmp);
}
}
} else {
auto finder = std::find(nested_globals.begin(),
Expand Down
5 changes: 5 additions & 0 deletions src/libasr/pass/intrinsic_function_registry.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#ifndef LFORTRAN_PASS_INTRINSIC_FUNCTION_REGISTRY_H
#define LFORTRAN_PASS_INTRINSIC_FUNCTION_REGISTRY_H

#include <libasr/asr.h>
#include <libasr/containers.h>
#include <libasr/asr_utils.h>
Expand Down Expand Up @@ -513,3 +516,5 @@ inline std::string get_intrinsic_name(int x) {
} // namespace ASRUtils

} // namespace LCompilers

#endif // LFORTRAN_PASS_INTRINSIC_FUNCTION_REGISTRY_H

0 comments on commit a1fff8b

Please sign in to comment.