Skip to content

Commit 336ed71

Browse files
committed
[send-non-sendable] Convert SILInstruction translation to use an exhaustive switch.
This ensures that we actually handle all instructions. I already found that we are not handling ~106 cases... but to make this just a refactoring patch, I just put in a default + a break + left in the error. rdar://115367810
1 parent a1daf81 commit 336ed71

File tree

1 file changed

+149
-131
lines changed

1 file changed

+149
-131
lines changed

lib/SILOptimizer/Mandatory/SendNonSendable.cpp

Lines changed: 149 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -695,130 +695,142 @@ class PartitionOpTranslator {
695695
// to its effect on the non-Sendable partition, if it has one.
696696
//
697697
// The current pattern of
698-
std::vector<PartitionOp> translateSILInstruction(SILInstruction *instruction) {
698+
std::vector<PartitionOp> translateSILInstruction(SILInstruction *inst) {
699699
LLVM_DEBUG(translationIndex++;);
700-
currentInstruction = instruction;
700+
currentInstruction = inst;
701701

702+
switch (inst->getKind()) {
702703
// The following instructions are treated as assigning their result to a
703704
// fresh region.
704-
if (isa<AllocBoxInst,
705-
AllocPackInst,
706-
AllocRefDynamicInst,
707-
AllocRefInst,
708-
AllocStackInst,
709-
EnumInst,
710-
KeyPathInst,
711-
LiteralInst,
712-
ObjCProtocolInst,
713-
WitnessMethodInst>(instruction))
714-
return translateSILAssignFresh(instruction->getResult(0));
715-
716-
if (isa<SelectEnumAddrInst, SelectEnumInst>(instruction))
717-
return translateSILSelectEnum(instruction);
705+
case SILInstructionKind::AllocBoxInst:
706+
case SILInstructionKind::AllocPackInst:
707+
case SILInstructionKind::AllocRefDynamicInst:
708+
case SILInstructionKind::AllocRefInst:
709+
case SILInstructionKind::AllocStackInst:
710+
case SILInstructionKind::EnumInst:
711+
case SILInstructionKind::KeyPathInst:
712+
case SILInstructionKind::FunctionRefInst:
713+
case SILInstructionKind::DynamicFunctionRefInst:
714+
case SILInstructionKind::PreviousDynamicFunctionRefInst:
715+
case SILInstructionKind::GlobalAddrInst:
716+
case SILInstructionKind::BaseAddrForOffsetInst:
717+
case SILInstructionKind::GlobalValueInst:
718+
case SILInstructionKind::IntegerLiteralInst:
719+
case SILInstructionKind::FloatLiteralInst:
720+
case SILInstructionKind::StringLiteralInst:
721+
case SILInstructionKind::HasSymbolInst:
722+
case SILInstructionKind::ObjCProtocolInst:
723+
case SILInstructionKind::WitnessMethodInst:
724+
return translateSILAssignFresh(inst->getResult(0));
725+
726+
case SILInstructionKind::SelectEnumAddrInst:
727+
case SILInstructionKind::SelectEnumInst:
728+
return translateSILSelectEnum(inst);
718729

719730
// The following instructions are treated as assignments of their result (tgt)
720731
// to their operand (src). This could yield a variety of behaviors depending
721732
// on the sendability of both src and tgt.
722733
// TODO: we could reduce the size of PartitionOp sequences generated by
723734
// treating some of these as lookthroughs in simplifyVal instead of
724735
// as assignments
725-
if (isa<AddressToPointerInst,
726-
BeginAccessInst,
727-
BeginBorrowInst,
728-
CopyValueInst,
729-
ConvertEscapeToNoEscapeInst,
730-
ConvertFunctionInst,
731-
CopyBlockInst,
732-
CopyBlockWithoutEscapingInst,
733-
IndexAddrInst,
734-
InitBlockStorageHeaderInst,
735-
InitEnumDataAddrInst,
736-
InitExistentialAddrInst,
737-
InitExistentialRefInst,
738-
LoadInst,
739-
LoadBorrowInst,
740-
LoadWeakInst,
741-
OpenExistentialAddrInst,
742-
OpenExistentialBoxInst,
743-
OpenExistentialRefInst,
744-
PointerToAddressInst,
745-
ProjectBlockStorageInst,
746-
RefElementAddrInst,
747-
RefToUnmanagedInst,
748-
StrongCopyUnownedValueInst,
749-
StructElementAddrInst,
750-
StructExtractInst,
751-
TailAddrInst,
752-
ThickToObjCMetatypeInst,
753-
ThinToThickFunctionInst,
754-
TupleElementAddrInst,
755-
UncheckedAddrCastInst,
756-
UncheckedEnumDataInst,
757-
UncheckedOwnershipConversionInst,
758-
UncheckedRefCastInst,
759-
UncheckedTakeEnumDataAddrInst,
760-
UnmanagedToRefInst,
761-
UpcastInst,
762-
763-
//dynamic dispatch:
764-
ClassMethodInst,
765-
ObjCMethodInst,
766-
SuperMethodInst,
767-
ObjCSuperMethodInst
768-
>(instruction))
769-
return translateSILAssign(
770-
instruction->getResult(0),
771-
instruction->getOperand(0));
772-
773-
// these are treated as stores - meaning that they could write values into
736+
case SILInstructionKind::AddressToPointerInst:
737+
case SILInstructionKind::BeginAccessInst:
738+
case SILInstructionKind::BeginBorrowInst:
739+
case SILInstructionKind::CopyValueInst:
740+
case SILInstructionKind::ConvertEscapeToNoEscapeInst:
741+
case SILInstructionKind::ConvertFunctionInst:
742+
case SILInstructionKind::CopyBlockInst:
743+
case SILInstructionKind::CopyBlockWithoutEscapingInst:
744+
case SILInstructionKind::IndexAddrInst:
745+
case SILInstructionKind::InitBlockStorageHeaderInst:
746+
case SILInstructionKind::InitEnumDataAddrInst:
747+
case SILInstructionKind::InitExistentialAddrInst:
748+
case SILInstructionKind::InitExistentialRefInst:
749+
case SILInstructionKind::LoadInst:
750+
case SILInstructionKind::LoadBorrowInst:
751+
case SILInstructionKind::LoadWeakInst:
752+
case SILInstructionKind::OpenExistentialAddrInst:
753+
case SILInstructionKind::OpenExistentialBoxInst:
754+
case SILInstructionKind::OpenExistentialRefInst:
755+
case SILInstructionKind::PointerToAddressInst:
756+
case SILInstructionKind::ProjectBlockStorageInst:
757+
case SILInstructionKind::RefElementAddrInst:
758+
case SILInstructionKind::RefToUnmanagedInst:
759+
case SILInstructionKind::StrongCopyUnownedValueInst:
760+
case SILInstructionKind::StructElementAddrInst:
761+
case SILInstructionKind::StructExtractInst:
762+
case SILInstructionKind::TailAddrInst:
763+
case SILInstructionKind::ThickToObjCMetatypeInst:
764+
case SILInstructionKind::ThinToThickFunctionInst:
765+
case SILInstructionKind::TupleElementAddrInst:
766+
case SILInstructionKind::UncheckedAddrCastInst:
767+
case SILInstructionKind::UncheckedEnumDataInst:
768+
case SILInstructionKind::UncheckedOwnershipConversionInst:
769+
case SILInstructionKind::UncheckedRefCastInst:
770+
case SILInstructionKind::UncheckedTakeEnumDataAddrInst:
771+
case SILInstructionKind::UnmanagedToRefInst:
772+
case SILInstructionKind::UpcastInst:
773+
774+
// Dynamic dispatch:
775+
case SILInstructionKind::ClassMethodInst:
776+
case SILInstructionKind::ObjCMethodInst:
777+
case SILInstructionKind::SuperMethodInst:
778+
case SILInstructionKind::ObjCSuperMethodInst:
779+
return translateSILAssign(inst->getResult(0), inst->getOperand(0));
780+
781+
// These are treated as stores - meaning that they could write values into
774782
// memory. The beahvior of this depends on whether the tgt addr is aliased,
775-
// but conservative behavior is to treat these as merges of the regions
776-
// of the src value and tgt addr
777-
if (isa<CopyAddrInst,
778-
ExplicitCopyAddrInst,
779-
StoreInst,
780-
StoreBorrowInst,
781-
StoreWeakInst>(instruction))
782-
return translateSILStore(
783-
instruction->getOperand(1),
784-
instruction->getOperand(0));
785-
786-
// handle applications
787-
if (isApplyInst(*instruction))
788-
return translateSILApply(instruction);
789-
790-
// handle tuple destruction
791-
if (auto destructTupleInst = dyn_cast<DestructureTupleInst>(instruction))
783+
// but conservative behavior is to treat these as merges of the regions of
784+
// the src value and tgt addr
785+
case SILInstructionKind::CopyAddrInst:
786+
case SILInstructionKind::ExplicitCopyAddrInst:
787+
case SILInstructionKind::StoreInst:
788+
case SILInstructionKind::StoreBorrowInst:
789+
case SILInstructionKind::StoreWeakInst:
790+
return translateSILStore(inst->getOperand(1), inst->getOperand(0));
791+
792+
case SILInstructionKind::ApplyInst:
793+
case SILInstructionKind::BeginApplyInst:
794+
case SILInstructionKind::BuiltinInst:
795+
case SILInstructionKind::PartialApplyInst:
796+
case SILInstructionKind::TryApplyInst:
797+
return translateSILApply(inst);
798+
799+
case SILInstructionKind::DestructureTupleInst: {
800+
// handle tuple destruction
801+
auto *destructTupleInst = cast<DestructureTupleInst>(inst);
792802
return translateSILMultiAssign(
793803
{destructTupleInst->getResults().begin(),
794804
destructTupleInst->getResults().end()},
795805
{destructTupleInst->getOperand()});
806+
}
796807

797808
// handle instructions that aggregate their operands into a single structure
798809
// - treated as a multi assign
799-
if (isa<ObjectInst,
800-
StructInst,
801-
TupleInst>(instruction))
810+
case SILInstructionKind::ObjectInst:
811+
case SILInstructionKind::StructInst:
812+
case SILInstructionKind::TupleInst:
802813
return translateSILMultiAssign(
803-
{instruction->getResult(0)},
804-
{instruction->getOperandValues().begin(),
805-
instruction->getOperandValues().end()});
814+
{inst->getResult(0)},
815+
{inst->getOperandValues().begin(), inst->getOperandValues().end()});
806816

807817
// Handle returns and throws - require the operand to be non-consumed
808-
if (isa<ReturnInst, ThrowInst>(instruction))
809-
return translateSILRequire(instruction->getOperand(0));
810-
811-
// handle branching terminators
812-
// in particular, need to handle phi-node-like argument passing
813-
814-
if (auto branchInst = dyn_cast<BranchInst>(instruction)) {
818+
case SILInstructionKind::ReturnInst:
819+
case SILInstructionKind::ThrowInst:
820+
return translateSILRequire(inst->getOperand(0));
821+
822+
// handle branching terminators. in particular, need to handle phi-node-like
823+
// argument passing
824+
case SILInstructionKind::BranchInst: {
825+
auto *branchInst = cast<BranchInst>(inst);
815826
assert(branchInst->getNumArgs() == branchInst->getDestBB()->getNumArguments());
816827
return translateSILPhi(
817828
{{{branchInst->getArgs().begin(), branchInst->getArgs().end()},
818829
branchInst->getDestBB()}});
819830
}
820831

821-
if (auto condBranchInst = dyn_cast<CondBranchInst>(instruction)) {
832+
case SILInstructionKind::CondBranchInst: {
833+
auto *condBranchInst = cast<CondBranchInst>(inst);
822834
assert(condBranchInst->getNumTrueArgs() ==
823835
condBranchInst->getTrueBB()->getNumArguments());
824836
assert(condBranchInst->getNumFalseArgs() ==
@@ -833,62 +845,68 @@ class PartitionOpTranslator {
833845
condBranchInst->getFalseBB()}});
834846
}
835847

836-
if (auto switchEnumInst = dyn_cast<SwitchEnumInst>(instruction))
837-
return translateSILSwitchEnum(switchEnumInst);
848+
case SILInstructionKind::SwitchEnumInst:
849+
return translateSILSwitchEnum(cast<SwitchEnumInst>(inst));
838850

839-
if (auto dmBranchInst = dyn_cast<DynamicMethodBranchInst>(instruction)) {
851+
case SILInstructionKind::DynamicMethodBranchInst: {
852+
auto *dmBranchInst = cast<DynamicMethodBranchInst>(inst);
840853
assert(dmBranchInst->getHasMethodBB()->getNumArguments() <= 1);
841854
return translateSILPhi(
842855
{{{dmBranchInst->getOperand()}, dmBranchInst->getHasMethodBB()}});
843856
}
844857

845-
if (auto ccBranchInst = dyn_cast<CheckedCastBranchInst>(instruction)) {
858+
case SILInstructionKind::CheckedCastBranchInst: {
859+
auto *ccBranchInst = cast<CheckedCastBranchInst>(inst);
846860
assert(ccBranchInst->getSuccessBB()->getNumArguments() <= 1);
847861
return translateSILPhi(
848862
{{{ccBranchInst->getOperand()}, ccBranchInst->getSuccessBB()}});
849863
}
850864

851-
if (auto ccAddrBranchInst = dyn_cast<CheckedCastAddrBranchInst>(instruction)) {
865+
case SILInstructionKind::CheckedCastAddrBranchInst: {
866+
auto *ccAddrBranchInst = cast<CheckedCastAddrBranchInst>(inst);
852867
assert(ccAddrBranchInst->getSuccessBB()->getNumArguments() <= 1);
853868
return translateSILPhi({{{ccAddrBranchInst->getOperand(0)},
854869
ccAddrBranchInst->getSuccessBB()}});
855870
}
856871

857872
// these instructions are ignored because they cannot affect the partition
858873
// state - they do not manipulate what region non-sendable values lie in
859-
if (isa<AllocGlobalInst,
860-
DeallocBoxInst,
861-
DeallocStackInst,
862-
DebugValueInst,
863-
DestroyAddrInst,
864-
DestroyValueInst,
865-
EndAccessInst,
866-
EndBorrowInst,
867-
EndLifetimeInst,
868-
HopToExecutorInst,
869-
InjectEnumAddrInst,
870-
IsEscapingClosureInst, // ignored because result is always int
871-
MarkDependenceInst,
872-
MetatypeInst,
873-
874-
EndApplyInst,
875-
AbortApplyInst,
876-
877-
//ignored terminators
878-
CondFailInst,
879-
SwitchEnumAddrInst, // ignored as long as destinations can take no args
880-
SwitchValueInst, // ignored as long as destinations can take no args
881-
UnreachableInst,
882-
UnwindInst,
883-
YieldInst //TODO: yield should be handled
884-
>(instruction))
885-
//ignored instructions
874+
case SILInstructionKind::AllocGlobalInst:
875+
case SILInstructionKind::DeallocBoxInst:
876+
case SILInstructionKind::DeallocStackInst:
877+
case SILInstructionKind::DebugValueInst:
878+
case SILInstructionKind::DestroyAddrInst:
879+
case SILInstructionKind::DestroyValueInst:
880+
case SILInstructionKind::EndAccessInst:
881+
case SILInstructionKind::EndBorrowInst:
882+
case SILInstructionKind::EndLifetimeInst:
883+
case SILInstructionKind::HopToExecutorInst:
884+
case SILInstructionKind::InjectEnumAddrInst:
885+
case SILInstructionKind::IsEscapingClosureInst: // ignored because result is
886+
// always in
887+
case SILInstructionKind::MarkDependenceInst:
888+
case SILInstructionKind::MetatypeInst:
889+
case SILInstructionKind::EndApplyInst:
890+
case SILInstructionKind::AbortApplyInst:
891+
892+
// ignored terminators
893+
case SILInstructionKind::CondFailInst:
894+
case SILInstructionKind::SwitchEnumAddrInst: // ignored as long as
895+
// destinations can take no arg
896+
case SILInstructionKind::SwitchValueInst: // ignored as long as destinations
897+
// can take no args
898+
case SILInstructionKind::UnreachableInst:
899+
case SILInstructionKind::UnwindInst:
900+
case SILInstructionKind::YieldInst: // TODO: yield should be handled
886901
return {};
887902

903+
default:
904+
break;
905+
}
906+
888907
LLVM_DEBUG(llvm::errs() << "warning: ";
889-
llvm::errs()
890-
<< "unhandled instruction kind "
891-
<< getSILInstructionName(instruction->getKind()) << "\n";);
908+
llvm::errs() << "unhandled instruction kind "
909+
<< getSILInstructionName(inst->getKind()) << "\n";);
892910

893911
return {};
894912
}

0 commit comments

Comments
 (0)