Skip to content

Commit cd7213e

Browse files
committed
[send-non-sendable] Eliminate a bunch of temporary heap allocations caused by using std::vector temporaries.
Just making small improvements as I go.
1 parent 42df9c4 commit cd7213e

File tree

1 file changed

+24
-19
lines changed

1 file changed

+24
-19
lines changed

lib/SILOptimizer/Mandatory/SendNonSendable.cpp

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "swift/AST/DiagnosticsSIL.h"
1414
#include "swift/AST/Expr.h"
1515
#include "swift/AST/Type.h"
16+
#include "swift/Basic/FrozenMultiMap.h"
1617
#include "swift/SIL/BasicBlockData.h"
1718
#include "swift/SIL/BasicBlockDatastructures.h"
1819
#include "swift/SIL/MemAccessUtils.h"
@@ -461,8 +462,9 @@ class PartitionOpTranslator {
461462
// require all non-sendable sources, merge their regions, and assign the
462463
// resulting region to all non-sendable targets, or assign non-sendable
463464
// 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) {
466468

467469
std::vector<SILValue> nonSendableSrcs;
468470
std::vector<SILValue> nonSendableTgts;
@@ -514,11 +516,8 @@ class PartitionOpTranslator {
514516
// if this apply does not cross isolation domains, it has normal,
515517
// non-consuming multi-assignment semantics
516518
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());
522521

523522
if (auto cast = dyn_cast<ApplyInst>(applyInst))
524523
return translateIsolationCrossingSILApply(cast);
@@ -592,13 +591,15 @@ class PartitionOpTranslator {
592591
}
593592

594593
std::vector<PartitionOp> translateSILAssign(SILValue tgt, SILValue src) {
595-
return translateSILMultiAssign({tgt}, {src});
594+
return translateSILMultiAssign(TinyPtrVector<SILValue>(tgt),
595+
TinyPtrVector<SILValue>(src));
596596
}
597597

598598
// If the passed SILValue is NonSendable, then create a fresh region for it,
599599
// otherwise do nothing.
600600
std::vector<PartitionOp> translateSILAssignFresh(SILValue val) {
601-
return translateSILMultiAssign({val}, {});
601+
return translateSILMultiAssign(TinyPtrVector<SILValue>(val),
602+
TinyPtrVector<SILValue>());
602603
}
603604

604605
std::vector<PartitionOp> translateSILMerge(SILValue fst, SILValue snd) {
@@ -644,7 +645,8 @@ class PartitionOpTranslator {
644645
enumOperands.push_back(selectEnumInst.getCase(i).second);
645646
if (selectEnumInst.hasDefault())
646647
enumOperands.push_back(selectEnumInst.getDefaultResult());
647-
return translateSILMultiAssign({selectEnumInst->getResult(0)}, enumOperands);
648+
return translateSILMultiAssign(
649+
TinyPtrVector<SILValue>(selectEnumInst->getResult(0)), enumOperands);
648650
}
649651

650652
std::vector<PartitionOp> translateSILSwitchEnum(
@@ -671,16 +673,20 @@ class PartitionOpTranslator {
671673
// merge of all values that could be passed to it from this basic block.
672674
std::vector<PartitionOp> translateSILPhi(
673675
std::vector<std::pair<std::vector<SILValue>, SILBasicBlock*>> branches) {
674-
std::map<SILValue, std::vector<SILValue>> argSources;
676+
SmallFrozenMultiMap<SILValue, SILValue, 8> argSources;
675677
for (const auto &[args, dest] : branches) {
676678
assert(args.size() >= dest->getNumArguments());
677679
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]);
679681
}
682+
argSources.setFrozen();
680683
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)) {
683687
translated.push_back(op);
688+
}
689+
}
684690
return translated;
685691
}
686692

@@ -800,9 +806,8 @@ class PartitionOpTranslator {
800806
// handle tuple destruction
801807
auto *destructTupleInst = cast<DestructureTupleInst>(inst);
802808
return translateSILMultiAssign(
803-
{destructTupleInst->getResults().begin(),
804-
destructTupleInst->getResults().end()},
805-
{destructTupleInst->getOperand()});
809+
destructTupleInst->getResults(),
810+
TinyPtrVector<SILValue>(destructTupleInst->getOperand()));
806811
}
807812

808813
// handle instructions that aggregate their operands into a single structure
@@ -811,8 +816,8 @@ class PartitionOpTranslator {
811816
case SILInstructionKind::StructInst:
812817
case SILInstructionKind::TupleInst:
813818
return translateSILMultiAssign(
814-
{inst->getResult(0)},
815-
{inst->getOperandValues().begin(), inst->getOperandValues().end()});
819+
TinyPtrVector<SILValue>(inst->getResult(0)),
820+
inst->getOperandValues());
816821

817822
// Handle returns and throws - require the operand to be non-consumed
818823
case SILInstructionKind::ReturnInst:

0 commit comments

Comments
 (0)