Skip to content

Commit 31b511e

Browse files
authored
Merge pull request #17885 from eeckstein/fix-compactmap-perf
GenericSpecializer: Allow simple function specialization cycles.
2 parents 274114d + 1ebe33e commit 31b511e

File tree

3 files changed

+19
-12
lines changed

3 files changed

+19
-12
lines changed

lib/SILOptimizer/Utils/Generics.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ static bool createsInfiniteSpecializationLoop(ApplySite Apply) {
288288
auto *Callee = Apply.getCalleeFunction();
289289
SILFunction *Caller = nullptr;
290290
Caller = Apply.getFunction();
291+
int numAcceptedCycles = 1;
291292

292293
// Name of the function to be specialized.
293294
auto GenericFunc = Callee;
@@ -327,7 +328,13 @@ static bool createsInfiniteSpecializationLoop(ApplySite Apply) {
327328
if (growingSubstitutions(CurSpecializationInfo->getSubstitutions(),
328329
Apply.getSubstitutionMap())) {
329330
DEBUG(llvm::dbgs() << "Found a generic specialization loop!\n");
330-
return true;
331+
332+
// Accept a cycles up to a limit. This is necessary to generate
333+
// efficient code for some library functions, like compactMap, which
334+
// contain small specialization cycles.
335+
if (numAcceptedCycles == 0)
336+
return true;
337+
numAcceptedCycles--;
331338
}
332339
}
333340

test/SILOptimizer/generic_specialization_loops_detection_with_loops.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,16 @@
2121

2222
// Check that the compiler has produced a specialization information for a call-site that
2323
// was inlined from a specialized generic function.
24-
// CHECK-LABEL: // Generic specialization information for call-site $S044generic_specialization_loops_detection_with_C04foo4yyx_q_tr0_lF <Array<Int>, Array<Double>>
24+
// CHECK-LABEL: // Generic specialization information for call-site $S044generic_specialization_loops_detection_with_C04foo4yyx_q_tr0_lFSaySays5UInt8VGG_SaySaySiGGTg5:
2525
// CHECK-NEXT: // Caller: $S044generic_specialization_loops_detection_with_C04foo4yyx_q_tr0_lFSi_SdTg5
2626
// CHECK-NEXT: // Parent: $S044generic_specialization_loops_detection_with_C04bar4yyx_q_tr0_lF
27-
// CHECK-NEXT: // Substitutions: <Int, Double>
27+
// CHECK-NEXT: // Substitutions: <Array<UInt8>, Array<Int>>
2828
// CHECK-NEXT: //
2929
// CHECK-NEXT: // Caller: $S044generic_specialization_loops_detection_with_C011testFooBar4yyF
3030
// CHECK-NEXT: // Parent: $S044generic_specialization_loops_detection_with_C04foo4yyx_q_tr0_lF
3131
// CHECK-NEXT: // Substitutions: <Int, Double>
3232
// CHECK-NEXT: //
33-
// CHECK-NEXT: apply %{{[0-9]+}}<Array<Int>, Array<Double>>
33+
// CHECK-NEXT: apply %{{.*}}Array<Array<UInt8>>
3434

3535
// Check specializations of mutually recursive functions which
3636
// may result in an infinite specialization loop.

test/SILOptimizer/generic_specialization_loops_detection_without_loops.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,13 @@ func flood2<T>(_ x: T) {
137137
@inline(never)
138138
public func run_TypeFlood(_ N: Int) {
139139
for _ in 1...N {
140-
flood3(Some1<Some1<Some1<Int>>>())
141-
flood3(Some1<Some1<Some0<Int>>>())
142-
flood3(Some1<Some0<Some1<Int>>>())
143-
flood3(Some1<Some0<Some0<Int>>>())
144-
flood3(Some0<Some1<Some1<Int>>>())
145-
flood3(Some0<Some1<Some0<Int>>>())
146-
flood3(Some0<Some0<Some1<Int>>>())
147-
flood3(Some0<Some0<Some0<Int>>>())
140+
flood2(Some1<Some1<Some1<Int>>>())
141+
flood2(Some1<Some1<Some0<Int>>>())
142+
flood2(Some1<Some0<Some1<Int>>>())
143+
flood2(Some1<Some0<Some0<Int>>>())
144+
flood2(Some0<Some1<Some1<Int>>>())
145+
flood2(Some0<Some1<Some0<Int>>>())
146+
flood2(Some0<Some0<Some1<Int>>>())
147+
flood2(Some0<Some0<Some0<Int>>>())
148148
}
149149
}

0 commit comments

Comments
 (0)