Skip to content

Commit 1a08018

Browse files
authored
Merge pull request #79963 from gottesmm/pr-6e79b08bb62307778a04913d3c02b8ed620f61bc
Revert "SILGen: Emit an addressable representation for immutable bindings on demand."
2 parents 9b876fd + f6349aa commit 1a08018

14 files changed

+72
-625
lines changed

include/swift/AST/Types.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -4334,7 +4334,9 @@ inline bool isConsumedParameterInCaller(ParameterConvention conv) {
43344334
return isConsumedParameter<false>(conv);
43354335
}
43364336

4337-
/// Returns true if conv is a guaranteed parameter.
4337+
/// Returns true if conv is a guaranteed parameter. This may look unnecessary
4338+
/// but this will allow code to generalize to handle Indirect_Guaranteed
4339+
/// parameters when they are added.
43384340
template <bool InCallee>
43394341
bool isGuaranteedParameter(ParameterConvention conv) {
43404342
switch (conv) {

lib/SIL/IR/AbstractionPattern.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -1679,7 +1679,9 @@ AbstractionPattern::isFunctionParamAddressable(TypeConverter &TC,
16791679
auto type = getType();
16801680

16811681
if (type->isTypeParameter() || type->is<ArchetypeType>()) {
1682-
return false;
1682+
// If the function abstraction pattern is completely opaque, assume we
1683+
// may need to preserve the address for dependencies.
1684+
return true;
16831685
}
16841686

16851687
auto fnTy = cast<AnyFunctionType>(getType());

lib/SILGen/SILGenApply.cpp

+7-13
Original file line numberDiff line numberDiff line change
@@ -3462,9 +3462,11 @@ SILGenFunction::tryEmitAddressableParameterAsAddress(ArgumentSource &&arg,
34623462
expr = le->getSubExpr();
34633463
}
34643464
if (auto dre = dyn_cast<DeclRefExpr>(expr)) {
3465-
if (auto param = dyn_cast<VarDecl>(dre->getDecl())) {
3466-
if (auto addr = getLocalVariableAddressableBuffer(param, expr,
3467-
ownership)) {
3465+
if (auto param = dyn_cast<ParamDecl>(dre->getDecl())) {
3466+
if (VarLocs.count(param)
3467+
&& VarLocs[param].addressable
3468+
&& param->getValueOwnership() == ownership) {
3469+
auto addr = VarLocs[param].value;
34683470
return ManagedValue::forBorrowedAddressRValue(addr);
34693471
}
34703472
}
@@ -3575,20 +3577,12 @@ class ArgEmitter {
35753577
void emit(ArgumentSource &&arg, AbstractionPattern origParamType,
35763578
bool isAddressable,
35773579
std::optional<AnyFunctionType::Param> origParam = std::nullopt) {
3578-
if (isAddressable) {
3580+
if (isAddressable && origParam) {
35793581
// If the function takes an addressable parameter, and its argument is
35803582
// a reference to an addressable declaration with compatible ownership,
35813583
// forward the address along in-place.
3582-
ValueOwnership paramOwnership;
3583-
if (isGuaranteedParameterInCaller(ParamInfos.front().getConvention())) {
3584-
paramOwnership = ValueOwnership::Shared;
3585-
} else if (isMutatingParameter(ParamInfos.front().getConvention())) {
3586-
paramOwnership = ValueOwnership::InOut;
3587-
} else {
3588-
paramOwnership = ValueOwnership::Owned;
3589-
}
35903584
if (auto addr = SGF.tryEmitAddressableParameterAsAddress(std::move(arg),
3591-
paramOwnership)) {
3585+
origParam->getValueOwnership())) {
35923586
claimNextParameters(1);
35933587
Args.push_back(addr);
35943588
return;

lib/SILGen/SILGenBuilder.cpp

-12
Original file line numberDiff line numberDiff line change
@@ -1081,18 +1081,6 @@ class EndAccessCleanup final : public Cleanup {
10811081
};
10821082
}
10831083

1084-
SILValue
1085-
SILGenBuilder::emitBeginAccess(SILLocation loc,
1086-
SILValue address,
1087-
SILAccessKind kind,
1088-
SILAccessEnforcement enforcement) {
1089-
auto access = createBeginAccess(loc, address,
1090-
kind, enforcement,
1091-
/*no nested conflict*/ false, false);
1092-
SGF.Cleanups.pushCleanup<EndAccessCleanup>(access);
1093-
return access;
1094-
}
1095-
10961084
ManagedValue
10971085
SILGenBuilder::createOpaqueBorrowBeginAccess(SILLocation loc,
10981086
ManagedValue address) {

lib/SILGen/SILGenBuilder.h

-4
Original file line numberDiff line numberDiff line change
@@ -477,10 +477,6 @@ class SILGenBuilder : public SILBuilder {
477477
ManagedValue base,
478478
MarkDependenceKind dependencekind);
479479

480-
SILValue emitBeginAccess(SILLocation loc, SILValue address,
481-
SILAccessKind kind,
482-
SILAccessEnforcement enforcement);
483-
484480
ManagedValue createOpaqueBorrowBeginAccess(SILLocation loc,
485481
ManagedValue address);
486482
ManagedValue createOpaqueConsumeBeginAccess(SILLocation loc,

lib/SILGen/SILGenConstructor.cpp

+7-8
Original file line numberDiff line numberDiff line change
@@ -1173,8 +1173,7 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
11731173
MarkUnresolvedNonCopyableValueInst::CheckKind::
11741174
ConsumableAndAssignable);
11751175
}
1176-
VarLocs[selfDecl] = VarLoc(selfArg.getValue(),
1177-
SILAccessEnforcement::Static);
1176+
VarLocs[selfDecl] = VarLoc::get(selfArg.getValue());
11781177
}
11791178
}
11801179

@@ -1697,7 +1696,7 @@ void SILGenFunction::emitIVarInitializer(SILDeclRef ivarInitializer) {
16971696
selfArg = B.createMarkUninitialized(selfDecl, selfArg,
16981697
MarkUninitializedInst::RootSelf);
16991698
assert(selfTy.hasReferenceSemantics() && "can't emit a value type ctor here");
1700-
VarLocs[selfDecl] = VarLoc(selfArg, SILAccessEnforcement::Unknown);
1699+
VarLocs[selfDecl] = VarLoc::get(selfArg);
17011700

17021701
auto cleanupLoc = CleanupLocation(loc);
17031702
prepareEpilog(cd, std::nullopt, std::nullopt, cleanupLoc);
@@ -1728,11 +1727,11 @@ void SILGenFunction::emitInitAccessor(AccessorDecl *accessor) {
17281727
loc.markAutoGenerated();
17291728

17301729
SILValue argValue = F.begin()->createFunctionArgument(type, arg);
1731-
if (markUninitialized) {
1732-
argValue = B.createMarkUninitializedOut(loc, argValue);
1733-
}
1734-
1735-
VarLocs[arg] = VarLoc(argValue, SILAccessEnforcement::Static);
1730+
VarLocs[arg] =
1731+
markUninitialized
1732+
? VarLoc::get(B.createMarkUninitializedOut(loc, argValue))
1733+
: VarLoc::get(argValue);
1734+
17361735
InitAccessorArgumentMappings[property] = arg;
17371736
};
17381737

lib/SILGen/SILGenDecl.cpp

+7-163
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ class DestroyLocalVariable : public Cleanup {
472472
Var->print(llvm::errs());
473473
llvm::errs() << "\n";
474474
if (isActive()) {
475-
auto &loc = SGF.VarLocs[Var];
475+
auto loc = SGF.VarLocs[Var];
476476
assert((loc.box || loc.value) && "One of box or value should be set");
477477
if (loc.box) {
478478
llvm::errs() << "Box: " << loc.box << "\n";
@@ -664,8 +664,7 @@ class LocalVariableInitialization : public SingleBufferInitialization {
664664
/// decl to.
665665
assert(SGF.VarLocs.count(decl) == 0 && "Already emitted the local?");
666666

667-
SGF.VarLocs[decl] = SILGenFunction::VarLoc(Addr,
668-
SILAccessEnforcement::Dynamic, Box);
667+
SGF.VarLocs[decl] = SILGenFunction::VarLoc::get(Addr, Box);
669668

670669
SingleBufferInitialization::finishInitialization(SGF);
671670
assert(!DidFinish &&
@@ -678,54 +677,6 @@ class LocalVariableInitialization : public SingleBufferInitialization {
678677
} // end anonymous namespace
679678

680679
namespace {
681-
682-
static void deallocateAddressable(SILGenFunction &SGF,
683-
SILLocation l,
684-
SILGenFunction::VarLoc &loc) {
685-
SGF.B.createEndBorrow(l, loc.addressableBuffer.state->storeBorrow);
686-
SGF.B.createDeallocStack(l, loc.addressableBuffer.state->allocStack);
687-
if (loc.addressableBuffer.state->reabstraction) {
688-
SGF.B.createDestroyValue(l, loc.addressableBuffer.state->reabstraction);
689-
}
690-
}
691-
692-
/// Cleanup to deallocate the addressable buffer for a parameter or let
693-
/// binding.
694-
class DeallocateLocalVariableAddressableBuffer : public Cleanup {
695-
ValueDecl *vd;
696-
public:
697-
DeallocateLocalVariableAddressableBuffer(ValueDecl *vd) : vd(vd) {}
698-
699-
void emit(SILGenFunction &SGF, CleanupLocation l,
700-
ForUnwind_t forUnwind) override {
701-
auto found = SGF.VarLocs.find(vd);
702-
if (found == SGF.VarLocs.end()) {
703-
return;
704-
}
705-
auto &loc = found->second;
706-
707-
if (loc.addressableBuffer.state) {
708-
// The addressable buffer was forced, so clean it up now.
709-
deallocateAddressable(SGF, l, loc);
710-
} else {
711-
// Remember this insert location in case we need to force the addressable
712-
// buffer later.
713-
SILInstruction *marker = SGF.B.createTuple(l, {});
714-
loc.addressableBuffer.cleanupPoints.emplace_back(marker);
715-
}
716-
}
717-
718-
void dump(SILGenFunction &SGF) const override {
719-
#ifndef NDEBUG
720-
llvm::errs() << "DeallocateLocalVariableAddressableBuffer\n"
721-
<< "State:" << getState() << "\n"
722-
<< "Decl: ";
723-
vd->print(llvm::errs());
724-
llvm::errs() << "\n";
725-
#endif
726-
}
727-
};
728-
729680
/// Initialize a writeback buffer that receives the value of a 'let'
730681
/// declaration.
731682
class LetValueInitialization : public Initialization {
@@ -804,8 +755,7 @@ class LetValueInitialization : public Initialization {
804755
if (isUninitialized)
805756
address = SGF.B.createMarkUninitializedVar(vd, address);
806757
DestroyCleanup = SGF.enterDormantTemporaryCleanup(address, *lowering);
807-
SGF.VarLocs[vd] = SILGenFunction::VarLoc(address,
808-
SILAccessEnforcement::Unknown);
758+
SGF.VarLocs[vd] = SILGenFunction::VarLoc::get(address);
809759
}
810760
// Push a cleanup to destroy the let declaration. This has to be
811761
// inactive until the variable is initialized: if control flow exits the
@@ -816,10 +766,6 @@ class LetValueInitialization : public Initialization {
816766
SGF.Cleanups.pushCleanupInState<DestroyLocalVariable>(
817767
CleanupState::Dormant, vd);
818768
DestroyCleanup = SGF.Cleanups.getTopCleanup();
819-
820-
// If the binding has an addressable buffer forced, it should be cleaned
821-
// up here.
822-
SGF.enterLocalVariableAddressableBufferScope(vd);
823769
}
824770

825771
~LetValueInitialization() override {
@@ -937,8 +883,7 @@ class LetValueInitialization : public Initialization {
937883
if (SGF.getASTContext().SILOpts.supportsLexicalLifetimes(SGF.getModule()))
938884
value = getValueForLexicalLifetimeBinding(SGF, loc, value, wasPlusOne);
939885

940-
SGF.VarLocs[vd] = SILGenFunction::VarLoc(value,
941-
SILAccessEnforcement::Unknown);
886+
SGF.VarLocs[vd] = SILGenFunction::VarLoc::get(value);
942887

943888
// Emit a debug_value[_addr] instruction to record the start of this value's
944889
// lifetime, if permitted to do so.
@@ -1518,7 +1463,7 @@ SILGenFunction::emitInitializationForVarDecl(VarDecl *vd, bool forceImmutable,
15181463
assert(SILDebugClient && "Debugger client doesn't support SIL");
15191464
SILValue SV = SILDebugClient->emitLValueForVariable(vd, B);
15201465

1521-
VarLocs[vd] = VarLoc(SV, SILAccessEnforcement::Dynamic);
1466+
VarLocs[vd] = SILGenFunction::VarLoc::get(SV);
15221467
return InitializationPtr(new KnownAddressInitialization(SV));
15231468
}
15241469

@@ -1549,7 +1494,7 @@ SILGenFunction::emitInitializationForVarDecl(VarDecl *vd, bool forceImmutable,
15491494
if (isUninitialized)
15501495
addr = B.createMarkUninitializedVar(loc, addr);
15511496

1552-
VarLocs[vd] = VarLoc(addr, SILAccessEnforcement::Dynamic);
1497+
VarLocs[vd] = SILGenFunction::VarLoc::get(addr);
15531498
Result = InitializationPtr(new KnownAddressInitialization(addr));
15541499
} else {
15551500
std::optional<MarkUninitializedInst::Kind> uninitKind;
@@ -2364,7 +2309,7 @@ void SILGenFunction::destroyLocalVariable(SILLocation silLoc, VarDecl *vd) {
23642309
}
23652310
};
23662311

2367-
auto &loc = VarLocs[vd];
2312+
auto loc = VarLocs[vd];
23682313

23692314
// For a heap variable, the box is responsible for the value. We just need
23702315
// to give up our retain count on it.
@@ -2461,101 +2406,6 @@ void SILGenFunction::destroyLocalVariable(SILLocation silLoc, VarDecl *vd) {
24612406
llvm_unreachable("unhandled case");
24622407
}
24632408

2464-
void
2465-
SILGenFunction::enterLocalVariableAddressableBufferScope(VarDecl *decl) {
2466-
Cleanups.pushCleanup<DeallocateLocalVariableAddressableBuffer>(decl);
2467-
}
2468-
2469-
SILValue
2470-
SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
2471-
SILLocation curLoc,
2472-
ValueOwnership ownership) {
2473-
auto foundVarLoc = VarLocs.find(decl);
2474-
if (foundVarLoc == VarLocs.end()) {
2475-
return SILValue();
2476-
}
2477-
2478-
auto &varLoc = foundVarLoc->second;
2479-
SILType fullyAbstractedTy = getLoweredType(AbstractionPattern::getOpaque(),
2480-
decl->getTypeInContext()->getRValueType());
2481-
2482-
// Check whether the bound value is inherently suitable for addressability.
2483-
// It must already be in memory and fully abstracted.
2484-
if (varLoc.value->getType().isAddress()
2485-
&& fullyAbstractedTy.getASTType()==varLoc.value->getType().getASTType()) {
2486-
SILValue address = varLoc.value;
2487-
// Begin an access if the address is mutable.
2488-
if (varLoc.access != SILAccessEnforcement::Unknown) {
2489-
address = B.emitBeginAccess(curLoc, address,
2490-
ownership == ValueOwnership::InOut ? SILAccessKind::Modify
2491-
: SILAccessKind::Read,
2492-
varLoc.access);
2493-
}
2494-
return address;
2495-
}
2496-
2497-
// We can't retroactively introduce a reabstracted representation for a
2498-
// mutable binding (since we would now have two mutable memory locations
2499-
// representing the same value).
2500-
if (varLoc.access != SILAccessEnforcement::Unknown) {
2501-
return SILValue();
2502-
}
2503-
2504-
assert(ownership == ValueOwnership::Shared);
2505-
2506-
// Check whether the in-memory representation has already been forced.
2507-
if (auto &state = varLoc.addressableBuffer.state) {
2508-
return state->storeBorrow;
2509-
}
2510-
2511-
// Otherwise, force the addressable representation.
2512-
SILValue reabstraction, allocStack, storeBorrow;
2513-
{
2514-
SavedInsertionPointRAII save(B);
2515-
B.setInsertionPoint(varLoc.value->getNextInstruction());
2516-
auto declarationLoc = varLoc.value->getDefiningInsertionPoint()->getLoc();
2517-
2518-
// Reabstract if necessary.
2519-
auto value = varLoc.value;
2520-
reabstraction = SILValue();
2521-
if (value->getType().getASTType() != fullyAbstractedTy.getASTType()){
2522-
auto reabstracted = emitSubstToOrigValue(curLoc,
2523-
ManagedValue::forBorrowedRValue(value),
2524-
AbstractionPattern::getOpaque(),
2525-
decl->getTypeInContext()->getCanonicalType(),
2526-
SGFContext());
2527-
reabstraction = reabstracted.forward(*this);
2528-
value = reabstraction;
2529-
}
2530-
// TODO: reabstract
2531-
allocStack = B.createAllocStack(declarationLoc, value->getType(),
2532-
std::nullopt,
2533-
DoesNotHaveDynamicLifetime,
2534-
IsNotLexical,
2535-
IsNotFromVarDecl,
2536-
DoesNotUseMoveableValueDebugInfo,
2537-
/*skipVarDeclAssert*/ true);
2538-
storeBorrow = B.createStoreBorrow(declarationLoc, value, allocStack);
2539-
}
2540-
2541-
// Record the addressable representation.
2542-
varLoc.addressableBuffer.state
2543-
= std::make_unique<VarLoc::AddressableBuffer::State>(reabstraction,
2544-
allocStack,
2545-
storeBorrow);
2546-
2547-
// Emit cleanups on any paths where we previously would have cleaned up
2548-
// the addressable representation if it had been forced earlier.
2549-
for (SILInstruction *cleanupPoint : varLoc.addressableBuffer.cleanupPoints) {
2550-
SavedInsertionPointRAII insertCleanup(B, cleanupPoint);
2551-
deallocateAddressable(*this, cleanupPoint->getLoc(), varLoc);
2552-
cleanupPoint->eraseFromParent();
2553-
}
2554-
varLoc.addressableBuffer.cleanupPoints.clear();
2555-
2556-
return storeBorrow;
2557-
}
2558-
25592409
void BlackHoleInitialization::performPackExpansionInitialization(
25602410
SILGenFunction &SGF,
25612411
SILLocation loc,
@@ -2587,9 +2437,3 @@ void BlackHoleInitialization::copyOrInitValueInto(SILGenFunction &SGF, SILLocati
25872437
value = SGF.B.createMoveValue(loc, value);
25882438
SGF.B.createIgnoredUse(loc, value.getValue());
25892439
}
2590-
2591-
SILGenFunction::VarLoc::AddressableBuffer::~AddressableBuffer() {
2592-
for (auto cleanupPoint : cleanupPoints) {
2593-
cleanupPoint->eraseFromParent();
2594-
}
2595-
}

lib/SILGen/SILGenFunction.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,7 @@ void SILGenFunction::emitCaptures(SILLocation loc,
770770
}
771771
};
772772

773-
auto &Entry = found->second;
773+
auto Entry = found->second;
774774
auto val = Entry.value;
775775

776776
switch (SGM.Types.getDeclCaptureKind(capture, expansion)) {

0 commit comments

Comments
 (0)