15#include "mlir/IR/Builders.h"
16#include "mlir/IR/BuiltinAttributeInterfaces.h"
17#include "mlir/IR/Location.h"
18#include "mlir/IR/SymbolTable.h"
19#include "mlir/IR/Verifier.h"
20#include "mlir/Pass/PassManager.h"
21#include "llvm/ADT/STLExtras.h"
22#include "llvm/ADT/ScopeExit.h"
23#include "llvm/ADT/TypeSwitch.h"
24#include "llvm/ADT/iterator_range.h"
25#include "llvm/Support/Debug.h"
27#define DEBUG_TYPE "om-evaluator"
34LogicalResult verifyActualParameters(ClassLike classLike,
35 ArrayRef<EvaluatorValuePtr> actualParams) {
36 auto formalParamNames =
37 classLike.getFormalParamNames().getAsRange<StringAttr>();
38 auto formalParamTypes = classLike.getBodyBlock()->getArgumentTypes();
40 if (actualParams.size() != formalParamTypes.size()) {
41 auto error = classLike.emitError(
"actual parameter list length (")
42 << actualParams.size() <<
") does not match formal "
43 <<
"parameter list length (" << formalParamTypes.size() <<
")";
44 auto &diag = error.attachNote() <<
"actual parameters: ";
46 for (
const auto ¶m : actualParams) {
53 error.attachNote(classLike.getLoc())
54 <<
"formal parameters: " << formalParamTypes;
58 for (
auto [actualParam, formalParamName, formalParamType] :
59 llvm::zip(actualParams, formalParamNames, formalParamTypes)) {
60 if (!actualParam || !actualParam.get())
61 return classLike.emitError(
"actual parameter for ")
62 << formalParamName <<
" is null";
65 if (isa<AnyType>(formalParamType))
68 Type actualParamType = actualParam->getType();
69 assert(actualParamType &&
"actualParamType must be non-null!");
71 if (actualParamType != formalParamType) {
72 auto error = classLike.emitError(
"actual parameter for ")
73 << formalParamName <<
" has invalid type";
74 error.attachNote() <<
"actual parameter: " << *actualParam;
75 error.attachNote() <<
"format parameter type: " << formalParamType;
85class ScratchIRBuilder {
87 struct InstantiationInfo {
89 SmallVector<EvaluatorValuePtr> actualParams;
92 ScratchIRBuilder(ModuleOp module, SymbolTable &symbolTable,
94 : module(module), symbolTable(symbolTable), rootClass(rootClass),
95 wrapperClass(createWrapperClass(rootClass)) {}
97 FailureOr<InstantiationInfo> run(ArrayRef<EvaluatorValuePtr> actualParams);
101 ClassOp createWrapperClass(ClassLike rootClass);
106 Location loc, Type expectedType);
118 SymbolTable &symbolTable;
120 ClassOp wrapperClass;
123 DenseMap<evaluator::EvaluatorValue *, Value> importedValues;
127 SmallPtrSet<evaluator::ObjectValue *, 8> activeObjectImports;
129 SmallVector<Attribute> wrapperArgNames;
130 SmallVector<EvaluatorValuePtr> wrapperActualParams;
133FailureOr<ScratchIRBuilder::InstantiationInfo>
134ScratchIRBuilder::run(ArrayRef<EvaluatorValuePtr> actualParams) {
135 auto *ctx =
module.getContext();
136 assert(rootClass &&
"root class must be resolved before building scratch IR");
137 auto rootLoc = rootClass.getLoc();
138 auto rootClassName = rootClass.getSymNameAttr();
140 OpBuilder builder(wrapperClass.getFieldsOp());
141 builder.setInsertionPoint(wrapperClass.getFieldsOp());
142 SmallVector<Value> importedActualValues;
143 importedActualValues.reserve(actualParams.size());
144 auto formalTypes = rootClass.getBodyBlock()->getArgumentTypes();
145 for (
auto [actual, expectedType] : llvm::zip(actualParams, formalTypes)) {
146 auto imported = materializeInput(actual, rootLoc, expectedType);
147 if (failed(imported))
149 importedActualValues.push_back(*imported);
153 wrapperClass->setAttr(wrapperClass.getFormalParamNamesAttrName(),
154 builder.getArrayAttr(wrapperArgNames));
156 wrapperClass.updateFields(
160 ClassType::get(ctx, FlatSymbolRefAttr::get(rootClassName)),
161 rootClassName, importedActualValues)
163 {builder.getStringAttr(
"root")});
167 auto skipGlobalVerifier =
168 module->getAttrOfType<UnitAttr>("om.evaluator_skip_global_verifier");
170 ElaborateObjectOptions options;
171 if (skipGlobalVerifier) {
172 if (failed(verify(wrapperClass)))
174 pm.enableVerifier(
false);
175 }
else if (failed(verify(module)))
178 auto wrapperName = wrapperClass.getSymNameAttr();
179 options.targetClass = wrapperName.getValue().str();
180 pm.addPass(createElaborateObject(std::move(options)));
181 if (failed(pm.run(module)))
186 if (skipGlobalVerifier && failed(verify(wrapperClass)))
189 return InstantiationInfo{wrapperName, std::move(wrapperActualParams)};
192ClassOp ScratchIRBuilder::createWrapperClass(ClassLike rootClass) {
193 OpBuilder builder(module.getBody(), module.getBody()->end());
194 builder.setInsertionPointToEnd(module.getBody());
196 auto wrapper = ClassOp::create(builder, rootClass.getLoc(),
197 Twine(
"__om_evaluator_wrapper_") +
198 rootClass.getSymName());
199 (void)symbolTable.insert(wrapper);
200 Block *body = &wrapper.getBody().emplaceBlock();
201 builder.setInsertionPointToEnd(body);
202 ClassFieldsOp::create(builder, rootClass.getLoc(), ValueRange(), ArrayAttr{});
210 return emitError(loc,
"cannot materialize null OM evaluator value");
212 loc = value->getLoc();
214 return emitError(loc,
"cannot import OM evaluator value without an "
218 if (isa<AnyType>(expectedType))
219 return createWrapperArgument(value, loc, expectedType);
221 if (
auto it = importedValues.find(value.get()); it != importedValues.end())
224 if (value->isUnknown()) {
225 OpBuilder builder(wrapperClass.getFieldsOp());
226 auto result = UnknownValueOp::create(builder, loc, expectedType);
227 importedValues[value.get()] = result.getResult();
228 return result.getResult();
231 return llvm::TypeSwitch<evaluator::EvaluatorValue *, FailureOr<Value>>(
234 auto attr = attrValue->
getAttr();
236 return emitError(loc,
"cannot import OM attribute value without an "
239 OpBuilder builder(wrapperClass.getFieldsOp());
240 auto result = ConstantOp::create(builder, loc, cast<TypedAttr>(attr));
241 importedValues[value.get()] = result.getResult();
242 return result.getResult();
245 return materializeListInput(listValue, loc);
248 return materializeObjectInput(objectValue, loc);
251 auto result = createWrapperArgument(value, loc, expectedType);
252 if (succeeded(result))
253 importedValues[value.get()] = *result;
262 return emitError(loc,
"cannot import partially evaluated OM list value");
265 SmallVector<Value> elementValues;
266 elementValues.reserve(listValue->
getElements().size());
267 for (
const auto &elementValue : listValue->
getElements()) {
268 auto materializedElement =
269 materializeInput(elementValue, loc, listType.getElementType());
270 if (failed(materializedElement))
272 elementValues.push_back(*materializedElement);
275 OpBuilder builder(wrapperClass.getFieldsOp());
276 auto result = ListCreateOp::create(builder, loc, listType, elementValues);
277 importedValues[listValue] = result.getResult();
278 return result.getResult();
288 if (!activeObjectImports.insert(objectValue).second)
289 return emitError(loc,
"cannot import mutually referential OM objects");
291 llvm::scope_exit popActiveObjectImport(
292 [&] { activeObjectImports.erase(objectValue); });
295 SmallVector<Value> fieldValues;
296 auto fieldNames = classLike.getFieldNames();
297 fieldValues.reserve(fieldNames.size());
298 for (
auto fieldName : fieldNames) {
299 auto fieldNameAttr = cast<StringAttr>(fieldName);
300 auto field = objectValue->
getField(fieldNameAttr);
303 auto materializedField = materializeInput(
304 field.value(), loc, classLike.getFieldType(fieldNameAttr).value());
305 if (failed(materializedField))
307 fieldValues.push_back(*materializedField);
310 OpBuilder builder(wrapperClass.getFieldsOp());
312 ElaboratedObjectOp::create(builder, loc, classLike, fieldValues);
313 importedValues[objectValue] = result.getResult();
314 return result.getResult();
320 Builder builder(module.getContext());
321 wrapperArgNames.push_back(
322 builder.getStringAttr(Twine(
"arg") + Twine(wrapperArgNames.size())));
323 wrapperActualParams.push_back(value);
324 return wrapperClass.getBodyBlock()->addArgument(argType, loc);
337SmallVector<evaluator::EvaluatorValuePtr>
339 ArrayRef<Attribute> attributes) {
340 SmallVector<evaluator::EvaluatorValuePtr> values;
341 values.reserve(attributes.size());
342 for (
auto attr : attributes)
348 return llvm::TypeSwitch<const EvaluatorValue *, Type>(
this)
349 .Case<
AttributeValue>([](
auto *attr) -> Type {
return attr->getType(); })
350 .Case<ObjectValue>([](
auto *
object) {
return object->getObjectType(); })
351 .Case<ListValue>([](
auto *list) {
return list->getListType(); })
352 .Case<BasePathValue>(
353 [
this](
auto *tuple) {
return FrozenBasePathType::get(
ctx); })
355 [
this](
auto *tuple) {
return FrozenPathType::get(
ctx); });
358FailureOr<evaluator::EvaluatorValuePtr>
363 TypeSwitch<mlir::Type, FailureOr<evaluator::EvaluatorValuePtr>>(type)
364 .Case([&](circt::om::ListType type) {
366 std::make_shared<evaluator::ListValue>(type, loc);
369 .Case([&](circt::om::ClassType type)
370 -> FailureOr<evaluator::EvaluatorValuePtr> {
372 symbolTable.lookup<ClassLike>(type.getClassName().getValue());
374 return symbolTable.getOp()->emitError(
"unknown class name ")
375 << type.getClassName();
379 std::make_shared<evaluator::ObjectValue>(classDef, loc);
383 .Case([&](circt::om::StringType type) {
388 .Default([&](
auto type) {
return failure(); });
395 LLVM_DEBUG(
dbgs() <<
"- get: " << value <<
"\n");
399 auto evalVal = it->second;
400 evalVal->setLocIfUnknown(loc);
404 FailureOr<evaluator::EvaluatorValuePtr> result =
405 TypeSwitch<Value, FailureOr<evaluator::EvaluatorValuePtr>>(value)
406 .Case([&](BlockArgument arg) {
409 .Case([&](OpResult result) {
410 return TypeSwitch<Operation *,
411 FailureOr<evaluator::EvaluatorValuePtr>>(
412 result.getDefiningOp())
413 .Case([&](ConstantOp op) {
416 .Case<AnyCastOp>([&](AnyCastOp op) {
419 .Case<FrozenBasePathCreateOp>([&](FrozenBasePathCreateOp op) {
421 std::make_shared<evaluator::BasePathValue>(
422 op.getPathAttr(), loc);
425 .Case<FrozenPathCreateOp>([&](FrozenPathCreateOp op) {
427 std::make_shared<evaluator::PathValue>(
428 op.getTargetKindAttr(), op.getPathAttr(),
429 op.getModuleAttr(), op.getRefAttr(),
430 op.getFieldAttr(), loc);
433 .Case<FrozenEmptyPathOp>([&](FrozenEmptyPathOp op) {
435 std::make_shared<evaluator::PathValue>(
439 .Case<ListCreateOp, ListConcatOp>([&](
auto op) {
442 .Case<ElaboratedObjectOp>([&](
auto op) {
445 .Case<UnknownValueOp>(
447 .Default([&](Operation *op) {
448 auto error = op->emitError(
"unable to evaluate value");
449 error.attachNote() <<
"value: " << value;
456 objects[value] = result.value();
460FailureOr<evaluator::EvaluatorValuePtr>
467 LLVM_DEBUG(
dbgs() <<
"object:\n");
471 LLVM_DEBUG(
dbgs() <<
"name: " << className <<
"\n");
473 auto classDef =
symbolTable.lookup<ClassLike>(className);
475 return symbolTable.getOp()->emitError(
"unknown class name ") << className;
478 if (isa<ClassExternOp>(classDef)) {
480 std::make_shared<evaluator::ObjectValue>(classDef, loc);
481 result->markUnknown();
482 LLVM_DEBUG(
dbgs(1) <<
"extern: <unknown-value>\n");
487 ClassOp cls = cast<ClassOp>(classDef);
489 if (failed(verifyActualParameters(cls, actualParams)))
495 auto *
context = cls.getContext();
497 LLVM_DEBUG(
dbgs() <<
"ops:\n");
504 for (
auto &op : cls.getOps())
505 for (
auto result : op.getResults())
511 for (
auto &op : cls.getOps())
512 for (
auto result : op.getResults()) {
513 auto evaluated =
evaluateValue(result, actualParams, op.getLoc());
514 if (failed(evaluated))
519 LLVM_DEBUG(
dbgs() <<
"fields:\n");
520 auto fieldNames = cls.getFieldNames();
521 auto operands = cls.getFieldsOp()->getOperands();
522 for (
size_t i = 0; i < fieldNames.size(); ++i) {
523 auto name = fieldNames[i];
524 auto value = operands[i];
525 auto fieldLoc = cls.getFieldLocByIndex(i);
526 LLVM_DEBUG(
dbgs() <<
"- name: " << name <<
"\n"
527 <<
indent(1) <<
"evaluate:\n");
531 FailureOr<evaluator::EvaluatorValuePtr> result =
536 LLVM_DEBUG(
dbgs() <<
"value: " << result.value() <<
"\n");
537 fields[cast<StringAttr>(name)] = result.value();
542 std::make_shared<evaluator::ObjectValue>(cls, fields, loc);
544 assert(result->isFullyEvaluated() &&
545 "object with fields should be fully evaluated");
550FailureOr<std::shared_ptr<evaluator::EvaluatorValue>>
552 StringAttr className, ArrayRef<evaluator::EvaluatorValuePtr> actualParams) {
553 LLVM_DEBUG(dbgs() <<
"instantiate:\n");
555 DebugNesting nest(debugNesting);
558 dbgs() <<
"class: " << className <<
"\n" << indent() <<
"params:\n";
559 for (
auto ¶m : actualParams)
560 dbgs() <<
"- " << param <<
"\n";
563 auto rootClass = symbolTable.lookup<ClassLike>(className);
565 return symbolTable.getOp()->emitError(
"unknown class name ") << className;
566 if (failed(verifyActualParameters(rootClass, actualParams)))
569 ScratchIRBuilder scratchBuilder(getModule(), symbolTable, rootClass);
570 auto transformedInstantiation = scratchBuilder.run(actualParams);
571 if (failed(transformedInstantiation))
574 auto wrapper = instantiateImpl(transformedInstantiation->className,
575 transformedInstantiation->actualParams);
580 cast<evaluator::ObjectValue>(wrapper.value().get())->getField(
"root");
586FailureOr<std::shared_ptr<evaluator::EvaluatorValue>>
588 StringAttr className, ArrayRef<evaluator::EvaluatorValuePtr> actualParams) {
589 auto classDef =
symbolTable.lookup<ClassLike>(className);
591 return symbolTable.getOp()->emitError(
"unknown class name ") << className;
594 if (isa<ClassExternOp>(classDef)) {
596 std::make_shared<evaluator::ObjectValue>(
597 classDef, UnknownLoc::get(classDef.getContext()));
598 result->markUnknown();
599 LLVM_DEBUG(
dbgs(1) <<
"result: <unknown extern>\n");
604 ClassOp cls = cast<ClassOp>(classDef);
606 auto loc = cls.getLoc();
607 LLVM_DEBUG(
dbgs() <<
"evaluate object:\n");
613 LLVM_DEBUG(
dbgs() <<
"result: " << result.value() <<
"\n");
617FailureOr<evaluator::EvaluatorValuePtr>
622 LLVM_DEBUG(
dbgs() <<
"- eval: " << value <<
"\n");
625 if (evaluatorValue->isFullyEvaluated()) {
626 LLVM_DEBUG(
dbgs(1) <<
"fully evaluated: " << evaluatorValue <<
"\n");
627 return evaluatorValue;
630 return llvm::TypeSwitch<Value, FailureOr<evaluator::EvaluatorValuePtr>>(value)
631 .Case([&](BlockArgument arg) {
634 .Case([&](OpResult result) {
635 return TypeSwitch<Operation *, FailureOr<evaluator::EvaluatorValuePtr>>(
636 result.getDefiningOp())
637 .Case([&](ConstantOp op) {
640 .Case([&](ElaboratedObjectOp op) {
643 .Case([&](ListCreateOp op) {
646 .Case([&](ListConcatOp op) {
649 .Case([&](AnyCastOp op) {
652 .Case([&](FrozenBasePathCreateOp op) {
655 .Case([&](FrozenPathCreateOp op) {
658 .Case([&](FrozenEmptyPathOp op) {
661 .Case<UnknownValueOp>([&](UnknownValueOp op) {
664 .Default([&](Operation *op) {
665 auto error = op->emitError(
"unable to evaluate value");
666 error.attachNote() <<
"value: " << value;
675 auto val = actualParams[formalParam.getArgNumber()];
681FailureOr<circt::om::evaluator::EvaluatorValuePtr>
689FailureOr<evaluator::EvaluatorValuePtr>
694 if (failed(objectValue))
696 auto *
object = cast<evaluator::ObjectValue>(objectValue.value().get());
697 if (object->isFullyEvaluated())
701 symbolTable.lookup<ClassLike>(op.getClassNameAttr().getAttr());
703 return symbolTable.getOp()->emitError(
"unknown class name ")
704 << op.getClassNameAttr();
706 auto fieldNames = classLike.getFieldNames();
707 auto fieldValues = op.getFieldValues();
708 if (fieldNames.size() != fieldValues.size())
709 return op.emitError(
"field value list doesn't match class field list, "
711 << fieldNames.size() <<
" values but got " << fieldValues.size();
714 auto classOp = dyn_cast<ClassOp>(classLike.getOperation());
715 for (
auto [index, fieldNameAndValue] :
716 llvm::enumerate(llvm::zip(fieldNames, fieldValues))) {
717 auto [fieldName, fieldValue] = fieldNameAndValue;
718 auto fieldLoc = classOp ? classOp.getFieldLocByIndex(index) : loc;
720 if (failed(fieldResult))
723 fields[cast<StringAttr>(fieldName)] = fieldResult.value();
726 object->setFields(std::move(fields));
731FailureOr<evaluator::EvaluatorValuePtr>
736 SmallVector<evaluator::EvaluatorValuePtr> values;
738 bool hasUnknown =
false;
739 for (
auto operand : op.getOperands()) {
743 if (!result.value()->isFullyEvaluated())
746 if (result.value()->isUnknown())
748 values.push_back(result.value());
752 llvm::cast<evaluator::ListValue>(list.value().get())
753 ->setElements(std::move(values));
759 list.value()->markUnknown();
765FailureOr<evaluator::EvaluatorValuePtr>
770 SmallVector<evaluator::EvaluatorValuePtr> values;
773 bool hasUnknown =
false;
774 for (
auto operand : op.getOperands()) {
778 if (!result.value()->isFullyEvaluated())
781 if (result.value()->isUnknown())
784 auto *subList = llvm::cast<evaluator::ListValue>(result.value().get());
787 for (
const auto &subValue : subList->getElements())
788 values.push_back(subValue);
792 llvm::cast<evaluator::ListValue>(list.value().get())
793 ->setElements(std::move(values));
799 list.value()->markUnknown();
804FailureOr<evaluator::EvaluatorValuePtr>
810 auto *path = llvm::cast<evaluator::BasePathValue>(valueResult.get());
811 auto result =
evaluateValue(op.getBasePath(), actualParams, loc);
814 auto &value = result.value();
815 if (!value->isFullyEvaluated())
819 if (result.value()->isUnknown()) {
820 valueResult->markUnknown();
824 path->setBasepath(*llvm::cast<evaluator::BasePathValue>(value.get()));
828FailureOr<evaluator::EvaluatorValuePtr>
834 auto *path = llvm::cast<evaluator::PathValue>(valueResult.get());
835 auto result =
evaluateValue(op.getBasePath(), actualParams, loc);
838 auto &value = result.value();
839 if (!value->isFullyEvaluated())
843 if (result.value()->isUnknown()) {
844 valueResult->markUnknown();
848 path->setBasepath(*llvm::cast<evaluator::BasePathValue>(value.get()));
859FailureOr<evaluator::EvaluatorValuePtr>
865 TypeSwitch<Type, FailureOr<EvaluatorValuePtr>>(type)
866 .Case([&](ListType type) -> FailureOr<EvaluatorValuePtr> {
868 return success(std::make_shared<ListValue>(type, loc));
870 .Case([&](ClassType type) -> FailureOr<EvaluatorValuePtr> {
873 symbolTable.lookup<ClassLike>(type.getClassName().getValue());
875 return symbolTable.getOp()->emitError(
"unknown class name ")
876 << type.getClassName();
879 return success(std::make_shared<ObjectValue>(classDef, loc));
881 .Case([&](FrozenBasePathType type) -> FailureOr<EvaluatorValuePtr> {
883 return success(std::make_shared<BasePathValue>(type.getContext()));
885 .Case([&](FrozenPathType type) -> FailureOr<EvaluatorValuePtr> {
890 .Default([&](Type type) -> FailureOr<EvaluatorValuePtr> {
897 if (succeeded(result))
898 result->get()->markUnknown();
904FailureOr<evaluator::EvaluatorValuePtr>
914FailureOr<EvaluatorValuePtr>
916 auto field =
fields.find(name);
917 if (field ==
fields.end())
918 return cls.emitError(
"field ") << name <<
" does not exist";
925 SmallVector<Attribute> fieldNames;
927 fieldNames.push_back(f.first);
929 llvm::sort(fieldNames, [](Attribute a, Attribute b) {
930 return cast<StringAttr>(a).getValue() < cast<StringAttr>(b).getValue();
933 return ArrayAttr::get(
cls.getContext(), fieldNames);
943 markFullyEvaluated();
947 :
EvaluatorValue(path.getContext(), Kind::BasePath, loc), path(path) {}
956 auto newPath = llvm::to_vector(basepath.
path.getPath());
957 auto oldPath =
path.getPath();
958 newPath.append(oldPath.begin(), oldPath.end());
959 path = PathAttr::get(
path.getContext(), newPath);
975 path.markFullyEvaluated();
982 return StringAttr::get(
getContext(),
"OMDeleted:");
983 SmallString<64> result;
985 case TargetKind::DontTouch:
986 result +=
"OMDontTouchedReferenceTarget";
988 case TargetKind::Instance:
989 result +=
"OMInstanceTarget";
991 case TargetKind::MemberInstance:
992 result +=
"OMMemberInstanceTarget";
994 case TargetKind::MemberReference:
995 result +=
"OMMemberReferenceTarget";
997 case TargetKind::Reference:
998 result +=
"OMReferenceTarget";
1002 if (!
path.getPath().empty())
1003 result +=
path.getPath().front().module;
1005 result +=
module.getValue();
1007 for (
const auto &elt :
path) {
1008 result += elt.module.getValue();
1010 result += elt.instance.getValue();
1013 if (!
module.getValue().empty())
1014 result +=
module.getValue();
1015 if (!
ref.getValue().empty()) {
1017 result +=
ref.getValue();
1019 if (!
field.getValue().empty())
1020 result +=
field.getValue();
1021 return StringAttr::get(
field.getContext(), result);
1026 auto newPath = llvm::to_vector(basepath.
getPath().getPath());
1027 auto oldPath =
path.getPath();
1028 newPath.append(oldPath.begin(), oldPath.end());
1029 path = PathAttr::get(
path.getContext(), newPath);
1039 return mlir::emitError(
getLoc(),
"cannot set AttributeValue of type ")
1040 << this->
type <<
" to Attribute " <<
attr;
1042 return mlir::emitError(
1044 "cannot set AttributeValue that has already been fully evaluated");
1050std::shared_ptr<evaluator::EvaluatorValue>
1052 auto type = cast<TypedAttr>(
attr).getType();
1059 if (
auto listType = dyn_cast<circt::om::ListType>(
type)) {
1060 SmallVector<EvaluatorValuePtr> elements;
1061 auto listAttr = cast<om::ListAttr>(
attr);
1063 listAttr.getContext(), listAttr.getElements().getValue());
1064 elements.append(values.begin(), values.end());
1065 auto list = std::make_shared<evaluator::ListValue>(listType, elements,
loc);
1069 return std::shared_ptr<AttributeValue>(
1073std::shared_ptr<evaluator::EvaluatorValue>
1081 if (
auto listType = dyn_cast<circt::om::ListType>(
type))
1082 return std::make_shared<evaluator::ListValue>(listType,
loc);
1084 return std::shared_ptr<AttributeValue>(
assert(baseType &&"element must be base type")
static std::unique_ptr< Context > context
static Location getLoc(DefSlot slot)
false return failure()
Parse an optional keyword or string and set instance into 'result'.
FailureOr< evaluator::EvaluatorValuePtr > evaluateBasePathCreate(FrozenBasePathCreateOp op, ActualParameters actualParams, Location loc)
FailureOr< EvaluatorValuePtr > evaluateElaboratedObject(ElaboratedObjectOp op, ActualParameters actualParams, Location loc)
FailureOr< evaluator::EvaluatorValuePtr > evaluateEmptyPath(FrozenEmptyPathOp op, ActualParameters actualParams, Location loc)
FailureOr< evaluator::EvaluatorValuePtr > instantiate(StringAttr className, ArrayRef< EvaluatorValuePtr > actualParams)
Instantiate an Object with its class name and actual parameters.
SymbolTable symbolTable
The symbol table for the IR module the Evaluator was constructed with.
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.
DenseMap< Value, std::shared_ptr< evaluator::EvaluatorValue > > objects
Evaluator value storage for the current instantiation.
mlir::ModuleOp getModule()
Get the Module this Evaluator is built from.
ArrayRef< EvaluatorValuePtr > ActualParameters
FailureOr< evaluator::EvaluatorValuePtr > createUnknownValue(Type type, Location loc)
Create an unknown value of the specified type.
FailureOr< EvaluatorValuePtr > evaluateObjectInstance(StringAttr className, ActualParameters actualParams, Location loc)
Instantiate an Object with its class name and actual parameters.
llvm::indent indent(unsigned extra=0)
unsigned debugNesting
Current nesting depth for debug output indentation.
FailureOr< evaluator::EvaluatorValuePtr > evaluateUnknownValue(UnknownValueOp op, Location loc)
Evaluate an unknown value.
Evaluator(ModuleOp mod)
Construct an Evaluator with an IR module.
raw_ostream & dbgs(unsigned extra=0)
FailureOr< EvaluatorValuePtr > getOrCreateValue(Value value, ActualParameters actualParams, Location loc)
FailureOr< evaluator::EvaluatorValuePtr > instantiateImpl(StringAttr className, ArrayRef< EvaluatorValuePtr > actualParams)
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.
FailureOr< EvaluatorValuePtr > evaluateParameter(BlockArgument formalParam, ActualParameters actualParams, Location loc)
Evaluator dispatch functions for the small expression grammar.
FailureOr< evaluator::EvaluatorValuePtr > evaluatePathCreate(FrozenPathCreateOp op, ActualParameters actualParams, Location loc)
Values which can be directly representable by MLIR attributes.
LogicalResult setAttr(Attribute attr)
Attribute getAttr() const
AttributeValue(PrivateTag, Attribute attr, Location loc)
static std::shared_ptr< EvaluatorValue > get(Attribute attr, LocationAttr loc={})
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.
bool isFullyEvaluated() const
EvaluatorValue(MLIRContext *ctx, Kind kind, Location loc)
MLIRContext * getContext() const
void markFullyEvaluated()
A List which contains variadic length of elements with the same type.
const auto & getElements() const
om::ListType getListType() const
Return the type of the value, which is a ListType.
A composite Object, which has a type and fields.
FailureOr< EvaluatorValuePtr > getField(StringAttr field)
Get a field of the Object by name.
ArrayAttr getFieldNames()
Get all the field names of the Object.
om::ClassLike getClassOp() const
llvm::SmallDenseMap< StringAttr, EvaluatorValuePtr > fields
StringAttr getAsString() const
om::TargetKindAttr targetKind
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)
SmallDenseMap< StringAttr, EvaluatorValuePtr > ObjectFields
The fields of a composite Object, currently represented as a map.
std::shared_ptr< EvaluatorValue > EvaluatorValuePtr
A value of an object in memory.
SmallVector< EvaluatorValuePtr > getEvaluatorValuesFromAttributes(MLIRContext *context, ArrayRef< Attribute > attributes)
evaluator::EvaluatorValuePtr EvaluatorValuePtr
RAII helper to increment/decrement debugNesting.