Skip to content

Commit de69652

Browse files
authored
Merge pull request #5416 from gottesmm/copy_value_destroy_value
2 parents d2eec15 + ab0ffa2 commit de69652

File tree

14 files changed

+153
-8
lines changed

14 files changed

+153
-8
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,16 @@ class SILBuilder {
747747
operand, atomicity));
748748
}
749749

750+
CopyValueInst *createCopyValue(SILLocation Loc, SILValue operand) {
751+
return insert(new (F.getModule())
752+
CopyValueInst(getSILDebugLocation(Loc), operand));
753+
}
754+
755+
DestroyValueInst *createDestroyValue(SILLocation Loc, SILValue operand) {
756+
return insert(new (F.getModule())
757+
DestroyValueInst(getSILDebugLocation(Loc), operand));
758+
}
759+
750760
AutoreleaseValueInst *createAutoreleaseValue(SILLocation Loc,
751761
SILValue operand,
752762
Atomicity atomicity) {

include/swift/SIL/SILCloner.h

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,19 +1131,34 @@ SILCloner<ImplClass>::visitRetainValueInst(RetainValueInst *Inst) {
11311131
Inst->getAtomicity()));
11321132
}
11331133

1134-
template<typename ImplClass>
1135-
void
1136-
SILCloner<ImplClass>::visitReleaseValueInst(ReleaseValueInst *Inst) {
1134+
template <typename ImplClass>
1135+
void SILCloner<ImplClass>::visitCopyValueInst(CopyValueInst *Inst) {
1136+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1137+
doPostProcess(Inst,
1138+
getBuilder().createCopyValue(getOpLocation(Inst->getLoc()),
1139+
getOpValue(Inst->getOperand())));
1140+
}
1141+
1142+
template <typename ImplClass>
1143+
void SILCloner<ImplClass>::visitReleaseValueInst(ReleaseValueInst *Inst) {
11371144
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
11381145
doPostProcess(Inst,
11391146
getBuilder().createReleaseValue(getOpLocation(Inst->getLoc()),
11401147
getOpValue(Inst->getOperand()),
11411148
Inst->getAtomicity()));
11421149
}
11431150

1144-
template<typename ImplClass>
1145-
void
1146-
SILCloner<ImplClass>::visitAutoreleaseValueInst(AutoreleaseValueInst *Inst) {
1151+
template <typename ImplClass>
1152+
void SILCloner<ImplClass>::visitDestroyValueInst(DestroyValueInst *Inst) {
1153+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1154+
doPostProcess(
1155+
Inst, getBuilder().createDestroyValue(getOpLocation(Inst->getLoc()),
1156+
getOpValue(Inst->getOperand())));
1157+
}
1158+
1159+
template <typename ImplClass>
1160+
void SILCloner<ImplClass>::visitAutoreleaseValueInst(
1161+
AutoreleaseValueInst *Inst) {
11471162
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
11481163
doPostProcess(Inst,
11491164
getBuilder().createAutoreleaseValue(getOpLocation(Inst->getLoc()),

include/swift/SIL/SILInstruction.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4193,6 +4193,21 @@ class CopyBlockInst :
41934193
: UnaryInstructionBase(DebugLoc, operand, operand->getType()) {}
41944194
};
41954195

4196+
class CopyValueInst : public UnaryInstructionBase<ValueKind::CopyValueInst> {
4197+
friend class SILBuilder;
4198+
4199+
CopyValueInst(SILDebugLocation DebugLoc, SILValue operand)
4200+
: UnaryInstructionBase(DebugLoc, operand, operand->getType()) {}
4201+
};
4202+
4203+
class DestroyValueInst
4204+
: public UnaryInstructionBase<ValueKind::DestroyValueInst> {
4205+
friend class SILBuilder;
4206+
4207+
DestroyValueInst(SILDebugLocation DebugLoc, SILValue operand)
4208+
: UnaryInstructionBase(DebugLoc, operand) {}
4209+
};
4210+
41964211
/// Given an object reference, return true iff it is non-nil and refers
41974212
/// to a native swift object with strong reference count of 1.
41984213
class IsUniqueInst : public UnaryInstructionBase<ValueKind::IsUniqueInst>

include/swift/SIL/SILNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ ABSTRACT_VALUE(SILInstruction, ValueBase)
145145
INST(FixLifetimeInst, SILInstruction, fix_lifetime, MayHaveSideEffects, DoesNotRelease)
146146
INST(MarkDependenceInst, SILInstruction, mark_dependence, None, DoesNotRelease)
147147
INST(CopyBlockInst, SILInstruction, copy_block, MayHaveSideEffects, DoesNotRelease)
148+
INST(CopyValueInst, SILInstruction, copy_value, MayHaveSideEffects, DoesNotRelease)
149+
INST(DestroyValueInst, SILInstruction, destroy_value, MayHaveSideEffects, MayRelease)
148150

149151
// IsUnique does not actually write to memory but should be modeled
150152
// as such. Its operand is a pointer to an object reference. The

lib/IRGen/IRGenSIL.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,9 @@ class IRGenSILFunction :
806806
void visitLoadWeakInst(LoadWeakInst *i);
807807
void visitStoreWeakInst(StoreWeakInst *i);
808808
void visitRetainValueInst(RetainValueInst *i);
809+
void visitCopyValueInst(CopyValueInst *i);
809810
void visitReleaseValueInst(ReleaseValueInst *i);
811+
void visitDestroyValueInst(DestroyValueInst *i);
810812
void visitAutoreleaseValueInst(AutoreleaseValueInst *i);
811813
void visitSetDeallocatingInst(SetDeallocatingInst *i);
812814
void visitStructInst(StructInst *i);
@@ -2956,6 +2958,14 @@ void IRGenSILFunction::visitRetainValueInst(swift::RetainValueInst *i) {
29562958
out.claimAll();
29572959
}
29582960

2961+
void IRGenSILFunction::visitCopyValueInst(swift::CopyValueInst *i) {
2962+
Explosion in = getLoweredExplosion(i->getOperand());
2963+
Explosion out;
2964+
cast<LoadableTypeInfo>(getTypeInfo(i->getOperand()->getType()))
2965+
.copy(*this, in, out, irgen::Atomicity::Atomic);
2966+
setLoweredExplosion(i, out);
2967+
}
2968+
29592969
// TODO: Implement this more generally for arbitrary values. Currently the
29602970
// SIL verifier restricts it to single-refcounted-pointer types.
29612971
void IRGenSILFunction::visitAutoreleaseValueInst(swift::AutoreleaseValueInst *i)
@@ -3007,6 +3017,12 @@ void IRGenSILFunction::visitReleaseValueInst(swift::ReleaseValueInst *i) {
30073017
: irgen::Atomicity::NonAtomic);
30083018
}
30093019

3020+
void IRGenSILFunction::visitDestroyValueInst(swift::DestroyValueInst *i) {
3021+
Explosion in = getLoweredExplosion(i->getOperand());
3022+
cast<LoadableTypeInfo>(getTypeInfo(i->getOperand()->getType()))
3023+
.consume(*this, in, irgen::Atomicity::Atomic);
3024+
}
3025+
30103026
void IRGenSILFunction::visitStructInst(swift::StructInst *i) {
30113027
Explosion out;
30123028
for (SILValue elt : i->getElements())

lib/Parse/ParseSIL.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,6 +1927,8 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
19271927
UNARY_INSTRUCTION(IsUnique)
19281928
UNARY_INSTRUCTION(IsUniqueOrPinned)
19291929
UNARY_INSTRUCTION(DestroyAddr)
1930+
UNARY_INSTRUCTION(CopyValue)
1931+
UNARY_INSTRUCTION(DestroyValue)
19301932
UNARY_INSTRUCTION(CondFail)
19311933
REFCOUNTING_INSTRUCTION(StrongPin)
19321934
REFCOUNTING_INSTRUCTION(StrongRetain)

lib/SIL/SILPrinter.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,6 +1269,14 @@ class SILPrinter : public SILVisitor<SILPrinter> {
12691269
*this << getIDAndType(I->getOperand());
12701270
}
12711271

1272+
void visitCopyValueInst(CopyValueInst *I) {
1273+
*this << getIDAndType(I->getOperand());
1274+
}
1275+
1276+
void visitDestroyValueInst(DestroyValueInst *I) {
1277+
*this << getIDAndType(I->getOperand());
1278+
}
1279+
12721280
void visitRetainValueInst(RetainValueInst *I) { visitRefCountingInst(I); }
12731281

12741282
void visitReleaseValueInst(ReleaseValueInst *I) { visitRefCountingInst(I); }

lib/SILOptimizer/Utils/SILInliner.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) {
325325
case ValueKind::CopyBlockInst:
326326
case ValueKind::CopyAddrInst:
327327
case ValueKind::RetainValueInst:
328+
case ValueKind::CopyValueInst:
328329
case ValueKind::DeallocBoxInst:
329330
case ValueKind::DeallocExistentialBoxInst:
330331
case ValueKind::DeallocRefInst:
@@ -337,6 +338,7 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) {
337338
case ValueKind::ProjectBoxInst:
338339
case ValueKind::ProjectExistentialBoxInst:
339340
case ValueKind::ReleaseValueInst:
341+
case ValueKind::DestroyValueInst:
340342
case ValueKind::AutoreleaseValueInst:
341343
case ValueKind::DynamicMethodBranchInst:
342344
case ValueKind::DynamicMethodInst:

lib/Serialization/DeserializeSIL.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,6 +1274,8 @@ bool SILDeserializer::readSILInstruction(
12741274

12751275
UNARY_INSTRUCTION(CondFail)
12761276
REFCOUNTING_INSTRUCTION(RetainValue)
1277+
UNARY_INSTRUCTION(CopyValue)
1278+
UNARY_INSTRUCTION(DestroyValue)
12771279
REFCOUNTING_INSTRUCTION(ReleaseValue)
12781280
REFCOUNTING_INSTRUCTION(AutoreleaseValue)
12791281
REFCOUNTING_INSTRUCTION(SetDeallocating)

lib/Serialization/SerializeSIL.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,8 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
992992
}
993993
case ValueKind::CondFailInst:
994994
case ValueKind::RetainValueInst:
995+
case ValueKind::CopyValueInst:
996+
case ValueKind::DestroyValueInst:
995997
case ValueKind::ReleaseValueInst:
996998
case ValueKind::AutoreleaseValueInst:
997999
case ValueKind::SetDeallocatingInst:
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: %target-swift-frontend -parse-sil -emit-ir %s | %FileCheck %s
2+
3+
// Make sure that we are using type lowering and that we are handling the return
4+
// value correctly.
5+
6+
sil_stage canonical
7+
8+
import Builtin
9+
10+
struct Foo {
11+
var t1 : Builtin.Int32
12+
var c1 : Builtin.NativeObject
13+
var t2 : Builtin.Int32
14+
var c2 : Builtin.NativeObject
15+
var t3 : Builtin.Int32
16+
}
17+
18+
// CHECK: define{{( protected)?}} void @trivial(
19+
// CHECK-NEXT: entry
20+
// CHECK-NEXT: ret void
21+
sil @trivial : $@convention(thin) (Builtin.Int32) -> () {
22+
bb0(%0 : $Builtin.Int32):
23+
%1 = copy_value %0 : $Builtin.Int32
24+
destroy_value %1 : $Builtin.Int32
25+
%2 = tuple()
26+
return %2 : $()
27+
}
28+
29+
// CHECK: define{{( protected)?}} void @non_trivial(
30+
// CHECK: [[GEP1:%.*]] = getelementptr inbounds %V24copy_value_destroy_value3Foo, %V24copy_value_destroy_value3Foo* %0, i32 0, i32 2
31+
// CHECK: [[VAL1:%.*]] = load %swift.refcounted*, %swift.refcounted** [[GEP1]], align 8
32+
// CHECK: [[GEP2:%.*]] = getelementptr inbounds %V24copy_value_destroy_value3Foo, %V24copy_value_destroy_value3Foo* %0, i32 0, i32 5
33+
// CHECK: [[VAL2:%.*]] = load %swift.refcounted*, %swift.refcounted** [[GEP2]], align 8
34+
// CHECK: call void @swift_rt_swift_retain(%swift.refcounted* [[VAL1]])
35+
// CHECK: call void @swift_rt_swift_retain(%swift.refcounted* [[VAL2]])
36+
// CHECK: call void @swift_rt_swift_release(%swift.refcounted* [[VAL1]])
37+
// CHECK: call void @swift_rt_swift_release(%swift.refcounted* [[VAL2]])
38+
sil @non_trivial : $@convention(thin) (Foo) -> () {
39+
bb0(%0 : $Foo):
40+
%1 = copy_value %0 : $Foo
41+
destroy_value %1 : $Foo
42+
%2 = tuple()
43+
return %2 : $()
44+
}

test/SIL/Parser/basic.sil

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1080,10 +1080,15 @@ sil @test_mark_fn_escape : $() -> () {
10801080
sil @test_copy_release_value : $(Val) -> (Val) {
10811081
bb0(%0 : $Val):
10821082
retain_value %0 : $Val
1083+
%1 = copy_value %0 : $Val
10831084
release_value %0 : $Val
1084-
return %0 : $Val
1085+
destroy_value %0 : $Val
1086+
return %1 : $Val
10851087
// CHECK: retain_value [[T0:%.*]] : $Val
1088+
// CHECK-NEXT: [[COPY_RESULT:%.*]] = copy_value [[T0]] : $Val
10861089
// CHECK-NEXT: release_value [[T0]] : $Val
1090+
// CHECK-NEXT: destroy_value [[T0]] : $Val
1091+
// CHECK-NEXT: return [[COPY_RESULT]]
10871092
}
10881093

10891094
// CHECK-LABEL: sil @test_autorelease_value
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// First parse this and then emit a *.sib. Then read in the *.sib, then recreate
2+
// RUN: rm -rfv %t
3+
// RUN: mkdir %t
4+
// RUN: %target-sil-opt %s -emit-sib -o %t/tmp.sib -module-name copydestroy_value
5+
// RUN: %target-sil-opt %t/tmp.sib -o %t/tmp.2.sib -module-name copydestroy_value
6+
// RUN: %target-sil-opt %t/tmp.2.sib -module-name copydestroy_value | %FileCheck %s
7+
8+
sil_stage canonical
9+
10+
import Builtin
11+
12+
// CHECK-LABEL: sil @test : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
13+
// CHECK: bb0([[ARG1:%[0-9]+]] : $Builtin.NativeObject):
14+
// CHECK: [[COPY_VALUE_RESULT:%[0-9]+]] = copy_value [[ARG1]] : $Builtin.NativeObject
15+
// CHECK: destroy_value [[ARG1]]
16+
// CHECK: return [[COPY_VALUE_RESULT]]
17+
sil @test : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
18+
bb0(%0 : $Builtin.NativeObject):
19+
%1 = copy_value %0 : $Builtin.NativeObject
20+
destroy_value %0 : $Builtin.NativeObject
21+
return %1 : $Builtin.NativeObject
22+
}

utils/sil-mode.el

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@
107107
`(,(regexp-opt '("retain_value" "release_value" "tuple" "tuple_extract"
108108
"tuple_element_addr" "struct" "struct_extract"
109109
"struct_element_addr" "ref_element_addr"
110-
"autorelease_value")
110+
"autorelease_value" "copy_value" "destroy_value")
111111
'words) . font-lock-keyword-face)
112112
;; Enums. *NOTE* We do not include enum itself here since enum is a
113113
;; swift declaration as well handled at the top.

0 commit comments

Comments
 (0)