summary refs log tree commit diff stats
path: root/compiler/ic
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2021-04-19 11:48:06 +0200
committerGitHub <noreply@github.com>2021-04-19 11:48:06 +0200
commit4b0b536419a500dc2e5a987ed9c2a374e0848008 (patch)
treed2f0caf0cfe36dc549ecadefee9ed1002b66558f /compiler/ic
parent83fa0fc843a5757c6fa1af9ac89b85b71c0c7581 (diff)
downloadNim-4b0b536419a500dc2e5a987ed9c2a374e0848008.tar.gz
ic refactoring (#17778)
* minor IC documentation update

* IC: refactoring: removed the 'shared' type and fields, these were a leftover from an earlier design
Diffstat (limited to 'compiler/ic')
-rw-r--r--compiler/ic/dce.nim18
-rw-r--r--compiler/ic/design.rst8
-rw-r--r--compiler/ic/ic.nim175
-rw-r--r--compiler/ic/integrity.nim26
-rw-r--r--compiler/ic/navigator.nim12
-rw-r--r--compiler/ic/packed_ast.nim56
-rw-r--r--compiler/ic/rodfiles.nim10
7 files changed, 146 insertions, 159 deletions
diff --git a/compiler/ic/dce.nim b/compiler/ic/dce.nim
index 0918fc379..48ed414e2 100644
--- a/compiler/ic/dce.nim
+++ b/compiler/ic/dce.nim
@@ -27,7 +27,7 @@ type
 proc isExportedToC(c: var AliveContext; g: PackedModuleGraph; symId: int32): bool =
   ## "Exported to C" procs are special (these are marked with '.exportc') because these
   ## must not be optimized away!
-  let symPtr = addr g[c.thisModule].fromDisk.sh.syms[symId]
+  let symPtr = unsafeAddr g[c.thisModule].fromDisk.syms[symId]
   let flags = symPtr.flags
   # due to a bug/limitation in the lambda lifting, unused inner procs
   # are not transformed correctly; issue (#411). However, the whole purpose here
@@ -39,7 +39,7 @@ proc isExportedToC(c: var AliveContext; g: PackedModuleGraph; symId: int32): boo
       # XXX: This used to be a condition to:
       #  (sfExportc in prc.flags and lfExportLib in prc.loc.flags) or
     if sfCompilerProc in flags:
-      c.compilerProcs[g[c.thisModule].fromDisk.sh.strings[symPtr.name]] = (c.thisModule, symId)
+      c.compilerProcs[g[c.thisModule].fromDisk.strings[symPtr.name]] = (c.thisModule, symId)
 
 template isNotGeneric(n: NodePos): bool = ithSon(tree, n, genericParamsPos).kind == nkEmpty
 
@@ -47,17 +47,17 @@ proc followLater(c: var AliveContext; g: PackedModuleGraph; module: int; item: i
   ## Marks a symbol 'item' as used and later in 'followNow' the symbol's body will
   ## be analysed.
   if not c.alive[module].containsOrIncl(item):
-    var body = g[module].fromDisk.sh.syms[item].ast
+    var body = g[module].fromDisk.syms[item].ast
     if body != emptyNodeId:
-      let opt = g[module].fromDisk.sh.syms[item].options
-      if g[module].fromDisk.sh.syms[item].kind in routineKinds:
+      let opt = g[module].fromDisk.syms[item].options
+      if g[module].fromDisk.syms[item].kind in routineKinds:
         body = NodeId ithSon(g[module].fromDisk.bodies, NodePos body, bodyPos)
       c.stack.add((module, opt, NodePos(body)))
 
     when false:
-      let nid = g[module].fromDisk.sh.syms[item].name
+      let nid = g[module].fromDisk.syms[item].name
       if nid != LitId(0):
-        let name = g[module].fromDisk.sh.strings[nid]
+        let name = g[module].fromDisk.strings[nid]
         if name in ["nimFrame", "callDepthLimitReached"]:
           echo "I was called! ", name, " body exists: ", body != emptyNodeId, " ", module, " ", item
 
@@ -66,12 +66,12 @@ proc requestCompilerProc(c: var AliveContext; g: PackedModuleGraph; name: string
   followLater(c, g, module, item)
 
 proc loadTypeKind(t: PackedItemId; c: AliveContext; g: PackedModuleGraph; toSkip: set[TTypeKind]): TTypeKind =
-  template kind(t: ItemId): TTypeKind = g[t.module].fromDisk.sh.types[t.item].kind
+  template kind(t: ItemId): TTypeKind = g[t.module].fromDisk.types[t.item].kind
 
   var t2 = translateId(t, g, c.thisModule, c.decoder.config)
   result = t2.kind
   while result in toSkip:
-    t2 = translateId(g[t2.module].fromDisk.sh.types[t2.item].types[^1], g, t2.module, c.decoder.config)
+    t2 = translateId(g[t2.module].fromDisk.types[t2.item].types[^1], g, t2.module, c.decoder.config)
     result = t2.kind
 
 proc rangeCheckAnalysis(c: var AliveContext; g: PackedModuleGraph; tree: PackedTree; n: NodePos) =
diff --git a/compiler/ic/design.rst b/compiler/ic/design.rst
index d8e1315b1..b096e3103 100644
--- a/compiler/ic/design.rst
+++ b/compiler/ic/design.rst
@@ -7,12 +7,8 @@ The frontend produces a set of `.rod` files. Every `.nim` module
 produces its own `.rod` file.
 
 - The IR must be a faithful representation of the AST in memory.
-- The backend can do its own caching but doesn't have to.
-- We know by comparing 'nim check compiler/nim' against 'nim c compiler/nim'
-  that 2/3 of the compiler's runtime is spent in the frontend. Hence we
-  implement IC for the frontend first and only later for the backend. The
-  backend will recompile everything until we implement its own caching
-  mechanisms.
+- The backend can do its own caching but doesn't have to. In the
+  current implementation the backend also caches its results.
 
 Advantage of the "set of files" vs the previous global database:
 - By construction, we either read from the `.rod` file or from the
diff --git a/compiler/ic/ic.nim b/compiler/ic/ic.nim
index 6f208a2a4..a23685be7 100644
--- a/compiler/ic/ic.nim
+++ b/compiler/ic/ic.nim
@@ -51,7 +51,12 @@ type
     emittedTypeInfo*: seq[string]
     backendFlags*: set[ModuleBackendFlag]
 
-    sh*: Shared
+    syms*: seq[PackedSym]
+    types*: seq[PackedType]
+    strings*: BiTable[string] # we could share these between modules.
+    numbers*: BiTable[BiggestInt] # we also store floats in here so
+                                  # that we can assure that every bit is kept
+
     cfg: PackedConfig
 
   PackedEncoder* = object
@@ -66,6 +71,50 @@ type
     symMarker*: IntSet #Table[ItemId, SymId]    # ItemId.item -> SymId
     config*: ConfigRef
 
+proc toString*(tree: PackedTree; n: NodePos; m: PackedModule; nesting: int;
+               result: var string) =
+  let pos = n.int
+  if result.len > 0 and result[^1] notin {' ', '\n'}:
+    result.add ' '
+
+  result.add $tree[pos].kind
+  case tree.nodes[pos].kind
+  of nkNone, nkEmpty, nkNilLit, nkType: discard
+  of nkIdent, nkStrLit..nkTripleStrLit:
+    result.add " "
+    result.add m.strings[LitId tree.nodes[pos].operand]
+  of nkSym:
+    result.add " "
+    result.add m.strings[m.syms[tree.nodes[pos].operand].name]
+  of directIntLit:
+    result.add " "
+    result.addInt tree.nodes[pos].operand
+  of externSIntLit:
+    result.add " "
+    result.addInt m.numbers[LitId tree.nodes[pos].operand]
+  of externUIntLit:
+    result.add " "
+    result.add $cast[uint64](m.numbers[LitId tree.nodes[pos].operand])
+  of nkFloatLit..nkFloat128Lit:
+    result.add " "
+    result.add $cast[BiggestFloat](m.numbers[LitId tree.nodes[pos].operand])
+  else:
+    result.add "(\n"
+    for i in 1..(nesting+1)*2: result.add ' '
+    for child in sonsReadonly(tree, n):
+      toString(tree, child, m, nesting + 1, result)
+    result.add "\n"
+    for i in 1..nesting*2: result.add ' '
+    result.add ")"
+    #for i in 1..nesting*2: result.add ' '
+
+proc toString*(tree: PackedTree; n: NodePos; m: PackedModule): string =
+  result = ""
+  toString(tree, n, m, 0, result)
+
+proc debug*(tree: PackedTree; m: PackedModule) =
+  stdout.write toString(tree, NodePos 0, m)
+
 proc isActive*(e: PackedEncoder): bool = e.config != nil
 proc disable(e: var PackedEncoder) = e.config = nil
 
@@ -134,14 +183,14 @@ proc toLitId(x: FileIndex; c: var PackedEncoder; m: var PackedModule): LitId =
     result = c.filenames.getOrDefault(x)
     if result == LitId(0):
       let p = msgs.toFullPath(c.config, x)
-      result = getOrIncl(m.sh.strings, p)
+      result = getOrIncl(m.strings, p)
       c.filenames[x] = result
     c.lastFile = x
     c.lastLit = result
   assert result != LitId(0)
 
 proc toFileIndex*(x: LitId; m: PackedModule; config: ConfigRef): FileIndex =
-  result = msgs.fileInfoIdx(config, AbsoluteFile m.sh.strings[x])
+  result = msgs.fileInfoIdx(config, AbsoluteFile m.strings[x])
 
 proc includesIdentical(m: var PackedModule; config: ConfigRef): bool =
   for it in mitems(m.includes):
@@ -151,7 +200,6 @@ proc includesIdentical(m: var PackedModule; config: ConfigRef): bool =
 
 proc initEncoder*(c: var PackedEncoder; m: var PackedModule; moduleSym: PSym; config: ConfigRef; pc: PackedConfig) =
   ## setup a context for serializing to packed ast
-  m.sh = Shared()
   c.thisModule = moduleSym.itemId.module
   c.config = config
   m.moduleFlags = moduleSym.flags
@@ -179,11 +227,11 @@ proc addImportFileDep*(c: var PackedEncoder; m: var PackedModule; f: FileIndex)
   m.imports.add toLitId(f, c, m)
 
 proc addHidden*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
-  let nameId = getOrIncl(m.sh.strings, s.name.s)
+  let nameId = getOrIncl(m.strings, s.name.s)
   m.hidden.add((nameId, s.itemId.item))
 
 proc addExported*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
-  let nameId = getOrIncl(m.sh.strings, s.name.s)
+  let nameId = getOrIncl(m.strings, s.name.s)
   m.exports.add((nameId, s.itemId.item))
 
 proc addConverter*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
@@ -201,12 +249,12 @@ proc addMethod*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
   m.methods.add s.itemId.item
 
 proc addReexport*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
-  let nameId = getOrIncl(m.sh.strings, s.name.s)
+  let nameId = getOrIncl(m.strings, s.name.s)
   m.reexports.add((nameId, PackedItemId(module: toLitId(s.itemId.module.FileIndex, c, m),
                                         item: s.itemId.item)))
 
 proc addCompilerProc*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
-  let nameId = getOrIncl(m.sh.strings, s.name.s)
+  let nameId = getOrIncl(m.strings, s.name.s)
   m.compilerProcs.add((nameId, s.itemId.item))
 
 proc toPackedNode*(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var PackedModule)
@@ -225,11 +273,11 @@ proc flush(c: var PackedEncoder; m: var PackedModule) =
 
 proc toLitId(x: string; m: var PackedModule): LitId =
   ## store a string as a literal
-  result = getOrIncl(m.sh.strings, x)
+  result = getOrIncl(m.strings, x)
 
 proc toLitId(x: BiggestInt; m: var PackedModule): LitId =
   ## store an integer as a literal
-  result = getOrIncl(m.sh.numbers, x)
+  result = getOrIncl(m.numbers, x)
 
 proc toPackedInfo(x: TLineInfo; c: var PackedEncoder; m: var PackedModule): PackedLineInfo =
   PackedLineInfo(line: x.line, col: x.col, file: toLitId(x.fileIndex, c, m))
@@ -299,8 +347,8 @@ proc storeType(t: PType; c: var PackedEncoder; m: var PackedModule): PackedItemI
   result = PackedItemId(module: toLitId(t.uniqueId.module.FileIndex, c, m), item: t.uniqueId.item)
 
   if t.uniqueId.module == c.thisModule and not c.typeMarker.containsOrIncl(t.uniqueId.item):
-    if t.uniqueId.item >= m.sh.types.len:
-      setLen m.sh.types, t.uniqueId.item+1
+    if t.uniqueId.item >= m.types.len:
+      setLen m.types, t.uniqueId.item+1
 
     var p = PackedType(kind: t.kind, flags: t.flags, callConv: t.callConv,
       size: t.size, align: t.align, nonUniqueId: t.itemId.item,
@@ -315,7 +363,7 @@ proc storeType(t: PType; c: var PackedEncoder; m: var PackedModule): PackedItemI
     p.owner = t.owner.safeItemId(c, m)
 
     # fill the reserved slot, nothing else:
-    m.sh.types[t.uniqueId.item] = p
+    m.types[t.uniqueId.item] = p
 
 proc toPackedLib(l: PLib; c: var PackedEncoder; m: var PackedModule): PackedLib =
   ## the plib hangs off the psym via the .annex field
@@ -334,8 +382,8 @@ proc storeSym*(s: PSym; c: var PackedEncoder; m: var PackedModule): PackedItemId
   result = PackedItemId(module: toLitId(s.itemId.module.FileIndex, c, m), item: s.itemId.item)
 
   if s.itemId.module == c.thisModule and not c.symMarker.containsOrIncl(s.itemId.item):
-    if s.itemId.item >= m.sh.syms.len:
-      setLen m.sh.syms, s.itemId.item+1
+    if s.itemId.item >= m.syms.len:
+      setLen m.syms, s.itemId.item+1
 
     assert sfForward notin s.flags
 
@@ -363,7 +411,7 @@ proc storeSym*(s: PSym; c: var PackedEncoder; m: var PackedModule): PackedItemId
       p.cname = toLitId(s.cname, m)
 
     # fill the reserved slot, nothing else:
-    m.sh.syms[s.itemId.item] = p
+    m.syms[s.itemId.item] = p
 
 proc addModuleRef(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var PackedModule) =
   ## add a remote symbol reference to the tree
@@ -387,7 +435,7 @@ proc toPackedNode*(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var Pa
                             typeId: storeTypeLater(n.typ, c, m), info: info)
   of nkIdent:
     ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
-                            operand: int32 getOrIncl(m.sh.strings, n.ident.s),
+                            operand: int32 getOrIncl(m.strings, n.ident.s),
                             typeId: storeTypeLater(n.typ, c, m), info: info)
   of nkSym:
     if n.sym.itemId.module == c.thisModule:
@@ -405,15 +453,15 @@ proc toPackedNode*(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var Pa
                             typeId: storeTypeLater(n.typ, c, m), info: info)
   of externIntLit:
     ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
-                            operand: int32 getOrIncl(m.sh.numbers, n.intVal),
+                            operand: int32 getOrIncl(m.numbers, n.intVal),
                             typeId: storeTypeLater(n.typ, c, m), info: info)
   of nkStrLit..nkTripleStrLit:
     ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
-                            operand: int32 getOrIncl(m.sh.strings, n.strVal),
+                            operand: int32 getOrIncl(m.strings, n.strVal),
                             typeId: storeTypeLater(n.typ, c, m), info: info)
   of nkFloatLit..nkFloat128Lit:
     ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
-                            operand: int32 getOrIncl(m.sh.numbers, cast[BiggestInt](n.floatVal)),
+                            operand: int32 getOrIncl(m.numbers, cast[BiggestInt](n.floatVal)),
                             typeId: storeTypeLater(n.typ, c, m), info: info)
   else:
     let patchPos = ir.prepare(n.kind, n.flags,
@@ -499,7 +547,6 @@ proc loadError(err: RodFileError; filename: AbsoluteFile; config: ConfigRef;) =
 
 proc loadRodFile*(filename: AbsoluteFile; m: var PackedModule; config: ConfigRef;
                   ignoreConfig = false): RodFileError =
-  m.sh = Shared()
   var f = rodfiles.open(filename.string)
   f.loadHeader()
   f.loadSection configSection
@@ -519,7 +566,7 @@ proc loadRodFile*(filename: AbsoluteFile; m: var PackedModule; config: ConfigRef
     f.loadSection section
     f.load data
 
-  loadTabSection stringsSection, m.sh.strings
+  loadTabSection stringsSection, m.strings
 
   loadSeqSection checkSumsSection, m.includes
   if not includesIdentical(m, config):
@@ -527,7 +574,7 @@ proc loadRodFile*(filename: AbsoluteFile; m: var PackedModule; config: ConfigRef
 
   loadSeqSection depsSection, m.imports
 
-  loadTabSection numbersSection, m.sh.numbers
+  loadTabSection numbersSection, m.numbers
 
   loadSeqSection exportsSection, m.exports
   loadSeqSection hiddenSection, m.hidden
@@ -545,8 +592,8 @@ proc loadRodFile*(filename: AbsoluteFile; m: var PackedModule; config: ConfigRef
   loadSeqSection toReplaySection, m.toReplay.nodes
   loadSeqSection topLevelSection, m.topLevel.nodes
   loadSeqSection bodiesSection, m.bodies.nodes
-  loadSeqSection symsSection, m.sh.syms
-  loadSeqSection typesSection, m.sh.types
+  loadSeqSection symsSection, m.syms
+  loadSeqSection typesSection, m.types
 
   loadSeqSection typeInstCacheSection, m.typeInstCache
   loadSeqSection procInstCacheSection, m.procInstCache
@@ -586,13 +633,13 @@ proc saveRodFile*(filename: AbsoluteFile; encoder: var PackedEncoder; m: var Pac
     f.storeSection section
     f.store data
 
-  storeTabSection stringsSection, m.sh.strings
+  storeTabSection stringsSection, m.strings
 
   storeSeqSection checkSumsSection, m.includes
 
   storeSeqSection depsSection, m.imports
 
-  storeTabSection numbersSection, m.sh.numbers
+  storeTabSection numbersSection, m.numbers
 
   storeSeqSection exportsSection, m.exports
   storeSeqSection hiddenSection, m.hidden
@@ -610,9 +657,9 @@ proc saveRodFile*(filename: AbsoluteFile; encoder: var PackedEncoder; m: var Pac
   storeSeqSection topLevelSection, m.topLevel.nodes
 
   storeSeqSection bodiesSection, m.bodies.nodes
-  storeSeqSection symsSection, m.sh.syms
+  storeSeqSection symsSection, m.syms
 
-  storeSeqSection typesSection, m.sh.types
+  storeSeqSection typesSection, m.types
 
   storeSeqSection typeInstCacheSection, m.typeInstCache
   storeSeqSection procInstCacheSection, m.procInstCache
@@ -700,17 +747,17 @@ proc loadNodes*(c: var PackedDecoder; g: var PackedModuleGraph; thisModule: int;
   of nkEmpty, nkNilLit, nkType:
     discard
   of nkIdent:
-    result.ident = getIdent(c.cache, g[thisModule].fromDisk.sh.strings[n.litId])
+    result.ident = getIdent(c.cache, g[thisModule].fromDisk.strings[n.litId])
   of nkSym:
     result.sym = loadSym(c, g, thisModule, PackedItemId(module: LitId(0), item: tree.nodes[n.int].operand))
   of directIntLit:
     result.intVal = tree.nodes[n.int].operand
   of externIntLit:
-    result.intVal = g[thisModule].fromDisk.sh.numbers[n.litId]
+    result.intVal = g[thisModule].fromDisk.numbers[n.litId]
   of nkStrLit..nkTripleStrLit:
-    result.strVal = g[thisModule].fromDisk.sh.strings[n.litId]
+    result.strVal = g[thisModule].fromDisk.strings[n.litId]
   of nkFloatLit..nkFloat128Lit:
-    result.floatVal = cast[BiggestFloat](g[thisModule].fromDisk.sh.numbers[n.litId])
+    result.floatVal = cast[BiggestFloat](g[thisModule].fromDisk.numbers[n.litId])
   of nkModuleRef:
     let (n1, n2) = sons2(tree, n)
     assert n1.kind == nkInt32Lit
@@ -767,7 +814,7 @@ proc symHeaderFromPacked(c: var PackedDecoder; g: var PackedModuleGraph;
     options: s.options,
     position: if s.kind in {skForVar, skVar, skLet, skTemp}: 0 else: s.position,
     offset: if s.kind in routineKinds: defaultOffset else: s.offset,
-    name: getIdent(c.cache, g[si].fromDisk.sh.strings[s.name])
+    name: getIdent(c.cache, g[si].fromDisk.strings[s.name])
   )
 
 template loadAstBody(p, field) =
@@ -785,7 +832,7 @@ proc loadLib(c: var PackedDecoder; g: var PackedModuleGraph;
     result = nil
   else:
     result = PLib(generated: l.generated, isOverriden: l.isOverriden,
-                  kind: l.kind, name: rope g[si].fromDisk.sh.strings[l.name])
+                  kind: l.kind, name: rope g[si].fromDisk.strings[l.name])
     loadAstBody(l, path)
 
 proc symBodyFromPacked(c: var PackedDecoder; g: var PackedModuleGraph;
@@ -798,14 +845,14 @@ proc symBodyFromPacked(c: var PackedDecoder; g: var PackedModuleGraph;
     loadAstBody(s, ast)
   result.annex = loadLib(c, g, si, item, s.annex)
   when hasFFI:
-    result.cname = g[si].fromDisk.sh.strings[s.cname]
+    result.cname = g[si].fromDisk.strings[s.cname]
 
   if s.kind in {skLet, skVar, skField, skForVar}:
     result.guard = loadSym(c, g, si, s.guard)
     result.bitsize = s.bitsize
     result.alignment = s.alignment
   result.owner = loadSym(c, g, si, s.owner)
-  let externalName = g[si].fromDisk.sh.strings[s.externalName]
+  let externalName = g[si].fromDisk.strings[s.externalName]
   if externalName != "":
     result.loc.r = rope externalName
   result.loc.flags = s.locFlags
@@ -818,14 +865,14 @@ proc loadSym(c: var PackedDecoder; g: var PackedModuleGraph; thisModule: int; s:
     assert g[si].status in {loaded, storing, stored}
     if not g[si].symsInit:
       g[si].symsInit = true
-      setLen g[si].syms, g[si].fromDisk.sh.syms.len
+      setLen g[si].syms, g[si].fromDisk.syms.len
 
     if g[si].syms[s.item] == nil:
-      if g[si].fromDisk.sh.syms[s.item].kind != skModule:
-        result = symHeaderFromPacked(c, g, g[si].fromDisk.sh.syms[s.item], si, s.item)
+      if g[si].fromDisk.syms[s.item].kind != skModule:
+        result = symHeaderFromPacked(c, g, g[si].fromDisk.syms[s.item], si, s.item)
         # store it here early on, so that recursions work properly:
         g[si].syms[s.item] = result
-        symBodyFromPacked(c, g, g[si].fromDisk.sh.syms[s.item], si, s.item, result)
+        symBodyFromPacked(c, g, g[si].fromDisk.syms[s.item], si, s.item, result)
       else:
         result = g[si].module
         assert result != nil
@@ -866,13 +913,13 @@ proc loadType(c: var PackedDecoder; g: var PackedModuleGraph; thisModule: int; t
 
     if not g[si].typesInit:
       g[si].typesInit = true
-      setLen g[si].types, g[si].fromDisk.sh.types.len
+      setLen g[si].types, g[si].fromDisk.types.len
 
     if g[si].types[t.item] == nil:
-      result = typeHeaderFromPacked(c, g, g[si].fromDisk.sh.types[t.item], si, t.item)
+      result = typeHeaderFromPacked(c, g, g[si].fromDisk.types[t.item], si, t.item)
       # store it here early on, so that recursions work properly:
       g[si].types[t.item] = result
-      typeBodyFromPacked(c, g, g[si].fromDisk.sh.types[t.item], si, t.item, result)
+      typeBodyFromPacked(c, g, g[si].fromDisk.types[t.item], si, t.item, result)
     else:
       result = g[si].types[t.item]
     assert result.itemId.item > 0
@@ -897,7 +944,7 @@ proc setupLookupTables(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCa
     let e2 =
       when e[1] is PackedItemId: e[1]
       else: PackedItemId(module: LitId(0), item: e[1])
-    iface.mgetOrPut(cache.getIdent(m.fromDisk.sh.strings[nameLit]), @[]).add(e2)
+    iface.mgetOrPut(cache.getIdent(m.fromDisk.strings[nameLit]), @[]).add(e2)
 
   for e in m.fromDisk.exports:
     m.iface.impl(e)
@@ -1000,7 +1047,7 @@ proc loadProcBody*(config: ConfigRef, cache: IdentCache;
     lastFile: FileIndex(-1),
     config: config,
     cache: cache)
-  let pos = g[mId].fromDisk.sh.syms[s.itemId.item].ast
+  let pos = g[mId].fromDisk.syms[s.itemId.item].ast
   assert pos != emptyNodeId
   result = loadProcBody(decoder, g, mId, g[mId].fromDisk.bodies, NodePos pos)
 
@@ -1042,15 +1089,15 @@ proc translateId*(id: PackedItemId; g: PackedModuleGraph; thisModule: int; confi
 
 proc checkForHoles(m: PackedModule; config: ConfigRef; moduleId: int) =
   var bugs = 0
-  for i in 1 .. high(m.sh.syms):
-    if m.sh.syms[i].kind == skUnknown:
+  for i in 1 .. high(m.syms):
+    if m.syms[i].kind == skUnknown:
       echo "EMPTY ID ", i, " module ", moduleId, " ", toFullPath(config, FileIndex(moduleId))
       inc bugs
   assert bugs == 0
   when false:
     var nones = 0
-    for i in 1 .. high(m.sh.types):
-      inc nones, m.sh.types[i].kind == tyNone
+    for i in 1 .. high(m.types):
+      inc nones, m.types[i].kind == tyNone
     assert nones < 1
 
 proc simulateLoadedModule*(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache;
@@ -1133,13 +1180,13 @@ proc interfaceSymbol*(config: ConfigRef, cache: IdentCache;
   result = loadSym(decoder, g, int(module), values[0])
 
 proc idgenFromLoadedModule*(m: LoadedModule): IdGenerator =
-  IdGenerator(module: m.module.itemId.module, symId: int32 m.fromDisk.sh.syms.len,
-              typeId: int32 m.fromDisk.sh.types.len)
+  IdGenerator(module: m.module.itemId.module, symId: int32 m.fromDisk.syms.len,
+              typeId: int32 m.fromDisk.types.len)
 
 proc searchForCompilerproc*(m: LoadedModule; name: string): int32 =
   # slow, linear search, but the results are cached:
   for it in items(m.fromDisk.compilerProcs):
-    if m.fromDisk.sh.strings[it[0]] == name:
+    if m.fromDisk.strings[it[0]] == name:
       return it[1]
   return -1
 
@@ -1149,31 +1196,31 @@ proc rodViewer*(rodfile: AbsoluteFile; config: ConfigRef, cache: IdentCache) =
   var m: PackedModule
   let err = loadRodFile(rodfile, m, config, ignoreConfig=true)
   if err != ok:
-    config.quitOrRaise "Error: could not load: " & $rodfile.string & " reason: " & $err 
+    config.quitOrRaise "Error: could not load: " & $rodfile.string & " reason: " & $err
 
   when true:
     echo "exports:"
     for ex in m.exports:
-      echo "  ", m.sh.strings[ex[0]], " local ID: ", ex[1]
-      assert ex[0] == m.sh.syms[ex[1]].name
+      echo "  ", m.strings[ex[0]], " local ID: ", ex[1]
+      assert ex[0] == m.syms[ex[1]].name
       # ex[1] int32
 
     echo "reexports:"
     for ex in m.reexports:
-      echo "  ", m.sh.strings[ex[0]]
+      echo "  ", m.strings[ex[0]]
     #  reexports*: seq[(LitId, PackedItemId)]
 
     echo "hidden: " & $m.hidden.len
     for ex in m.hidden:
-      echo "  ", m.sh.strings[ex[0]], " local ID: ", ex[1]
+      echo "  ", m.strings[ex[0]], " local ID: ", ex[1]
 
   echo "all symbols"
-  for i in 0..high(m.sh.syms):
-    if m.sh.syms[i].name != LitId(0):
-      echo "  ", m.sh.strings[m.sh.syms[i].name], " local ID: ", i, " kind ", m.sh.syms[i].kind
+  for i in 0..high(m.syms):
+    if m.syms[i].name != LitId(0):
+      echo "  ", m.strings[m.syms[i].name], " local ID: ", i, " kind ", m.syms[i].kind
     else:
-      echo "  <anon symbol?> local ID: ", i, " kind ", m.sh.syms[i].kind
+      echo "  <anon symbol?> local ID: ", i, " kind ", m.syms[i].kind
 
-  echo "symbols: ", m.sh.syms.len, " types: ", m.sh.types.len,
+  echo "symbols: ", m.syms.len, " types: ", m.types.len,
     " top level nodes: ", m.topLevel.nodes.len, " other nodes: ", m.bodies.nodes.len,
-    " strings: ", m.sh.strings.len, " numbers: ", m.sh.numbers.len
+    " strings: ", m.strings.len, " numbers: ", m.numbers.len
diff --git a/compiler/ic/integrity.nim b/compiler/ic/integrity.nim
index a28f2066a..428c344a3 100644
--- a/compiler/ic/integrity.nim
+++ b/compiler/ic/integrity.nim
@@ -42,12 +42,12 @@ proc checkType(c: var CheckedContext; typeId: PackedItemId) =
   if not c.checkedTypes.containsOrIncl(itemId):
     let oldThisModule = c.thisModule
     c.thisModule = itemId.module
-    checkTypeObj c, c.g.packed[itemId.module].fromDisk.sh.types[itemId.item]
+    checkTypeObj c, c.g.packed[itemId.module].fromDisk.types[itemId.item]
     c.thisModule = oldThisModule
 
 proc checkSym(c: var CheckedContext; s: PackedSym) =
   if s.name != LitId(0):
-    assert c.g.packed[c.thisModule].fromDisk.sh.strings.hasLitId s.name
+    assert c.g.packed[c.thisModule].fromDisk.strings.hasLitId s.name
   checkType c, s.typ
   if s.ast != emptyNodeId:
     checkNode(c, c.g.packed[c.thisModule].fromDisk.bodies, NodePos s.ast)
@@ -57,14 +57,14 @@ proc checkSym(c: var CheckedContext; s: PackedSym) =
 proc checkLocalSym(c: var CheckedContext; item: int32) =
   let itemId = ItemId(module: c.thisModule, item: item)
   if not c.checkedSyms.containsOrIncl(itemId):
-    checkSym c, c.g.packed[c.thisModule].fromDisk.sh.syms[item]
+    checkSym c, c.g.packed[c.thisModule].fromDisk.syms[item]
 
 proc checkForeignSym(c: var CheckedContext; symId: PackedItemId) =
   let itemId = translateId(symId, c.g.packed, c.thisModule, c.g.config)
   if not c.checkedSyms.containsOrIncl(itemId):
     let oldThisModule = c.thisModule
     c.thisModule = itemId.module
-    checkSym c, c.g.packed[itemId.module].fromDisk.sh.syms[itemId.item]
+    checkSym c, c.g.packed[itemId.module].fromDisk.syms[itemId.item]
     c.thisModule = oldThisModule
 
 proc checkNode(c: var CheckedContext; tree: PackedTree; n: NodePos) =
@@ -74,15 +74,15 @@ proc checkNode(c: var CheckedContext; tree: PackedTree; n: NodePos) =
   of nkEmpty, nkNilLit, nkType, nkNilRodNode:
     discard
   of nkIdent:
-    assert c.g.packed[c.thisModule].fromDisk.sh.strings.hasLitId n.litId
+    assert c.g.packed[c.thisModule].fromDisk.strings.hasLitId n.litId
   of nkSym:
     checkLocalSym(c, tree.nodes[n.int].operand)
   of directIntLit:
     discard
   of externIntLit, nkFloatLit..nkFloat128Lit:
-    assert c.g.packed[c.thisModule].fromDisk.sh.numbers.hasLitId n.litId
+    assert c.g.packed[c.thisModule].fromDisk.numbers.hasLitId n.litId
   of nkStrLit..nkTripleStrLit:
-    assert c.g.packed[c.thisModule].fromDisk.sh.strings.hasLitId n.litId
+    assert c.g.packed[c.thisModule].fromDisk.strings.hasLitId n.litId
   of nkModuleRef:
     let (n1, n2) = sons2(tree, n)
     assert n1.kind == nkInt32Lit
@@ -97,25 +97,25 @@ proc checkTree(c: var CheckedContext; t: PackedTree) =
 
 proc checkLocalSymIds(c: var CheckedContext; m: PackedModule; symIds: seq[int32]) =
   for symId in symIds:
-    assert symId >= 0 and symId < m.sh.syms.len, $symId & " " & $m.sh.syms.len
+    assert symId >= 0 and symId < m.syms.len, $symId & " " & $m.syms.len
 
 proc checkModule(c: var CheckedContext; m: PackedModule) =
   # We check that:
   # - Every symbol references existing types and symbols.
   # - Every tree node references existing types and symbols.
-  for i in 0..high(m.sh.syms):
+  for i in 0..high(m.syms):
     checkLocalSym c, int32(i)
 
   checkTree c, m.toReplay
   checkTree c, m.topLevel
 
   for e in m.exports:
-    assert e[1] >= 0 and e[1] < m.sh.syms.len
-    assert e[0] == m.sh.syms[e[1]].name
+    assert e[1] >= 0 and e[1] < m.syms.len
+    assert e[0] == m.syms[e[1]].name
 
   for e in m.compilerProcs:
-    assert e[1] >= 0 and e[1] < m.sh.syms.len
-    assert e[0] == m.sh.syms[e[1]].name
+    assert e[1] >= 0 and e[1] < m.syms.len
+    assert e[0] == m.syms[e[1]].name
 
   checkLocalSymIds c, m, m.converters
   checkLocalSymIds c, m, m.methods
diff --git a/compiler/ic/navigator.nim b/compiler/ic/navigator.nim
index b09275220..b1a237cf7 100644
--- a/compiler/ic/navigator.nim
+++ b/compiler/ic/navigator.nim
@@ -35,12 +35,12 @@ proc isTracked(current, trackPos: PackedLineInfo, tokenLen: int): bool =
 
 proc searchLocalSym(c: var NavContext; s: PackedSym; info: PackedLineInfo): bool =
   result = s.name != LitId(0) and
-    isTracked(info, c.trackPos, c.g.packed[c.thisModule].fromDisk.sh.strings[s.name].len)
+    isTracked(info, c.trackPos, c.g.packed[c.thisModule].fromDisk.strings[s.name].len)
 
 proc searchForeignSym(c: var NavContext; s: ItemId; info: PackedLineInfo): bool =
-  let name = c.g.packed[s.module].fromDisk.sh.syms[s.item].name
+  let name = c.g.packed[s.module].fromDisk.syms[s.item].name
   result = name != LitId(0) and
-    isTracked(info, c.trackPos, c.g.packed[s.module].fromDisk.sh.strings[name].len)
+    isTracked(info, c.trackPos, c.g.packed[s.module].fromDisk.strings[name].len)
 
 const
   EmptyItemId = ItemId(module: -1'i32, item: -1'i32)
@@ -51,7 +51,7 @@ proc search(c: var NavContext; tree: PackedTree): ItemId =
     case tree.nodes[i].kind
     of nkSym:
       let item = tree.nodes[i].operand
-      if searchLocalSym(c, c.g.packed[c.thisModule].fromDisk.sh.syms[item], tree.nodes[i].info):
+      if searchLocalSym(c, c.g.packed[c.thisModule].fromDisk.syms[item], tree.nodes[i].info):
         return ItemId(module: c.thisModule, item: item)
     of nkModuleRef:
       if tree.nodes[i].info.line == c.trackPos.line and tree.nodes[i].info.file == c.trackPos.file:
@@ -74,7 +74,7 @@ proc isDecl(tree: PackedTree; n: NodePos): bool =
 
 proc usage(c: var NavContext; info: PackedLineInfo; isDecl: bool) =
   var m = ""
-  var file = c.g.packed[c.thisModule].fromDisk.sh.strings[info.file]
+  var file = c.g.packed[c.thisModule].fromDisk.strings[info.file]
   if c.outputSep == ' ':
     file = os.extractFilename file
   toLocation(m, file, info.line.int, info.col.int + ColOffset)
@@ -102,7 +102,7 @@ proc nav(g: ModuleGraph) =
   # translate the track position to a packed position:
   let unpacked = g.config.m.trackPos
   let mid = unpacked.fileIndex
-  let fileId = g.packed[int32 mid].fromDisk.sh.strings.getKeyId(toFullPath(g.config, mid))
+  let fileId = g.packed[int32 mid].fromDisk.strings.getKeyId(toFullPath(g.config, mid))
 
   if fileId == LitId(0):
     internalError(g.config, unpacked, "cannot find a valid file ID")
diff --git a/compiler/ic/packed_ast.nim b/compiler/ic/packed_ast.nim
index 0649b56ce..2700c8253 100644
--- a/compiler/ic/packed_ast.nim
+++ b/compiler/ic/packed_ast.nim
@@ -98,17 +98,6 @@ type
 
   PackedTree* = object ## usually represents a full Nim module
     nodes*: seq[PackedNode]
-    #sh*: Shared
-
-  Shared* = ref object # shared between different versions of 'Module'.
-                       # (though there is always exactly one valid
-                       # version of a module)
-    syms*: seq[PackedSym]
-    types*: seq[PackedType]
-    strings*: BiTable[string] # we could share these between modules.
-    numbers*: BiTable[BiggestInt] # we also store floats in here so
-                                  # that we can assure that every bit is kept
-    #config*: ConfigRef
 
   PackedInstantiation* = object
     key*, sym*: PackedItemId
@@ -374,51 +363,6 @@ const
   externUIntLit* = {nkUIntLit, nkUInt8Lit, nkUInt16Lit, nkUInt32Lit, nkUInt64Lit}
   directIntLit* = nkInt32Lit
 
-proc toString*(tree: PackedTree; n: NodePos; sh: Shared; nesting: int;
-               result: var string) =
-  let pos = n.int
-  if result.len > 0 and result[^1] notin {' ', '\n'}:
-    result.add ' '
-
-  result.add $tree[pos].kind
-  case tree.nodes[pos].kind
-  of nkNone, nkEmpty, nkNilLit, nkType: discard
-  of nkIdent, nkStrLit..nkTripleStrLit:
-    result.add " "
-    result.add sh.strings[LitId tree.nodes[pos].operand]
-  of nkSym:
-    result.add " "
-    result.add sh.strings[sh.syms[tree.nodes[pos].operand].name]
-  of directIntLit:
-    result.add " "
-    result.addInt tree.nodes[pos].operand
-  of externSIntLit:
-    result.add " "
-    result.addInt sh.numbers[LitId tree.nodes[pos].operand]
-  of externUIntLit:
-    result.add " "
-    result.add $cast[uint64](sh.numbers[LitId tree.nodes[pos].operand])
-  of nkFloatLit..nkFloat128Lit:
-    result.add " "
-    result.add $cast[BiggestFloat](sh.numbers[LitId tree.nodes[pos].operand])
-  else:
-    result.add "(\n"
-    for i in 1..(nesting+1)*2: result.add ' '
-    for child in sonsReadonly(tree, n):
-      toString(tree, child, sh, nesting + 1, result)
-    result.add "\n"
-    for i in 1..nesting*2: result.add ' '
-    result.add ")"
-    #for i in 1..nesting*2: result.add ' '
-
-
-proc toString*(tree: PackedTree; n: NodePos; sh: Shared): string =
-  result = ""
-  toString(tree, n, sh, 0, result)
-
-proc debug*(tree: PackedTree; sh: Shared) =
-  stdout.write toString(tree, NodePos 0, sh)
-
 when false:
   proc identIdImpl(tree: PackedTree; n: NodePos): LitId =
     if n.kind == nkIdent:
diff --git a/compiler/ic/rodfiles.nim b/compiler/ic/rodfiles.nim
index 86d8ba203..a52bd18b3 100644
--- a/compiler/ic/rodfiles.nim
+++ b/compiler/ic/rodfiles.nim
@@ -23,8 +23,8 @@ from typetraits import supportsCopyMem
 ## (`RodFileError`). The file format broken up into sections (`RodSection`)
 ## and preceeded by a header (see: `cookie`). The precise layout, section
 ## ordering and data following the section are determined by the user. See
-## `ic.loadRoadFile`.
-## 
+## `ic.loadRodFile`.
+##
 ## A basic but "wrong" example of the lifecycle:
 ## ---------------------------------------------
 ## 1. `create` or `open`        - create a new one or open an existing
@@ -45,10 +45,10 @@ from typetraits import supportsCopyMem
 ## The API is centered around IO and prone to error, each operation checks or
 ## sets the `RodFile.err` field. A user of this API needs to handle these
 ## appropriately.
-## 
+##
 ## API Notes
 ## =========
-## 
+##
 ## Valid inputs for Rod files
 ## --------------------------
 ## ASTs, hopes, dreams, and anything as long as it and any children it may have
@@ -61,7 +61,7 @@ from typetraits import supportsCopyMem
 ## ----------------------------
 ## A flag based approach is used where operations no-op in case of a
 ## preexisting error and set the flag if they encounter one.
-## 
+##
 ## Misc
 ## ----
 ## * 'Prim' is short for 'primitive', as in a non-sequence type