14 #include "mlir/IR/BuiltinAttributeInterfaces.h"
15 #include "mlir/IR/Location.h"
16 #include "mlir/IR/SymbolTable.h"
17 #include "llvm/ADT/TypeSwitch.h"
18 #include "llvm/Support/Debug.h"
20 #define DEBUG_TYPE "om-evaluator"
30 return cast<ModuleOp>(symbolTable.getOp());
33 SmallVector<evaluator::EvaluatorValuePtr>
35 ArrayRef<Attribute> attributes) {
36 SmallVector<evaluator::EvaluatorValuePtr> values;
37 values.reserve(attributes.size());
38 for (
auto attr : attributes)
39 values.push_back(std::make_shared<evaluator::AttributeValue>(attr));
44 using namespace evaluator;
50 assert(isFullyEvaluated());
51 return llvm::TypeSwitch<EvaluatorValue *, LogicalResult>(
this)
54 [](
auto v) {
return v->finalizeImpl(); });
58 return llvm::TypeSwitch<const EvaluatorValue *, Type>(
this)
59 .Case<
AttributeValue>([](
auto *attr) -> Type {
return attr->getType(); })
60 .Case<ObjectValue>([](
auto *
object) {
return object->getObjectType(); })
61 .Case<ListValue>([](
auto *list) {
return list->getListType(); })
62 .Case<MapValue>([](
auto *map) {
return map->getMapType(); })
63 .Case<ReferenceValue>([](
auto *ref) {
return ref->getValueType(); })
64 .Case<TupleValue>([](
auto *tuple) {
return tuple->getTupleType(); })
71 FailureOr<evaluator::EvaluatorValuePtr>
75 return TypeSwitch<mlir::Type, FailureOr<evaluator::EvaluatorValuePtr>>(type)
76 .Case([&](circt::om::MapType type) {
78 std::make_shared<evaluator::MapValue>(type, loc);
79 return success(result);
81 .Case([&](circt::om::ListType type) {
83 std::make_shared<evaluator::ListValue>(type, loc);
84 return success(result);
86 .Case([&](mlir::TupleType type) {
88 std::make_shared<evaluator::TupleValue>(type, loc);
89 return success(result);
92 .Case([&](circt::om::ClassType type)
93 -> FailureOr<evaluator::EvaluatorValuePtr> {
95 symbolTable.lookup<ClassOp>(type.getClassName().getValue());
97 return symbolTable.getOp()->emitError(
"unknown class name ")
98 << type.getClassName();
101 std::make_shared<evaluator::ObjectValue>(cls, loc);
103 return success(result);
105 .Default([&](
auto type) {
return failure(); });
110 auto it = objects.find({value, actualParams});
111 if (it != objects.end()) {
112 auto evalVal = it->second;
113 evalVal->setLocIfUnknown(loc);
117 FailureOr<evaluator::EvaluatorValuePtr> result =
118 TypeSwitch<Value, FailureOr<evaluator::EvaluatorValuePtr>>(value)
119 .Case([&](BlockArgument arg) {
120 auto val = (*actualParams)[arg.getArgNumber()];
124 .Case([&](OpResult result) {
125 return TypeSwitch<Operation *,
126 FailureOr<evaluator::EvaluatorValuePtr>>(
127 result.getDefiningOp())
128 .Case([&](ConstantOp op) {
129 return evaluateConstant(op, actualParams, loc);
131 .Case([&](IntegerBinaryArithmeticOp op) {
135 std::make_shared<evaluator::AttributeValue>(
136 op.getResult().getType(), loc);
137 return success(result);
139 .Case<ObjectFieldOp>([&](
auto op) {
143 std::make_shared<evaluator::ReferenceValue>(
144 value.getType(), loc);
145 return success(result);
147 .Case<AnyCastOp>([&](AnyCastOp op) {
148 return getOrCreateValue(op.getInput(), actualParams, loc);
150 .Case<FrozenBasePathCreateOp>([&](FrozenBasePathCreateOp op) {
152 std::make_shared<evaluator::BasePathValue>(
153 op.getPathAttr(), loc);
154 return success(result);
156 .Case<FrozenPathCreateOp>([&](FrozenPathCreateOp op) {
158 std::make_shared<evaluator::PathValue>(
159 op.getTargetKindAttr(), op.getPathAttr(),
160 op.getModuleAttr(), op.getRefAttr(),
161 op.getFieldAttr(), loc);
162 return success(result);
164 .Case<FrozenEmptyPathOp>([&](FrozenEmptyPathOp op) {
166 std::make_shared<evaluator::PathValue>(
168 return success(result);
170 .Case<ListCreateOp, ListConcatOp, TupleCreateOp, MapCreateOp,
171 ObjectFieldOp>([&](
auto op) {
172 return getPartiallyEvaluatedValue(op.getType(), loc);
174 .Case<ObjectOp>([&](
auto op) {
175 return getPartiallyEvaluatedValue(op.getType(), op.getLoc());
177 .Default([&](Operation *op) {
178 auto error = op->emitError(
"unable to evaluate value");
179 error.attachNote() <<
"value: " << value;
186 objects[{value, actualParams}] = result.value();
190 FailureOr<evaluator::EvaluatorValuePtr>
195 ClassOp cls = symbolTable.lookup<ClassOp>(className);
197 return symbolTable.getOp()->emitError(
"unknown class name ") << className;
199 auto formalParamNames = cls.getFormalParamNames().getAsRange<StringAttr>();
200 auto formalParamTypes = cls.getBodyBlock()->getArgumentTypes();
203 if (actualParams->size() != formalParamTypes.size()) {
204 auto error = cls.emitError(
"actual parameter list length (")
205 << actualParams->size() <<
") does not match formal "
206 <<
"parameter list length (" << formalParamTypes.size() <<
")";
207 auto &diag = error.attachNote() <<
"actual parameters: ";
210 for (
const auto ¶m : *actualParams) {
217 error.attachNote(cls.getLoc()) <<
"formal parameters: " << formalParamTypes;
222 for (
auto [actualParam, formalParamName, formalParamType] :
223 llvm::zip(*actualParams, formalParamNames, formalParamTypes)) {
224 if (!actualParam || !actualParam.get())
225 return cls.emitError(
"actual parameter for ")
226 << formalParamName <<
" is null";
229 if (isa<AnyType>(formalParamType))
232 Type actualParamType = actualParam->getType();
234 assert(actualParamType &&
"actualParamType must be non-null!");
236 if (actualParamType != formalParamType) {
237 auto error = cls.emitError(
"actual parameter for ")
238 << formalParamName <<
" has invalid type";
239 error.attachNote() <<
"actual parameter: " << *actualParam;
240 error.attachNote() <<
"format parameter type: " << formalParamType;
248 auto *context = cls.getContext();
249 for (
auto &op : cls.getOps())
250 for (
auto result : op.getResults()) {
257 worklist.push({result, actualParams});
260 auto fieldNames = cls.getFieldNames();
261 auto operands = cls.getFieldsOp()->getOperands();
262 for (
size_t i = 0; i < fieldNames.size(); ++i) {
263 auto name = fieldNames[i];
264 auto value = operands[i];
265 auto fieldLoc = cls.getFieldLocByIndex(i);
266 FailureOr<evaluator::EvaluatorValuePtr> result =
267 evaluateValue(value, actualParams, fieldLoc);
271 fields[cast<StringAttr>(name)] = result.value();
275 if (instanceKey.first) {
277 getOrCreateValue(instanceKey.first, instanceKey.second, loc).value();
278 auto *
object = llvm::cast<evaluator::ObjectValue>(result.get());
279 object->setFields(std::move(fields));
285 std::make_shared<evaluator::ObjectValue>(cls, fields, loc);
290 FailureOr<std::shared_ptr<evaluator::EvaluatorValue>>
292 StringAttr className, ArrayRef<evaluator::EvaluatorValuePtr> actualParams) {
293 ClassOp cls = symbolTable.lookup<ClassOp>(className);
295 return symbolTable.getOp()->emitError(
"unknown class name ") << className;
298 std::make_unique<SmallVector<std::shared_ptr<evaluator::EvaluatorValue>>>(
301 actualParametersBuffers.push_back(std::move(parameters));
303 auto loc = cls.getLoc();
304 auto result = evaluateObjectInstance(
305 className, actualParametersBuffers.back().get(), loc);
312 while (!worklist.empty()) {
313 auto [value, args] = worklist.front();
316 auto result = evaluateValue(value, args, loc);
322 if (!result.value()->isFullyEvaluated())
323 worklist.push({value, args});
326 auto &
object = result.value();
329 if (failed(object->finalize()))
330 return cls.emitError() <<
"failed to finalize evaluation. Probably the "
331 "class contains a dataflow cycle";
335 FailureOr<evaluator::EvaluatorValuePtr>
338 auto evaluatorValue = getOrCreateValue(value, actualParams, loc).value();
341 if (evaluatorValue->isFullyEvaluated())
342 return evaluatorValue;
344 return llvm::TypeSwitch<Value, FailureOr<evaluator::EvaluatorValuePtr>>(value)
345 .Case([&](BlockArgument arg) {
346 return evaluateParameter(arg, actualParams, loc);
348 .Case([&](OpResult result) {
349 return TypeSwitch<Operation *, FailureOr<evaluator::EvaluatorValuePtr>>(
350 result.getDefiningOp())
351 .Case([&](ConstantOp op) {
352 return evaluateConstant(op, actualParams, loc);
354 .Case([&](IntegerBinaryArithmeticOp op) {
355 return evaluateIntegerBinaryArithmetic(op, actualParams, loc);
357 .Case([&](ObjectOp op) {
358 return evaluateObjectInstance(op, actualParams);
360 .Case([&](ObjectFieldOp op) {
361 return evaluateObjectField(op, actualParams, loc);
363 .Case([&](ListCreateOp op) {
364 return evaluateListCreate(op, actualParams, loc);
366 .Case([&](ListConcatOp op) {
367 return evaluateListConcat(op, actualParams, loc);
369 .Case([&](TupleCreateOp op) {
370 return evaluateTupleCreate(op, actualParams, loc);
372 .Case([&](TupleGetOp op) {
373 return evaluateTupleGet(op, actualParams, loc);
375 .Case([&](AnyCastOp op) {
376 return evaluateValue(op.getInput(), actualParams, loc);
378 .Case([&](MapCreateOp op) {
379 return evaluateMapCreate(op, actualParams, loc);
381 .Case([&](FrozenBasePathCreateOp op) {
382 return evaluateBasePathCreate(op, actualParams, loc);
384 .Case([&](FrozenPathCreateOp op) {
385 return evaluatePathCreate(op, actualParams, loc);
387 .Case([&](FrozenEmptyPathOp op) {
388 return evaluateEmptyPath(op, actualParams, loc);
390 .Default([&](Operation *op) {
391 auto error = op->emitError(
"unable to evaluate value");
392 error.attachNote() <<
"value: " << value;
401 auto val = (*actualParams)[formalParam.getArgNumber()];
407 FailureOr<circt::om::evaluator::EvaluatorValuePtr>
411 return success(std::make_shared<circt::om::evaluator::AttributeValue>(
412 op.getValue(), loc));
416 FailureOr<EvaluatorValuePtr>
418 IntegerBinaryArithmeticOp op,
ActualParameters actualParams, Location loc) {
420 auto handle = getOrCreateValue(op.getResult(), actualParams, loc);
423 if (handle.value()->isFullyEvaluated())
428 auto lhsResult = evaluateValue(op.getLhs(), actualParams, loc);
429 if (failed(lhsResult))
431 if (!lhsResult.value()->isFullyEvaluated())
434 auto rhsResult = evaluateValue(op.getRhs(), actualParams, loc);
435 if (failed(rhsResult))
437 if (!rhsResult.value()->isFullyEvaluated())
443 llvm::TypeSwitch<evaluator::EvaluatorValue *, om::IntegerAttr>(value)
445 return val->
getAs<om::IntegerAttr>();
448 return cast<evaluator::AttributeValue>(
449 val->getStrippedValue()->get())
450 ->getAs<om::IntegerAttr>();
454 om::IntegerAttr lhs = extractAttr(lhsResult.value().get());
455 om::IntegerAttr rhs = extractAttr(rhsResult.value().get());
457 "expected om::IntegerAttr for IntegerBinaryArithmeticOp operands");
463 APSInt lhsVal = lhs.getValue().getAPSInt();
464 APSInt rhsVal = rhs.getValue().getAPSInt();
465 if (lhsVal.getBitWidth() > rhsVal.getBitWidth())
466 rhsVal = rhsVal.extend(lhsVal.getBitWidth());
467 else if (rhsVal.getBitWidth() > lhsVal.getBitWidth())
468 lhsVal = lhsVal.extend(rhsVal.getBitWidth());
471 FailureOr<APSInt> result = op.evaluateIntegerOperation(lhsVal, rhsVal);
474 return op->emitError(
"failed to evaluate integer operation");
477 MLIRContext *ctx = op->getContext();
482 auto *handleValue = cast<evaluator::AttributeValue>(handle.value().get());
483 auto resultStatus = handleValue->setAttr(resultAttr);
484 if (failed(resultStatus))
487 auto finalizeStatus = handleValue->finalize();
488 if (failed(finalizeStatus))
489 return finalizeStatus;
495 FailureOr<circt::om::Evaluator::ActualParameters>
499 auto parameters = std::make_unique<
500 SmallVector<std::shared_ptr<evaluator::EvaluatorValue>>>();
503 for (
auto input : range) {
504 auto inputResult = getOrCreateValue(input, actualParams, loc);
505 if (failed(inputResult))
507 parameters->push_back(inputResult.value());
510 actualParametersBuffers.push_back(std::move(parameters));
511 return actualParametersBuffers.back().get();
515 FailureOr<evaluator::EvaluatorValuePtr>
518 auto loc = op.getLoc();
519 if (isFullyEvaluated({op, actualParams}))
520 return getOrCreateValue(op, actualParams, loc);
523 createParametersFromOperands(op.getOperands(), actualParams, loc);
526 return evaluateObjectInstance(op.getClassNameAttr(), params.value(), loc,
531 FailureOr<evaluator::EvaluatorValuePtr>
536 FailureOr<evaluator::EvaluatorValuePtr> currentObjectResult =
537 evaluateValue(op.getObject(), actualParams, loc);
538 if (failed(currentObjectResult))
539 return currentObjectResult;
541 auto *currentObject =
542 llvm::cast<evaluator::ObjectValue>(currentObjectResult.value().get());
544 auto objectFieldValue = getOrCreateValue(op, actualParams, loc).value();
549 for (
auto field : op.getFieldPath().getAsRange<FlatSymbolRefAttr>()) {
551 if (!currentObject->getFields().contains(field.getAttr()))
552 return objectFieldValue;
554 auto currentField = currentObject->getField(field.getAttr());
555 finalField = currentField.value();
556 if (
auto *nextObject =
557 llvm::dyn_cast<evaluator::ObjectValue>(finalField.get()))
558 currentObject = nextObject;
562 llvm::cast<evaluator::ReferenceValue>(objectFieldValue.get())
563 ->setValue(finalField);
566 return objectFieldValue;
570 FailureOr<evaluator::EvaluatorValuePtr>
575 SmallVector<evaluator::EvaluatorValuePtr> values;
576 auto list = getOrCreateValue(op, actualParams, loc);
577 for (
auto operand : op.getOperands()) {
578 auto result = evaluateValue(operand, actualParams, loc);
581 if (!result.value()->isFullyEvaluated())
583 values.push_back(result.value());
587 llvm::cast<evaluator::ListValue>(list.value().get())
588 ->setElements(std::move(values));
593 FailureOr<evaluator::EvaluatorValuePtr>
598 SmallVector<evaluator::EvaluatorValuePtr> values;
599 auto list = getOrCreateValue(op, actualParams, loc);
604 llvm::TypeSwitch<evaluator::EvaluatorValue *, evaluator::ListValue *>(
608 return cast<evaluator::ListValue>(val->getStrippedValue()->get());
612 for (
auto operand : op.getOperands()) {
613 auto result = evaluateValue(operand, actualParams, loc);
616 if (!result.value()->isFullyEvaluated())
622 values.push_back(subValue);
626 llvm::cast<evaluator::ListValue>(list.value().get())
627 ->setElements(std::move(values));
632 FailureOr<evaluator::EvaluatorValuePtr>
636 SmallVector<evaluator::EvaluatorValuePtr> values;
637 for (
auto operand : op.getOperands()) {
638 auto result = evaluateValue(operand, actualParams, loc);
641 values.push_back(result.value());
645 auto val = getOrCreateValue(op, actualParams, loc);
646 llvm::cast<evaluator::TupleValue>(val.value().get())
647 ->setElements(std::move(values));
654 auto tuple = evaluateValue(op.getInput(), actualParams, loc);
658 cast<evaluator::TupleValue>(tuple.value().get())
659 ->getElements()[op.getIndex()];
667 DenseMap<Attribute, evaluator::EvaluatorValuePtr> elements;
668 auto valueResult = getOrCreateValue(op, actualParams, loc).value();
669 for (
auto operand : op.getOperands()) {
670 auto result = evaluateValue(operand, actualParams, loc);
674 auto &value = result.value();
675 if (!value->isFullyEvaluated())
677 const auto &element =
678 llvm::cast<evaluator::TupleValue>(value.get())->getElements();
679 assert(element.size() == 2);
681 llvm::cast<evaluator::AttributeValue>(element[0].
get())->getAttr();
682 if (!elements.insert({attr, element[1]}).second)
683 return op.emitError() <<
"map contains duplicated keys";
687 llvm::cast<evaluator::MapValue>(valueResult.get())
688 ->setElements(std::move(elements));
692 FailureOr<evaluator::EvaluatorValuePtr>
697 auto valueResult = getOrCreateValue(op, actualParams, loc).value();
698 auto *path = llvm::cast<evaluator::BasePathValue>(valueResult.get());
699 auto result = evaluateValue(op.getBasePath(), actualParams, loc);
702 auto &value = result.value();
703 if (!value->isFullyEvaluated())
705 path->setBasepath(*llvm::cast<evaluator::BasePathValue>(value.get()));
709 FailureOr<evaluator::EvaluatorValuePtr>
714 auto valueResult = getOrCreateValue(op, actualParams, loc).value();
715 auto *path = llvm::cast<evaluator::PathValue>(valueResult.get());
716 auto result = evaluateValue(op.getBasePath(), actualParams, loc);
719 auto &value = result.value();
720 if (!value->isFullyEvaluated())
722 path->setBasepath(*llvm::cast<evaluator::BasePathValue>(value.get()));
728 auto valueResult = getOrCreateValue(op, actualParams, loc).value();
737 FailureOr<EvaluatorValuePtr>
739 auto field = fields.find(name);
740 if (field == fields.end())
741 return cls.emitError(
"field ") << name <<
" does not exist";
742 return success(fields[name]);
748 SmallVector<Attribute> fieldNames;
749 for (
auto &f : fields)
750 fieldNames.push_back(f.first);
752 llvm::sort(fieldNames, [](Attribute a, Attribute b) {
753 return cast<StringAttr>(a).getValue() < cast<StringAttr>(b).getValue();
760 for (
auto &&[e, value] : fields)
773 SmallVector<Attribute> attrs;
774 for (
auto &[key, _] : elements)
775 attrs.push_back(key);
777 std::sort(attrs.begin(), attrs.end(), [](Attribute l, Attribute r) {
778 if (auto lInt = dyn_cast<mlir::IntegerAttr>(l))
779 if (auto rInt = dyn_cast<mlir::IntegerAttr>(r))
780 return lInt.getValue().ult(rInt.getValue());
782 assert(isa<StringAttr>(l) && isa<StringAttr>(r) &&
783 "key type should be integer or string");
784 return cast<StringAttr>(l).getValue() < cast<StringAttr>(r).getValue();
791 for (
auto &&[e, value] : elements)
802 auto result = getStrippedValue();
805 value = std::move(result.value());
814 for (
auto &value : elements) {
827 path(PathAttr::
get(context, {})) {
828 markFullyEvaluated();
832 :
EvaluatorValue(path.getContext(), Kind::BasePath, loc), path(path) {}
835 assert(isFullyEvaluated());
840 assert(!isFullyEvaluated());
841 auto newPath = llvm::to_vector(basepath.
path.getPath());
842 auto oldPath = path.getPath();
843 newPath.append(oldPath.begin(), oldPath.end());
845 markFullyEvaluated();
853 StringAttr module, StringAttr ref,
854 StringAttr field, Location loc)
856 path(path), module(module), ref(ref), field(field) {}
859 PathValue path(
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, loc);
868 SmallString<64> result;
869 switch (targetKind.getValue()) {
870 case TargetKind::DontTouch:
871 result +=
"OMDontTouchedReferenceTarget";
873 case TargetKind::Instance:
874 result +=
"OMInstanceTarget";
876 case TargetKind::MemberInstance:
877 result +=
"OMMemberInstanceTarget";
879 case TargetKind::MemberReference:
880 result +=
"OMMemberReferenceTarget";
882 case TargetKind::Reference:
883 result +=
"OMReferenceTarget";
887 if (!path.getPath().empty())
888 result += path.getPath().front().module;
890 result += module.getValue();
892 for (
const auto &elt : path) {
893 result += elt.module.getValue();
895 result += elt.instance.getValue();
898 if (!module.getValue().empty())
899 result += module.getValue();
900 if (!ref.getValue().empty()) {
902 result += ref.getValue();
904 if (!field.getValue().empty())
905 result += field.getValue();
910 assert(!isFullyEvaluated());
911 auto newPath = llvm::to_vector(basepath.
getPath().getPath());
912 auto oldPath = path.getPath();
913 newPath.append(oldPath.begin(), oldPath.end());
915 markFullyEvaluated();
923 if (cast<TypedAttr>(attr).getType() != this->type)
924 return mlir::emitError(getLoc(),
"cannot set AttributeValue of type ")
925 << this->type <<
" to Attribute " << attr;
926 if (isFullyEvaluated())
927 return mlir::emitError(
929 "cannot set AttributeValue that has already been fully evaluated");
931 markFullyEvaluated();
936 if (!isFullyEvaluated())
937 return mlir::emitError(
938 getLoc(),
"cannot finalize AttributeValue that is not fully evaluated");
assert(baseType &&"element must be base type")
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
static LogicalResult finalizeEvaluatorValue(EvaluatorValuePtr &value)
std::shared_ptr< EvaluatorValue > EvaluatorValuePtr
A value of an object in memory.
SmallVector< EvaluatorValuePtr > getEvaluatorValuesFromAttributes(MLIRContext *context, ArrayRef< Attribute > attributes)
FailureOr< evaluator::EvaluatorValuePtr > evaluateBasePathCreate(FrozenBasePathCreateOp op, ActualParameters actualParams, Location loc)
FailureOr< evaluator::EvaluatorValuePtr > evaluateEmptyPath(FrozenEmptyPathOp op, ActualParameters actualParams, Location loc)
FailureOr< evaluator::EvaluatorValuePtr > getPartiallyEvaluatedValue(Type type, Location loc)
FailureOr< EvaluatorValuePtr > evaluateValue(Value value, ActualParameters actualParams, Location loc)
Evaluate a Value in a Class body according to the small expression grammar described in the rationale...
FailureOr< EvaluatorValuePtr > evaluateConstant(ConstantOp op, ActualParameters actualParams, Location loc)
Evaluator dispatch function for constants.
FailureOr< EvaluatorValuePtr > evaluateIntegerBinaryArithmetic(IntegerBinaryArithmeticOp op, ActualParameters actualParams, Location loc)
mlir::ModuleOp getModule()
Get the Module this Evaluator is built from.
FailureOr< EvaluatorValuePtr > evaluateObjectField(ObjectFieldOp op, ActualParameters actualParams, Location loc)
Evaluator dispatch function for Object fields.
Evaluator(ModuleOp mod)
Construct an Evaluator with an IR module.
FailureOr< evaluator::EvaluatorValuePtr > evaluateMapCreate(MapCreateOp op, ActualParameters actualParams, Location loc)
Evaluator dispatch function for Map creation.
FailureOr< evaluator::EvaluatorValuePtr > instantiate(StringAttr className, ArrayRef< EvaluatorValuePtr > actualParams)
Instantiate an Object with its class name and actual parameters.
FailureOr< EvaluatorValuePtr > getOrCreateValue(Value value, ActualParameters actualParams, Location loc)
SmallVectorImpl< std::shared_ptr< evaluator::EvaluatorValue > > * ActualParameters
FailureOr< EvaluatorValuePtr > evaluateListCreate(ListCreateOp op, ActualParameters actualParams, Location loc)
Evaluator dispatch function for List creation.
FailureOr< EvaluatorValuePtr > evaluateListConcat(ListConcatOp op, ActualParameters actualParams, Location loc)
Evaluator dispatch function for List concatenation.
std::pair< Value, ActualParameters > ObjectKey
FailureOr< EvaluatorValuePtr > evaluateParameter(BlockArgument formalParam, ActualParameters actualParams, Location loc)
Evaluator dispatch functions for the small expression grammar.
FailureOr< EvaluatorValuePtr > evaluateObjectInstance(StringAttr className, ActualParameters actualParams, Location loc, ObjectKey instanceKey={})
Instantiate an Object with its class name and actual parameters.
FailureOr< EvaluatorValuePtr > evaluateTupleGet(TupleGetOp op, ActualParameters actualParams, Location loc)
Evaluator dispatch function for List creation.
FailureOr< EvaluatorValuePtr > evaluateTupleCreate(TupleCreateOp op, ActualParameters actualParams, Location loc)
Evaluator dispatch function for Tuple creation.
FailureOr< evaluator::EvaluatorValuePtr > evaluatePathCreate(FrozenPathCreateOp op, ActualParameters actualParams, Location loc)
FailureOr< ActualParameters > createParametersFromOperands(ValueRange range, ActualParameters actualParams, Location loc)
Evaluator dispatch function for Object instances.
Values which can be directly representable by MLIR attributes.
LogicalResult setAttr(Attribute attr)
LogicalResult finalizeImpl()
BasePathValue(MLIRContext *context)
void setBasepath(const BasePathValue &basepath)
Set the basepath which this path is relative to.
om::PathAttr getPath() const
Base class for evaluator runtime values.
void markFullyEvaluated()
A List which contains variadic length of elements with the same type.
LogicalResult finalizeImpl()
const auto & getElements() const
ArrayAttr getKeys()
Return an array of keys in the ascending order.
LogicalResult finalizeImpl()
A composite Object, which has a type and fields.
LogicalResult finalizeImpl()
FailureOr< EvaluatorValuePtr > getField(StringAttr field)
Get a field of the Object by name.
ArrayAttr getFieldNames()
Get all the field names of the Object.
StringAttr getAsString() const
void setBasepath(const BasePathValue &basepath)
PathValue(om::TargetKindAttr targetKind, om::PathAttr path, StringAttr module, StringAttr ref, StringAttr field, Location loc)
Create a path value representing a regular path.
static PathValue getEmptyPath(Location loc)
Values which can be used as pointers to different values.
LogicalResult finalizeImpl()