Merge pull request #436 from hzeller/20230111-get-ready-for-string-view

Prepare plug-in to be ready for UHDM string_view return values.
diff --git a/systemverilog-plugin/UhdmAst.cc b/systemverilog-plugin/UhdmAst.cc
index 7795e7d..0a1b626 100644
--- a/systemverilog-plugin/UhdmAst.cc
+++ b/systemverilog-plugin/UhdmAst.cc
@@ -67,6 +67,11 @@
     static const IdString id("\\is_imported");
     return id;
 }
+/*static*/ const IdString &UhdmAst::is_simplified_wire()
+{
+    static const IdString id("\\is_simplified_wire");
+    return id;
+}
 
 static void sanitize_symbol_name(std::string &name)
 {
@@ -944,6 +949,8 @@
         AST_INTERNAL::current_scope[current_node->str] = current_node;
         break;
     case AST::AST_WIRE:
+        current_node->attributes[UhdmAst::is_simplified_wire()] = AST::AstNode::mkconst_int(1, true);
+        [[fallthrough]];
     case AST::AST_PARAMETER:
     case AST::AST_LOCALPARAM:
         AST_INTERNAL::current_scope[current_node->str] = current_node;
@@ -956,7 +963,11 @@
                 break;
             }
             AST::AstNode *wire_node = AST_INTERNAL::current_scope[current_node->str];
-            simplify(wire_node, nullptr);
+
+            // if a wire is simplified multiple times, its ranges may be added multiple times and be redundant as a result
+            if (!wire_node->attributes.count(UhdmAst::is_simplified_wire())) {
+                simplify(wire_node, nullptr);
+            }
             const std::vector<AST::AstNode *> packed_ranges = wire_node->attributes.count(UhdmAst::packed_ranges())
                                                                 ? wire_node->attributes[UhdmAst::packed_ranges()]->children
                                                                 : std::vector<AST::AstNode *>();
@@ -1634,6 +1645,10 @@
         visitEachDescendant(current_node, [&](AST::AstNode *node) {
             node->attributes.erase(UhdmAst::packed_ranges());
             node->attributes.erase(UhdmAst::unpacked_ranges());
+            if (node->attributes.count(UhdmAst::is_simplified_wire())) {
+                delete node->attributes[UhdmAst::is_simplified_wire()];
+                node->attributes.erase(UhdmAst::is_simplified_wire());
+            }
         });
     }
 }
diff --git a/systemverilog-plugin/UhdmAst.h b/systemverilog-plugin/UhdmAst.h
index f3b1017..6d6a8f6 100644
--- a/systemverilog-plugin/UhdmAst.h
+++ b/systemverilog-plugin/UhdmAst.h
@@ -174,6 +174,7 @@
     // set this attribute to force conversion of multirange wire to single range. It is useful to force-convert some memories.
     static const ::Yosys::IdString &force_convert();
     static const ::Yosys::IdString &is_imported();
+    static const ::Yosys::IdString &is_simplified_wire();
 };
 
 } // namespace systemverilog_plugin