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;
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<ArrayRef<Operand>, OperandToValue>;
using OperandValueRange = TransformRange<ArrayRef<Operand*>, OperandToValue>;
using OperandRefValueRange =
TransformRange<ArrayRef<Operand>, OperandRefToValue>;
using NonTypeDependentOperandValueRange =
OptionalTransformRange<ArrayRef<Operand>, NonTypeDependentOperandToValue>;
using TransformedOperandValueRange =
OptionalTransformRange<ArrayRef<Operand>, OperandToTransformedValue>;
OptionalTransformRange<ArrayRef<Operand>, OperandToTransformedValue>;
static OperandValueRange getOperandValues(ArrayRef<Operand*> operands);
OperandRefValueRange getOperandValues() const;
NonTypeDependentOperandValueRange getNonTypeDependentOperandValues() const;
OperandValueRange
getOperandValues(bool skipTypeDependentOperands = false) const;
TransformedOperandValueRange
getOperandValues(std::function<SILValue(SILValue)> 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<SILValue> 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<Operand*> 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

View File

@@ -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();

View File

@@ -75,8 +75,7 @@ OwnershipLiveRange::OwnershipLiveRange(SILValue value)
auto *ti = dyn_cast<TermInst>(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;
})) {