Skip to content

Commit b23b791

Browse files
committed
[region-isolation] Move ValueIsolationRegionInfo from RegionAnalysis.h -> PartitionUtils.h.
I am going to need this so that I can use it when evaluating partition ops. Specifically, so I can when I find two values that do not merge correctly, emit an error.
1 parent 18aa7d8 commit b23b791

File tree

2 files changed

+169
-150
lines changed

2 files changed

+169
-150
lines changed

include/swift/SILOptimizer/Analysis/RegionAnalysis.h

Lines changed: 0 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -130,155 +130,6 @@ enum class TrackableValueFlag {
130130

131131
using TrackedValueFlagSet = OptionSet<TrackableValueFlag>;
132132

133-
class ValueIsolationRegionInfo {
134-
public:
135-
/// The lattice is:
136-
///
137-
/// Unknown -> Disconnected -> TransferringParameter -> Task -> Actor.
138-
///
139-
/// Unknown means no information. We error when merging on it.
140-
enum Kind {
141-
Unknown,
142-
Disconnected,
143-
Task,
144-
Actor,
145-
};
146-
147-
private:
148-
Kind kind;
149-
// clang-format off
150-
std::variant<
151-
// Used for actor isolated when we have ActorIsolation info from the AST.
152-
std::optional<ActorIsolation>,
153-
// Used for actor isolation when we infer the actor at the SIL level.
154-
NominalTypeDecl *,
155-
// The task isolated parameter when we find a task isolated value.
156-
SILValue
157-
> data;
158-
// clang-format on
159-
160-
ValueIsolationRegionInfo(Kind kind,
161-
std::optional<ActorIsolation> actorIsolation)
162-
: kind(kind), data(actorIsolation) {}
163-
ValueIsolationRegionInfo(Kind kind, NominalTypeDecl *decl)
164-
: kind(kind), data(decl) {}
165-
166-
ValueIsolationRegionInfo(Kind kind, SILValue value)
167-
: kind(kind), data(value) {}
168-
169-
public:
170-
ValueIsolationRegionInfo() : kind(Kind::Unknown), data() {}
171-
172-
operator bool() const { return kind != Kind::Unknown; }
173-
174-
operator Kind() const { return kind; }
175-
176-
Kind getKind() const { return kind; }
177-
178-
bool isDisconnected() const { return kind == Kind::Disconnected; }
179-
bool isActorIsolated() const { return kind == Kind::Actor; }
180-
bool isTaskIsolated() const { return kind == Kind::Task; }
181-
182-
void print(llvm::raw_ostream &os) const {
183-
switch (Kind(*this)) {
184-
case Unknown:
185-
os << "unknown";
186-
return;
187-
case Disconnected:
188-
os << "disconnected";
189-
return;
190-
case Actor:
191-
os << "actor";
192-
return;
193-
case Task:
194-
os << "task";
195-
return;
196-
}
197-
}
198-
199-
void printForDiagnostics(llvm::raw_ostream &os) const;
200-
201-
SWIFT_DEBUG_DUMP {
202-
print(llvm::dbgs());
203-
llvm::dbgs() << '\n';
204-
}
205-
206-
std::optional<ActorIsolation> getActorIsolation() const {
207-
assert(kind == Actor);
208-
assert(std::holds_alternative<std::optional<ActorIsolation>>(data) &&
209-
"Doesn't have an actor isolation?!");
210-
return std::get<std::optional<ActorIsolation>>(data);
211-
}
212-
213-
NominalTypeDecl *getActorInstance() const {
214-
assert(kind == Actor);
215-
assert(std::holds_alternative<NominalTypeDecl *>(data) &&
216-
"Doesn't have an actor instance?!");
217-
return std::get<NominalTypeDecl *>(data);
218-
}
219-
220-
SILValue getTaskIsolatedValue() const {
221-
assert(kind == Task);
222-
assert(std::holds_alternative<SILValue>(data) &&
223-
"Doesn't have a task isolated value");
224-
return std::get<SILValue>(data);
225-
}
226-
227-
bool hasActorIsolation() const {
228-
return std::holds_alternative<std::optional<ActorIsolation>>(data);
229-
}
230-
231-
bool hasActorInstance() const {
232-
return std::holds_alternative<NominalTypeDecl *>(data);
233-
}
234-
235-
bool hasTaskIsolatedValue() const {
236-
return std::holds_alternative<SILValue>(data);
237-
}
238-
239-
[[nodiscard]] ValueIsolationRegionInfo
240-
merge(ValueIsolationRegionInfo other) const {
241-
// If we are greater than the other kind, then we are further along the
242-
// lattice. We ignore the change.
243-
if (unsigned(other.kind) < unsigned(kind))
244-
return *this;
245-
246-
assert(kind != ValueIsolationRegionInfo::Actor &&
247-
"Actor should never be merged with another actor?!");
248-
249-
// Otherwise, take the other value.
250-
return other;
251-
}
252-
253-
ValueIsolationRegionInfo withActorIsolated(ActorIsolation isolation) {
254-
return ValueIsolationRegionInfo::getActorIsolated(isolation);
255-
}
256-
257-
static ValueIsolationRegionInfo getDisconnected() {
258-
return {Kind::Disconnected, {}};
259-
}
260-
261-
static ValueIsolationRegionInfo
262-
getActorIsolated(ActorIsolation actorIsolation) {
263-
return {Kind::Actor, actorIsolation};
264-
}
265-
266-
/// Sometimes we may have something that is actor isolated or that comes from
267-
/// a type. First try getActorIsolation and otherwise, just use the type.
268-
static ValueIsolationRegionInfo getActorIsolated(NominalTypeDecl *nomDecl) {
269-
auto actorIsolation = swift::getActorIsolation(nomDecl);
270-
if (actorIsolation.isActorIsolated())
271-
return getActorIsolated(actorIsolation);
272-
if (nomDecl->isActor())
273-
return {Kind::Actor, nomDecl};
274-
return {};
275-
}
276-
277-
static ValueIsolationRegionInfo getTaskIsolated(SILValue value) {
278-
return {Kind::Task, value};
279-
}
280-
};
281-
282133
} // namespace regionanalysisimpl
283134

284135
class regionanalysisimpl::TrackableValueState {
@@ -451,7 +302,6 @@ class RegionAnalysisValueMap {
451302
using TrackableValueState = regionanalysisimpl::TrackableValueState;
452303
using TrackableValueID = Element;
453304
using RepresentativeValue = regionanalysisimpl::RepresentativeValue;
454-
using ValueIsolationRegionInfo = regionanalysisimpl::ValueIsolationRegionInfo;
455305

456306
private:
457307
/// A map from the representative of an equivalence class of values to their

include/swift/SILOptimizer/Utils/PartitionUtils.h

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,175 @@ class Partition {
995995
}
996996
};
997997

998+
class ValueIsolationRegionInfo {
999+
public:
1000+
/// The lattice is:
1001+
///
1002+
/// Unknown -> Disconnected -> TransferringParameter -> Task -> Actor.
1003+
///
1004+
/// Unknown means no information. We error when merging on it.
1005+
enum Kind {
1006+
Unknown,
1007+
Disconnected,
1008+
Task,
1009+
Actor,
1010+
};
1011+
1012+
private:
1013+
Kind kind;
1014+
// clang-format off
1015+
std::variant<
1016+
// Used for actor isolated when we have ActorIsolation info from the AST.
1017+
std::optional<ActorIsolation>,
1018+
// Used for actor isolation when we infer the actor at the SIL level.
1019+
NominalTypeDecl *,
1020+
// The task isolated parameter when we find a task isolated value.
1021+
SILValue
1022+
> data;
1023+
// clang-format on
1024+
1025+
ValueIsolationRegionInfo(Kind kind,
1026+
std::optional<ActorIsolation> actorIsolation)
1027+
: kind(kind), data(actorIsolation) {}
1028+
ValueIsolationRegionInfo(Kind kind, NominalTypeDecl *decl)
1029+
: kind(kind), data(decl) {}
1030+
1031+
ValueIsolationRegionInfo(Kind kind, SILValue value)
1032+
: kind(kind), data(value) {}
1033+
1034+
public:
1035+
ValueIsolationRegionInfo() : kind(Kind::Unknown), data() {}
1036+
1037+
operator bool() const { return kind != Kind::Unknown; }
1038+
1039+
operator Kind() const { return kind; }
1040+
1041+
Kind getKind() const { return kind; }
1042+
1043+
bool isDisconnected() const { return kind == Kind::Disconnected; }
1044+
bool isActorIsolated() const { return kind == Kind::Actor; }
1045+
bool isTaskIsolated() const { return kind == Kind::Task; }
1046+
1047+
void print(llvm::raw_ostream &os) const {
1048+
switch (Kind(*this)) {
1049+
case Unknown:
1050+
os << "unknown";
1051+
return;
1052+
case Disconnected:
1053+
os << "disconnected";
1054+
return;
1055+
case Actor:
1056+
os << "actor";
1057+
return;
1058+
case Task:
1059+
os << "task";
1060+
return;
1061+
}
1062+
}
1063+
1064+
void printForDiagnostics(llvm::raw_ostream &os) const;
1065+
1066+
SWIFT_DEBUG_DUMP {
1067+
print(llvm::dbgs());
1068+
llvm::dbgs() << '\n';
1069+
}
1070+
1071+
std::optional<ActorIsolation> getActorIsolation() const {
1072+
assert(kind == Actor);
1073+
assert(std::holds_alternative<std::optional<ActorIsolation>>(data) &&
1074+
"Doesn't have an actor isolation?!");
1075+
return std::get<std::optional<ActorIsolation>>(data);
1076+
}
1077+
1078+
NominalTypeDecl *getActorInstance() const {
1079+
assert(kind == Actor);
1080+
assert(std::holds_alternative<NominalTypeDecl *>(data) &&
1081+
"Doesn't have an actor instance?!");
1082+
return std::get<NominalTypeDecl *>(data);
1083+
}
1084+
1085+
SILValue getTaskIsolatedValue() const {
1086+
assert(kind == Task);
1087+
assert(std::holds_alternative<SILValue>(data) &&
1088+
"Doesn't have a task isolated value");
1089+
return std::get<SILValue>(data);
1090+
}
1091+
1092+
bool hasActorIsolation() const {
1093+
return std::holds_alternative<std::optional<ActorIsolation>>(data);
1094+
}
1095+
1096+
bool hasActorInstance() const {
1097+
return std::holds_alternative<NominalTypeDecl *>(data);
1098+
}
1099+
1100+
bool hasTaskIsolatedValue() const {
1101+
return std::holds_alternative<SILValue>(data);
1102+
}
1103+
1104+
/// If we actually have an actor decl, return that. Otherwise, see if we have
1105+
/// an actor isolation if we can find one in there. Returns nullptr if we
1106+
/// fail.
1107+
NominalTypeDecl *tryInferActorDecl() const {
1108+
if (hasActorIsolation()) {
1109+
auto actorIsolation = getActorIsolation();
1110+
if (auto *actor = actorIsolation->getActorOrNullPtr()) {
1111+
return actor;
1112+
}
1113+
return nullptr;
1114+
}
1115+
1116+
if (hasActorInstance()) {
1117+
auto actorDecl = getActorInstance();
1118+
return actorDecl;
1119+
}
1120+
1121+
return nullptr;
1122+
}
1123+
1124+
[[nodiscard]] ValueIsolationRegionInfo
1125+
merge(ValueIsolationRegionInfo other) const {
1126+
// If we are greater than the other kind, then we are further along the
1127+
// lattice. We ignore the change.
1128+
if (unsigned(other.kind) < unsigned(kind))
1129+
return *this;
1130+
1131+
assert(kind != ValueIsolationRegionInfo::Actor &&
1132+
"Actor should never be merged with another actor?!");
1133+
1134+
// Otherwise, take the other value.
1135+
return other;
1136+
}
1137+
1138+
ValueIsolationRegionInfo withActorIsolated(ActorIsolation isolation) {
1139+
return ValueIsolationRegionInfo::getActorIsolated(isolation);
1140+
}
1141+
1142+
static ValueIsolationRegionInfo getDisconnected() {
1143+
return {Kind::Disconnected, {}};
1144+
}
1145+
1146+
static ValueIsolationRegionInfo
1147+
getActorIsolated(ActorIsolation actorIsolation) {
1148+
return {Kind::Actor, actorIsolation};
1149+
}
1150+
1151+
/// Sometimes we may have something that is actor isolated or that comes from
1152+
/// a type. First try getActorIsolation and otherwise, just use the type.
1153+
static ValueIsolationRegionInfo getActorIsolated(NominalTypeDecl *nomDecl) {
1154+
auto actorIsolation = swift::getActorIsolation(nomDecl);
1155+
if (actorIsolation.isActorIsolated())
1156+
return getActorIsolated(actorIsolation);
1157+
if (nomDecl->isActor())
1158+
return {Kind::Actor, nomDecl};
1159+
return {};
1160+
}
1161+
1162+
static ValueIsolationRegionInfo getTaskIsolated(SILValue value) {
1163+
return {Kind::Task, value};
1164+
}
1165+
};
1166+
9981167
/// A data structure that applies a series of PartitionOps to a single Partition
9991168
/// that it modifies.
10001169
///

0 commit comments

Comments
 (0)