Skip to content

Commit a0e7360

Browse files
committed
[move-keyword] Wire up support for the move keyword in lvalue/rvalue emission.
I also updated the move function tests to show that this is working. As a nice bonus, I was able to enable all of the tests also in a non-optimized stdlib.
1 parent c27ec70 commit a0e7360

10 files changed

+288
-268
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "LValue.h"
2020
#include "RValue.h"
2121
#include "ResultPlan.h"
22+
#include "SGFContext.h"
2223
#include "SILGen.h"
2324
#include "SILGenDynamicCast.h"
2425
#include "SILGenFunctionBuilder.h"
@@ -42,6 +43,7 @@
4243
#include "swift/Basic/type_traits.h"
4344
#include "swift/SIL/DynamicCasts.h"
4445
#include "swift/SIL/SILArgument.h"
46+
#include "swift/SIL/SILInstruction.h"
4547
#include "swift/SIL/SILUndef.h"
4648
#include "swift/SIL/TypeLowering.h"
4749
#include "llvm/ADT/STLExtras.h"
@@ -537,6 +539,7 @@ namespace {
537539
LinearFunctionExtractOriginalExpr *E, SGFContext C);
538540
RValue visitLinearToDifferentiableFunctionExpr(
539541
LinearToDifferentiableFunctionExpr *E, SGFContext C);
542+
RValue visitMoveExpr(MoveExpr *E, SGFContext C);
540543
};
541544
} // end anonymous namespace
542545

@@ -5848,6 +5851,39 @@ RValue RValueEmitter::visitErrorExpr(ErrorExpr *E, SGFContext C) {
58485851
llvm::report_fatal_error("Found an ErrorExpr but didn't emit an error?");
58495852
}
58505853

5854+
RValue RValueEmitter::visitMoveExpr(MoveExpr *E, SGFContext C) {
5855+
auto *subExpr = cast<DeclRefExpr>(E->getSubExpr());
5856+
auto subASTType = subExpr->getType()->getCanonicalType();
5857+
5858+
auto subType = SGF.getLoweredType(subASTType);
5859+
5860+
if (subType.isLoadable(SGF.F)) {
5861+
auto mv = SGF.emitRValue(subExpr).getAsSingleValue(SGF, subExpr);
5862+
if (mv.getType().isTrivial(SGF.F))
5863+
return RValue(SGF, {mv}, subType.getASTType());
5864+
mv = SGF.B.createMoveValue(E, mv);
5865+
auto *movedValue = cast<MoveValueInst>(mv.getValue());
5866+
movedValue->setAllowsDiagnostics(true /*set allows diagnostics*/);
5867+
return RValue(SGF, {mv}, subType.getASTType());
5868+
}
5869+
5870+
// If we aren't loadable, then create a temporary initialization and
5871+
// mark_unresolved_move into that.
5872+
std::unique_ptr<TemporaryInitialization> optTemp;
5873+
optTemp = SGF.emitTemporary(E, SGF.getTypeLowering(subType));
5874+
SILValue toAddr = optTemp->getAddressForInPlaceInitialization(SGF, E);
5875+
assert(!isa<LValueType>(E->getType()->getCanonicalType()) &&
5876+
"Shouldn't see an lvalue type here");
5877+
5878+
ManagedValue mv =
5879+
SGF.emitRValue(subExpr, SGFContext(SGFContext::AllowImmediatePlusZero))
5880+
.getAsSingleValue(SGF, subExpr);
5881+
assert(mv.getType().isAddress());
5882+
SGF.B.createMarkUnresolvedMoveAddr(subExpr, mv.getValue(), toAddr);
5883+
optTemp->finishInitialization(SGF);
5884+
return RValue(SGF, {optTemp->getManagedAddress()}, subType.getASTType());
5885+
}
5886+
58515887
RValue SILGenFunction::emitRValue(Expr *E, SGFContext C) {
58525888
assert(!E->getType()->hasLValueType() &&
58535889
"l-values must be emitted with emitLValue");

lib/SILGen/SILGenLValue.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "LValue.h"
2424
#include "RValue.h"
2525
#include "SILGen.h"
26+
#include "SILGenFunction.h"
2627
#include "Scope.h"
2728
#include "swift/AST/DiagnosticsCommon.h"
2829
#include "swift/AST/DiagnosticsSIL.h"
@@ -35,6 +36,7 @@
3536
#include "swift/SIL/SILArgument.h"
3637
#include "swift/SIL/SILUndef.h"
3738
#include "swift/SIL/TypeLowering.h"
39+
#include "llvm/ADT/STLExtras.h"
3840
#include "llvm/Support/raw_ostream.h"
3941
using namespace swift;
4042
using namespace Lowering;
@@ -323,6 +325,8 @@ class LLVM_LIBRARY_VISIBILITY SILGenLValue
323325
LValue visitKeyPathApplicationExpr(KeyPathApplicationExpr *e,
324326
SGFAccessKind accessKind,
325327
LValueOptions options);
328+
LValue visitMoveExpr(MoveExpr *e, SGFAccessKind accessKind,
329+
LValueOptions options);
326330

327331
// Expressions that wrap lvalues
328332

@@ -3709,6 +3713,27 @@ LValue SILGenLValue::visitInOutExpr(InOutExpr *e, SGFAccessKind accessKind,
37093713
return visitRec(e->getSubExpr(), accessKind, options);
37103714
}
37113715

3716+
LValue SILGenLValue::visitMoveExpr(MoveExpr *e, SGFAccessKind accessKind,
3717+
LValueOptions options) {
3718+
// Do formal evaluation of the base l-value.
3719+
LValue baseLV = visitRec(e->getSubExpr(), SGFAccessKind::ReadWrite,
3720+
options.forComputedBaseLValue());
3721+
3722+
ManagedValue addr = SGF.emitAddressOfLValue(e, std::move(baseLV));
3723+
3724+
// Now create the temporary and
3725+
auto temp =
3726+
SGF.emitFormalAccessTemporary(e, SGF.F.getTypeLowering(addr.getType()));
3727+
auto toAddr = temp->getAddressForInPlaceInitialization(SGF, e);
3728+
SGF.B.createMarkUnresolvedMoveAddr(e, addr.getValue(), toAddr);
3729+
temp->finishInitialization(SGF);
3730+
3731+
// Now return the temporary in a value component.
3732+
return LValue::forValue(SGFAccessKind::BorrowedAddressRead,
3733+
temp->getManagedAddress(),
3734+
toAddr->getType().getASTType());
3735+
}
3736+
37123737
/// Emit an lvalue that refers to the given property. This is
37133738
/// designed to work with ManagedValue 'base's that are either +0 or +1.
37143739
LValue SILGenFunction::emitPropertyLValue(SILLocation loc, ManagedValue base,

test/DebugInfo/move_function_dbginfo.swift

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
// slightly differently on other platforms.
1515
// REQUIRES: OS=macosx
1616
// REQUIRES: CPU=x86_64 || CPU=arm64
17-
// REQUIRES: optimized_stdlib
1817

1918
//////////////////
2019
// Declarations //
@@ -81,7 +80,7 @@ public var falseValue: Bool { false }
8180
public func copyableValueTest() {
8281
let k = Klass()
8382
k.doSomething()
84-
let m = _move(k)
83+
let m = _move k
8584
m.doSomething()
8685
}
8786

@@ -127,7 +126,7 @@ public func copyableValueTest() {
127126
// DWARF-NEXT: DW_AT_type (
128127
public func copyableArgTest(_ k: __owned Klass) {
129128
k.doSomething()
130-
let m = _move(k)
129+
let m = _move k
131130
m.doSomething()
132131
}
133132

@@ -169,7 +168,7 @@ public func copyableArgTest(_ k: __owned Klass) {
169168
public func copyableVarTest() {
170169
var k = Klass()
171170
k.doSomething()
172-
let m = _move(k)
171+
let m = _move k
173172
m.doSomething()
174173
k = Klass()
175174
k.doSomething()
@@ -212,7 +211,7 @@ public func copyableVarTest() {
212211
// DWARF-NEXT: DW_AT_type (
213212
public func copyableVarArgTest(_ k: inout Klass) {
214213
k.doSomething()
215-
let m = _move(k)
214+
let m = _move k
216215
m.doSomething()
217216
k = Klass()
218217
k.doSomething()
@@ -262,7 +261,7 @@ public func copyableVarArgTest(_ k: inout Klass) {
262261
public func addressOnlyValueTest<T : P>(_ x: T) {
263262
let k = x
264263
k.doSomething()
265-
let m = _move(k)
264+
let m = _move k
266265
m.doSomething()
267266
}
268267

@@ -304,7 +303,7 @@ public func addressOnlyValueTest<T : P>(_ x: T) {
304303
// DWARF-NEXT: DW_AT_type (
305304
public func addressOnlyValueArgTest<T : P>(_ k: __owned T) {
306305
k.doSomething()
307-
let m = _move(k)
306+
let m = _move k
308307
m.doSomething()
309308
}
310309

@@ -349,7 +348,7 @@ public func addressOnlyValueArgTest<T : P>(_ k: __owned T) {
349348
public func addressOnlyVarTest<T : P>(_ x: T) {
350349
var k = x
351350
k.doSomething()
352-
let m = _move(k)
351+
let m = _move k
353352
m.doSomething()
354353
k = x
355354
k.doSomething()
@@ -394,7 +393,7 @@ public func addressOnlyVarTest<T : P>(_ x: T) {
394393
// DWARF-NEXT: DW_AT_artificial (true)
395394
public func addressOnlyVarArgTest<T : P>(_ k: inout T, _ x: T) {
396395
k.doSomething()
397-
let m = _move(k)
396+
let m = _move k
398397
m.doSomething()
399398
k = x
400399
k.doSomething()
@@ -417,7 +416,7 @@ public func copyableValueCCFlowTest() {
417416
let k = Klass()
418417
k.doSomething()
419418
if trueValue {
420-
let m = _move(k)
419+
let m = _move k
421420
m.doSomething()
422421
}
423422
}
@@ -434,7 +433,7 @@ public func copyableValueCCFlowTest() {
434433
public func copyableValueArgCCFlowTest(_ k: __owned Klass) {
435434
k.doSomething()
436435
if trueValue {
437-
let m = _move(k)
436+
let m = _move k
438437
m.doSomething()
439438
}
440439
}
@@ -464,7 +463,7 @@ public func copyableVarTestCCFlowReinitOutOfBlockTest() {
464463
var k = Klass()
465464
k.doSomething()
466465
if trueValue {
467-
let m = _move(k)
466+
let m = _move k
468467
m.doSomething()
469468
}
470469
k = Klass()
@@ -494,7 +493,7 @@ public func copyableVarTestCCFlowReinitOutOfBlockTest() {
494493
public func copyableVarArgTestCCFlowReinitOutOfBlockTest(_ k: inout Klass) {
495494
k.doSomething()
496495
if trueValue {
497-
let m = _move(k)
496+
let m = _move k
498497
m.doSomething()
499498
}
500499
k = Klass()
@@ -529,7 +528,7 @@ public func copyableVarTestCCFlowReinitInBlockTest() {
529528
var k = Klass()
530529
k.doSomething()
531530
if trueValue {
532-
let m = _move(k)
531+
let m = _move k
533532
m.doSomething()
534533
k = Klass()
535534
}
@@ -563,7 +562,7 @@ public func copyableVarTestCCFlowReinitInBlockTest() {
563562
public func copyableVarArgTestCCFlowReinitInBlockTest(_ k: inout Klass) {
564563
k.doSomething()
565564
if trueValue {
566-
let m = _move(k)
565+
let m = _move k
567566
m.doSomething()
568567
k = Klass()
569568
}
@@ -595,7 +594,7 @@ public func addressOnlyVarTestCCFlowReinitOutOfBlockTest<T : P>(_ x: T.Type) {
595594
var k = T.value
596595
k.doSomething()
597596
if trueValue {
598-
let m = _move(k)
597+
let m = _move k
599598
m.doSomething()
600599
}
601600
k = T.value
@@ -626,7 +625,7 @@ public func addressOnlyVarTestCCFlowReinitOutOfBlockTest<T : P>(_ x: T.Type) {
626625
public func addressOnlyVarArgTestCCFlowReinitOutOfBlockTest<T : P>(_ k: inout (any P), _ x: T.Type) {
627626
k.doSomething()
628627
if trueValue {
629-
let m = _move(k)
628+
let m = _move k
630629
m.doSomething()
631630
}
632631
k = T.value
@@ -660,7 +659,7 @@ public func addressOnlyVarTestCCFlowReinitInBlockTest<T : P>(_ x: T.Type) {
660659
var k = T.value
661660
k.doSomething()
662661
if trueValue {
663-
let m = _move(k)
662+
let m = _move k
664663
m.doSomething()
665664
k = T.value
666665
}
@@ -693,7 +692,7 @@ public func addressOnlyVarTestCCFlowReinitInBlockTest<T : P>(_ x: T.Type) {
693692
public func addressOnlyVarArgTestCCFlowReinitInBlockTest<T : P>(_ k: inout (any P), _ x: T.Type) {
694693
k.doSomething()
695694
if trueValue {
696-
let m = _move(k)
695+
let m = _move k
697696
m.doSomething()
698697
k = T.value
699698
}

test/DebugInfo/move_function_dbginfo_async.swift

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
// slightly differently on other platforms.
1616
// REQUIRES: OS=macosx
1717
// REQUIRES: CPU=x86_64 || CPU=arm64
18-
// REQUIRES: optimized_stdlib
1918

2019
//////////////////
2120
// Declarations //
@@ -83,7 +82,7 @@ public func forceSplit5() async {}
8382
// DWARF-NEXT: DW_AT_name ("msg")
8483
public func letSimpleTest<T>(_ msg: __owned T) async {
8584
await forceSplit()
86-
use(_move(msg))
85+
use(_move msg)
8786
}
8887

8988
// CHECK-LABEL: define swifttailcc void @"$s27move_function_dbginfo_async13varSimpleTestyyxz_xtYalF"(%swift.context* swiftasync %0, %swift.opaque* %1, %swift.opaque* noalias %2, %swift.type* %T)
@@ -147,7 +146,7 @@ public func letSimpleTest<T>(_ msg: __owned T) async {
147146
// DWARF: DW_TAG_formal_parameter
148147
// DWARF-NEXT: DW_AT_name ("msg")
149148
//
150-
// We reinitialize our value in this funclet and then move it and then
149+
// We reinitialize our value in this funclet and then _move it and then
151150
// reinitialize it again. So we have two different live ranges. Sadly, we don't
152151
// validate that the first live range doesn't start at the beginning of the
153152
// function. But we have lldb tests to validate that.
@@ -162,7 +161,7 @@ public func letSimpleTest<T>(_ msg: __owned T) async {
162161
// DWARF-SAME: DW_OP_entry_value([[ASYNC_REG]]), DW_OP_plus_uconst 0x[[MSG_LOC]], DW_OP_plus_uconst 0x8, DW_OP_deref
163162
// DWARF-NEXT: DW_AT_name ("msg")
164163
//
165-
// We did not move the value again here, so we just get a normal entry value for
164+
// We did not _move the value again here, so we just get a normal entry value for
166165
// the entire function.
167166
//
168167
// DWARF: DW_AT_linkage_name ("$s3out13varSimpleTestyyxz_xtYalFTQ4_")
@@ -180,10 +179,10 @@ public func letSimpleTest<T>(_ msg: __owned T) async {
180179
// Change name to varSimpleTestArg
181180
public func varSimpleTest<T>(_ msg: inout T, _ msg2: T) async {
182181
await forceSplit()
183-
use(_move(msg))
182+
use(_move msg)
184183
await forceSplit()
185184
msg = msg2
186-
let msg3 = _move(msg)
185+
let msg3 = _move msg
187186
let _ = msg3
188187
msg = msg2
189188
await forceSplit()
@@ -278,7 +277,7 @@ public func varSimpleTestVar() async {
278277
var k = Klass()
279278
k.doSomething()
280279
await forceSplit()
281-
let m = _move(k)
280+
let m = _move k
282281
m.doSomething()
283282
await forceSplit()
284283
k = Klass()
@@ -384,7 +383,7 @@ public func varSimpleTestVar() async {
384383
public func letArgCCFlowTrueTest<T>(_ msg: __owned T) async {
385384
await forceSplit1()
386385
if trueValue {
387-
use(_move(msg))
386+
use(_move msg)
388387
await forceSplit2()
389388
} else {
390389
await forceSplit3()
@@ -535,7 +534,7 @@ public func letArgCCFlowTrueTest<T>(_ msg: __owned T) async {
535534
public func varArgCCFlowTrueTest<T : P>(_ msg: inout T) async {
536535
await forceSplit1()
537536
if trueValue {
538-
use(_move(msg))
537+
use(_move msg)
539538
await forceSplit2()
540539
} else {
541540
await forceSplit3()

0 commit comments

Comments
 (0)