-
-
Notifications
You must be signed in to change notification settings - Fork 129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add provision to visit_FunctionCall
in update_call_args
#2796
Conversation
It seems the ASR is incorrect if I will review this PR carefully later today. |
I think the code is fine otherwise. I checked the ASR for the new test you added and it seems there are two definitions of the function "f". I see two ways forward:
|
This is expected, no? The way we tackle external function is we have separate symbols defined in each symtab as Interface and BindC and then LLVM appends |
Are the two declarations of |
Yes. |
Ok, so let's merge this PR after you fix the macro issue. Then the next step is to improve the LLVM backend to generate correct code. If |
bc8b58d
to
b13b34d
Compare
The only trouble is both |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the PR is fine.
Why cannot the two "f" be treated like two different functions with two different hashes? They should generate the same signature. |
Yes, they can be treated. In this case, the only place where subroutine b()
external f
call a(f)
end subroutine
subroutine a(f)
real r
external f
r = f(2.0)
print *, r
end subroutine So we need to somehow bypass the assertion for this kind of special cases. |
with the following diff, we have it working diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp
index 4617fd5b5..bf8e45434 100644
--- a/src/libasr/codegen/asr_to_llvm.cpp
+++ b/src/libasr/codegen/asr_to_llvm.cpp
@@ -7896,6 +7896,12 @@ public:
if (ASRUtils::get_FunctionType(fn)->m_deftype == ASR::deftypeType::Implementation) {
LCOMPILERS_ASSERT(llvm_symtab_fn.find(h) != llvm_symtab_fn.end());
tmp = llvm_symtab_fn[h];
+ } else if (llvm_symtab_fn_arg.find(h) == llvm_symtab_fn_arg.end() &&
+ ASR::is_a<ASR::Function_t>(*var_sym) &&
+ ASRUtils::get_FunctionType(fn)->m_deftype == ASR::deftypeType::Interface ) {
+ LCOMPILERS_ASSERT(llvm_symtab_fn.find(h) != llvm_symtab_fn.end());
+ tmp = llvm_symtab_fn[h];
+ // LCOMPILERS_ASSERT(tmp != nullptr)
} else {
// Must be an argument/chained procedure pass
LCOMPILERS_ASSERT(llvm_symtab_fn_arg.find(h) != llvm_symtab_fn_arg.end()); % lfortran c.f90 --implicit-interface --show-llvm
; ModuleID = 'LFortran'
source_filename = "LFortran"
@0 = private unnamed_addr constant [2 x i8] c" \00", align 1
@1 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@2 = private unnamed_addr constant [9 x i8] c"%13.8e%s\00", align 1
define void @a(float (float*)* %f) {
.entry:
%call_arg_value = alloca float, align 4
%r = alloca float, align 4
store float 2.000000e+00, float* %call_arg_value, align 4
%0 = call float %f(float* %call_arg_value)
store float %0, float* %r, align 4
%1 = load float, float* %r, align 4
%2 = fpext float %1 to double
call void (i8*, ...) @_lfortran_printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @2, i32 0, i32 0), double %2, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @1, i32 0, i32 0))
br label %return
return: ; preds = %.entry
ret void
}
declare float @f(float*)
define void @b() {
.entry:
call void @a(float (float*)* @f.1)
br label %return
return: ; preds = %.entry
ret void
}
declare float @f.1(float*)
declare void @_lfortran_printf(i8*, ...)
define i32 @main(i32 %0, i8** %1) {
.entry:
call void @_lpython_set_argv(i32 %0, i8** %1)
call void @b()
ret i32 0
}
declare void @_lpython_set_argv(i32, i8**) |
Ok, submit a PR. |
With this we get correct ASR for #1977 (comment), however the error still persists. On debugging, I found that
llvm_symtab_fn_arg
consists hash corresponding tof
present in symbol table ofa
, and then when we encountercall a(f)
in body ofb
,f
is part of symbol table belonging tob
and thus it throws error.One way to fix this is, whenever we add hash of an external function into
llvm_symtab_fn_arg
, lookup all the symtabs where it is present and add their hash as well. Although, we do not have any information to check ifis_external(f)
.Another way that comes to my mind is to make all external functions part of module
__lcompilers_external_functions_module
, this way we have a global module accessible to every subroutine but, this will have a large blast radius ( handlingExternalSymbol
, the same we faced in #2396 ).