* `optimize_mode` is passed to `link.File` and stored there
* improve the debugging function `Module.dumpInst`
* get rid of `Value.the_one_possible_value` in favor of a few more
specific values for different types. This is less buggy, one less
footgun.
* `Type.onePossibleValue` now returns a `?Value` instead of `bool`.
* codegen handles undefined values. `undef` is a new `MCValue` tag.
It uses 0xaa values depending on optimization mode. However
optimization mode does not yet support scope overrides.
* link.zig: move the `Options` field from `File.Elf` and `File.C` to
the base struct.
- fix the Tag enum to adhere to style conventions
* ZIR now supports emitting undefined values.
* Fix the logic of comptime math to properly compare against zero using
the `compareWithZero` function.
* AST: flatten ControlFlowExpression into Continue, Break, and Return.
* AST: unify identifiers and literals into the same AST type: OneToken
* AST: ControlFlowExpression uses TrailerFlags to optimize storage
space.
* astgen: support `var` as well as `const` locals, and support
explicitly typed locals. Corresponding Module and codegen code is not
implemented yet.
* astgen: support result locations.
* ZIR: add the following instructions (see the corresponding doc
comments for explanations of semantics):
- alloc
- alloc_inferred
- bitcast_result_ptr
- coerce_result_block_ptr
- coerce_result_ptr
- coerce_to_ptr_elem
- ensure_result_used
- ensure_result_non_error
- ret_ptr
- ret_type
- store
- param_type
* the skeleton structure for result locations is set up. It's looking
pretty clean so far.
* add compile error for unused result and compile error for discarding
errors.
* astgen: split builtin calls up to implemented manually, and implement
`@as`, `@bitCast` (and others) with respect to result locations.
* add CLI support for hex and raw object formats. They are not
supported by the self-hosted compiler yet, and emit errors.
* rename `--c` CLI to `-ofmt=[objectformat]` which can be any of the
object formats. Only ELF and C are supported so far. Also added missing
help to the help text.
* Remove hard tabs from C backend test cases. Shame on you Noam, you
are grounded, you should know better, etc. Bad boy.
* Delete C backend code and test case that relied on comptime_int
incorrectly making it all the way to codegen.
I'm allowing incremental compilation of ZIR modules to be broken. This
is not a real use case of ZIR, and the feature requires a lot of code
duplication with incremental compilation of Zig AST (which works great).
* Take advantage of coercing anonymous struct literals to struct types.
* Reworks Module to favor Zig source as the primary use case.
Breaks ZIR compilation, which will have to be restored in a future commit.
* Decl uses src_index rather then src, pointing to an AST Decl node
index, or ZIR Module Decl index, rather than a byte offset.
* ZIR instructions have an `analyzed_inst` field instead of Module
having a hash table.
* Module.Fn loses the `fn_type` field since it is redundant with
its `owner_decl` `TypedValue` type.
* Implement Type and Value copying. A ZIR Const instruction's TypedValue
is copied to the Decl arena during analysis, which allows freeing the
ZIR text instructions post-analysis.
* Don't flush the ELF file if there are compilation errors.
* Function return types allow arbitrarily complex expressions.
* AST->ZIR for function calls and return statements.
* Deleted decls are deleted; unused decls are also detected as deleted.
Cycles are not yet detected.
* Re-analysis is smarter and will not cause a re-analysis of dependants
when only a function body is changed.
The binary file abstraction changed its struct named "Decl" to
"TextBlock" and it now represents an allocated slice of memory in
the .text section. It has two new fields: prev and next, making it
a linked list node. This allows a TextBlock to find its neighbors.
The ElfFile struct now has free_list and last_text_block fields.
Doc comments for free_list are reproduced here:
A list of text blocks that have surplus capacity. This list can have false
positives, as functions grow and shrink over time, only sometimes being added
or removed from the freelist.
A text block has surplus capacity when its overcapacity value is greater than
minimum_text_block_size * alloc_num / alloc_den. That is, when it has so
much extra capacity, that we could fit a small new symbol in it, itself with
ideal_capacity or more.
Ideal capacity is defined by size * alloc_num / alloc_den.
Overcapacity is measured by actual_capacity - ideal_capacity. Note that
overcapacity can be negative. A simple way to have negative overcapacity is to
allocate a fresh text block, which will have ideal capacity, and then grow it
by 1 byte. It will then have -1 overcapacity.
The last_text_block keeps track of the end of the .text section.
Allocation, freeing, and resizing decls are all now more sophisticated,
and participate in the virtual address allocation scheme. There is no
longer the possibility for virtual address collisions.
However there does not appear to be an x86 encoding for calling an
immediate address. So there's no point of setting this up. We should
just emit an indirect call to the got addr.
* add TypedValue.Managed which represents a Type, a Value, and some
kind of memory management strategy.
* introduce an analysis queue
* flesh out how incremental compilation works with respect to exports
* ir.text.Module is only capable of one error message during parsing
* link.zig no longer has a decl table map and instead has structs that
exist directly on ir.Module.Decl and ir.Module.Export
* implement primitive .text block allocation
* implement linker code for updating Decls and Exports
* implement null Type
Some supporting std lib changes:
* add std.ArrayList.appendSliceAssumeCapacity
* add std.fs.File.copyRange and copyRangeAll
* fix std.HashMap having modification safety on in ReleaseSmall builds
* add std.HashMap.putAssumeCapacityNoClobber
* introduce std.ArrayListUnmanaged for when you have the allocator
stored elsewhere
* move std.heap.ArenaAllocator implementation to its own file. extract
the main state into std.heap.ArenaAllocator.State, which can be
stored as an alternative to storing the entire ArenaAllocator, saving
24 bytes per ArenaAllocator on 64 bit targets.
* std.LinkedList.Node pointer field now defaults to being null
initialized.
* Rework self-hosted compiler Package API
* Delete almost all the bitrotted self-hosted compiler code. The only bit
rotted code left is in main.zig and compilation.zig
* Add call instruction to ZIR
* self-hosted compiler ir API and link API are reworked to support
a long-running compiler that incrementally updates declarations
* Introduce the concept of scopes to ZIR semantic analysis
* ZIR text format supports referencing named decls that are declared
later in the file
* Figure out how memory management works for the long-running compiler
and incremental compilation. The main roots are top level
declarations. There is a table of decls. The key is a cryptographic
hash of the fully qualified decl name. Each decl has an arena
allocator where all of the memory related to that decl is stored.
Each code block has its own arena allocator for the lifetime of
the block. Values that want to survive when going out of scope in
a block must get copied into the outer block. Finally, values must
get copied into the Decl arena to be long-lived.
* Delete the unused MemoryCell struct. Instead, comptime pointers are
based on references to Decl structs.
* Figure out how caching works. Each Decl will store a set of other
Decls which must be recompiled when it changes.
This branch is still work-in-progress; this commit breaks the build.
Jonathan S writes:
On common systems with a 022 umask, this will still result in a
file created with 755 permissions, but it works appropriately if the
system is configured more leniently. (As another data point, C's fopen
seems to open files with the 666 mode.)