@@ -1859,7 +1859,21 @@ void irgen::emitLazyMetadataAccessor(IRGenModule &IGM,
1859
1859
1860
1860
void irgen::emitLazySpecializedGenericTypeMetadata (IRGenModule &IGM,
1861
1861
CanType type) {
1862
- emitSpecializedGenericStructMetadata (IGM, type);
1862
+ switch (type->getKind ()) {
1863
+ case TypeKind::Struct:
1864
+ case TypeKind::BoundGenericStruct:
1865
+ emitSpecializedGenericStructMetadata (IGM, type,
1866
+ *type.getStructOrBoundGenericStruct ());
1867
+ break ;
1868
+ case TypeKind::Enum:
1869
+ case TypeKind::BoundGenericEnum:
1870
+ emitSpecializedGenericEnumMetadata (IGM, type,
1871
+ *type.getEnumOrBoundGenericEnum ());
1872
+ break ;
1873
+ default :
1874
+ llvm_unreachable (" Cannot statically specialize types of kind other than "
1875
+ " struct and enum." );
1876
+ }
1863
1877
}
1864
1878
1865
1879
llvm::Constant *
@@ -3472,8 +3486,12 @@ namespace {
3472
3486
: public ValueMetadataBuilderBase<StructMetadataVisitor<Impl>> {
3473
3487
using super = ValueMetadataBuilderBase<StructMetadataVisitor<Impl>>;
3474
3488
3489
+ bool HasUnfilledFieldOffset = false ;
3490
+
3475
3491
protected:
3476
- ConstantStructBuilder &B;
3492
+ using ConstantBuilder = ConstantStructBuilder;
3493
+ ConstantBuilder &B;
3494
+ using NominalDecl = StructDecl;
3477
3495
using super::IGM;
3478
3496
using super::Target;
3479
3497
using super::asImpl;
@@ -3562,16 +3580,6 @@ namespace {
3562
3580
3563
3581
return flags;
3564
3582
}
3565
- };
3566
-
3567
- class StructMetadataBuilder :
3568
- public StructMetadataBuilderBase<StructMetadataBuilder> {
3569
-
3570
- bool HasUnfilledFieldOffset = false ;
3571
- public:
3572
- StructMetadataBuilder (IRGenModule &IGM, StructDecl *theStruct,
3573
- ConstantStructBuilder &B)
3574
- : StructMetadataBuilderBase(IGM, theStruct, B) {}
3575
3583
3576
3584
void flagUnfilledFieldOffset () {
3577
3585
HasUnfilledFieldOffset = true ;
@@ -3580,13 +3588,21 @@ namespace {
3580
3588
bool canBeConstant () {
3581
3589
return !HasUnfilledFieldOffset;
3582
3590
}
3591
+ };
3592
+
3593
+ class StructMetadataBuilder
3594
+ : public StructMetadataBuilderBase<StructMetadataBuilder> {
3595
+ public:
3596
+ StructMetadataBuilder (IRGenModule &IGM, StructDecl *theStruct,
3597
+ ConstantStructBuilder &B)
3598
+ : StructMetadataBuilderBase(IGM, theStruct, B) {}
3583
3599
3584
3600
void createMetadataAccessFunction () {
3585
3601
createNonGenericMetadataAccessFunction (IGM, Target);
3586
3602
maybeCreateSingletonMetadataInitialization ();
3587
3603
}
3588
3604
};
3589
-
3605
+
3590
3606
// / Emit a value witness table for a fixed-layout generic type, or a template
3591
3607
// / if the value witness table is dependent on generic parameters.
3592
3608
static ConstantReference
@@ -3710,24 +3726,25 @@ namespace {
3710
3726
}
3711
3727
};
3712
3728
3713
- class SpecializedGenericStructMetadataBuilder
3714
- : public StructMetadataBuilderBase<
3715
- SpecializedGenericStructMetadataBuilder > {
3716
- using super =
3717
- StructMetadataBuilderBase<SpecializedGenericStructMetadataBuilder>;
3729
+ template < template < typename > class MetadataBuilderBase , typename Impl>
3730
+ class SpecializedGenericNominalMetadataBuilderBase
3731
+ : public MetadataBuilderBase<Impl > {
3732
+ using super = MetadataBuilderBase<Impl>;
3733
+
3718
3734
CanType type;
3719
- bool HasUnfilledFieldOffset = false ;
3720
3735
3721
3736
protected:
3722
3737
using super::asImpl;
3723
3738
using super::getLoweredType;
3724
3739
using super::IGM;
3725
3740
using super::Target;
3741
+ using typename super::ConstantBuilder;
3742
+ using typename super::NominalDecl;
3726
3743
3727
3744
public:
3728
- SpecializedGenericStructMetadataBuilder (IRGenModule &IGM, CanType type,
3729
- StructDecl &decl,
3730
- ConstantStructBuilder &B)
3745
+ SpecializedGenericNominalMetadataBuilderBase (IRGenModule &IGM, CanType type,
3746
+ NominalDecl &decl,
3747
+ ConstantBuilder &B)
3731
3748
: super(IGM, &decl, B), type(type) {}
3732
3749
3733
3750
void noteStartOfTypeSpecificMembers () {}
@@ -3750,7 +3767,7 @@ namespace {
3750
3767
auto t = requirement.TypeParameter .subst (genericSubstitutions ());
3751
3768
ConstantReference ref = IGM.getAddrOfTypeMetadata (
3752
3769
CanType (t), SymbolReferenceKind::Relative_Direct);
3753
- B.add (ref.getDirectValue ());
3770
+ this -> B .add (ref.getDirectValue ());
3754
3771
}
3755
3772
3756
3773
void addGenericWitnessTable (GenericRequirement requirement) {
@@ -3773,7 +3790,7 @@ namespace {
3773
3790
addr = IGM.getAddrOfWitnessTable (rootConformance);
3774
3791
}
3775
3792
3776
- B.add (addr);
3793
+ this -> B .add (addr);
3777
3794
}
3778
3795
3779
3796
SubstitutionMap genericSubstitutions () {
@@ -3789,10 +3806,21 @@ namespace {
3789
3806
3790
3807
return flags;
3791
3808
}
3809
+ };
3810
+
3811
+ class SpecializedGenericStructMetadataBuilder
3812
+ : public SpecializedGenericNominalMetadataBuilderBase<
3813
+ StructMetadataBuilderBase,
3814
+ SpecializedGenericStructMetadataBuilder> {
3815
+ using super = SpecializedGenericNominalMetadataBuilderBase<
3816
+ StructMetadataBuilderBase, SpecializedGenericStructMetadataBuilder>;
3792
3817
3793
- void flagUnfilledFieldOffset () { HasUnfilledFieldOffset = true ; }
3794
3818
3795
- bool canBeConstant () { return !HasUnfilledFieldOffset; }
3819
+ public:
3820
+ SpecializedGenericStructMetadataBuilder (IRGenModule &IGM, CanType type,
3821
+ StructDecl &decl,
3822
+ ConstantStructBuilder &B)
3823
+ : super(IGM, type, decl, B) {}
3796
3824
};
3797
3825
3798
3826
} // end anonymous namespace
@@ -3828,8 +3856,8 @@ void irgen::emitStructMetadata(IRGenModule &IGM, StructDecl *structDecl) {
3828
3856
init.finishAndCreateFuture ());
3829
3857
}
3830
3858
3831
- void irgen::emitSpecializedGenericStructMetadata (IRGenModule &IGM,
3832
- CanType type ) {
3859
+ void irgen::emitSpecializedGenericStructMetadata (IRGenModule &IGM, CanType type,
3860
+ StructDecl &decl ) {
3833
3861
Type ty = type.getPointer ();
3834
3862
auto &context = type->getNominalOrBoundGenericNominal ()->getASTContext ();
3835
3863
PrettyStackTraceType stackTraceRAII (
@@ -3840,7 +3868,6 @@ void irgen::emitSpecializedGenericStructMetadata(IRGenModule &IGM,
3840
3868
3841
3869
bool isPattern = false ;
3842
3870
3843
- auto &decl = *type.getStructOrBoundGenericStruct ();
3844
3871
SpecializedGenericStructMetadataBuilder builder (IGM, type, decl, init);
3845
3872
builder.layout ();
3846
3873
@@ -3871,9 +3898,13 @@ namespace {
3871
3898
class EnumMetadataBuilderBase
3872
3899
: public ValueMetadataBuilderBase<EnumMetadataVisitor<Impl>> {
3873
3900
using super = ValueMetadataBuilderBase<EnumMetadataVisitor<Impl>>;
3901
+ bool HasUnfilledPayloadSize = false ;
3874
3902
3875
3903
protected:
3876
- ConstantStructBuilder &B;
3904
+ using ConstantBuilder = ConstantStructBuilder;
3905
+ using NominalDecl = EnumDecl;
3906
+ ConstantBuilder &B;
3907
+ using super::asImpl;
3877
3908
using super::IGM;
3878
3909
using super::Target;
3879
3910
@@ -3894,8 +3925,12 @@ namespace {
3894
3925
return irgen::emitValueWitnessTable (IGM, type, false , relativeReference);
3895
3926
}
3896
3927
3928
+ ConstantReference getValueWitnessTable (bool relativeReference) {
3929
+ return emitValueWitnessTable (relativeReference);
3930
+ }
3931
+
3897
3932
void addValueWitnessTable () {
3898
- B.add (emitValueWitnessTable ( /* relative */ false ).getValue ());
3933
+ B.add (asImpl (). getValueWitnessTable ( false ).getValue ());
3899
3934
}
3900
3935
3901
3936
llvm::Constant *emitNominalTypeDescriptor () {
@@ -3904,8 +3939,12 @@ namespace {
3904
3939
return descriptor;
3905
3940
}
3906
3941
3942
+ llvm::Constant *getNominalTypeDescriptor () {
3943
+ return emitNominalTypeDescriptor ();
3944
+ }
3945
+
3907
3946
void addNominalTypeDescriptor () {
3908
- B.add (emitNominalTypeDescriptor ());
3947
+ B.add (asImpl (). getNominalTypeDescriptor ());
3909
3948
}
3910
3949
3911
3950
void addGenericArgument (GenericRequirement requirement) {
@@ -3915,16 +3954,22 @@ namespace {
3915
3954
void addGenericWitnessTable (GenericRequirement requirement) {
3916
3955
llvm_unreachable (" Concrete type metadata cannot have generic requirements" );
3917
3956
}
3918
- };
3919
3957
3920
- class EnumMetadataBuilder
3921
- : public EnumMetadataBuilderBase<EnumMetadataBuilder> {
3922
- bool HasUnfilledPayloadSize = false ;
3958
+ bool hasTrailingFlags () {
3959
+ return IGM. shouldPrespecializeGenericMetadata ();
3960
+ }
3923
3961
3924
- public:
3925
- EnumMetadataBuilder (IRGenModule &IGM, EnumDecl *theEnum,
3926
- ConstantStructBuilder &B)
3927
- : EnumMetadataBuilderBase(IGM, theEnum, B) {}
3962
+ void addTrailingFlags () {
3963
+ auto flags = asImpl ().getTrailingFlags ();
3964
+
3965
+ B.addInt (IGM.Int64Ty , flags.getOpaqueValue ());
3966
+ }
3967
+
3968
+ MetadataTrailingFlags getTrailingFlags () {
3969
+ MetadataTrailingFlags flags;
3970
+
3971
+ return flags;
3972
+ }
3928
3973
3929
3974
void addPayloadSize () {
3930
3975
auto payloadSize = getConstantPayloadSize (IGM, Target);
@@ -3940,6 +3985,27 @@ namespace {
3940
3985
bool canBeConstant () {
3941
3986
return !HasUnfilledPayloadSize;
3942
3987
}
3988
+ };
3989
+
3990
+ class SpecializedGenericEnumMetadataBuilder
3991
+ : public SpecializedGenericNominalMetadataBuilderBase<
3992
+ EnumMetadataBuilderBase, SpecializedGenericEnumMetadataBuilder> {
3993
+
3994
+ using super = SpecializedGenericNominalMetadataBuilderBase<
3995
+ EnumMetadataBuilderBase, SpecializedGenericEnumMetadataBuilder>;
3996
+
3997
+ public:
3998
+ SpecializedGenericEnumMetadataBuilder (IRGenModule &IGM, CanType type,
3999
+ EnumDecl &decl, ConstantBuilder &B)
4000
+ : super(IGM, type, decl, B){};
4001
+ };
4002
+
4003
+ class EnumMetadataBuilder
4004
+ : public EnumMetadataBuilderBase<EnumMetadataBuilder> {
4005
+ public:
4006
+ EnumMetadataBuilder (IRGenModule &IGM, EnumDecl *theEnum,
4007
+ ConstantStructBuilder &B)
4008
+ : EnumMetadataBuilderBase(IGM, theEnum, B) {}
3943
4009
3944
4010
void createMetadataAccessFunction () {
3945
4011
createNonGenericMetadataAccessFunction (IGM, Target);
@@ -3990,6 +4056,16 @@ namespace {
3990
4056
return EnumContextDescriptorBuilder (IGM, Target, RequireMetadata).emit ();
3991
4057
}
3992
4058
4059
+ GenericMetadataPatternFlags getPatternFlags () {
4060
+ auto flags = super::getPatternFlags ();
4061
+
4062
+ if (IGM.shouldPrespecializeGenericMetadata ()) {
4063
+ flags.setHasTrailingFlags (true );
4064
+ }
4065
+
4066
+ return flags;
4067
+ }
4068
+
3993
4069
ConstantReference emitValueWitnessTable (bool relativeReference) {
3994
4070
assert (relativeReference && " should only relative reference" );
3995
4071
return getValueWitnessTableForGenericValueType (IGM, Target,
@@ -4033,6 +4109,26 @@ void irgen::emitEnumMetadata(IRGenModule &IGM, EnumDecl *theEnum) {
4033
4109
init.finishAndCreateFuture ());
4034
4110
}
4035
4111
4112
+ void irgen::emitSpecializedGenericEnumMetadata (IRGenModule &IGM, CanType type,
4113
+ EnumDecl &decl) {
4114
+ Type ty = type.getPointer ();
4115
+ auto &context = type->getNominalOrBoundGenericNominal ()->getASTContext ();
4116
+ PrettyStackTraceType stackTraceRAII (
4117
+ context, " emitting prespecialized metadata for" , ty);
4118
+ ConstantInitBuilder initBuilder (IGM);
4119
+ auto init = initBuilder.beginStruct ();
4120
+ init.setPacked (true );
4121
+
4122
+ bool isPattern = false ;
4123
+
4124
+ SpecializedGenericEnumMetadataBuilder builder (IGM, type, decl, init);
4125
+ builder.layout ();
4126
+
4127
+ bool canBeConstant = builder.canBeConstant ();
4128
+ IGM.defineTypeMetadata (type, isPattern, canBeConstant,
4129
+ init.finishAndCreateFuture ());
4130
+ }
4131
+
4036
4132
llvm::Value *IRGenFunction::emitObjCSelectorRefLoad (StringRef selector) {
4037
4133
llvm::Constant *loadSelRef = IGM.getAddrOfObjCSelectorRef (selector);
4038
4134
llvm::Value *loadSel =
0 commit comments