mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-30 09:54:49 +00:00
* IC: renamed to_packed_ast module to ic module * IC: don't store the --forceBuild flag, makes it easier to test * IC: enable hello world test * Codegen: refactorings for IC; changed the name mangling algorithm * fixed the HCR regressions * life is too short for HCR * tconvexhull is now allowed to use deepCopy * IC exposed a stdlib bug, required a refactoring * codegen: code cleanups * IC: even if a module is outdated, its dependencies might come from disk * IC: progress * IC: better name mangling, module IDs are not stable * IC: another refactoring helping with --ic:on --gc:arc * disable arraymancer on Windows for the time being * disable arraymancer altogether * IC: make basic test work with 'nim cpp' * IC: progress on --ic:on --gc:arc * wip; name mangling for type info
107 lines
4.1 KiB
Nim
107 lines
4.1 KiB
Nim
#
|
|
#
|
|
# The Nim Compiler
|
|
# (c) Copyright 2021 Andreas Rumpf
|
|
#
|
|
# See the file "copying.txt", included in this
|
|
# distribution, for details about the copyright.
|
|
#
|
|
|
|
## New entry point into our C/C++ code generator. Ideally
|
|
## somebody would rewrite the old backend (which is 8000 lines of crufty Nim code)
|
|
## to work on packed trees directly and produce the C code as an AST which can
|
|
## then be rendered to text in a very simple manner. Unfortunately nobody wrote
|
|
## this code. So instead we wrap the existing cgen.nim and its friends so that
|
|
## we call directly into the existing code generation logic but avoiding the
|
|
## naive, outdated `passes` design. Thus you will see some
|
|
## `useAliveDataFromDce in flags` checks in the old code -- the old code is
|
|
## 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]
|
|
# std/intsets would give `UnusedImport`, pending https://github.com/nim-lang/Nim/issues/14246
|
|
import ".."/[ast, options, lineinfos, modulegraphs, cgendata, cgen,
|
|
pathutils, extccomp, msgs]
|
|
|
|
import packed_ast, ic, dce, rodfiles
|
|
|
|
proc unpackTree(g: ModuleGraph; thisModule: int;
|
|
tree: PackedTree; n: NodePos): PNode =
|
|
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) =
|
|
if g.backend == nil:
|
|
g.backend = cgendata.newModuleList(g)
|
|
|
|
var bmod = cgen.newModule(BModuleList(g.backend), m.module, g.config)
|
|
bmod.idgen = idgenFromLoadedModule(m)
|
|
bmod.flags.incl useAliveDataFromDce
|
|
bmod.alive = move alive[m.module.position]
|
|
|
|
for p in allNodes(m.fromDisk.topLevel):
|
|
let n = unpackTree(g, m.module.position, m.fromDisk.topLevel, p)
|
|
cgen.genTopLevelStmt(bmod, n)
|
|
|
|
finalCodegenActions(g, bmod, newNodeI(nkStmtList, m.module.info))
|
|
|
|
proc addFileToLink(config: ConfigRef; m: PSym) =
|
|
let filename = AbsoluteFile toFullPath(config, m.position.FileIndex)
|
|
let ext =
|
|
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 objFile = completeCfilePath(config, toObjFile(config, cfile))
|
|
if fileExists(objFile):
|
|
var cf = Cfile(nimname: m.name.s, cname: cfile,
|
|
obj: objFile,
|
|
flags: {CfileFlag.Cached})
|
|
addFileToCompile(config, cf)
|
|
|
|
proc aliveSymsChanged(config: ConfigRef; position: int; alive: AliveSyms): bool =
|
|
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)
|
|
var f2 = rodfiles.open(asymFile.string)
|
|
f2.loadHeader()
|
|
f2.loadSection aliveSymsSection
|
|
var oldData: seq[int32]
|
|
f2.loadSeq(oldData)
|
|
f2.close
|
|
if f2.err == ok and oldData == s:
|
|
result = false
|
|
else:
|
|
result = true
|
|
var f = rodfiles.create(asymFile.string)
|
|
f.storeHeader()
|
|
f.storeSection aliveSymsSection
|
|
f.storeSeq(s)
|
|
close f
|
|
|
|
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):
|
|
# case statement here to enforce exhaustive checks.
|
|
case g.packed[i].status
|
|
of undefined:
|
|
discard "nothing to do"
|
|
of loading:
|
|
assert false
|
|
of storing, outdated:
|
|
generateCodeForModule(g, g.packed[i], 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
|
|
# 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)
|