-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathd1246r1.bs
166 lines (137 loc) · 6.26 KB
/
d1246r1.bs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
<pre class='metadata'>
Title: The <code>no_float</code> function attribute
Shortname: P1246
Revision: 1
Audience: EWG
Status: P
Group: WG21
<!--URL: http://wg21.link/d1246r1-->
!Source: <a href="https://github.com/bcardosolopes/cpp-papers/blob/master/d1246r1.bs">github.com/bcardosolopes/cpp-papers/blob/master/d1246r1.bs</a>
Editor: Bruno Cardoso Lopes, Apple, [email protected]
Editor: JF Bastien, Apple, [email protected]
No abstract: true
Date: 2018-11-05
Markup Shorthands: markdown yes
<!--Toggle Diffs: yes-->
</pre>
Edit History {#edit}
============
r0 → r1 {#r0r1}
-------
Address feedback from discussions on [email protected]. The changelog adds:
- [[#bikeshed|Bikeshed]] section for alternative names for the attribute.
- [[#exp|Implementation experience]] section.
- Note on inlining in [[#proposal|Proposed Solution]].
- Note on attribute [[#sema|Semantics]].
Introduction {#intro}
============
Code generation for floating-point is usually controlled by compiler flags. In
[[Clang]] this can be achieved by invoking the compiler with
`-mno-implicit-float`, `-msoft-float` or via other target specific mechanisms,
for instance, compiling code for the [[Darwin]] kernel disables float by
default.
This is desirable because:
* Some hardware doesn't support floating-point at all, requiring "soft-float"
emulation of floating-point using integer instructions. This is inefficient
and bloats the final binary and developers often want to opt-out of it.
* Some code wants to avoid saving and restoring floating-point registers, for
example kernel syscalls don't want to trample over user-mode floating-point
registers. Saving and restoring registers can get expensive: even with a
conservative calling convention modern AVX512-enabled x86 CPUs have `ZMM`
registers of 64 bytes each (in the worst case 32 such registers must be
saved and restored).
This approach has many drawbacks:
* As is often the case with compiler flags, without changes to the Standard,
each vendor ends up with a different mode, harming portability.
* Different pieces of a project might want different floating-point code
generation; relying on extra compiler flags for specific translation units
in a project is brittle and also has maintenance and portability costs. For
instance, in an application one might want to opt out from floating-point
only for specific pieces (e.g. cryptography code and kernel level
`printf`-like utilities still want to use floating-point)
* Readability expectations: while maintaining and creating new code, the
user has to look into the build system setup to find out whether the code
in question can be translated to floating-point code. This might affect
assumptions about rounding mode, auto vectorization and other implementation
defined floating-point behavior.
Proposed Solution {#propsal}
=================
We propose a new function level attribute `no_float`. Attaching `no_float` to
a function means:
1. Floating-point types cannot be used directly in the function.
1. The function's parameters and return types cannot be floating-point types.
1. Other functions that use floating-point types can be called from one marked
with the `no_float` attribute as long as the callee's parameters and return
type aren't floating-point.
1. Implementations can define the inlining behavior. Example: can't inline
functions with incompatible attributes or if it does, it should to preserve
those attributes in some other manner.
1. No floating-point instructions should be emitted implicitly for the
function. It's implementation defined what should happen instead,
implementers might make it equivalent to what [[GCC]] and [[Clang]] do for
`-msoft-float` (disable auto-vectorization, inlined `memcpy` cannot use
SIMD registers, etc).
Issue: Alternatively for 3., we could make implementation defined what happens
for such cross-calls, the compiler could in theory codegen two versions of the
function, one with and another without and call the right one).
This attribute standardizes a combination of existing ad-hoc practices and
documents code's expectation: functions shouldn't inadvertently use
floating-point. Code fails to compile if the function uses floating-point, and
the compiler knows to further avoid implicitly add floating-point register /
instruction uses in the function.
Examples:
<xmp>
double h(double y) { return y + 0.3; }
double i(double y = 42.) { return y * 42.; }
double j() { return 0.2; }
[[no_float]] void g() {
j(); // ERROR: j()'s return type is floating-point.
h(a); // ERROR: h()'s parameter type is floating-point.
i(); // ERROR: i()'s parameter type is floating-point.
}
</xmp>
We also propose adding module-level attributes for this, see [[p1245r0]].
Semantics {#sema}
=========
There are concerns that by not emitting floating-point when using `no_float`
one could change the semantics of C++, which would make this attribute
unsuitable for standardization. However, we believe this is not the case
because since potential calling convention, vectorizer or rounding mode
behaviors are not something that are currently covered the abstract machine.
Implementation experience {#exp}
=========================
We don't provide a implementation for this at this time but it's worth
mentioning that all major pieces are already available in Clang. When
the compiler is invoked with `-mno-implicit-float`, clang inserts a
`noimplicitfloat` attribute for each function in the TU, which defaults
to use soft-float for those functions.
Bikeshed {#bikeshed}
========
Alternative names for the attribute:
- nofloat
- nofloatingpoint
- nofp
- noimplicitfloat
- noimplicitfp
- gpr_only
<pre class=biblio>
{
"p1245r0": {
"href": "http://wg21.link/p1245r0",
"title": "export module containing [[attribute]];",
"authors": ["Bruno Cardoso Lopes", "JF Bastien"]
},
"Clang": {
"href": "http://clang.llvm.org",
"title": "Clang: a C language family frontend for LLVM"
},
"GCC": {
"href": "https://gcc.gnu.org",
"title": "GCC, the GNU Compiler Collection"
},
"Darwin": {
"href": "https://en.wikipedia.org/wiki/Darwin_(operating_system)",
"title": "Darwin (operating system)"
}
}
</pre>