From 05224aaa1f08fc077b22ce36f28f53e7fff5a54d Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Tue, 18 Jan 2022 09:12:33 -0800 Subject: [PATCH] Improve the SILInstruction::getOperandValues() API. Add NonTypeDependentOperandToValue predicate for composability. Add a getNonTypeDependentOperandValues(), which can be used as a functor. The skipTypeDependentOperands parameter complicated the API. --- include/swift/SIL/SILInstruction.h | 63 ++++++++++++++----- lib/SIL/Utils/OwnershipUtils.cpp | 8 +-- .../SemanticARC/OwnershipLiveRange.cpp | 3 +- 3 files changed, 52 insertions(+), 22 deletions(-) diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h index 9cbb1ab336f..432035712f3 100644 --- a/include/swift/SIL/SILInstruction.h +++ b/include/swift/SIL/SILInstruction.h @@ -567,19 +567,30 @@ public: bool maySuspend() const; private: - /// Predicate used to filter OperandValueRange. + /// Functor for Operand::get() struct OperandToValue; - /// Predicate used to filter TransformedOperandValueRange. + /// Functor for Operand::get() + struct OperandRefToValue; + /// Predicate to filter NonTypeDependentOperandValueRange + struct NonTypeDependentOperandToValue; + /// Predicate to filter TransformedOperandValueRange. struct OperandToTransformedValue; public: - using OperandValueRange = - OptionalTransformRange, OperandToValue>; + using OperandValueRange = TransformRange, OperandToValue>; + using OperandRefValueRange = + TransformRange, OperandRefToValue>; + using NonTypeDependentOperandValueRange = + OptionalTransformRange, NonTypeDependentOperandToValue>; using TransformedOperandValueRange = - OptionalTransformRange, OperandToTransformedValue>; + OptionalTransformRange, OperandToTransformedValue>; + + static OperandValueRange getOperandValues(ArrayRef operands); + + OperandRefValueRange getOperandValues() const; + + NonTypeDependentOperandValueRange getNonTypeDependentOperandValues() const; - OperandValueRange - getOperandValues(bool skipTypeDependentOperands = false) const; TransformedOperandValueRange getOperandValues(std::function transformFn, bool skipTypeDependentOperands) const; @@ -879,14 +890,24 @@ inline const SILNode *SILNode::instAsNode(const SILInstruction *inst) { struct SILInstruction::OperandToValue { - const SILInstruction &i; - bool skipTypeDependentOps; + SILValue operator()(const Operand *use) const { + return use->get(); + } +}; - OperandToValue(const SILInstruction &i, bool skipTypeDependentOps) - : i(i), skipTypeDependentOps(skipTypeDependentOps) {} +struct SILInstruction::OperandRefToValue { + SILValue operator()(const Operand &use) const { + return use.get(); + } +}; + +struct SILInstruction::NonTypeDependentOperandToValue { + const SILInstruction &i; + + NonTypeDependentOperandToValue(const SILInstruction &i): i(i) {} Optional operator()(const Operand &use) const { - if (skipTypeDependentOps && i.isTypeDependentOperand(use)) + if (i.isTypeDependentOperand(use)) return None; return use.get(); } @@ -910,11 +931,21 @@ struct SILInstruction::OperandToTransformedValue { } }; +inline SILInstruction::OperandValueRange +SILInstruction::getOperandValues(ArrayRef operands) { + return OperandValueRange(operands, OperandToValue()); +} + inline auto -SILInstruction::getOperandValues(bool skipTypeDependentOperands) const - -> OperandValueRange { - return OperandValueRange(getAllOperands(), - OperandToValue(*this, skipTypeDependentOperands)); +SILInstruction::getOperandValues() const -> OperandRefValueRange { + return OperandRefValueRange(getAllOperands(), OperandRefToValue()); +} + +inline auto +SILInstruction::getNonTypeDependentOperandValues() const + -> NonTypeDependentOperandValueRange { + return NonTypeDependentOperandValueRange(getAllOperands(), + NonTypeDependentOperandToValue(*this)); } inline auto diff --git a/lib/SIL/Utils/OwnershipUtils.cpp b/lib/SIL/Utils/OwnershipUtils.cpp index 3af8be6354b..5329769813d 100644 --- a/lib/SIL/Utils/OwnershipUtils.cpp +++ b/lib/SIL/Utils/OwnershipUtils.cpp @@ -1055,7 +1055,7 @@ bool swift::getAllBorrowIntroducingValues(SILValue inputValue, // instruction if (isForwardingBorrow(value)) { if (auto *i = value->getDefiningInstruction()) { - llvm::copy(i->getOperandValues(true /*skip type dependent ops*/), + llvm::copy(i->getNonTypeDependentOperandValues(), std::back_inserter(worklist)); continue; } @@ -1100,7 +1100,7 @@ BorrowedValue swift::getSingleBorrowIntroducingValue(SILValue inputValue) { // instruction if (isForwardingBorrow(currentValue)) { if (auto *i = currentValue->getDefiningInstruction()) { - auto instOps = i->getOperandValues(true /*ignore type dependent ops*/); + auto instOps = i->getNonTypeDependentOperandValues(); // If we have multiple incoming values, return .None. We can't handle // this. auto begin = instOps.begin(); @@ -1160,7 +1160,7 @@ bool swift::getAllOwnedValueIntroducers( // instruction if (isForwardingConsume(value)) { if (auto *i = value->getDefiningInstruction()) { - llvm::copy(i->getOperandValues(true /*skip type dependent ops*/), + llvm::copy(i->getNonTypeDependentOperandValues(), std::back_inserter(worklist)); continue; } @@ -1201,7 +1201,7 @@ OwnedValueIntroducer swift::getSingleOwnedValueIntroducer(SILValue inputValue) { // instruction if (isForwardingConsume(currentValue)) { if (auto *i = currentValue->getDefiningInstruction()) { - auto instOps = i->getOperandValues(true /*ignore type dependent ops*/); + auto instOps = i->getNonTypeDependentOperandValues(); // If we have multiple incoming values, return .None. We can't handle // this. auto begin = instOps.begin(); diff --git a/lib/SILOptimizer/SemanticARC/OwnershipLiveRange.cpp b/lib/SILOptimizer/SemanticARC/OwnershipLiveRange.cpp index 63e642f6439..97080560ec6 100644 --- a/lib/SILOptimizer/SemanticARC/OwnershipLiveRange.cpp +++ b/lib/SILOptimizer/SemanticARC/OwnershipLiveRange.cpp @@ -75,8 +75,7 @@ OwnershipLiveRange::OwnershipLiveRange(SILValue value) auto *ti = dyn_cast(user); if ((ti && !ti->isTransformationTerminator()) || !canOpcodeForwardGuaranteedValues(op) || - 1 != count_if(user->getOperandValues( - true /*ignore type dependent operands*/), + 1 != count_if(user->getNonTypeDependentOperandValues(), [&](SILValue v) { return v.getOwnershipKind() == OwnershipKind::Owned; })) {