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