mirror of https://github.com/llvm/circt.git
[OM] Add C API and Python bindings for EvaluatorValue::Reference. (#6785)
In some OM dialect constructs, it is possible to receive EvaluatorValue::Reference values. In the Python bindings, where we are converting an EvaluatorValue to a Python value, we need to dereference the Reference, to get at the underlying EvaluatorValue that was set during evaluation. This adds the necessary C APIs, and updates the Python bindings to use them. If we encounter a Reference, we dereference it and recursively call the converter function. A Python test was added using an example IR from the Evaluator unit tests, which delays evaluation and introduces references.
This commit is contained in:
parent
23eb8c330a
commit
675716b168
|
@ -207,6 +207,15 @@ omEvaluatorValueIsAPath(OMEvaluatorValue evaluatorValue);
|
|||
MLIR_CAPI_EXPORTED MlirAttribute
|
||||
omEvaluatorPathGetAsString(OMEvaluatorValue evaluatorValue);
|
||||
|
||||
/// Query if the EvaluatorValue is a Reference.
|
||||
MLIR_CAPI_EXPORTED bool
|
||||
omEvaluatorValueIsAReference(OMEvaluatorValue evaluatorValue);
|
||||
|
||||
/// Dereference a Reference EvaluatorValue. Emits an error and returns null if
|
||||
/// the Reference cannot be dereferenced.
|
||||
MLIR_CAPI_EXPORTED OMEvaluatorValue
|
||||
omEvaluatorValueGetReferenceValue(OMEvaluatorValue evaluatorValue);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ReferenceAttr API
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -91,6 +91,28 @@ with Context() as ctx, Location.unknown():
|
|||
%3 = om.frozenpath_empty
|
||||
om.class.field @deleted, %3 : !om.frozenpath
|
||||
}
|
||||
|
||||
om.class @Class1(%input: !om.integer) {
|
||||
%0 = om.constant #om.integer<1 : si3> : !om.integer
|
||||
om.class.field @value, %0 : !om.integer
|
||||
om.class.field @input, %input : !om.integer
|
||||
}
|
||||
|
||||
om.class @Class2() {
|
||||
%0 = om.constant #om.integer<2 : si3> : !om.integer
|
||||
om.class.field @value, %0 : !om.integer
|
||||
}
|
||||
|
||||
om.class @IntegerBinaryArithmeticObjectsDelayed() {
|
||||
%0 = om.object @Class1(%5) : (!om.integer) -> !om.class.type<@Class1>
|
||||
%1 = om.object.field %0, [@value] : (!om.class.type<@Class1>) -> !om.integer
|
||||
|
||||
%2 = om.object @Class2() : () -> !om.class.type<@Class2>
|
||||
%3 = om.object.field %2, [@value] : (!om.class.type<@Class2>) -> !om.integer
|
||||
|
||||
%5 = om.integer.add %1, %3 : !om.integer
|
||||
om.class.field @result, %5 : !om.integer
|
||||
}
|
||||
}
|
||||
""")
|
||||
|
||||
|
@ -232,3 +254,8 @@ paths_fields = [
|
|||
]
|
||||
for paths_field in paths_fields:
|
||||
assert isinstance(paths_field.value.type, om.PathType)
|
||||
|
||||
delayed = evaluator.instantiate("IntegerBinaryArithmeticObjectsDelayed")
|
||||
|
||||
# CHECK: 3
|
||||
print(delayed.result)
|
||||
|
|
|
@ -377,6 +377,10 @@ PythonValue omEvaluatorValueToPythonValue(OMEvaluatorValue result) {
|
|||
if (omEvaluatorValueIsAPath(result))
|
||||
return Path(result);
|
||||
|
||||
if (omEvaluatorValueIsAReference(result))
|
||||
return omEvaluatorValueToPythonValue(
|
||||
omEvaluatorValueGetReferenceValue(result));
|
||||
|
||||
// If the field was a primitive, return the Attribute.
|
||||
assert(omEvaluatorValueIsAPrimitive(result));
|
||||
return omEvaluatorValueGetPrimitive(result);
|
||||
|
|
|
@ -325,6 +325,31 @@ MlirAttribute omEvaluatorPathGetAsString(OMEvaluatorValue evaluatorValue) {
|
|||
return wrap((Attribute)path->getAsString());
|
||||
}
|
||||
|
||||
/// Query if the EvaluatorValue is a Reference.
|
||||
bool omEvaluatorValueIsAReference(OMEvaluatorValue evaluatorValue) {
|
||||
return isa<evaluator::ReferenceValue>(unwrap(evaluatorValue).get());
|
||||
}
|
||||
|
||||
/// Dereference a Reference EvaluatorValue. Emits an error and returns null if
|
||||
/// the Reference cannot be dereferenced.
|
||||
OMEvaluatorValue
|
||||
omEvaluatorValueGetReferenceValue(OMEvaluatorValue evaluatorValue) {
|
||||
// Assert the EvaluatorValue is a Reference.
|
||||
assert(omEvaluatorValueIsAReference(evaluatorValue));
|
||||
|
||||
// Attempt to get the final EvaluatorValue from the Reference.
|
||||
auto result =
|
||||
llvm::cast<evaluator::ReferenceValue>(unwrap(evaluatorValue).get())
|
||||
->getStrippedValue();
|
||||
|
||||
// If this failed, an error diagnostic has been emitted, and we return null.
|
||||
if (failed(result))
|
||||
return {};
|
||||
|
||||
// If this succeeded, wrap the EvaluatorValue and return it.
|
||||
return wrap(result.value());
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ReferenceAttr API.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
Loading…
Reference in New Issue