See Parallel OptMergePass implementation for context.
For maintainable multuthreaded read-only access to RTLIL, it would be extremely desirable for code that only has const references to RTLIL objects to be unable to mutate the RTLIL. Unfortunately one big reason that’s not true today is that a number of RTLIL objects expose public fields that are (non-const) pointers to other RTLIL objects, e.g. SigChunk::wire, SigBit::wire, Module::design, Wire::module, Cell::module, Process::module. There are also “pointer-like” fields that are containers (std::vector, pool, dict), e.g. Module::cells.
Fixing the design and module fields is actually pretty easy using a ConstPropagatingPtr class, with only a very small amount of non-RTLIL-core code needing to be updated. See GitHub - rocallahan/yosys at const-ptrs for details. Likewise we can also update some containers easily such as Design::modules_.
SigChunk::wire and SigBit::wire are more problematic. The problem is that we do pass these around by value in some cases so it’s quite normal to have a non-const SigBit where nevertheless we want the underlying Wire pointer to be const. We can’t just make it const for all SigBits because that breaks a lot of code. We may need “read only” variants of SigBit, SigChunk and SigSpec whose underlying Wire pointers are const even if the object itself is not. That would probably require a lot of API duplication, which we are trying to avoid, but I don’t have any better ideas at the moment.