aboutsummaryrefslogtreecommitdiff
path: root/src/InternPool.zig
AgeCommit message (Collapse)Author
2024-10-16incremental: introduce `file` dependencies to handle AstGen failuresmlugg
The re-analysis here is a little coarse; it'd be nice in the future to have a way for an AstGen failure to preserve *all* analysis which depends on the last success, and just hide the compile errors which depend on it somehow. But I'm not sure how we'd achieve that, so this works fine for now. Resolves: #21223
2024-09-26remove formatted panicsAndrew Kelley
implements #17969
2024-09-12InternPool: Replace default values with a .empty declarationLinus Groh
2024-09-12Replace deprecated default initializations with decl literalsLinus Groh
2024-09-10Dwarf: implement and test multi array listJacob Young
2024-08-28std: update `std.builtin.Type` fields to follow naming conventionsmlugg
The compiler actually doesn't need any functional changes for this: Sema does reification based on the tag indices of `std.builtin.Type` already! So, no zig1.wasm update is necessary. This change is necessary to disallow name clashes between fields and decls on a type, which is a prerequisite of #9938.
2024-08-27compiler: implement `@branchHint`, replacing `@setCold`mlugg
Implements the accepted proposal to introduce `@branchHint`. This builtin is permitted as the first statement of a block if that block is the direct body of any of the following: * a function (*not* a `test`) * either branch of an `if` * the RHS of a `catch` or `orelse` * a `switch` prong * an `or` or `and` expression It lowers to the ZIR instruction `extended(branch_hint(...))`. When Sema encounters this instruction, it sets `sema.branch_hint` appropriately, and `zirCondBr` etc are expected to reset this value as necessary. The state is on `Sema` rather than `Block` to make it automatically propagate up non-conditional blocks without special handling. If `@panic` is reached, the branch hint is set to `.cold` if none was already set; similarly, error branches get a hint of `.unlikely` if no hint is explicitly provided. If a condition is comptime-known, `cold` hints from the taken branch are allowed to propagate up, but other hints are discarded. This is because a `likely`/`unlikely` hint just indicates the direction this branch is likely to go, which is redundant information when the branch is known at comptime; but `cold` hints indicate that control flow is unlikely to ever reach this branch, meaning if the branch is always taken from its parent, then the parent is also unlikely to ever be reached. This branch information is stored in AIR `cond_br` and `switch_br`. In addition, `try` and `try_ptr` instructions have variants `try_cold` and `try_ptr_cold` which indicate that the error case is cold (rather than just unlikely); this is reachable through e.g. `errdefer unreachable` or `errdefer @panic("")`. A new API `unwrapSwitch` is introduced to `Air` to make it more convenient to access `switch_br` instructions. In time, I plan to update all AIR instructions to be accessed via an `unwrap` method which returns a convenient tagged union a la `InternPool.indexToKey`. The LLVM backend lowers branch hints for conditional branches and switches as follows: * If any branch is marked `unpredictable`, the instruction is marked `!unpredictable`. * Any branch which is marked as `cold` gets a `llvm.assume(i1 true) [ "cold"() ]` call to mark the code path cold. * If any branch is marked `likely` or `unlikely`, branch weight metadata is attached with `!prof`. Likely branches get a weight of 2000, and unlikely branches a weight of 1. In `switch` statements, un-annotated branches get a weight of 1000 as a "middle ground" hint, since there could be likely *and* unlikely *and* un-annotated branches. For functions, a `cold` hint corresponds to the `cold` function attribute, and other hints are currently ignored -- as far as I can tell LLVM doesn't really have a way to lower them. (Ideally, we would want the branch hint given in the function to propagate to call sites.) The compiler and standard library do not yet use this new builtin. Resolves: #21148
2024-08-26remove some stale codeDavid Rubin
- Don't create an `inner_sema` in `unionFields` - Remove assertions of the sema owner, when we literally just set it
2024-08-25sema: `resolve{Struct,Union}Inner` don't throw away SemasDavid Rubin
before this, calls to `resolveTypeFieldsStruct` (now renamed to the more correct `resolveStructFieldTypes`) would just throw away the sema that `resolveStructInner` created and create its own. There is no reason to do this, and we fix it to preserve the sema through it all.
2024-08-25sema: rework type resolution to use Zcu when possibleDavid Rubin
2024-08-21compiler: handle eval branch quota in memoized callsmlugg
In a `memoized_call`, store how many backwards braches the call performs. Add this to `sema.branch_count` when using a memoized call. If this exceeds the quota, perform a non-memoized call to get a correct "exceeded X backwards branches" error. Also, do not memoize calls which do `@setEvalBranchQuota` or similar, as this affects global state which must apply to the caller. Change some eval branch quotas so that the compiler itself still builds correctly. This commit manually changes a file in Aro which is automatically generated. The sources which generate the file are not in this repo. Upstream Aro should make the suitable changes on their end before the next sync of Aro sources into the Zig repo.
2024-08-18Zir: add instructions to fetch std.builtin typesmlugg
This replaces the constant `Zir.Inst.Ref` tags (and the analagous tags in `Air.Inst.Ref`, `InternPool.Index`) referring to types in `std.builtin` with a ZIR instruction `extended(builtin_type(...))` which instructs Sema to fetch such a type, effectively as if it were a shorthand for the ZIR for `@import("std").builtin.xyz`. Previously, this was achieved through constant tags in `Ref`. The analagous `InternPool` indices began as `simple_type` values, and were later rewritten to the correct type information. This system was kind of brittle, and more importantly, isn't compatible with incremental compilation of std, since incremental compilation relies on the ability to recreate types at different indices when they change. Replacing the old system with this instruction slightly increases the size of ZIR, but it simplifies logic and allows incremental compilation to work correctly on the standard library. This shouldn't have a significant impact on ZIR size or compiler performance, but I will take measurements in the PR to confirm this.
2024-08-18frontend: handle incremental updates of replaced runtime functionsmlugg
2024-08-18frontend: removed resolved IES data for outdated functionsmlugg
Without this, incremental updates which would change inferred error sets fail, since they assume the IES is resolved and equals the old set, resulting in false positive compile errors when e.g. coercing to an IES.
2024-08-17compiler: add some doc commentsmlugg
2024-08-17frontend: incremental compilation progressmlugg
Another big commit, sorry! This commit makes all fixes necessary for incremental updates of the compiler itself (specifically, adding a breakpoint to `zirCompileLog`) to succeed, at least on the frontend. The biggest change here is a reform to how types are handled. It works like this: * When a type is first created in `zirStructDecl` etc, its namespace is scanned. If the type requires resolution, an `interned` dependency is declared for the containing `AnalUnit`. * `zirThis` also declared an `interned` dependency for its `AnalUnit` on the namespace's owner type. * If the type's namespace changes, the surrounding source declaration changes hash, so `zirStructDecl` etc will be hit again. We check whether the namespace has been scanned this generation, and re-scan it if not. * Namespace lookups also check whether the namespace in question requires a re-scan based on the generation. This is because there's no guarantee that the `zirStructDecl` is re-analyzed before the namespace lookup is re-analyzed. * If a type's structure (essentially its fields) change, then the type's `Cau` is considered outdated. When the type is re-analyzed due to being outdated, or the `zirStructDecl` is re-analyzed by being transitively outdated, or a corresponding `zirThis` is re-analyzed by being transitively outdated, the struct type is recreated at a new `InternPool` index. The namespace's owner is updated (but not re-scanned, since that is handled by the mechanisms above), and the old type, while remaining a valid `Index`, is removed from the map metadata so it will never be found by lookups. `zirStructDecl` and `zirThis` store an `interned` dependency on the *new* type.
2024-08-17InternPool: don't remove outdated typesmlugg
When a type becomes outdated, there will still be lingering references to the old index -- for instance, any declaration whose value was that type holds a reference to that index. These references may live for an arbitrarily long time in some cases. So, we can't just remove the type from the pool -- the old `Index` must remain valid! Instead, we want to preserve the old `Index`, but avoid it from ever appearing in lookups. (It's okay if analysis of something referencing the old `Index` does weird stuff -- such analysis are guaranteed by the incremental compilation model to always be unreferenced.) So, we use the new `InternPool.putKeyReplace` to replace the shard entry for this index with the newly-created index.
2024-08-17frontend: incremental progressmlugg
This commit makes more progress towards incremental compilation, fixing some crashes in the frontend. Notably, it fixes the regressions introduced by #20964. It also cleans up the "outdated file root" mechanism, by virtue of deleting it: we now detect outdated file roots just after updating ZIR refs, and re-scan their namespaces.
2024-08-16Dwarf: rework self-hosted debug info from scratchJacob Young
This is in preparation for incremental and actually being able to debug executables built by the x86_64 backend.
2024-08-11frontend: give all container types namespacesmlugg
Eliding the namespace when a container type has no decls was an experiment in saving memory, but it ended up causing more trouble than it was worth in various places. So, take the small memory hit for reified types, and just give every container type a namespace.
2024-08-11compiler: split Decl into Nav and Caumlugg
The type `Zcu.Decl` in the compiler is problematic: over time it has gained many responsibilities. Every source declaration, container type, generic instantiation, and `@extern` has a `Decl`. The functions of these `Decl`s are in some cases entirely disjoint. After careful analysis, I determined that the two main responsibilities of `Decl` are as follows: * A `Decl` acts as the "subject" of semantic analysis at comptime. A single unit of analysis is either a runtime function body, or a `Decl`. It registers incremental dependencies, tracks analysis errors, etc. * A `Decl` acts as a "global variable": a pointer to it is consistent, and it may be lowered to a specific symbol by the codegen backend. This commit eliminates `Decl` and introduces new types to model these responsibilities: `Cau` (Comptime Analysis Unit) and `Nav` (Named Addressable Value). Every source declaration, and every container type requiring resolution (so *not* including `opaque`), has a `Cau`. For a source declaration, this `Cau` performs the resolution of its value. (When #131 is implemented, it is unsolved whether type and value resolution will share a `Cau` or have two distinct `Cau`s.) For a type, this `Cau` is the context in which type resolution occurs. Every non-`comptime` source declaration, every generic instantiation, and every distinct `extern` has a `Nav`. These are sent to codegen/link: the backends by definition do not care about `Cau`s. This commit has some minor technically-breaking changes surrounding `usingnamespace`. I don't think they'll impact anyone, since the changes are fixes around semantics which were previously inconsistent (the behavior changed depending on hashmap iteration order!). Aside from that, this changeset has no significant user-facing changes. Instead, it is an internal refactor which makes it easier to correctly model the responsibilities of different objects, particularly regarding incremental compilation. The performance impact should be negligible, but I will take measurements before merging this work into `master`. Co-authored-by: Jacob Young <jacobly0@users.noreply.github.com> Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
2024-07-22add new builtin: `@disableInstrumentation`Andrew Kelley
This is needed to ensure that start code does not try to access thread local storage before it has set up thread local storage.
2024-07-21ip: use `getExternFunc` in `getCoerced`David Rubin
`ip.get` specifically doesn't allow `extern_func` keys to access it.
2024-07-16Merge pull request #20632 from jacobly0/codegen-threadJacob Young
InternPool: enable separate codegen/linking thread
2024-07-16InternPool: enable separate codegen/linking threadJacob Young
Let's see what happens :)
2024-07-16InternPool: reduce max tid width by one bitJacob Young
@mlugg keeps stealing my bits!
2024-07-16InternPool: fix various data structure invariantsJacob Young
2024-07-16InternPool: fix `DependencyIterator` iterationJacob Young
2024-07-15Sema: support pointer subtractionWooster
2024-07-13InternPool: add and use a mutate mutex for each listJacob Young
This allows the mutate mutex to only be locked during actual grows, which are rare. For the lists that didn't previously have a mutex, this change has little effect since grows are rare and there is zero contention on a mutex that is only ever locked by one thread. This change allows `extra` to be mutated without racing with a grow.
2024-07-10InternPool: fix optimization assertion failureJacob Young
2024-07-10InternPool: make `global_error_set` thread-safeJacob Young
2024-07-10InternPool: fix extra mutation racesJacob Young
2024-07-10InternPool: make `maps` thread-safeJacob Young
2024-07-10InternPool: make `tracked_insts` thread-safeJacob Young
2024-07-10InternPool: make `files` more thread-safeJacob Young
2024-07-10InternPool: fix undefined decl fully qualified nameJacob Young
This is now possible after moving `File.Index` to `*File` mapping into intern pool.
2024-07-10InternPool: add `FileIndex` to `*File` mappingJacob Young
2024-07-10InternPool: fix race on struct flagsJacob Young
2024-07-10InternPool: fix race on `FuncInstance.branch_quota`Jacob Young
2024-07-10Zcu: cache fully qualified name on DeclJacob Young
This avoids needing to mutate the intern pool from backends.
2024-07-09InternPool: implement thread-safe allocated listsJacob Young
2024-07-08InternPool: fix multi-thread buildJacob Young
2024-07-07InternPool: fix dumping of simple typesJacob Young
2024-07-07InternPool: start documenting new thread-safe fieldsJacob Young
2024-07-07InternPool: implement and use thread-safe list for extra and limbsJacob Young
2024-07-07InternPool: remove usage of data with simple indicesJacob Young
This allows them to be atomically replaced.
2024-07-07InternPool: temporarily disable multi-threaded behaviorJacob Young
This reduces the cost of the new data structure until the multi-threaded behavior is actually used.
2024-07-07InternPool: implement and use thread-safe list for itemsJacob Young
2024-07-07InternPool: implement and use thread-safe list for stringsJacob Young