Skip to content

Commit d4c83bc

Browse files
committed
[AddressLowering] Handle move_value.
It's handled just like begin_borrow: ignored unless lexical.
1 parent bb46f74 commit d4c83bc

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

lib/SILOptimizer/Mandatory/AddressLowering.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,9 @@ static Operand *getProjectedDefOperand(SILValue value) {
872872

873873
return nullptr;
874874

875+
case ValueKind::MoveValueInst:
876+
return &cast<MoveValueInst>(value)->getOperandRef();
877+
875878
case ValueKind::MultipleValueInstructionResult: {
876879
SILInstruction *destructure =
877880
cast<MultipleValueInstructionResult>(value)->getParent();
@@ -3128,6 +3131,8 @@ class UseRewriter : SILInstructionVisitor<UseRewriter> {
31283131
// types.
31293132
void visitOpenExistentialValueInst(OpenExistentialValueInst *openExistential);
31303133

3134+
void visitMoveValueInst(MoveValueInst *mvi);
3135+
31313136
void visitReturnInst(ReturnInst *returnInst) {
31323137
// Returns are rewritten for any function with indirect results after
31333138
// opaque value rewriting.
@@ -3295,6 +3300,10 @@ void UseRewriter::visitBeginBorrowInst(BeginBorrowInst *borrow) {
32953300
visitLifetimeIntroducer(borrow);
32963301
}
32973302

3303+
void UseRewriter::visitMoveValueInst(MoveValueInst *mvi) {
3304+
visitLifetimeIntroducer(mvi);
3305+
}
3306+
32983307
// Opening an opaque existential. Rewrite the opened existentials here on
32993308
// the use-side because it may produce either loadable or address-only
33003309
// types.

test/SILOptimizer/address_lowering.sil

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1924,6 +1924,60 @@ entry(%addr : $*T):
19241924
return %retval : $()
19251925
}
19261926

1927+
// The move_value is lexical so the corresponding alloc_stack must be marked
1928+
// lexical too.
1929+
// CHECK-LABEL: sil [ossa] @testMoveValueLexical : {{.*}} {
1930+
// CHECK: alloc_stack [lexical]
1931+
// CHECK-LABEL: } // end sil function 'testMoveValueLexical'
1932+
sil [ossa] @testMoveValueLexical : $@convention(thin) <T> () -> () {
1933+
%getT = function_ref @getT : $@convention(thin) <T> () -> @out T
1934+
%instance = apply %getT<T>() : $@convention(thin) <T> () -> @out T
1935+
%moved = move_value [lexical] %instance : $T
1936+
destroy_value %moved : $T
1937+
%retval = tuple ()
1938+
return %retval : $()
1939+
}
1940+
1941+
// Verify that the temporary storage is lexical and moved out of
1942+
// (copy_addr [take]).
1943+
// CHECK-LABEL: sil [ossa] @testMoveValueLexicalAndReturn : {{.*}} {
1944+
// CHECK: {{bb[0-9]+}}([[RETVAL:%[^,]+]] :
1945+
// CHECK: [[STACK:%[^,]+]] = alloc_stack [lexical]
1946+
// CHECK: copy_addr [take] [[STACK]] to [init] [[RETVAL]]
1947+
// CHECK-LABEL: } // end sil function 'testMoveValueLexicalAndReturn'
1948+
sil [ossa] @testMoveValueLexicalAndReturn : $@convention(thin) <T> () -> @out T {
1949+
%getT = function_ref @getT : $@convention(thin) <T> () -> @out T
1950+
%instance = apply %getT<T>() : $@convention(thin) <T> () -> @out T
1951+
%moved = move_value [lexical] %instance : $T
1952+
return %moved : $T
1953+
}
1954+
1955+
// Verify that a move_value gets no stack storage if it's from an argument.
1956+
// CHECK-LABEL: sil [ossa] @testMoveValueLexicalArgument : {{.*}} {
1957+
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] :
1958+
// CHECK: destroy_addr [[INSTANCE]]
1959+
// CHECK-LABEL: } // end sil function 'testMoveValueLexicalArgument'
1960+
sil [ossa] @testMoveValueLexicalArgument : $@convention(thin) <T> (@in T) -> () {
1961+
entry(%instance : @owned $T):
1962+
%moved = move_value [lexical] %instance : $T
1963+
destroy_value %moved : $T
1964+
%retval = tuple ()
1965+
return %retval : $()
1966+
}
1967+
1968+
// Only lexical move_values should mark the alloc_stack lexical.
1969+
// CHECK-LABEL: sil [ossa] @testMoveValueNonlexical : {{.*}} {
1970+
// CHECK-NOT: alloc_stack [lexical]
1971+
// CHECK-LABEL: } // end sil function 'testMoveValueNonlexical'
1972+
sil [ossa] @testMoveValueNonlexical : $@convention(thin) <T> () -> () {
1973+
%getT = function_ref @getT : $@convention(thin) <T> () -> @out T
1974+
%instance = apply %getT<T>() : $@convention(thin) <T> () -> @out T
1975+
%moved = move_value %instance : $T
1976+
destroy_value %moved : $T
1977+
%retval = tuple ()
1978+
return %retval : $()
1979+
}
1980+
19271981
// CHECK-LABEL: sil hidden [ossa] @testOpaqueYield :
19281982
// CHECK: bb0(%0 : @guaranteed $TestGeneric<T>):
19291983
// CHECK: [[REF:%.*]] = ref_element_addr %0 : $TestGeneric<T>, #TestGeneric.borrowedGeneric

0 commit comments

Comments
 (0)