12417 Commits

Author SHA1 Message Date
Andrew Kelley
7e19c95668 Sema: move inferred_alloc_const/mut_type to InternPool
Now, all types are migrated to use `InternPool`. The `Type.Tag` enum is
deleted in this commit.
2023-06-10 20:47:54 -07:00
Andrew Kelley
65d65f5dda Module: remove tmp_hack_arena
This was only needed when pointers were not fully migrated to InternPool
yet.
2023-06-10 20:47:53 -07:00
Andrew Kelley
dfb3521160 compiler: remove var_args_param_type from SimpleType
This is now represented instead by a special `InternPool.Index.Tag` that
has no corresponding type/value.
2023-06-10 20:47:53 -07:00
Jacob Young
115c089562 Value: add intern and unintern to facilitate code conversion
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-10 20:47:53 -07:00
Jacob Young
be78a12d7d Sema: port Value.decl_ptr to InternPool 2023-06-10 20:47:53 -07:00
Jacob Young
c473594114 Sema: port reify struct access to use InternPool 2023-06-10 20:47:53 -07:00
Jacob Young
f8b6eb63d5 Sema: add coerceTupleToStruct result to the InternPool 2023-06-10 20:47:53 -07:00
Jacob Young
d28fc5bacb InternPool: add repeated aggregate storage 2023-06-10 20:47:53 -07:00
Andrew Kelley
9ff514b6a3 compiler: move error union types and error set types to InternPool
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-10 20:47:53 -07:00
Andrew Kelley
7bf91fc79a compiler: eliminate legacy Type.Tag.pointer
Now pointer types are stored only in InternPool.
2023-06-10 20:47:53 -07:00
Andrew Kelley
607737d841 compiler: eliminate legacy Type.Tag.optional
Now optional types are only stored in InternPool.
2023-06-10 20:47:53 -07:00
Andrew Kelley
f21ca3da19 compiler: move anyframe->T to InternPool
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-10 20:47:53 -07:00
Andrew Kelley
17882162b3 stage2: move function types to InternPool 2023-06-10 20:47:53 -07:00
Andrew Kelley
6a9a918fbe stage2: encode one-possible-value tuple specially
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-10 20:47:53 -07:00
Andrew Kelley
d18881de1b stage2: move anon tuples and anon structs to InternPool 2023-06-10 20:47:52 -07:00
Andrew Kelley
88dbd62bcb stage2: move enum tag values into the InternPool
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-10 20:46:17 -07:00
Andrew Kelley
d89807efbb stage2: remove legacy Type array and array_sentinel
These are now handled by the InternPool.
2023-06-10 20:42:31 -07:00
mlugg
466328d1ca InternPool: transition float values 2023-06-10 20:42:30 -07:00
Andrew Kelley
5881a2d637 stage2: move enum types into the InternPool
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-10 20:42:30 -07:00
Andrew Kelley
404cbc36c5 InternPool: fix deinit leaking inner maps 2023-06-10 20:42:30 -07:00
Andrew Kelley
50bebb9e21 InternPool: ability to encode enums
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-10 20:42:30 -07:00
Andrew Kelley
3ba099bfba stage2: move union types and values to InternPool 2023-06-10 20:42:30 -07:00
Andrew Kelley
8297f28546 stage2: move struct types and aggregate values to InternPool 2023-06-10 20:42:30 -07:00
Andrew Kelley
275652f620 stage2: move opaque types to InternPool 2023-06-10 20:42:30 -07:00
Andrew Kelley
e94a81c951 InternPool: add optional values 2023-06-10 20:42:30 -07:00
Andrew Kelley
68b95a39b1 InternPool: add ptr-to-int value
Also modify coercion in Sema to be InternPool-aware by calling
getCoerced.

The unnecessary comptime logic in mod.intValue is deleted too
2023-06-10 20:42:30 -07:00
Andrew Kelley
fd674d95be InternPool: add indexToKey for empty struct types 2023-06-10 20:42:30 -07:00
Andrew Kelley
ad06b249b6 Sema: introduce Value.enum_field_0
and use it to fix typeHasOnePossibleValue logic in two different places.
2023-06-10 20:42:30 -07:00
Andrew Kelley
8587e510e4 stage2: more InternPool related fixes
* 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-10 20:42:30 -07:00
Andrew Kelley
3116477dcc stage2: move empty struct type and value to InternPool 2023-06-10 20:42:30 -07:00
Andrew Kelley
2f9b7dc102 InternPool: add an int_u8 value encoding
On a simple input file, this had a total savings of 21% in the
InternPool:

Before:
    int_positive: 427 occurrences, 8975 total bytes
After:
    int_positive: 258 occurrences, 5426 total bytes
    int_u8: 169 occurrences, 845 total bytes
2023-06-10 20:42:29 -07:00
Andrew Kelley
4fe0c583be stage2: more InternPool-related fixes 2023-06-10 20:42:29 -07:00
Andrew Kelley
4d88f825bc stage2: implement intTagType logic
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-10 20:42:29 -07:00
Andrew Kelley
a5fb169594 stage2: bug fixes related to Type/Value/InternPool 2023-06-10 20:42:29 -07:00
Andrew Kelley
8699cdc3df InternPool: fix UAF in getCoercedInt and add u16 int value encoding 2023-06-10 20:42:29 -07:00
mlugg
2ffef605c7 Replace uses of Value.zero, Value.one, Value.negative_one
This is a bit nasty, mainly because Type.onePossibleValue is now
errorable, which is a quite viral change.
2023-06-10 20:42:29 -07:00
Andrew Kelley
4c3c605e5f InternPool: add getCoercedInt to avoid copy in Sema 2023-06-10 20:42:29 -07:00
mlugg
c1ca16d779 wip: progress towards compiling tests 2023-06-10 20:42:29 -07:00
Andrew Kelley
9d9e1a2991 InternPool: implement indexToKey and equality for int values 2023-06-10 20:42:29 -07:00
Andrew Kelley
6c713b40f7 InternPool: add an encoding for arrays with sentinels 2023-06-10 20:42:29 -07:00
Andrew Kelley
75900ec1b5 stage2: move integer values to InternPool 2023-06-10 20:42:29 -07:00
Andrew Kelley
73720b6975 Sema: update onePossibleValue for InternPool 2023-06-10 20:42:29 -07:00
Andrew Kelley
f7bd42785b LLVM backend: update integer constant lowering for InternPool 2023-06-10 20:42:29 -07:00
Andrew Kelley
27d641eb35 stage2: fix interned integer value printing 2023-06-10 20:42:29 -07:00
Andrew Kelley
6350aabf9d InternPool: fix bug in addLimbsExtraAssumeCapacity 2023-06-10 20:42:29 -07:00
Andrew Kelley
9626811725 Sema: add typeHasOnePossibleValue logic for InternPool 2023-06-10 20:42:29 -07:00
Andrew Kelley
31aee50c1a InternPool: add a slice encoding
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.
2023-06-10 20:42:29 -07:00
Andrew Kelley
08e9763951 stage2: add missing comptimeOnly logic for InternPool 2023-06-10 20:42:28 -07:00
Andrew Kelley
80bf5af345 fix AIR printing of interned constants 2023-06-10 20:42:28 -07:00
Andrew Kelley
3e6dd0da7a stage2: add tmp_hack_arena for the InternPool transition
Temporarily used for some unfortunate allocations made by backends that
need to construct pointer types that can't be represented by the
InternPool. Once all types are migrated to be stored in the InternPool,
this can be removed.
2023-06-10 20:42:28 -07:00