aboutsummaryrefslogtreecommitdiff
path: root/src/type.zig
AgeCommit message (Collapse)Author
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-10Sema: remove opv status from arrays with sentinelsJacob Young
Being able to create a pointer to the non-opv sentinel means that these types have to actually be stored.
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-10Type: fix `@sizeOf(?anyerror)`Jacob Young
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-10Type: fix `@typeName` for `undefined`Jacob 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: fix build-exe and compiler-rt crashesJacob Young
2023-06-10InternPool: fix more crashesJacob 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-10InternPool: port most of value tagsJacob Young
2023-06-10Type: hack around `isNoReturn` queries for the remaining legacy tagsJacob Young
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-10Sema: port reify struct access to use 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: eliminate legacy Type.Tag.optionalAndrew Kelley
Now optional types are only stored 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.
2023-06-10stage2: remove legacy Type array and array_sentinelAndrew Kelley
These are now handled by the InternPool.
2023-06-10InternPool: transition float valuesmlugg
2023-06-10stage2: move enum types into the InternPoolAndrew Kelley
Unlike unions and structs, enums are actually *encoded* into the InternPool directly, rather than using the SegmentedList trick. This results in them being quite compact, and greatly improved the ergonomics of using enum types throughout the compiler. It did however require introducing a new concept to the InternPool which is an "incomplete" item - something that is added to gain a permanent Index, but which is then mutated in place. This was necessary because enum tag values and tag types may reference the namespaces created by the enum itself, which required constructing the namespace, decl, and calling analyzeDecl on the decl, which required the decl value, which required the enum type, which required an InternPool index to be assigned and for it to be meaningful. The API for updating enums in place turned out to be quite slick and efficient - the methods directly populate pre-allocated arrays and return the information necessary to output the same compilation errors as before.
2023-06-10InternPool: ability to encode enumsAndrew Kelley
This introduces a string table into InternPool as well as a curious new field called `maps` which is an array list of array hash maps with void/void key/value. Some types such as enums, structs, and unions need to store mappings from field names to field index, or value to field index. In such cases, they will store the underlying field names and values directly, relying on one of these maps, stored separately, to provide lookup. This allows the InternPool to be serialized via simple array copies, omitting all the maps, which are only used for optimizing lookup based on field name or field value. When the InternPool is deserialized it can be loaded via simple array copies, and then as a post-processing step the field name maps can be generated as extra metadata that is tacked on. This commit provides two encodings for enums - one when the integer tag type is explicitly provided and one when it is not. This is simpler than the previous setup, which has three encodings. Previous sizes: * EnumSimple: 40 bytes + 16 bytes per field * EnumNumbered: 80 bytes + 24 bytes per field * EnumFull: 184 bytes + 24 bytes per field Sizes after this commit: * type_enum_explicit: 24 bytes + 8 bytes per field * type_enum_auto: 16 bytes + 4 bytes per field
2023-06-10stage2: move union types and values to InternPoolAndrew Kelley
2023-06-10stage2: move struct types and aggregate values to InternPoolAndrew Kelley
2023-06-10stage2: move opaque types to InternPoolAndrew Kelley
2023-06-10InternPool: add optional valuesAndrew Kelley
2023-06-10InternPool: add ptr-to-int valueAndrew Kelley
Also modify coercion in Sema to be InternPool-aware by calling getCoerced. The unnecessary comptime logic in mod.intValue is deleted too
2023-06-10Sema: introduce Value.enum_field_0Andrew Kelley
and use it to fix typeHasOnePossibleValue logic in two different places.
2023-06-10stage2: more InternPool related fixesAndrew Kelley
* make Sema.zirPtrType coerce the sentinel value against the element type * fix lazyAbiAlignment wrong result type * typeHasOnePossibleValue no longer tries to create interned enum tag value with integer zero, instead uses enum_field_index * Type.ptr avoids trying to store typed null values into the intern pool
2023-06-10stage2: move empty struct type and value to InternPoolAndrew Kelley
2023-06-10stage2: more InternPool-related fixesAndrew Kelley
2023-06-10stage2: implement intTagType logicAndrew Kelley
This commit changes a lot of `*const Module` to `*Module` to make it work, since accessing the integer tag type of an enum might need to mutate the InternPool by adding a new integer type into it. An alternate strategy would be to pre-heat the InternPool with the integer tag type when creating an enum type, which would make it so that intTagType could accept a const Module instead of a mutable one, asserting that the InternPool already had the integer tag type.
2023-06-10stage2: bug fixes related to Type/Value/InternPoolAndrew Kelley
2023-06-10Replace uses of Value.zero, Value.one, Value.negative_onemlugg
This is a bit nasty, mainly because Type.onePossibleValue is now errorable, which is a quite viral change.
2023-06-10wip: progress towards compiling testsmlugg
2023-06-10stage2: move integer values to InternPoolAndrew Kelley
2023-06-10Sema: update onePossibleValue for InternPoolAndrew Kelley
2023-06-10InternPool: add a slice encodingAndrew Kelley
This uses the data field to reference its pointer field type, which allows for efficient and infallible access of a slice type's pointer type.