diff options
Diffstat (limited to 'compiler/ic/cbackend.nim')
-rw-r--r-- | compiler/ic/cbackend.nim | 87 |
1 files changed, 66 insertions, 21 deletions
diff --git a/compiler/ic/cbackend.nim b/compiler/ic/cbackend.nim index 34ee59d52..83f1b4cc7 100644 --- a/compiler/ic/cbackend.nim +++ b/compiler/ic/cbackend.nim @@ -19,9 +19,12 @@ ## anymore. DCE is now done as prepass over the entire packed module graph. import std/[packedsets, algorithm, tables] - # std/intsets would give `UnusedImport`, pending https://github.com/nim-lang/Nim/issues/14246 + +when defined(nimPreviewSlimSystem): + import std/assertions + import ".."/[ast, options, lineinfos, modulegraphs, cgendata, cgen, - pathutils, extccomp, msgs] + pathutils, extccomp, msgs, modulepaths] import packed_ast, ic, dce, rodfiles @@ -30,12 +33,16 @@ proc unpackTree(g: ModuleGraph; thisModule: int; var decoder = initPackedDecoder(g.config, g.cache) result = loadNodes(decoder, g.packed, thisModule, tree, n) -proc generateCodeForModule(g: ModuleGraph; m: var LoadedModule; alive: var AliveSyms) = +proc setupBackendModule(g: ModuleGraph; m: var LoadedModule) = if g.backend == nil: g.backend = cgendata.newModuleList(g) - + assert g.backend != nil var bmod = cgen.newModule(BModuleList(g.backend), m.module, g.config) bmod.idgen = idgenFromLoadedModule(m) + +proc generateCodeForModule(g: ModuleGraph; m: var LoadedModule; alive: var AliveSyms) = + var bmod = BModuleList(g.backend).modules[m.module.position] + assert bmod != nil bmod.flags.incl useAliveDataFromDce bmod.alive = move alive[m.module.position] @@ -44,9 +51,13 @@ proc generateCodeForModule(g: ModuleGraph; m: var LoadedModule; alive: var Alive cgen.genTopLevelStmt(bmod, n) finalCodegenActions(g, bmod, newNodeI(nkStmtList, m.module.info)) + for disp in getDispatchers(g): + genProcAux(bmod, disp) + m.fromDisk.backendFlags = cgen.whichInitProcs(bmod) proc replayTypeInfo(g: ModuleGraph; m: var LoadedModule; origin: FileIndex) = for x in mitems(m.fromDisk.emittedTypeInfo): + #echo "found type ", x, " for file ", int(origin) g.emittedTypeInfo[x] = origin proc addFileToLink(config: ConfigRef; m: PSym) = @@ -55,7 +66,8 @@ proc addFileToLink(config: ConfigRef; m: PSym) = if config.backend == backendCpp: ".nim.cpp" elif config.backend == backendObjc: ".nim.m" else: ".nim.c" - let cfile = changeFileExt(completeCfilePath(config, withPackageName(config, filename)), ext) + let cfile = changeFileExt(completeCfilePath(config, + mangleModuleName(config, filename).AbsoluteFile), ext) let objFile = completeCfilePath(config, toObjFile(config, cfile)) if fileExists(objFile): var cf = Cfile(nimname: m.name.s, cname: cfile, @@ -64,7 +76,7 @@ proc addFileToLink(config: ConfigRef; m: PSym) = addFileToCompile(config, cf) when defined(debugDce): - import std / [os, packedsets] + import os, std/packedsets proc storeAliveSymsImpl(asymFile: AbsoluteFile; s: seq[int32]) = var f = rodfiles.create(asymFile.string) @@ -88,7 +100,7 @@ proc aliveSymsChanged(config: ConfigRef; position: int; alive: AliveSyms): bool var f2 = rodfiles.open(asymFile.string) f2.loadHeader() f2.loadSection aliveSymsSection - var oldData: seq[int32] + var oldData: seq[int32] = @[] f2.loadSeq(oldData) f2.close if f2.err == ok and oldData == s: @@ -98,38 +110,71 @@ proc aliveSymsChanged(config: ConfigRef; position: int; alive: AliveSyms): bool 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" + echo "in old but not in new ", oldAsSet.difference(newAsSet), " number of entries in old ", oldAsSet.len + echo "in new but not in old ", newAsSet.difference(oldAsSet), " number of entries in new ", newAsSet.len + #if execShellCmd(getAppFilename() & " rod " & quoteShell(asymFile.changeFileExt("rod"))) != 0: + # echo "command failed" result = true storeAliveSymsImpl(asymFile, s) +proc genPackedModule(g: ModuleGraph, i: int; alive: var AliveSyms) = + # case statement here to enforce exhaustive checks. + case g.packed[i].status + of undefined: + discard "nothing to do" + of loading, stored: + assert false + of storing, outdated: + storeAliveSyms(g.config, g.packed[i].module.position, alive) + generateCodeForModule(g, g.packed[i], alive) + closeRodFile(g, g.packed[i].module) + of loaded: + if g.packed[i].loadedButAliveSetChanged: + generateCodeForModule(g, g.packed[i], alive) + else: + addFileToLink(g.config, g.packed[i].module) + replayTypeInfo(g, g.packed[i], FileIndex(i)) + + if g.backend == nil: + g.backend = cgendata.newModuleList(g) + registerInitProcs(BModuleList(g.backend), g.packed[i].module, g.packed[i].fromDisk.backendFlags) + proc generateCode*(g: ModuleGraph) = ## The single entry point, generate C(++) code for the entire ## Nim program aka `ModuleGraph`. resetForBackend(g) var alive = computeAliveSyms(g.packed, g.config) - for i in 0..high(g.packed): + when false: + for i in 0..<len(g.packed): + echo i, " is of status ", g.packed[i].status, " ", toFullPath(g.config, FileIndex(i)) + + # First pass: Setup all the backend modules for all the modules that have + # changed: + for i in 0..<len(g.packed): # case statement here to enforce exhaustive checks. case g.packed[i].status of undefined: discard "nothing to do" - of loading: + of loading, stored: 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) + setupBackendModule(g, g.packed[i]) 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 # S itself. A is then edited not to use S either. Thus we have to # recompile B in order to remove S from the final result. if aliveSymsChanged(g.config, g.packed[i].module.position, alive): - generateCodeForModule(g, g.packed[i], alive) - else: - addFileToLink(g.config, g.packed[i].module) - replayTypeInfo(g, g.packed[i], FileIndex(i)) + g.packed[i].loadedButAliveSetChanged = true + setupBackendModule(g, g.packed[i]) + + # Second pass: Code generation. + let mainModuleIdx = g.config.projectMainIdx2.int + # We need to generate the main module last, because only then + # all init procs have been registered: + for i in 0..<len(g.packed): + if i != mainModuleIdx: + genPackedModule(g, i, alive) + if mainModuleIdx >= 0: + genPackedModule(g, mainModuleIdx, alive) |