aboutsummaryrefslogtreecommitdiff
path: root/src/Module.zig
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2023-05-26 21:22:34 -0400
committerAndrew Kelley <andrew@ziglang.org>2023-06-10 20:47:56 -0700
commit2d5bc0146941f4cc207c4fd23058e25a16fd40a7 (patch)
tree64087a3ecf4d63d9e53a5f04156dff508d58bd26 /src/Module.zig
parentc8b0d4d149c891ed83db57fe6986d10c5dd654af (diff)
downloadzig-2d5bc0146941f4cc207c4fd23058e25a16fd40a7.tar.gz
zig-2d5bc0146941f4cc207c4fd23058e25a16fd40a7.zip
behavior: get more test cases passing with llvm
Diffstat (limited to 'src/Module.zig')
-rw-r--r--src/Module.zig83
1 files changed, 35 insertions, 48 deletions
diff --git a/src/Module.zig b/src/Module.zig
index 1605bffdd9..314e636bab 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -99,6 +99,7 @@ monomorphed_funcs: MonomorphedFuncsSet = .{},
/// The set of all comptime function calls that have been cached so that future calls
/// with the same parameters will get the same return value.
memoized_calls: MemoizedCallSet = .{},
+memoized_call_args: MemoizedCall.Args = .{},
/// Contains the values from `@setAlignStack`. A sparse table is used here
/// instead of a field of `Fn` because usage of `@setAlignStack` is rare, while
/// functions are many.
@@ -230,46 +231,30 @@ pub const MemoizedCallSet = std.HashMapUnmanaged(
);
pub const MemoizedCall = struct {
- module: *Module,
+ args: *const Args,
+
+ pub const Args = std.ArrayListUnmanaged(InternPool.Index);
pub const Key = struct {
func: Fn.Index,
- args: []TypedValue,
- };
+ args_index: u32,
+ args_count: u32,
- pub const Result = struct {
- val: Value,
- arena: std.heap.ArenaAllocator.State,
+ pub fn args(key: Key, ctx: MemoizedCall) []InternPool.Index {
+ return ctx.args.items[key.args_index..][0..key.args_count];
+ }
};
- pub fn eql(ctx: @This(), a: Key, b: Key) bool {
- if (a.func != b.func) return false;
-
- assert(a.args.len == b.args.len);
- for (a.args, 0..) |a_arg, arg_i| {
- const b_arg = b.args[arg_i];
- if (!a_arg.eql(b_arg, ctx.module)) {
- return false;
- }
- }
+ pub const Result = InternPool.Index;
- return true;
+ pub fn eql(ctx: MemoizedCall, a: Key, b: Key) bool {
+ return a.func == b.func and mem.eql(InternPool.Index, a.args(ctx), b.args(ctx));
}
- /// Must match `Sema.GenericCallAdapter.hash`.
- pub fn hash(ctx: @This(), key: Key) u64 {
+ pub fn hash(ctx: MemoizedCall, key: Key) u64 {
var hasher = std.hash.Wyhash.init(0);
-
- // The generic function Decl is guaranteed to be the first dependency
- // of each of its instantiations.
std.hash.autoHash(&hasher, key.func);
-
- // This logic must be kept in sync with the logic in `analyzeCall` that
- // computes the hash.
- for (key.args) |arg| {
- arg.hash(&hasher, ctx.module);
- }
-
+ std.hash.autoHashStrat(&hasher, key.args(ctx), .Deep);
return hasher.final();
}
};
@@ -883,6 +868,10 @@ pub const Decl = struct {
return decl.ty.abiAlignment(mod);
}
}
+
+ pub fn intern(decl: *Decl, mod: *Module) Allocator.Error!void {
+ decl.val = (try decl.val.intern(decl.ty, mod)).toValue();
+ }
};
/// This state is attached to every Decl when Module emit_h is non-null.
@@ -3325,15 +3314,8 @@ pub fn deinit(mod: *Module) void {
mod.test_functions.deinit(gpa);
mod.align_stack_fns.deinit(gpa);
mod.monomorphed_funcs.deinit(gpa);
-
- {
- var it = mod.memoized_calls.iterator();
- while (it.next()) |entry| {
- gpa.free(entry.key_ptr.args);
- entry.value_ptr.arena.promote(gpa).deinit();
- }
- mod.memoized_calls.deinit(gpa);
- }
+ mod.memoized_call_args.deinit(gpa);
+ mod.memoized_calls.deinit(gpa);
mod.decls_free_list.deinit(gpa);
mod.allocated_decls.deinit(gpa);
@@ -5894,6 +5876,7 @@ pub fn initNewAnonDecl(
typed_value: TypedValue,
name: [:0]u8,
) !void {
+ assert(typed_value.ty.toIntern() == mod.intern_pool.typeOf(typed_value.val.toIntern()));
errdefer mod.gpa.free(name);
const new_decl = mod.declPtr(new_decl_index);
@@ -6645,7 +6628,7 @@ pub fn markDeclAlive(mod: *Module, decl: *Decl) Allocator.Error!void {
if (decl.alive) return;
decl.alive = true;
- decl.val = (try decl.val.intern(decl.ty, mod)).toValue();
+ try decl.intern(mod);
// This is the first time we are marking this Decl alive. We must
// therefore recurse into its value and mark any Decl it references
@@ -6749,15 +6732,19 @@ pub fn ptrType(mod: *Module, info: InternPool.Key.PtrType) Allocator.Error!Type
}
}
- // Canonicalize host_size. If it matches the bit size of the pointee type,
- // we change it to 0 here. If this causes an assertion trip, the pointee type
- // needs to be resolved before calling this ptr() function.
- if (info.host_size != 0) {
- const elem_bit_size = info.elem_type.toType().bitSize(mod);
- assert(info.bit_offset + elem_bit_size <= info.host_size * 8);
- if (info.host_size * 8 == elem_bit_size) {
- canon_info.host_size = 0;
- }
+ switch (info.vector_index) {
+ // Canonicalize host_size. If it matches the bit size of the pointee type,
+ // we change it to 0 here. If this causes an assertion trip, the pointee type
+ // needs to be resolved before calling this ptr() function.
+ .none => if (info.host_size != 0) {
+ const elem_bit_size = info.elem_type.toType().bitSize(mod);
+ assert(info.bit_offset + elem_bit_size <= info.host_size * 8);
+ if (info.host_size * 8 == elem_bit_size) {
+ canon_info.host_size = 0;
+ }
+ },
+ .runtime => {},
+ _ => assert(@enumToInt(info.vector_index) < info.host_size),
}
return (try intern(mod, .{ .ptr_type = canon_info })).toType();