@@ -827,3 +827,161 @@ swift::getSingleOwnedValueIntroducer(SILValue inputValue) {
827827
828828 llvm_unreachable (" Should never hit this" );
829829}
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