A replayable .il names twines and source location sets by pool index, and
a design that has freed slots writes a set with gaps in it. Reading such a
file into a fresh design packed the survivors, so write, read, write did
not reproduce the file.
Let the pools intern at a caller-chosen index and use that while loading
into a design with no twines or srcs of its own, falling back to the old
remapping when the file's numbering does not fit this build.
Source locations move off the attribute dict into a dedicated SrcRef on
AttrObject, interned in a per-design SrcPool that hash-conses sets of
location twines. Locations share their file prefix with each other through
the twine pool, and objects that fuse (opt_merge, share, ff/mem rewrites)
carry the union of their inputs' locations instead of a '|'-joined string.
write_rtlil emits an `srcs` section of location sets alongside `twines`;
read_rtlil resolves `\src "@N"` back to a handle and still accepts a plain
location string. -readable renders the locations as text.