Skip to content

Commit ec81ecd

Browse files
committed
[region-isolation] Eliminate more of the 'task or actor isolated value cannot be transferred' warning.
Specifically, I had to teach the variable name inferrer how to infer through unchecked_enum_data and unchecked_take_enum_data_addr.
1 parent 2ee1242 commit ec81ecd

File tree

3 files changed

+81
-6
lines changed

3 files changed

+81
-6
lines changed

lib/SILOptimizer/Utils/VariableNameUtils.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,12 @@ VariableNameInferrer::findDebugInfoProvidingValueHelper(SILValue searchValue) {
276276
continue;
277277
}
278278

279+
if (auto *uedi = dyn_cast<UncheckedEnumDataInst>(searchValue)) {
280+
variableNamePath.push_back(uedi);
281+
searchValue = uedi->getOperand();
282+
continue;
283+
}
284+
279285
if (auto *tei = dyn_cast<TupleExtractInst>(searchValue)) {
280286
variableNamePath.push_back(tei);
281287
searchValue = tei->getOperand();
@@ -294,6 +300,12 @@ VariableNameInferrer::findDebugInfoProvidingValueHelper(SILValue searchValue) {
294300
continue;
295301
}
296302

303+
if (auto *e = dyn_cast<UncheckedTakeEnumDataAddrInst>(searchValue)) {
304+
variableNamePath.push_back(e);
305+
searchValue = e->getOperand();
306+
continue;
307+
}
308+
297309
if (auto *dti = dyn_cast_or_null<DestructureTupleInst>(
298310
searchValue->getDefiningInstruction())) {
299311
// Append searchValue, so we can find the specific tuple index.
@@ -473,6 +485,11 @@ void VariableNameInferrer::popSingleVariableName() {
473485
return;
474486
}
475487

488+
if (auto *uedi = dyn_cast<UncheckedEnumDataInst>(inst)) {
489+
resultingString += getNameFromDecl(uedi->getElement());
490+
return;
491+
}
492+
476493
if (auto *sei = dyn_cast<StructElementAddrInst>(inst)) {
477494
resultingString += getNameFromDecl(sei->getField());
478495
return;
@@ -484,6 +501,11 @@ void VariableNameInferrer::popSingleVariableName() {
484501
return;
485502
}
486503

504+
if (auto *uedi = dyn_cast<UncheckedTakeEnumDataAddrInst>(inst)) {
505+
resultingString += getNameFromDecl(uedi->getElement());
506+
return;
507+
}
508+
487509
resultingString += "<unknown decl>";
488510
return;
489511
}

test/Concurrency/transfernonsendable.sil

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,15 +249,17 @@ bb0(%0 : @guaranteed $MainActorIsolatedEnum):
249249
debug_value %0 : $MainActorIsolatedEnum, var, name "myname"
250250
%2 = unchecked_enum_data %0 : $MainActorIsolatedEnum, #MainActorIsolatedEnum.second!enumelt
251251
%3 = copy_value %2 : $NonSendableKlass
252-
return %3 : $NonSendableKlass // expected-warning {{task or actor isolated value cannot be transferred}}
252+
return %3 : $NonSendableKlass // expected-warning {{transferring 'myname.second' may cause a race}}
253+
// expected-note @-1 {{main actor-isolated 'myname.second' cannot be a transferring result. main actor-isolated uses may race with caller uses}}
253254
}
254255

255256
sil [ossa] @synchronous_returns_transferring_globalactor_enum_uncheckedtakeenumdataaddr : $@convention(method) (@in MainActorIsolatedEnum) -> @sil_transferring @owned NonSendableKlass {
256257
bb0(%0 : $*MainActorIsolatedEnum):
257258
debug_value %0 : $*MainActorIsolatedEnum, var, name "myname"
258259
%2 = unchecked_take_enum_data_addr %0 : $*MainActorIsolatedEnum, #MainActorIsolatedEnum.second!enumelt
259260
%3 = load [take] %2 : $*NonSendableKlass
260-
return %3 : $NonSendableKlass // expected-warning {{task or actor isolated value cannot be transferred}}
261+
return %3 : $NonSendableKlass // expected-warning {{transferring 'myname.second' may cause a race}}
262+
// expected-note @-1 {{main actor-isolated 'myname.second' cannot be a transferring result. main actor-isolated uses may race with caller uses}}
261263
}
262264

263265
sil [ossa] @synchronous_returns_transferring_globalactor_enum_switchenum : $@convention(method) (@guaranteed MainActorIsolatedEnum) -> @sil_transferring @owned FakeOptional<NonSendableKlass> {

test/SILOptimizer/variable_name_inference.sil

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ sil @getContainsKlass : $@convention(thin) () -> @owned ContainsKlass
3131
sil @useIndirect : $@convention(thin) <T> (@in_guaranteed T) -> ()
3232
sil @sideEffect : $@convention(thin) () -> ()
3333

34+
enum FakeOptional<T> {
35+
case none
36+
case some(T)
37+
}
38+
3439
//===----------------------------------------------------------------------===//
3540
// MARK: Tests
3641
//===----------------------------------------------------------------------===//
@@ -391,17 +396,63 @@ bb0(%0 : @owned $Klass, %1 : @guaranteed $KlassWithKlassPair):
391396
return %37 : $()
392397
}
393398

394-
// CHECK-LABEL: begin running test 1 of 1 on function_argument_inference_from_result: variable-name-inference with: @trace[0]
399+
// CHECK-LABEL: begin running test 1 of 1 on function_argument_inference_through_structextract: variable-name-inference with: @trace[0]
395400
// CHECK: Input Value: %3 = copy_value %2 : $Klass
396401
// CHECK: Name: 'self.lhs'
397402
// CHECK: Root: %0 = argument of bb0 : $KlassPair
398-
// CHECK: end running test 1 of 1 on function_argument_inference_from_result: variable-name-inference with: @trace[0]
399-
sil [ossa] @function_argument_inference_from_result : $@convention(thin) (@guaranteed KlassPair) -> @owned Klass {
403+
// CHECK: end running test 1 of 1 on function_argument_inference_through_structextract: variable-name-inference with: @trace[0]
404+
sil [ossa] @function_argument_inference_through_structextract : $@convention(thin) (@guaranteed KlassPair) -> @owned Klass {
400405
bb0(%0 : @guaranteed $KlassPair):
401406
specify_test "variable-name-inference @trace[0]"
402407
debug_value %0 : $KlassPair, let, name "self", argno 1, implicit
403408
%2 = struct_extract %0 : $KlassPair, #KlassPair.lhs
404409
%3 = copy_value %2 : $Klass
405410
debug_value [trace] %3 : $Klass
406411
return %3 : $Klass
407-
}
412+
}
413+
414+
// CHECK-LABEL: begin running test 1 of 1 on function_argument_inference_through_uncheckedenumdata: variable-name-inference with: @trace[0]
415+
// CHECK: Input Value: %3 = copy_value %2 : $Klass
416+
// CHECK: Name: 'self.some'
417+
// CHECK: Root: %0 = argument of bb0 : $FakeOptional<Klass>
418+
// CHECK: end running test 1 of 1 on function_argument_inference_through_uncheckedenumdata: variable-name-inference with: @trace[0]
419+
sil [ossa] @function_argument_inference_through_uncheckedenumdata : $@convention(thin) (@guaranteed FakeOptional<Klass>) -> @owned Klass {
420+
bb0(%0 : @guaranteed $FakeOptional<Klass>):
421+
specify_test "variable-name-inference @trace[0]"
422+
debug_value %0 : $FakeOptional<Klass>, let, name "self", argno 1, implicit
423+
%2 = unchecked_enum_data %0 : $FakeOptional<Klass>, #FakeOptional.some!enumelt
424+
%3 = copy_value %2 : $Klass
425+
debug_value [trace] %3 : $Klass
426+
return %3 : $Klass
427+
}
428+
429+
// CHECK-LABEL: begin running test 1 of 1 on function_argument_inference_through_uncheckedtakeenumdataaddr: variable-name-inference with: @trace[0]
430+
// CHECK: Input Value: %3 = load [take] %2 : $*Klass
431+
// CHECK: Name: 'self.some'
432+
// CHECK: Root: %0 = argument of bb0 : $*FakeOptional<Klass>
433+
// CHECK: end running test 1 of 1 on function_argument_inference_through_uncheckedtakeenumdataaddr: variable-name-inference with: @trace[0]
434+
sil [ossa] @function_argument_inference_through_uncheckedtakeenumdataaddr : $@convention(thin) (@in FakeOptional<Klass>) -> @owned Klass {
435+
bb0(%0 : $*FakeOptional<Klass>):
436+
specify_test "variable-name-inference @trace[0]"
437+
debug_value %0 : $*FakeOptional<Klass>, let, name "self", argno 1, implicit
438+
%2 = unchecked_take_enum_data_addr %0 : $*FakeOptional<Klass>, #FakeOptional.some!enumelt
439+
%3 = load [take] %2 : $*Klass
440+
debug_value [trace] %3 : $Klass
441+
return %3 : $Klass
442+
}
443+
444+
// CHECK-LABEL: begin running test 1 of 1 on function_argument_inference_through_uncheckedtakeenumdataaddr_2: variable-name-inference with: @trace[0]
445+
// CHECK: Input Value: %2 = unchecked_take_enum_data_addr %0
446+
// CHECK: Name: 'self.some'
447+
// CHECK: Root: %0 = argument of bb0 : $*FakeOptional<Klass>
448+
// CHECK: end running test 1 of 1 on function_argument_inference_through_uncheckedtakeenumdataaddr_2: variable-name-inference with: @trace[0]
449+
sil [ossa] @function_argument_inference_through_uncheckedtakeenumdataaddr_2 : $@convention(thin) (@in FakeOptional<Klass>) -> @owned Klass {
450+
bb0(%0 : $*FakeOptional<Klass>):
451+
specify_test "variable-name-inference @trace[0]"
452+
debug_value %0 : $*FakeOptional<Klass>, let, name "self", argno 1, implicit
453+
%2 = unchecked_take_enum_data_addr %0 : $*FakeOptional<Klass>, #FakeOptional.some!enumelt
454+
debug_value [trace] %2 : $*Klass
455+
%3 = load [take] %2 : $*Klass
456+
return %3 : $Klass
457+
}
458+

0 commit comments

Comments
 (0)