
The constructor function was being defined without indicating its "__init__" name, which made it interpret it as a regular fuction rather than a constructor. When overload resolution failed, Pybind would attempt to print the arguments actually passed to the function, including "self", which is not initialized since the constructor couldn't be called. This would result in "__repr__" being called with "self" referencing an uninitialized MLIR C API object, which in turn would cause undefined behavior when attempting to print in C++. Even if the correct name is provided, the mechanism used by PybindAdaptors.h to bind constructors directly as "__init__" functions taking "self" is deprecated by Pybind. The new mechanism does not seem to have access to a fully-constructed "self" object (i.e., the constructor in C++ takes a `pybind11::detail::value_and_holder` that cannot be forwarded back to Python). Instead, redefine "__new__" to perform the required checks (there are no additional initialization needed for attributes and types as they are all wrappers around a C++ pointer). "__new__" can call its equivalent on a superclass without needing "self". Bump pybind11 dependency to 3.8.0, which is the first version that allows one to redefine "__new__". Reviewed By: stellaraccident Differential Revision: https://reviews.llvm.org/D117646
112 lines
3.7 KiB
TableGen
112 lines
3.7 KiB
TableGen
//===-- python_test_ops.td - Python test Op definitions ----*- tablegen -*-===//
|
|
//
|
|
// Part of the LLVM Project, 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef PYTHON_TEST_OPS
|
|
#define PYTHON_TEST_OPS
|
|
|
|
include "mlir/Bindings/Python/Attributes.td"
|
|
include "mlir/IR/OpBase.td"
|
|
include "mlir/Interfaces/InferTypeOpInterface.td"
|
|
|
|
def Python_Test_Dialect : Dialect {
|
|
let name = "python_test";
|
|
let cppNamespace = "python_test";
|
|
}
|
|
|
|
class TestType<string name, string typeMnemonic>
|
|
: TypeDef<Python_Test_Dialect, name> {
|
|
let mnemonic = typeMnemonic;
|
|
}
|
|
|
|
class TestAttr<string name, string attrMnemonic>
|
|
: AttrDef<Python_Test_Dialect, name> {
|
|
let mnemonic = attrMnemonic;
|
|
}
|
|
|
|
class TestOp<string mnemonic, list<OpTrait> traits = []>
|
|
: Op<Python_Test_Dialect, mnemonic, traits>;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Type definitions.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
def TestType : TestType<"TestType", "test_type">;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Attribute definitions.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
def TestAttr : TestAttr<"TestAttr", "test_attr">;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Operation definitions.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
def AttributedOp : TestOp<"attributed_op"> {
|
|
let arguments = (ins I32Attr:$mandatory_i32,
|
|
OptionalAttr<I32Attr>:$optional_i32,
|
|
UnitAttr:$unit);
|
|
}
|
|
|
|
def PropertyOp : TestOp<"property_op"> {
|
|
let arguments = (ins I32Attr:$property,
|
|
I32:$idx);
|
|
}
|
|
|
|
def DummyOp : TestOp<"dummy_op"> {
|
|
}
|
|
|
|
def InferResultsOp : TestOp<"infer_results_op", [InferTypeOpInterface]> {
|
|
let arguments = (ins);
|
|
let results = (outs AnyInteger:$single, AnyInteger:$doubled);
|
|
|
|
let extraClassDeclaration = [{
|
|
static ::mlir::LogicalResult inferReturnTypes(
|
|
::mlir::MLIRContext *context, ::llvm::Optional<::mlir::Location> location,
|
|
::mlir::ValueRange operands, ::mlir::DictionaryAttr attributes,
|
|
::mlir::RegionRange regions,
|
|
::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) {
|
|
::mlir::Builder b(context);
|
|
inferredReturnTypes.push_back(b.getI32Type());
|
|
inferredReturnTypes.push_back(b.getI64Type());
|
|
return ::mlir::success();
|
|
}
|
|
}];
|
|
}
|
|
|
|
// If all result types are buildable, the InferTypeOpInterface is implied and is
|
|
// autogenerated by C++ ODS.
|
|
def InferResultsImpliedOp : TestOp<"infer_results_implied_op"> {
|
|
let results = (outs I32:$integer, F64:$flt, Index:$index);
|
|
}
|
|
|
|
def SameOperandAndResultTypeOp : TestOp<"same_operand_and_result_type_op",
|
|
[SameOperandsAndResultType]> {
|
|
let arguments = (ins Variadic<AnyType>);
|
|
let results = (outs AnyType:$one, AnyType:$two);
|
|
}
|
|
|
|
def FirstAttrDeriveTypeAttrOp : TestOp<"first_attr_derive_type_attr_op",
|
|
[FirstAttrDerivedResultType]> {
|
|
let arguments = (ins AnyType:$input, TypeAttr:$type);
|
|
let results = (outs AnyType:$one, AnyType:$two);
|
|
}
|
|
|
|
def FirstAttrDeriveAttrOp : TestOp<"first_attr_derive_attr_op",
|
|
[FirstAttrDerivedResultType]> {
|
|
let arguments = (ins AnyAttr:$iattr);
|
|
let results = (outs AnyType:$one, AnyType:$two, AnyType:$three);
|
|
}
|
|
|
|
def OptionalOperandOp : TestOp<"optional_operand_op"> {
|
|
let arguments = (ins Optional<AnyType>:$input);
|
|
let results = (outs I32:$result);
|
|
}
|
|
|
|
#endif // PYTHON_TEST_OPS
|