Undefined function return value
limonovthesecond2 opened this issue · comments
This code
while true
a = foo()
b = foo()
print(a, b)
end
def foo()
rand(10)
end
compiles to:
op rand a 10 0
op rand b 10 0
print a
print __fn0retval
jump 0 always 0 0
end
where __fn0retval
is undefined
. Expected:
op rand a 10 0
op rand b 10 0
print a
print b
jump 0 always 0 0
end
With #set optimization = aggressive
it compiles without an undefined variable:
op rand a 10 0
op rand __fn0retval 10 0
print a
print __fn0retval
jump 0 always 0 0
The problem is that the function inliner doesn't check the function return value isn't used anywhere else. This information is not readily available to the optimizers at this moment.
I don't have a reason to assume this issue doesn't affect aggressive optimization as well in some circumstances. Until this is made to work, I'll have to disable this particular optimization.
It appears a new kind of optimization will be needed to solve this. Currently, the function inliner replaces the function return value variable with the target variable (mistakenly, as explained above). To fix the issue, this replacement will be cancelled in the next version.
I've made some more changes that should ultimately mean the function return value variables won't need almost any kind of special treatment. Then a generic optimization needs to be added, to deal with code like this:
i = rand(10)
a = i
i = rand(20)
b = i
print(a, b)
Currently, this code produces:
op rand i 10 0
set a i
op rand i 20 0
print a
print i
end
Of course, the source code typically doesn't contain such constructs, but this is what function inliner produces. We'd want to replace op rand i 10 0
with op rand a 10 0
and drop the set a i
. This will be a bit complex, but at least it is a generic optimization and not one targeting just the function return values.