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.
This commit is contained in:
Andrew Trick
2022-01-18 09:12:33 -08:00
parent 23252935f6
commit 05224aaa1f
3 changed files with 52 additions and 22 deletions

View File

@@ -567,19 +567,30 @@ public:
bool maySuspend() const; bool maySuspend() const;
private: private:
/// Predicate used to filter OperandValueRange. /// Functor for Operand::get()
struct OperandToValue; 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; struct OperandToTransformedValue;
public: public:
using OperandValueRange = using OperandValueRange = TransformRange<ArrayRef<Operand*>, OperandToValue>;
OptionalTransformRange<ArrayRef<Operand>, OperandToValue>; using OperandRefValueRange =
TransformRange<ArrayRef<Operand>, OperandRefToValue>;
using NonTypeDependentOperandValueRange =
OptionalTransformRange<ArrayRef<Operand>, NonTypeDependentOperandToValue>;
using TransformedOperandValueRange = using TransformedOperandValueRange =
OptionalTransformRange<ArrayRef<Operand>, OperandToTransformedValue>; OptionalTransformRange<ArrayRef<Operand>, OperandToTransformedValue>;
OperandValueRange static OperandValueRange getOperandValues(ArrayRef<Operand*> operands);
getOperandValues(bool skipTypeDependentOperands = false) const;
OperandRefValueRange getOperandValues() const;
NonTypeDependentOperandValueRange getNonTypeDependentOperandValues() const;
TransformedOperandValueRange TransformedOperandValueRange
getOperandValues(std::function<SILValue(SILValue)> transformFn, getOperandValues(std::function<SILValue(SILValue)> transformFn,
bool skipTypeDependentOperands) const; bool skipTypeDependentOperands) const;
@@ -879,14 +890,24 @@ inline const SILNode *SILNode::instAsNode(const SILInstruction *inst) {
struct SILInstruction::OperandToValue { struct SILInstruction::OperandToValue {
const SILInstruction &i; SILValue operator()(const Operand *use) const {
bool skipTypeDependentOps; return use->get();
}
};
OperandToValue(const SILInstruction &i, bool skipTypeDependentOps) struct SILInstruction::OperandRefToValue {
: i(i), skipTypeDependentOps(skipTypeDependentOps) {} SILValue operator()(const Operand &use) const {
return use.get();
}
};
struct SILInstruction::NonTypeDependentOperandToValue {
const SILInstruction &i;
NonTypeDependentOperandToValue(const SILInstruction &i): i(i) {}
Optional<SILValue> operator()(const Operand &use) const { Optional<SILValue> operator()(const Operand &use) const {
if (skipTypeDependentOps && i.isTypeDependentOperand(use)) if (i.isTypeDependentOperand(use))
return None; return None;
return use.get(); return use.get();
} }
@@ -910,11 +931,21 @@ struct SILInstruction::OperandToTransformedValue {
} }
}; };
inline SILInstruction::OperandValueRange
SILInstruction::getOperandValues(ArrayRef<Operand*> operands) {
return OperandValueRange(operands, OperandToValue());
}
inline auto inline auto
SILInstruction::getOperandValues(bool skipTypeDependentOperands) const SILInstruction::getOperandValues() const -> OperandRefValueRange {
-> OperandValueRange { return OperandRefValueRange(getAllOperands(), OperandRefToValue());
return OperandValueRange(getAllOperands(), }
OperandToValue(*this, skipTypeDependentOperands));
inline auto
SILInstruction::getNonTypeDependentOperandValues() const
-> NonTypeDependentOperandValueRange {
return NonTypeDependentOperandValueRange(getAllOperands(),
NonTypeDependentOperandToValue(*this));
} }
inline auto inline auto

View File

@@ -1055,7 +1055,7 @@ bool swift::getAllBorrowIntroducingValues(SILValue inputValue,
// instruction // instruction
if (isForwardingBorrow(value)) { if (isForwardingBorrow(value)) {
if (auto *i = value->getDefiningInstruction()) { if (auto *i = value->getDefiningInstruction()) {
llvm::copy(i->getOperandValues(true /*skip type dependent ops*/), llvm::copy(i->getNonTypeDependentOperandValues(),
std::back_inserter(worklist)); std::back_inserter(worklist));
continue; continue;
} }
@@ -1100,7 +1100,7 @@ BorrowedValue swift::getSingleBorrowIntroducingValue(SILValue inputValue) {
// instruction // instruction
if (isForwardingBorrow(currentValue)) { if (isForwardingBorrow(currentValue)) {
if (auto *i = currentValue->getDefiningInstruction()) { 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 // If we have multiple incoming values, return .None. We can't handle
// this. // this.
auto begin = instOps.begin(); auto begin = instOps.begin();
@@ -1160,7 +1160,7 @@ bool swift::getAllOwnedValueIntroducers(
// instruction // instruction
if (isForwardingConsume(value)) { if (isForwardingConsume(value)) {
if (auto *i = value->getDefiningInstruction()) { if (auto *i = value->getDefiningInstruction()) {
llvm::copy(i->getOperandValues(true /*skip type dependent ops*/), llvm::copy(i->getNonTypeDependentOperandValues(),
std::back_inserter(worklist)); std::back_inserter(worklist));
continue; continue;
} }
@@ -1201,7 +1201,7 @@ OwnedValueIntroducer swift::getSingleOwnedValueIntroducer(SILValue inputValue) {
// instruction // instruction
if (isForwardingConsume(currentValue)) { if (isForwardingConsume(currentValue)) {
if (auto *i = currentValue->getDefiningInstruction()) { 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 // If we have multiple incoming values, return .None. We can't handle
// this. // this.
auto begin = instOps.begin(); auto begin = instOps.begin();

View File

@@ -75,8 +75,7 @@ OwnershipLiveRange::OwnershipLiveRange(SILValue value)
auto *ti = dyn_cast<TermInst>(user); auto *ti = dyn_cast<TermInst>(user);
if ((ti && !ti->isTransformationTerminator()) || if ((ti && !ti->isTransformationTerminator()) ||
!canOpcodeForwardGuaranteedValues(op) || !canOpcodeForwardGuaranteedValues(op) ||
1 != count_if(user->getOperandValues( 1 != count_if(user->getNonTypeDependentOperandValues(),
true /*ignore type dependent operands*/),
[&](SILValue v) { [&](SILValue v) {
return v.getOwnershipKind() == OwnershipKind::Owned; return v.getOwnershipKind() == OwnershipKind::Owned;
})) { })) {