@@ -299,8 +299,6 @@ FOR_KNOWN_FOUNDATION_TYPES(CACHE_FOUNDATION_DECL)
299
299
llvm::DenseMap<std::pair<Type,char >, MetatypeType*> MetatypeTypes;
300
300
llvm::DenseMap<std::pair<Type,char >,
301
301
ExistentialMetatypeType*> ExistentialMetatypeTypes;
302
- llvm::DenseMap<std::pair<Type,std::pair<Type,unsigned >>, FunctionType*>
303
- FunctionTypes;
304
302
llvm::DenseMap<Type, ArraySliceType*> ArraySliceTypes;
305
303
llvm::DenseMap<std::pair<Type, Type>, DictionaryType *> DictionaryTypes;
306
304
llvm::DenseMap<Type, OptionalType*> OptionalTypes;
@@ -320,6 +318,9 @@ FOR_KNOWN_FOUNDATION_TYPES(CACHE_FOUNDATION_DECL)
320
318
llvm::FoldingSet<ProtocolCompositionType> ProtocolCompositionTypes;
321
319
llvm::FoldingSet<LayoutConstraintInfo> LayoutConstraints;
322
320
321
+ // / The set of function types.
322
+ llvm::FoldingSet<FunctionType> FunctionTypes;
323
+
323
324
// / The set of normal protocol conformances.
324
325
llvm::FoldingSet<NormalProtocolConformance> NormalConformances;
325
326
@@ -2103,7 +2104,6 @@ size_t ASTContext::Implementation::Arena::getTotalMemory() const {
2103
2104
// TupleTypes ?
2104
2105
llvm::capacity_in_bytes (MetatypeTypes) +
2105
2106
llvm::capacity_in_bytes (ExistentialMetatypeTypes) +
2106
- llvm::capacity_in_bytes (FunctionTypes) +
2107
2107
llvm::capacity_in_bytes (ArraySliceTypes) +
2108
2108
llvm::capacity_in_bytes (DictionaryTypes) +
2109
2109
llvm::capacity_in_bytes (OptionalTypes) +
@@ -2113,6 +2113,7 @@ size_t ASTContext::Implementation::Arena::getTotalMemory() const {
2113
2113
llvm::capacity_in_bytes (InOutTypes) +
2114
2114
llvm::capacity_in_bytes (DependentMemberTypes) +
2115
2115
llvm::capacity_in_bytes (DynamicSelfTypes);
2116
+ // FunctionTypes ?
2116
2117
// EnumTypes ?
2117
2118
// StructTypes ?
2118
2119
// ClassTypes ?
@@ -3606,37 +3607,66 @@ DynamicSelfType *DynamicSelfType::get(Type selfType, const ASTContext &ctx) {
3606
3607
return result;
3607
3608
}
3608
3609
3609
- static RecursiveTypeProperties getFunctionRecursiveProperties (Type Input,
3610
- Type Result) {
3611
- // assert(!Input->hasLValueType()
3612
- // && "function should not take lvalues directly as parameters") ;
3613
-
3614
- auto properties = Input ->getRecursiveProperties ()
3615
- | Result ->getRecursiveProperties ();
3610
+ static RecursiveTypeProperties
3611
+ getFunctionRecursiveProperties (ArrayRef<AnyFunctionType::Param> params,
3612
+ Type result) {
3613
+ RecursiveTypeProperties properties ;
3614
+ for ( auto param : params)
3615
+ properties |= param. getPlainType () ->getRecursiveProperties ();
3616
+ properties |= result ->getRecursiveProperties ();
3616
3617
properties &= ~RecursiveTypeProperties::IsLValue;
3617
3618
return properties;
3618
3619
}
3619
3620
3621
+ static bool
3622
+ isFunctionTypeCanonical (ArrayRef<AnyFunctionType::Param> params,
3623
+ Type result) {
3624
+ for (auto param : params) {
3625
+ if (!param.getPlainType ()->isCanonical ())
3626
+ return false ;
3627
+ }
3628
+
3629
+ return result->isCanonical ();
3630
+ }
3631
+
3620
3632
// For now, generic function types cannot be dependent (in fact,
3621
3633
// they erase dependence) or contain type variables, and they're
3622
3634
// always materializable.
3623
3635
static RecursiveTypeProperties
3624
- getGenericFunctionRecursiveProperties (Type Input, Type Result) {
3625
- // assert(!Input->hasLValueType()
3626
- // && "function should not take lvalues directly as parameters");
3627
-
3636
+ getGenericFunctionRecursiveProperties (ArrayRef<AnyFunctionType::Param> params,
3637
+ Type result) {
3628
3638
static_assert (RecursiveTypeProperties::BitWidth == 10 ,
3629
3639
" revisit this if you add new recursive type properties" );
3630
3640
RecursiveTypeProperties properties;
3631
- if (Input->getRecursiveProperties ().hasError ())
3632
- properties |= RecursiveTypeProperties::HasError;
3633
- if (Result->getRecursiveProperties ().hasDynamicSelf ())
3641
+
3642
+ for (auto param : params) {
3643
+ if (param.getPlainType ()->getRecursiveProperties ().hasError ())
3644
+ properties |= RecursiveTypeProperties::HasError;
3645
+ }
3646
+
3647
+ if (result->getRecursiveProperties ().hasDynamicSelf ())
3634
3648
properties |= RecursiveTypeProperties::HasDynamicSelf;
3635
- if (Result ->getRecursiveProperties ().hasError ())
3649
+ if (result ->getRecursiveProperties ().hasError ())
3636
3650
properties |= RecursiveTypeProperties::HasError;
3651
+
3637
3652
return properties;
3638
3653
}
3639
3654
3655
+ static bool
3656
+ isGenericFunctionTypeCanonical (GenericSignature *sig,
3657
+ ArrayRef<AnyFunctionType::Param> params,
3658
+ Type result) {
3659
+ if (!sig->isCanonical ())
3660
+ return false ;
3661
+
3662
+ for (auto param : params) {
3663
+ if (!sig->isCanonicalTypeInContext (param.getPlainType ()))
3664
+ return false ;
3665
+ }
3666
+
3667
+ return sig->isCanonicalTypeInContext (result);
3668
+ }
3669
+
3640
3670
AnyFunctionType *AnyFunctionType::withExtInfo (ExtInfo info) const {
3641
3671
if (isa<FunctionType>(this ))
3642
3672
return FunctionType::get (getParams (), getResult (), info,
@@ -3742,62 +3772,79 @@ void AnyFunctionType::relabelParams(MutableArrayRef<Param> params,
3742
3772
}
3743
3773
}
3744
3774
3775
+ static void profileParams (llvm::FoldingSetNodeID &ID,
3776
+ ArrayRef<AnyFunctionType::Param> params) {
3777
+ ID.AddInteger (params.size ());
3778
+ for (auto param : params) {
3779
+ ID.AddPointer (param.getLabel ().get ());
3780
+ ID.AddPointer (param.getPlainType ().getPointer ());
3781
+ ID.AddInteger (param.getParameterFlags ().toRaw ());
3782
+ }
3783
+ }
3784
+
3785
+ void FunctionType::Profile (llvm::FoldingSetNodeID &ID,
3786
+ ArrayRef<AnyFunctionType::Param> params,
3787
+ Type result,
3788
+ ExtInfo info) {
3789
+ profileParams (ID, params);
3790
+ ID.AddPointer (result.getPointer ());
3791
+ ID.AddInteger (info.getFuncAttrKey ());
3792
+ }
3793
+
3745
3794
FunctionType *FunctionType::get (ArrayRef<AnyFunctionType::Param> params,
3746
3795
Type result, ExtInfo info,
3747
3796
bool canonicalVararg) {
3748
3797
auto input = composeInput (result->getASTContext (), params, canonicalVararg);
3749
- auto properties = getFunctionRecursiveProperties (input , result);
3798
+ auto properties = getFunctionRecursiveProperties (params , result);
3750
3799
auto arena = getArena (properties);
3751
- uint16_t attrKey = info.getFuncAttrKey ();
3752
3800
3753
- const ASTContext &C = input->getASTContext ();
3801
+ llvm::FoldingSetNodeID id;
3802
+ FunctionType::Profile (id, params, result, info);
3754
3803
3755
- FunctionType *&Entry
3756
- = C.getImpl ().getArena (arena).FunctionTypes [{input, {result, attrKey} }];
3757
- if (Entry) return Entry;
3758
-
3759
- void *mem = C.Allocate (sizeof (FunctionType) +
3760
- sizeof (AnyFunctionType::Param) * params.size (),
3761
- alignof (FunctionType), arena);
3762
- return Entry = new (mem) FunctionType (params, input, result,
3763
- properties, info);
3804
+ const ASTContext &ctx = result->getASTContext ();
3805
+
3806
+ // Do we already have this generic function type?
3807
+ void *insertPos;
3808
+ if (auto funcTy =
3809
+ ctx.getImpl ().getArena (arena).FunctionTypes .FindNodeOrInsertPos (id, insertPos)) {
3810
+ return funcTy;
3811
+ }
3812
+
3813
+ void *mem = ctx.Allocate (sizeof (FunctionType) +
3814
+ sizeof (AnyFunctionType::Param) * params.size (),
3815
+ alignof (FunctionType), arena);
3816
+
3817
+ bool isCanonical = isFunctionTypeCanonical (params, result);
3818
+ auto funcTy = new (mem) FunctionType (params, input, result, info,
3819
+ isCanonical ? &ctx : nullptr ,
3820
+ properties);
3821
+ ctx.getImpl ().getArena (arena).FunctionTypes .InsertNode (funcTy, insertPos);
3822
+ return funcTy;
3764
3823
}
3765
3824
3766
3825
// If the input and result types are canonical, then so is the result.
3767
3826
FunctionType::FunctionType (ArrayRef<AnyFunctionType::Param> params,
3768
3827
Type input, Type output,
3769
- RecursiveTypeProperties properties,
3770
- ExtInfo Info)
3771
- : AnyFunctionType(TypeKind::Function,
3772
- (isCanonicalFunctionInputType(input) &&
3773
- output->isCanonical())
3774
- ? &input->getASTContext()
3775
- : nullptr,
3776
- input, output, properties, params.size(), Info) {
3828
+ ExtInfo info,
3829
+ const ASTContext *ctx,
3830
+ RecursiveTypeProperties properties)
3831
+ : AnyFunctionType(TypeKind::Function, ctx,
3832
+ input, output, properties, params.size(), info) {
3777
3833
std::uninitialized_copy (params.begin (), params.end (),
3778
3834
getTrailingObjects<AnyFunctionType::Param>());
3779
3835
}
3780
3836
3781
3837
void GenericFunctionType::Profile (llvm::FoldingSetNodeID &ID,
3782
3838
GenericSignature *sig,
3783
- Type input ,
3839
+ ArrayRef<AnyFunctionType::Param> params ,
3784
3840
Type result,
3785
3841
ExtInfo info) {
3786
3842
ID.AddPointer (sig);
3787
- ID. AddPointer (input. getPointer () );
3843
+ profileParams (ID, params );
3788
3844
ID.AddPointer (result.getPointer ());
3789
3845
ID.AddInteger (info.getFuncAttrKey ());
3790
3846
}
3791
3847
3792
- // / If this is a ParenType, unwrap it to produce the underlying type.
3793
- // / Otherwise, return \c type.
3794
- static Type unwrapParenType (Type type) {
3795
- if (auto parenTy = dyn_cast<ParenType>(type.getPointer ()))
3796
- return parenTy->getUnderlyingType ();
3797
-
3798
- return type;
3799
- }
3800
-
3801
3848
GenericFunctionType *GenericFunctionType::get (GenericSignature *sig,
3802
3849
ArrayRef<Param> params,
3803
3850
Type result,
@@ -3806,10 +3853,10 @@ GenericFunctionType *GenericFunctionType::get(GenericSignature *sig,
3806
3853
assert (sig && " no generic signature for generic function type?!" );
3807
3854
3808
3855
auto input = composeInput (result->getASTContext (), params, canonicalVararg);
3809
- assert (!input-> hasTypeVariable () && ! result->hasTypeVariable ());
3856
+ assert (!result->hasTypeVariable ());
3810
3857
3811
3858
llvm::FoldingSetNodeID id;
3812
- GenericFunctionType::Profile (id, sig, input , result, info);
3859
+ GenericFunctionType::Profile (id, sig, params , result, info);
3813
3860
3814
3861
const ASTContext &ctx = input->getASTContext ();
3815
3862
@@ -3824,10 +3871,7 @@ GenericFunctionType *GenericFunctionType::get(GenericSignature *sig,
3824
3871
// it's canonical. Unfortunately, isCanonicalTypeInContext can cause
3825
3872
// new GenericFunctionTypes to be created and thus invalidate our insertion
3826
3873
// point.
3827
- bool isCanonical = sig->isCanonical ()
3828
- && isCanonicalFunctionInputType (input)
3829
- && sig->isCanonicalTypeInContext (unwrapParenType (input))
3830
- && sig->isCanonicalTypeInContext (result);
3874
+ bool isCanonical = isGenericFunctionTypeCanonical (sig, params, result);
3831
3875
3832
3876
if (auto funcTy
3833
3877
= ctx.getImpl ().GenericFunctionTypes .FindNodeOrInsertPos (id, insertPos)) {
@@ -3838,7 +3882,7 @@ GenericFunctionType *GenericFunctionType::get(GenericSignature *sig,
3838
3882
sizeof (AnyFunctionType::Param) * params.size (),
3839
3883
alignof (GenericFunctionType));
3840
3884
3841
- auto properties = getGenericFunctionRecursiveProperties (input , result);
3885
+ auto properties = getGenericFunctionRecursiveProperties (params , result);
3842
3886
auto funcTy = new (mem) GenericFunctionType (sig, params, input, result, info,
3843
3887
isCanonical ? &ctx : nullptr ,
3844
3888
properties);
0 commit comments