@@ -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
973997struct 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