`is_pub` added to `Fn` would cost us an additional 8
bytes of memory per function, which is a real bummer
since it's only 1 bit of information.
If we wanted to really remove this, I suspect we could
make this a function isPub() which looks at the AST of
the corresponding Decl and finds if the FnProto AST node
has the pub token. However I saw an easier approach -
The data of whether something is pub or not is actually
a property of a Decl anyway, not a function, so we can
look at moving the field into Decl. Indeed, doing this,
we see that Decl already has deletion_flag: bool which
is hiding in the padding bytes between the enum (1 byte)
and the following u32 field (generation). So if we put
the is_pub bool there, it actually will take up no
additional space, with 1 byte of padding remaining.
This was an easy reworking of the code since any
func.is_pub could be changed simply to func.owner_decl.is_pub.
I also modified `Var` to make the init value non-optional
and moved the optional bit to a has_init: bool field. This is worse from
the perspective of control flow and safety, however it makes
`@sizeOf(Var)` go from 32 bytes to 24 bytes. The more code we can fit
into memory at once, the more justified we are in using the compiler as
a long-running process that does incremental updates.
Exports now have a dirty flag and are rewritten on flush if this flag
has been set.
A couple other minor changes have been made based on Andrew's review.
Thus far, we only generate the type, function, export, and code
sections. These are sufficient to generate and export simple functions.
Codegen is currently hardcoded to `i32.const 42`, the main goal of this
commit is to create infrastructure for the container format which will
work with incremental compilation.
This is part of an ongoing effort to reduce size of in-memory AST. This
enum flattening pattern is widespread throughout the self-hosted
compiler.
This is a API breaking change for consumers of the self-hosted parser.
* introduce a dump() function on Module.Fn which helpfully prints to
stderr the ZIR representation of a function (can be called before
attempting to codegen it). This is a debugging tool.
* implement x86 codegen for loops
* liveness: fix analysis of conditional branches. The logic was buggy
in a couple ways:
- it never actually saved the results into the IR instruction (fixed now)
- it incorrectly labeled operands as dying when their true death was
after the conditional branch ended (fixed now)
* zir rendering is enhanced to show liveness analysis results. this
helps when debugging liveness analysis.
* fix bug in zir rendering not numbering instructions correctly
closes#6021
SrcFn represents the function in the linked output file, if the
`Decl` is a function. This is stored here and not in `Fn` because `Decl`
survives across updates but `Fn` does not.
TODO Look into making `Fn` a longer lived structure and moving this field there
to save on memory usage.
* the .debug_line header is written properly
* link.File.Elf gains:
- SrcFn, which is now a field in Module.Fn
- SrcFile, which is now a field in Module.Scope.File
* link.File.Elf gets a whole *Package field rather than only
root_src_dir_path.
* the fields first_dbg_line_file and last_dbg_line_file tell where the
Line Number Program begins and ends, which alows moving files when
the header gets too big, and allows appending files to the end.
* codegen is passed a buffer for emitting .debug_line
Line Number Program opcodes for functions.
See #5963
There is some work-in-progress code here, but I need to go make some
experimental changes to changing how to represent source locations and I
want to do that in a separate commit.