Skip to content

Commit 99532a8

Browse files
committed
fix issue 16503 : add fast math bridge for LDC
1 parent a3f205a commit 99532a8

File tree

4 files changed

+64
-24
lines changed

4 files changed

+64
-24
lines changed

std/experimental/ndslice/internal.d

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,35 @@ import std.traits;
55
import std.meta;
66
import std.experimental.ndslice.slice;
77

8+
/+
9+
fastmath do nothing here,
10+
but remove constraint for LDC that operations for pointer's computations
11+
maybe mixed up with callers computations if both computations has fastmath attribute.
12+
So, it is just a bridge between two fastmath functions.
13+
fmb alias is used to relax users.
14+
+/
15+
package alias fmb = fastmath;
16+
17+
version(LDC)
18+
{
19+
static import ldc.attributes;
20+
alias fastmath = ldc.attributes.fastmath;
21+
}
22+
else
23+
{
24+
alias fastmath = fastmathDummy;
25+
}
26+
27+
enum FastmathDummy { init }
28+
FastmathDummy fastmathDummy() { return FastmathDummy.init; }
29+
830
template PtrTuple(Names...)
931
{
1032
@LikePtr struct PtrTuple(Ptrs...)
1133
if (allSatisfy!(isSlicePointer, Ptrs) && Ptrs.length == Names.length)
1234
{
35+
@fmb:
36+
1337
Ptrs ptrs;
1438

1539
void opOpAssign(string op)(sizediff_t shift)
@@ -57,6 +81,7 @@ struct PtrShell(Range)
5781
{
5882
sizediff_t _shift;
5983
Range _range;
84+
@fmb:
6085

6186
enum hasAccessByRef = isPointer!Range ||
6287
__traits(compiles, &_range[0]);
@@ -174,13 +199,19 @@ private template PtrTupleFrontMembers(Names...)
174199
{
175200
alias Top = Names[0..$-1];
176201
enum int m = Top.length;
202+
/+
203+
fastmath do nothing here,
204+
but remove constraint for LDC that operations for pointer's computations
205+
maybe mixed up with callers computations if both computations has fastmath attribute.
206+
So, it is just a bridge between two fastmath functions.
207+
+/
177208
enum PtrTupleFrontMembers = PtrTupleFrontMembers!Top
178209
~ "
179-
@property auto ref " ~ Names[$-1] ~ "() {
210+
@fmb @property auto ref " ~ Names[$-1] ~ "() {
180211
return _ptrs__[" ~ m.stringof ~ "][0];
181212
}
182213
static if (!__traits(compiles, &(_ptrs__[" ~ m.stringof ~ "][0])))
183-
@property auto ref " ~ Names[$-1] ~ "(T)(auto ref T value) {
214+
@fmb @property auto ref " ~ Names[$-1] ~ "(T)(auto ref T value) {
184215
return _ptrs__[" ~ m.stringof ~ "][0] = value;
185216
}
186217
";
@@ -193,6 +224,7 @@ private template PtrTupleFrontMembers(Names...)
193224

194225
@LikePtr struct Pack(size_t N, Range)
195226
{
227+
@fmb:
196228
alias Elem = Slice!(N, Range);
197229
alias PureN = Elem.PureN;
198230
alias PureRange = Elem.PureRange;
@@ -212,31 +244,31 @@ private template PtrTupleFrontMembers(Names...)
212244
@LikePtr struct Map(Range, alias fun)
213245
{
214246
Range _ptr;
215-
mixin PropagatePtr;
216-
247+
// can not use @fmb here because fun maybe an LLVM function.
217248
auto ref opIndex(size_t index)
218249
{
219250
return fun(_ptr[index]);
220251
}
252+
mixin PropagatePtr;
221253
}
222254

223255
private mixin template PropagatePtr()
224256
{
225-
void opOpAssign(string op)(sizediff_t shift)
257+
@fmb void opOpAssign(string op)(sizediff_t shift)
226258
if (op == `+` || op == `-`)
227259
{
228260
mixin (`_ptr ` ~ op ~ `= shift;`);
229261
}
230262

231-
auto opBinary(string op)(sizediff_t shift)
263+
@fmb auto opBinary(string op)(sizediff_t shift)
232264
if (op == `+` || op == `-`)
233265
{
234266
auto ret = this;
235267
ret.opOpAssign!op(shift);
236268
return ret;
237269
}
238270

239-
auto opUnary(string op)()
271+
@fmb auto opUnary(string op)()
240272
if (op == `++` || op == `--`)
241273
{
242274
mixin(op ~ `_ptr;`);
@@ -271,8 +303,6 @@ alias RangeOf(T : Slice!(N, Range), size_t N, Range) = Range;
271303

272304
template isMemory(T)
273305
{
274-
import std.experimental.ndslice.slice : PtrTuple;
275-
import std.experimental.ndslice.selection : Map, Pack;
276306
static if (isPointer!T)
277307
enum isMemory = true;
278308
else

std/experimental/ndslice/iteration.d

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ import std.meta;
104104
import std.experimental.ndslice.internal;
105105
import std.experimental.ndslice.slice; //: Slice;
106106

107+
@fmb:
108+
107109
private enum _swappedCode = q{
108110
with (slice)
109111
{
@@ -130,7 +132,7 @@ See_also: $(LREF everted), $(LREF transposed)
130132
+/
131133
template swapped(size_t dimensionA, size_t dimensionB)
132134
{
133-
auto swapped(size_t N, Range)(Slice!(N, Range) slice)
135+
@fmb auto swapped(size_t N, Range)(Slice!(N, Range) slice)
134136
{
135137
{
136138
enum i = 0;
@@ -239,7 +241,7 @@ Returns:
239241
+/
240242
template rotated(size_t dimensionA, size_t dimensionB)
241243
{
242-
auto rotated(size_t N, Range)(Slice!(N, Range) slice, sizediff_t k = 1)
244+
@fmb auto rotated(size_t N, Range)(Slice!(N, Range) slice, sizediff_t k = 1)
243245
{
244246
{
245247
enum i = 0;
@@ -408,7 +410,7 @@ See_also: $(LREF swapped), $(LREF everted)
408410
template transposed(Dimensions...)
409411
if (Dimensions.length)
410412
{
411-
Slice!(N, Range) transposed(size_t N, Range)(auto ref Slice!(N, Range) slice)
413+
@fmb Slice!(N, Range) transposed(size_t N, Range)(auto ref Slice!(N, Range) slice)
412414
{
413415
mixin DimensionsCountCTError;
414416
foreach (i, dimension; Dimensions)
@@ -550,7 +552,7 @@ Returns:
550552
template reversed(Dimensions...)
551553
if (Dimensions.length)
552554
{
553-
auto reversed(size_t N, Range)(Slice!(N, Range) slice)
555+
@fmb auto reversed(size_t N, Range)(Slice!(N, Range) slice)
554556
{
555557
foreach (i, dimension; Dimensions)
556558
{
@@ -664,7 +666,7 @@ Returns:
664666
template strided(Dimensions...)
665667
if (Dimensions.length)
666668
{
667-
auto strided(size_t N, Range)(Slice!(N, Range) slice, Repeat!(Dimensions.length, size_t) factors)
669+
@fmb auto strided(size_t N, Range)(Slice!(N, Range) slice, Repeat!(Dimensions.length, size_t) factors)
668670
body
669671
{
670672
foreach (i, dimension; Dimensions)
@@ -890,7 +892,7 @@ Returns:
890892
template dropOne(Dimensions...)
891893
if (Dimensions.length)
892894
{
893-
Slice!(N, Range) dropOne(size_t N, Range)(Slice!(N, Range) slice)
895+
@fmb Slice!(N, Range) dropOne(size_t N, Range)(Slice!(N, Range) slice)
894896
{
895897
foreach (i, dimension; Dimensions)
896898
{
@@ -931,7 +933,7 @@ body
931933
template dropBackOne(Dimensions...)
932934
if (Dimensions.length)
933935
{
934-
Slice!(N, Range) dropBackOne(size_t N, Range)(Slice!(N, Range) slice)
936+
@fmb Slice!(N, Range) dropBackOne(size_t N, Range)(Slice!(N, Range) slice)
935937
{
936938
foreach (i, dimension; Dimensions)
937939
{
@@ -1027,7 +1029,7 @@ Returns:
10271029
template dropExactly(Dimensions...)
10281030
if (Dimensions.length)
10291031
{
1030-
Slice!(N, Range) dropExactly(size_t N, Range)(Slice!(N, Range) slice, Repeat!(Dimensions.length, size_t) ns)
1032+
@fmb Slice!(N, Range) dropExactly(size_t N, Range)(Slice!(N, Range) slice, Repeat!(Dimensions.length, size_t) ns)
10311033
body
10321034
{
10331035
foreach (i, dimension; Dimensions)
@@ -1055,7 +1057,7 @@ body
10551057
template dropBackExactly(Dimensions...)
10561058
if (Dimensions.length)
10571059
{
1058-
Slice!(N, Range) dropBackExactly(size_t N, Range)(Slice!(N, Range) slice, Repeat!(Dimensions.length, size_t) ns)
1060+
@fmb Slice!(N, Range) dropBackExactly(size_t N, Range)(Slice!(N, Range) slice, Repeat!(Dimensions.length, size_t) ns)
10591061
body
10601062
{
10611063
foreach (i, dimension; Dimensions)
@@ -1116,7 +1118,7 @@ Returns:
11161118
template drop(Dimensions...)
11171119
if (Dimensions.length)
11181120
{
1119-
Slice!(N, Range) drop(size_t N, Range)(Slice!(N, Range) slice, Repeat!(Dimensions.length, size_t) ns)
1121+
@fmb Slice!(N, Range) drop(size_t N, Range)(Slice!(N, Range) slice, Repeat!(Dimensions.length, size_t) ns)
11201122
body
11211123
{
11221124
foreach (i, dimension; Dimensions)
@@ -1144,7 +1146,7 @@ body
11441146
template dropBack(Dimensions...)
11451147
if (Dimensions.length)
11461148
{
1147-
Slice!(N, Range) dropBack(size_t N, Range)(Slice!(N, Range) slice, Repeat!(Dimensions.length, size_t) ns)
1149+
@fmb Slice!(N, Range) dropBack(size_t N, Range)(Slice!(N, Range) slice, Repeat!(Dimensions.length, size_t) ns)
11481150
body
11491151
{
11501152
foreach (i, dimension; Dimensions)

std/experimental/ndslice/selection.d

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ import std.meta; //: allSatisfy;
6060
import std.experimental.ndslice.internal;
6161
import std.experimental.ndslice.slice; //: Slice;
6262

63+
@fmb:
64+
6365
/++
6466
Creates a packed slice, i.e. slice of slices.
6567
The function does not carry out any calculations, it simply returns the same
@@ -73,7 +75,7 @@ Returns:
7375
+/
7476
template pack(K...)
7577
{
76-
auto pack(size_t N, Range)(auto ref Slice!(N, Range) slice)
78+
@fmb auto pack(size_t N, Range)(auto ref Slice!(N, Range) slice)
7779
{
7880
template Template(size_t NInner, Range, R...)
7981
{
@@ -930,6 +932,7 @@ auto byElement(size_t N, Range)(auto ref Slice!(N, Range) slice)
930932
+/
931933
static struct ByElement
932934
{
935+
@fmb:
933936
This _slice;
934937
size_t _length;
935938
size_t[N] _indexes;
@@ -1436,6 +1439,7 @@ auto byElementInStandardSimplex(size_t N, Range)(auto ref Slice!(N, Range) slice
14361439
+/
14371440
static struct ByElementInTopSimplex
14381441
{
1442+
@fmb:
14391443
This _slice;
14401444
size_t _length;
14411445
size_t maxHypercubeLength;
@@ -1676,7 +1680,7 @@ template IndexSlice(size_t N)
16761680
{
16771681
private size_t[N-1] _lengths;
16781682

1679-
size_t[N] opIndex(size_t index) const
1683+
@fmb size_t[N] opIndex(size_t index) const
16801684
{
16811685
size_t[N] indexes = void;
16821686
foreach_reverse (i; Iota!(0, N - 1))
@@ -1786,7 +1790,7 @@ struct IotaMap()
17861790
{
17871791
enum bool empty = false;
17881792

1789-
static size_t opIndex()(size_t index) @safe pure nothrow @nogc @property
1793+
@fmb static size_t opIndex()(size_t index) @safe pure nothrow @nogc @property
17901794
{
17911795
pragma(inline, true);
17921796
return index;
@@ -1912,6 +1916,8 @@ template RepeatSlice(size_t N, T)
19121916
private alias UT = T;
19131917
private UT _value;
19141918

1919+
@fmb:
1920+
19151921
ref T opIndex(sizediff_t)
19161922
{
19171923
return _value;
@@ -1968,7 +1974,7 @@ template mapSlice(fun...)
19681974
if (fun.length)
19691975
{
19701976
///
1971-
auto mapSlice(size_t N, Range)
1977+
@fmb auto mapSlice(size_t N, Range)
19721978
(auto ref Slice!(N, Range) tensor)
19731979
{
19741980
// this static if-else block

std/experimental/ndslice/slice.d

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,6 +1202,8 @@ struct Slice(size_t _N, _Range)
12021202
&& (isPointer!_Range || is(typeof(_Range.init[size_t.init]))))
12031203
|| is(_Range == Slice!(N1, Range1), size_t N1, Range1)))
12041204
{
1205+
@fmb:
1206+
12051207
package:
12061208

12071209
enum doUnittest = is(_Range == int*) && _N == 1;

0 commit comments

Comments
 (0)