<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 1, 2016 at 1:29 PM, Owen Anderson via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word">Hi Lang,<div><br></div><div>I want to ask what I feel is an important high-level question here:  how does this approach differ, fundamentally, from exceptions, and why should we go down the route of building our own error handling scheme rather than “just” adopting exceptions?</div><div><br></div><div>To answer my own question, my impression is that your proposed scheme is functionally similar to exceptions, with the major deviation of being opt-in rather than opt-out. </div></div></blockquote><div><br></div><div>The other big difference is visibility at the call site that the operation can fail - making it harder to write code and forget that this operation can fail.<br><br>(this comes at a cost - seeing Google's own util::Status ( <a href="http://google.github.io/google-api-cpp-client/latest/doxygen/client_2util_2status_8h.html">http://google.github.io/google-api-cpp-client/latest/doxygen/client_2util_2status_8h.html</a> ) and the kinds of macros that evolve around it to handle the verbose idiom of "Status s = func(...., &result); if (s) { return s; }" so it doesn't noisy up all the code doesn't exactly endear me to this path, but I'm not sure there's much better (I actually like/prefer exceptions, and I admit they'd be nicer if there was some annotation on the call site to indicate that the call might fail - but also realize there are a fair few folks who are far more adamantly anti-exceptions))</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div> While opt-in is intellectually appealing at first glance, I’m not convinced that it is actually the best solution to some of the problems at play here.  In particular, an opt-in scheme will require threading the error-handling type system through many layers of generic and/or boilerplate code in order to allow various callbacks in target backends to report errors properly.</div><div><br></div><div>As a concrete example, every backend under the sun has some degree of implicit contract between the backend and the frontend regarding supported IR constructs.  This can be as “simple” as ABI lowering and intrinsic names for a typical CPU target, but can be far more complex for targets with non-traditional execution models.  In either case, it seems very desirable for the target in the abstract, and instruction selection in particular, to be able to report violations of this contract via the error reporting mechanism.  However, to do some in the context of SelectionDAG or FastISel (and I see no particular reason why GlobalISel will be particularly different) would require threading error checking through vast swaths of code both in the instruction selection infrastructure and in the callbacks for the targets themselves.</div></div></blockquote><div><br></div><div>It may be that other approaches, more like the diagnostic handling options discussed in the original thread (& that we have plumbed through for the "remarks" support). But maybe you need a hard stop on these errors, in which case you do need some implicit or explicit control flow to get you out. There was a bit of discussion about how to do this for lld recently - returning stub results that are "sufficient" maybe with a flag saying "this isn't a real result" - more like Clang's Parser/Sema: we don't have error results everywhere. We return erroneous stubs and the like which allow a lot of Clang to continue on without worrying about whether something failed. Only handling the failures in relatively few places.</div><div><br></div><div>This is also useful for providing error recovery/multiple errors (eg: this instruction /and/ thin instruction were both wrong - so the user doesn't have to edit/compile loop again just to find out the two lines they wrote both needed changes). <br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div>  Moreover, instruction selection tends to be a performance sensitive component of the compiler, which argues in favor of exceptions which are, at least notionally, zero-cost.</div></div></blockquote><div><br></div><div>Is there much reason to believe that return failures are more expensive (I think there are some arguments to be made here, but I haven't heard many articulated). (It's my understanding that Swift uses an error-return like ABI, not exception-like tables)</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div><br></div><div>I’m not claiming here to have a global optimally solution to the problem, and I emphatically <b>do</b> want to see LLVM be better behaved about error handling in general.  But it’s not clear to me exactly where the right cost/benefit tradeoff lies in terms of error handling technologies.</div><div><br></div><div>—Owen</div><div><div class="h5"><div><br></div><div><br><div><blockquote type="cite"><div>On Mar 1, 2016, at 1:15 PM, Lang Hames via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:</div><br><div><div>lhames added a comment.<br><br>As described in the original RFC (see "Error handling in LLVM libraries." on the llvm-dev mailing list), this patch adds support for an error-handling system tentatively named TypedError. This scheme can be thought of as a hybrid between error returns an exceptions: Errors in the scheme are explicitly represented as return types in the API (like error codes), but error values are structured, user-defined types, similar to c++ exceptions.<br><br>The motivation and details of the scheme can be read in the original RFC, my expectation is that this thread will focus on the implementation details.<br><br><br>Repository:<br>  rL LLVM<br><br><a href="http://reviews.llvm.org/D17778" target="_blank">http://reviews.llvm.org/D17778</a><br><br><br><br>_______________________________________________<br>llvm-commits mailing list<br><a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br></div></div></blockquote></div><br></div></div></div></div><br>_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
<br></blockquote></div><br></div></div>