[pydm] Defines the structure for the full numeric hierarchy. (#7274)

* [pydm] Defines the structure for the full numeric hierarchy.

* Full support modeled for signed/unsigned 8/16/32/64 bit integers, fp16/bf16/fp32/fp64, complex64/complex128, bool, weak integer, weak real, arbitrary precision integer.
* Actual support for everything is more limited. Using a frontend pass to squash all weak types to i32/f32 for now (type inference/analysis needs to come into play here before making such decisions).
* Numeric promotion is in-flux at the moment, but shooting for a combination of Numba/Cython/JAX reasoning about this. Key is that weak integer/real types exist and bind to the hierarchy in different ways. See: https://jax.readthedocs.io/en/latest/type_promotion.html
* This makes the generic runtime support a lot more complicated and required quite a few more lowerings and canonicalizations to achieve (i.e. the runtime library decodes the bit patterns in the type code to make numeric type decisions).
* The generated code is still a joke and not something we would ever use, but it does run: https://gist.github.com/stellaraccident/e9f41a09a3834465d7576312fc63c278
* Still holding off on any real optimizations beyond canonicalizations since generality is helpful at this stage. Most of what is there should melt away with some simple variable load/store analysis.
diff --git a/llvm-external-projects/iree-dialects/lib/Dialect/IREEPyDM/IR/Ops.cpp b/llvm-external-projects/iree-dialects/lib/Dialect/IREEPyDM/IR/Ops.cpp
index 245e6be..3f93482 100644
--- a/llvm-external-projects/iree-dialects/lib/Dialect/IREEPyDM/IR/Ops.cpp
+++ b/llvm-external-projects/iree-dialects/lib/Dialect/IREEPyDM/IR/Ops.cpp
@@ -77,6 +77,39 @@
 }
 
 //===----------------------------------------------------------------------===//
+// ApplyCompareOp
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+/// Matches an `apply_compare` op where both operands are defined by
+/// `box` ops that have the same operand type. Replaces the operands with the
+/// operands of the `box`.
+struct UnboxApplyCompareOperands : public OpRewritePattern<ApplyCompareOp> {
+ public:
+  using OpRewritePattern::OpRewritePattern;
+  LogicalResult matchAndRewrite(ApplyCompareOp op,
+                                PatternRewriter &rewriter) const override {
+    auto boxLeft = op.left().getDefiningOp<BoxOp>();
+    auto boxRight = op.right().getDefiningOp<BoxOp>();
+    if (!boxLeft || !boxRight) return failure();
+    if (boxLeft.primitive().getType() != boxRight.primitive().getType())
+      return failure();
+    rewriter.replaceOpWithNewOp<ApplyCompareOp>(
+        op, rewriter.getType<BoolType>(), op.dunder_nameAttr(),
+        boxLeft.primitive(), boxRight.primitive());
+    return success();
+  }
+};
+
+}  // namespace
+
+void ApplyCompareOp::getCanonicalizationPatterns(RewritePatternSet &patterns,
+                                                 MLIRContext *context) {
+  patterns.add<UnboxApplyCompareOperands>(context);
+}
+
+//===----------------------------------------------------------------------===//
 // AsBoolOp
 //===----------------------------------------------------------------------===//