<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8">
</head>
<body>
<div style="font-family:sans-serif"><div style="white-space:normal">
<p dir="auto">On 1 Jan 2020, at 11:16, Mark de Wever wrote:</p>

</div>
<div style="white-space:normal"><blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px"><p dir="auto">This RFC asks the community for its interest in centralizing Clang's<br>
implementation limits and how you feel about the proposed approach.<br>
<br>
Abstract<br>
========<br>
<br>
At the moment the implementation limits of the Clang compiler are hidden<br>
in magic numbers in the code. These numbers sometimes differ between the<br>
frontend and the backend. They are not always properly guarded by compiler<br>
warnings, instead they trigger assertion failures.</p>
</blockquote></div>
<div style="white-space:normal">

<p dir="auto"><em>Technically</em>, crashing is still a valid way of indicating non-acceptance,<br>
although obviously I agree that we should diagnose these things properly.<br>
(They can’t just be warnings, though.)</p>

</div>
<div style="white-space:normal"><blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px"><p dir="auto">This proposal suggests a TableGen based solution to better maintain these<br>
limits. This solution will be able to generate a header and documentation<br>
of these limits. The latter is required by the C++ standard [implimits].</p>
</blockquote></div>
<div style="white-space:normal">

<p dir="auto">I think this is a great approach.</p>

</div>
<div style="white-space:normal"><blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px"><p dir="auto">The problem<br>
===========<br>
<br>
The proposal tries to solve 2 issues:<br>
* Implementation limits are not always clear and duplicated in the source.<br>
* Document C++ Implementation quantities  is required by the C++ standard<br>
  [implimits].</p>
</blockquote></div>
<div style="white-space:normal">

<p dir="auto">I suspect that the biggest part of this project by far will be testing<br>
these implementation limits and then figuring out all the places that they<br>
fall over.</p>

</div>
<div style="white-space:normal"><blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px"><p dir="auto">Unclear limits<br>
--------------<br>
<br>
The compiler has several limitations often 'hidden' as the width of a<br>
bit-field in a structure. This makes it hard to find these limits. Not<br>
only for our users but also for developers. While looking at a proper<br>
limit for the maximum width of a bit-field in the frontend I discovered<br>
it didn't matter what the frontend picked, the backend already had a<br>
limit [D71142]. To fix this issue the frontend and backend should have<br>
the same limit. To avoid duplicating the value it should be in a header<br>
available to the frontend and backend.</p>
</blockquote></div>
<div style="white-space:normal">

<p dir="auto">FWIW, we don’t generally refer to IRGen as the “backend”.</p>

<p dir="auto">In many cases, the right code change will probably be to introduce a<br>
static assertion linking the implementation limit to some value in code,<br>
rather than using the limit directly.  For example, many limits will<br>
be absolute numbers, and it is probably better to<br>
<code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">static_assert(IQ_MaxWidgets < (1ULL << SomeBitFieldWidth))</code> than to<br>
try to make that bit-field have the exact right width.  This is also<br>
a pattern that works even if the limit is stored in a normal field<br>
of type (say) <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">unsigned</code>; such places should also have a <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">static_assert</code><br>
in order to remind the reader/maintainer that there’s an implementation<br>
limit affected.</p>

<p dir="auto">John.</p>

</div>
<div style="white-space:normal"><blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px"><p dir="auto">Since the values are often stored in a bit-field there is no standard way<br>
to get the maximum value. This means the limit needs a small helper<br>
function to get the value, for example [D63975] uses<br>
`getMaxFunctionScopeDepth()`.<br>
<br>
<br>
Standard conformance<br>
--------------------<br>
<br>
This is rather simple the C++ standard Annex B states:<br>
   Because computers are finite, C++ implementations are inevitably<br>
   limited in the size of the programs they can successfully process.<br>
   Every implementation shall document those limitations where known.<br>
<br>
Currently this documentation is not available.<br>
<br>
<br>
The proposed solution<br>
=====================<br>
<br>
In order to solve this issue I created a proof-of-concept solution<br>
[D72053]. It contains a new file<br>
clang/include/clang/Basic/ImplementationQuantities.td with two TableGen<br>
generators which create:<br>
* An inc file with a set of constants containing the limits. This file<br>
  $BUILD_DIR/tools/clang/include/clang/Basic/ImplementationQuantities.inc<br>
  is included in the header<br>
  clang/include/clang/Basic/ImplementationQuantities.h.<br>
* The document clang/docs/ImplementationQuantities.rst<br>
  This document documents the limits of Clang. These limits include, but<br>
  are not limited to the quantities in [implimits].<br>
<br>
The quantity limit has the following possible types:<br>
* The quantity is limited by the number of bits in a bit-field. TableGen<br>
  generates two constants:<br>
  * FieldNameBits, the number of bits in the bit-field.<br>
  * MaxFieldName, the maximum value of the bit-field. (This assumes all<br>
    bit-fields can be stored in an unsigned.)<br>
* The quantity is limited by a value. TableGen generates one constant:<br>
  * MaxFieldName, the maximum value of the field.<br>
* The quantity's limit is determined by a compiler flag. TableGen<br>
  generates one constant:<br>
  * FieldNameDefault, the default value of the compiler flag.<br>
* The quantity's limit cannot be expressed in a number. For example it<br>
  depends on the stack size or available memory of the system. In this<br>
  case TableGen generates no constant, only documentation.<br>
<br>
For all types documentation is generated. The documentation shows the<br>
description of the limit and the limit implemented in Clang. If the<br>
recommended value is not 0 it is a value described in the C++ Standard. In<br>
this case the recommended value is shown in the documentation.<br>
<br>
<br>
Questions<br>
=========<br>
<br>
* If this proposal is accepted how to we make sure the document is updated<br>
  before releasing a new version of clang?<br>
* The compiler flag limits are also documented in the UserManual. This means<br>
  these limits are still duplicated. Do we want to let the UserManual also be<br>
  generated and use the values here or just keep the duplication?<br>
<br>
<br>
Bikeshed<br>
========<br>
<br>
I picked IQ for the namespace of the quantities since it's short and not<br>
often used in the codebase so it's easy greppable.<br>
<br>
<br>
[implimits] <a href="http://eel.is/c++draft/implimits" style="color:#777">http://eel.is/c++draft/implimits</a><br>
[D63975] <a href="https://reviews.llvm.org/D63975" style="color:#777">https://reviews.llvm.org/D63975</a><br>
[D71142] <a href="https://reviews.llvm.org/D71142" style="color:#777">https://reviews.llvm.org/D71142</a><br>
[D72053] <a href="https://reviews.llvm.org/D72053" style="color:#777">https://reviews.llvm.org/D72053</a><br>
<br>
<br>
Kind regards,<br>
Mark de Wever</p>
</blockquote></div>
<div style="white-space:normal">
</div>
</div>
</body>
</html>