mirror of
https://github.com/nim-lang/Nim.git
synced 2026-09-01 19:33:42 +00:00
IC: add -d:icSymCount, and use it to settle the full-compiler comparison
Counts every `newSym` mint, by kind, and reports on exit. A gensym's number is its item id, so ONE extra symbol anywhere shifts every later name in the generated C — which makes a mint count far more sensitive than diffing output, and localises a difference by symbol kind instead of by whichever file happened to show it. It was written to answer a question I had reported wrongly. Comparing the cursor-driven and `PNode`-driven builds over the whole compiler showed 3 of 215 `.c` files differing, and I attributed 2 of them to the compiler being nondeterministic. That control was invalid: I had compared two runs across an edit to `ccgexprs.nim`, so what I read as nondeterminism was line numbers moving inside assertion strings. The compiler is DETERMINISTIC — same binary, same source, twice, 0 of 215 differ. What the count establishes: the two builds mint exactly the same symbols, 515_551 of them, with no per-kind difference at all. So nothing in the cursor path creates or skips a symbol, and the earlier gensym-numbered differences — which had zero non-gensym lines — were ordering, not extra work. On the current tree the comparison is clean: cursor-driven and `PNode`-driven produce BYTE-IDENTICAL `.c` for all 215 files of `compiler/nim.nim`. I have not isolated why the same comparison showed 3 differences one commit earlier; the commit between was behaviour-neutral by inspection, so I am recording the observation rather than a claim about its cause. Verified: both build configurations compile; the diagnostic is behind a define and costs nothing otherwise. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XEF7FJvUkGKvG9LSGuEaNR
This commit is contained in:
@@ -781,10 +781,28 @@ when false:
|
||||
echo k
|
||||
echo v
|
||||
|
||||
when defined(icSymCount):
|
||||
import std / [syncio, exitprocs, tables as symCountTables]
|
||||
var symMints*: symCountTables.CountTable[string]
|
||||
var symMintTotal*: int
|
||||
var symCountHooked = false
|
||||
|
||||
proc newSym*(symKind: TSymKind, name: PIdent, idgen: IdGenerator; owner: PSym,
|
||||
info: TLineInfo; options: TOptions = {}): PSym =
|
||||
# generates a symbol and initializes the hash field too
|
||||
assert not name.isNil
|
||||
when defined(icSymCount):
|
||||
# Counting symbol MINTS, not their names in the output: a gensym's number is
|
||||
# its item id, so one extra symbol anywhere shifts every later name. A count
|
||||
# is therefore far more sensitive than diffing generated C, and it localises
|
||||
# the extra mint by kind instead of by whatever file happened to show it.
|
||||
inc symMintTotal
|
||||
symMints.inc $symKind
|
||||
if not symCountHooked:
|
||||
symCountHooked = true
|
||||
addExitProc proc () =
|
||||
stderr.writeLine "SYMMINT total=" & $symMintTotal
|
||||
for k, v in symMints: stderr.writeLine "SYMMINT " & k & "=" & $v
|
||||
let id = nextSymId idgen
|
||||
result = PSym(name: name, kindImpl: symKind, flagsImpl: {}, infoImpl: info, itemId: id,
|
||||
optionsImpl: options, ownerFieldImpl: owner, offsetImpl: defaultOffset,
|
||||
|
||||
Reference in New Issue
Block a user