diff --git a/llvm-external-projects/iree-dialects/lib/Dialect/PyDM/IR/CMakeLists.txt b/llvm-external-projects/iree-dialects/lib/Dialect/PyDM/IR/CMakeLists.txt
new file mode 100644
index 0000000..7ca64d8
--- /dev/null
+++ b/llvm-external-projects/iree-dialects/lib/Dialect/PyDM/IR/CMakeLists.txt
@@ -0,0 +1,16 @@
+add_mlir_library(IREEPyDMDialect
+  PyDMDialect.cpp
+  PyDMOps.cpp
+
+  ADDITIONAL_HEADER_DIRS
+  ${IREE_DIALECTS_SOURCE_DIR}/include
+
+  DEPENDS
+  IREEPyDMIncGen
+
+  LINK_LIBS PUBLIC
+  MLIRIR
+  MLIRSideEffectInterfaces
+)
+
+iree_dialects_target_includes(IREEPyDMDialect)
diff --git a/llvm-external-projects/iree-dialects/lib/Dialect/PyDM/IR/PyDMDialect.cpp b/llvm-external-projects/iree-dialects/lib/Dialect/PyDM/IR/PyDMDialect.cpp
new file mode 100644
index 0000000..5db10f7
--- /dev/null
+++ b/llvm-external-projects/iree-dialects/lib/Dialect/PyDM/IR/PyDMDialect.cpp
@@ -0,0 +1,337 @@
+// Copyright 2021 The IREE Authors
+//
+// Licensed under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#include "iree-dialects/Dialect/PyDM/IR/PyDMDialect.h"
+
+#include "iree-dialects/Dialect/PyDM/IR/PyDMInterfaces.h"
+#include "iree-dialects/Dialect/PyDM/IR/PyDMOps.h"
+#include "llvm/ADT/TypeSwitch.h"
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/DialectImplementation.h"
+#include "mlir/Support/LLVM.h"
+
+using namespace mlir;
+namespace PYDM = mlir::iree_compiler::IREE::PYDM;
+using namespace PYDM;
+
+#include "iree-dialects/Dialect/PyDM/IR/PyDMDialect.cpp.inc"
+#include "iree-dialects/Dialect/PyDM/IR/PyDMOpInterfaces.cpp.inc"
+#include "iree-dialects/Dialect/PyDM/IR/PyDMTypeInterfaces.cpp.inc"
+#define GET_TYPEDEF_CLASSES
+#include "iree-dialects/Dialect/PyDM/IR/PyDMTypes.cpp.inc"
+
+//------------------------------------------------------------------------------
+// Dialect implementation
+//------------------------------------------------------------------------------
+
+using BuiltinIntegerType = mlir::IntegerType;
+
+using PyBoolType = PYDM::BoolType;
+using PyConstantOp = PYDM::ConstantOp;
+using PyIntegerType = PYDM::IntegerType;
+using PyRealType = PYDM::RealType;
+
+void IREEPyDMDialect::initialize() {
+  addTypes<
+#define GET_TYPEDEF_LIST
+#include "iree-dialects/Dialect/PyDM/IR/PyDMTypes.cpp.inc"
+      >();
+  addOperations<
+#define GET_OP_LIST
+#include "iree-dialects/Dialect/PyDM/IR/PyDMOps.cpp.inc"
+      >();
+}
+
+Operation *IREEPyDMDialect::materializeConstant(OpBuilder &builder,
+                                                Attribute value, Type type,
+                                                Location loc) {
+  // Since we support materialization of builtin types too, explicitly
+  // allow these.
+  if (type.isa<PyBoolType, BytesType, PyIntegerType, PyRealType, StrType,
+               BuiltinIntegerType>()) {
+    return builder.create<PYDM::ConstantOp>(loc, type, value);
+  }
+
+  if (type.isa<NoneType>()) {
+    return builder.create<PYDM::NoneOp>(loc, type);
+  }
+
+  if (type.isa<ExceptionResultType>() && value.isa<UnitAttr>()) {
+    return builder.create<PYDM::SuccessOp>(loc, type);
+  }
+
+  llvm_unreachable("unhandled iree_pydm constant materialization");
+}
+
+Type IREEPyDMDialect::parseType(DialectAsmParser &parser) const {
+  StringRef typeTag;
+  if (succeeded(parser.parseKeyword(&typeTag))) {
+    Type genType;
+    auto parseResult = generatedTypeParser(parser, typeTag, genType);
+    if (parseResult.hasValue()) {
+      if (*parseResult) {
+        return Type();
+      }
+      return genType;
+    }
+  }
+
+  parser.emitError(parser.getNameLoc(), "unknown dialect type");
+  return Type();
+}
+
+void IREEPyDMDialect::printType(Type type, DialectAsmPrinter &printer) const {
+  (void)generatedTypePrinter(type, printer);
+}
+
+//------------------------------------------------------------------------------
+// Python type implementation
+//------------------------------------------------------------------------------
+
+// BoolType
+BuiltinTypeCode PYDM::BoolType::getTypeCode() const {
+  return static_cast<BuiltinTypeCode>(
+      makeNumericTypeCode(*getNumericCategory(), *getNumericSubTypeCode()));
+}
+
+StringRef PYDM::BoolType::getPythonTypeName() const { return "bool"; }
+
+Optional<NumericCategory> PYDM::BoolType::getNumericCategory() const {
+  return NumericCategory::Bool;
+}
+
+Optional<int> PYDM::BoolType::getNumericSubTypeCode() const { return 0; }
+
+Optional<int> PYDM::BoolType::getNumericPromotionOrder() const {
+  return static_cast<int>(getTypeCode());
+}
+
+// BytesType
+BuiltinTypeCode PYDM::BytesType::getTypeCode() const {
+  return BuiltinTypeCode::Bytes;
+}
+
+StringRef PYDM::BytesType::getPythonTypeName() const { return "bytes"; }
+
+// ExceptionResultType
+BuiltinTypeCode PYDM::ExceptionResultType::getTypeCode() const {
+  return BuiltinTypeCode::ExceptionResult;
+}
+
+StringRef PYDM::ExceptionResultType::getPythonTypeName() const {
+  return "Exception";
+}
+
+// IntegerType
+LogicalResult PYDM::IntegerType::verify(
+    function_ref<InFlightDiagnostic()> emitError, Optional<int> bitWidth) {
+  if (!bitWidth) return success();
+  int w = abs(*bitWidth);
+  if (w == 0 || w == 8 || w == 16 || w == 32 || w == 64) return success();
+  return emitError() << "unsupported python integer bit width: " << w;
+}
+
+BuiltinTypeCode PYDM::IntegerType::getTypeCode() const {
+  return static_cast<BuiltinTypeCode>(
+      makeNumericTypeCode(*getNumericCategory(), *getNumericSubTypeCode()));
+}
+
+StringRef PYDM::IntegerType::getPythonTypeName() const { return "int"; }
+
+Optional<NumericCategory> PYDM::IntegerType::getNumericCategory() const {
+  if (isWeak()) return NumericCategory::WeakInteger;
+  if (getBitWidth() == 0) return NumericCategory::APSigned;
+  if (isSigned()) return NumericCategory::Signed;
+  return NumericCategory::Unsigned;
+}
+
+Optional<int> PYDM::IntegerType::getNumericSubTypeCode() const {
+  if (isWeak()) return 0;
+  IntegerSubTypeCode stc;
+  switch (getBitWidth()) {
+    case 8:
+      stc = IntegerSubTypeCode::Integer8;
+      break;
+    case 16:
+      stc = IntegerSubTypeCode::Integer16;
+      break;
+    case 32:
+      stc = IntegerSubTypeCode::Integer32;
+      break;
+    case 64:
+      stc = IntegerSubTypeCode::Integer64;
+      break;
+    default: {
+      llvm_unreachable("unsupported numeric bitwidth");
+    }
+  }
+  return static_cast<int>(stc);
+}
+
+Optional<int> PYDM::IntegerType::getNumericPromotionOrder() const {
+  return static_cast<int>(getTypeCode());
+}
+
+bool PYDM::IntegerType::isWeak() const { return !getImpl()->bitWidth; }
+
+unsigned PYDM::IntegerType::getBitWidth() const {
+  return abs(*getImpl()->bitWidth);
+}
+
+bool PYDM::IntegerType::isSigned() const { return *getImpl()->bitWidth >= 0; }
+
+BuiltinTypeCode PYDM::ListType::getTypeCode() const {
+  return BuiltinTypeCode::List;
+}
+
+// ListType
+StringRef PYDM::ListType::getPythonTypeName() const { return "list"; }
+
+BuiltinTypeCode PYDM::NoneType::getTypeCode() const {
+  return BuiltinTypeCode::List;
+}
+
+bool PYDM::ListType::isRefinable() const {
+  if (getStorageClass() == CollectionStorageClass::Empty) return false;
+
+  if (!getUniformElementType()) return true;
+
+  if (auto pyType = getUniformElementType().dyn_cast<PythonTypeInterface>())
+    return pyType.isRefinable();
+
+  return false;
+}
+
+Type PYDM::ListType::getElementStorageType() const {
+  switch (getStorageClass()) {
+    case CollectionStorageClass::Boxed:
+    case CollectionStorageClass::Empty:
+      return ObjectType::get(getContext());
+    case CollectionStorageClass::Unboxed:
+      assert(getUniformElementType() &&
+             "unboxed list should have uniform element type");
+      return getUniformElementType();
+    default:
+      llvm_unreachable("unsupported storage class");
+      return {};
+  }
+}
+
+// NoneType
+StringRef PYDM::NoneType::getPythonTypeName() const { return "None"; }
+
+// ObjectType
+BuiltinTypeCode PYDM::ObjectType::getTypeCode() const {
+  return BuiltinTypeCode::Object;
+}
+
+StringRef PYDM::ObjectType::getPythonTypeName() const { return "object"; }
+
+bool PYDM::ObjectType::isRefinable() const {
+  if (!getPrimitiveType()) return true;
+
+  if (auto pyType = getPrimitiveType().dyn_cast<PythonTypeInterface>())
+    return pyType.isRefinable();
+
+  return false;
+}
+
+// RealType
+LogicalResult PYDM::RealType::verify(
+    function_ref<InFlightDiagnostic()> emitError, FloatType floatType) {
+  if (!floatType) return success();
+  if (!floatType.isa<BFloat16Type, Float16Type, Float32Type, Float64Type>()) {
+    return emitError() << "unsupported Python floating point type: "
+                       << floatType;
+  }
+  return success();
+}
+
+BuiltinTypeCode PYDM::RealType::getTypeCode() const {
+  return static_cast<BuiltinTypeCode>(
+      makeNumericTypeCode(*getNumericCategory(), *getNumericSubTypeCode()));
+}
+
+StringRef PYDM::RealType::getPythonTypeName() const { return "float"; }
+
+Optional<NumericCategory> PYDM::RealType::getNumericCategory() const {
+  if (isWeak()) return NumericCategory::WeakReal;
+  return NumericCategory::Real;
+}
+
+Optional<int> PYDM::RealType::getNumericSubTypeCode() const {
+  if (isWeak()) return 0;
+  RealSubTypeCode stc =
+      TypeSwitch<Type, RealSubTypeCode>(getFloatType())
+          .Case([](BFloat16Type t) { return RealSubTypeCode::BF16; })
+          .Case([](Float16Type t) { return RealSubTypeCode::FP16; })
+          .Case([](Float32Type t) { return RealSubTypeCode::FP32; })
+          .Case([](Float64Type t) { return RealSubTypeCode::FP64; })
+          .Default([](Type t) {
+            llvm_unreachable("unsupported float type");
+            return RealSubTypeCode::FP64;
+          });
+  return static_cast<int>(stc);
+}
+
+Optional<int> PYDM::RealType::getNumericPromotionOrder() const {
+  return static_cast<int>(getTypeCode());
+}
+
+bool PYDM::RealType::isWeak() const { return !getImpl()->floatType; }
+
+// StrType
+BuiltinTypeCode PYDM::StrType::getTypeCode() const {
+  return BuiltinTypeCode::Str;
+}
+
+StringRef PYDM::StrType::getPythonTypeName() const { return "str"; }
+
+// TupleType
+BuiltinTypeCode PYDM::TupleType::getTypeCode() const {
+  return BuiltinTypeCode::Tuple;
+}
+
+StringRef PYDM::TupleType::getPythonTypeName() const { return "tuple"; }
+
+// TypeType
+BuiltinTypeCode PYDM::TypeType::getTypeCode() const {
+  return BuiltinTypeCode::Type;
+}
+
+StringRef PYDM::TypeType::getPythonTypeName() const { return "type"; }
+
+Type PYDM::TupleType::getElementStorageType() const {
+  // TODO: When it implements unboxed storage, switch here.
+  return ObjectType::get(getContext());
+}
+
+//------------------------------------------------------------------------------
+// Union type implementation
+//------------------------------------------------------------------------------
+
+LogicalResult PYDM::UnionType::verify(
+    llvm::function_ref<InFlightDiagnostic()> emitError,
+    ArrayRef<Type> alternatives) {
+  int lastTypeCode = 0;
+  for (Type alternative : alternatives) {
+    if (auto pythonType = alternative.dyn_cast<PYDM::PythonTypeInterface>()) {
+      int thisTypeCode = static_cast<int>(pythonType.getTypeCode());
+      // TODO: This doesn't account for parameterized types.
+      if (thisTypeCode <= lastTypeCode) {
+        return emitError() << "expected total order of union to be normative. "
+                              "got out of order: "
+                           << alternative;
+      }
+    } else {
+      return emitError() << "expected a python type in union. got: "
+                         << alternative;
+    }
+  }
+
+  return failure();
+}
diff --git a/llvm-external-projects/iree-dialects/lib/Dialect/PyDM/IR/PyDMOps.cpp b/llvm-external-projects/iree-dialects/lib/Dialect/PyDM/IR/PyDMOps.cpp
new file mode 100644
index 0000000..7ef7bfc
--- /dev/null
+++ b/llvm-external-projects/iree-dialects/lib/Dialect/PyDM/IR/PyDMOps.cpp
@@ -0,0 +1,810 @@
+// Copyright 2021 The IREE Authors
+//
+// Licensed under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#include "iree-dialects/Dialect/PyDM/IR/PyDMOps.h"
+
+#include "iree-dialects/Dialect/PyDM/IR/PyDMDialect.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/TypeSwitch.h"
+#include "llvm/Support/Debug.h"
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/FunctionImplementation.h"
+#include "mlir/IR/OpImplementation.h"
+#include "mlir/IR/TypeUtilities.h"
+
+using namespace mlir;
+namespace PYDM = mlir::iree_compiler::IREE::PYDM;
+using namespace PYDM;
+
+using llvm::dbgs;
+
+using PyBoolType = PYDM::BoolType;
+using PyConstantOp = PYDM::ConstantOp;
+using PyIntegerType = PYDM::IntegerType;
+using PyRealType = PYDM::RealType;
+using PyCallOp = PYDM::CallOp;
+using PyFuncOp = PYDM::FuncOp;
+
+static LogicalResult verify(Operation *) { return success(); }
+
+//===----------------------------------------------------------------------===//
+// Utilities
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+/// Generic pattern to unbox any operands that are a specific object
+/// type (i.e. object<integer>).
+struct UnboxOperands : public RewritePattern {
+  UnboxOperands(StringRef rootName, MLIRContext *context,
+                Optional<llvm::SmallSet<int, 4>> operandIndices = None)
+      : RewritePattern(rootName, 1, context), operandIndices(operandIndices) {}
+  LogicalResult matchAndRewrite(Operation *op,
+                                PatternRewriter &rewriter) const override {
+    Location loc = op->getLoc();
+    bool changed = false;
+    SmallVector<Value> operands(op->getOperands());
+    auto excResultType = rewriter.getType<ExceptionResultType>();
+    for (int operandIndex = 0, e = operands.size(); operandIndex < e;
+         ++operandIndex) {
+      Value &operand = operands[operandIndex];
+      if (operandIndices && !operandIndices->contains(operandIndex)) continue;
+      if (auto objectType = operand.getType().dyn_cast<ObjectType>()) {
+        Type primitiveType = objectType.getPrimitiveType();
+        if (primitiveType) {
+          // Unbox.
+          auto unboxOp = rewriter.create<UnboxOp>(
+              loc, TypeRange{excResultType, primitiveType}, operand);
+          operand = unboxOp.primitive();
+          changed = true;
+        }
+      }
+    }
+
+    if (changed) {
+      rewriter.updateRootInPlace(op, [&]() { op->setOperands(operands); });
+      return success();
+    }
+
+    return failure();
+  }
+  Optional<llvm::SmallSet<int, 4>> operandIndices;
+};
+
+}  // namespace
+
+static Value getNumericZeroConstant(Location loc, Type numericType,
+                                    OpBuilder &builder) {
+  return TypeSwitch<Type, Value>(numericType)
+      .Case([&](PyBoolType t) -> Value {
+        return builder.create<PyConstantOp>(loc, t, builder.getBoolAttr(false));
+      })
+      .Case([&](PyIntegerType t) -> Value {
+        return builder.create<PyConstantOp>(loc, t,
+                                            builder.getI64IntegerAttr(0));
+      })
+      .Case([&](PyRealType t) -> Value {
+        return builder.create<PyConstantOp>(loc, t,
+                                            builder.getF64FloatAttr(0.0));
+      });
+}
+
+static Value getBoolConstant(Location loc, bool pred, OpBuilder &builder) {
+  return builder.create<PyConstantOp>(loc, builder.getType<BoolType>(),
+                                      builder.getBoolAttr(pred));
+}
+
+//===----------------------------------------------------------------------===//
+// Constants
+//===----------------------------------------------------------------------===//
+
+OpFoldResult PyConstantOp::fold(ArrayRef<Attribute> operands) {
+  assert(operands.empty() && "constant has no operands");
+  return getValue();
+}
+
+OpFoldResult NoneOp::fold(ArrayRef<Attribute> operands) {
+  assert(operands.empty() && "constant has no operands");
+  return UnitAttr::get(getContext());
+}
+
+OpFoldResult SuccessOp::fold(ArrayRef<Attribute> operands) {
+  assert(operands.empty() && "constant has no operands");
+  return UnitAttr::get(getContext());
+}
+
+//===----------------------------------------------------------------------===//
+// Variables
+//===----------------------------------------------------------------------===//
+
+void AllocFreeVarOp::getAsmResultNames(OpAsmSetValueNameFn setNameFn) {
+  setNameFn(getResult(), name());
+}
+
+//===----------------------------------------------------------------------===//
+// ApplyBinaryOp
+//===----------------------------------------------------------------------===//
+
+namespace {
+struct ApplyBinaryToSequenceClone : public OpRewritePattern<ApplyBinaryOp> {
+  using OpRewritePattern::OpRewritePattern;
+  LogicalResult matchAndRewrite(ApplyBinaryOp op,
+                                PatternRewriter &rewriter) const override {
+    if (op.dunder_name() != "mul") return failure();
+    Value listOperand;
+    Value countOperand;
+    if (isBuiltinSequence(op.left()) && isInteger(op.right())) {
+      listOperand = op.left();
+      countOperand = op.right();
+    } else if (isInteger(op.left()) && isBuiltinSequence(op.right())) {
+      countOperand = op.left();
+      listOperand = op.right();
+    } else {
+      return failure();
+    }
+    Type resultType = op.getResult().getType();
+    rewriter.replaceOpWithNewOp<SequenceCloneOp>(op, resultType, listOperand,
+                                                 countOperand);
+    return success();
+  }
+
+  static bool isBuiltinSequence(Value operand) {
+    return operand.getType().isa<PYDM::ListType, PYDM::TupleType>();
+  }
+  static bool isInteger(Value operand) {
+    return operand.getType().isa<PYDM::IntegerType>();
+  }
+};
+}  // namespace
+
+void ApplyBinaryOp::getCanonicalizationPatterns(RewritePatternSet &patterns,
+                                                MLIRContext *context) {
+  patterns.add<UnboxOperands>(getOperationName(), context);
+  patterns.add<ApplyBinaryToSequenceClone>(context);
+}
+
+bool ApplyBinaryOp::refineResultTypes() {
+  auto leftType = left().getType();
+  auto rightType = right().getType();
+  auto applyUpdates = [&](Type newResultType) -> bool {
+    if (newResultType != getResult().getType()) {
+      getResult().setType(newResultType);
+      return true;
+    }
+    return false;
+  };
+
+  // Both numeric types. It is only dynamically legal for statically known
+  // numeric types to be the same, in which case the result type must be the
+  // same as well.
+  auto ptLeft = leftType.dyn_cast<PythonTypeInterface>();
+  auto ptRight = rightType.dyn_cast<PythonTypeInterface>();
+  if (ptLeft && ptRight && ptLeft.getNumericPromotionOrder() &&
+      ptRight.getNumericPromotionOrder()) {
+    if (leftType == rightType) {
+      return applyUpdates(leftType);
+    }
+  }
+
+  // (list, integer) or (integer, list) refine to the list type.
+  if (dunder_name() == "mul") {
+    auto leftList = leftType.dyn_cast<ListType>();
+    auto rightList = rightType.dyn_cast<ListType>();
+    auto leftInteger = leftType.dyn_cast<IntegerType>();
+    auto rightInteger = rightType.dyn_cast<IntegerType>();
+    if (leftList && rightInteger) {
+      return applyUpdates(leftList);
+    } else if (leftInteger && rightList) {
+      return applyUpdates(rightList);
+    }
+  }
+
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// ApplyCompareOp
+//===----------------------------------------------------------------------===//
+
+void ApplyCompareOp::getCanonicalizationPatterns(RewritePatternSet &patterns,
+                                                 MLIRContext *context) {
+  patterns.add<UnboxOperands>(getOperationName(), context);
+}
+
+//===----------------------------------------------------------------------===//
+// AsBoolOp
+//===----------------------------------------------------------------------===//
+
+namespace {
+struct FoldAsBoolFromBool : public OpRewritePattern<AsBoolOp> {
+ public:
+  using OpRewritePattern::OpRewritePattern;
+  LogicalResult matchAndRewrite(AsBoolOp op,
+                                PatternRewriter &rewriter) const override {
+    if (op.value().getType().isa<BoolType>()) {
+      rewriter.replaceOp(op, op.value());
+      return success();
+    }
+    return failure();
+  }
+};
+
+struct FoldAsBoolFromNumeric : public OpRewritePattern<AsBoolOp> {
+ public:
+  using OpRewritePattern::OpRewritePattern;
+  LogicalResult matchAndRewrite(AsBoolOp op,
+                                PatternRewriter &rewriter) const override {
+    auto loc = op.getLoc();
+    auto ptType = op.value().getType().dyn_cast<PythonTypeInterface>();
+    if (!ptType) return failure();
+    if (!ptType.getNumericPromotionOrder()) return failure();
+
+    auto boolType = rewriter.getType<BoolType>();
+    Value zeroValue =
+        getNumericZeroConstant(loc, op.value().getType(), rewriter);
+    Value trueValue = getBoolConstant(loc, true, rewriter);
+    Value falseValue = getBoolConstant(loc, false, rewriter);
+    Value cmpResult = rewriter.create<ApplyCompareOp>(
+        loc, boolType, rewriter.getStringAttr("eq"), op.value(), zeroValue);
+    rewriter.replaceOpWithNewOp<SelectOp>(op, boolType, cmpResult, falseValue,
+                                          trueValue);
+    return success();
+  }
+};
+
+}  // namespace
+
+void AsBoolOp::getCanonicalizationPatterns(RewritePatternSet &patterns,
+                                           MLIRContext *context) {
+  patterns.add<FoldAsBoolFromBool, FoldAsBoolFromNumeric>(context);
+}
+
+OpFoldResult AsBoolOp::fold(ArrayRef<Attribute> operands) {
+  Builder b(getContext());
+  // Fold NoneType to False.
+  if (value().getType().isa<NoneType>()) {
+    return b.getBoolAttr(false);
+  }
+
+  return {};
+}
+
+//===----------------------------------------------------------------------===//
+// AssignSubscriptOp
+//===----------------------------------------------------------------------===//
+
+void AssignSubscriptOp::getCanonicalizationPatterns(RewritePatternSet &patterns,
+                                                    MLIRContext *context) {
+  llvm::SmallSet<int, 4> unboxIndices;
+  unboxIndices.insert(0);
+  unboxIndices.insert(1);
+  patterns.add<UnboxOperands>(getOperationName(), context, unboxIndices);
+}
+
+//===----------------------------------------------------------------------===//
+// BoolToPredOp
+//===----------------------------------------------------------------------===//
+
+OpFoldResult BoolToPredOp::fold(ArrayRef<Attribute> operands) {
+  if (!operands[0]) return {};
+  // Since both BoolType and I1 share the attribute form (an IntegerAttr of I1),
+  // we can just return it.
+  return operands[0];
+}
+
+//===----------------------------------------------------------------------===//
+// BoxOp and UnboxOp
+//===----------------------------------------------------------------------===//
+
+LogicalResult BoxOp::canonicalize(BoxOp op, PatternRewriter &rewriter) {
+  // Sometimes boxes are emitted when the input is an object. Just remove.
+  if (op.primitive().getType().isa<ObjectType>()) {
+    rewriter.replaceOp(op, op.primitive());
+    return success();
+  }
+
+  // Box to an appropriate type and static info cast.
+  ObjectType objectType = rewriter.getType<ObjectType>(nullptr);
+  if (op.object().getType() == objectType &&
+      !op.primitive().getType().isa<ObjectType>()) {
+    auto refinedBox = rewriter.create<BoxOp>(
+        op.getLoc(),
+        rewriter.getType<ObjectType>(
+            op.primitive().getType().cast<PrimitiveType>()),
+        op.primitive());
+    rewriter.replaceOpWithNewOp<StaticInfoCastOp>(op, op.object().getType(),
+                                                  refinedBox);
+    return success();
+  }
+
+  return failure();
+}
+
+LogicalResult UnboxOp::canonicalize(UnboxOp unboxOp,
+                                    PatternRewriter &rewriter) {
+  auto loc = unboxOp.getLoc();
+
+  // Handle the case of an immediate BoxOp producer.
+  if (auto boxProducer =
+          dyn_cast_or_null<BoxOp>(unboxOp.object().getDefiningOp())) {
+    // If the producer is boxing to the same type we are unboxing, then
+    // just elide everything.
+    if (boxProducer.primitive().getType() == unboxOp.primitive().getType()) {
+      auto successValue = rewriter.create<SuccessOp>(
+          loc, rewriter.getType<ExceptionResultType>());
+      rewriter.replaceOp(unboxOp, {successValue, boxProducer.primitive()});
+      return success();
+    }
+  }
+  return failure();
+}
+
+//===----------------------------------------------------------------------===//
+// DynamicBinaryPromoteOp
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+/// Resolves a DynamicBinaryPromote over numeric operands to either elide
+/// or insert specific PromoteNumeric ops.
+struct ResolveNumericDynamicBinaryPromote
+    : public OpRewritePattern<DynamicBinaryPromoteOp> {
+ public:
+  using OpRewritePattern::OpRewritePattern;
+  LogicalResult matchAndRewrite(DynamicBinaryPromoteOp op,
+                                PatternRewriter &rewriter) const override {
+    auto loc = op.getLoc();
+    auto leftType = op.left().getType();
+    auto rightType = op.right().getType();
+    auto leftResultType = op.getResultTypes()[0];
+    auto rightResultType = op.getResultTypes()[1];
+    auto leftPt = leftType.dyn_cast<PythonTypeInterface>();
+    auto rightPt = rightType.dyn_cast<PythonTypeInterface>();
+    if (!leftPt || !rightPt) return failure();
+
+    Optional<int> leftOrder = leftPt.getNumericPromotionOrder();
+    Optional<int> rightOrder = rightPt.getNumericPromotionOrder();
+    Value newLeft = op.left();
+    Value newRight = op.right();
+
+    if (leftOrder && rightOrder) {
+      // Both numeric.
+      if (*leftOrder > *rightOrder) {
+        newRight = rewriter.create<PromoteNumericOp>(loc, leftType, newRight);
+      }
+      if (*rightOrder > *leftOrder) {
+        newLeft = rewriter.create<PromoteNumericOp>(loc, rightType, newLeft);
+      }
+    } else {
+      return failure();
+    }
+
+    // Need to box back to the original type (which will always be a generic
+    // object).
+    newLeft = rewriter.create<BoxOp>(loc, leftResultType, newLeft);
+    newRight = rewriter.create<BoxOp>(loc, rightResultType, newRight);
+
+    rewriter.replaceOp(op, {newLeft, newRight});
+    return success();
+  }
+};
+
+/// If we statically determine one of the arguments to be a concrete, non
+/// numeric type, then the op has no meaning and is elided.
+struct ElideNonNumericDynamicBinaryPromote
+    : public OpRewritePattern<DynamicBinaryPromoteOp> {
+ public:
+  using OpRewritePattern::OpRewritePattern;
+  LogicalResult matchAndRewrite(DynamicBinaryPromoteOp op,
+                                PatternRewriter &rewriter) const override {
+    if ((!isConcreteNonNumericType(op.left().getType()) &&
+         !isConcreteNonNumericType(op.right().getType())))
+      return failure();
+
+    // Since DynamicBinaryPromote already returns object, and we only match
+    // non-object operands, box them back.
+    auto loc = op.getLoc();
+    auto leftResultType = op.getResultTypes()[0];
+    auto rightResultType = op.getResultTypes()[1];
+    Value newLeft = rewriter.create<BoxOp>(loc, leftResultType, op.left());
+    Value newRight = rewriter.create<BoxOp>(loc, rightResultType, op.right());
+    rewriter.replaceOp(op, {newLeft, newRight});
+    return success();
+  }
+
+  static bool isConcreteNonNumericType(Type t) {
+    if (t.isa<ObjectType>()) return false;
+    auto pt = t.dyn_cast<PythonTypeInterface>();
+    if (!pt || pt.getNumericPromotionOrder()) return false;
+    return true;
+  }
+};
+
+}  // namespace
+
+void DynamicBinaryPromoteOp::getCanonicalizationPatterns(
+    RewritePatternSet &patterns, MLIRContext *context) {
+  patterns.add<ResolveNumericDynamicBinaryPromote>(context);
+  patterns.add<UnboxOperands>(getOperationName(), context);
+  patterns.add<ElideNonNumericDynamicBinaryPromote>(context);
+}
+
+//===----------------------------------------------------------------------===//
+// FunctionalIfOp
+//===----------------------------------------------------------------------===//
+
+::llvm::StringRef FunctionalIfOp::getDefaultDialect() { return "iree_pydm"; }
+
+static LogicalResult verify(FunctionalIfOp op) {
+  if (op.getNumResults() != 0 && op.elseRegion().empty())
+    return op.emitOpError("must have an else block if defining values");
+
+  return RegionBranchOpInterface::verifyTypes(op);
+}
+
+static ParseResult parseFunctionalIfOp(OpAsmParser &parser,
+                                       OperationState &result) {
+  // Create the regions for 'then'.
+  result.regions.reserve(2);
+  Region *thenRegion = result.addRegion();
+  Region *elseRegion = result.addRegion();
+
+  auto &builder = parser.getBuilder();
+  OpAsmParser::OperandType cond;
+  Type conditionType = builder.getType<PyBoolType>();
+  if (parser.parseOperand(cond) ||
+      parser.resolveOperand(cond, conditionType, result.operands))
+    return failure();
+  // Parse optional results type list.
+  if (parser.parseOptionalArrowTypeList(result.types)) return failure();
+  // Parse the 'then' region.
+  if (parser.parseRegion(*thenRegion, /*arguments=*/{}, /*argTypes=*/{}))
+    return failure();
+  // IfOp::ensureTerminator(*thenRegion, parser.getBuilder(), result.location);
+
+  // If we find an 'else' keyword then parse the 'else' region.
+  if (!parser.parseOptionalKeyword("else")) {
+    if (parser.parseRegion(*elseRegion, /*arguments=*/{}, /*argTypes=*/{}))
+      return failure();
+    // IfOp::ensureTerminator(*elseRegion, parser.getBuilder(),
+    // result.location);
+  }
+
+  // Parse the optional attribute list.
+  if (parser.parseOptionalAttrDict(result.attributes)) return failure();
+  return success();
+}
+
+static void print(OpAsmPrinter &p, FunctionalIfOp op) {
+  bool printBlockTerminators = false;
+
+  p << " " << op.condition();
+  if (!op.results().empty()) {
+    p << " -> (" << op.getResultTypes() << ")";
+    // Print yield explicitly if the op defines values.
+    printBlockTerminators = true;
+  }
+  p.printRegion(op.thenRegion(),
+                /*printEntryBlockArgs=*/false,
+                /*printBlockTerminators=*/printBlockTerminators);
+
+  // Print the 'else' regions if it exists and has a block.
+  auto &elseRegion = op.elseRegion();
+  if (!elseRegion.empty()) {
+    p << " else";
+    p.printRegion(elseRegion,
+                  /*printEntryBlockArgs=*/false,
+                  /*printBlockTerminators=*/printBlockTerminators);
+  }
+
+  p.printOptionalAttrDict(op->getAttrs());
+}
+
+/// Given the region at `index`, or the parent operation if `index` is None,
+/// return the successor regions. These are the regions that may be selected
+/// during the flow of control. `operands` is a set of optional attributes that
+/// correspond to a constant value for each operand, or null if that operand is
+/// not a constant.
+void FunctionalIfOp::getSuccessorRegions(
+    Optional<unsigned> index, ArrayRef<Attribute> operands,
+    SmallVectorImpl<RegionSuccessor> &regions) {
+  // The `then` and the `else` region branch back to the parent operation.
+  if (index.hasValue()) {
+    regions.push_back(RegionSuccessor(getResults()));
+    return;
+  }
+
+  // Don't consider the else region if it is empty.
+  Region *elseRegion = &this->elseRegion();
+  if (elseRegion->empty()) elseRegion = nullptr;
+
+  // Otherwise, the successor is dependent on the condition.
+  if (auto condAttr = operands.front().dyn_cast_or_null<BoolAttr>()) {
+    bool condition = condAttr.getValue();
+    // Add the successor regions using the condition.
+    regions.push_back(RegionSuccessor(condition ? &thenRegion() : elseRegion));
+  } else {
+    // If the condition isn't constant, both regions may be executed.
+    regions.push_back(RegionSuccessor(&thenRegion()));
+    // If the else region does not exist, it is not a viable successor.
+    if (elseRegion) regions.push_back(RegionSuccessor(elseRegion));
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// FuncOp
+//===----------------------------------------------------------------------===//
+
+::llvm::StringRef PyFuncOp::getDefaultDialect() { return "iree_pydm"; }
+
+LogicalResult PyFuncOp::verifyType() {
+  // TODO: Enforce arg/result invariants.
+  return success();
+}
+
+static ParseResult parseFuncOp(OpAsmParser &parser, OperationState &result) {
+  auto buildFuncType = [](Builder &builder, ArrayRef<Type> argTypes,
+                          ArrayRef<Type> results,
+                          function_like_impl::VariadicFlag, std::string &) {
+    return builder.getFunctionType(argTypes, results);
+  };
+
+  return function_like_impl::parseFunctionLikeOp(
+      parser, result, /*allowVariadic=*/false, buildFuncType);
+}
+
+static void print(PyFuncOp op, OpAsmPrinter &p) {
+  FunctionType fnType = op.getType();
+  function_like_impl::printFunctionLikeOp(
+      p, op, fnType.getInputs(), /*isVariadic=*/false, fnType.getResults());
+}
+
+static LogicalResult verify(PyFuncOp op) {
+  // TODO: Enforce invariants.
+  return success();
+}
+
+//===----------------------------------------------------------------------===//
+// MakeListOp
+//===----------------------------------------------------------------------===//
+
+static LogicalResult verify(MakeListOp op) {
+  auto listType = op.list().getType().cast<ListType>();
+  switch (listType.getStorageClass()) {
+    case CollectionStorageClass::Boxed:
+      for (auto element : op.elements()) {
+        if (!element.getType().isa<ObjectType>()) {
+          return op.emitOpError() << "making a list with boxed storage class "
+                                     "must have object elements. Got: "
+                                  << element.getType();
+        }
+      }
+      break;
+    case CollectionStorageClass::Unboxed:
+      for (auto element : op.elements()) {
+        if (element.getType().isa<ObjectType>()) {
+          return op.emitOpError() << "making a list with unboxed storage class "
+                                     "must not have object elements. Got: "
+                                  << element.getType();
+        }
+      }
+      break;
+    case CollectionStorageClass::Empty:
+      if (!op.elements().empty()) {
+        return op.emitOpError()
+               << "making a list with empty storage class must have zero "
+                  "elements";
+      }
+      break;
+  }
+  return success();
+}
+
+//===----------------------------------------------------------------------===//
+// NegOp
+//===----------------------------------------------------------------------===//
+
+void NegOp::getCanonicalizationPatterns(RewritePatternSet &patterns,
+                                        MLIRContext *context) {
+  patterns.add<UnboxOperands>(getOperationName(), context);
+}
+
+bool NegOp::refineResultTypes() {
+  if (value().getType() != getResult().getType()) {
+    getResult().setType(value().getType());
+    return true;
+  }
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// PatternMatchCallOp
+//===----------------------------------------------------------------------===//
+
+LogicalResult PatternMatchCallOp::verifySymbolUses(
+    SymbolTableCollection &symbolTable) {
+  auto verifySymbols = [&](ArrayAttr symbols) -> LogicalResult {
+    for (auto symbolAttr : symbols) {
+      auto symbol = symbolAttr.cast<FlatSymbolRefAttr>();
+      PyFuncOp fn =
+          symbolTable.lookupNearestSymbolFrom<PyFuncOp>(*this, symbol);
+      if (!fn)
+        return emitOpError() << "'" << symbol.getValue()
+                             << "' does not reference a valid function";
+    }
+    return success();
+  };
+  auto genericsAttr = (*this)->getAttrOfType<ArrayAttr>("generic_match");
+  if (!genericsAttr)
+    return emitOpError(
+        "requires a 'generic_match' array of symbol reference attributes");
+  if (failed(verifySymbols(genericsAttr))) return failure();
+
+  auto specificsAttr = (*this)->getAttrOfType<ArrayAttr>("specific_match");
+  if (!specificsAttr)
+    return emitOpError(
+        "requires a 'specific_match' array of symbol reference attributes");
+  if (failed(verifySymbols(specificsAttr))) return failure();
+
+  return success();
+}
+
+//===----------------------------------------------------------------------===//
+// PromoteNumericOp
+//===----------------------------------------------------------------------===//
+
+OpFoldResult PromoteNumericOp::fold(ArrayRef<Attribute> operands) {
+  if (!operands[0]) return {};
+
+  Builder b(getContext());
+  Attribute fromAttr = operands[0];
+  return TypeSwitch<Type, OpFoldResult>(getResult().getType())
+      .Case([&](PyIntegerType toType) -> OpFoldResult {
+        return TypeSwitch<Attribute, OpFoldResult>(fromAttr)
+            .Case([&](BoolAttr fromBool) -> OpFoldResult {
+              return b.getI64IntegerAttr(fromBool.getValue() ? 1 : 0);
+            })
+            .Default([](Attribute) -> OpFoldResult { return {}; });
+      })
+      .Case([&](PyRealType toType) -> OpFoldResult {
+        return TypeSwitch<Attribute, OpFoldResult>(fromAttr)
+            .Case([&](BoolAttr fromBool) -> OpFoldResult {
+              return b.getF64FloatAttr(fromBool.getValue() ? 1.0 : 0.0);
+            })
+            .Case([&](IntegerAttr fromInteger) -> OpFoldResult {
+              APInt value = fromInteger.getValue();
+              return b.getF64FloatAttr(value.getSExtValue());
+            })
+            .Default([](Attribute) -> OpFoldResult { return {}; });
+      })
+      .Default([](Type) -> OpFoldResult { return {}; });
+}
+
+LogicalResult PromoteNumericOp::canonicalize(PromoteNumericOp op,
+                                             PatternRewriter &rewriter) {
+  if (op.input().getType() == op.getResult().getType()) {
+    rewriter.replaceOp(op, op.input());
+    return success();
+  }
+  return failure();
+}
+
+//===----------------------------------------------------------------------===//
+// RaiseOnFailureOp
+//===----------------------------------------------------------------------===//
+
+LogicalResult PYDM::RaiseOnFailureOp::fold(
+    ArrayRef<Attribute> operands, SmallVectorImpl<OpFoldResult> &results) {
+  assert(operands.size() == 1 && "expected one fold operand");
+  // Unit exception result is success. Just elide.
+  if (operands[0] && operands[0].isa<UnitAttr>()) {
+    erase();
+    return success();
+  }
+  return failure();
+}
+
+//===----------------------------------------------------------------------===//
+// SelectOp
+//===----------------------------------------------------------------------===//
+
+OpFoldResult SelectOp::fold(ArrayRef<Attribute> operands) {
+  if (!operands[0]) return {};
+
+  BoolAttr boolAttr = operands[0].cast<BoolAttr>();
+  if (boolAttr.getValue())
+    return true_value();
+  else
+    return false_value();
+}
+
+//===----------------------------------------------------------------------===//
+// SequenceCloneOp
+//===----------------------------------------------------------------------===//
+
+bool SequenceCloneOp::refineResultTypes() {
+  if (sequence().getType() != getResult().getType()) {
+    getResult().setType(sequence().getType());
+    return true;
+  }
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// SubscriptOp
+//===----------------------------------------------------------------------===//
+
+void SubscriptOp::getCanonicalizationPatterns(RewritePatternSet &patterns,
+                                              MLIRContext *context) {
+  patterns.add<UnboxOperands>(getOperationName(), context);
+}
+
+//===----------------------------------------------------------------------===//
+// CallOp
+//===----------------------------------------------------------------------===//
+
+LogicalResult PyCallOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
+  // Check that the callee attribute was specified.
+  auto fnAttr = (*this)->getAttrOfType<FlatSymbolRefAttr>("callee");
+  if (!fnAttr)
+    return emitOpError("requires a 'callee' symbol reference attribute");
+  PyFuncOp fn = symbolTable.lookupNearestSymbolFrom<PyFuncOp>(*this, fnAttr);
+  if (!fn)
+    return emitOpError() << "'" << fnAttr.getValue()
+                         << "' does not reference a valid function";
+
+  // Verify that the operand and result types match the callee.
+  auto fnType = fn.getType();
+  if (fnType.getNumInputs() != getNumOperands())
+    return emitOpError("incorrect number of operands for callee");
+
+  for (unsigned i = 0, e = fnType.getNumInputs(); i != e; ++i) {
+    if (getOperand(i).getType() != fnType.getInput(i)) {
+      return emitOpError("operand type mismatch: expected operand type ")
+             << fnType.getInput(i) << ", but provided "
+             << getOperand(i).getType() << " for operand number " << i;
+    }
+  }
+
+  if (fnType.getNumResults() != getNumResults())
+    return emitOpError("incorrect number of results for callee");
+
+  for (unsigned i = 0, e = fnType.getNumResults(); i != e; ++i) {
+    if (getResult(i).getType() != fnType.getResult(i)) {
+      auto diag = emitOpError("result type mismatch at index ") << i;
+      diag.attachNote() << "      op result types: " << getResultTypes();
+      diag.attachNote() << "function result types: " << fnType.getResults();
+      return diag;
+    }
+  }
+
+  return success();
+}
+
+FunctionType PyCallOp::getCalleeType() {
+  return FunctionType::get(getContext(), getOperandTypes(), getResultTypes());
+}
+
+//===----------------------------------------------------------------------===//
+// DynamicCallOp
+//===----------------------------------------------------------------------===//
+
+LogicalResult DynamicCallOp::verifySymbolUses(
+    SymbolTableCollection &symbolTable) {
+  // Check that the callee attribute was specified.
+  auto fnAttr = (*this)->getAttrOfType<FlatSymbolRefAttr>("callee");
+  if (!fnAttr)
+    return emitOpError("requires a 'callee' symbol reference attribute");
+  Operation *fn = symbolTable.lookupNearestSymbolFrom(*this, fnAttr);
+  if (!fn || !isa<PyFuncOp>(fn))
+    return emitOpError() << "'" << fnAttr.getValue()
+                         << "' does not reference a valid function";
+  return success();
+}
+
+#define GET_OP_CLASSES
+#include "iree-dialects/Dialect/PyDM/IR/PyDMOps.cpp.inc"
