57 CallableT transformTokensFn) {
58 return DictionaryAttr::getWithSorted(
61 anno.getValue(), [&](NamedAttribute namedAttr) -> NamedAttribute {
62 if (namedAttr.getName() ==
"target")
63 if (auto target = dyn_cast<StringAttr>(namedAttr.getValue()))
64 if (auto tokens = tokenizePath(target.getValue()))
67 StringAttr::get(target.getContext(),
68 transformTokensFn(tokens.value()).str())};
74 auto circuitName = circuit.getNameAttr();
76 llvm::MapVector<StringRef, Operation *> renameTable;
77 auto symbolTable = SymbolTable(circuit.getOperation());
78 auto manglePrivateSymbol = [&](SymbolOpInterface symbolOp) {
79 auto symbolName = symbolOp.getNameAttr();
81 StringAttr::get(symbolOp->getContext(),
82 circuitName.getValue() +
"_" + symbolName.getValue());
83 renameTable.insert(std::pair(symbolName.getValue(), symbolOp));
84 return symbolTable.rename(symbolOp, newSymbolName);
87 for (
auto &op : circuit.getOps()) {
88 auto symbolOp = dyn_cast<SymbolOpInterface>(op);
92 if (symbolOp.isPrivate())
93 if (failed(manglePrivateSymbol(symbolOp)))
97 circuit.walk([&](Operation *op) {
99 if (
auto cls = dyn_cast<ClassType>(type))
100 if (
auto *newOp = renameTable.lookup(cls.getName()))
101 return ClassType::get(FlatSymbolRefAttr::get(newOp),
105 auto updateTypeAttr = [&](Attribute attr) -> Attribute {
106 if (
auto typeAttr = dyn_cast<TypeAttr>(attr)) {
107 auto newType =
updateType(typeAttr.getValue());
108 if (newType != typeAttr.getValue())
109 return TypeAttr::get(newType);
113 auto updateResults = [&](
auto &&results) {
114 for (
auto result : results)
115 if (
auto newType =
updateType(result.getType());
116 newType != result.getType())
117 result.setType(newType);
120 TypeSwitch<Operation *>(op)
121 .Case<CircuitOp>([&](CircuitOp circuit) {
122 SmallVector<Attribute> newAnnotations;
124 circuit.getAnnotationsAttr(), std::back_inserter(newAnnotations),
125 [&](Attribute attr) {
126 return transformAnnotationTarget(
127 cast<DictionaryAttr>(attr), [&](TokenAnnoTarget &tokens) {
128 if (auto *newModule = renameTable.lookup(tokens.module))
130 cast<SymbolOpInterface>(newModule).getName();
134 circuit.setAnnotationsAttr(
135 ArrayAttr::get(circuit.getContext(), newAnnotations));
137 .Case<ObjectOp>([&](ObjectOp obj) {
138 auto resultTypeName = obj.getResult().getType().getName();
139 if (
auto *newOp = renameTable.lookup(resultTypeName))
140 obj.getResult().setType(dyn_cast<ClassOp>(newOp).getInstanceType());
142 .Case<FModuleOp>([&](FModuleOp module) {
143 SmallVector<Attribute> newPortTypes;
144 llvm::transform(module.getPortTypesAttr().getValue(),
145 std::back_inserter(newPortTypes), updateTypeAttr);
146 module.setPortTypesAttr(
147 ArrayAttr::get(module->getContext(), newPortTypes));
148 updateResults(module.getBodyBlock()->getArguments());
151 [&](InstanceOp instance) { updateResults(instance->getResults()); })
152 .Case<WireOp>([&](WireOp wire) { updateResults(wire->getResults()); })
153 .Default([](Operation *op) {});
160 SymbolOpInterface incomingOp) {
161 if (!((isa<FExtModuleOp>(collidingOp) && isa<FModuleOp>(incomingOp)) ||
162 (isa<FExtModuleOp>(incomingOp) && isa<FModuleOp>(collidingOp))))
164 auto definition = collidingOp;
165 auto declaration = incomingOp;
166 if (!isa<FModuleOp>(collidingOp)) {
167 definition = incomingOp;
168 declaration = collidingOp;
170 if (!definition.isPublic())
171 return definition->emitOpError(
"should be a public symbol");
172 if (!declaration.isPublic())
173 return declaration->emitOpError(
"should be a public symbol");
175 constexpr const StringRef attrsToCompare[] = {
176 "portDirections",
"portSymbols",
"portNames",
"portTypes",
"layers"};
177 auto allAttrsMatch = all_of(attrsToCompare, [&](StringRef attr) {
178 return definition->getAttr(attr) == declaration->getAttr(attr);
184 declaration->erase();
185 return declaration == incomingOp;