Argh, today I had to write a op_clone tree copier from scratch for my inliner. Copying graphs is not trivial, with pointers pointing inside and outside. In #perl5
we only had functions to clone data, but not code. op_clone keeps the data, but the inlined function needs to change some ops. esp. nextstate and args: by ref and if by value with a copy of the data.
My old attempt was fast, but destructively modified each inlined function in the definition.
More memory (max 10 copied ops per inlined cv), but more speed. No costly arg handling, no costly call and leave handling. Using the stack naturally and not as hackish and expensive as currently. Supporting fast call-by-ref, constants and literals and call-by-value, everything compile-time.
Now the loop-unroller will also be trivial.
BTW: nextstate is horror. It ends a statement, every ';',
and it resets the SP, the stack pointer, for each new line. A normal compiler would keep track of the stack context and would not pollute the stack with unconsumed data. lhs expr should not push their results to the stack, unless it's the end of a function.
For my inliner I added 2 new state ops, to keep the SP inside inlined functions, setstate and keepstate. Horrible, but so far an easier hack than rewriting the compiler to honor the lhs context properly.