Skip to content

Commit 8e0aeff

Browse files
committed
[move-only-object] Make sure that we also convert copy_value -> explicit_copy_value for pure move only values along side no implicit copy values.
1 parent c16e0cf commit 8e0aeff

File tree

3 files changed

+81
-1
lines changed

3 files changed

+81
-1
lines changed

lib/SILOptimizer/Mandatory/MoveOnlyDiagnostics.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,24 @@
2222
using namespace swift;
2323
using namespace swift::siloptimizer;
2424

25+
static llvm::cl::opt<bool> SilentlyEmitDiagnostics(
26+
"move-only-diagnostics-silently-emit-diagnostics",
27+
llvm::cl::desc(
28+
"For testing purposes, emit the diagnostic silently so we can "
29+
"filecheck the result of emitting an error from the move checkers"),
30+
llvm::cl::init(false));
31+
2532
//===----------------------------------------------------------------------===//
2633
// MARK: Utilities
2734
//===----------------------------------------------------------------------===//
2835

2936
template <typename... T, typename... U>
3037
static void diagnose(ASTContext &Context, SourceLoc loc, Diag<T...> diag,
3138
U &&...args) {
39+
// If for testing reasons we want to return that we emitted an error but not
40+
// emit the actual error itself, return early.
41+
if (SilentlyEmitDiagnostics)
42+
return;
3243
Context.Diags.diagnose(loc, diag, std::forward<U>(args)...);
3344
}
3445

lib/SILOptimizer/Mandatory/MoveOnlyObjectChecker.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ bool MoveOnlyChecker::cleanupAfterEmittingDiagnostic() {
9292
auto *cvi = dyn_cast<CopyValueInst>(&*ii);
9393
++ii;
9494

95-
if (!cvi || !cvi->getOperand()->getType().isMoveOnlyWrapped())
95+
if (!cvi || !cvi->getOperand()->getType().isMoveOnly())
9696
continue;
9797

9898
SILBuilderWithScope b(cvi);
@@ -326,6 +326,9 @@ bool MoveOnlyChecker::check(NonLocalAccessBlockAnalysis *accessBlockAnalysis,
326326
// First search for candidates to process and emit diagnostics on any
327327
// mark_must_check [noimplicitcopy] we didn't recognize.
328328
bool emittedDiagnostic = searchForCandidateMarkMustChecks(diagnosticEmitter);
329+
LLVM_DEBUG(llvm::dbgs()
330+
<< "Emitting diagnostic when checking for mark must check inst: "
331+
<< (emittedDiagnostic ? "yes" : "no") << '\n');
329332

330333
// If we didn't find any introducers to check, just return if we emitted an
331334
// error (which is the only way we emitted a change to the instruction
@@ -354,6 +357,9 @@ bool MoveOnlyChecker::check(NonLocalAccessBlockAnalysis *accessBlockAnalysis,
354357
// First canonicalize ownership.
355358
if (!canonicalizer.canonicalize(markedValue)) {
356359
diagnosticEmitter.emitCheckerDoesntUnderstandDiagnostic(markedValue);
360+
LLVM_DEBUG(
361+
llvm::dbgs()
362+
<< "Emitted checker doesnt understand diagnostic! Exiting early!\n");
357363
continue;
358364
} else {
359365
// Always set changed to true if we succeeded in canonicalizing since we
@@ -382,6 +388,8 @@ bool MoveOnlyChecker::check(NonLocalAccessBlockAnalysis *accessBlockAnalysis,
382388
}
383389

384390
emittedDiagnostic = diagnosticEmitter.emittedAnyDiagnostics();
391+
LLVM_DEBUG(llvm::dbgs() << "Emitting checker based diagnostic: "
392+
<< (emittedDiagnostic ? "yes" : "no") << '\n');
385393

386394
// Ok, we have success. All of our marker instructions were proven as safe or
387395
// we emitted a diagnostic. Now we need to clean up the IR by eliminating our
@@ -473,6 +481,17 @@ class MoveOnlyCheckerPass : public SILFunctionTransform {
473481
.check(accessBlockAnalysis, domTree)) {
474482
invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions);
475483
}
484+
485+
if (getOptions().VerifyAll) {
486+
for (auto &block : *getFunction()) {
487+
for (auto &inst : block) {
488+
if (auto *cvi = dyn_cast<CopyValueInst>(&inst)) {
489+
assert(!cvi->getOperand()->getType().isMoveOnly() &&
490+
"Shouldn't copy move only types at this point");
491+
}
492+
}
493+
}
494+
}
476495
}
477496
};
478497

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// RUN: %target-sil-opt -sil-move-only-object-checker -enable-experimental-move-only -enable-sil-verify-all -move-only-diagnostics-silently-emit-diagnostics %s | %FileCheck %s
2+
3+
sil_stage raw
4+
5+
@_moveOnly
6+
class Klass {}
7+
8+
sil @classUseMoveOnlyWithoutEscaping : $@convention(thin) (@guaranteed Klass) -> ()
9+
10+
// CHECK-LABEL: sil [ossa] @chainErrorTest : $@convention(thin) (@guaranteed Klass) -> () {
11+
// CHECK-NOT: copy_value
12+
// CHECK: explicit_copy_value
13+
// CHECK-NOT: copy_value
14+
// CHECK: explicit_copy_value
15+
// CHECK-NOT: copy_value
16+
// CHECK: } // end sil function 'chainErrorTest'
17+
sil [ossa] @chainErrorTest : $@convention(thin) (@guaranteed Klass) -> () {
18+
bb0(%0 : @guaranteed $Klass):
19+
%1 = copy_value %0 : $Klass
20+
%2 = mark_must_check [no_copy] %1 : $Klass
21+
debug_value %2 : $Klass, let, name "x", argno 1
22+
%4 = copy_value %2 : $Klass
23+
%5 = move_value [lexical] %4 : $Klass
24+
%6 = mark_must_check [no_implicit_copy] %5 : $Klass
25+
debug_value %6 : $Klass, let, name "x2"
26+
%8 = copy_value %6 : $Klass
27+
%9 = move_value [lexical] %8 : $Klass
28+
%10 = mark_must_check [no_implicit_copy] %9 : $Klass
29+
debug_value %10 : $Klass, let, name "y2"
30+
%12 = copy_value %10 : $Klass
31+
%13 = move_value [lexical] %12 : $Klass
32+
%14 = mark_must_check [no_implicit_copy] %13 : $Klass
33+
debug_value %14 : $Klass, let, name "k2"
34+
%16 = copy_value %6 : $Klass
35+
%17 = move_value [lexical] %16 : $Klass
36+
%18 = mark_must_check [no_implicit_copy] %17 : $Klass
37+
debug_value %18 : $Klass, let, name "k3"
38+
%20 = copy_value %18 : $Klass
39+
%21 = move_value %20 : $Klass
40+
destroy_value %21 : $Klass
41+
%23 = function_ref @classUseMoveOnlyWithoutEscaping : $@convention(thin) (@guaranteed Klass) -> ()
42+
%24 = apply %23(%14) : $@convention(thin) (@guaranteed Klass) -> ()
43+
destroy_value %18 : $Klass
44+
destroy_value %14 : $Klass
45+
destroy_value %10 : $Klass
46+
destroy_value %6 : $Klass
47+
destroy_value %2 : $Klass
48+
%30 = tuple ()
49+
return %30 : $()
50+
}

0 commit comments

Comments
 (0)