-
-
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 support for global ALLOCATABLE
variables
#3997
Conversation
The test is good. Now we have to fix it. :) @Pranavchiku, could you please provide a few hints for @kmr-srbh how to fix it? |
All the credit for the test goes to @assem2002! :) |
To fix this, let's create a small example that works and see how LFortran processes it: program mm
! use a
implicit none
integer, allocatable, dimension(:) :: f
allocate(f(4))
f = [1, 2, 3, 4]
print *,f
end program mm Understand how allocatable is handled in this, and replicate behaviour for modules. You may begin with following diff to understand difference in how LFortran handles two examples and then pick all required stuff from diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp
index a1388942b..75da76472 100644
--- a/src/libasr/codegen/asr_to_llvm.cpp
+++ b/src/libasr/codegen/asr_to_llvm.cpp
@@ -2576,6 +2576,7 @@ public:
}
void visit_Variable(const ASR::Variable_t &x) {
+ std::cout<<"visit_Variable: "<<x.m_name<<std::endl;
if (x.m_value && x.m_storage == ASR::storage_typeType::Parameter) {
this->visit_expr_wrapper(x.m_value, true);
return;
@@ -3343,6 +3344,7 @@ public:
template<typename T>
void declare_vars(const T &x, bool create_vtabs=true) {
+ std::cout<<"Declare vars"<<std::endl;
llvm::Value *target_var;
uint32_t debug_arg_count = 0;
std::vector<std::string> var_order = ASRUtils::determine_variable_declaration_order(x.m_symtab);
@@ -3380,6 +3382,7 @@ public:
ASR::symbol_t* var_sym = x.m_symtab->get_symbol(item);
if (is_a<ASR::Variable_t>(*var_sym)) {
ASR::Variable_t *v = down_cast<ASR::Variable_t>(var_sym);
+ std::cout<<"v->m_name: "<<v->m_name<<std::endl;
uint32_t h = get_hash((ASR::asr_t*)v);
llvm::Type *type;
int n_dims = 0, a_kind = 4;
@@ -3519,6 +3522,7 @@ public:
(ASRUtils::extract_physical_type(v->m_type) == ASR::array_physical_typeType::CharacterArraySinglePointer &&
ASRUtils::is_dimension_empty(m_dims,n_dims))))
) {
+ std::cout<<"in here"<<std::endl;
fill_array_details_(ptr, type_, m_dims, n_dims,
is_malloc_array_type, is_array_type, is_list, v->m_type);
} Also, you need to figure out the cause of error, there can be two cases
|
I had checked this. The issue occurs due to the 2nd reason, when (base) saurabh-kumar@Awadh:~/Projects/System/lfortran$ lfortran ./examples/example.f90
visiting allocate
Segmentation fault (core dumped) |
look up for I hope this isn't misleading. I'm still looking into it. |
Thanks for looking into this @assem2002! Actually, the issue is one level deeper - we are not being able to correctly declare the variable. Debug info with the example given in #3997 (comment) (base) saurabh-kumar@Awadh:~/Projects/System/lfortran$ lfortran ./examples/example.f90
visit variable
declare vars
var_order len: 4
sym_type: integer
v->m_name: __1_k
var_type: integer
sym_type: integer
v->m_name: __1_t
var_type: integer
sym_type: integer
v->m_name: __1_v
var_type: integer
sym_type: integer[:]
v->m_name: __libasr__created__var__0__array_constant_
var_type: integer[:]
Segmentation fault (core dumped) Debug info with the example given in #3997 (comment) (base) saurabh-kumar@Awadh:~/Projects/System/lfortran$ lfortran ./examples/example.f90
declare vars
var_order len: 5
sym_type: integer
v->m_name: __1_k
var_type: integer
sym_type: integer
v->m_name: __1_t
var_type: integer
sym_type: integer
v->m_name: __1_v
var_type: integer
sym_type: integer[:]
v->m_name: __libasr__created__var__0__array_constant_
var_type: integer[:]
sym_type: integer[:] allocatable
v->m_name: f
var_type: integer[:] allocatable
in here
1 2 3 4 As you can see from |
Great!. let's try to handle it quickly to proceed with 'SNAP' compilation. |
With the latest commit, the stated example now works. module a
implicit none
integer, allocatable, dimension(:) :: f
end module a
program mm
use a
implicit none
allocate(f(4))
f = [1, 2, 3, 4]
print *,f
end program mm (base) saurabh-kumar@Awadh:~/Projects/System/lfortran$ lfortran ./examples/example.f90
1 2 3 4 However, I do not know the reason why, but a few tests fail - The following tests FAILED:
472 - modules_53 (Failed)
543 - derived_types_22 (Failed)
545 - derived_types_24 (Failed)
771 - private1 (Failed)
832 - common_03 (Failed)
834 - common_09 (Failed)
837 - common_12 (Failed)
Errors while running CTest
Command failed. I am new to the language and still learning it. @Pranavchiku @certik could you please look into it? |
After the new changes, 31 test references get updated. The high number make me think that we need something more to complete this PR. I am not committing those new files now as I suspect they might be not required. |
This PR does not fix #3968. I am working on the issue to think of a fix. |
could you separate the module and the program of the test case in two files and try to run the files. |
Thanks for the suggestion @assem2002! I think it is not correct to alter the tests for a new addition. Let's wait for others to have a look. 🙂 |
could you just test it locally on your machine for now. If it works and we still encounter the same |
I had tested this @assem2002, but the issue persists. |
Thanks for trying to fix this @kmr-srbh. @Pranavchiku would you have time to help further please? |
I had a look into the failing tests, and found that the change I had made to get symbols past external(11fed98), was causing the variables to hold abnormal values. As it turns out, the number of variables to be declared was being increased by 1. While this change leads to the example presented in the PR description to work, it causes the above stated failure. I have tried many ways to fix this including trying to handle The issue now is, why does the variable |
I think you managed to make a pointer to an array-type in LLVM and it works and this should be it as you have mentioned we shouldn't take any step further. |
I am not sure if this is the case. When I was testing the initial implementation, I noticed that the flow of execution was being directed to the |
I'll try to dig more deeper and let you know. |
I see nothing wrong in the diff, what you are trying to do is make it equivalent to: module a
implicit none
! integer, allocatable, dimension(:) :: f
integer, pointer :: f(:)
end module a
program mm
use a
implicit none
allocate(f(4))
f = [1, 2, 3, 4]
print *,f
end program mm
Which segfaults with % lfortran a.f90
% gfortran a.f90 && ./a.out
1 2 3 4 |
The way to proceed will be to observe how the below example works. program main
integer, pointer, dimension(:) :: f
allocate(f(4))
f = [1, 2, 3, 4]
end program In our case, we set %2 = load %array*, %array** @f, align 8
%3 = getelementptr %array, %array* %2, i32 0, i32 1 Where %f = alloca %array*, align 8
store %array* null, %array** %f, align 8
%arr_desc = alloca %array, align 8
%2 = getelementptr %array, %array* %arr_desc, i32 0, i32 2
%3 = alloca i32, align 4
store i32 1, i32* %3, align 4
%4 = load i32, i32* %3, align 4
%5 = alloca %dimension_descriptor, i32 %4, align 8
store %dimension_descriptor* %5, %dimension_descriptor** %2, align 8
%6 = getelementptr %array, %array* %arr_desc, i32 0, i32 4
store i32 1, i32* %6, align 4
%7 = getelementptr %array, %array* %arr_desc, i32 0, i32 0
store i32* null, i32** %7, align 8 And after this we begin code to allocate and thus this do not segfault. You'll have to compare both examples and get it right. |
Simply, you will need to populate descriptor of |
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.
left comment above on how to proceed
@Pranavchiku I explored the way to implement this according to your suggestion. I think it will be achieved using the |
I'll ask you to close this once #4111 is merged. |
Thanks for suggesting this PR |
Closing with reference to #4111 |
fixes #3993
The chief reason for the issue was
ALLOCATABLE
type not being handled in the global scope. We can handle it in a way similar toPOINTER
when handling variables.TODO
ExternalSymbol