13
13
#include " swift/AST/DiagnosticsSIL.h"
14
14
#include " swift/AST/Expr.h"
15
15
#include " swift/AST/Type.h"
16
+ #include " swift/Basic/FrozenMultiMap.h"
16
17
#include " swift/SIL/BasicBlockData.h"
17
18
#include " swift/SIL/BasicBlockDatastructures.h"
18
19
#include " swift/SIL/MemAccessUtils.h"
@@ -461,8 +462,9 @@ class PartitionOpTranslator {
461
462
// require all non-sendable sources, merge their regions, and assign the
462
463
// resulting region to all non-sendable targets, or assign non-sendable
463
464
// targets to a fresh region if there are no non-sendable sources
464
- std::vector<PartitionOp> translateSILMultiAssign (
465
- std::vector<SILValue> tgts, std::vector<SILValue> srcs) {
465
+ template <typename TargetRange, typename SourceRange>
466
+ std::vector<PartitionOp> translateSILMultiAssign (const TargetRange &tgts,
467
+ const SourceRange &srcs) {
466
468
467
469
std::vector<SILValue> nonSendableSrcs;
468
470
std::vector<SILValue> nonSendableTgts;
@@ -514,11 +516,8 @@ class PartitionOpTranslator {
514
516
// if this apply does not cross isolation domains, it has normal,
515
517
// non-consuming multi-assignment semantics
516
518
if (!SILApplyCrossesIsolation (applyInst))
517
- return translateSILMultiAssign (
518
- getApplyResults (applyInst),
519
- {applyInst->getOperandValues ().begin (),
520
- applyInst->getOperandValues ().end ()}
521
- );
519
+ return translateSILMultiAssign (getApplyResults (applyInst),
520
+ applyInst->getOperandValues ());
522
521
523
522
if (auto cast = dyn_cast<ApplyInst>(applyInst))
524
523
return translateIsolationCrossingSILApply (cast);
@@ -592,13 +591,15 @@ class PartitionOpTranslator {
592
591
}
593
592
594
593
std::vector<PartitionOp> translateSILAssign (SILValue tgt, SILValue src) {
595
- return translateSILMultiAssign ({tgt}, {src});
594
+ return translateSILMultiAssign (TinyPtrVector<SILValue>(tgt),
595
+ TinyPtrVector<SILValue>(src));
596
596
}
597
597
598
598
// If the passed SILValue is NonSendable, then create a fresh region for it,
599
599
// otherwise do nothing.
600
600
std::vector<PartitionOp> translateSILAssignFresh (SILValue val) {
601
- return translateSILMultiAssign ({val}, {});
601
+ return translateSILMultiAssign (TinyPtrVector<SILValue>(val),
602
+ TinyPtrVector<SILValue>());
602
603
}
603
604
604
605
std::vector<PartitionOp> translateSILMerge (SILValue fst, SILValue snd) {
@@ -644,7 +645,8 @@ class PartitionOpTranslator {
644
645
enumOperands.push_back (selectEnumInst.getCase (i).second );
645
646
if (selectEnumInst.hasDefault ())
646
647
enumOperands.push_back (selectEnumInst.getDefaultResult ());
647
- return translateSILMultiAssign ({selectEnumInst->getResult (0 )}, enumOperands);
648
+ return translateSILMultiAssign (
649
+ TinyPtrVector<SILValue>(selectEnumInst->getResult (0 )), enumOperands);
648
650
}
649
651
650
652
std::vector<PartitionOp> translateSILSwitchEnum (
@@ -671,16 +673,20 @@ class PartitionOpTranslator {
671
673
// merge of all values that could be passed to it from this basic block.
672
674
std::vector<PartitionOp> translateSILPhi (
673
675
std::vector<std::pair<std::vector<SILValue>, SILBasicBlock*>> branches) {
674
- std::map <SILValue, std::vector< SILValue> > argSources;
676
+ SmallFrozenMultiMap <SILValue, SILValue, 8 > argSources;
675
677
for (const auto &[args, dest] : branches) {
676
678
assert (args.size () >= dest->getNumArguments ());
677
679
for (unsigned i = 0 ; i < dest->getNumArguments (); i++)
678
- argSources[ dest->getArgument (i)]. push_back ( args[i]);
680
+ argSources. insert ( dest->getArgument (i), args[i]);
679
681
}
682
+ argSources.setFrozen ();
680
683
std::vector<PartitionOp> translated;
681
- for (const auto &[arg, srcs] : argSources)
682
- for (auto op : translateSILMultiAssign ({arg}, srcs))
684
+ for (auto pair : argSources.getRange ()) {
685
+ for (auto op : translateSILMultiAssign (
686
+ TinyPtrVector<SILValue>(pair.first ), pair.second )) {
683
687
translated.push_back (op);
688
+ }
689
+ }
684
690
return translated;
685
691
}
686
692
@@ -800,9 +806,8 @@ class PartitionOpTranslator {
800
806
// handle tuple destruction
801
807
auto *destructTupleInst = cast<DestructureTupleInst>(inst);
802
808
return translateSILMultiAssign (
803
- {destructTupleInst->getResults ().begin (),
804
- destructTupleInst->getResults ().end ()},
805
- {destructTupleInst->getOperand ()});
809
+ destructTupleInst->getResults (),
810
+ TinyPtrVector<SILValue>(destructTupleInst->getOperand ()));
806
811
}
807
812
808
813
// handle instructions that aggregate their operands into a single structure
@@ -811,8 +816,8 @@ class PartitionOpTranslator {
811
816
case SILInstructionKind::StructInst:
812
817
case SILInstructionKind::TupleInst:
813
818
return translateSILMultiAssign (
814
- { inst->getResult (0 )} ,
815
- { inst->getOperandValues (). begin (), inst-> getOperandValues (). end ()} );
819
+ TinyPtrVector<SILValue>( inst->getResult (0 )) ,
820
+ inst->getOperandValues ());
816
821
817
822
// Handle returns and throws - require the operand to be non-consumed
818
823
case SILInstructionKind::ReturnInst:
0 commit comments