10
10
//
11
11
// ===----------------------------------------------------------------------===//
12
12
13
+ #include " swift/SIL/SILInstruction.h"
13
14
#define DEBUG_TYPE " libsil"
14
15
#include " swift/AST/AnyFunctionRef.h"
15
16
#include " swift/AST/ASTContext.h"
@@ -668,6 +669,26 @@ namespace {
668
669
return B.createLoad (loc, addr, LoadOwnershipQualifier::Unqualified);
669
670
}
670
671
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
+
671
692
void emitDestroyAddress (SILBuilder &B, SILLocation loc,
672
693
SILValue addr) const override {
673
694
// Trivial
@@ -762,6 +783,40 @@ namespace {
762
783
// Otherwise, emit the copy value operation.
763
784
return B.emitCopyValueOperation (loc, loadValue);
764
785
}
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
+ }
765
820
};
766
821
767
822
// / A CRTP helper class for loadable but non-trivial aggregate types.
@@ -802,6 +857,32 @@ namespace {
802
857
forExpansion) {
803
858
}
804
859
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
+
805
886
virtual SILValue rebuildAggregate (SILBuilder &B, SILLocation loc,
806
887
ArrayRef<SILValue> values) const = 0;
807
888
@@ -820,16 +901,12 @@ namespace {
820
901
void forEachNonTrivialChild (SILBuilder &B, SILLocation loc,
821
902
SILValue aggValue,
822
903
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
+ });
833
910
}
834
911
835
912
using SimpleOperationTy = void (TypeLowering::*)(SILBuilder &B,
@@ -839,10 +916,11 @@ namespace {
839
916
SILValue aggValue,
840
917
SimpleOperationTy operation) const {
841
918
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
+ });
846
924
}
847
925
848
926
SILValue emitCopyValue (SILBuilder &B, SILLocation loc,
@@ -860,20 +938,16 @@ namespace {
860
938
return emitCopyValue (B, loc, aggValue);
861
939
}
862
940
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
+ });
877
951
878
952
return rebuildAggregate (B, loc, loweredChildValues);
879
953
}
@@ -911,6 +985,8 @@ namespace {
911
985
// / A lowering for loadable but non-trivial tuple types.
912
986
class LoadableTupleTypeLowering final
913
987
: public LoadableAggTypeLowering<LoadableTupleTypeLowering, unsigned > {
988
+ using Super = LoadableAggTypeLowering<LoadableTupleTypeLowering, unsigned >;
989
+
914
990
public:
915
991
LoadableTupleTypeLowering (CanType type, RecursiveProperties properties,
916
992
TypeExpansionContext forExpansion)
@@ -919,10 +995,35 @@ namespace {
919
995
SILValue emitRValueProject (SILBuilder &B, SILLocation loc,
920
996
SILValue tupleValue, unsigned index,
921
997
const TypeLowering &eltLowering) const {
998
+ assert (!B.hasOwnership () &&
999
+ " Shouldn't call this when ownership is enabled?! Destructure "
1000
+ " non-trivial tuples instead" );
922
1001
return B.createTupleExtract (loc, tupleValue, index,
923
1002
eltLowering.getLoweredType ());
924
1003
}
925
1004
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
+
926
1027
SILValue rebuildAggregate (SILBuilder &B, SILLocation loc,
927
1028
ArrayRef<SILValue> values) const override {
928
1029
return B.createTuple (loc, getLoweredType (), values);
@@ -947,7 +1048,10 @@ namespace {
947
1048
948
1049
// / A lowering for loadable but non-trivial struct types.
949
1050
class LoadableStructTypeLowering final
950
- : public LoadableAggTypeLowering<LoadableStructTypeLowering, VarDecl*> {
1051
+ : public LoadableAggTypeLowering<LoadableStructTypeLowering, VarDecl *> {
1052
+ using Super =
1053
+ LoadableAggTypeLowering<LoadableStructTypeLowering, VarDecl *>;
1054
+
951
1055
public:
952
1056
LoadableStructTypeLowering (CanType type, RecursiveProperties properties,
953
1057
TypeExpansionContext forExpansion)
@@ -960,6 +1064,26 @@ namespace {
960
1064
fieldLowering.getLoweredType ());
961
1065
}
962
1066
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
+
963
1087
SILValue rebuildAggregate (SILBuilder &B, SILLocation loc,
964
1088
ArrayRef<SILValue> values) const override {
965
1089
return B.createStruct (loc, getLoweredType (), values);
@@ -979,7 +1103,7 @@ namespace {
979
1103
}
980
1104
}
981
1105
};
982
-
1106
+
983
1107
// / A lowering for loadable but non-trivial enum types.
984
1108
class LoadableEnumTypeLowering final : public NonTrivialLoadableTypeLowering {
985
1109
public:
@@ -1241,6 +1365,20 @@ namespace {
1241
1365
llvm_unreachable (" calling emitLoad on non-loadable type" );
1242
1366
}
1243
1367
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
+
1244
1382
void emitDestroyAddress (SILBuilder &B, SILLocation loc,
1245
1383
SILValue addr) const override {
1246
1384
if (!isTrivial ())
0 commit comments