<html><body>
<p><font size="2" face="sans-serif">That's written nicely and describes the options well. &nbsp;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: &nbsp;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 &lt; n; ++i)<br>
{<br>
 &nbsp; &nbsp;. . .<br>
 &nbsp; &nbsp;break;                        /* At this point the address of the code after the loop is unknown but must be branched to. */<br>
 &nbsp; &nbsp;. . .<br>
}<br>
</font></ul>
<font size="2" face="sans-serif">Answer: &nbsp;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: &nbsp;Can a try-catch be compiled in one pass plus fixups?</font><br>
<br>
<font size="2" face="sans-serif">Answer: &nbsp;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: &nbsp;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: &nbsp;No. &nbsp;If trapping is being used then the trapping mechanism must be enabled at the beginning. &nbsp;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: &nbsp;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 &nbsp;initialize_try_block;</font><br>
<br>
<font size="2" face="sans-serif">        start_of_try_block:</font><br>
<font size="2" face="sans-serif">         &nbsp; &nbsp;. . . /* try block */</font><br>
<font size="2" face="sans-serif">        end_of_try_block:</font><br>
<font size="2" face="sans-serif">         &nbsp; &nbsp;goto &nbsp;after_catch_handlers;</font><br>
<br>
<font size="2" face="sans-serif">        initialize_try_block:</font><br>
<font size="2" face="sans-serif">         &nbsp; &nbsp;. . . initialize try block exception handling; . . .</font><br>
<font size="2" face="sans-serif">         &nbsp; &nbsp;goto &nbsp;start_of_try_block;</font><br>
<br>
<font size="2" face="sans-serif">        catch_handler_1:</font><br>
<font size="2" face="sans-serif">         &nbsp; &nbsp;. . .</font><br>
<font size="2" face="sans-serif">        catch_handler_2:</font><br>
<font size="2" face="sans-serif">         &nbsp; &nbsp;. . .</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: &nbsp;Yes, always in C, at least for now, since the only kind of try-catch in C would be to handle floating-point exceptions. &nbsp;That means even detecting exceptions by conditional branches would work.</font><br>
<br>
<br>
<font size="2" face="sans-serif">Conclusion: &nbsp;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 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IBM Canada Lab &nbsp; &nbsp; &nbsp; &nbsp; 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 &lt;pcfp@oakapple.net&gt;</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. &nbsp; &nbsp; &nbsp;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. &nbsp; &nbsp;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. &nbsp; &nbsp;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. &nbsp; &nbsp;It is not possible to write portable code to<br>
handle a hardware trap and continue in any useful way. &nbsp; &nbsp;<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. &nbsp; &nbsp; 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. &nbsp; &nbsp; &nbsp;In either case, after the normal case terminates<br>
normally or the exceptional case terminates, the &quot;following code&quot; 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. &nbsp; &nbsp;<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++. &nbsp; &nbsp;<br>
C++ catch clauses have as<br>
arguments a parameter and its type. &nbsp; &nbsp; 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. &nbsp; &nbsp; 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>
 &nbsp; in standard C, exceptions receive names in &lt;fenv.h&gt; 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. &nbsp; &nbsp; 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. &nbsp; &nbsp;<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, &nbsp;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. &nbsp; &nbsp;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. &nbsp; &nbsp;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>