aboutsummaryrefslogtreecommitdiff
path: root/src/InternPool.zig
AgeCommit message (Collapse)Author
2023-06-10InternPool: fix key for empty array with sentinelJacob Young
2023-06-10InternPool: debug dump all the dataAndrew Kelley
2023-06-10InternPool: remove memoized_declAndrew Kelley
This is neither a type nor a value. Simplifies `addStrLit` as well as the many places that switch on `InternPool.Key`. This is a partial revert of bec29b9e498e08202679aa29a45dab2a06a69a1e.
2023-06-10InternPool: further optimize Key hashingAndrew Kelley
This is a continuation of 2f24228c758bc8a35d13379703bc1695008212b0. This commit comes with smaller gains, but gains nonetheless. memcpy is showing up as much less interesting in callgrind output for behavior tests. Current status: this branch is 1.15 ± 0.02 times slower than merge-base.
2023-06-10InternPool: add representation for value of empty enums and unionsmlugg
This is a bit odd, because this value doesn't actually exist: see #15909. This gets all the empty enum/union behavior tests passing. Also adds an assertion to `Sema.analyzeBodyInner` which would have helped figure out the issue here much more quickly.
2023-06-10InternPool: improve hashing performanceAndrew Kelley
Key.PtrType is now an extern struct so that hashing it can be done by reinterpreting bytes directly. It also uses the same representation for type_pointer Tag encoding and the Key. Accessing pointer attributes now requires packed struct access, however, many operations are now a copy of a u32 rather than several independent fields. This function moves the top two most used Key variants - pointer types and pointer values - to use a single-shot hash function that branches for small keys instead of calling memcpy. As a result, perf against merge-base went from 1.17x ± 0.04 slower to 1.12x ± 0.04 slower. After the pointer value hashing was changed, total CPU instructions spent in memcpy went from 4.40% to 4.08%, and after additionally improving pointer type hashing, it further decreased to 3.72%.
2023-06-10InternPool: pass by const pointerAndrew Kelley
The Zig language allows the compiler to make this optimization automatically. We should definitely make the compiler do that, and revert this commit. However, that will not happen in this branch, and I want to continue to explore achieving performance parity with merge-base. So, this commit changes all InternPool parameters to be passed by const pointer rather than by value. I measured a 1.03x ± 0.03 speedup vs the previous commit compiling the (set of passing) behavior tests. Against merge-base, this commit is 1.17x ± 0.04 slower, which is an improvement from the previous measurement of 1.22x ± 0.02. Related issue: #13510 Related issue: #14129 Related issue: #15688
2023-06-10InternPool: eliminate indexToKey call graph cycleAndrew Kelley
Recursion makes this hot function more difficult to profile and optimize. I measured a 1.05x speedup vs the previous commit with the (set of passing) behavior tests. This commit was the last in a series, and the main thing it needed to do was make InternPool.typeOf not call indexToKey(). This required adding a type field to the runtime_value encoding even though it is technically redundant. This could have been avoided with a loop inside typeOf, but I wanted to keep the machine code of that hot function as simple as possible. The variable encoding is still responsible for a relatively small slice of the InternPool data size. I added a function that provides the payload type corresponding to the InternPool.Tag type, which allows for some handy inline switch prongs. Let's start moving the structs that are specific to InternPool.Tag into the corresponding namespace. This will provide type safety if the encoding of InternPool changes for these types later.
2023-06-10InternPool: avoid indexToKey recursion for type_enum_autoAndrew Kelley
Recursion makes this hot function more difficult to profile and optimize. This commit adds the integer tag type to the type_enum_auto encoding even though the integer tag type can be inferred based on the number of fields of the enum. This avoids a call to getAssumeExists of the integer tag type inside indexToKey.
2023-06-10Sema: fix pointer arithmetic on single array pointersJacob Young
2023-06-10InternPool: avoid indexToKey recursion for ptr_sliceAndrew Kelley
Recursion makes this hot function more difficult to profile and optimize. The ptr_slice encoding now additionally includes the slice type. This makes typeOf() implementable without indexToKey() as well as no longer using recursion in the ptr_slice prong of indexToKey itself. Unfortunately some logic had to be duplicated. However, I think that a future enhancement could eliminate the duplication as well as remove some other unwanted code, improving performance, by representing a slice value in `Key.Ptr` without `addr` populated directly, but with an `Index` pointing to the underlying manyptr value.
2023-06-10InternPool: avoid indexToKey recursion for opt_payloadAndrew Kelley
This is a hot function, and recursion makes it more difficult to profile, as well as likely making it more difficult to optimize. Previously, indexToKey for opt_payload would call getAssumeExists() on the optional type. This made it possible to omit the optional type in the encoding of opt_payload. However, getAssumeExists() *must* call indexToKey because of hashing/equality. So, this commit adds the optional type to the opt_payload encoding, which increases its "extra" size from 0 to 8 bytes. As a result, the opt_payload encoding went from not showing up on the top 25 largest tags to...still not showing up in the top 25 largest tags. This also helps make InternPool.typeOf() no longer need to call indexToKey which is another hot function and another source of recursion.
2023-06-10InternPool: avoid indexToKey recursion for only_possible_valueAndrew Kelley
This is a hot function, and recursion makes it more difficult to profile, as well as likely making it more difficult to optimize.
2023-06-10InternPool: avoid indexToKey recursion for ptr_elem,ptr_fieldAndrew Kelley
This is a hot function, and recursion makes it more difficult to profile, as well as likely making it more difficult to optimize.
2023-06-10InternPool: avoid indexToKey recursion for type_sliceAndrew Kelley
This is a hot function, and recursion makes it more difficult to profile, as well as likely making it more difficult to optimize.
2023-06-10InternPool: fix various pointer issuesJacob Young
2023-06-10behavior: fix more compiler crashesJacob Young
2023-06-10behavior: additional llvm fixesJacob Young
2023-06-10Module: move memoized data to the intern poolJacob Young
This avoids memory management bugs with the previous implementation.
2023-06-10behavior: pass more tests on llvm againJacob Young
2023-06-10behavior: get more test cases passing with llvmJacob Young
2023-06-10InternPool: optimize zigTypeTag()Andrew Kelley
This is a particularly hot function, so we operate directly on encodings rather than the more straightforward implementation of calling `indexToKey`. I measured this as 1.05 ± 0.04 times faster than the previous commit with a ReleaseFast build against hello world (which includes std.debug and formatted printing). I also profiled the function and found that zigTypeTag() went from being a major caller of `indexToKey` to being completely insignificant due to being so fast.
2023-06-10InternPool: correct the logic for struct size dumpAndrew Kelley
2023-06-10InternPool: fix build-exe and compiler-rt crashesJacob Young
2023-06-10InternPool: fix more crashesJacob Young
2023-06-10InternPool: fix enough crashes to run `build-obj` on a simple programJacob Young
2023-06-10Sema: inferred allocations no longer abuse type/value systemAndrew Kelley
Previously, there were types and values for inferred allocations and a lot of special-case handling. Now, instead, the special casing is limited to AIR instructions for these use cases. Instead of storing data in Value payloads, the data is now stored in AIR instruction data as well as the previously `void` value type of the `unresolved_inferred_allocs` hash map.
2023-06-10Air: remove constant tagJacob Young
Some uses have been moved to their own tag, the rest use interned. Also, finish porting comptime mutation to be more InternPool aware.
2023-06-10InternPool: fix crashes up to in progress comptime mutationJacob Young
2023-06-10InternPool: remove more legacy valuesJacob Young
Reinstate some tags that will be needed for comptime init.
2023-06-10InternPool: port most of value tagsJacob Young
2023-06-10InternPool: support int->comptime_int in getCoercedAndrew Kelley
2023-06-10InternPool: add lldb pretty printing for indicesJacob Young
2023-06-10InternPool: add missing logicJacob Young
2023-06-10InternPool: fix logic bugsJacob Young
2023-06-10InternPool: add more pointer valuesJacob Young
2023-06-10InternPool: fix coersion issuesJacob Young
2023-06-10InternPool: add missing ensureCapacity call with enumsAndrew Kelley
2023-06-10Sema: move `inferred_alloc_const/mut_type` to InternPoolAndrew Kelley
Now, all types are migrated to use `InternPool`. The `Type.Tag` enum is deleted in this commit.
2023-06-10compiler: remove var_args_param_type from SimpleTypeAndrew Kelley
This is now represented instead by a special `InternPool.Index.Tag` that has no corresponding type/value.
2023-06-10Value: add `intern` and `unintern` to facilitate code conversionJacob Young
This allows some code (like struct initializers) to use interned types while other code (such as comptime mutation) continues to use legacy types. With these changes, an `zig build-obj empty.zig` gets to a crash on missing interned error union types.
2023-06-10Sema: port Value.decl_ptr to InternPoolJacob Young
2023-06-10InternPool: add repeated aggregate storageJacob Young
2023-06-10compiler: move error union types and error set types to InternPoolAndrew Kelley
One change worth noting in this commit is that `module.global_error_set` is no longer kept strictly up-to-date. The previous code reserved integer error values when dealing with error set types, but this is no longer needed because the integer values are not needed for semantic analysis unless `@errorToInt` or `@intToError` are used and therefore may be assigned lazily.
2023-06-10compiler: eliminate legacy Type.Tag.pointerAndrew Kelley
Now pointer types are stored only in InternPool.
2023-06-10compiler: move `anyframe->T` to InternPoolAndrew Kelley
Also I moved `anyframe` from being represented by `SimpleType` to being represented by the `none` tag of `anyframe_type` because most code wants to handle these two types together.
2023-06-10stage2: move function types to InternPoolAndrew Kelley
2023-06-10stage2: encode one-possible-value tuple speciallyAndrew Kelley
Anonymous structs and anonymous tuples can be stored via a only_possible_value tag because their type encodings, by definition, will have every value specified, which can be used to populate the fields slice in `Key.Aggregate`. Also fix `isTupleOrAnonStruct`.
2023-06-10stage2: move anon tuples and anon structs to InternPoolAndrew Kelley
2023-06-10stage2: move enum tag values into the InternPoolAndrew Kelley
I'm seeing a new assertion trip: the call to `enumTagFieldIndex` in the implementation of `@Type` is attempting to query the field index of an union's enum tag, but the type of the enum tag value provided is not the same as the union's tag type. Most likely this is a problem with type coercion, since values are now typed. Another problem is that I added some hacks in std.builtin because I didn't see any convenient way to access them from Sema. That should definitely be cleaned up before merging this branch.