On Thu, Jan 07, 2021 at 05:47:37PM +0000, sighoya via Digitalmars-d-learn wrote:
> 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?

The compiler knows exactly which line it is at the point where the
exception is created, and can insert it there.


> We need either some machinery for that to be backpropagated or we
> didn't inline at all in the said case.

There is no need for any machinery. The information is already
statically available at compile-time.


> > 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?

This is just an over-simplified example to illustrate the point. Real
code obviously isn't this simple, and neither are real optimizers.


> > 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.

Again, this was an over-simplified contrived example just to illustrate
the point. Real code and real optimizers are obviously much more complex
than this.  The main point here is that being able to assume things
about control flow in a function gives the optimizer more tools to
produce better code.  This is neither the time nor place to get into
the nitty-gritty details of how exactly optimization works. If you're
unfamiliar with the subject, I recommend reading a textbook on compiler
construction.


> 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.

Because every introduced catch block in the libunwind implementation
introduces additional overhead.


[...]
> > 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.

Wrong. Out of memory only occurs at specific points in the code (i.e.,
when you call a memory allocation primitive).


> > 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.

This tells me that you do not understand how compiled languages work.
Again, I recommend reading a textbook on compiler construction. It will
help you understand this issues better. (And it will also indirectly
help you write better code, once you understand what exactly the
compiler does with it, and what the machine actually does.)


> 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.

All of this information is already available at compile-time. The
compiler can be easily emit code to write this information into some
error-handling area that can be looked up by the catch block.

Also, you are confusing debugging information with the mechanism of
try/catch. Any such information is a part of the payload of an
exception; this is not the concern of the mechanism of how try/catch are
implemented.


T

-- 
Perhaps the most widespread illusion is that if we were in power we would 
behave very differently from those who now hold it---when, in truth, in order 
to get power we would have to become very much like them. -- Unknown

Reply via email to