Skip to content

Commit a9e8baa

Browse files
committed
[isolation-regions] Eliminate last temporary std::vector usage from the non-error path.
1 parent 63db040 commit a9e8baa

File tree

1 file changed

+50
-33
lines changed

1 file changed

+50
-33
lines changed

lib/SILOptimizer/Mandatory/SendNonSendable.cpp

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,20 @@ static SILValue getUnderlyingTrackedValue(SILValue value) {
8787
return value;
8888
}
8989

90+
namespace {
91+
92+
struct TermArgSources {
93+
SmallFrozenMultiMap<SILValue, SILValue, 8> argSources;
94+
95+
template <typename ValueRangeTy = ArrayRef<SILValue>>
96+
void addValues(ValueRangeTy valueRange, SILBasicBlock *destBlock) {
97+
for (auto pair : llvm::enumerate(valueRange))
98+
argSources.insert(destBlock->getArgument(pair.index()), pair.value());
99+
}
100+
};
101+
102+
} // namespace
103+
90104
//===----------------------------------------------------------------------===//
91105
// MARK: Main Computation
92106
//===----------------------------------------------------------------------===//
@@ -475,7 +489,7 @@ class PartitionOpTranslator {
475489
self->neverConsumedValueIDs.push_back(state->getID());
476490
self->argIDs.push_back(state->getID());
477491
}
478-
}
492+
}
479493
}
480494

481495
return argIDs;
@@ -505,7 +519,8 @@ class PartitionOpTranslator {
505519
// get the results of an apply instruction. This is the single result value
506520
// for most apply instructions, but for try apply it is the two arguments
507521
// to each succ block
508-
void getApplyResults(const SILInstruction *inst, SmallVectorImpl<SILValue> &foundResults) {
522+
void getApplyResults(const SILInstruction *inst,
523+
SmallVectorImpl<SILValue> &foundResults) {
509524
if (isa<ApplyInst, BeginApplyInst, BuiltinInst, PartialApplyInst>(inst)) {
510525
copy(inst->getResults(), std::back_inserter(foundResults));
511526
return;
@@ -723,19 +738,19 @@ class PartitionOpTranslator {
723738
}
724739

725740
void translateSILSwitchEnum(SwitchEnumInst *switchEnumInst) {
726-
std::vector<std::pair<std::vector<SILValue>, SILBasicBlock*>> branches;
741+
TermArgSources argSources;
727742

728743
// accumulate each switch case that branches to a basic block with an arg
729744
for (unsigned i = 0; i < switchEnumInst->getNumCases(); i++) {
730745
SILBasicBlock *dest = switchEnumInst->getCase(i).second;
731746
if (dest->getNumArguments() > 0) {
732747
assert(dest->getNumArguments() == 1
733748
&& "expected at most one bb arg in dest of enum switch");
734-
branches.push_back({{switchEnumInst->getOperand()}, dest});
749+
argSources.addValues({switchEnumInst->getOperand()}, dest);
735750
}
736751
}
737752

738-
translateSILPhi(branches);
753+
translateSILPhi(argSources);
739754
}
740755

741756
// translate a SIL instruction corresponding to possible branches with args
@@ -744,17 +759,9 @@ class PartitionOpTranslator {
744759
// and a pointer to the bb being branches to itself.
745760
// this is handled as assigning to each possible arg being branched to the
746761
// merge of all values that could be passed to it from this basic block.
747-
void translateSILPhi(
748-
const std::vector<std::pair<std::vector<SILValue>, SILBasicBlock *>>
749-
&branches) {
750-
SmallFrozenMultiMap<SILValue, SILValue, 8> argSources;
751-
for (const auto &[args, dest] : branches) {
752-
assert(args.size() >= dest->getNumArguments());
753-
for (unsigned i = 0; i < dest->getNumArguments(); i++)
754-
argSources.insert(dest->getArgument(i), args[i]);
755-
}
756-
argSources.setFrozen();
757-
for (auto pair : argSources.getRange()) {
762+
void translateSILPhi(TermArgSources &argSources) {
763+
argSources.argSources.setFrozen();
764+
for (auto pair : argSources.argSources.getRange()) {
758765
translateSILMultiAssign(TinyPtrVector<SILValue>(pair.first), pair.second);
759766
}
760767
}
@@ -894,9 +901,9 @@ class PartitionOpTranslator {
894901
case SILInstructionKind::BranchInst: {
895902
auto *branchInst = cast<BranchInst>(inst);
896903
assert(branchInst->getNumArgs() == branchInst->getDestBB()->getNumArguments());
897-
return translateSILPhi(
898-
{{{branchInst->getArgs().begin(), branchInst->getArgs().end()},
899-
branchInst->getDestBB()}});
904+
TermArgSources argSources;
905+
argSources.addValues(branchInst->getArgs(), branchInst->getDestBB());
906+
return translateSILPhi(argSources);
900907
}
901908

902909
case SILInstructionKind::CondBranchInst: {
@@ -905,14 +912,12 @@ class PartitionOpTranslator {
905912
condBranchInst->getTrueBB()->getNumArguments());
906913
assert(condBranchInst->getNumFalseArgs() ==
907914
condBranchInst->getFalseBB()->getNumArguments());
908-
return translateSILPhi({{// true branch
909-
{condBranchInst->getTrueArgs().begin(),
910-
condBranchInst->getTrueArgs().end()},
911-
condBranchInst->getTrueBB()},
912-
{// false branch
913-
{condBranchInst->getFalseArgs().begin(),
914-
condBranchInst->getFalseArgs().end()},
915-
condBranchInst->getFalseBB()}});
915+
TermArgSources argSources;
916+
argSources.addValues(condBranchInst->getTrueArgs(),
917+
condBranchInst->getTrueBB());
918+
argSources.addValues(condBranchInst->getFalseArgs(),
919+
condBranchInst->getFalseBB());
920+
return translateSILPhi(argSources);
916921
}
917922

918923
case SILInstructionKind::SwitchEnumInst:
@@ -921,22 +926,34 @@ class PartitionOpTranslator {
921926
case SILInstructionKind::DynamicMethodBranchInst: {
922927
auto *dmBranchInst = cast<DynamicMethodBranchInst>(inst);
923928
assert(dmBranchInst->getHasMethodBB()->getNumArguments() <= 1);
924-
return translateSILPhi(
925-
{{{dmBranchInst->getOperand()}, dmBranchInst->getHasMethodBB()}});
929+
TermArgSources argSources;
930+
argSources.addValues({dmBranchInst->getOperand()},
931+
dmBranchInst->getHasMethodBB());
932+
return translateSILPhi(argSources);
926933
}
927934

928935
case SILInstructionKind::CheckedCastBranchInst: {
929936
auto *ccBranchInst = cast<CheckedCastBranchInst>(inst);
930937
assert(ccBranchInst->getSuccessBB()->getNumArguments() <= 1);
931-
return translateSILPhi(
932-
{{{ccBranchInst->getOperand()}, ccBranchInst->getSuccessBB()}});
938+
TermArgSources argSources;
939+
argSources.addValues({ccBranchInst->getOperand()},
940+
ccBranchInst->getSuccessBB());
941+
return translateSILPhi(argSources);
933942
}
934943

935944
case SILInstructionKind::CheckedCastAddrBranchInst: {
936945
auto *ccAddrBranchInst = cast<CheckedCastAddrBranchInst>(inst);
937946
assert(ccAddrBranchInst->getSuccessBB()->getNumArguments() <= 1);
938-
return translateSILPhi({{{ccAddrBranchInst->getOperand(0)},
939-
ccAddrBranchInst->getSuccessBB()}});
947+
948+
// checked_cast_addr_br does not have any arguments in its resulting
949+
// block. We should just use a multi-assign on its operands.
950+
//
951+
// TODO: We should be smarter and treat the success/fail branches
952+
// differently depending on what the result of checked_cast_addr_br
953+
// is. For now just keep the current behavior. It is more conservative,
954+
// but still correct.
955+
return translateSILMultiAssign(ArrayRef<SILValue>(),
956+
ccAddrBranchInst->getOperandValues());
940957
}
941958

942959
// these instructions are ignored because they cannot affect the partition

0 commit comments

Comments
 (0)