Skip to content

Commit

Permalink
Implement FunctionType in ASR (lcompilers#1518)
Browse files Browse the repository at this point in the history
  • Loading branch information
czgdp1807 committed Feb 14, 2023
1 parent f9322ae commit 0daef38
Show file tree
Hide file tree
Showing 179 changed files with 342 additions and 289 deletions.
12 changes: 7 additions & 5 deletions src/libasr/ASR.asdl
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,9 @@ symbol
stmt* body)
| Module(symbol_table symtab, identifier name, identifier* dependencies,
bool loaded_from_mod, bool intrinsic)
| Function(symbol_table symtab, identifier name, identifier* dependencies, expr* args, stmt* body,
expr? return_var, abi abi, access access, deftype deftype,
string? bindc_name, bool elemental, bool pure, bool module, bool inline,
bool static, ttype* type_params, symbol* restrictions, bool is_restriction,
bool deterministic, bool side_effect_free)
| Function(symbol_table symtab, identifier name, ttype function_signature,
identifier* dependencies, expr* args, stmt* body, expr? return_var,
access access, bool deterministic, bool side_effect_free)
| GenericProcedure(symbol_table parent_symtab, identifier name,
symbol* procs, access access)
| CustomOperator(symbol_table parent_symtab, identifier name,
Expand Down Expand Up @@ -358,6 +356,10 @@ ttype
| Const(ttype type)
| CPtr()
| TypeParameter(identifier param, dimension* dims)
| FunctionType(ttype* arg_types, ttype? return_var_type,
abi abi, deftype deftype, string? bindc_name, bool elemental,
bool pure, bool module, bool inline, bool static, ttype* type_params,
symbol* restrictions, bool is_restriction)

restriction_arg = RestrictionArg(identifier restriction_name, symbol restriction_func)

Expand Down
3 changes: 2 additions & 1 deletion src/libasr/asr_scopes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ void SymbolTable::mark_all_variables_external(Allocator &/*al*/) {
}
case (ASR::symbolType::Function) : {
ASR::Function_t *v = ASR::down_cast<ASR::Function_t>(a.second);
v->m_abi = ASR::abiType::Interactive;
ASR::FunctionType_t* v_func_type = ASR::down_cast<ASR::FunctionType_t>(v->m_function_signature);
v_func_type->m_abi = ASR::abiType::Interactive;
v->m_body = nullptr;
v->n_body = 0;
break;
Expand Down
15 changes: 11 additions & 4 deletions src/libasr/asr_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ void set_intrinsic(ASR::symbol_t* sym) {
}
case ASR::symbolType::Function: {
ASR::Function_t* function_sym = ASR::down_cast<ASR::Function_t>(sym);
function_sym->m_abi = ASR::abiType::Intrinsic;
ASR::FunctionType_t* func_sym_type = ASR::down_cast<ASR::FunctionType_t>(function_sym->m_function_signature);
func_sym_type->m_abi = ASR::abiType::Intrinsic;
break;
}
case ASR::symbolType::StructType: {
Expand Down Expand Up @@ -431,7 +432,9 @@ bool use_overloaded(ASR::expr_t* left, ASR::expr_t* right,
err("Unable to resolve matched function for operator overloading, " + matched_func_name, loc);
}
ASR::ttype_t *return_type = nullptr;
if( func->m_elemental && func->n_args == 1 && ASRUtils::is_array(ASRUtils::expr_type(a_args[0].m_value)) ) {
if( ASRUtils::get_FunctionType(func)->m_elemental &&
func->n_args == 1 &&
ASRUtils::is_array(ASRUtils::expr_type(a_args[0].m_value)) ) {
return_type = ASRUtils::duplicate_type(al, ASRUtils::expr_type(a_args[0].m_value));
} else {
return_type = ASRUtils::expr_type(func->m_return_var);
Expand Down Expand Up @@ -813,7 +816,9 @@ bool use_overloaded(ASR::expr_t* left, ASR::expr_t* right,
err("Unable to resolve matched function for operator overloading, " + matched_func_name, loc);
}
ASR::ttype_t *return_type = nullptr;
if( func->m_elemental && func->n_args == 1 && ASRUtils::is_array(ASRUtils::expr_type(a_args[0].m_value)) ) {
if( ASRUtils::get_FunctionType(func)->m_elemental &&
func->n_args == 1 &&
ASRUtils::is_array(ASRUtils::expr_type(a_args[0].m_value)) ) {
return_type = ASRUtils::duplicate_type(al, ASRUtils::expr_type(a_args[0].m_value));
} else {
return_type = ASRUtils::expr_type(func->m_return_var);
Expand Down Expand Up @@ -968,7 +973,9 @@ ASR::asr_t* symbol_resolve_external_generic_procedure_without_eval(
if( ASR::is_a<ASR::Function_t>(*final_sym) ) {
ASR::Function_t* func = ASR::down_cast<ASR::Function_t>(final_sym);
if (func->m_return_var) {
if( func->m_elemental && func->n_args == 1 && ASRUtils::is_array(ASRUtils::expr_type(args[0].m_value)) ) {
if( ASRUtils::get_FunctionType(func)->m_elemental &&
func->n_args == 1 &&
ASRUtils::is_array(ASRUtils::expr_type(args[0].m_value)) ) {
return_type = ASRUtils::duplicate_type(al, ASRUtils::expr_type(args[0].m_value));
} else {
return_type = ASRUtils::EXPR2VAR(func->m_return_var)->m_type;
Expand Down
44 changes: 41 additions & 3 deletions src/libasr/asr_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,15 @@ static inline bool is_intrinsic_symbol(const ASR::symbol_t *fn) {
return false;
}

static inline ASR::FunctionType_t* get_FunctionType(const ASR::Function_t* x) {
return ASR::down_cast<ASR::FunctionType_t>(x->m_function_signature);
}

static inline ASR::FunctionType_t* get_FunctionType(const ASR::Function_t& x) {
return ASR::down_cast<ASR::FunctionType_t>(x.m_function_signature);
}


// Returns true if the Function is intrinsic, otherwise false
// This version uses the `intrinsic` member of `Module`, so it
// should be used instead of is_intrinsic_procedure
Expand All @@ -533,7 +542,7 @@ static inline bool is_intrinsic_function2(const ASR::Function_t *fn) {
ASR::Module_t *m = get_sym_module0(sym);
if (m != nullptr) {
if (m->m_intrinsic ||
fn->m_abi == ASR::abiType::Intrinsic) {
ASRUtils::get_FunctionType(fn)->m_abi == ASR::abiType::Intrinsic) {
return true;
}
}
Expand Down Expand Up @@ -1336,7 +1345,8 @@ static inline bool is_generic_function(ASR::symbol_t *x) {
switch (x2->type) {
case ASR::symbolType::Function: {
ASR::Function_t *func_sym = ASR::down_cast<ASR::Function_t>(x2);
return func_sym->n_type_params > 0 && !func_sym->m_is_restriction;
return (ASRUtils::get_FunctionType(func_sym)->n_type_params > 0 &&
!ASRUtils::get_FunctionType(func_sym)->m_is_restriction);
}
default: return false;
}
Expand All @@ -1347,7 +1357,7 @@ static inline bool is_restriction_function(ASR::symbol_t *x) {
switch (x2->type) {
case ASR::symbolType::Function: {
ASR::Function_t *func_sym = ASR::down_cast<ASR::Function_t>(x2);
return func_sym->m_is_restriction;
return ASRUtils::get_FunctionType(func_sym)->m_is_restriction;
}
default: return false;
}
Expand Down Expand Up @@ -2285,6 +2295,34 @@ static inline bool is_pass_array_by_data_possible(ASR::Function_t* x, std::vecto
return v.size() > 0;
}

inline ASR::asr_t* make_Function_t_util(Allocator& al, const Location& loc,
SymbolTable* m_symtab, char* m_name, char** m_dependencies, size_t n_dependencies,
ASR::expr_t** a_args, size_t n_args, ASR::stmt_t** m_body, size_t n_body,
ASR::expr_t* m_return_var, ASR::abiType m_abi, ASR::accessType m_access,
ASR::deftypeType m_deftype, char* m_bindc_name, bool m_elemental, bool m_pure,
bool m_module, bool m_inline, bool m_static, ASR::ttype_t** m_type_params,
size_t n_type_params, ASR::symbol_t** m_restrictions, size_t n_restrictions,
bool m_is_restriction, bool m_deterministic, bool m_side_effect_free) {
Vec<ASR::ttype_t*> arg_types;
arg_types.reserve(al, n_args);
for( size_t i = 0; i < n_args; i++ ) {
arg_types.push_back(al, ASRUtils::expr_type(a_args[i]));
}
ASR::ttype_t* return_var_type = nullptr;
if( m_return_var ) {
return_var_type = ASRUtils::expr_type(m_return_var);
}
ASR::ttype_t* func_type = ASRUtils::TYPE(ASR::make_FunctionType_t(
al, loc, arg_types.p, arg_types.size(), return_var_type, m_abi,
m_deftype, m_bindc_name, m_elemental, m_pure, m_module, m_inline,
m_static, m_type_params, n_type_params, m_restrictions, n_restrictions,
m_is_restriction));
return ASR::make_Function_t(
al, loc, m_symtab, m_name, func_type, m_dependencies, n_dependencies,
a_args, n_args, m_body, n_body, m_return_var, m_access, m_deterministic,
m_side_effect_free);
}

static inline ASR::expr_t* get_bound(ASR::expr_t* arr_expr, int dim,
std::string bound, Allocator& al) {
ASR::ttype_t* int32_type = ASRUtils::TYPE(ASR::make_Integer_t(al, arr_expr->base.loc,
Expand Down
8 changes: 4 additions & 4 deletions src/libasr/codegen/asr_to_c_cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,10 +327,10 @@ R"(#include <stdio.h>
template_for_Kokkos.clear();
template_number = 0;
std::string sub, inl, static_attr;
if (x.m_inline) {
if (ASRUtils::get_FunctionType(x)->m_inline) {
inl = "inline __attribute__((always_inline)) ";
}
if( x.m_static ) {
if( ASRUtils::get_FunctionType(x)->m_static ) {
static_attr = "static ";
}
if (x.m_return_var) {
Expand Down Expand Up @@ -471,8 +471,8 @@ R"(#include <stdio.h>
sym_info[get_hash((ASR::asr_t*)&x)] = s;
}
std::string sub = get_function_declaration(x);
if (x.m_abi == ASR::abiType::BindC
&& x.m_deftype == ASR::deftypeType::Interface) {
if (ASRUtils::get_FunctionType(x)->m_abi == ASR::abiType::BindC
&& ASRUtils::get_FunctionType(x)->m_deftype == ASR::deftypeType::Interface) {
sub += ";\n";
} else {
sub += "\n";
Expand Down
5 changes: 3 additions & 2 deletions src/libasr/codegen/asr_to_julia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ class ASRToJuliaVisitor : public ASR::BaseVisitor<ASRToJuliaVisitor>
std::string get_function_declaration(const ASR::Function_t& x)
{
std::string sub, inl, ret_type;
if (x.m_inline) {
if (ASRUtils::get_FunctionType(x)->m_inline) {
inl = "@inline ";
}
if (x.m_return_var) {
Expand Down Expand Up @@ -665,7 +665,8 @@ class ASRToJuliaVisitor : public ASR::BaseVisitor<ASRToJuliaVisitor>
sym_info[get_hash((ASR::asr_t*) &x)] = s;
}
std::string sub = get_function_declaration(x);
if (x.m_abi == ASR::abiType::BindC && x.m_deftype == ASR::deftypeType::Interface) {
if (ASRUtils::get_FunctionType(x)->m_abi == ASR::abiType::BindC &&
ASRUtils::get_FunctionType(x)->m_deftype == ASR::deftypeType::Interface) {
} else {
indentation_level += 1;
std::string indent(indentation_level * indentation_spaces, ' ');
Expand Down
Loading

0 comments on commit 0daef38

Please sign in to comment.