Skip to content

Commit

Permalink
Merge pull request swiftlang#77709 from gottesmm/pr-6feaf0c91a7d95d75…
Browse files Browse the repository at this point in the history
…b36d32cc91a32150d992162

[region-isolation] Some initial NFCI refactoring commits before adding experimental support for inheriting isolation to nonisolated functions
  • Loading branch information
gottesmm authored Nov 20, 2024
2 parents 729e3c0 + d94e4c4 commit e6b4e0f
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 124 deletions.
12 changes: 12 additions & 0 deletions include/swift/AST/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -5348,6 +5348,18 @@ class SILFunctionType final
return getParameters().back();
}

/// Return SILParameterInfo for the isolated parameter in this SILFunctionType
/// if one exists. Returns None otherwise.
std::optional<SILParameterInfo> maybeGetIsolatedParameter() const {
for (auto param : getParameters()) {
if (param.hasOption(SILParameterInfo::Isolated)) {
return param;
}
}

return {};
}

struct IndirectMutatingParameterFilter {
bool operator()(SILParameterInfo param) const {
return param.isIndirectMutating();
Expand Down
52 changes: 52 additions & 0 deletions include/swift/SILOptimizer/Utils/PartitionUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ namespace swift {

class Partition;
class SendingOperandToStateMap;
class RegionAnalysisValueMap;

/// The representative value of the equivalence class that makes up a tracked
/// value.
Expand Down Expand Up @@ -380,6 +381,7 @@ class IsolationHistory::Factory {
IsolationHistory get() { return IsolationHistory(this); }
};

/// A struct that represents a specific "sending" operand of an ApplySite.
struct SendingOperandState {
/// The dynamic isolation info of the region of value when we sent.
///
Expand Down Expand Up @@ -954,6 +956,12 @@ class PartitionOpError {
const PartitionOp *op;

UnknownCodePatternError(const PartitionOp &op) : op(&op) {}

void print(llvm::raw_ostream &os, RegionAnalysisValueMap &valueMap) const;

SWIFT_DEBUG_DUMPER(dump(RegionAnalysisValueMap &valueMap)) {
print(llvm::dbgs(), valueMap);
}
};

struct LocalUseAfterSendError {
Expand All @@ -964,6 +972,12 @@ class PartitionOpError {
LocalUseAfterSendError(const PartitionOp &op, Element elt,
Operand *sendingOp)
: op(&op), sentElement(elt), sendingOp(sendingOp) {}

void print(llvm::raw_ostream &os, RegionAnalysisValueMap &valueMap) const;

SWIFT_DEBUG_DUMPER(dump(RegionAnalysisValueMap &valueMap)) {
print(llvm::dbgs(), valueMap);
}
};

struct SentNeverSendableError {
Expand All @@ -975,6 +989,12 @@ class PartitionOpError {
SILDynamicMergedIsolationInfo isolationRegionInfo)
: op(&op), sentElement(sentElement),
isolationRegionInfo(isolationRegionInfo) {}

void print(llvm::raw_ostream &os, RegionAnalysisValueMap &valueMap) const;

SWIFT_DEBUG_DUMPER(dump(RegionAnalysisValueMap &valueMap)) {
print(llvm::dbgs(), valueMap);
}
};

struct AssignNeverSendableIntoSendingResultError {
Expand All @@ -992,6 +1012,12 @@ class PartitionOpError {
: op(&op), destElement(destElement), destValue(destValue),
srcElement(srcElement), srcValue(srcValue),
srcIsolationRegionInfo(srcIsolationRegionInfo) {}

void print(llvm::raw_ostream &os, RegionAnalysisValueMap &valueMap) const;

SWIFT_DEBUG_DUMPER(dump(RegionAnalysisValueMap &valueMap)) {
print(llvm::dbgs(), valueMap);
}
};

struct InOutSendingNotInitializedAtExitError {
Expand All @@ -1002,6 +1028,12 @@ class PartitionOpError {
InOutSendingNotInitializedAtExitError(const PartitionOp &op, Element elt,
Operand *sendingOp)
: op(&op), sentElement(elt), sendingOp(sendingOp) {}

void print(llvm::raw_ostream &os, RegionAnalysisValueMap &valueMap) const;

SWIFT_DEBUG_DUMPER(dump(RegionAnalysisValueMap &valueMap)) {
print(llvm::dbgs(), valueMap);
}
};

struct InOutSendingNotDisconnectedAtExitError {
Expand All @@ -1013,6 +1045,12 @@ class PartitionOpError {
const PartitionOp &op, Element elt,
SILDynamicMergedIsolationInfo isolation)
: op(&op), inoutSendingElement(elt), isolationInfo(isolation) {}

void print(llvm::raw_ostream &os, RegionAnalysisValueMap &valueMap) const;

SWIFT_DEBUG_DUMPER(dump(RegionAnalysisValueMap &valueMap)) {
print(llvm::dbgs(), valueMap);
}
};

#define PARTITION_OP_ERROR(NAME) \
Expand Down Expand Up @@ -1067,6 +1105,20 @@ class PartitionOpError {

Kind getKind() const { return kind; }

void print(llvm::raw_ostream &os, RegionAnalysisValueMap &valueMap) const {
switch (getKind()) {
#define PARTITION_OP_ERROR(NAME) \
case NAME: \
return get##NAME##Error().print(os, valueMap);
#include "PartitionOpError.def"
}
llvm_unreachable("Covered switch isn't covered?!");
}

SWIFT_DEBUG_DUMPER(dump(RegionAnalysisValueMap &valueMap)) {
return print(llvm::dbgs(), valueMap);
}

#define PARTITION_OP_ERROR(NAME) \
NAME##Error get##NAME##Error() const { \
assert(getKind() == Kind::NAME); \
Expand Down
1 change: 1 addition & 0 deletions include/swift/SILOptimizer/Utils/SILIsolationInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ class SILDynamicMergedIsolationInfo {
operator bool() const { return bool(innerInfo); }

SILIsolationInfo *operator->() { return &innerInfo; }
const SILIsolationInfo *operator->() const { return &innerInfo; }

SILIsolationInfo getIsolationInfo() const { return innerInfo; }

Expand Down
45 changes: 24 additions & 21 deletions lib/SILGen/SILGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,25 @@ static bool isEmittedOnDemand(SILModule &M, SILDeclRef constant) {
return false;
}

static ActorIsolation getActorIsolationForFunction(SILFunction &fn) {
if (auto constant = fn.getDeclRef()) {
if (constant.kind == SILDeclRef::Kind::Deallocator) {
// Deallocating destructor is always nonisolated. Isolation of the deinit
// applies only to isolated deallocator and destroyer.
return ActorIsolation::forNonisolated(false);
}

// If we have actor isolation for our constant, put the isolation onto the
// function. If the isolation is unspecified, we do not return it.
if (auto isolation =
getActorIsolationOfContext(constant.getInnermostDeclContext()))
return isolation;
}

// Otherwise, return for unspecified.
return ActorIsolation::forUnspecified();
}

SILFunction *SILGenModule::getFunction(SILDeclRef constant,
ForDefinition_t forDefinition) {
// If we already emitted the function, return it.
Expand All @@ -756,16 +775,8 @@ SILFunction *SILGenModule::getFunction(SILDeclRef constant,
return IGM.getFunction(constant, NotForDefinition);
});

if (constant.kind == SILDeclRef::Kind::Deallocator) {
// Deallocating destructor is always nonisolated.
// Isolation of the deinit applies only to isolated deallocator and
// destroyer.
F->setActorIsolation(ActorIsolation::forNonisolated(false));
} else {
// If we have global actor isolation for our constant, put the isolation onto
// the function.
F->setActorIsolation(getActorIsolationOfContext(constant.getInnermostDeclContext()));
}
F->setDeclRef(constant);
F->setActorIsolation(getActorIsolationForFunction(*F));

assert(F && "SILFunction should have been defined");

Expand Down Expand Up @@ -1254,23 +1265,15 @@ void SILGenModule::preEmitFunction(SILDeclRef constant, SILFunction *F,
F->setGenericEnvironment(genericEnv, capturedEnvs, forwardingSubs);
}

if (constant.kind == SILDeclRef::Kind::Deallocator) {
// Deallocating destructor is always nonisolated.
// Isolation of the deinit applies only to isolated deallocator and
// destroyer.
F->setActorIsolation(ActorIsolation::forNonisolated(false));
} else {
// If we have global actor isolation for our constant, put the isolation
// onto the function.
F->setActorIsolation(getActorIsolationOfContext(constant.getInnermostDeclContext()));
}

// Create a debug scope for the function using astNode as source location.
F->setDebugScope(new (M) SILDebugScope(Loc, F));

// Initialize F with the constant we created for it.
F->setDeclRef(constant);

// Set our actor isolation.
F->setActorIsolation(getActorIsolationForFunction(*F));

LLVM_DEBUG(llvm::dbgs() << "lowering ";
F->printName(llvm::dbgs());
llvm::dbgs() << " : ";
Expand Down
56 changes: 30 additions & 26 deletions lib/SILGen/SILGenApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3412,11 +3412,18 @@ Expr *ArgumentSource::findStorageReferenceExprForBorrow() && {
namespace {

class ArgEmitter {
public:
enum Flag {
IsYield = 0x1,
IsForCoroutine = 0x2,
};
using OptionSet = OptionSet<Flag>;

private:
SILGenFunction &SGF;
SILLocation ApplyLoc;
SILFunctionTypeRepresentation Rep;
bool IsYield;
bool IsForCoroutine;
OptionSet Options;
ForeignInfo Foreign;
ClaimedParamsRef ParamInfos;
SmallVectorImpl<ManagedValue> &Args;
Expand All @@ -3427,13 +3434,11 @@ class ArgEmitter {

public:
ArgEmitter(SILGenFunction &SGF, SILLocation applyLoc,
SILFunctionTypeRepresentation Rep,
bool isYield, bool isForCoroutine, ClaimedParamsRef paramInfos,
SmallVectorImpl<ManagedValue> &args,
SILFunctionTypeRepresentation Rep, OptionSet options,
ClaimedParamsRef paramInfos, SmallVectorImpl<ManagedValue> &args,
SmallVectorImpl<DelayedArgument> &delayedArgs,
const ForeignInfo &foreign)
: SGF(SGF), ApplyLoc(applyLoc),
Rep(Rep), IsYield(isYield), IsForCoroutine(isForCoroutine),
: SGF(SGF), ApplyLoc(applyLoc), Rep(Rep), Options(options),
Foreign(foreign), ParamInfos(paramInfos), Args(args),
DelayedArguments(delayedArgs) {}

Expand Down Expand Up @@ -3559,7 +3564,7 @@ class ArgEmitter {
// If we have a guaranteed +0 parameter...
if (param.isGuaranteedInCaller() || isShared) {
// And this is a yield, emit a borrowed r-value.
if (IsYield) {
if (Options.contains(Flag::IsYield)) {
if (tryEmitBorrowed(std::move(arg), loweredSubstArgType,
loweredSubstParamType, origParamType, paramSlice))
return;
Expand Down Expand Up @@ -3610,7 +3615,7 @@ class ArgEmitter {

// Handle yields of storage reference expressions specially so that we
// don't emit them as +1 r-values and then expand.
if (IsYield) {
if (Options.contains(Flag::IsYield)) {
if (auto result = std::move(arg).findStorageReferenceExprForBorrow()) {
emitExpandedBorrowed(result, origParamType);
return;
Expand Down Expand Up @@ -3858,7 +3863,8 @@ class ArgEmitter {

auto convertOwnershipConvention = [&](ManagedValue value) {
return convertOwnershipConventionGivenParamInfo(
SGF, param, origParam, value, loc, IsForCoroutine);
SGF, param, origParam, value, loc,
Options.contains(Flag::IsForCoroutine));
};

auto contexts = getRValueEmissionContexts(loweredSubstArgType, param);
Expand Down Expand Up @@ -4423,10 +4429,9 @@ void DelayedArgument::emitDefaultArgument(SILGenFunction &SGF,

SmallVector<ManagedValue, 4> loweredArgs;
SmallVector<DelayedArgument, 4> delayedArgs;
auto emitter = ArgEmitter(SGF, info.loc, info.functionRepresentation,
/*yield*/ false, /*coroutine*/ false,
info.paramsToEmit, loweredArgs,
delayedArgs, ForeignInfo{});
auto emitter =
ArgEmitter(SGF, info.loc, info.functionRepresentation, {},
info.paramsToEmit, loweredArgs, delayedArgs, ForeignInfo{});

emitter.emitSingleArg(ArgumentSource(info.loc, std::move(value)),
info.origResultType);
Expand Down Expand Up @@ -4818,9 +4823,11 @@ class CallSite {
const ForeignInfo &foreign) && {
auto params = lowering.claimParams(origFormalType, getParams(), foreign);

ArgEmitter emitter(SGF, Loc, lowering.Rep, /*yield*/ false,
/*isForCoroutine*/ substFnType->isCoroutine(), params,
args, delayedArgs, foreign);
ArgEmitter::OptionSet options;
if (substFnType->isCoroutine())
options |= ArgEmitter::IsForCoroutine;
ArgEmitter emitter(SGF, Loc, lowering.Rep, options, params, args,
delayedArgs, foreign);
emitter.emitPreparedArgs(std::move(Args), origFormalType);
}

Expand Down Expand Up @@ -6069,8 +6076,8 @@ void SILGenFunction::emitYield(SILLocation loc,
origYield.getConvention()});
}

ArgEmitter emitter(*this, loc, fnType->getRepresentation(), /*yield*/ true,
/*isForCoroutine*/ false, ClaimedParamsRef(substYieldTys),
ArgEmitter emitter(*this, loc, fnType->getRepresentation(),
ArgEmitter::IsYield, ClaimedParamsRef(substYieldTys),
yieldArgs, delayedArgs, ForeignInfo{});

for (auto i : indices(valueSources)) {
Expand Down Expand Up @@ -7077,10 +7084,9 @@ static void emitPseudoFunctionArguments(SILGenFunction &SGF,
SmallVector<ManagedValue, 4> argValues;
SmallVector<DelayedArgument, 2> delayedArgs;

ArgEmitter emitter(SGF, applyLoc, SILFunctionTypeRepresentation::Thin,
/*yield*/ false,
/*isForCoroutine*/ false, ClaimedParamsRef(substParamTys),
argValues, delayedArgs, ForeignInfo{});
ArgEmitter emitter(SGF, applyLoc, SILFunctionTypeRepresentation::Thin, {},
ClaimedParamsRef(substParamTys), argValues, delayedArgs,
ForeignInfo{});

emitter.emitPreparedArgs(std::move(args), origFnType);

Expand Down Expand Up @@ -7765,9 +7771,7 @@ SmallVector<ManagedValue, 4> SILGenFunction::emitKeyPathSubscriptOperands(

SmallVector<ManagedValue, 4> argValues;
SmallVector<DelayedArgument, 2> delayedArgs;
ArgEmitter emitter(*this, loc, fnType->getRepresentation(),
/*yield*/ false,
/*isForCoroutine*/ false,
ArgEmitter emitter(*this, loc, fnType->getRepresentation(), {},
ClaimedParamsRef(fnType->getParameters()), argValues,
delayedArgs, ForeignInfo{});

Expand Down
Loading

0 comments on commit e6b4e0f

Please sign in to comment.