mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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:
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
})) {
|
})) {
|
||||||
|
|||||||
Reference in New Issue
Block a user