<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.msonormal0, li.msonormal0, div.msonormal0
        {mso-style-name:msonormal;
        mso-margin-top-alt:auto;
        margin-right:0in;
        mso-margin-bottom-alt:auto;
        margin-left:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">Oh I like Option 4.  I think I understand what you mean.  Clang would create and insert a “floating point region statement” into the code stream whenever we need to modify the floating point state.
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Globally there is the floating point state that comes from the command line options.  Any pragma that modifies the floating point state must occur at the start of a block, this would get encoded into FloatingPointRegionStmt. Any blocks
 nested within this block takes the settings of the outer block. The floating point state reverts to the surrounding state when the block is exited.  Expression nodes no longer need to carry around FPOptions.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">float f(float a, float b) {<o:p></o:p></p>
<p class="MsoNormal">#pragma float_control(except, off) // the floating point environment from the command line is merged with the settings from the pragma and inserted at the beginning of the compound statement<o:p></o:p></p>
<p class="MsoNormal">return a*b + 3;<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Using Trailing storage on BinaryOperator is hard because CompoundAssignment derives from BinaryOperator and Trailing storage demands that BinaryOperator be finalized.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Also I got an email a while ago – I think that floating point state also affects complex floating point literals. Intrinsics are called for these literals and so we’d need the information during codegen for those expressions too.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b>From:</b> Serge Pavlov <sepavloff@gmail.com> <br>
<b>Sent:</b> Thursday, March 12, 2020 2:24 AM<br>
<b>To:</b> Clang Dev <cfe-dev@lists.llvm.org><br>
<b>Cc:</b> hokein@google.com; Sam McCall <sammccall@google.com>; Blower, Melanie I <melanie.blower@intel.com>; Theko Lekena <mlekena@skidmore.edu>; Nicolas Lesser <blitzrakete@gmail.com>; Han Shen <shenhan@google.com>; Robinson, Paul <paul.robinson@sony.com><br>
<b>Subject:</b> Design of FPOptions<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">Hi all,<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">There are development efforts aimed at reducing space occupied by the field FPFeatures (<a href="https://reviews.llvm.org/D72841">https://reviews.llvm.org/D72841</a>). The expected result is reduction of the FPFeatures size from 8 bits
 to 7, so it is really a battle for bit. I have concern that such work can impact readability and maintainability of the code and would like to discuss alternative ways.<br>
<br>
<b>Background</b><br>
<br>
There are two main things that form background of the problem.<br>
<br>
First, operations that involve floating point arguments need to specify floating point environment. The latter is comprised of bits of hardware state registers  (rounding direction, denormals behavior, exception mask) and options and hints provided by user
 to compiler (whether NANs may occur, shall sign of zero be conserved, may exceptions be ignored). The list of relevant options was discussed in
<a href="http://lists.llvm.org/pipermail/llvm-dev/2020-January/138652.html">http://lists.llvm.org/pipermail/llvm-dev/2020-January/138652.html</a>. It is convenient to collect all aspects of the FP environment into one object, this is what class FPOptions does.
 Now this class contains only few attributes but in <a href="https://reviews.llvm.org/D72841">
https://reviews.llvm.org/D72841</a> an attempt was made to extend it in right direction.<br>
<br>
Second, the Clang internal representation (AST) was implemented to be as compact as possible. The dark side of this principle is inconvenient class organization and diffuse class boundaries, - derived classes keep their states in parent class fields, which
 are fixed in size. FP environment now is represented by a field in the class BinaryOperatorBitfields and is only 8 bits in size.<br>
<br>
<b>The problem</b><br>
<br>
8 bits is too few to keep all FP related state and options. So in <a href="https://reviews.llvm.org/D72841">
https://reviews.llvm.org/D72841</a> FPOptions was moved out of BinaryOperatorBitfields and made a field in classes UnaryOperator, BinaryOperator, CallExpr and CXXOperatorCallExpr. It is a step in right direction as, for example, now UnaryOperator does not have
 FPOption.<br>
<br>
This change however resulted in that every instance of BinaryOperator, CallExpr and other now increase in size. To reduce the space refactoring of
<a href="https://reviews.llvm.org/D72841">https://reviews.llvm.org/D72841</a> was started.<br>
<br>
Current support of FP environment in clang is weak, ongoing development in this direction will eventually increase size required for FP state and options and increase number of AST nodes that require knowledge of FP environment (these could be FloatingLiteral,
 InitListExpr, CXXDefaultArgExpr and some other). We must elaborate solution that allow future extensions without massive changes.<br>
<br>
<b>Possible solutions</b><br>
<br>
1. Consider memory consumption as inevitable evil and add FPOtions to every node where it is needed.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><br>
2. Add FPOptions to subclasses, for example FloatingUnaryOperator and similar. It however would swamp class hierarchy with duplicates and make handling AST more complex, as we use static polymorphism, not dynamic.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><br>
3. Use trailing objects. While this way is natural when the size of additional information is variable, using trailing objects to keep just some fields of an object is inconvenient.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><br>
4. Keep FPOptions is a special node, say FloatingPointRegionStmt. As now FP environment can be modified only at block and function level, actually the same FPOption is replicated to all nodes of that block. This FloatingPointRegionStmt would be similar to nodes
 like ExprWithCleanups, as it would represent a notion rather than source code construct. We also could embed FPOptions directly into CompoundStmt, but we must also provide similar facility at least for initializers and default arguments.<br>
<br>
I am inclined to the solution 4, as it reduces size consumption and at the same time does not limit implementation of FPOptions.<o:p></o:p></p>
</div>
<p class="MsoNormal"><br clear="all">
<o:p></o:p></p>
<div>
<div>
<p class="MsoNormal">Thanks,<br>
--Serge<o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>