@@ -87,6 +87,20 @@ static SILValue getUnderlyingTrackedValue(SILValue value) {
87
87
return value;
88
88
}
89
89
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
+
90
104
// ===----------------------------------------------------------------------===//
91
105
// MARK: Main Computation
92
106
// ===----------------------------------------------------------------------===//
@@ -475,7 +489,7 @@ class PartitionOpTranslator {
475
489
self->neverConsumedValueIDs .push_back (state->getID ());
476
490
self->argIDs .push_back (state->getID ());
477
491
}
478
- }
492
+ }
479
493
}
480
494
481
495
return argIDs;
@@ -505,7 +519,8 @@ class PartitionOpTranslator {
505
519
// get the results of an apply instruction. This is the single result value
506
520
// for most apply instructions, but for try apply it is the two arguments
507
521
// to each succ block
508
- void getApplyResults (const SILInstruction *inst, SmallVectorImpl<SILValue> &foundResults) {
522
+ void getApplyResults (const SILInstruction *inst,
523
+ SmallVectorImpl<SILValue> &foundResults) {
509
524
if (isa<ApplyInst, BeginApplyInst, BuiltinInst, PartialApplyInst>(inst)) {
510
525
copy (inst->getResults (), std::back_inserter (foundResults));
511
526
return ;
@@ -723,19 +738,19 @@ class PartitionOpTranslator {
723
738
}
724
739
725
740
void translateSILSwitchEnum (SwitchEnumInst *switchEnumInst) {
726
- std::vector<std::pair<std::vector<SILValue>, SILBasicBlock*>> branches ;
741
+ TermArgSources argSources ;
727
742
728
743
// accumulate each switch case that branches to a basic block with an arg
729
744
for (unsigned i = 0 ; i < switchEnumInst->getNumCases (); i++) {
730
745
SILBasicBlock *dest = switchEnumInst->getCase (i).second ;
731
746
if (dest->getNumArguments () > 0 ) {
732
747
assert (dest->getNumArguments () == 1
733
748
&& " expected at most one bb arg in dest of enum switch" );
734
- branches. push_back ({{ switchEnumInst->getOperand ()}, dest} );
749
+ argSources. addValues ({ switchEnumInst->getOperand ()}, dest);
735
750
}
736
751
}
737
752
738
- translateSILPhi (branches );
753
+ translateSILPhi (argSources );
739
754
}
740
755
741
756
// translate a SIL instruction corresponding to possible branches with args
@@ -744,17 +759,9 @@ class PartitionOpTranslator {
744
759
// and a pointer to the bb being branches to itself.
745
760
// this is handled as assigning to each possible arg being branched to the
746
761
// 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 ()) {
758
765
translateSILMultiAssign (TinyPtrVector<SILValue>(pair.first ), pair.second );
759
766
}
760
767
}
@@ -894,9 +901,9 @@ class PartitionOpTranslator {
894
901
case SILInstructionKind::BranchInst: {
895
902
auto *branchInst = cast<BranchInst>(inst);
896
903
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 );
900
907
}
901
908
902
909
case SILInstructionKind::CondBranchInst: {
@@ -905,14 +912,12 @@ class PartitionOpTranslator {
905
912
condBranchInst->getTrueBB ()->getNumArguments ());
906
913
assert (condBranchInst->getNumFalseArgs () ==
907
914
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);
916
921
}
917
922
918
923
case SILInstructionKind::SwitchEnumInst:
@@ -921,22 +926,34 @@ class PartitionOpTranslator {
921
926
case SILInstructionKind::DynamicMethodBranchInst: {
922
927
auto *dmBranchInst = cast<DynamicMethodBranchInst>(inst);
923
928
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);
926
933
}
927
934
928
935
case SILInstructionKind::CheckedCastBranchInst: {
929
936
auto *ccBranchInst = cast<CheckedCastBranchInst>(inst);
930
937
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);
933
942
}
934
943
935
944
case SILInstructionKind::CheckedCastAddrBranchInst: {
936
945
auto *ccAddrBranchInst = cast<CheckedCastAddrBranchInst>(inst);
937
946
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 ());
940
957
}
941
958
942
959
// these instructions are ignored because they cannot affect the partition
0 commit comments