Skip to content

Commit c2e8b9e

Browse files
committed
[sil] Teach the SILCloner how to clone from ossa -> non-ossa.
At a high level, we perform the OME lowering as we transform.
1 parent 9b0a94f commit c2e8b9e

File tree

3 files changed

+323
-2
lines changed

3 files changed

+323
-2
lines changed

include/swift/SIL/SILCloner.h

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,28 @@ SILCloner<ImplClass>::visitStringLiteralInst(StringLiteralInst *Inst) {
999999
template <typename ImplClass>
10001000
void SILCloner<ImplClass>::visitLoadInst(LoadInst *Inst) {
10011001
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1002-
recordClonedInstruction(
1002+
if (!getBuilder().hasOwnership()) {
1003+
switch (Inst->getOwnershipQualifier()) {
1004+
case LoadOwnershipQualifier::Copy: {
1005+
auto *li = getBuilder().createLoad(getOpLocation(Inst->getLoc()),
1006+
getOpValue(Inst->getOperand()),
1007+
LoadOwnershipQualifier::Unqualified);
1008+
// This will emit a retain_value/strong_retain as appropriate.
1009+
getBuilder().emitCopyValueOperation(getOpLocation(Inst->getLoc()), li);
1010+
return recordClonedInstruction(Inst, li);
1011+
}
1012+
case LoadOwnershipQualifier::Take:
1013+
case LoadOwnershipQualifier::Trivial:
1014+
case LoadOwnershipQualifier::Unqualified:
1015+
break;
1016+
}
1017+
return recordClonedInstruction(
1018+
Inst, getBuilder().createLoad(getOpLocation(Inst->getLoc()),
1019+
getOpValue(Inst->getOperand()),
1020+
LoadOwnershipQualifier::Unqualified));
1021+
}
1022+
1023+
return recordClonedInstruction(
10031024
Inst, getBuilder().createLoad(getOpLocation(Inst->getLoc()),
10041025
getOpValue(Inst->getOperand()),
10051026
Inst->getOwnershipQualifier()));
@@ -1008,6 +1029,14 @@ void SILCloner<ImplClass>::visitLoadInst(LoadInst *Inst) {
10081029
template <typename ImplClass>
10091030
void SILCloner<ImplClass>::visitLoadBorrowInst(LoadBorrowInst *Inst) {
10101031
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1032+
// If we are not inlining into an ownership function, just use a load.
1033+
if (!getBuilder().hasOwnership()) {
1034+
return recordClonedInstruction(
1035+
Inst, getBuilder().createLoad(getOpLocation(Inst->getLoc()),
1036+
getOpValue(Inst->getOperand()),
1037+
LoadOwnershipQualifier::Unqualified));
1038+
}
1039+
10111040
recordClonedInstruction(
10121041
Inst, getBuilder().createLoadBorrow(getOpLocation(Inst->getLoc()),
10131042
getOpValue(Inst->getOperand())));
@@ -1016,6 +1045,10 @@ void SILCloner<ImplClass>::visitLoadBorrowInst(LoadBorrowInst *Inst) {
10161045
template <typename ImplClass>
10171046
void SILCloner<ImplClass>::visitBeginBorrowInst(BeginBorrowInst *Inst) {
10181047
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1048+
if (!getBuilder().hasOwnership()) {
1049+
return recordFoldedValue(Inst, getOpValue(Inst->getOperand()));
1050+
}
1051+
10191052
recordClonedInstruction(
10201053
Inst, getBuilder().createBeginBorrow(getOpLocation(Inst->getLoc()),
10211054
getOpValue(Inst->getOperand())));
@@ -1024,6 +1057,31 @@ void SILCloner<ImplClass>::visitBeginBorrowInst(BeginBorrowInst *Inst) {
10241057
template <typename ImplClass>
10251058
void SILCloner<ImplClass>::visitStoreInst(StoreInst *Inst) {
10261059
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1060+
if (!getBuilder().hasOwnership()) {
1061+
switch (Inst->getOwnershipQualifier()) {
1062+
case StoreOwnershipQualifier::Assign: {
1063+
auto *li = getBuilder().createLoad(getOpLocation(Inst->getLoc()),
1064+
getOpValue(Inst->getDest()),
1065+
LoadOwnershipQualifier::Unqualified);
1066+
auto *si = getBuilder().createStore(
1067+
getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()),
1068+
getOpValue(Inst->getDest()), StoreOwnershipQualifier::Unqualified);
1069+
getBuilder().emitDestroyValueOperation(getOpLocation(Inst->getLoc()), li);
1070+
return recordClonedInstruction(Inst, si);
1071+
}
1072+
case StoreOwnershipQualifier::Init:
1073+
case StoreOwnershipQualifier::Trivial:
1074+
case StoreOwnershipQualifier::Unqualified:
1075+
break;
1076+
}
1077+
1078+
return recordClonedInstruction(
1079+
Inst, getBuilder().createStore(getOpLocation(Inst->getLoc()),
1080+
getOpValue(Inst->getSrc()),
1081+
getOpValue(Inst->getDest()),
1082+
StoreOwnershipQualifier::Unqualified));
1083+
}
1084+
10271085
recordClonedInstruction(
10281086
Inst, getBuilder().createStore(
10291087
getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()),
@@ -1033,6 +1091,16 @@ void SILCloner<ImplClass>::visitStoreInst(StoreInst *Inst) {
10331091
template <typename ImplClass>
10341092
void SILCloner<ImplClass>::visitStoreBorrowInst(StoreBorrowInst *Inst) {
10351093
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1094+
if (!getBuilder().hasOwnership()) {
1095+
// TODO: Eliminate store_borrow result so we can use
1096+
// recordClonedInstruction. It is not "technically" necessary, but it is
1097+
// better from an invariant perspective.
1098+
getBuilder().createStore(
1099+
getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()),
1100+
getOpValue(Inst->getDest()), StoreOwnershipQualifier::Unqualified);
1101+
return;
1102+
}
1103+
10361104
recordClonedInstruction(
10371105
Inst, getBuilder().createStoreBorrow(getOpLocation(Inst->getLoc()),
10381106
getOpValue(Inst->getSrc()),
@@ -1042,6 +1110,11 @@ void SILCloner<ImplClass>::visitStoreBorrowInst(StoreBorrowInst *Inst) {
10421110
template <typename ImplClass>
10431111
void SILCloner<ImplClass>::visitEndBorrowInst(EndBorrowInst *Inst) {
10441112
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1113+
1114+
// Do not clone any end_borrow.
1115+
if (!getBuilder().hasOwnership())
1116+
return;
1117+
10451118
recordClonedInstruction(
10461119
Inst,
10471120
getBuilder().createEndBorrow(getOpLocation(Inst->getLoc()),
@@ -1546,6 +1619,12 @@ void SILCloner<ImplClass>::visitUnmanagedRetainValueInst(
15461619
template <typename ImplClass>
15471620
void SILCloner<ImplClass>::visitCopyValueInst(CopyValueInst *Inst) {
15481621
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1622+
if (!getBuilder().hasOwnership()) {
1623+
SILValue newValue = getBuilder().emitCopyValueOperation(
1624+
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()));
1625+
return recordFoldedValue(Inst, newValue);
1626+
}
1627+
15491628
recordClonedInstruction(
15501629
Inst, getBuilder().createCopyValue(getOpLocation(Inst->getLoc()),
15511630
getOpValue(Inst->getOperand())));
@@ -1583,6 +1662,13 @@ void SILCloner<ImplClass>::visitUnmanagedReleaseValueInst(
15831662
template <typename ImplClass>
15841663
void SILCloner<ImplClass>::visitDestroyValueInst(DestroyValueInst *Inst) {
15851664
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1665+
if (!getBuilder().hasOwnership()) {
1666+
return recordClonedInstruction(
1667+
Inst, getBuilder().createReleaseValue(
1668+
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()),
1669+
RefCountingInst::Atomicity::Atomic));
1670+
}
1671+
15861672
recordClonedInstruction(
15871673
Inst, getBuilder().createDestroyValue(getOpLocation(Inst->getLoc()),
15881674
getOpValue(Inst->getOperand())));
@@ -1795,6 +1881,16 @@ template <typename ImplClass>
17951881
void SILCloner<ImplClass>::visitDestructureStructInst(
17961882
DestructureStructInst *Inst) {
17971883
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1884+
1885+
if (!getBuilder().hasOwnership()) {
1886+
getBuilder().emitDestructureValueOperation(
1887+
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()),
1888+
[&](unsigned index, SILValue value) {
1889+
recordFoldedValue(Inst->getResults()[index], value);
1890+
});
1891+
return;
1892+
}
1893+
17981894
recordClonedInstruction(
17991895
Inst, getBuilder().createDestructureStruct(
18001896
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand())));
@@ -1804,6 +1900,15 @@ template <typename ImplClass>
18041900
void SILCloner<ImplClass>::visitDestructureTupleInst(
18051901
DestructureTupleInst *Inst) {
18061902
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1903+
if (!getBuilder().hasOwnership()) {
1904+
getBuilder().emitDestructureValueOperation(
1905+
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()),
1906+
[&](unsigned index, SILValue value) {
1907+
recordFoldedValue(Inst->getResults()[index], value);
1908+
});
1909+
return;
1910+
}
1911+
18071912
recordClonedInstruction(
18081913
Inst, getBuilder().createDestructureTuple(
18091914
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand())));
@@ -2104,6 +2209,11 @@ SILCloner<ImplClass>::visitFixLifetimeInst(FixLifetimeInst *Inst) {
21042209
template <typename ImplClass>
21052210
void SILCloner<ImplClass>::visitEndLifetimeInst(EndLifetimeInst *Inst) {
21062211
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
2212+
2213+
// These are only needed in OSSA.
2214+
if (!getBuilder().hasOwnership())
2215+
return;
2216+
21072217
recordClonedInstruction(
21082218
Inst, getBuilder().createEndLifetime(getOpLocation(Inst->getLoc()),
21092219
getOpValue(Inst->getOperand())));
@@ -2113,6 +2223,11 @@ template <typename ImplClass>
21132223
void SILCloner<ImplClass>::visitUncheckedOwnershipConversionInst(
21142224
UncheckedOwnershipConversionInst *Inst) {
21152225
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
2226+
2227+
if (!getBuilder().hasOwnership()) {
2228+
return recordFoldedValue(Inst, getOpValue(Inst->getOperand()));
2229+
}
2230+
21162231
ValueOwnershipKind Kind = SILValue(Inst).getOwnershipKind();
21172232
if (getOpValue(Inst->getOperand()).getOwnershipKind() ==
21182233
ValueOwnershipKind::Any) {

lib/SIL/SILBuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ void SILBuilder::emitDestructureValueOperation(
558558
function_ref<void(unsigned, SILValue)> func) {
559559
// Do a quick check to see if we have a tuple without elements. In that
560560
// case, bail early since we are not going to ever invoke Func.
561-
if (auto tupleType = operand->getType().castTo<TupleType>())
561+
if (auto tupleType = operand->getType().getAs<TupleType>())
562562
if (0 == tupleType->getNumElements())
563563
return;
564564

0 commit comments

Comments
 (0)