@@ -1316,6 +1316,53 @@ struct Deduper {
1316
1316
}
1317
1317
}
1318
1318
1319
+ hw::InnerSymAttr mergeInnerSymbols (RenameMap &renameMap, FModuleLike toModule,
1320
+ hw::InnerSymAttr toSym,
1321
+ hw::InnerSymAttr fromSym) {
1322
+ if (fromSym && !fromSym.getProps ().empty ()) {
1323
+ auto &isn = getNamespace (toModule);
1324
+ // The properties for the new inner symbol..
1325
+ SmallVector<hw::InnerSymPropertiesAttr> newProps;
1326
+ // If the "to" op already has an inner symbol, copy all its properties.
1327
+ if (toSym)
1328
+ llvm::append_range (newProps, toSym);
1329
+ // Add each property from the fromSym to the toSym.
1330
+ for (auto fromProp : fromSym) {
1331
+ hw::InnerSymPropertiesAttr newProp;
1332
+ auto *it = llvm::find_if (newProps, [&](auto p) {
1333
+ return p.getFieldID () == fromProp.getFieldID ();
1334
+ });
1335
+ if (it != newProps.end ()) {
1336
+ // If we already have an inner sym with the same field id, use
1337
+ // that.
1338
+ newProp = *it;
1339
+ // If the old symbol is public, we need to make the new one public.
1340
+ if (fromProp.getSymVisibility ().getValue () == " public" &&
1341
+ newProp.getSymVisibility ().getValue () != " public" ) {
1342
+ *it = hw::InnerSymPropertiesAttr::get (context, newProp.getName (),
1343
+ newProp.getFieldID (),
1344
+ fromProp.getSymVisibility ());
1345
+ }
1346
+ } else {
1347
+ // We need to add a new property to the inner symbol for this field.
1348
+ auto newName = isn.newName (fromProp.getName ().getValue ());
1349
+ newProp = hw::InnerSymPropertiesAttr::get (
1350
+ context, StringAttr::get (context, newName), fromProp.getFieldID (),
1351
+ fromProp.getSymVisibility ());
1352
+ newProps.push_back (newProp);
1353
+ }
1354
+ renameMap[fromProp.getName ()] = newProp.getName ();
1355
+ }
1356
+ // Sort the fields by field id.
1357
+ llvm::sort (newProps, [](auto &p, auto &q) {
1358
+ return p.getFieldID () < q.getFieldID ();
1359
+ });
1360
+ // Return the merged inner symbol.
1361
+ return hw::InnerSymAttr::get (context, newProps);
1362
+ }
1363
+ return hw::InnerSymAttr ();
1364
+ }
1365
+
1319
1366
// Record the symbol name change of the operation or any of its ports when
1320
1367
// merging two operations. The renamed symbols are used to update the
1321
1368
// target of any NLAs. This will add symbols to the "to" operation if needed.
@@ -1324,22 +1371,20 @@ struct Deduper {
1324
1371
Operation *from) {
1325
1372
// If the "from" operation has an inner_sym, we need to make sure the
1326
1373
// "to" operation also has an `inner_sym` and then record the renaming.
1327
- if (auto fromSym = getInnerSymName (from)) {
1328
- auto toSym =
1329
- getOrAddInnerSym (to, [&]( auto _) -> hw::InnerSymbolNamespace & {
1330
- return getNamespace (toModule);
1331
- });
1332
- renameMap[fromSym] = toSym ;
1374
+ if (auto fromInnerSym = dyn_cast<hw::InnerSymbolOpInterface> (from)) {
1375
+ auto toInnerSym = cast<hw::InnerSymbolOpInterface>(to);
1376
+ if ( auto newSymAttr = mergeInnerSymbols (renameMap, toModule,
1377
+ toInnerSym. getInnerSymAttr (),
1378
+ fromInnerSym. getInnerSymAttr ()))
1379
+ toInnerSym. setInnerSymbolAttr (newSymAttr) ;
1333
1380
}
1334
1381
1335
1382
// If there are no port symbols on the "from" operation, we are done here.
1336
1383
auto fromPortSyms = from->getAttrOfType <ArrayAttr>(" portSymbols" );
1337
1384
if (!fromPortSyms || fromPortSyms.empty ())
1338
1385
return ;
1339
1386
// We have to map each "fromPort" to each "toPort".
1340
- auto &moduleNamespace = getNamespace (toModule);
1341
1387
auto portCount = fromPortSyms.size ();
1342
- auto portNames = to->getAttrOfType <ArrayAttr>(" portNames" );
1343
1388
auto toPortSyms = to->getAttrOfType <ArrayAttr>(" portSymbols" );
1344
1389
1345
1390
// Create an array of new port symbols for the "to" operation, copy in the
@@ -1351,27 +1396,12 @@ struct Deduper {
1351
1396
newPortSyms.assign (toPortSyms.begin (), toPortSyms.end ());
1352
1397
1353
1398
for (unsigned portNo = 0 ; portNo < portCount; ++portNo) {
1354
- // If this fromPort doesn't have a symbol, move on to the next one.
1355
- if (!fromPortSyms[portNo])
1356
- continue ;
1357
- auto fromSym = cast<hw::InnerSymAttr>(fromPortSyms[portNo]);
1358
-
1359
- // If this toPort doesn't have a symbol, assign one.
1360
- hw::InnerSymAttr toSym;
1361
- if (!newPortSyms[portNo]) {
1362
- // Get a reasonable base name for the port.
1363
- StringRef symName = " inner_sym" ;
1364
- if (portNames)
1365
- symName = cast<StringAttr>(portNames[portNo]).getValue ();
1366
- // Create the symbol and store it into the array.
1367
- toSym = hw::InnerSymAttr::get (
1368
- StringAttr::get (context, moduleNamespace.newName (symName)));
1369
- newPortSyms[portNo] = toSym;
1370
- } else
1371
- toSym = cast<hw::InnerSymAttr>(newPortSyms[portNo]);
1372
-
1373
- // Record the renaming.
1374
- renameMap[fromSym.getSymName ()] = toSym.getSymName ();
1399
+ if (auto newPortSym = mergeInnerSymbols (
1400
+ renameMap, toModule,
1401
+ llvm::cast_if_present<hw::InnerSymAttr>(newPortSyms[portNo]),
1402
+ cast<hw::InnerSymAttr>(fromPortSyms[portNo]))) {
1403
+ newPortSyms[portNo] = newPortSym;
1404
+ }
1375
1405
}
1376
1406
1377
1407
// Commit the new symbol attribute.
0 commit comments