Skip to content

Commit 65d164a

Browse files
committed
Revert "[SIL] Distributed: Remove logic related to ad-hoc requirements from SILFunction"
This reverts commit 1909b12.
1 parent dfe9d33 commit 65d164a

File tree

14 files changed

+112
-13
lines changed

14 files changed

+112
-13
lines changed

Diff for: include/swift/SIL/SILFunction.h

+32
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,17 @@ class SILFunction
264264
/// @_dynamicReplacement(for:) function.
265265
SILFunction *ReplacedFunction = nullptr;
266266

267+
/// This SILFunction REFerences an ad-hoc protocol requirement witness in
268+
/// order to keep it alive, such that it main be obtained in IRGen. Without
269+
/// this explicit reference, the witness would seem not-used, and not be
270+
/// accessible for IRGen.
271+
///
272+
/// Specifically, one such case is the DistributedTargetInvocationDecoder's
273+
/// 'decodeNextArgument' which must be retained, as it is only used from IRGen
274+
/// and such, appears as-if unused in SIL and would get optimized away.
275+
// TODO: Consider making this a general "references adhoc functions" and make it an array?
276+
SILFunction *RefAdHocRequirementFunction = nullptr;
277+
267278
Identifier ObjCReplacementFor;
268279

269280
/// The head of a single-linked list of currently alive BasicBlockBitfield.
@@ -585,6 +596,27 @@ class SILFunction
585596
ReplacedFunction = nullptr;
586597
}
587598

599+
SILFunction *getReferencedAdHocRequirementWitnessFunction() const {
600+
return RefAdHocRequirementFunction;
601+
}
602+
// Marks that this `SILFunction` uses the passed in ad-hoc protocol
603+
// requirement witness `f` and therefore must retain it explicitly,
604+
// otherwise we might not be able to get a reference to it.
605+
void setReferencedAdHocRequirementWitnessFunction(SILFunction *f) {
606+
assert(RefAdHocRequirementFunction == nullptr && "already set");
607+
608+
if (f == nullptr)
609+
return;
610+
RefAdHocRequirementFunction = f;
611+
RefAdHocRequirementFunction->incrementRefCount();
612+
}
613+
void dropReferencedAdHocRequirementWitnessFunction() {
614+
if (!RefAdHocRequirementFunction)
615+
return;
616+
RefAdHocRequirementFunction->decrementRefCount();
617+
RefAdHocRequirementFunction = nullptr;
618+
}
619+
588620
bool hasObjCReplacement() const {
589621
return !ObjCReplacementFor.empty();
590622
}

Diff for: lib/SIL/IR/SILFunction.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ void SILFunction::createSnapshot(int id) {
278278
newSnapshot->DeclCtxt = DeclCtxt;
279279
newSnapshot->Profiler = Profiler;
280280
newSnapshot->ReplacedFunction = ReplacedFunction;
281+
newSnapshot->RefAdHocRequirementFunction = RefAdHocRequirementFunction;
281282
newSnapshot->ObjCReplacementFor = ObjCReplacementFor;
282283
newSnapshot->SemanticsAttrSet = SemanticsAttrSet;
283284
newSnapshot->SpecializeAttrSet = SpecializeAttrSet;

Diff for: lib/SIL/IR/SILFunctionBuilder.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,15 @@ void SILFunctionBuilder::addFunctionAttributes(
274274

275275
F->setDynamicallyReplacedFunction(replacedFunc);
276276
}
277+
} else if (constant.isDistributedThunk()) {
278+
auto decodeFuncDecl =
279+
getAssociatedDistributedInvocationDecoderDecodeNextArgumentFunction(
280+
decl);
281+
assert(decodeFuncDecl && "decodeNextArgument function not found!");
282+
283+
auto decodeRef = SILDeclRef(decodeFuncDecl);
284+
auto *adHocFunc = getOrCreateDeclaration(decodeFuncDecl, decodeRef);
285+
F->setReferencedAdHocRequirementWitnessFunction(adHocFunc);
277286
}
278287
}
279288

Diff for: lib/SIL/IR/SILModule.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ SILModule::~SILModule() {
154154
for (SILFunction &F : *this) {
155155
F.dropAllReferences();
156156
F.dropDynamicallyReplacedFunction();
157+
F.dropReferencedAdHocRequirementWitnessFunction();
157158
F.clearSpecializeAttrs();
158159
}
159160

@@ -491,6 +492,7 @@ void SILModule::eraseFunction(SILFunction *F) {
491492
// (References are not needed anymore.)
492493
F->clear();
493494
F->dropDynamicallyReplacedFunction();
495+
F->dropReferencedAdHocRequirementWitnessFunction();
494496
// Drop references for any _specialize(target:) functions.
495497
F->clearSpecializeAttrs();
496498
}

Diff for: lib/SIL/IR/SILPrinter.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -3411,6 +3411,12 @@ void SILFunction::print(SILPrintContext &PrintCtx) const {
34113411
OS << "\"] ";
34123412
}
34133413

3414+
if (auto *usedFunc = getReferencedAdHocRequirementWitnessFunction()) {
3415+
OS << "[ref_adhoc_requirement_witness \"";
3416+
OS << usedFunc->getName();
3417+
OS << "\"] ";
3418+
}
3419+
34143420
if (hasObjCReplacement()) {
34153421
OS << "[objc_replacement_for \"";
34163422
OS << getObjCReplacement().str();

Diff for: lib/SIL/Parser/ParseSIL.cpp

+30-7
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ static bool parseDeclSILOptional(
675675
UseStackForPackMetadata_t *useStackForPackMetadata,
676676
bool *hasUnsafeNonEscapableResult, IsExactSelfClass_t *isExactSelfClass,
677677
SILFunction **dynamicallyReplacedFunction,
678-
Identifier *objCReplacementFor,
678+
SILFunction **usedAdHocRequirementWitness, Identifier *objCReplacementFor,
679679
SILFunction::Purpose *specialPurpose, Inline_t *inlineStrategy,
680680
OptimizationMode *optimizationMode, PerformanceConstraints *perfConstraints,
681681
bool *isPerformanceConstraint,
@@ -825,6 +825,26 @@ static bool parseDeclSILOptional(
825825
*dynamicallyReplacedFunction = Func;
826826
SP.P.consumeToken(tok::string_literal);
827827

828+
SP.P.parseToken(tok::r_square, diag::expected_in_attribute_list);
829+
continue;
830+
} else if (usedAdHocRequirementWitness && SP.P.Tok.getText() == "ref_adhoc_requirement_witness") {
831+
SP.P.consumeToken(tok::identifier);
832+
if (SP.P.Tok.getKind() != tok::string_literal) {
833+
SP.P.diagnose(SP.P.Tok, diag::expected_in_attribute_list);
834+
return true;
835+
}
836+
// Drop the double quotes.
837+
StringRef witnessFunc = SP.P.Tok.getText().drop_front().drop_back();
838+
SILFunction *Func = M.lookUpFunction(witnessFunc.str());
839+
if (!Func) {
840+
Identifier Id = SP.P.Context.getIdentifier(witnessFunc);
841+
SP.P.diagnose(SP.P.Tok, diag::sil_adhoc_requirement_witness_func_not_found,
842+
Id);
843+
return true;
844+
}
845+
*usedAdHocRequirementWitness = Func;
846+
SP.P.consumeToken(tok::string_literal);
847+
828848
SP.P.parseToken(tok::r_square, diag::expected_in_attribute_list);
829849
continue;
830850
} else if (objCReplacementFor &&
@@ -7062,6 +7082,7 @@ bool SILParserState::parseDeclSIL(Parser &P) {
70627082
ValueDecl *ClangDecl = nullptr;
70637083
EffectsKind MRK = EffectsKind::Unspecified;
70647084
SILFunction *DynamicallyReplacedFunction = nullptr;
7085+
SILFunction *AdHocWitnessFunction = nullptr;
70657086
Identifier objCReplacementFor;
70667087
if (parseSILLinkage(FnLinkage, P) ||
70677088
parseDeclSILOptional(
@@ -7070,7 +7091,7 @@ bool SILParserState::parseDeclSIL(Parser &P) {
70707091
&isRuntimeAccessible, &forceEnableLexicalLifetimes,
70717092
&useStackForPackMetadata, &hasUnsafeNonEscapableResult,
70727093
&isExactSelfClass, &DynamicallyReplacedFunction,
7073-
&objCReplacementFor, &specialPurpose,
7094+
&AdHocWitnessFunction, &objCReplacementFor, &specialPurpose,
70747095
&inlineStrategy, &optimizationMode, &perfConstr,
70757096
&isPerformanceConstraint, &markedAsUsed,
70767097
&section, nullptr, &isWeakImported, &needStackProtection,
@@ -7116,6 +7137,8 @@ bool SILParserState::parseDeclSIL(Parser &P) {
71167137
FunctionState.F->setIsExactSelfClass(isExactSelfClass);
71177138
FunctionState.F->setDynamicallyReplacedFunction(
71187139
DynamicallyReplacedFunction);
7140+
FunctionState.F->setReferencedAdHocRequirementWitnessFunction(
7141+
AdHocWitnessFunction);
71197142
if (!objCReplacementFor.empty())
71207143
FunctionState.F->setObjCReplacement(objCReplacementFor);
71217144
FunctionState.F->setSpecialPurpose(specialPurpose);
@@ -7325,7 +7348,7 @@ bool SILParserState::parseSILGlobal(Parser &P) {
73257348
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
73267349
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
73277350
nullptr,
7328-
nullptr, nullptr, nullptr, nullptr, &isLet,
7351+
nullptr, nullptr, nullptr, nullptr, nullptr, &isLet,
73297352
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
73307353
nullptr, nullptr, State, M) ||
73317354
P.parseToken(tok::at_sign, diag::expected_sil_value_name) ||
@@ -7379,7 +7402,7 @@ bool SILParserState::parseSILProperty(Parser &P) {
73797402
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
73807403
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
73817404
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
7382-
nullptr, nullptr, SP, M))
7405+
nullptr, nullptr, nullptr, SP, M))
73837406
return true;
73847407

73857408
ValueDecl *VD;
@@ -7449,7 +7472,7 @@ bool SILParserState::parseSILVTable(Parser &P) {
74497472
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
74507473
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
74517474
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
7452-
nullptr, nullptr, VTableState, M))
7475+
nullptr, nullptr, nullptr, VTableState, M))
74537476
return true;
74547477

74557478

@@ -7572,7 +7595,7 @@ bool SILParserState::parseSILMoveOnlyDeinit(Parser &parser) {
75727595
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
75737596
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
75747597
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
7575-
nullptr, nullptr, moveOnlyDeinitTableState, M))
7598+
nullptr, nullptr, nullptr, moveOnlyDeinitTableState, M))
75767599
return true;
75777600

75787601
// Parse the class name.
@@ -8059,7 +8082,7 @@ bool SILParserState::parseSILWitnessTable(Parser &P) {
80598082
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
80608083
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
80618084
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
8062-
nullptr, nullptr, WitnessState, M))
8085+
nullptr, nullptr, nullptr, WitnessState, M))
80638086
return true;
80648087

80658088
// Parse the protocol conformance.

Diff for: lib/SILOptimizer/Analysis/CallerAnalysis.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ CallerAnalysis::FunctionInfo::FunctionInfo(SILFunction *f)
3535
// final/visibility/etc.
3636
mayHaveIndirectCallers(
3737
f->getDynamicallyReplacedFunction() ||
38+
f->getReferencedAdHocRequirementWitnessFunction() ||
3839
canBeCalledIndirectly(f->getRepresentation())),
3940
mayHaveExternalCallers(f->isPossiblyUsedExternally() ||
4041
f->isAvailableExternally()) {}

Diff for: lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,7 @@ bool FunctionSignatureTransform::run(bool hasCaller) {
668668
hasCaller |= FSOOptimizeIfNotCalled;
669669

670670
if (!hasCaller && (F->getDynamicallyReplacedFunction() ||
671+
F->getReferencedAdHocRequirementWitnessFunction() ||
671672
canBeCalledIndirectly(F->getRepresentation()))) {
672673
LLVM_DEBUG(llvm::dbgs() << " function has no caller -> abort\n");
673674
return false;

Diff for: lib/SILOptimizer/IPO/DeadFunctionElimination.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ class DeadFunctionAndGlobalElimination {
110110
if (F->isDynamicallyReplaceable())
111111
return true;
112112

113+
if (F->getReferencedAdHocRequirementWitnessFunction())
114+
return true;
115+
113116
// Don't remove pre-specialized functions. We need to preserver the
114117
// pre-specialization specifications from other modules.
115118
if (F->hasPrespecialization())
@@ -340,6 +343,9 @@ class DeadFunctionAndGlobalElimination {
340343
if (auto *replacedFn = F->getDynamicallyReplacedFunction())
341344
ensureAlive(replacedFn);
342345

346+
if (auto *adHocWitness = F->getReferencedAdHocRequirementWitnessFunction())
347+
ensureAlive(adHocWitness);
348+
343349
// First scan all instructions of the function.
344350
for (SILBasicBlock &BB : *F) {
345351
for (SILInstruction &I : BB) {

Diff for: lib/Serialization/DeserializeSIL.cpp

+13-2
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,7 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn,
556556
ModuleID parentModuleID;
557557
TypeID funcTyID;
558558
IdentifierID replacedFunctionID;
559+
IdentifierID usedAdHocWitnessFunctionID;
559560
GenericSignatureID genericSigID;
560561
unsigned rawLinkage, isTransparent, isSerialized, isThunk,
561562
isWithoutActuallyEscapingThunk, specialPurpose, inlineStrategy,
@@ -571,7 +572,7 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn,
571572
numAttrs, hasQualifiedOwnership, isWeakImported,
572573
LIST_VER_TUPLE_PIECES(available), isDynamic, isExactSelfClass,
573574
isDistributed, isRuntimeAccessible, forceEnableLexicalLifetimes, funcTyID,
574-
replacedFunctionID, genericSigID,
575+
replacedFunctionID, usedAdHocWitnessFunctionID, genericSigID,
575576
clangNodeOwnerID, parentModuleID, SemanticsIDs);
576577

577578
if (funcTyID == 0)
@@ -600,6 +601,13 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn,
600601
replacedObjectiveCFunc = MF->getIdentifier(replacedFunctionID);
601602
}
602603

604+
SILFunction *usedAdHocWitnessFunction = nullptr;
605+
if (usedAdHocWitnessFunctionID) {
606+
auto usedAdHocWitnessFunctionStr =
607+
MF->getIdentifier(usedAdHocWitnessFunctionID).str();
608+
usedAdHocWitnessFunction = getFuncForReference(usedAdHocWitnessFunctionStr);
609+
}
610+
603611
auto linkageOpt = fromStableSILLinkage(rawLinkage);
604612
if (!linkageOpt) {
605613
LLVM_DEBUG(llvm::dbgs() << "invalid linkage code " << rawLinkage
@@ -718,6 +726,8 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn,
718726
fn->setDynamicallyReplacedFunction(replacedFunction);
719727
if (!replacedObjectiveCFunc.empty())
720728
fn->setObjCReplacement(replacedObjectiveCFunc);
729+
if (usedAdHocWitnessFunction)
730+
fn->setReferencedAdHocRequirementWitnessFunction(usedAdHocWitnessFunction);
721731
if (clangNodeOwner)
722732
fn->setClangNodeOwner(clangNodeOwner);
723733
for (auto ID : SemanticsIDs) {
@@ -3402,6 +3412,7 @@ bool SILDeserializer::hasSILFunction(StringRef Name,
34023412
ModuleID parentModuleID;
34033413
TypeID funcTyID;
34043414
IdentifierID replacedFunctionID;
3415+
IdentifierID usedAdHocWitnessFunctionID;
34053416
GenericSignatureID genericSigID;
34063417
unsigned rawLinkage, isTransparent, isSerialized, isThunk,
34073418
isWithoutActuallyEscapingThunk, isGlobal, inlineStrategy,
@@ -3417,7 +3428,7 @@ bool SILDeserializer::hasSILFunction(StringRef Name,
34173428
numSpecAttrs, hasQualifiedOwnership, isWeakImported,
34183429
LIST_VER_TUPLE_PIECES(available), isDynamic, isExactSelfClass,
34193430
isDistributed, isRuntimeAccessible, forceEnableLexicalLifetimes, funcTyID,
3420-
replacedFunctionID, genericSigID,
3431+
replacedFunctionID, usedAdHocWitnessFunctionID, genericSigID,
34213432
clangOwnerID, parentModuleID, SemanticsIDs);
34223433
auto linkage = fromStableSILLinkage(rawLinkage);
34233434
if (!linkage) {

Diff for: lib/Serialization/ModuleFormat.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5858
/// describe what change you made. The content of this comment isn't important;
5959
/// it just ensures a conflict if two people change the module format.
6060
/// Don't worry about adhering to the 80-column limit for this line.
61-
const uint16_t SWIFTMODULE_VERSION_MINOR = 854; // _distributedThunkTarget
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 855; // ref_adhoc_requirement_witness attributes are back
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///

Diff for: lib/Serialization/SILFormat.h

+1
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ namespace sil_block {
312312
BCFixed<1>, // are lexical lifetimes force-enabled
313313
TypeIDField, // SILFunctionType
314314
DeclIDField, // SILFunction name or 0 (replaced function)
315+
DeclIDField, // SILFunction name or 0 (used ad-hoc requirement witness function)
315316
GenericSignatureIDField,
316317
DeclIDField, // ClangNode owner
317318
ModuleIDField, // Parent ModuleDecl *

Diff for: lib/Serialization/SerializeSIL.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,12 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) {
483483
S.addUniquedStringRef(F.getObjCReplacement().str());
484484
}
485485

486+
IdentifierID usedAdHocWitnessFunctionID = 0;
487+
if (auto *fun = F.getReferencedAdHocRequirementWitnessFunction()) {
488+
addReferencedSILFunction(fun, true);
489+
usedAdHocWitnessFunctionID = S.addUniquedStringRef(fun->getName());
490+
}
491+
486492
unsigned numAttrs = NoBody ? 0 : F.getSpecializeAttrs().size();
487493

488494
auto resilience = F.getModule().getSwiftModule()->getResilienceStrategy();
@@ -516,7 +522,7 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) {
516522
(unsigned)F.isExactSelfClass(), (unsigned)F.isDistributed(),
517523
(unsigned)F.isRuntimeAccessible(),
518524
(unsigned)F.forceEnableLexicalLifetimes(), FnID, replacedFunctionID,
519-
genericSigID, clangNodeOwnerID,
525+
usedAdHocWitnessFunctionID, genericSigID, clangNodeOwnerID,
520526
parentModuleID, SemanticsIDs);
521527

522528
F.visitArgEffects(

Diff for: test/Distributed/SIL/distributed_thunk.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ distributed actor DA {
99
}
1010

1111
extension DA {
12-
// CHECK-LABEL: sil hidden [thunk] [distributed] [ossa] @$s17distributed_thunk2DAC1fyyYaKFTE : $@convention(method) @async (@guaranteed DA) -> @error any Error {
12+
// CHECK-LABEL: sil hidden [thunk] [distributed] [ref_adhoc_requirement_witness "$s11Distributed29LocalTestingInvocationDecoderC18decodeNextArgumentxyKSeRzSERzlF"] [ossa] @$s17distributed_thunk2DAC1fyyYaKFTE : $@convention(method) @async (@guaranteed DA) -> @error any Error {
1313
// CHECK: function_ref @swift_distributed_actor_is_remote
1414

1515
// Call the actor function
@@ -65,7 +65,7 @@ protocol Server2: DistributedActor {
6565
}
6666

6767
extension Server2 where ActorSystem == LocalTestingDistributedActorSystem {
68-
// CHECK-LABEL: sil hidden [thunk] [distributed] [ossa] @$s17distributed_thunk7Server2PAA11Distributed012LocalTestingD11ActorSystemC0gH0RtzrlE8sayHelloyyYaKFTE
68+
// CHECK-LABEL: sil hidden [thunk] [distributed] [ref_adhoc_requirement_witness "$s11Distributed29LocalTestingInvocationDecoderC18decodeNextArgumentxyKSeRzSERzlF"] [ossa] @$s17distributed_thunk7Server2PAA11Distributed012LocalTestingD11ActorSystemC0gH0RtzrlE8sayHelloyyYaKFTE
6969
// CHECK-NOT: return
7070
// CHECK: function_ref @swift_distributed_actor_is_remote
7171
distributed func sayHello() { /* default impl */ }

0 commit comments

Comments
 (0)