Simplify affine binary op expression class hierarchy

- Drop sub-classing of affine binary op expressions.
- Drop affine expr op kind sub. Represent it as multiply by -1 and add. This
  will also be in line with the math form when we'll need to represent a system of
  linear equalities/inequalities: the negative number goes into the coefficient
  of an affine form. (For eg. x_1 + (-1)*x_2 + 3*x_3 + (-2) >= 0). The folding
  simplification will transparently deal with multiplying the -1 with any other
  constants. This also means we won't need to simplify a multiply expression
  like in x_1 + (-2)*x_2 to a subtract expression (x_1 - 2*x_2) for
  canonicalization/uniquing.
- When we print the IR, we will still pretty print to a subtract when possible.

PiperOrigin-RevId: 205298958
diff --git a/lib/IR/AffineMap.cpp b/lib/IR/AffineMap.cpp
index d8e09b5..8972510 100644
--- a/lib/IR/AffineMap.cpp
+++ b/lib/IR/AffineMap.cpp
@@ -38,7 +38,7 @@
 
   if (isa<AffineConstantExpr>(lhs) ||
       (lhs->isSymbolicOrConstant() && !rhs->isSymbolicOrConstant()))
-    return AffineAddExpr::get(rhs, lhs, context);
+    return AffineBinaryOpExpr::get(Kind::Add, rhs, lhs, context);
 
   return nullptr;
   // TODO(someone): implement more simplification like x + 0 -> x; (x + 2) + 4
@@ -46,16 +46,6 @@
   // simplifications as opposed to incremental hacks.
 }
 
-AffineExpr *AffineBinaryOpExpr::simplifySub(AffineExpr *lhs, AffineExpr *rhs,
-                                            MLIRContext *context) {
-  if (auto *l = dyn_cast<AffineConstantExpr>(lhs))
-    if (auto *r = dyn_cast<AffineConstantExpr>(rhs))
-      return AffineConstantExpr::get(l->getValue() - r->getValue(), context);
-
-  return nullptr;
-  // TODO(someone): implement more simplification like mentioned for add.
-}
-
 /// Simplify a multiply expression. Fold it to a constant when possible, and
 /// make the symbolic/constant operand the RHS.
 AffineExpr *AffineBinaryOpExpr::simplifyMul(AffineExpr *lhs, AffineExpr *rhs,
@@ -71,7 +61,7 @@
   // constant. (Note that a constant is trivially symbolic).
   if (!rhs->isSymbolicOrConstant() || isa<AffineConstantExpr>(lhs)) {
     // At least one of them has to be symbolic.
-    return AffineMulExpr::get(rhs, lhs, context);
+    return AffineBinaryOpExpr::get(Kind::Mul, rhs, lhs, context);
   }
 
   return nullptr;