diff --git a/include/swift/SIL/SILArgument.h b/include/swift/SIL/SILArgument.h index 4f23c1cd6ff46..d5d8537fd8c3b 100644 --- a/include/swift/SIL/SILArgument.h +++ b/include/swift/SIL/SILArgument.h @@ -173,6 +173,10 @@ class SILArgument : public ValueBase { /// is the enum itself (the operand of the switch_enum). SILValue getSingleTerminatorOperand() const; + /// If this SILArgument's parent block has a single predecessor whose + /// terminator has a single operand, return that terminator. + TermInst *getSingleTerminator() const; + /// Return the SILArgumentKind of this argument. SILArgumentKind getKind() const { return SILArgumentKind(ValueBase::getKind()); @@ -264,6 +268,10 @@ class SILPhiArgument : public SILArgument { /// is the enum itself (the operand of the switch_enum). SILValue getSingleTerminatorOperand() const; + /// If this SILArgument's parent block has a single predecessor whose + /// terminator has a single operand, return that terminator. + TermInst *getSingleTerminator() const; + static bool classof(const SILInstruction *) = delete; static bool classof(const SILUndef *) = delete; static bool classof(const SILNode *node) { @@ -403,6 +411,16 @@ inline bool SILArgument::getSingleTerminatorOperands( llvm_unreachable("Covered switch is not covered?!"); } +inline TermInst *SILArgument::getSingleTerminator() const { + switch (getKind()) { + case SILArgumentKind::SILPhiArgument: + return cast(this)->getSingleTerminator(); + case SILArgumentKind::SILFunctionArgument: + return nullptr; + } + llvm_unreachable("Covered switch is not covered?!"); +} + } // end swift namespace #endif diff --git a/lib/SIL/SILArgument.cpp b/lib/SIL/SILArgument.cpp index f45bdf80edd11..131b8b888ae85 100644 --- a/lib/SIL/SILArgument.cpp +++ b/lib/SIL/SILArgument.cpp @@ -235,6 +235,14 @@ SILValue SILPhiArgument::getSingleTerminatorOperand() const { return getSingleTerminatorOperandForPred(parentBlock, predBlock, getIndex()); } +TermInst *SILPhiArgument::getSingleTerminator() const { + auto *parentBlock = getParent(); + auto *predBlock = parentBlock->getSinglePredecessorBlock(); + if (!predBlock) + return nullptr; + return const_cast(predBlock)->getTerminator(); +} + const SILPhiArgument *BranchInst::getArgForOperand(const Operand *oper) const { assert(oper->getUser() == this); return cast(