Skip to content

[6.0][region-isolation] Reuse ActorInstance::lookThroughInsts when computing the actor instance for SILIsolationInfo purposes. #75044

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 80 additions & 26 deletions include/swift/SILOptimizer/Utils/SILIsolationInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ class ActorInstance {
}
};

/// The isolation info inferred for a specific SILValue. Use
/// SILIsolationInfo::get() to compute these. It is intended to be a
/// conservatively correct model that we expand over time with more pattern
/// matching.
class SILIsolationInfo {
public:
/// The lattice is:
Expand All @@ -128,6 +132,23 @@ class SILIsolationInfo {
Actor,
};

enum class Flag : uint8_t {
None,

/// If set, this means that the element that we derived this from was marked
/// with nonisolated(unsafe).
UnsafeNonIsolated = 0x1,

/// If set, this means that this actor isolation is from an isolated
/// parameter and should be allowed to merge into a self parameter.
UnappliedIsolatedAnyParameter = 0x2,

/// The maximum number of bits used by a Flag.
MaxNumBits = 2,
};

using Options = OptionSet<Flag>;

private:
/// The actor isolation if this value has one. The default unspecified case
/// otherwise.
Expand All @@ -142,13 +163,13 @@ class SILIsolationInfo {
ActorInstance actorInstance;

unsigned kind : 8;
unsigned unsafeNonIsolated : 1;
unsigned options : 8;

SILIsolationInfo(SILValue isolatedValue, SILValue actorInstance,
ActorIsolation actorIsolation, bool isUnsafeNonIsolated)
ActorIsolation actorIsolation, Options options = Options())
: actorIsolation(actorIsolation), isolatedValue(isolatedValue),
actorInstance(ActorInstance::getForValue(actorInstance)), kind(Actor),
unsafeNonIsolated(isUnsafeNonIsolated) {
options(options.toRaw()) {
assert((!actorInstance ||
(actorIsolation.getKind() == ActorIsolation::ActorInstance &&
actorInstance->getType()
Expand All @@ -159,24 +180,22 @@ class SILIsolationInfo {
}

SILIsolationInfo(SILValue isolatedValue, ActorInstance actorInstance,
ActorIsolation actorIsolation, bool isUnsafeNonIsolated)
ActorIsolation actorIsolation, Options options = Options())
: actorIsolation(actorIsolation), isolatedValue(isolatedValue),
actorInstance(actorInstance), kind(Actor),
unsafeNonIsolated(isUnsafeNonIsolated) {
actorInstance(actorInstance), kind(Actor), options(options.toRaw()) {
assert(actorInstance);
assert(actorIsolation.getKind() == ActorIsolation::ActorInstance);
}

SILIsolationInfo(Kind kind, SILValue isolatedValue)
: actorIsolation(), isolatedValue(isolatedValue), kind(kind),
unsafeNonIsolated(false) {}
: actorIsolation(), isolatedValue(isolatedValue), kind(kind), options(0) {
}

SILIsolationInfo(Kind kind, bool isUnsafeNonIsolated)
: actorIsolation(), kind(kind), unsafeNonIsolated(isUnsafeNonIsolated) {}
SILIsolationInfo(Kind kind, Options options = Options())
: actorIsolation(), kind(kind), options(options.toRaw()) {}

public:
SILIsolationInfo()
: actorIsolation(), kind(Kind::Unknown), unsafeNonIsolated(false) {}
SILIsolationInfo() : actorIsolation(), kind(Kind::Unknown), options(0) {}

operator bool() const { return kind != Kind::Unknown; }

Expand All @@ -188,12 +207,43 @@ class SILIsolationInfo {
bool isActorIsolated() const { return kind == Kind::Actor; }
bool isTaskIsolated() const { return kind == Kind::Task; }

bool isUnsafeNonIsolated() const { return unsafeNonIsolated; }
Options getOptions() const { return Options(options); }

void setOptions(Options newOptions) { options = newOptions.toRaw(); }

bool isUnsafeNonIsolated() const {
return getOptions().contains(Flag::UnsafeNonIsolated);
}

SILIsolationInfo withUnsafeNonIsolated(bool newValue = true) const {
assert(*this && "Cannot be unknown");
auto self = *this;
self.unsafeNonIsolated = newValue;
if (newValue) {
self.options = (self.getOptions() | Flag::UnsafeNonIsolated).toRaw();
} else {
self.options =
self.getOptions().toRaw() & ~Options(Flag::UnsafeNonIsolated).toRaw();
}
return self;
}

/// Returns true if this actor isolation is derived from an unapplied
/// isolation parameter. When merging, we allow for this to be merged with a
/// more specific isolation kind.
bool isUnappliedIsolatedAnyParameter() const {
return getOptions().contains(Flag::UnappliedIsolatedAnyParameter);
}

SILIsolationInfo withUnappliedIsolatedParameter(bool newValue = true) const {
assert(*this && "Cannot be unknown");
auto self = *this;
if (newValue) {
self.options =
(self.getOptions() | Flag::UnappliedIsolatedAnyParameter).toRaw();
} else {
self.options = self.getOptions().toRaw() &
~Options(Flag::UnappliedIsolatedAnyParameter).toRaw();
}
return self;
}

Expand Down Expand Up @@ -243,7 +293,8 @@ class SILIsolationInfo {
}

static SILIsolationInfo getDisconnected(bool isUnsafeNonIsolated) {
return {Kind::Disconnected, isUnsafeNonIsolated};
return {Kind::Disconnected,
isUnsafeNonIsolated ? Flag::UnsafeNonIsolated : Flag::None};
}

/// Create an actor isolation for a value that we know is actor isolated to a
Expand All @@ -261,7 +312,7 @@ class SILIsolationInfo {
getFlowSensitiveActorIsolated(SILValue isolatedValue,
ActorIsolation actorIsolation) {
return {isolatedValue, SILValue(), actorIsolation,
false /*nonisolated(unsafe)*/};
Flag::UnappliedIsolatedAnyParameter};
}

/// Only use this as a fallback if we cannot find better information.
Expand All @@ -270,8 +321,7 @@ class SILIsolationInfo {
if (crossing.getCalleeIsolation().isActorIsolated()) {
// SIL level, just let it through
return SILIsolationInfo(SILValue(), SILValue(),
crossing.getCalleeIsolation(),
false /*nonisolated(unsafe)*/);
crossing.getCalleeIsolation());
}

return {};
Expand All @@ -287,8 +337,7 @@ class SILIsolationInfo {
return {};
}
return {isolatedValue, actorInstance,
ActorIsolation::forActorInstanceSelf(typeDecl),
false /*nonisolated(unsafe)*/};
ActorIsolation::forActorInstanceSelf(typeDecl)};
}

static SILIsolationInfo getActorInstanceIsolated(SILValue isolatedValue,
Expand All @@ -301,8 +350,7 @@ class SILIsolationInfo {
return {};
}
return {isolatedValue, actorInstance,
ActorIsolation::forActorInstanceSelf(typeDecl),
false /*nonisolated(unsafe)*/};
ActorIsolation::forActorInstanceSelf(typeDecl)};
}

/// A special actor instance isolated for partial apply cases where we do not
Expand All @@ -318,14 +366,13 @@ class SILIsolationInfo {
}
return {isolatedValue, SILValue(),
ActorIsolation::forActorInstanceSelf(typeDecl),
false /*nonisolated(unsafe)*/};
Flag::UnappliedIsolatedAnyParameter};
}

static SILIsolationInfo getGlobalActorIsolated(SILValue value,
Type globalActorType) {
return {value, SILValue() /*no actor instance*/,
ActorIsolation::forGlobalActor(globalActorType),
false /*nonisolated(unsafe)*/};
ActorIsolation::forGlobalActor(globalActorType)};
}

static SILIsolationInfo getGlobalActorIsolated(SILValue value,
Expand Down Expand Up @@ -382,6 +429,9 @@ class SILIsolationInfo {
bool isEqual(const SILIsolationInfo &other) const;

void Profile(llvm::FoldingSetNodeID &id) const;

private:
void printOptions(llvm::raw_ostream &os) const;
};

/// A SILIsolationInfo that has gone through merging and represents the dynamic
Expand All @@ -395,7 +445,7 @@ class SILDynamicMergedIsolationInfo {

public:
SILDynamicMergedIsolationInfo() : innerInfo() {}
explicit SILDynamicMergedIsolationInfo(SILIsolationInfo innerInfo)
SILDynamicMergedIsolationInfo(SILIsolationInfo innerInfo)
: innerInfo(innerInfo) {}

/// Returns nullptr only if both this isolation info and \p other are actor
Expand Down Expand Up @@ -435,6 +485,10 @@ class SILDynamicMergedIsolationInfo {
SWIFT_DEBUG_DUMPER(dumpForDiagnostics()) {
innerInfo.dumpForDiagnostics();
}

void printForOneLineLogging(llvm::raw_ostream &os) const {
innerInfo.printForOneLineLogging(os);
}
};

} // namespace swift
Expand Down
3 changes: 2 additions & 1 deletion lib/SILOptimizer/Analysis/RegionAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1633,8 +1633,9 @@ class PartitionOpTranslator {
if (originalMergedInfo)
originalMergedInfo->printForDiagnostics(llvm::dbgs());
else llvm::dbgs() << "nil";
llvm::dbgs() << "\nValue: "
llvm::dbgs() << "\nValue Rep: "
<< value->getRepresentative().getValue();
llvm::dbgs() << "Original Src: " << src;
llvm::dbgs() << "Value Info: ";
value->getIsolationRegionInfo().printForDiagnostics(llvm::dbgs());
llvm::dbgs() << "\n");
Expand Down
Loading