Functions used in expressions are inlined wrongly
cardillan opened this issue · comments
When a function inlined by the optimizer is used in an expression repeatedly, the return value from one of the calls is lost:
def foo()
rand(10)
end
print(foo() + foo())
compiles to
op rand __fn0retval 10 0
op add __tmp2 __tmp0 __fn0retval
print __tmp2
end
Fixed for the next release. Currently, the above code compiles to:
op rand __fn0retval 10 0
set __tmp0 __fn0retval
op rand __fn0retval 10 0
op add __tmp2 __tmp0 __fn0retval
print __tmp2
end
The first two instructions could be merged into one, but aren't, because __fn0retval
is a protected variable. The most generic solution is to replace the function return variable with a normal temporary variable when inlining the call, because the protection is no longer necessary after the inlining - plus it decouples the inlined call from other call sites.
The function inliner was expanded to replace the return value variables with the receiving variable. It helps in some cases, but a return
statement can still prevent the desired optimization from happening. This will be resolved separately.