Fil-C on Nix

Filnix wiki

mbrock/filnix

nanofil/bench/default.nix

The runtime benchmark's binaries and inputs (docs/perf.md). Each program is built by filcc -O2 (ref), by plain clang without Fil-C (native) and by nanofil in every mode below, through the same nanofil-cc wrapper the Nix checks use, and kept unstripped for perf. Build with

nix build --impure -f nanofil/bench -o nanofil/bench/out

from the repository root (--argstr only O,O-stack builds just those nanofil modes); run.py then checks and times them.

λflake?, pkgs?, filcc?, only?
flakedefault builtins.getFlaketoString../..
pkgsdefault importflake.inputs.nixpkgs system = "x86_64-linux";
filccdefault flake.packages.x86_64-linux.filcc-staging
onlydefault ""
let

The flake's copy of nanofil: tracked files only, not out/ or results.

19cc=
import"${flake}/nanofil/nix/nanofil-cc.nix" inherit pkgs filcc;
20programs=
import"${flake}/nanofil/bench/programs.nix" inherit pkgs filcc;

Plain clang, no Fil-C (native): the LLVM version Fil-C is built from, behind the same kind of Nix wrapper and with the same flags.

25native=
pkgs.llvmPackages_20.clang

NANOFIL_OPT for each nanofil mode. off is the reference backend without the middle end; the others are what a user would choose.

28modes=
29off=
""
30O=
"-O"
31O-reuse=
"-O --checks=reuse"
32O-refchecks=
"-O --checks=reference"
33O-guard=
"-O --checks=guard"
34O-temps=
"-O --registers=temps"
35O-noinline=
"-O --inline=none"
36O-small=
"-O --inline=small"
37O-refbranches=
"-O --branches=reference"
38O-stack=
"-O --registers=stack"
39O-call=
"-O --memcpy=call"
40O-nosimplify=
"-O --simplify=none"
41O-limit4000=
"-O --registers-limit=4000"
42O-merged=
"-O --bounds=merged"
43O-or=
"-O --bounds=or"
44O-sign=
"-O --bounds=sign"
45O-hoist=
"-O --checks=hoist"
46O-hoist-merged=
"-O --checks=hoist --bounds=merged"
47O-hoist-or=
"-O --checks=hoist --bounds=or"
48O-schedule=
"-O --checks=schedule"
49O-share-block=
"-O --share=block"
50O-share-null=
"-O --share=null"
51O-share=
"-O --share=upper"
52O-half=
"-O --checks=half"
53O-forward=
"-O --checks=forward"
54O-combined=
"-O --checks=combined"
55O-all=
"-O --checks=combined --share=upper"
56O-hull=
"-O --checks=hull"
57O-getter=
"-O --checks=getter"
58O-extended=
"-O --checks=extended"
59O-lowers=
"-O --lowers=shared"
used by chosen
61chosen=
only ≡ ""
→
else
pkgs.lib.filterAttrsm: _: builtins.elemm pkgs.lib.splitString"," only modes
uses modes

4 MiB of C source text from the four pinned tarballs, sorted by path and repeated, and 4 MiB of SHA-256 counter output. Both depend only on nixpkgs' pinned sources.

71inputs=
pkgs.runCommand"nanofil-bench-inputs" nativeBuildInputs = pkgs.python3;
mkdir src $out
for s in ${pkgs.zlib.src} ${pkgs.lua5_4.src} ${pkgs.bzip2.src}; do
tar -xf $s -C src
done
cp -r ${pkgs.lz4.src} src/lz4
find src -type f \( -name '*.c' -o -name '*.h' \) | LC_ALL=C sort | xargs cat >one
for i in 1 2 3 4 5 6 7 8; do cat one; done >many
head -c 4194304 many >$out/text
python3 -c '
import hashlib, sys
out = bytearray()
i = 0
while len(out) < 4194304:
out += hashlib.sha256(b"nanofil-bench:" + i.to_bytes(8, "little")).digest()
i += 1
sys.stdout.buffer.write(out)' >$out/random
test $(stat -c %s $out/text) = 4194304
in
pkgs.linkFarm"nanofil-bench"
97name=
"inputs"
++
pkgs.lib.concatLists
pkgs.lib.mapAttrsToList
λname _
106name=
"${name}/ref"
107path=
programs.buildname "ref" "${filcc}/bin/clang" "" ""
110name=
"${name}/native"
111path=
programs.buildname "native" "${native}/bin/clang" "" ""
++
pkgs.lib.mapAttrsToList
λmode opt
115name=
"${name}/${mode}"
116path=
programs.progs