IC: backend: remember produced type information (#17440)
This commit is contained in:
parent
1d19cd660f
commit
d6a16020fe
9 changed files with 93 additions and 42 deletions
|
|
@ -18,7 +18,7 @@
|
|||
## also doing cross-module dependency tracking and DCE that we don't need
|
||||
## anymore. DCE is now done as prepass over the entire packed module graph.
|
||||
|
||||
import std/[packedsets, algorithm]
|
||||
import std/[packedsets, algorithm, tables]
|
||||
# std/intsets would give `UnusedImport`, pending https://github.com/nim-lang/Nim/issues/14246
|
||||
import ".."/[ast, options, lineinfos, modulegraphs, cgendata, cgen,
|
||||
pathutils, extccomp, msgs]
|
||||
|
|
@ -45,6 +45,10 @@ proc generateCodeForModule(g: ModuleGraph; m: var LoadedModule; alive: var Alive
|
|||
|
||||
finalCodegenActions(g, bmod, newNodeI(nkStmtList, m.module.info))
|
||||
|
||||
proc replayTypeInfo(g: ModuleGraph; m: var LoadedModule; origin: FileIndex) =
|
||||
for x in mitems(m.fromDisk.emittedTypeInfo):
|
||||
g.emittedTypeInfo[x] = origin
|
||||
|
||||
proc addFileToLink(config: ConfigRef; m: PSym) =
|
||||
let filename = AbsoluteFile toFullPath(config, m.position.FileIndex)
|
||||
let ext =
|
||||
|
|
@ -59,11 +63,28 @@ proc addFileToLink(config: ConfigRef; m: PSym) =
|
|||
flags: {CfileFlag.Cached})
|
||||
addFileToCompile(config, cf)
|
||||
|
||||
proc aliveSymsChanged(config: ConfigRef; position: int; alive: AliveSyms): bool =
|
||||
when defined(debugDce):
|
||||
import std / [os, packedsets]
|
||||
|
||||
proc storeAliveSymsImpl(asymFile: AbsoluteFile; s: seq[int32]) =
|
||||
var f = rodfiles.create(asymFile.string)
|
||||
f.storeHeader()
|
||||
f.storeSection aliveSymsSection
|
||||
f.storeSeq(s)
|
||||
close f
|
||||
|
||||
template prepare {.dirty.} =
|
||||
let asymFile = toRodFile(config, AbsoluteFile toFullPath(config, position.FileIndex), ".alivesyms")
|
||||
var s = newSeqOfCap[int32](alive[position].len)
|
||||
for a in items(alive[position]): s.add int32(a)
|
||||
sort(s)
|
||||
|
||||
proc storeAliveSyms(config: ConfigRef; position: int; alive: AliveSyms) =
|
||||
prepare()
|
||||
storeAliveSymsImpl(asymFile, s)
|
||||
|
||||
proc aliveSymsChanged(config: ConfigRef; position: int; alive: AliveSyms): bool =
|
||||
prepare()
|
||||
var f2 = rodfiles.open(asymFile.string)
|
||||
f2.loadHeader()
|
||||
f2.loadSection aliveSymsSection
|
||||
|
|
@ -73,12 +94,17 @@ proc aliveSymsChanged(config: ConfigRef; position: int; alive: AliveSyms): bool
|
|||
if f2.err == ok and oldData == s:
|
||||
result = false
|
||||
else:
|
||||
when defined(debugDce):
|
||||
let oldAsSet = toPackedSet[int32](oldData)
|
||||
let newAsSet = toPackedSet[int32](s)
|
||||
echo "set of live symbols changed ", asymFile.changeFileExt("rod"), " ", position, " ", f2.err
|
||||
echo "in old but not in new ", oldAsSet.difference(newAsSet)
|
||||
echo "in new but not in old ", newAsSet.difference(oldAsSet)
|
||||
|
||||
if execShellCmd(getAppFilename() & " rod " & quoteShell(asymFile.changeFileExt("rod"))) != 0:
|
||||
echo "command failed"
|
||||
result = true
|
||||
var f = rodfiles.create(asymFile.string)
|
||||
f.storeHeader()
|
||||
f.storeSection aliveSymsSection
|
||||
f.storeSeq(s)
|
||||
close f
|
||||
storeAliveSymsImpl(asymFile, s)
|
||||
|
||||
proc generateCode*(g: ModuleGraph) =
|
||||
## The single entry point, generate C(++) code for the entire
|
||||
|
|
@ -95,6 +121,8 @@ proc generateCode*(g: ModuleGraph) =
|
|||
assert false
|
||||
of storing, outdated:
|
||||
generateCodeForModule(g, g.packed[i], alive)
|
||||
closeRodFile(g, g.packed[i].module)
|
||||
storeAliveSyms(g.config, g.packed[i].module.position, alive)
|
||||
of loaded:
|
||||
# Even though this module didn't change, DCE might trigger a change.
|
||||
# Consider this case: Module A uses symbol S from B and B does not use
|
||||
|
|
@ -104,3 +132,4 @@ proc generateCode*(g: ModuleGraph) =
|
|||
generateCodeForModule(g, g.packed[i], alive)
|
||||
else:
|
||||
addFileToLink(g.config, g.packed[i].module)
|
||||
replayTypeInfo(g, g.packed[i], FileIndex(i))
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ type
|
|||
methodsPerType*: seq[(PackedItemId, int, PackedItemId)]
|
||||
enumToStringProcs*: seq[(PackedItemId, PackedItemId)]
|
||||
|
||||
emittedTypeInfo*: seq[string]
|
||||
|
||||
sh*: Shared
|
||||
cfg: PackedConfig
|
||||
|
||||
|
|
@ -58,7 +60,7 @@ type
|
|||
config*: ConfigRef
|
||||
|
||||
proc isActive*(e: PackedEncoder): bool = e.config != nil
|
||||
proc disable*(e: var PackedEncoder) = e.config = nil
|
||||
proc disable(e: var PackedEncoder) = e.config = nil
|
||||
|
||||
template primConfigFields(fn: untyped) {.dirty.} =
|
||||
fn backend
|
||||
|
|
@ -552,6 +554,7 @@ proc loadRodFile*(filename: AbsoluteFile; m: var PackedModule; config: ConfigRef
|
|||
loadSeqSection attachedOpsSection, m.attachedOps
|
||||
loadSeqSection methodsPerTypeSection, m.methodsPerType
|
||||
loadSeqSection enumToStringProcsSection, m.enumToStringProcs
|
||||
loadSeqSection typeInfoSection, m.emittedTypeInfo
|
||||
|
||||
close(f)
|
||||
result = f.err
|
||||
|
|
@ -614,6 +617,7 @@ proc saveRodFile*(filename: AbsoluteFile; encoder: var PackedEncoder; m: var Pac
|
|||
storeSeqSection attachedOpsSection, m.attachedOps
|
||||
storeSeqSection methodsPerTypeSection, m.methodsPerType
|
||||
storeSeqSection enumToStringProcsSection, m.enumToStringProcs
|
||||
storeSeqSection typeInfoSection, m.emittedTypeInfo
|
||||
|
||||
close(f)
|
||||
encoder.disable()
|
||||
|
|
@ -1139,7 +1143,10 @@ proc rodViewer*(rodfile: AbsoluteFile; config: ConfigRef, cache: IdentCache) =
|
|||
|
||||
echo "all symbols"
|
||||
for i in 0..high(m.sh.syms):
|
||||
echo " ", m.sh.strings[m.sh.syms[i].name], " local ID: ", i
|
||||
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
|
||||
else:
|
||||
echo " <anon symbol?> local ID: ", i, " kind ", m.sh.syms[i].kind
|
||||
|
||||
echo "symbols: ", m.sh.syms.len, " types: ", m.sh.types.len,
|
||||
" top level nodes: ", m.topLevel.nodes.len, " other nodes: ", m.bodies.nodes.len,
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ type
|
|||
attachedOpsSection
|
||||
methodsPerTypeSection
|
||||
enumToStringProcsSection
|
||||
typeInfoSection # required by the backend
|
||||
aliveSymsSection # beware, this is stored in a `.alivesyms` file.
|
||||
|
||||
RodFileError* = enum
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue