-
Notifications
You must be signed in to change notification settings - Fork 167
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
Replace BlockCall symbol with the one in current scope #1688
Replace BlockCall symbol with the one in current scope #1688
Conversation
The issue was in the def func() -> i32:
return 30
def test() -> i32:
temp: i32 = func()
return temp
x : i32
x = test()
print(x) (TranslationUnit
(SymbolTable
1
{
_global_symbols:
(Module
(SymbolTable
6
{
_lpython_main_program:
(Function
(SymbolTable
5
{
_lpython_return_variable_func_test:
(Variable
5
_lpython_return_variable_func_test
[]
Local
()
()
Default
(Integer 4 [])
Source
Public
Required
.false.
),
_lpython_return_variable_test:
(Variable
5
_lpython_return_variable_test
[]
Local
()
()
Default
(Integer 4 [])
Source
Public
Required
.false.
),
temp_test:
(Variable
5
temp_test
[]
Local
()
()
Default
(Integer 4 [])
Source
Public
Required
.false.
),
~empty_block:
(Block
(SymbolTable
8
{
})
~empty_block
[]
)
})
_lpython_main_program
(FunctionType
[]
()
Source
Implementation
()
.false.
.false.
.false.
.false.
.false.
[]
[]
.false.
)
[]
[]
[(=
(Var 5 _lpython_return_variable_func_test)
(IntegerConstant 30 (Integer 4 []))
()
)
(GoTo
1
__1
)
(BlockCall
1
3 ~empty_block ! < ------------- Here is the issue
)
(=
(Var 5 temp_test)
(Var 5 _lpython_return_variable_func_test)
()
)
(=
(Var 5 _lpython_return_variable_test)
(Var 5 temp_test)
()
)
(GoTo
2
__2
)
(BlockCall
2
5 ~empty_block
)
(=
(Var 6 x)
(Var 5 _lpython_return_variable_test)
()
)
(Print
()
[(Var 6 x)]
()
()
)]
()
Public
.false.
.false.
),
func:
(Function
(SymbolTable
2
{
_lpython_return_variable:
(Variable
2
_lpython_return_variable
[]
ReturnVar
()
()
Default
(Integer 4 [])
Source
Public
Required
.false.
)
})
func
(FunctionType
[]
(Integer 4 [])
Source
Implementation
()
.false.
.false.
.false.
.false.
.false.
[]
[]
.false.
)
[]
[]
[(=
(Var 2 _lpython_return_variable)
(IntegerConstant 30 (Integer 4 []))
()
)
(Return)]
(Var 2 _lpython_return_variable)
Public
.false.
.false.
),
test:
(Function
(SymbolTable
3
{
_lpython_return_variable:
(Variable
3
_lpython_return_variable
[]
ReturnVar
()
()
Default
(Integer 4 [])
Source
Public
Required
.false.
),
_lpython_return_variable_func:
(Variable
3
_lpython_return_variable_func
[]
Local
()
()
Default
(Integer 4 [])
Source
Public
Required
.false.
),
temp:
(Variable
3
temp
[]
Local
()
()
Default
(Integer 4 [])
Source
Public
Required
.false.
),
~empty_block:
(Block
(SymbolTable
7
{
})
~empty_block
[]
)
})
test
(FunctionType
[]
(Integer 4 [])
Source
Implementation
()
.false.
.false.
.false.
.false.
.false.
[]
[]
.false.
)
[]
[]
[(=
(Var 3 _lpython_return_variable_func)
(IntegerConstant 30 (Integer 4 []))
()
)
(GoTo
1
__1
)
(BlockCall
1
3 ~empty_block
)
(=
(Var 3 temp)
(Var 3 _lpython_return_variable_func)
()
)
(=
(Var 3 _lpython_return_variable)
(Var 3 temp)
()
)
(Return)]
(Var 3 _lpython_return_variable)
Public
.false.
.false.
),
x:
(Variable
6
x
[]
Local
()
()
Default
(Integer 4 [])
Source
Public
Required
.false.
)
})
_global_symbols
[]
.false.
.false.
),
main_program:
(Program
(SymbolTable
4
{
_lpython_main_program:
(ExternalSymbol
4
_lpython_main_program
6 _lpython_main_program
_global_symbols
[]
_lpython_main_program
Public
)
})
main_program
[_global_symbols]
[(SubroutineCall
4 _lpython_main_program
()
[]
()
)]
)
})
[]
) Here the statements from the |
Thank you. Please check if this also fixes #1677 |
We need to be careful here, I think you want to duplicate it, don't you? |
I thought the If we duplicate it, should we create an ExternalSymbol for the Block? ...
_lpython_main_program:
(Function
(SymbolTable
5
{
...
(BlockCall
1
3 ~empty_block ! < ---- This is created in another function symtab
)
...
(BlockCall
2
5 ~empty_block
)
... |
I don't know. I agree that goto is specific to a function. But removing it seems to make the code incorrect. So we need to figure out how to solve this. |
Correct. We need to duplicate it and then edit |
53ad721
to
1f60cf0
Compare
I'm not sure if this new change was a correct fix. What does the |
std::string block_name = ASRUtils::symbol_name(bc->m_m); | ||
LCOMPILERS_ASSERT(current_scope->get_symbol(block_name)) | ||
bc->m_m = current_scope->get_symbol(block_name); | ||
} |
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.
Instead of doing the edit here, you need to follow the same pattern as in visit_Var
(add visit_BlockCall
and then edit its symbol, if the code is exactly the same then add a macro to generate code for each method).
lpython/src/libasr/pass/inline_function_calls.cpp
Lines 98 to 123 in 1f60cf0
void visit_Var(const ASR::Var_t& x) { | |
ASR::Var_t& xx = const_cast<ASR::Var_t&>(x); | |
std::string x_var_name = std::string(ASRUtils::symbol_name(x.m_v)); | |
// If anything is not local to a function being inlined | |
// then do not inline the function by setting | |
// fixed_duplicated_expr_stmt to false. | |
// To be supported later. | |
if( current_routine_scope && | |
current_routine_scope->get_symbol(x_var_name) == nullptr ) { | |
fixed_duplicated_expr_stmt = false; | |
return ; | |
} | |
if( x.m_v->type == ASR::symbolType::Variable ) { | |
ASR::Variable_t* x_var = ASR::down_cast<ASR::Variable_t>(x.m_v); | |
if( arg2value.find(x_var_name) != arg2value.end() ) { | |
x_var = ASR::down_cast<ASR::Variable_t>(arg2value[x_var_name]); | |
if( current_scope->get_symbol(std::string(x_var->m_name)) != nullptr ) { | |
xx.m_v = arg2value[x_var_name]; | |
} | |
x_var = ASR::down_cast<ASR::Variable_t>(x.m_v); | |
} | |
} else { | |
fixed_duplicated_expr_stmt = false; | |
} | |
} |
I think the bug is in the inline pass. It must create a unique name for the |
Rather, it looks like the issue is that the Block symbol points to the old location and BlockCall is calling it from the old location, so one gets the following error message:
caused by:
So it looks like the nested function pass needs to copy over the Block symbol (duplicate). |
#1688 (comment) is the correct approach. If one is not doing it fully then ASR verify pass errors will always be there. Also I think editing is not happening correctly for BlockCall. https://github.com/lcompilers/lpython/pull/1688/files#r1161810225 isn’t addressed yet. |
1f60cf0
to
165df87
Compare
165df87
to
63fbb9d
Compare
This seems to fix the issue. |
If you are not sure then apply changes to LFortran and see if they work there. If they do then we are good. More testing should ensure that we are not facing any bugs. |
Also, I think we should have a |
Yes, we need |
LFortran PR: lfortran/lfortran#1566 |
Fixes: #1668