@@ -827,3 +827,161 @@ swift::getSingleOwnedValueIntroducer(SILValue inputValue) {
827
827
828
828
llvm_unreachable (" Should never hit this" );
829
829
}
830
+
831
+ // ===----------------------------------------------------------------------===//
832
+ // Forwarding Operand
833
+ // ===----------------------------------------------------------------------===//
834
+
835
+ Optional<ForwardingOperand> ForwardingOperand::get (Operand *use) {
836
+ auto *user = use->getUser ();
837
+ if (isa<OwnershipForwardingTermInst>(user))
838
+ return ForwardingOperand (use);
839
+ if (isa<OwnershipForwardingSingleValueInst>(user))
840
+ return ForwardingOperand (use);
841
+ if (isa<OwnershipForwardingConversionInst>(user))
842
+ return ForwardingOperand (use);
843
+ if (isa<OwnershipForwardingSelectEnumInstBase>(user))
844
+ return ForwardingOperand (use);
845
+ if (isa<OwnershipForwardingMultipleValueInstruction>(user))
846
+ return ForwardingOperand (use);
847
+ return None;
848
+ }
849
+
850
+ ValueOwnershipKind ForwardingOperand::getOwnershipKind () const {
851
+ auto *user = use->getUser ();
852
+ if (auto *ofti = dyn_cast<OwnershipForwardingTermInst>(user))
853
+ return ofti->getOwnershipKind ();
854
+ if (auto *ofsvi = dyn_cast<OwnershipForwardingSingleValueInst>(user))
855
+ return ofsvi->getOwnershipKind ();
856
+ if (auto *ofci = dyn_cast<OwnershipForwardingConversionInst>(user))
857
+ return ofci->getOwnershipKind ();
858
+ if (auto *ofseib = dyn_cast<OwnershipForwardingSelectEnumInstBase>(user))
859
+ return ofseib->getOwnershipKind ();
860
+ if (auto *ofmvi = dyn_cast<OwnershipForwardingMultipleValueInstruction>(user))
861
+ return ofmvi->getOwnershipKind ();
862
+ llvm_unreachable (" Out of sync with ForwardingOperand::get?!" );
863
+ }
864
+
865
+ void ForwardingOperand::setOwnershipKind (ValueOwnershipKind newKind) const {
866
+ auto *user = use->getUser ();
867
+ if (auto *ofsvi = dyn_cast<OwnershipForwardingSingleValueInst>(user))
868
+ if (!ofsvi->getType ().isTrivial (*ofsvi->getFunction ()))
869
+ return ofsvi->setOwnershipKind (newKind);
870
+ if (auto *ofci = dyn_cast<OwnershipForwardingConversionInst>(user))
871
+ if (!ofci->getType ().isTrivial (*ofci->getFunction ()))
872
+ return ofci->setOwnershipKind (newKind);
873
+ if (auto *ofseib = dyn_cast<OwnershipForwardingSelectEnumInstBase>(user))
874
+ if (!ofseib->getType ().isTrivial (*ofseib->getFunction ()))
875
+ return ofseib->setOwnershipKind (newKind);
876
+
877
+ if (auto *ofmvi = dyn_cast<OwnershipForwardingMultipleValueInstruction>(user)) {
878
+ assert (ofmvi->getNumOperands () == 1 );
879
+ if (!ofmvi->getOperand (0 )->getType ().isTrivial (*ofmvi->getFunction ())) {
880
+ ofmvi->setOwnershipKind (newKind);
881
+ // TODO: Refactor this better.
882
+ if (auto *dsi = dyn_cast<DestructureStructInst>(ofmvi)) {
883
+ for (auto &result : dsi->getAllResultsBuffer ()) {
884
+ if (result.getType ().isTrivial (*dsi->getFunction ()))
885
+ continue ;
886
+ result.setOwnershipKind (newKind);
887
+ }
888
+ } else {
889
+ auto *dti = cast<DestructureTupleInst>(ofmvi);
890
+ for (auto &result : dti->getAllResultsBuffer ()) {
891
+ if (result.getType ().isTrivial (*dti->getFunction ()))
892
+ continue ;
893
+ result.setOwnershipKind (newKind);
894
+ }
895
+ }
896
+ }
897
+ return ;
898
+ }
899
+
900
+ if (auto *ofti = dyn_cast<OwnershipForwardingTermInst>(user)) {
901
+ assert (ofti->getNumOperands () == 1 );
902
+ if (!ofti->getOperand (0 )->getType ().isTrivial (*ofti->getFunction ())) {
903
+ ofti->setOwnershipKind (newKind);
904
+
905
+ // Then convert all of its incoming values that are owned to be guaranteed.
906
+ for (auto &succ : ofti->getSuccessors ()) {
907
+ auto *succBlock = succ.getBB ();
908
+
909
+ // If we do not have any arguments, then continue.
910
+ if (succBlock->args_empty ())
911
+ continue ;
912
+
913
+ for (auto *succArg : succBlock->getSILPhiArguments ()) {
914
+ // If we have an any value, just continue.
915
+ if (!succArg->getType ().isTrivial (*ofti->getFunction ()))
916
+ continue ;
917
+ succArg->setOwnershipKind (newKind);
918
+ }
919
+ }
920
+ }
921
+ return ;
922
+ }
923
+
924
+ llvm_unreachable (" Out of sync with ForwardingOperand::get?!" );
925
+ }
926
+
927
+ void ForwardingOperand::replaceOwnershipKind (ValueOwnershipKind oldKind,
928
+ ValueOwnershipKind newKind) const {
929
+ auto *user = use->getUser ();
930
+
931
+ if (auto *ofsvi = dyn_cast<OwnershipForwardingSingleValueInst>(user))
932
+ if (ofsvi->getOwnershipKind () == oldKind)
933
+ return ofsvi->setOwnershipKind (newKind);
934
+
935
+ if (auto *ofci = dyn_cast<OwnershipForwardingConversionInst>(user))
936
+ if (ofci->getOwnershipKind () == oldKind)
937
+ return ofci->setOwnershipKind (newKind);
938
+
939
+ if (auto *ofseib = dyn_cast<OwnershipForwardingSelectEnumInstBase>(user))
940
+ if (ofseib->getOwnershipKind () == oldKind)
941
+ return ofseib->setOwnershipKind (newKind);
942
+
943
+ if (auto *ofmvi = dyn_cast<OwnershipForwardingMultipleValueInstruction>(user)) {
944
+ if (ofmvi->getOwnershipKind () == oldKind) {
945
+ ofmvi->setOwnershipKind (newKind);
946
+ }
947
+ // TODO: Refactor this better.
948
+ if (auto *dsi = dyn_cast<DestructureStructInst>(ofmvi)) {
949
+ for (auto &result : dsi->getAllResultsBuffer ()) {
950
+ if (result.getOwnershipKind () != oldKind)
951
+ continue ;
952
+ result.setOwnershipKind (newKind);
953
+ }
954
+ } else {
955
+ auto *dti = cast<DestructureTupleInst>(ofmvi);
956
+ for (auto &result : dti->getAllResultsBuffer ()) {
957
+ if (result.getOwnershipKind () != oldKind)
958
+ continue ;
959
+ result.setOwnershipKind (newKind);
960
+ }
961
+ }
962
+ return ;
963
+ }
964
+
965
+ if (auto *ofti = dyn_cast<OwnershipForwardingTermInst>(user)) {
966
+ if (ofti->getOwnershipKind () == oldKind) {
967
+ ofti->setOwnershipKind (newKind);
968
+ // Then convert all of its incoming values that are owned to be guaranteed.
969
+ for (auto &succ : ofti->getSuccessors ()) {
970
+ auto *succBlock = succ.getBB ();
971
+
972
+ // If we do not have any arguments, then continue.
973
+ if (succBlock->args_empty ())
974
+ continue ;
975
+
976
+ for (auto *succArg : succBlock->getSILPhiArguments ()) {
977
+ // If we have an any value, just continue.
978
+ if (succArg->getOwnershipKind () == oldKind) {
979
+ succArg->setOwnershipKind (newKind);
980
+ }
981
+ }
982
+ }
983
+ }
984
+ return ;
985
+ }
986
+ llvm_unreachable (" Out of sync with ForwardingOperand::get?!" );
987
+ }
0 commit comments