@@ -2591,156 +2591,139 @@ namespace {
2591
2591
// /
2592
2592
// / NOTE: If you modify the special cases in this, you should update
2593
2593
// / isTypeMetadataForLayoutAccessible in SIL.cpp.
2594
- class EmitTypeMetadataRefForLayout
2595
- : public CanTypeVisitor<EmitTypeMetadataRefForLayout, llvm::Value *,
2596
- DynamicMetadataRequest> {
2597
- private:
2598
- IRGenFunction &IGF;
2599
- public:
2600
- EmitTypeMetadataRefForLayout (IRGenFunction &IGF) : IGF(IGF) {}
2601
-
2602
- llvm::Value *emitDirectMetadataRef (CanType type,
2603
- DynamicMetadataRequest request) {
2604
- return IGF.IGM .getAddrOfTypeMetadata (type);
2605
- }
2606
-
2607
- // / For most types, we can just emit the usual metadata.
2608
- llvm::Value *visitType (CanType t, DynamicMetadataRequest request) {
2609
- return IGF.emitTypeMetadataRef (t, request).getMetadata ();
2610
- }
2611
-
2612
- llvm::Value *visitBoundGenericEnumType (CanBoundGenericEnumType type,
2613
- DynamicMetadataRequest request) {
2614
- // Optionals have a lowered payload type, so we recurse here.
2615
- if (auto objectTy = type.getOptionalObjectType ()) {
2616
- if (auto metadata = tryGetLocal (type, request))
2617
- return metadata;
2618
-
2619
- auto payloadMetadata = visit (objectTy, request);
2620
- llvm::Value *args[] = { payloadMetadata };
2621
- llvm::Type *types[] = { IGF.IGM .TypeMetadataPtrTy };
2622
-
2623
- // Call the generic metadata accessor function.
2624
- llvm::Function *accessor =
2625
- IGF.IGM .getAddrOfGenericTypeMetadataAccessFunction (
2626
- type->getDecl (), types, NotForDefinition);
2627
-
2628
- auto response =
2629
- IGF.emitGenericTypeMetadataAccessFunctionCall (accessor, args,
2630
- request);
2631
-
2632
- return setLocal (type, response);
2633
- }
2594
+ class EmitTypeMetadataRefForLayout
2595
+ : public CanTypeVisitor<EmitTypeMetadataRefForLayout, CanType> {
2596
+ public:
2597
+ EmitTypeMetadataRefForLayout () {}
2598
+
2599
+ // / For most types, we can just emit the usual metadata.
2600
+ CanType visitType (CanType t) { return t; }
2601
+
2602
+ CanType visitBoundGenericEnumType (CanBoundGenericEnumType ty) {
2603
+ // Optionals have a lowered payload type, so we recurse here.
2604
+ if (auto objectTy = ty.getOptionalObjectType ()) {
2605
+ auto payloadTy = visit (objectTy);
2606
+ if (payloadTy == objectTy)
2607
+ return ty;
2608
+ auto &C = ty->getASTContext ();
2609
+ auto optDecl = C.getOptionalDecl ();
2610
+ return CanType (BoundGenericEnumType::get (optDecl, Type (), payloadTy));
2611
+ }
2612
+
2613
+ // Otherwise, generic arguments are not lowered.
2614
+ return ty;
2615
+ }
2634
2616
2635
- // Otherwise, generic arguments are not lowered.
2636
- return visitType (type, request);
2637
- }
2617
+ CanType visitTupleType (CanTupleType ty) {
2618
+ bool changed = false ;
2619
+ SmallVector<TupleTypeElt, 4 > loweredElts;
2620
+ loweredElts.reserve (ty->getNumElements ());
2638
2621
2639
- llvm::Value *visitTupleType (CanTupleType type,
2640
- DynamicMetadataRequest request) {
2641
- if (auto metadata = tryGetLocal (type, request))
2642
- return metadata;
2622
+ for (auto i : indices (ty->getElementTypes ())) {
2623
+ auto substEltType = ty.getElementType (i);
2624
+ auto &substElt = ty->getElement (i);
2643
2625
2644
- auto response = emitTupleTypeMetadataRef (IGF, type, request,
2645
- /* labels*/ false ,
2646
- [&](CanType eltType, DynamicMetadataRequest eltRequest) {
2647
- // This use of 'forComplete' is technically questionable, but in
2648
- // this class we're always producing responses we can ignore, so
2649
- // it's okay.
2650
- return MetadataResponse::forComplete (visit (eltType, eltRequest));
2651
- });
2626
+ // Make sure we don't have something non-materializable.
2627
+ auto Flags = substElt.getParameterFlags ();
2628
+ assert (Flags.getValueOwnership () == ValueOwnership::Default);
2629
+ assert (!Flags.isVariadic ());
2652
2630
2653
- return setLocal (type, response);
2654
- }
2631
+ CanType loweredSubstEltType = visit (substEltType);
2632
+ changed =
2633
+ (changed || substEltType != loweredSubstEltType || !Flags.isNone ());
2655
2634
2656
- llvm::Value *visitAnyFunctionType (CanAnyFunctionType type,
2657
- DynamicMetadataRequest request) {
2658
- llvm_unreachable (" not a SIL type" );
2659
- }
2660
-
2661
- llvm::Value *visitSILFunctionType (CanSILFunctionType type,
2662
- DynamicMetadataRequest request) {
2663
- // All function types have the same layout regardless of arguments or
2664
- // abstraction level. Use the metadata for () -> () for thick functions,
2665
- // or AnyObject for block functions.
2666
- auto &C = type->getASTContext ();
2667
- switch (type->getRepresentation ()) {
2668
- case SILFunctionType::Representation::Thin:
2669
- case SILFunctionType::Representation::Method:
2670
- case SILFunctionType::Representation::WitnessMethod:
2671
- case SILFunctionType::Representation::ObjCMethod:
2672
- case SILFunctionType::Representation::CFunctionPointer:
2673
- case SILFunctionType::Representation::Closure:
2674
- // A thin function looks like a plain pointer.
2675
- // FIXME: Except for extra inhabitants?
2676
- return emitDirectMetadataRef (C.TheRawPointerType , request);
2677
- case SILFunctionType::Representation::Thick:
2678
- // All function types look like () -> ().
2679
- // FIXME: It'd be nice not to have to call through the runtime here.
2680
- return IGF.emitTypeMetadataRef (
2681
- CanFunctionType::get ({}, C.TheEmptyTupleType ),
2682
- request).getMetadata ();
2683
- case SILFunctionType::Representation::Block:
2684
- // All block types look like AnyObject.
2685
- return emitDirectMetadataRef (C.getAnyObjectType (), request);
2686
- }
2687
-
2688
- llvm_unreachable (" Not a valid SILFunctionType." );
2635
+ // Note: we drop @escaping and @autoclosure which can still appear on
2636
+ // materializable tuple types.
2637
+ //
2638
+ // FIXME: Replace this with an assertion that the original tuple element
2639
+ // did not have any flags.
2640
+ loweredElts.emplace_back (loweredSubstEltType, substElt.getName (),
2641
+ ParameterTypeFlags ());
2689
2642
}
2690
2643
2691
- llvm::Value *visitAnyMetatypeType (CanAnyMetatypeType type,
2692
- DynamicMetadataRequest request) {
2693
-
2694
- assert (type->hasRepresentation ()
2695
- && " not a lowered metatype" );
2644
+ if (!changed)
2645
+ return ty;
2696
2646
2697
- switch (type->getRepresentation ()) {
2698
- case MetatypeRepresentation::Thin:
2699
- // Thin metatypes are empty, so they look like the empty tuple type.
2700
- return emitEmptyTupleTypeMetadataRef (IGF.IGM );
2647
+ // The cast should succeed, because if we end up with a one-element
2648
+ // tuple type here, it must have a label.
2649
+ return cast<TupleType>(
2650
+ CanType (TupleType::get (loweredElts, ty->getASTContext ())));
2651
+ }
2701
2652
2702
- case MetatypeRepresentation::Thick:
2703
- case MetatypeRepresentation::ObjC:
2704
- // Thick and ObjC metatypes look like pointers with extra inhabitants.
2705
- // Get the metatype metadata from the runtime.
2706
- // FIXME: It'd be nice not to need a runtime call here; we should just
2707
- // have a standard aligned-pointer type metadata.
2708
- return IGF.emitTypeMetadataRef (type);
2709
- }
2653
+ CanType visitAnyFunctionType (CanAnyFunctionType ty) {
2654
+ llvm_unreachable (" not a SIL type" );
2655
+ }
2710
2656
2711
- llvm_unreachable (" Not a valid MetatypeRepresentation." );
2712
- }
2657
+ CanType visitSILFunctionType (CanSILFunctionType ty) {
2658
+ // All function types have the same layout regardless of arguments or
2659
+ // abstraction level. Use the metadata for () -> () for thick functions,
2660
+ // or AnyObject for block functions.
2661
+ auto &C = ty->getASTContext ();
2662
+ switch (ty->getRepresentation ()) {
2663
+ case SILFunctionType::Representation::Thin:
2664
+ case SILFunctionType::Representation::Method:
2665
+ case SILFunctionType::Representation::WitnessMethod:
2666
+ case SILFunctionType::Representation::ObjCMethod:
2667
+ case SILFunctionType::Representation::CFunctionPointer:
2668
+ case SILFunctionType::Representation::Closure:
2669
+ // A thin function looks like a plain pointer.
2670
+ // FIXME: Except for extra inhabitants?
2671
+ return C.TheRawPointerType ;
2672
+ case SILFunctionType::Representation::Thick:
2673
+ // All function types look like () -> ().
2674
+ // FIXME: It'd be nice not to have to call through the runtime here.
2675
+ return CanFunctionType::get ({}, C.TheEmptyTupleType );
2676
+ case SILFunctionType::Representation::Block:
2677
+ // All block types look like AnyObject.
2678
+ return C.getAnyObjectType ();
2679
+ }
2680
+
2681
+ llvm_unreachable (" Not a valid SILFunctionType." );
2682
+ }
2713
2683
2714
- // / Try to find the metatype in local data.
2715
- llvm::Value *tryGetLocal (CanType type, DynamicMetadataRequest request) {
2716
- auto response = IGF.tryGetLocalTypeMetadataForLayout (
2717
- SILType::getPrimitiveObjectType (type),
2718
- request);
2719
- assert (request.canResponseStatusBeIgnored ());
2720
- return (response ? response.getMetadata () : nullptr );
2721
- }
2684
+ CanType visitAnyMetatypeType (CanAnyMetatypeType ty) {
2685
+ assert (ty->hasRepresentation () && " not a lowered metatype" );
2686
+ auto &C = ty->getASTContext ();
2687
+ switch (ty->getRepresentation ()) {
2688
+ case MetatypeRepresentation::Thin:
2689
+ // Thin metatypes are empty, so they look like the empty tuple type.
2690
+ return C.TheEmptyTupleType ;
2722
2691
2723
- // / Set the metatype in local data.
2724
- llvm::Value *setLocal (CanType type, MetadataResponse response) {
2725
- IGF.setScopedLocalTypeMetadataForLayout (
2726
- SILType::getPrimitiveObjectType (type),
2727
- response);
2728
- return response.getMetadata ();
2692
+ case MetatypeRepresentation::Thick:
2693
+ case MetatypeRepresentation::ObjC:
2694
+ // Thick and ObjC metatypes look like pointers with extra inhabitants.
2695
+ // Get the metatype metadata from the runtime.
2696
+ // FIXME: It'd be nice not to need a runtime call here; we should just
2697
+ // have a standard aligned-pointer type metadata.
2698
+ return ty;
2729
2699
}
2730
2700
2731
- };
2701
+ llvm_unreachable (" Not a valid MetatypeRepresentation." );
2702
+ }
2703
+ };
2732
2704
} // end anonymous namespace
2733
2705
2734
2706
llvm::Value *IRGenFunction::emitTypeMetadataRefForLayout (SILType type) {
2735
2707
return emitTypeMetadataRefForLayout (type, MetadataState::Complete);
2736
2708
}
2737
2709
2738
2710
llvm::Value *
2739
- IRGenFunction::emitTypeMetadataRefForLayout (SILType type ,
2711
+ IRGenFunction::emitTypeMetadataRefForLayout (SILType ty ,
2740
2712
DynamicMetadataRequest request) {
2741
2713
assert (request.canResponseStatusBeIgnored ());
2742
- return EmitTypeMetadataRefForLayout (*this ).visit (type.getASTType (),
2743
- request);
2714
+
2715
+ if (auto response =
2716
+ tryGetLocalTypeMetadataForLayout (ty.getObjectType (), request)) {
2717
+ assert (request.canResponseStatusBeIgnored () || !response.isValid ());
2718
+ return response.getMetadata ();
2719
+ }
2720
+
2721
+ // Map to a layout equivalent AST type.
2722
+ auto layoutEquivalentType =
2723
+ EmitTypeMetadataRefForLayout ().visit (ty.getASTType ());
2724
+ auto response = emitTypeMetadataRef (layoutEquivalentType, request);
2725
+ setScopedLocalTypeMetadataForLayout (ty.getObjectType (), response);
2726
+ return response.getMetadata ();
2744
2727
}
2745
2728
2746
2729
namespace {
0 commit comments