On Thursday, 7 January 2021 at 14:34:50 UTC, H. S. Teoh wrote:
This has nothing to do with inlining. Inlining is done at
compile-time, and the inlined function becomes part of the
caller.
True
There is no stack pointer decrementing involved anymore
Also true.
because there's no longer a function call in the emitted code.
And this is the problem, how to refer to the original line of the
inlined function were the exception was thrown?
We need either some machinery for that to be backpropagated or we
didn't inline at all in the said case.
One very important assumption is control flow: if you have
operations A, B, C in your function and the optimizer can
assume that control will always reach all 3 operations, then it
can reorder the operations (e.g., to improve instruction cache
coherence) without changing the meaning of the code.
Wonderful, we have an example!
If all three operations don't refer to depend on each other. Or
maybe the compiler execute them in parallel. Did we refer to lazy
evaluation or asynchronous code execution here?
If the exception were propagated via normal return mechanisms,
then the optimizer still has a way to optimize it: it can do A
and C first, then if B fails it can insert code to undo C,
which may still be faster than doing A and C separately.
Puh, that's sounds a bit of reordering nondeterministic effectful
operations which definitely aren't rollbackable in general, only
in simple cases.
But in general, why not generate a try catch mechanism at compile
time catching the exception in case B throws and store it
temporarily in an exception variable.
After A has executed and was successful, just rethrow the
exception of B.
All this could be generated at compile time, no runtime cost but
involves some kind of code duplication.
This is why performance-conscious people prefer nothrow where
possible: it lets the optimizer make more assumptions, and
thereby, opens the possibility for better optimizations.
But the assumption is wrong, every function can fail, e.g. out of
memory, aborting the whole program in this case just to do better
optimizations isn't the fine english way.
This makes no sense. Inlining is done at compile-time; if you
are loading the code as a dynamic library, by definition you're
not inlining anymore.
As I said, I don't know how this is handled in D, but in theory
you can even inline an already compiled function though you need
meta information to do that. My idea was just to fetch the line
number from the metadata of the throw statement in the callee in
order to localize the error correctly in the original source code.