Skip to content

Commit 8c2707c

Browse files
committed
Fix printing of (SIL)SpecializeAttr.
Print the requirements that are in the `@_specialize` signature but aren’t part of the enclosing context, matching the previous form but after semantic analysis.
1 parent c8ac000 commit 8c2707c

File tree

3 files changed

+68
-31
lines changed

3 files changed

+68
-31
lines changed

lib/AST/Attr.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -561,13 +561,11 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
561561

562562
Printer << "exported: "<< exported << ", ";
563563
Printer << "kind: " << kind << ", ";
564+
SmallVector<Requirement, 4> requirementsScratch;
564565
ArrayRef<Requirement> requirements;
565566
if (auto sig = attr->getSpecializedSgnature())
566567
requirements = sig->getRequirements();
567568

568-
if (!requirements.empty()) {
569-
Printer << "where ";
570-
}
571569
std::function<Type(Type)> GetInterfaceType;
572570
auto *FnDecl = dyn_cast_or_null<AbstractFunctionDecl>(D);
573571
if (!FnDecl || !FnDecl->getGenericEnvironment())
@@ -580,7 +578,18 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
580578
GetInterfaceType = [=](Type Ty) -> Type {
581579
return GenericEnv->getSugaredType(Ty);
582580
};
581+
582+
if (auto sig = attr->getSpecializedSgnature()) {
583+
requirementsScratch = sig->requirementsNotSatisfiedBy(
584+
GenericEnv->getGenericSignature());
585+
requirements = requirementsScratch;
586+
}
583587
}
588+
589+
if (!requirements.empty()) {
590+
Printer << "where ";
591+
}
592+
584593
interleave(requirements,
585594
[&](Requirement req) {
586595
auto FirstTy = GetInterfaceType(req.getFirstType());

lib/SIL/SILPrinter.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3032,8 +3032,36 @@ void SILSpecializeAttr::print(llvm::raw_ostream &OS) const {
30323032

30333033
OS << "exported: " << exported << ", ";
30343034
OS << "kind: " << kind << ", ";
3035-
OS << "signature: ";
3036-
getSpecializedSignature()->print(OS);
3035+
3036+
auto requirements = getSpecializedSignature()->requirementsNotSatisfiedBy(
3037+
getFunction()->getGenericEnvironment()->getGenericSignature());
3038+
if (!requirements.empty()) {
3039+
OS << "where ";
3040+
SILFunction *F = getFunction();
3041+
assert(F);
3042+
auto GenericEnv = F->getGenericEnvironment();
3043+
interleave(requirements,
3044+
[&](Requirement req) {
3045+
if (!GenericEnv) {
3046+
req.print(OS, SubPrinter);
3047+
return;
3048+
}
3049+
// Use GenericEnvironment to produce user-friendly
3050+
// names instead of something like t_0_0.
3051+
auto FirstTy = GenericEnv->getSugaredType(req.getFirstType());
3052+
if (req.getKind() != RequirementKind::Layout) {
3053+
auto SecondTy =
3054+
GenericEnv->getSugaredType(req.getSecondType());
3055+
Requirement ReqWithDecls(req.getKind(), FirstTy, SecondTy);
3056+
ReqWithDecls.print(OS, SubPrinter);
3057+
} else {
3058+
Requirement ReqWithDecls(req.getKind(), FirstTy,
3059+
req.getLayoutConstraint());
3060+
ReqWithDecls.print(OS, SubPrinter);
3061+
}
3062+
},
3063+
[&] { OS << ", "; });
3064+
}
30373065
}
30383066

30393067
//===----------------------------------------------------------------------===//

test/SILOptimizer/eager_specialize.sil

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -359,20 +359,20 @@ bb0(%0 : $*S, %1 : $*S, %2 : $*S):
359359

360360
// Check specialized for 32 bits
361361
// specialized copyValueAndReturn<A>(A, s : inout A) -> A
362-
// CHECK-LABEL: sil shared [noinline] @$s16eager_specialize18copyValueAndReturn_1sxx_xztlFxxxRlze31_lIetilr_Tp5 : $@convention(thin) <τ_0_0 where τ_0_0 : _Trivial(32)> (@in τ_0_0, @inout τ_0_0) -> @out τ_0_0
363-
// CHECK: bb0(%0 : $*τ_0_0, %1 : $*τ_0_0, %2 : $*τ_0_0):
364-
// CHECK: copy_addr %2 to [initialization] %0 : $*τ_0_0
365-
// CHECK: destroy_addr %1 : $*τ_0_0
362+
// CHECK-LABEL: sil shared [noinline] @$s16eager_specialize18copyValueAndReturn_1sxx_xztlFxxxRlze31_lIetilr_Tp5 : $@convention(thin) <S where S : _Trivial(32)> (@in S, @inout S) -> @out S
363+
// CHECK: bb0(%0 : $*S, %1 : $*S, %2 : $*S):
364+
// CHECK: copy_addr %2 to [initialization] %0 : $*S
365+
// CHECK: destroy_addr %1 : $*S
366366
// CHECK: %5 = tuple ()
367367
// CHECK: return %5 : $()
368368
// CHECK: } // end sil function '$s16eager_specialize18copyValueAndReturn_1sxx_xztlFxxxRlze31_lIetilr_Tp5'
369369

370370
// Check specialized for 64 bits
371371
// specialized copyValueAndReturn<A>(A, s : inout A) -> A
372-
// CHECK-LABEL: sil shared [noinline] @$s16eager_specialize18copyValueAndReturn_1sxx_xztlFxxxRlze63_lIetilr_Tp5 : $@convention(thin) <τ_0_0 where τ_0_0 : _Trivial(64)> (@in τ_0_0, @inout τ_0_0) -> @out τ_0_0
373-
// CHECK: bb0(%0 : $*τ_0_0, %1 : $*τ_0_0, %2 : $*τ_0_0):
374-
// CHECK: copy_addr %2 to [initialization] %0 : $*τ_0_0
375-
// CHECK: destroy_addr %1 : $*τ_0_0
372+
// CHECK-LABEL: sil shared [noinline] @$s16eager_specialize18copyValueAndReturn_1sxx_xztlFxxxRlze63_lIetilr_Tp5 : $@convention(thin) <S where S : _Trivial(64)> (@in S, @inout S) -> @out S
373+
// CHECK: bb0(%0 : $*S, %1 : $*S, %2 : $*S):
374+
// CHECK: copy_addr %2 to [initialization] %0 : $*S
375+
// CHECK: destroy_addr %1 : $*S
376376
// CHECK: %5 = tuple ()
377377
// CHECK: return %5 : $()
378378
// CHECK: } // end sil function '$s16eager_specialize18copyValueAndReturn_1sxx_xztlFxxxRlze63_lIetilr_Tp5'
@@ -455,10 +455,10 @@ bb0(%0 : $*S, %1 : $*S, %2 : $*S):
455455

456456
// Check the specialization for _Trivial
457457
// specialized copyValueAndReturn2<A> (A, s : inout A) -> A
458-
// CHECK-LABEL: sil shared [noinline] @$s16eager_specialize19copyValueAndReturn2_1sxx_xztlFxxxRlzTlIetilr_Tp5 : $@convention(thin) <τ_0_0 where τ_0_0 : _Trivial> (@in τ_0_0, @inout τ_0_0) -> @out τ_0_0
459-
// CHECK: bb0(%0 : $*τ_0_0, %1 : $*τ_0_0, %2 : $*τ_0_0):
460-
// CHECK: copy_addr %2 to [initialization] %0 : $*τ_0_0
461-
// CHECK: destroy_addr %1 : $*τ_0_0
458+
// CHECK-LABEL: sil shared [noinline] @$s16eager_specialize19copyValueAndReturn2_1sxx_xztlFxxxRlzTlIetilr_Tp5 : $@convention(thin) <S where S : _Trivial> (@in S, @inout S) -> @out S
459+
// CHECK: bb0(%0 : $*S, %1 : $*S, %2 : $*S):
460+
// CHECK: copy_addr %2 to [initialization] %0 : $*S
461+
// CHECK: destroy_addr %1 : $*S
462462
// CHECK: %5 = tuple ()
463463
// CHECK: return %5 : $()
464464
// CHECK: } // end sil function '$s16eager_specialize19copyValueAndReturn2_1sxx_xztlFxxxRlzTlIetilr_Tp5'
@@ -510,10 +510,10 @@ bb0(%0 : $*S, %1 : $*S, %2 : $*S):
510510

511511
// Check for specialized function for _RefCountedObject
512512
// specialized copyValueAndReturn3<A> (A, s : inout A) -> A
513-
// CHECK-LABEL: sil shared [noinline] @$s16eager_specialize19copyValueAndReturn3_1sxx_xztlFxxxRlzRlIetilr_Tp5 : $@convention(thin) <τ_0_0 where τ_0_0 : _RefCountedObject> (@in τ_0_0, @inout τ_0_0) -> @out τ_0_0
514-
// CHECK: bb0(%0 : $*τ_0_0, %1 : $*τ_0_0, %2 : $*τ_0_0):
515-
// CHECK: copy_addr %2 to [initialization] %0 : $*τ_0_0
516-
// CHECK: destroy_addr %1 : $*τ_0_0
513+
// CHECK-LABEL: sil shared [noinline] @$s16eager_specialize19copyValueAndReturn3_1sxx_xztlFxxxRlzRlIetilr_Tp5 : $@convention(thin) <S where S : _RefCountedObject> (@in S, @inout S) -> @out S
514+
// CHECK: bb0(%0 : $*S, %1 : $*S, %2 : $*S):
515+
// CHECK: copy_addr %2 to [initialization] %0 : $*S
516+
// CHECK: destroy_addr %1 : $*S
517517
// CHECK: %5 = tuple ()
518518
// CHECK: return %5 : $()
519519
// CHECK: } // end sil function '$s16eager_specialize19copyValueAndReturn3_1sxx_xztlFxxxRlzRlIetilr_Tp5'
@@ -599,11 +599,11 @@ bb0(%0 : $*T, %1 : $*S):
599599

600600
// Check for specialized function for τ_0_0 == Int64
601601
// specialized checkExplicitPartialSpecialization<A, B> (A, B) -> ()
602-
// CHECK-LABEL: sil shared @$s16eager_specialize34checkExplicitPartialSpecializationyyx_q_tr0_lFs5Int64Vq_ADRszr0_lIetyi_Tp5 : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == Int64> (Int64, @in τ_0_1) -> ()
603-
// CHECK: bb0(%0 : $Int64, %1 : $*τ_0_1):
602+
// CHECK-LABEL: sil shared @$s16eager_specialize34checkExplicitPartialSpecializationyyx_q_tr0_lFs5Int64Vq_ADRszr0_lIetyi_Tp5 : $@convention(thin) <T, S where T == Int64> (Int64, @in S) -> ()
603+
// CHECK: bb0(%0 : $Int64, %1 : $*S):
604604
// CHECK: %2 = alloc_stack $Int64
605605
// CHECK: store %0 to %2 : $*Int64
606-
// CHECK: destroy_addr %1 : $*τ_0_1
606+
// CHECK: destroy_addr %1 : $*S
607607
// CHECK: destroy_addr %2 : $*Int64
608608
// CHECK: %6 = tuple ()
609609
// CHECK: dealloc_stack %2 : $*Int64
@@ -702,7 +702,7 @@ bb0(%0 : $*Self, %1 : $*Self, %2 : $@thick Self.Type):
702702

703703
// Check that a specialization for _Trivial(32) uses direct loads and stores
704704
// instead of value witness functions to load and store the value of a generic type.
705-
// CHECK-IRGEN-LABEL: define linkonce_odr hidden swiftcc void @"$s16eager_specialize18copyValueAndReturn_1sxx_xztlFxxxRlze31_lIetilr_Tp5"(i32* noalias nocapture sret, i32* noalias nocapture dereferenceable(4), i32* nocapture dereferenceable(4), %swift.type* %"\CF\84_0_0")
705+
// CHECK-IRGEN-LABEL: define linkonce_odr hidden swiftcc void @"$s16eager_specialize18copyValueAndReturn_1sxx_xztlFxxxRlze31_lIetilr_Tp5"(i32* noalias nocapture sret, i32* noalias nocapture dereferenceable(4), i32* nocapture dereferenceable(4), %swift.type* %S)
706706
// CHECK-IRGEN: entry:
707707
// CHECK-IRGEN: %3 = load i32, i32* %2
708708
// CHECK-IRGEN-NEXT: store i32 %3, i32* %0
@@ -711,7 +711,7 @@ bb0(%0 : $*Self, %1 : $*Self, %2 : $@thick Self.Type):
711711

712712
// Check that a specialization for _Trivial(64) uses direct loads and stores
713713
// instead of value witness functions to load and store the value of a generic type.
714-
// CHECK-IRGEN-LABEL: define linkonce_odr hidden swiftcc void @"$s16eager_specialize18copyValueAndReturn_1sxx_xztlFxxxRlze63_lIetilr_Tp5"(i64* noalias nocapture sret, i64* noalias nocapture dereferenceable(8), i64* nocapture dereferenceable(8), %swift.type* %"\CF\84_0_0")
714+
// CHECK-IRGEN-LABEL: define linkonce_odr hidden swiftcc void @"$s16eager_specialize18copyValueAndReturn_1sxx_xztlFxxxRlze63_lIetilr_Tp5"(i64* noalias nocapture sret, i64* noalias nocapture dereferenceable(8), i64* nocapture dereferenceable(8), %swift.type* %S)
715715
// CHECK-IRGEN: entry:
716716
// CHECK-IRGEN: %3 = load i64, i64* %2
717717
// CHECK-IRGEN-NEXT: store i64 %3, i64* %0
@@ -720,12 +720,12 @@ bb0(%0 : $*Self, %1 : $*Self, %2 : $@thick Self.Type):
720720

721721
// Check that a specialization for _Trivial does not call the 'destroy' value witness,
722722
// because it is known that the object is Trivial, i.e. contains no references.
723-
// CHECK-IRGEN-LABEL: define linkonce_odr hidden swiftcc void @"$s16eager_specialize19copyValueAndReturn2_1sxx_xztlFxxxRlzTlIetilr_Tp5"(%swift.opaque* noalias nocapture sret, %swift.opaque* noalias nocapture, %swift.opaque* nocapture, %swift.type* %"\CF\84_0_0")
723+
// CHECK-IRGEN-LABEL: define linkonce_odr hidden swiftcc void @"$s16eager_specialize19copyValueAndReturn2_1sxx_xztlFxxxRlzTlIetilr_Tp5"(%swift.opaque* noalias nocapture sret, %swift.opaque* noalias nocapture, %swift.opaque* nocapture, %swift.type* %S)
724724
// CHECK-IRGEN-NEXT: entry:
725-
// CHECK-IRGEN: %3 = bitcast %swift.type* %"\CF\84_0_0" to i8***
725+
// CHECK-IRGEN: %3 = bitcast %swift.type* %S to i8***
726726
// CHECK-IRGEN-NEXT: %4 = getelementptr inbounds i8**, i8*** %3, i{{.*}} -1
727-
// CHECK-IRGEN-NEXT: %"\CF\84_0_0.valueWitnesses" = load i8**, i8*** %4
728-
// CHECK-IRGEN-NEXT: %5 = getelementptr inbounds i8*, i8** %"\CF\84_0_0.valueWitnesses"
727+
// CHECK-IRGEN-NEXT: %S.valueWitnesses = load i8**, i8*** %4
728+
// CHECK-IRGEN-NEXT: %5 = getelementptr inbounds i8*, i8** %S.valueWitnesses
729729
// CHECK-IRGEN-NEXT: %6 = load i8*, i8** %5
730730
// CHECK-IRGEN-NEXT: %initializeWithCopy = {{.*}}
731731
// CHECK-IRGEN-NEXT: %7 = call {{.*}} %initializeWithCopy
@@ -830,7 +830,7 @@ bb2(%10 : $Error): // Preds: bb0
830830
} // end sil function '$s34eager_specialize_throwing_function19ClassUsingThrowingPC1gys5Int64VxKAA0G1PRzlFZ'
831831

832832
// Check that a specialization was produced and it is not inlined.
833-
// CHECK-EAGER-SPECIALIZE-AND-GENERICS-INLINE-LABEL: sil{{.*}}@{{.*}}testSimpleGeneric{{.*}}where τ_0_0 : _Trivial(64, 64)
833+
// CHECK-EAGER-SPECIALIZE-AND-GENERICS-INLINE-LABEL: sil{{.*}}@{{.*}}testSimpleGeneric{{.*}}where T : _Trivial(64, 64)
834834
// CHECK-EAGER-SPECIALIZE-AND-GENERICS-INLINE-LABEL: sil{{.*}}@testSimpleGeneric :
835835
// CHECK-EAGER-SPECIALIZE-AND-GENERICS-INLINE: [[METATYPE:%.*]] = metatype $@thick T.Type
836836
// CHECK-EAGER-SPECIALIZE-AND-GENERICS-INLINE: [[SIZEOF:%.*]] = builtin "sizeof"<T>([[METATYPE]] : $@thick T.Type)

0 commit comments

Comments
 (0)