You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Digging into why arraymancer in particular ends up producing a lot of C files that need to be compiled, despite the majority of arraymancer not being used reveals some weirdness with generics.
To give a short description in words:
Importing a module foo.nim defining a procedure bar in a test file test.nim that returns a generic of a type C[D], which is also, but independently, used in the test file will generate a C file for foo. This happens iff the compiler must automatically deduce the type to C[D] in the test file.
While the C compiler ends up eliminating most of that code, it still slows down compilation and I'm still not convinced this isn't also the reason for sometimes compiling in dynamic libraries that should not show up.
Note how notUsed is not even exported, nor does this file define any globals.
and our test file:
import foo
# workslet bar: seq[float] =@[1.2.float, 3, 4]
var bar: seq[float]
let bar =@[1, 2, 3] # different type than `seq[float]` being returned in `foo`# brokenlet bar =@[2.float, 4, 10]
var bar =@[2.float, 4, 10]
Consider each line as a separate test file of course.
Meaning of works and broken
Works means the compiler does not produce a C file for foo. Broken means it does. So for the first 3 lines individually,
we end up with the following compilation output:
basti at voidRipper in~/org/Misc/dead_code_elim_bug ツ nim c -f test.nim
Hint: used config file '/home/basti/src/nim/nim_git_repo/config/nim.cfg' [Conf]
Hint: used config file '/home/basti/src/nim/nim_git_repo/config/config.nims' [Conf]
..........................................................
/home/basti/org/Misc/dead_code_elim_bug/foo.nim(1, 6) Hint: 'notUsed' is declared but not used [XDeclaredButNotUsed]
/home/basti/org/Misc/dead_code_elim_bug/test.nim(9, 5) Hint: 'bar' is declared but not used [XDeclaredButNotUsed]
/home/basti/org/Misc/dead_code_elim_bug/test.nim(1, 8) Warning: imported and not used: 'foo' [UnusedImport]
CC: stdlib_digitsutils.nim
CC: stdlib_assertions.nim
CC: stdlib_dollars.nim
CC: stdlib_system.nim
CC: test.nim
Hint: [Link]
Hint: gc: refc; opt: none (DEBUG BUILD, `-d:release` generates faster code)
26641 lines; 0.310s; 31.645MiB peakmem; proj: /home/basti/org/Misc/dead_code_elim_bug/test.nim; out: /home/basti/org/Misc/dead_code_elim_bug/test [SuccessX]
Note no CC: foo.nim.
Whereas the ones listed as broken:
basti at voidRipper in~/org/Misc/dead_code_elim_bug ツ nim c -f test.nim
Hint: used config file '/home/basti/src/nim/nim_git_repo/config/nim.cfg' [Conf]
Hint: used config file '/home/basti/src/nim/nim_git_repo/config/config.nims' [Conf]
..........................................................
/home/basti/org/Misc/dead_code_elim_bug/foo.nim(1, 6) Hint: 'notUsed' is declared but not used [XDeclaredButNotUsed]
/home/basti/org/Misc/dead_code_elim_bug/test.nim(15, 5) Hint: 'bar' is declared but not used [XDeclaredButNotUsed]
/home/basti/org/Misc/dead_code_elim_bug/test.nim(1, 8) Warning: imported and not used: 'foo' [UnusedImport]
CC: stdlib_digitsutils.nim
CC: stdlib_assertions.nim
CC: stdlib_dollars.nim
CC: stdlib_system.nim
CC: foo.nim
CC: test.nim
Hint: [Link]
Hint: gc: refc; opt: none (DEBUG BUILD, `-d:release` generates faster code)
26641 lines; 0.316s; 31.613MiB peakmem; proj: /home/basti/org/Misc/dead_code_elim_bug/test.nim; out: /home/basti/org/Misc/dead_code_elim_bug/test [SuccessX]
Note the line CC: foo.nim.
In larger code bases this leads to all sorts of C files being generated that aren't used anywhere unless one is very diligent in only importing the parts that are required (i.e. using import arraymancer / tensor instead of import arraymancer).
Possible Solution
Not enough understanding of how the compiler works to have any idea here.
Additional Information
Tested both on a devel from beginning of November, as well as todays:
Nim Compiler Version 1.7.1 [Linux: amd64]
Compiled at 2021-12-06
Copyright (c) 2006-2021 by Andreas Rumpf
git hash: faacd63bf69561fe915f3651e6b917bb2c0e5bc2
active boot switches: -d:release -d:danger
The text was updated successfully, but these errors were encountered:
Digging into why arraymancer in particular ends up producing a lot of C files that need to be compiled, despite the majority of arraymancer not being used reveals some weirdness with generics.
To give a short description in words:
Importing a module
foo.nim
defining a procedurebar
in a test filetest.nim
that returns a generic of a typeC[D]
, which is also, but independently, used in the test file will generate a C file forfoo
. This happens iff the compiler must automatically deduce the type toC[D]
in the test file.While the C compiler ends up eliminating most of that code, it still slows down compilation and I'm still not convinced this isn't also the reason for sometimes compiling in dynamic libraries that should not show up.
Example
Easier as code. The module we import:
foo.nim
:Note how
notUsed
is not even exported, nor does this file define any globals.and our test file:
Consider each line as a separate test file of course.
Meaning of
works
andbroken
Works means the compiler does not produce a C file for
foo
. Broken means it does. So for the first 3 lines individually,we end up with the following compilation output:
Note no
CC: foo.nim
.Whereas the ones listed as broken:
Note the line
CC: foo.nim
.In larger code bases this leads to all sorts of C files being generated that aren't used anywhere unless one is very diligent in only importing the parts that are required (i.e. using
import arraymancer / tensor
instead ofimport arraymancer
).Possible Solution
Not enough understanding of how the compiler works to have any idea here.
Additional Information
Tested both on a devel from beginning of November, as well as todays:
The text was updated successfully, but these errors were encountered: