Skip to content

Commit 538cdba

Browse files
authored
Merge pull request #72403 from gottesmm/rdar124960994
[region-isolation] Change named transfer non transferable error to use the dynamic merged IsolationRegionInfo found during dataflow.
2 parents 36c20ac + a2d1adf commit 538cdba

16 files changed

+414
-346
lines changed

include/swift/AST/ActorIsolation.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ class ActorIsolation {
192192
}
193193

194194
NominalTypeDecl *getActor() const;
195+
NominalTypeDecl *getActorOrNullPtr() const;
195196

196197
VarDecl *getActorInstance() const;
197198

include/swift/AST/DiagnosticsSIL.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,7 @@ NOTE(regionbasedisolation_named_info_transfer_yields_race, none,
974974
(Identifier, ActorIsolation, ActorIsolation))
975975
NOTE(regionbasedisolation_named_transfer_non_transferrable, none,
976976
"transferring %1 %0 to %2 callee could cause races between %2 and %1 uses",
977-
(Identifier, ActorIsolation, ActorIsolation))
977+
(Identifier, StringRef, ActorIsolation))
978978
NOTE(regionbasedisolation_named_transfer_into_transferring_param, none,
979979
"%0 %1 is passed as a transferring parameter; Uses in callee may race with later %0 uses",
980980
(StringRef, Identifier))

include/swift/SILOptimizer/Analysis/RegionAnalysis.h

Lines changed: 9 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -130,162 +130,12 @@ 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 {
285136
unsigned id;
286137
TrackedValueFlagSet flagSet = {TrackableValueFlag::isMayAlias};
287-
ValueIsolationRegionInfo regionInfo =
288-
ValueIsolationRegionInfo::getDisconnected();
138+
IsolationRegionInfo regionInfo = IsolationRegionInfo::getDisconnected();
289139

290140
public:
291141
TrackableValueState(unsigned newID) : id(newID) {}
@@ -302,19 +152,19 @@ class regionanalysisimpl::TrackableValueState {
302152

303153
bool isNonSendable() const { return !isSendable(); }
304154

305-
ValueIsolationRegionInfo::Kind getRegionInfoKind() {
155+
IsolationRegionInfo::Kind getIsolationRegionInfoKind() const {
306156
return regionInfo.getKind();
307157
}
308158

309159
ActorIsolation getActorIsolation() const {
310160
return regionInfo.getActorIsolation().value();
311161
}
312162

313-
void mergeIsolationRegionInfo(ValueIsolationRegionInfo newRegionInfo) {
163+
void mergeIsolationRegionInfo(IsolationRegionInfo newRegionInfo) {
314164
regionInfo = regionInfo.merge(newRegionInfo);
315165
}
316166

317-
ValueIsolationRegionInfo getIsolationRegionInfo() const { return regionInfo; }
167+
IsolationRegionInfo getIsolationRegionInfo() const { return regionInfo; }
318168

319169
TrackableValueID getID() const { return TrackableValueID(id); }
320170

@@ -413,7 +263,7 @@ class regionanalysisimpl::TrackableValue {
413263

414264
bool isNonSendable() const { return !isSendable(); }
415265

416-
ValueIsolationRegionInfo getIsolationRegionInfo() const {
266+
IsolationRegionInfo getIsolationRegionInfo() const {
417267
return valueState.getIsolationRegionInfo();
418268
}
419269

@@ -451,7 +301,6 @@ class RegionAnalysisValueMap {
451301
using TrackableValueState = regionanalysisimpl::TrackableValueState;
452302
using TrackableValueID = Element;
453303
using RepresentativeValue = regionanalysisimpl::RepresentativeValue;
454-
using ValueIsolationRegionInfo = regionanalysisimpl::ValueIsolationRegionInfo;
455304

456305
private:
457306
/// A map from the representative of an equivalence class of values to their
@@ -484,8 +333,8 @@ class RegionAnalysisValueMap {
484333
/// exists. Returns nullptr otherwise.
485334
SILInstruction *maybeGetActorIntroducingInst(Element trackableValueID) const;
486335

487-
ValueIsolationRegionInfo getIsolationRegion(Element trackableValueID) const;
488-
ValueIsolationRegionInfo getIsolationRegion(SILValue trackableValueID) const;
336+
IsolationRegionInfo getIsolationRegion(Element trackableValueID) const;
337+
IsolationRegionInfo getIsolationRegion(SILValue trackableValueID) const;
489338

490339
void print(llvm::raw_ostream &os) const;
491340
SWIFT_DEBUG_DUMP { print(llvm::dbgs()); }
@@ -508,9 +357,8 @@ class RegionAnalysisValueMap {
508357
std::optional<TrackableValue> tryToTrackValue(SILValue value) const;
509358
TrackableValue
510359
getActorIntroducingRepresentative(SILInstruction *introducingInst,
511-
ValueIsolationRegionInfo isolation) const;
512-
bool mergeIsolationRegionInfo(SILValue value,
513-
ValueIsolationRegionInfo isolation);
360+
IsolationRegionInfo isolation) const;
361+
bool mergeIsolationRegionInfo(SILValue value, IsolationRegionInfo isolation);
514362
bool valueHasID(SILValue value, bool dumpIfHasNoID = false);
515363
TrackableValueID lookupValueID(SILValue value);
516364
};

0 commit comments

Comments
 (0)