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) {});
187 SymbolOpInterface incomingOp) {
188 if (!collidingOp.isPublic())
189 return collidingOp->emitOpError(
"should be a public symbol");
190 if (!incomingOp.isPublic())
191 return incomingOp->emitOpError(
"should be a public symbol");
193 if ((isa<FExtModuleOp>(collidingOp) && isa<FModuleOp>(incomingOp)) ||
194 (isa<FExtModuleOp>(incomingOp) && isa<FModuleOp>(collidingOp))) {
195 auto definition = collidingOp;
196 auto declaration = incomingOp;
197 if (!isa<FModuleOp>(collidingOp)) {
198 definition = incomingOp;
199 declaration = collidingOp;
202 constexpr const StringRef attrsToCompare[] = {
203 "portDirections",
"portSymbols",
"portNames",
"portTypes",
"layers"};
204 if (!all_of(attrsToCompare, [&](StringRef attr) {
205 return definition->getAttr(attr) == declaration->getAttr(attr);
209 declaration->erase();
210 return declaration == incomingOp;
213 if (isa<FExtModuleOp>(collidingOp) && isa<FExtModuleOp>(incomingOp)) {
214 constexpr const StringRef attrsToCompare[] = {
215 "portDirections",
"portSymbols",
"portNames",
216 "portTypes",
"knownLayers",
"layers",
218 if (!all_of(attrsToCompare, [&](StringRef attr) {
219 return collidingOp->getAttr(attr) == incomingOp->getAttr(attr);
223 auto collidingParams = collidingOp->getAttrOfType<ArrayAttr>(
"parameters");
224 auto incomingParams = incomingOp->getAttrOfType<ArrayAttr>(
"parameters");
225 if (collidingParams == incomingParams) {
226 if (collidingOp->getAttr(
"defname") != incomingOp->getAttr(
"defname"))
234 if (collidingParams.empty() || incomingParams.empty()) {
235 auto declaration = collidingParams.empty() ? collidingOp : incomingOp;
236 declaration->erase();
237 return declaration == incomingOp;