<html><body>
<p><font size="2" face="sans-serif">That's written nicely and describes the options well. It did get me thinking though, and I decided I disagree with one thing we've been assuming, and that may affect our proposal.</font><br>
<br>
<br>
<font size="2" face="sans-serif">Question 1: Is there really any truly one pass compiler?<br>
Here are some examples of things hard to compile in one pass:</font><br>
<ul type="disc" style="padding-left: 18pt">
<li><font size="2" face="sans-serif">goto label;                        /* At this point the address of label is unknown but must be branched to. */<br>
. . .<br>
label:<br>
</font>
<li><font size="2" face="sans-serif">for (i = 0; i < n; ++i)<br>
{<br>
. . .<br>
break;                        /* At this point the address of the code after the loop is unknown but must be branched to. */<br>
. . .<br>
}<br>
</font></ul>
<font size="2" face="sans-serif">Answer: The minimum is one pass plus fixups, or if it generates assembler code, the compiler is a minimum of 2 passes (compiler plus assembler pass one) plus fixups.</font><br>
<br>
<br>
<font size="2" face="sans-serif">Question 2: Can a try-catch be compiled in one pass plus fixups?</font><br>
<br>
<font size="2" face="sans-serif">Answer: Yes, if it's known to handle floating-point exceptions at the beginning, and if the fixup mechanism is able to either patch a load immediate instruction with the mask of exceptions to enable, or the mask is put in a compiler-generated constant that's loaded at the beginning and initialized after seeing the catches.</font><br>
<br>
<br>
<font size="2" face="sans-serif">Question 3: Can a try-catch be compiled in one pass plus fixups if it isn't known at the beginning that it will be handling floating-point exceptions?</font><br>
<br>
<font size="2" face="sans-serif">Answer: No. If trapping is being used then the trapping mechanism must be enabled at the beginning. If conditional branches are being used to detect exceptions then the compiler needs to know to generate them from the beginning.</font><br>
<br>
<font size="2" face="sans-serif">Alternate answer: Yes, if the compiler generates a forward branch to try block initialization that's generated after the catch clauses are seen, and which branches back to the top, the equivalent of:</font><br>
<br>
<font size="2" face="sans-serif">        goto initialize_try_block;</font><br>
<br>
<font size="2" face="sans-serif">        start_of_try_block:</font><br>
<font size="2" face="sans-serif">         . . . /* try block */</font><br>
<font size="2" face="sans-serif">        end_of_try_block:</font><br>
<font size="2" face="sans-serif">         goto after_catch_handlers;</font><br>
<br>
<font size="2" face="sans-serif">        initialize_try_block:</font><br>
<font size="2" face="sans-serif">         . . . initialize try block exception handling; . . .</font><br>
<font size="2" face="sans-serif">         goto start_of_try_block;</font><br>
<br>
<font size="2" face="sans-serif">        catch_handler_1:</font><br>
<font size="2" face="sans-serif">         . . .</font><br>
<font size="2" face="sans-serif">        catch_handler_2:</font><br>
<font size="2" face="sans-serif">         . . .</font><br>
<br>
<font size="2" face="sans-serif">        after_catch_handlers:</font><br>
<br>
<font size="2" face="sans-serif">That involves two extra unconditional branch instructions, but one pass compilers are not designed to generate optimal code so that may be an acceptable cost.</font><br>
<br>
<font size="2" face="sans-serif">Additional answer: Yes, always in C, at least for now, since the only kind of try-catch in C would be to handle floating-point exceptions. That means even detecting exceptions by conditional branches would work.</font><br>
<br>
<br>
<font size="2" face="sans-serif">Conclusion: The catches can be put at the end of the try block if we think that's the best place for them from a usability point of view, with only limited extra cost for single pass compilers.</font><br>
<br>
<font size="2" face="sans-serif">- Ian McIntosh IBM Canada Lab Compiler Back End Support and Development<br>
</font><br>
<br>
<img width="16" height="16" src="cid:1__=0ABBF67CDF12B9D28f9e8a93df938@ca.ibm.com" border="0" alt="Inactive hide details for David Hough CFP ---2014-06-05 07:27:12 PM---Alternate Exception Handling Syntax How fast you can driv"><font size="2" color="#424282" face="sans-serif">David Hough CFP ---2014-06-05 07:27:12 PM---Alternate Exception Handling Syntax How fast you can drive a car depends on how fast you can stop</font><br>
<br>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr valign="top"><td width="1%"><img width="96" height="1" src="cid:2__=0ABBF67CDF12B9D28f9e8a93df938@ca.ibm.com" border="0" alt=""><br>
<ul style="padding-left: 4pt"><font size="1" color="#5F5F5F" face="sans-serif">From:</font></ul>
</td><td width="100%"><img width="1" height="1" src="cid:2__=0ABBF67CDF12B9D28f9e8a93df938@ca.ibm.com" border="0" alt=""><br>
<font size="1" face="sans-serif">David Hough CFP <pcfp@oakapple.net></font></td></tr>
<tr valign="top"><td width="1%"><img width="96" height="1" src="cid:2__=0ABBF67CDF12B9D28f9e8a93df938@ca.ibm.com" border="0" alt=""><br>
<ul style="padding-left: 4pt"><font size="1" color="#5F5F5F" face="sans-serif">To:</font></ul>
</td><td width="100%"><img width="1" height="1" src="cid:2__=0ABBF67CDF12B9D28f9e8a93df938@ca.ibm.com" border="0" alt=""><br>
<font size="1" face="sans-serif">cfp-interest@ucbtest.org, </font></td></tr>
<tr valign="top"><td width="1%"><img width="96" height="1" src="cid:2__=0ABBF67CDF12B9D28f9e8a93df938@ca.ibm.com" border="0" alt=""><br>
<ul style="padding-left: 4pt"><font size="1" color="#5F5F5F" face="sans-serif">Date:</font></ul>
</td><td width="100%"><img width="1" height="1" src="cid:2__=0ABBF67CDF12B9D28f9e8a93df938@ca.ibm.com" border="0" alt=""><br>
<font size="1" face="sans-serif">2014-06-05 07:27 PM</font></td></tr>
<tr valign="top"><td width="1%"><img width="96" height="1" src="cid:2__=0ABBF67CDF12B9D28f9e8a93df938@ca.ibm.com" border="0" alt=""><br>
<ul style="padding-left: 4pt"><font size="1" color="#5F5F5F" face="sans-serif">Subject:</font></ul>
</td><td width="100%"><img width="1" height="1" src="cid:2__=0ABBF67CDF12B9D28f9e8a93df938@ca.ibm.com" border="0" alt=""><br>
<font size="1" face="sans-serif">[Cfp-interest] draft of syntax discussion for C committee</font></td></tr>
<tr valign="top"><td width="1%"><img width="96" height="1" src="cid:2__=0ABBF67CDF12B9D28f9e8a93df938@ca.ibm.com" border="0" alt=""><br>
<ul style="padding-left: 4pt"><font size="1" color="#5F5F5F" face="sans-serif">Sent by:</font></ul>
</td><td width="100%"><img width="1" height="1" src="cid:2__=0ABBF67CDF12B9D28f9e8a93df938@ca.ibm.com" border="0" alt=""><br>
<font size="1" face="sans-serif">cfp-interest-bounces@oakapple.net</font></td></tr>
</table>
<hr width="100%" size="2" align="left" noshade style="color:#8091A5; "><br>
<br>
<br>
<tt><font size="2"><br>
<br>
Alternate Exception Handling Syntax<br>
<br>
<br>
How fast you can drive a car depends on how fast you can stop<br>
<br>
<br>
Alternate Exception Handling is specified in Chapter 8 of IEEE 754-2008.<br>
It's a series of recommendations to programming environments about what<br>
kinds of facilities to provide in languages for portable numeric <br>
programming. Some of these recommendations have to do with changes<br>
of control flow, and the best syntax to propose for these is the subject<br>
of this note.<br>
<br>
The overall idea is that the normal case should go as fast as possible<br>
for performance reasons, so testing for exceptional conditions should not<br>
slow it down. Likewise the normal case should terminate as quickly as<br>
possible when exceptional conditions arise, lest (particularly in a loop<br>
terminated by a floating-point conditional test) it get into an expensive<br>
or infinite loop.<br>
<br>
The previous IEEE 754-1985 recommended traps on exceptions. These are<br>
implemented in most IEEE 754 hardware systems, but they are so low level<br>
that they are not used<br>
much except for debugging, where they can be easily used to stop the <br>
program altogether. It is not possible to write portable code to<br>
handle a hardware trap and continue in any useful way. <br>
But if free testing for exceptions is built into the hardware without<br>
slowing down the normal case, how can we make it available to the application<br>
programmer?<br>
<br>
Thus 754-2008<br>
recommends alternate exception handling at a level that is meaningful<br>
to the application programmer, leaving the details of hardware trapping<br>
to the compiler, run time library, and operating system. It is also<br>
possible to implement 754-2008 alternate exception handling without hardware<br>
traps, but with significant performance penalties for either the normal case <br>
or exceptional case.<br>
<br>
The general programming paradigm as it might be naturally<br>
expressed in many languages is<br>
<br>
try {<br>
normal case code...<br>
}<br>
catch (floating-point exception-list) {<br>
exceptional case code...<br>
}<br>
following code...<br>
<br>
The normal case code is executed; if any of the exceptions in the list arises,<br>
the normal case code is interrupted as quickly as possible (and thus its<br>
output variables may be in an indeterminate state) and the exceptional case<br>
code is executed. In either case, after the normal case terminates<br>
normally or the exceptional case terminates, the "following code" is executed.<br>
<br>
There are versions of try/catch in standard C++, java, C#, perl, php, python,<br>
matlab. <br>
There are try/catch extensions in at least two Fortran compilers <br>
targeting .NET applications.<br>
These are all very similar but each slightly different. <br>
<br>
ruby has a somewhat<br>
more different version; any begin/end compound statement may have one or<br>
more rescue clauses corresponding to catch; there is no explicit try keyword.<br>
<br>
Naturally, for C, the closest analog is C++. <br>
C++ catch clauses have as<br>
arguments a parameter and its type. The parameter is set by the system<br>
for standard exceptions and by the programmer for programmer-defined exceptions<br>
generated with the throw() function; the catch clause is matched to the<br>
throw by the type of the thrown object. There is also a catch(...)<br>
syntax to catch all unspecified exceptions.<br>
<br>
Unlike most of the exceptions for which try/catch was designed, some <br>
floating-point exceptions arise frequently - inexact especially and <br>
underflow in some programs - and the default treatment of continuing<br>
execution with a prescribed result and raising a flag should be in force<br>
if no alternate treatment is called out in a catch clause.<br>
<br>
So much of C++ exception handling is unneeded to support 754-2008<br>
floating-point alternate exception handling:<br>
* no need to throw()<br>
* no need to catch(...) unspecified exceptions<br>
* catch clause is matched by exception rather than type -<br>
in standard C, exceptions receive names in <fenv.h> like FE_INVALID<br>
<br>
Furthermore there is another difference important for performance:<br>
whereas in C++ the code in the try clause is compiled without reference <br>
to subsequent catch clauses, for floating-point purposes it is usually<br>
desirable or necessary to know which exceptions are to be trapped.<br>
If the implementation is to be by traps, a trap handler has to be set<br>
up before the try clause and torn down on exit; if the implementation<br>
is to be by conditional branches on operands and results, that code<br>
has to be generated inline in the try clause. As a consequence,<br>
a strictly one-pass C<br>
compiler that could not exploit hardware traps would not be able to<br>
implement alternate exception handling fully and efficiently - it would<br>
have to test exception flags at the end of the try clause, and rely<br>
on the programmer to code in such a way that no expensive or infinite<br>
loop arises in the try clause if an exception arises. <br>
Furthermore, a little-appreciated but important requirement of 754-1985<br>
and 754-2008 is that exact underflow conditions must be detected by<br>
trapping (1985) or alternate exception handling (2008) <br>
if enabled, even though the underflow flag is not raised (and thus can't be<br>
used to detect exact underflow).<br>
<br>
The point of this very long preamble is that, syntactically, the catch<br>
clause for floating-point exceptions should be seen before the try clause<br>
rather than afterward as it is in most languages. One can imagine<br>
having the catch before, in which case the keyword should perhaps be<br>
different:<br>
<br>
catch_fe( exception-list) {<br>
exceptional case code...<br>
}<br>
try {<br>
normal case code...<br>
}<br>
<br>
or having it within the try clause:<br>
<br>
try {<br>
catch_fe( exception-list) {<br>
exceptional case code...<br>
}<br>
normal case code...<br>
}<br>
<br>
or allowing an optional red-flag pragma to warn one-pass compilers:<br>
<br>
try {<br>
#pragma STDC FENV_CATCH_AHEAD exception-list<br>
normal case code...<br>
}<br>
catch_fe (floating-point exception-list) {<br>
exceptional case code...<br>
}<br>
<br>
But having to specify the same exception-list in two different places<br>
seems error-prone.<br>
<br>
<br>
One result of preserving some form of try/catch syntax is that <br>
floating-point<br>
exception handling could be added to C++ with minimal syntactic effort, <br>
and most of<br>
C++ exception handling could be added to C with minimal syntactic effort.<br>
If that compatibility is deemed to be of low value, <br>
then there are other alternatives.<br>
<br>
<br>
First, since the explicit try clause is not really needed, one could<br>
define catch_fe clauses for any compound statement delimited by curly<br>
brackets, and instead of adding a catch_fe keyword, it could be a <br>
variety of pragma:<br>
<br>
<br>
{<br>
{<br>
#pragma STDC FENV_CATCH exception-list <br>
exceptional case code...<br>
}<br>
normal case code...<br>
}<br>
<br>
It's exactly the same try/catch semantics as what we started with, <br>
but in syntax not particularly close to C++ or anybody else's try/catch.<br>
However it does match other #pragma's <br>
having scope in compound statements or in files,<br>
that are already in C,<br>
or are already in<br>
previous floating-point extension reports going through the approval<br>
process, or that are being considered to control other aspects<br>
of floating-point code generation.<br>
<br>
<br>
While the C floating-point extensions discussion group could pursue any of<br>
these directions and report the results to the C committee,<br>
we'd appreciate early feedback and direction from the C committee<br>
as to which seems the most acceptable, or whether there's some better<br>
C-like way to express the semantics. The semantic content is pretty<br>
much the same with all, but the syntax possibilities vary widely.<br>
_______________________________________________<br>
Cfp-interest mailing list<br>
Cfp-interest@oakapple.net<br>
</font></tt><tt><font size="2"><a href="http://mailman.oakapple.net/mailman/listinfo/cfp-interest">http://mailman.oakapple.net/mailman/listinfo/cfp-interest</a></font></tt><tt><font size="2"><br>
<br>
</font></tt><br>
<br>
</body></html>