mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-11 03:39:31 +00:00
IC: final tweaks (#25958)
This commit is contained in:
@@ -1249,15 +1249,21 @@ proc commandIc*(conf: ConfigRef) =
|
||||
let nifmake = findNifmake()
|
||||
# Build the per-module rules concurrently: nifmake fans out all commands at
|
||||
# each DAG depth via execProcesses (defaults to all cores). Cold builds are
|
||||
# otherwise serial (one child at a time) and leave the machine idle. Opt out
|
||||
# with `-d:icNoParallel` (e.g. for readable, non-interleaved child output
|
||||
# when debugging a build), or cap the concurrency with `-d:icJobs:N` — an
|
||||
# uncapped fan-out across many cores can exhaust RAM on a large project
|
||||
# (each `nim m`/`cg` child holds its own module graph), which nifmake's own
|
||||
# `-j:N` exists to bound.
|
||||
# otherwise serial (one child at a time) and leave the machine idle. An
|
||||
# uncapped fan-out across many cores can exhaust RAM on a large project (each
|
||||
# `nim m`/`cg` child holds its own module graph), which nifmake's own `-j:N`
|
||||
# exists to bound. Concurrency is chosen (highest precedence first):
|
||||
# * `-d:icNoParallel` -> serial (readable, non-interleaved child output)
|
||||
# * `-d:icJobs:N` -> cap at N (legacy IC-tuning define)
|
||||
# * `--parallelBuild:N` -> cap at N (the standard Nim build-parallelism
|
||||
# flag; a no-op for `nim c` under IC, so we give
|
||||
# it meaning here — lets Nimbus devs pick their
|
||||
# own value without a `-d:` define)
|
||||
# * otherwise -> uncapped (all cores)
|
||||
let parallel =
|
||||
if isDefined(conf, "icNoParallel"): ""
|
||||
elif isDefined(conf, "icJobs"): " --parallel:" & conf.symbols["icJobs"]
|
||||
elif conf.numberOfProcessors > 0: " --parallel:" & $conf.numberOfProcessors
|
||||
else: " --parallel"
|
||||
|
||||
# Phase 1 — frontend (nifler + `nim m`), run to a discovery fixpoint.
|
||||
|
||||
@@ -219,8 +219,18 @@ proc collectBifStrLits*(path: string): seq[string] =
|
||||
## string literal it holds, in order — the binary analogue of the old nifstreams
|
||||
## scan that collected `StrLit`s. Keeps nifcore types out of `deps.nim`, which
|
||||
## only needs the recorded string list.
|
||||
##
|
||||
## Uses `loadFromFile` (a full read into owned memory) rather than the mmap-backed
|
||||
## `bif.load`, then CLOSES the handle. `bif.load` intentionally leaves the mapping
|
||||
## resident for the process lifetime; for the `nim ic` driver that reads these
|
||||
## sidecars while `nim m` children rewrite them, a lingering read mapping is a
|
||||
## Windows sharing violation: the child's `open(path, fmWrite)` fails with
|
||||
## `IOError: cannot open`. These sidecars are tiny, so the zero-copy mmap buys
|
||||
## nothing here anyway.
|
||||
result = @[]
|
||||
var m = bif.load(path)
|
||||
var f = open(path, fmRead)
|
||||
var m = bif.loadFromFile(f)
|
||||
close(f)
|
||||
var c = m.buf.beginRead()
|
||||
while c.hasMore:
|
||||
if c.kind == StrLit: result.add strVal(c)
|
||||
|
||||
@@ -47,6 +47,11 @@ type
|
||||
CoConsiderOwned
|
||||
CoDistinct
|
||||
CoHashTypeInsideNode
|
||||
CoPrecise # produce a FRONTEND-faithful, unique key (for the
|
||||
# stable NIF *name*, not hook dedup): keep distinctions
|
||||
# sem makes that the backend identity collapses — e.g.
|
||||
# an `int literal(x)` type carries its value so it does
|
||||
# not merge with `int`. See `getTypeKey`/`typeKeyHook`.
|
||||
|
||||
TypeLoader* = proc (t: PType) {.nimcall.}
|
||||
SymLoader* = proc (s: PSym) {.nimcall.}
|
||||
@@ -139,6 +144,20 @@ proc maybeImported(c: var Context; s: PSym; conf: ConfigRef) {.inline.} =
|
||||
if s != nil and {sfImportc, sfExportc} * s.flagsImpl != {}:
|
||||
c.symKey(s, conf)
|
||||
|
||||
proc emitPreciseFlags(c: var Context; t: PType; flags: set[ConsiderFlag]) {.inline.} =
|
||||
## Under CoPrecise the NIF *name* must be as fine as `types.sameType`, which
|
||||
## compares `eqTypeFlags * flags` (see `sameFlags`). Without this a
|
||||
## `proc() {.gcsafe.}` keyed identically to `proc()`, and a `ref X not nil`
|
||||
## identically to `ref X` — the loader would then merge two frontend-distinct
|
||||
## types onto one NIF name. Emitted only for the naming path (CoPrecise); the
|
||||
## `setAttachedOp` hook key (no CoPrecise) is unaffected, so its byte layout is
|
||||
## unchanged.
|
||||
if CoPrecise in flags:
|
||||
let ef = eqTypeFlags * t.flagsImpl
|
||||
if ef != {}:
|
||||
withTree c.m, "´tflags":
|
||||
for f in ef: c.m.addIntLit ord(f)
|
||||
|
||||
proc backendTypeName(t: PType; conf: ConfigRef): string =
|
||||
## Stable cross-module identity of a backend-minted (lower-stage) type: its
|
||||
## serialized `@bk` NIF name (mirrors ast2nif.nifTypeName). A closure-env
|
||||
@@ -229,6 +248,10 @@ proc typeKey(c: var Context; t: PType; flags: set[ConsiderFlag]; conf: ConfigRef
|
||||
of tyInt:
|
||||
withTree c.m, "i":
|
||||
c.m.addIntLit -1
|
||||
# An `int literal(x)` type (nImpl holds the value) must stay distinct from
|
||||
# plain `int` for the NIF name, else overload resolution breaks on reload.
|
||||
if CoPrecise in flags and t.nImpl != nil:
|
||||
c.m.addIntLit t.nImpl.intVal
|
||||
maybeImported(c, t.symImpl, conf)
|
||||
of tyInt8:
|
||||
withTree c.m, "i":
|
||||
@@ -266,6 +289,14 @@ proc typeKey(c: var Context; t: PType; flags: set[ConsiderFlag]; conf: ConfigRef
|
||||
withTree c.m, "u":
|
||||
c.m.addIntLit 64
|
||||
maybeImported(c, t.symImpl, conf)
|
||||
of tyFloat:
|
||||
withTree c.m, "f":
|
||||
c.m.addIntLit -1
|
||||
# A `float literal(x)` type (nImpl = nkFloatLit) must stay distinct from
|
||||
# plain `float`, just like the `int literal(x)` case above.
|
||||
if CoPrecise in flags and t.nImpl != nil and t.nImpl.kind in {nkFloatLit..nkFloat64Lit}:
|
||||
c.m.addFloatLit t.nImpl.floatVal
|
||||
maybeImported(c, t.symImpl, conf)
|
||||
of tyObject, tyEnum:
|
||||
if t.typeInstImpl != nil:
|
||||
# prevent against infinite recursions here, see bug #8883:
|
||||
@@ -381,6 +412,9 @@ proc typeKey(c: var Context; t: PType; flags: set[ConsiderFlag]; conf: ConfigRef
|
||||
|
||||
c.m.addIdent toNifTag(t.callConvImpl)
|
||||
if tfVarargs in t.flagsImpl: c.m.addIdent "´varargs"
|
||||
# `.gcsafe`/`.noSideEffect` (in eqTypeFlags) distinguish proc types under
|
||||
# sameType, so they must distinguish the NIF name too.
|
||||
emitPreciseFlags(c, t, flags)
|
||||
of tyArray:
|
||||
withTree c.m, toNifTag(t.kind):
|
||||
if t.sonsImpl.len == 0:
|
||||
@@ -395,6 +429,9 @@ proc typeKey(c: var Context; t: PType; flags: set[ConsiderFlag]; conf: ConfigRef
|
||||
c.typeKey t.sonsImpl[i], flags, conf
|
||||
if tfNotNil in t.flagsImpl and CoType notin flags:
|
||||
c.m.addIdent "´notnil"
|
||||
# tfNotNil/tfVarIsPtr/tfIsOutParam (eqTypeFlags) part of sameType identity
|
||||
# for ref/ptr/var/lent/sink; the hook path (no CoPrecise) keeps its layout.
|
||||
emitPreciseFlags(c, t, flags)
|
||||
|
||||
proc typeKey*(t: PType; conf: ConfigRef; tl: TypeLoader; sl: SymLoader): string =
|
||||
var c: Context = Context(m: createMangler(30, -1), tl: tl, sl: sl,
|
||||
|
||||
4
koch.nim
4
koch.nim
@@ -16,11 +16,11 @@ const
|
||||
ChecksumsStableCommit = "5c132cd332cce5d64a0da9ac3e4c9664313dccb4" # 0.2.2
|
||||
SatStableCommit = "9d52513b3c68bfb929dbd687d4fb2836cfee6936"
|
||||
|
||||
NimonyStableCommit = "557b865192e25e8e76ce4ccc81c6ea71676e92e7" # unversioned \
|
||||
NimonyStableCommit = "6f9ac6655dc6724ae4e5ccb93b8123c18d54391a" # unversioned \
|
||||
# Note that Nimony uses Nim as a git submodule but we don't want to install
|
||||
# Nimony's dependency to Nim as we are Nim. So a `git clone` without --recursive
|
||||
# is **required** here.
|
||||
# Commit from 2026-07-01 -- contains a critical feature addition from nifmake for us
|
||||
# Commit from 2026-07-03 -- .bif files are memory mapped too
|
||||
|
||||
# examples of possible values for fusion: #head, #ea82b54, 1.2.3
|
||||
FusionStableHash = "#562467452b32cb7a97410ea177f083e6d8405734"
|
||||
|
||||
Reference in New Issue
Block a user