On Thu, Jan 07, 2021 at 11:15:26AM +0000, sighoya via Digitalmars-d-learn wrote: > On Thursday, 7 January 2021 at 10:36:39 UTC, Jacob Carlborg wrote: [...] > > It's claimed that exceptions are not zero cost, even when an > > exception is not thrown. Because the compiler cannot optimize > > functions that may throw as well as those that cannot throw. > > Did you refer to the case a pure function is inlined into the caller > and the machinery of stack pointer decrementation doesn't work > anymore?
This has nothing to do with inlining. Inlining is done at compile-time, and the inlined function becomes part of the caller. There is no stack pointer decrementing involved anymore because there's no longer a function call in the emitted code. The optimizer works by transforming the code so that redundant operations are eliminated, and/or expensive operations are replaced with cheaper ones. It does this by relying on certain assumptions about the code that lets it replace/rearrange the code in a way that preserves its semantics. 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. The problem with unwinding is that the optimizer can no longer assume, for instance, that every function call will return control to the caller (if the called function throws, control flow will bypass the current function). So if B is a function call, then the optimizer can no longer assume C is always reached, so it cannot reorder the operations. Maybe there's a better sequence of instructions that does A and C together, but now the optimizer cannot use it because that would change the semantics of the code. 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. 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. [...] > In case of dyn libs, we may, can develop a machinery to gather > exception table information at compile time and to manipulate them in > order to inline them safely, but I don't know about the case in D > though. 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. T -- He who does not appreciate the beauty of language is not worthy to bemoan its flaws.