@@ -3279,7 +3279,8 @@ void NecessaryBindings::restore(IRGenFunction &IGF, Address buffer,
3279
3279
3280
3280
void NecessaryBindings::save (IRGenFunction &IGF, Address buffer) const {
3281
3281
emitInitOfGenericRequirementsBuffer (IGF, getRequirements (), buffer,
3282
- MetadataState::Complete, SubMap);
3282
+ MetadataState::Complete, SubMap,
3283
+ /* onHeapPacks=*/ !NoEscape);
3283
3284
}
3284
3285
3285
3286
llvm::Value *irgen::emitWitnessTableRef (IRGenFunction &IGF,
@@ -3485,22 +3486,22 @@ void EmitPolymorphicArguments::emit(SubstitutionMap subs,
3485
3486
3486
3487
NecessaryBindings
3487
3488
NecessaryBindings::forPartialApplyForwarder (IRGenModule &IGM,
3488
- CanSILFunctionType origType,
3489
- SubstitutionMap subs,
3490
- bool considerParameterSources) {
3491
- return computeBindings (IGM, origType, subs,
3492
- considerParameterSources);
3489
+ CanSILFunctionType origType,
3490
+ SubstitutionMap subs,
3491
+ bool noEscape,
3492
+ bool considerParameterSources) {
3493
+ NecessaryBindings bindings (subs, noEscape);
3494
+ bindings.computeBindings (IGM, origType, considerParameterSources);
3495
+ return bindings;
3493
3496
}
3494
3497
3495
- NecessaryBindings NecessaryBindings::computeBindings (
3496
- IRGenModule &IGM, CanSILFunctionType origType, SubstitutionMap subs,
3498
+ void NecessaryBindings::computeBindings (
3499
+ IRGenModule &IGM, CanSILFunctionType origType,
3497
3500
bool considerParameterSources) {
3498
3501
3499
- NecessaryBindings bindings (subs);
3500
-
3501
3502
// Bail out early if we don't have polymorphic parameters.
3502
3503
if (!hasPolymorphicParameters (origType))
3503
- return bindings ;
3504
+ return ;
3504
3505
3505
3506
// Figure out what we're actually required to pass:
3506
3507
PolymorphicConvention convention (IGM, origType, considerParameterSources);
@@ -3513,14 +3514,14 @@ NecessaryBindings NecessaryBindings::computeBindings(
3513
3514
continue ;
3514
3515
3515
3516
case MetadataSource::Kind::GenericLValueMetadata:
3516
- bindings. addRequirement (GenericRequirement::forMetadata (
3517
+ addRequirement (GenericRequirement::forMetadata (
3517
3518
getOrigSelfType (IGM, origType)));
3518
3519
continue ;
3519
3520
3520
3521
case MetadataSource::Kind::SelfMetadata:
3521
3522
// Async functions pass the SelfMetadata and SelfWitnessTable parameters
3522
3523
// along explicitly.
3523
- bindings. addRequirement (GenericRequirement::forMetadata (
3524
+ addRequirement (GenericRequirement::forMetadata (
3524
3525
getOrigSelfType (IGM, origType)));
3525
3526
continue ;
3526
3527
@@ -3538,10 +3539,8 @@ NecessaryBindings NecessaryBindings::computeBindings(
3538
3539
// - unfulfilled requirements
3539
3540
convention.enumerateUnfulfilledRequirements (
3540
3541
[&](GenericRequirement requirement) {
3541
- bindings. addRequirement (requirement);
3542
+ addRequirement (requirement);
3542
3543
});
3543
-
3544
- return bindings;
3545
3544
}
3546
3545
3547
3546
// / The information we need to record in generic type metadata
@@ -3592,7 +3591,8 @@ void irgen::emitInitOfGenericRequirementsBuffer(IRGenFunction &IGF,
3592
3591
ArrayRef<GenericRequirement> requirements,
3593
3592
Address buffer,
3594
3593
MetadataState metadataState,
3595
- SubstitutionMap subs) {
3594
+ SubstitutionMap subs,
3595
+ bool onHeapPacks) {
3596
3596
if (requirements.empty ()) return ;
3597
3597
3598
3598
// Cast the buffer to %type**.
@@ -3607,7 +3607,7 @@ void irgen::emitInitOfGenericRequirementsBuffer(IRGenFunction &IGF,
3607
3607
}
3608
3608
3609
3609
llvm::Value *value = emitGenericRequirementFromSubstitutions (
3610
- IGF, requirements[index], metadataState, subs);
3610
+ IGF, requirements[index], metadataState, subs, onHeapPacks );
3611
3611
slot = IGF.Builder .CreateElementBitCast (slot,
3612
3612
requirements[index].getType (IGF.IGM ));
3613
3613
IGF.Builder .CreateStore (value, slot);
@@ -3618,7 +3618,8 @@ llvm::Value *
3618
3618
irgen::emitGenericRequirementFromSubstitutions (IRGenFunction &IGF,
3619
3619
GenericRequirement requirement,
3620
3620
MetadataState metadataState,
3621
- SubstitutionMap subs) {
3621
+ SubstitutionMap subs,
3622
+ bool onHeapPacks) {
3622
3623
CanType depTy = requirement.getTypeParameter ();
3623
3624
CanType argType = depTy.subst (subs)->getCanonicalType ();
3624
3625
@@ -3627,16 +3628,39 @@ irgen::emitGenericRequirementFromSubstitutions(IRGenFunction &IGF,
3627
3628
return IGF.emitPackShapeExpression (argType);
3628
3629
3629
3630
case GenericRequirement::Kind::Metadata:
3630
- case GenericRequirement::Kind::MetadataPack:
3631
3631
return IGF.emitTypeMetadataRef (argType, metadataState).getMetadata ();
3632
3632
3633
- case GenericRequirement::Kind::WitnessTable:
3633
+ case GenericRequirement::Kind::MetadataPack: {
3634
+ auto metadata = IGF.emitTypeMetadataRef (argType, metadataState).getMetadata ();
3635
+ metadata = IGF.Builder .CreateBitCast (metadata, IGF.IGM .TypeMetadataPtrPtrTy );
3636
+
3637
+ // FIXME: We should track if this pack is already known to be on the heap
3638
+ if (onHeapPacks) {
3639
+ auto shape = IGF.emitPackShapeExpression (argType);
3640
+ metadata = IGF.Builder .CreateCall (IGF.IGM .getAllocateMetadataPackFunctionPointer (),
3641
+ {metadata, shape});
3642
+ }
3643
+
3644
+ return metadata;
3645
+ }
3646
+
3647
+ case GenericRequirement::Kind::WitnessTable: {
3648
+ auto conformance = subs.lookupConformance (depTy, requirement.getProtocol ());
3649
+ return emitWitnessTableRef (IGF, argType, conformance);
3650
+ }
3651
+
3634
3652
case GenericRequirement::Kind::WitnessTablePack: {
3635
- auto proto = requirement.getProtocol ();
3636
- auto conformance = subs.lookupConformance (depTy, proto);
3637
- assert (conformance.getRequirement () == proto);
3638
- llvm::Value *metadata = nullptr ;
3639
- auto wtable = emitWitnessTableRef (IGF, argType, &metadata, conformance);
3653
+ auto conformance = subs.lookupConformance (depTy, requirement.getProtocol ());
3654
+ auto wtable = emitWitnessTableRef (IGF, argType, conformance);
3655
+ wtable = IGF.Builder .CreateBitCast (wtable, IGF.IGM .WitnessTablePtrPtrTy );
3656
+
3657
+ // FIXME: We should track if this pack is already known to be on the heap
3658
+ if (onHeapPacks) {
3659
+ auto shape = IGF.emitPackShapeExpression (argType);
3660
+ wtable = IGF.Builder .CreateCall (IGF.IGM .getAllocateWitnessTablePackFunctionPointer (),
3661
+ {wtable, shape});
3662
+ }
3663
+
3640
3664
return wtable;
3641
3665
}
3642
3666
}
@@ -3651,10 +3675,10 @@ void GenericTypeRequirements::bindFromBuffer(IRGenFunction &IGF,
3651
3675
}
3652
3676
3653
3677
void irgen::bindFromGenericRequirementsBuffer (IRGenFunction &IGF,
3654
- ArrayRef<GenericRequirement> requirements,
3655
- Address buffer,
3656
- MetadataState metadataState,
3657
- SubstitutionMap subs) {
3678
+ ArrayRef<GenericRequirement> requirements,
3679
+ Address buffer,
3680
+ MetadataState metadataState,
3681
+ SubstitutionMap subs) {
3658
3682
if (requirements.empty ()) return ;
3659
3683
3660
3684
// Cast the buffer to %type**.
0 commit comments