Skip to content

Commit 4ab5024

Browse files
authored
Merge pull request #63791 from meg-gupta/csebug
Fix CSE `isEqual` and `HashVisitor` for escaped values
2 parents d9cfded + 619b4cd commit 4ab5024

File tree

4 files changed

+218
-123
lines changed

4 files changed

+218
-123
lines changed

include/swift/SIL/SILInstruction.h

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ class SILInstruction : public llvm::ilist_node<SILInstruction> {
643643
NonTypeDependentOperandValueRange getNonTypeDependentOperandValues() const;
644644

645645
TransformedOperandValueRange
646-
getOperandValues(std::function<SILValue(SILValue)> transformFn,
646+
getOperandValues(std::function<SILValue(const Operand *)> transformFn,
647647
bool skipTypeDependentOperands) const;
648648

649649
SILValue getOperand(unsigned Num) const {
@@ -720,8 +720,9 @@ class SILInstruction : public llvm::ilist_node<SILInstruction> {
720720
/// Returns true if the given instruction is completely identical to RHS,
721721
/// using \p opEqual to compare operands.
722722
///
723-
template <typename OpCmp>
724-
bool isIdenticalTo(const SILInstruction *RHS, OpCmp &&opEqual) const {
723+
bool
724+
isIdenticalTo(const SILInstruction *RHS,
725+
llvm::function_ref<bool(SILValue, SILValue)> opEqual) const {
725726
// Quick check if both instructions have the same kind, number of operands,
726727
// and types. This should filter out most cases.
727728
if (getKind() != RHS->getKind() ||
@@ -742,6 +743,29 @@ class SILInstruction : public llvm::ilist_node<SILInstruction> {
742743
return hasIdenticalState(RHS);
743744
}
744745

746+
bool isIdenticalTo(const SILInstruction *RHS,
747+
llvm::function_ref<bool(const Operand *, const Operand *)>
748+
opEqual) const {
749+
// Quick check if both instructions have the same kind, number of operands,
750+
// and types. This should filter out most cases.
751+
if (getKind() != RHS->getKind() ||
752+
getNumOperands() != RHS->getNumOperands()) {
753+
return false;
754+
}
755+
756+
if (!getResults().hasSameTypes(RHS->getResults()))
757+
return false;
758+
759+
// Check operands.
760+
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
761+
if (!opEqual(&getOperandRef(i), &RHS->getOperandRef(i)))
762+
return false;
763+
764+
// Check any special state of instructions that are not represented in the
765+
// instructions operands/type.
766+
return hasIdenticalState(RHS);
767+
}
768+
745769
/// Returns true if the instruction may have side effects.
746770
///
747771
/// Instructions that store into memory or change retain counts as well as
@@ -972,19 +996,20 @@ struct SILInstruction::NonTypeDependentOperandToValue {
972996

973997
struct SILInstruction::OperandToTransformedValue {
974998
const SILInstruction &i;
975-
std::function<SILValue(SILValue)> transformFn;
999+
std::function<SILValue(const Operand *)> transformFn;
9761000
bool skipTypeDependentOps;
9771001

978-
OperandToTransformedValue(const SILInstruction &i,
979-
std::function<SILValue(SILValue)> transformFn,
980-
bool skipTypeDependentOps)
1002+
OperandToTransformedValue(
1003+
const SILInstruction &i,
1004+
std::function<SILValue(const Operand *)> transformFn,
1005+
bool skipTypeDependentOps)
9811006
: i(i), transformFn(transformFn),
9821007
skipTypeDependentOps(skipTypeDependentOps) {}
9831008

9841009
Optional<SILValue> operator()(const Operand &use) const {
9851010
if (skipTypeDependentOps && i.isTypeDependentOperand(use))
9861011
return None;
987-
return transformFn(use.get());
1012+
return transformFn(&use);
9881013
}
9891014
};
9901015

@@ -1005,10 +1030,9 @@ SILInstruction::getNonTypeDependentOperandValues() const
10051030
NonTypeDependentOperandToValue(*this));
10061031
}
10071032

1008-
inline auto
1009-
SILInstruction::getOperandValues(std::function<SILValue(SILValue)> transformFn,
1010-
bool skipTypeDependentOperands) const
1011-
-> TransformedOperandValueRange {
1033+
inline auto SILInstruction::getOperandValues(
1034+
std::function<SILValue(const Operand *)> transformFn,
1035+
bool skipTypeDependentOperands) const -> TransformedOperandValueRange {
10121036
return TransformedOperandValueRange(
10131037
getAllOperands(),
10141038
OperandToTransformedValue(*this, transformFn, skipTypeDependentOperands));
@@ -6561,7 +6585,8 @@ class SelectEnumInstBase
65616585

65626586
SILValue getOperand() const { return getAllOperands()[0].get(); }
65636587
SILValue getEnumOperand() const { return getOperand(); }
6564-
6588+
const Operand &getEnumOperandRef() const { return getAllOperands()[0]; }
6589+
65656590
std::pair<EnumElementDecl*, SILValue>
65666591
getCase(unsigned i) const {
65676592
return std::make_pair(getEnumElementDeclStorage()[i],
@@ -8743,6 +8768,8 @@ class IndexingInst : public SingleValueInstruction {
87438768
ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
87448769
MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
87458770

8771+
const Operand &getBaseOperandRef() const { return getAllOperands()[Base]; }
8772+
87468773
DEFINE_ABSTRACT_SINGLE_VALUE_INST_BOILERPLATE(IndexingInst)
87478774
};
87488775

0 commit comments

Comments
 (0)