Skip to content

Commit c6ebea4

Browse files
committed
[sil] Define emitLowered{Load,Store} in type lowering and expose emitLowered{Copy,Load,Destroy,Store}Value on SILBuilder via emit*Operation methods.
This is in preparation for fixing lower aggregate instrs. These helpers allow for one to pass down a type expansion qualifier for emitLowered{Load,Store} to use when emitting lowered copy, destroys as part of emitting aggregate operations in non-ossa like load [copy].
1 parent 6714cef commit c6ebea4

File tree

3 files changed

+233
-30
lines changed

3 files changed

+233
-30
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,27 @@ class SILBuilder {
725725
return lowering.emitLoad(*this, Loc, LV, Qualifier);
726726
}
727727

728+
/// Convenience function for calling emitLoad on the type lowering for
729+
/// non-address values.
730+
SILValue emitLoweredLoadValueOperation(
731+
SILLocation Loc, SILValue LV, LoadOwnershipQualifier Qualifier,
732+
Lowering::TypeLowering::TypeExpansionKind ExpansionKind) {
733+
assert(isLoadableOrOpaque(LV->getType()));
734+
const auto &lowering = getTypeLowering(LV->getType());
735+
return lowering.emitLoweredLoad(*this, Loc, LV, Qualifier, ExpansionKind);
736+
}
737+
738+
/// Convenience function for calling emitLoweredStore on the type lowering for
739+
/// non-address values.
740+
void emitLoweredStoreValueOperation(
741+
SILLocation Loc, SILValue Value, SILValue Addr,
742+
StoreOwnershipQualifier Qual,
743+
Lowering::TypeLowering::TypeExpansionKind ExpansionKind) {
744+
assert(isLoadableOrOpaque(Value->getType()));
745+
const auto &lowering = getTypeLowering(Value->getType());
746+
lowering.emitLoweredStore(*this, Loc, Value, Addr, Qual, ExpansionKind);
747+
}
748+
728749
LoadBorrowInst *createLoadBorrow(SILLocation Loc, SILValue LV) {
729750
assert(isLoadableOrOpaque(LV->getType()) &&
730751
!LV->getType().isTrivial(getFunction()));
@@ -2186,6 +2207,16 @@ class SILBuilder {
21862207
return lowering.emitCopyValue(*this, Loc, v);
21872208
}
21882209

2210+
/// Convenience function for calling emitCopy on the type lowering
2211+
/// for the non-address value.
2212+
SILValue emitLoweredCopyValueOperation(
2213+
SILLocation Loc, SILValue v,
2214+
Lowering::TypeLowering::TypeExpansionKind expansionKind) {
2215+
assert(!v->getType().isAddress());
2216+
auto &lowering = getTypeLowering(v->getType());
2217+
return lowering.emitLoweredCopyValue(*this, Loc, v, expansionKind);
2218+
}
2219+
21892220
/// Convenience function for calling TypeLowering.emitDestroy on the type
21902221
/// lowering for the non-address value.
21912222
void emitDestroyValueOperation(SILLocation Loc, SILValue v) {
@@ -2196,6 +2227,18 @@ class SILBuilder {
21962227
lowering.emitDestroyValue(*this, Loc, v);
21972228
}
21982229

2230+
/// Convenience function for calling TypeLowering.emitDestroy on the type
2231+
/// lowering for the non-address value.
2232+
void emitLoweredDestroyValueOperation(
2233+
SILLocation Loc, SILValue v,
2234+
Lowering::TypeLowering::TypeExpansionKind expansionKind) {
2235+
assert(!v->getType().isAddress());
2236+
if (F->hasOwnership() && v.getOwnershipKind() == ValueOwnershipKind::None)
2237+
return;
2238+
auto &lowering = getTypeLowering(v->getType());
2239+
lowering.emitLoweredDestroyValue(*this, Loc, v, expansionKind);
2240+
}
2241+
21992242
/// Convenience function for destroying objects and addresses.
22002243
///
22012244
/// Objects are destroyed using emitDestroyValueOperation and addresses by

include/swift/SIL/TypeLowering.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,28 @@ class TypeLowering {
390390
///> types.
391391
};
392392

393+
/// Emit a load from \p addr given the LoadOwnershipQualifier \p qual.
394+
///
395+
/// This abstracts over the differences in between trivial and non-trivial
396+
/// types and lets one specify an expansion kind that gets passed to any
397+
/// copy_value that we create.
398+
virtual SILValue emitLoweredLoad(
399+
SILBuilder &B, SILLocation loc, SILValue addr,
400+
LoadOwnershipQualifier qual,
401+
Lowering::TypeLowering::TypeExpansionKind expansionKind) const = 0;
402+
403+
/// Emit a store of \p value into \p addr given the StoreOwnershipQualifier
404+
/// qual.
405+
///
406+
/// This abstracts over the differences in between trivial and non-trivial
407+
/// types and allows for one to specify an expansion kind that is passed to
408+
/// any destroy operations we create if we are asked to assign in non-ossa
409+
/// code.
410+
virtual void emitLoweredStore(
411+
SILBuilder &B, SILLocation loc, SILValue value, SILValue addr,
412+
StoreOwnershipQualifier qual,
413+
Lowering::TypeLowering::TypeExpansionKind expansionKind) const = 0;
414+
393415
//===--------------------------------------------------------------------===//
394416
// DestroyValue
395417
//===--------------------------------------------------------------------===//

lib/SIL/IR/TypeLowering.cpp

Lines changed: 168 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "swift/SIL/SILInstruction.h"
1314
#define DEBUG_TYPE "libsil"
1415
#include "swift/AST/AnyFunctionRef.h"
1516
#include "swift/AST/ASTContext.h"
@@ -668,6 +669,26 @@ namespace {
668669
return B.createLoad(loc, addr, LoadOwnershipQualifier::Unqualified);
669670
}
670671

672+
SILValue emitLoweredLoad(SILBuilder &B, SILLocation loc, SILValue addr,
673+
LoadOwnershipQualifier qual,
674+
TypeExpansionKind) const override {
675+
if (B.getFunction().hasOwnership())
676+
return B.createLoad(loc, addr, LoadOwnershipQualifier::Trivial);
677+
return B.createLoad(loc, addr, LoadOwnershipQualifier::Unqualified);
678+
}
679+
680+
void emitLoweredStore(SILBuilder &B, SILLocation loc, SILValue value,
681+
SILValue addr, StoreOwnershipQualifier qual,
682+
Lowering::TypeLowering::TypeExpansionKind
683+
expansionKind) const override {
684+
auto storeQual = [&]() -> StoreOwnershipQualifier {
685+
if (B.getFunction().hasOwnership())
686+
return StoreOwnershipQualifier::Trivial;
687+
return StoreOwnershipQualifier::Unqualified;
688+
}();
689+
B.createStore(loc, value, addr, storeQual);
690+
}
691+
671692
void emitDestroyAddress(SILBuilder &B, SILLocation loc,
672693
SILValue addr) const override {
673694
// Trivial
@@ -762,6 +783,40 @@ namespace {
762783
// Otherwise, emit the copy value operation.
763784
return B.emitCopyValueOperation(loc, loadValue);
764785
}
786+
787+
SILValue emitLoweredLoad(SILBuilder &B, SILLocation loc, SILValue addr,
788+
LoadOwnershipQualifier qual,
789+
TypeExpansionKind expansionKind) const override {
790+
if (B.getFunction().hasOwnership())
791+
return B.createLoad(loc, addr, qual);
792+
793+
SILValue loadValue =
794+
B.createLoad(loc, addr, LoadOwnershipQualifier::Unqualified);
795+
796+
// If we do not have a copy, just return the value...
797+
if (qual != LoadOwnershipQualifier::Copy)
798+
return loadValue;
799+
800+
// Otherwise, emit the copy value operation.
801+
return B.emitLoweredCopyValueOperation(loc, loadValue, expansionKind);
802+
}
803+
804+
void emitLoweredStore(SILBuilder &B, SILLocation loc, SILValue value,
805+
SILValue addr, StoreOwnershipQualifier qual,
806+
Lowering::TypeLowering::TypeExpansionKind
807+
expansionKind) const override {
808+
if (B.getFunction().hasOwnership()) {
809+
B.createStore(loc, value, addr, qual);
810+
return;
811+
}
812+
813+
if (qual == StoreOwnershipQualifier::Assign) {
814+
SILValue oldValue = B.emitLoadValueOperation(
815+
loc, addr, LoadOwnershipQualifier::Unqualified);
816+
B.emitLoweredDestroyValueOperation(loc, oldValue, expansionKind);
817+
}
818+
B.createStore(loc, value, addr, StoreOwnershipQualifier::Unqualified);
819+
}
765820
};
766821

767822
/// A CRTP helper class for loadable but non-trivial aggregate types.
@@ -802,6 +857,32 @@ namespace {
802857
forExpansion) {
803858
}
804859

860+
/// CRTP Default implementation of destructuring an aggregate value.
861+
///
862+
/// Uses getChildren() and emitRValueProject() to create projections for
863+
/// each child. Subclasses should override this to customize on how
864+
/// destructuring is done.
865+
///
866+
/// NOTE: Due to the CRTP, this must always be called as
867+
/// asImpl().destructureAggregate() to ensure that one gets the proper
868+
/// implementation!
869+
void destructureAggregate(
870+
SILBuilder &B, SILLocation loc, SILValue aggValue, bool skipTrivial,
871+
function_ref<void(unsigned, SILValue, const TypeLowering &)> visitor)
872+
const {
873+
for (auto pair : llvm::enumerate(getChildren(B.getModule().Types))) {
874+
auto &child = pair.value();
875+
auto &childLowering = child.getLowering();
876+
// Skip trivial children.
877+
if (skipTrivial && childLowering.isTrivial())
878+
continue;
879+
auto childIndex = child.getIndex();
880+
auto childValue = asImpl().emitRValueProject(B, loc, aggValue,
881+
childIndex, childLowering);
882+
visitor(pair.index(), childValue, childLowering);
883+
}
884+
}
885+
805886
virtual SILValue rebuildAggregate(SILBuilder &B, SILLocation loc,
806887
ArrayRef<SILValue> values) const = 0;
807888

@@ -820,16 +901,12 @@ namespace {
820901
void forEachNonTrivialChild(SILBuilder &B, SILLocation loc,
821902
SILValue aggValue,
822903
const T &operation) const {
823-
for (auto &child : getChildren(B.getModule().Types)) {
824-
auto &childLowering = child.getLowering();
825-
// Skip trivial children.
826-
if (childLowering.isTrivial())
827-
continue;
828-
auto childIndex = child.getIndex();
829-
auto childValue = asImpl().emitRValueProject(B, loc, aggValue,
830-
childIndex, childLowering);
831-
operation(B, loc, childIndex, childValue, childLowering);
832-
}
904+
asImpl().destructureAggregate(B, loc, aggValue, true /*skipTrivial*/,
905+
[&](unsigned, SILValue childValue,
906+
const TypeLowering &childLowering) {
907+
operation(B, loc, childValue,
908+
childLowering);
909+
});
833910
}
834911

835912
using SimpleOperationTy = void (TypeLowering::*)(SILBuilder &B,
@@ -839,10 +916,11 @@ namespace {
839916
SILValue aggValue,
840917
SimpleOperationTy operation) const {
841918
forEachNonTrivialChild(B, loc, aggValue,
842-
[operation](SILBuilder &B, SILLocation loc, IndexType index,
843-
SILValue childValue, const TypeLowering &childLowering) {
844-
(childLowering.*operation)(B, loc, childValue);
845-
});
919+
[operation](SILBuilder &B, SILLocation loc,
920+
SILValue childValue,
921+
const TypeLowering &childLowering) {
922+
(childLowering.*operation)(B, loc, childValue);
923+
});
846924
}
847925

848926
SILValue emitCopyValue(SILBuilder &B, SILLocation loc,
@@ -860,20 +938,16 @@ namespace {
860938
return emitCopyValue(B, loc, aggValue);
861939
}
862940

863-
llvm::SmallVector<SILValue, 8> loweredChildValues;
864-
for (auto &child : getChildren(B.getModule().Types)) {
865-
auto &childLowering = child.getLowering();
866-
SILValue childValue = asImpl().emitRValueProject(B, loc, aggValue,
867-
child.getIndex(),
868-
childLowering);
869-
if (!childLowering.isTrivial()) {
870-
SILValue loweredChildValue = childLowering.emitLoweredCopyChildValue(
871-
B, loc, childValue, style);
872-
loweredChildValues.push_back(loweredChildValue);
873-
} else {
874-
loweredChildValues.push_back(childValue);
875-
}
876-
}
941+
SmallVector<SILValue, 8> loweredChildValues;
942+
asImpl().destructureAggregate(
943+
B, loc, aggValue, false /*skipTrivial*/,
944+
[&](unsigned childIndex, SILValue childValue,
945+
const TypeLowering &childLowering) {
946+
if (!childLowering.isTrivial())
947+
childValue = childLowering.emitLoweredCopyChildValue(
948+
B, loc, childValue, style);
949+
loweredChildValues.push_back(childValue);
950+
});
877951

878952
return rebuildAggregate(B, loc, loweredChildValues);
879953
}
@@ -911,6 +985,8 @@ namespace {
911985
/// A lowering for loadable but non-trivial tuple types.
912986
class LoadableTupleTypeLowering final
913987
: public LoadableAggTypeLowering<LoadableTupleTypeLowering, unsigned> {
988+
using Super = LoadableAggTypeLowering<LoadableTupleTypeLowering, unsigned>;
989+
914990
public:
915991
LoadableTupleTypeLowering(CanType type, RecursiveProperties properties,
916992
TypeExpansionContext forExpansion)
@@ -919,10 +995,35 @@ namespace {
919995
SILValue emitRValueProject(SILBuilder &B, SILLocation loc,
920996
SILValue tupleValue, unsigned index,
921997
const TypeLowering &eltLowering) const {
998+
assert(!B.hasOwnership() &&
999+
"Shouldn't call this when ownership is enabled?! Destructure "
1000+
"non-trivial tuples instead");
9221001
return B.createTupleExtract(loc, tupleValue, index,
9231002
eltLowering.getLoweredType());
9241003
}
9251004

1005+
void destructureAggregate(
1006+
SILBuilder &B, SILLocation loc, SILValue aggValue, bool skipTrivial,
1007+
function_ref<void(unsigned childIndex, SILValue childValue,
1008+
const TypeLowering &childLowering)>
1009+
visitor) const {
1010+
// Without ownership, use our parent.
1011+
if (!B.hasOwnership())
1012+
return Super::destructureAggregate(B, loc, aggValue, skipTrivial,
1013+
visitor);
1014+
1015+
// Otherwise, emit a destructure tuple and do the loop.
1016+
auto *dti = B.createDestructureTuple(loc, aggValue);
1017+
for (auto pair : llvm::enumerate(dti->getResults())) {
1018+
SILValue childValue = pair.value();
1019+
auto &childLowering =
1020+
B.getFunction().getTypeLowering(childValue->getType());
1021+
if (skipTrivial && childLowering.isTrivial())
1022+
continue;
1023+
visitor(pair.index(), childValue, childLowering);
1024+
}
1025+
}
1026+
9261027
SILValue rebuildAggregate(SILBuilder &B, SILLocation loc,
9271028
ArrayRef<SILValue> values) const override {
9281029
return B.createTuple(loc, getLoweredType(), values);
@@ -947,7 +1048,10 @@ namespace {
9471048

9481049
/// A lowering for loadable but non-trivial struct types.
9491050
class LoadableStructTypeLowering final
950-
: public LoadableAggTypeLowering<LoadableStructTypeLowering, VarDecl*> {
1051+
: public LoadableAggTypeLowering<LoadableStructTypeLowering, VarDecl *> {
1052+
using Super =
1053+
LoadableAggTypeLowering<LoadableStructTypeLowering, VarDecl *>;
1054+
9511055
public:
9521056
LoadableStructTypeLowering(CanType type, RecursiveProperties properties,
9531057
TypeExpansionContext forExpansion)
@@ -960,6 +1064,26 @@ namespace {
9601064
fieldLowering.getLoweredType());
9611065
}
9621066

1067+
void destructureAggregate(
1068+
SILBuilder &B, SILLocation loc, SILValue aggValue, bool skipTrivial,
1069+
function_ref<void(unsigned childIndex, SILValue childValue,
1070+
const TypeLowering &childLowering)>
1071+
visitor) const {
1072+
if (!B.hasOwnership())
1073+
return Super::destructureAggregate(B, loc, aggValue, skipTrivial,
1074+
visitor);
1075+
1076+
auto *dsi = B.createDestructureStruct(loc, aggValue);
1077+
for (auto pair : llvm::enumerate(dsi->getResults())) {
1078+
SILValue childValue = pair.value();
1079+
auto &childLowering =
1080+
B.getFunction().getTypeLowering(childValue->getType());
1081+
if (skipTrivial && childLowering.isTrivial())
1082+
continue;
1083+
visitor(pair.index(), childValue, childLowering);
1084+
}
1085+
}
1086+
9631087
SILValue rebuildAggregate(SILBuilder &B, SILLocation loc,
9641088
ArrayRef<SILValue> values) const override {
9651089
return B.createStruct(loc, getLoweredType(), values);
@@ -979,7 +1103,7 @@ namespace {
9791103
}
9801104
}
9811105
};
982-
1106+
9831107
/// A lowering for loadable but non-trivial enum types.
9841108
class LoadableEnumTypeLowering final : public NonTrivialLoadableTypeLowering {
9851109
public:
@@ -1241,6 +1365,20 @@ namespace {
12411365
llvm_unreachable("calling emitLoad on non-loadable type");
12421366
}
12431367

1368+
SILValue emitLoweredLoad(SILBuilder &B, SILLocation loc, SILValue addr,
1369+
LoadOwnershipQualifier qual,
1370+
Lowering::TypeLowering::TypeExpansionKind
1371+
expansionKind) const override {
1372+
llvm_unreachable("calling emitLoweredLoad on non-loadable type?!");
1373+
}
1374+
1375+
void emitLoweredStore(SILBuilder &B, SILLocation loc, SILValue value,
1376+
SILValue addr, StoreOwnershipQualifier qual,
1377+
Lowering::TypeLowering::TypeExpansionKind
1378+
expansionKind) const override {
1379+
llvm_unreachable("calling emitLoweredStore on non-loadable type?!");
1380+
}
1381+
12441382
void emitDestroyAddress(SILBuilder &B, SILLocation loc,
12451383
SILValue addr) const override {
12461384
if (!isTrivial())

0 commit comments

Comments
 (0)