[RFC] DialectInterface for CSE

Thanks! The current proposed interface is intentionally limited to optional attributes right now to reduce the scope, but if more generalized version is preferred I’d be happy to make the interface more generalized one!

Providing interface to control the behavior of analysis and transformations seems good to me, I am not sure we can have a DialectOperationEquivalenceInterface though: the “equivalence” between operation is likely context dependent. That is the answer for the purpose of CSE may be different than for other purpose, so I would focus on a CSE specific interface right now.

That’s reasonable, in that case DialectCSEInterface should have hash function and equivalence checker that will be passed to corresponding SimpleOperationInfo members. We will also have to add extra callback to member functions of OperationEquivalence such as OperationEquivalence::computeHash or OperationEquivalence::isEquivalentTo to hook hash and equivalence check.

Based on the suggestions the interface DialectCSEInterface would be like this:

class DialectCSEInterface {
  /// Returns true if the operation is considered to be equivalent.
  virtual bool areOperationsEquivalent(Operation* lhs, Operation* rhs) const {
    return OperationEquivalence::isEquivalentTo(...);
  }

  /// Returns hash value for operation.
  virtual unsigned getHashValue(Operation* op) const {
    return OperationEquivalence::getHashValue(...);
  }
  
  /// Merge `op` (operation which is going to be CSEd and eliminated) to `existingOp`
  virtual void mergeOperations(Operation* op, Operation* existingOp) const {
  }
};
struct SimpleOperationInfo : public llvm::DenseMapInfo<Operation *> {
  static unsigned getHashValue(const Operation *opC) {
     auto interface = dyn_cast_or_null<DialectCSEInterface>(opC->getDialect() );
     if(interface) return interface->getHashValue(opC);
     return ...; // default implementation  
  }
  static bool isEqual(const Operation *lhsC, const Operation *rhsC) {
     auto interface = dyn_cast_or_null<DialectCSEInterface>(lhsC->getDialect() );
     if(interface) return interface->areOperationsEquivalent(lhsC, rhsC);
     return ...; // default implementation
  }