authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-16 16:29:08-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-16 16:29:08-07:00
logcdeb1fb88157130ba1260e6c2d4ef5a20df0c493
treed510a7942f92292839be15c7bc7e883e8dae428a
parent418197b6c51b99ee2a0be5e394753868f7dbf982

Sema: different solution to elemVal

I think that reusing the ComptimePtrLoad infrastructure is ultimately less logic and more robust than adding a `direct` flag to elem_ptr. * Some code in zirTypeInfo needed to be fixed to create proper Type/Value encodings. * comptime elemVal works by constructing an elem_ptr Value and then using the already existing pointerDeref function. There are some remaining calls to Value.elemValue which should be considered code smells at this point.

2 files changed, 64 insertions(+), 42 deletions(-)

src/Sema.zig+63-15
...@@ -10388,25 +10388,32 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -10388,25 +10388,32 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
10388 )).?;10388 )).?;
10389 try sema.mod.declareDeclDependency(sema.owner_decl, fn_info_decl);10389 try sema.mod.declareDeclDependency(sema.owner_decl, fn_info_decl);
10390 try sema.ensureDeclAnalyzed(fn_info_decl);10390 try sema.ensureDeclAnalyzed(fn_info_decl);
10391 var fn_ty_buffer: Value.ToTypeBuffer = undefined;
10392 const fn_ty = fn_info_decl.val.toType(&fn_ty_buffer);
10391 const param_info_decl = (try sema.namespaceLookup(10393 const param_info_decl = (try sema.namespaceLookup(
10392 block,10394 block,
10393 src,10395 src,
10394 fn_info_decl.val.castTag(.ty).?.data.getNamespace().?,10396 fn_ty.getNamespace().?,
10395 "Param",10397 "Param",
10396 )).?;10398 )).?;
10397 try sema.mod.declareDeclDependency(sema.owner_decl, param_info_decl);10399 try sema.mod.declareDeclDependency(sema.owner_decl, param_info_decl);
10398 try sema.ensureDeclAnalyzed(param_info_decl);10400 try sema.ensureDeclAnalyzed(param_info_decl);
10401 var param_buffer: Value.ToTypeBuffer = undefined;
10402 const param_ty = param_info_decl.val.toType(&param_buffer);
10399 const new_decl = try params_anon_decl.finish(10403 const new_decl = try params_anon_decl.finish(
10400 try Type.Tag.array.create(params_anon_decl.arena(), .{10404 try Type.Tag.array.create(params_anon_decl.arena(), .{
10401 .len = param_vals.len,10405 .len = param_vals.len,
10402 .elem_type = param_info_decl.ty,10406 .elem_type = try param_ty.copy(params_anon_decl.arena()),
10403 }),10407 }),
10404 try Value.Tag.aggregate.create(10408 try Value.Tag.aggregate.create(
10405 params_anon_decl.arena(),10409 params_anon_decl.arena(),
10406 param_vals,10410 param_vals,
10407 ),10411 ),
10408 );10412 );
10409 break :v try Value.Tag.decl_ref.create(sema.arena, new_decl);10413 break :v try Value.Tag.slice.create(sema.arena, .{
10414 .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl),
10415 .len = try Value.Tag.int_u64.create(sema.arena, param_vals.len),
10416 });
10410 };10417 };
1041110418
10412 const ret_ty_opt = if (info.return_type.tag() != .generic_poison)10419 const ret_ty_opt = if (info.return_type.tag() != .generic_poison)
...@@ -10823,7 +10830,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -10823,7 +10830,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
10823 try fields_anon_decl.arena().dupe(Value, union_field_vals),10830 try fields_anon_decl.arena().dupe(Value, union_field_vals),
10824 ),10831 ),
10825 );10832 );
10826 break :v try Value.Tag.decl_ref.create(sema.arena, new_decl);10833 break :v try Value.Tag.slice.create(sema.arena, .{
10834 .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl),
10835 .len = try Value.Tag.int_u64.create(sema.arena, union_field_vals.len),
10836 });
10827 };10837 };
1082810838
10829 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, union_ty.getNamespace());10839 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, union_ty.getNamespace());
...@@ -10897,7 +10907,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -10897,7 +10907,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
10897 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),10907 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
10898 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),10908 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
10899 );10909 );
10900 break :v try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl);10910 break :v try Value.Tag.slice.create(sema.arena, .{
10911 .ptr = try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl),
10912 .len = try Value.Tag.int_u64.create(sema.arena, bytes.len),
10913 });
10901 };10914 };
1090210915
10903 const struct_field_fields = try fields_anon_decl.arena().create([5]Value);10916 const struct_field_fields = try fields_anon_decl.arena().create([5]Value);
...@@ -10937,7 +10950,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -10937,7 +10950,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
10937 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),10950 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
10938 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),10951 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
10939 );10952 );
10940 break :v try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl);10953 break :v try Value.Tag.slice.create(sema.arena, .{
10954 .ptr = try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl),
10955 .len = try Value.Tag.int_u64.create(sema.arena, bytes.len),
10956 });
10941 };10957 };
1094210958
10943 const struct_field_fields = try fields_anon_decl.arena().create([5]Value);10959 const struct_field_fields = try fields_anon_decl.arena().create([5]Value);
...@@ -10979,7 +10995,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -10979,7 +10995,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
10979 try fields_anon_decl.arena().dupe(Value, struct_field_vals),10995 try fields_anon_decl.arena().dupe(Value, struct_field_vals),
10980 ),10996 ),
10981 );10997 );
10982 break :v try Value.Tag.decl_ref.create(sema.arena, new_decl);10998 break :v try Value.Tag.slice.create(sema.arena, .{
10999 .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl),
11000 .len = try Value.Tag.int_u64.create(sema.arena, struct_field_vals.len),
11001 });
10983 };11002 };
1098411003
10985 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, struct_ty.getNamespace());11004 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, struct_ty.getNamespace());
...@@ -11048,7 +11067,7 @@ fn typeInfoDecls(...@@ -11048,7 +11067,7 @@ fn typeInfoDecls(
11048 block,11067 block,
11049 src,11068 src,
11050 type_info_ty.getNamespace().?,11069 type_info_ty.getNamespace().?,
11051 "EnumField",11070 "Declaration",
11052 )).?;11071 )).?;
11053 try sema.mod.declareDeclDependency(sema.owner_decl, declaration_ty_decl);11072 try sema.mod.declareDeclDependency(sema.owner_decl, declaration_ty_decl);
11054 try sema.ensureDeclAnalyzed(declaration_ty_decl);11073 try sema.ensureDeclAnalyzed(declaration_ty_decl);
...@@ -11069,7 +11088,10 @@ fn typeInfoDecls(...@@ -11069,7 +11088,10 @@ fn typeInfoDecls(
11069 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),11088 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
11070 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),11089 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
11071 );11090 );
11072 break :v try Value.Tag.decl_ref.create(decls_anon_decl.arena(), new_decl);11091 break :v try Value.Tag.slice.create(decls_anon_decl.arena(), .{
11092 .ptr = try Value.Tag.decl_ref.create(decls_anon_decl.arena(), new_decl),
11093 .len = try Value.Tag.int_u64.create(decls_anon_decl.arena(), bytes.len),
11094 });
11073 };11095 };
1107411096
11075 const fields = try decls_anon_decl.arena().create([2]Value);11097 const fields = try decls_anon_decl.arena().create([2]Value);
...@@ -11092,7 +11114,10 @@ fn typeInfoDecls(...@@ -11092,7 +11114,10 @@ fn typeInfoDecls(
11092 try decls_anon_decl.arena().dupe(Value, decls_vals),11114 try decls_anon_decl.arena().dupe(Value, decls_vals),
11093 ),11115 ),
11094 );11116 );
11095 return try Value.Tag.decl_ref.create(sema.arena, new_decl);11117 return try Value.Tag.slice.create(sema.arena, .{
11118 .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl),
11119 .len = try Value.Tag.int_u64.create(sema.arena, decls_vals.len),
11120 });
11096}11121}
1109711122
11098fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {11123fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -16574,8 +16599,20 @@ fn elemVal(...@@ -16574,8 +16599,20 @@ fn elemVal(
16574 const runtime_src = if (maybe_slice_val) |slice_val| rs: {16599 const runtime_src = if (maybe_slice_val) |slice_val| rs: {
16575 const index_val = maybe_index_val orelse break :rs elem_index_src;16600 const index_val = maybe_index_val orelse break :rs elem_index_src;
16576 const index = @intCast(usize, index_val.toUnsignedInt());16601 const index = @intCast(usize, index_val.toUnsignedInt());
16577 const elem_val = try slice_val.elemValue(sema.arena, index);16602
16578 return sema.addConstant(array_ty.elemType2(), elem_val);16603 const elem_ty = array_ty.elemType2();
16604
16605 var payload: Value.Payload.ElemPtr = .{ .data = .{
16606 .array_ptr = slice_val.slicePtr(),
16607 .elem_ty = elem_ty,
16608 .index = index,
16609 } };
16610 const elem_ptr_val = Value.initPayload(&payload.base);
16611
16612 if (try sema.pointerDeref(block, array_src, elem_ptr_val, array_ty)) |elem_val| {
16613 return sema.addConstant(elem_ty, elem_val);
16614 }
16615 break :rs array_src;
16579 } else array_src;16616 } else array_src;
1658016617
16581 try sema.requireRuntimeBlock(block, runtime_src);16618 try sema.requireRuntimeBlock(block, runtime_src);
...@@ -16589,8 +16626,19 @@ fn elemVal(...@@ -16589,8 +16626,19 @@ fn elemVal(
16589 const array_val = maybe_array_val orelse break :rs array_src;16626 const array_val = maybe_array_val orelse break :rs array_src;
16590 const index_val = maybe_index_val orelse break :rs elem_index_src;16627 const index_val = maybe_index_val orelse break :rs elem_index_src;
16591 const index = @intCast(usize, index_val.toUnsignedInt());16628 const index = @intCast(usize, index_val.toUnsignedInt());
16592 const elem_val = try array_val.elemValue(sema.arena, index);16629 const elem_ty = array_ty.elemType2();
16593 return sema.addConstant(array_ty.elemType2(), elem_val);16630
16631 var payload: Value.Payload.ElemPtr = .{ .data = .{
16632 .array_ptr = array_val,
16633 .elem_ty = elem_ty,
16634 .index = index,
16635 } };
16636 const elem_ptr_val = Value.initPayload(&payload.base);
16637
16638 if (try sema.pointerDeref(block, array_src, elem_ptr_val, array_ty)) |elem_val| {
16639 return sema.addConstant(elem_ty, elem_val);
16640 }
16641 break :rs array_src;
16594 };16642 };
1659516643
16596 try sema.requireRuntimeBlock(block, runtime_src);16644 try sema.requireRuntimeBlock(block, runtime_src);
...@@ -16739,7 +16787,7 @@ fn elemPtrArray(...@@ -16739,7 +16787,7 @@ fn elemPtrArray(
16739 const index_u64 = index_val.toUnsignedInt();16787 const index_u64 = index_val.toUnsignedInt();
16740 // @intCast here because it would have been impossible to construct a value that16788 // @intCast here because it would have been impossible to construct a value that
16741 // required a larger index.16789 // required a larger index.
16742 const elem_ptr = try array_ptr_val.elemPtrDirect(array_ptr_ty, sema.arena, @intCast(usize, index_u64));16790 const elem_ptr = try array_ptr_val.elemPtr(array_ptr_ty, sema.arena, @intCast(usize, index_u64));
16743 return sema.addConstant(result_ty, elem_ptr);16791 return sema.addConstant(result_ty, elem_ptr);
16744 }16792 }
16745 }16793 }
src/value.zig+1-27
...@@ -505,7 +505,6 @@ pub const Value = extern union {...@@ -505,7 +505,6 @@ pub const Value = extern union {
505 .array_ptr = try payload.data.array_ptr.copy(arena),505 .array_ptr = try payload.data.array_ptr.copy(arena),
506 .elem_ty = try payload.data.elem_ty.copy(arena),506 .elem_ty = try payload.data.elem_ty.copy(arena),
507 .index = payload.data.index,507 .index = payload.data.index,
508 .direct = payload.data.direct,
509 },508 },
510 };509 };
511 return Value{ .ptr_otherwise = &new_payload.base };510 return Value{ .ptr_otherwise = &new_payload.base };
...@@ -2403,11 +2402,7 @@ pub const Value = extern union {...@@ -2403,11 +2402,7 @@ pub const Value = extern union {
2403 .decl_ref_mut => return val.castTag(.decl_ref_mut).?.data.decl.val.elemValueAdvanced(index, arena, buffer),2402 .decl_ref_mut => return val.castTag(.decl_ref_mut).?.data.decl.val.elemValueAdvanced(index, arena, buffer),
2404 .elem_ptr => {2403 .elem_ptr => {
2405 const data = val.castTag(.elem_ptr).?.data;2404 const data = val.castTag(.elem_ptr).?.data;
2406 if (!data.direct)2405 return data.array_ptr.elemValueAdvanced(index + data.index, arena, buffer);
2407 return data.array_ptr.elemValueAdvanced(index + data.index, arena, buffer);
2408
2409 const underlying = try data.array_ptr.elemValueAdvanced(data.index, arena, buffer);
2410 return underlying.elemValueAdvanced(index, arena, buffer);
2411 },2406 },
24122407
2413 // The child type of arrays which have only one possible value need2408 // The child type of arrays which have only one possible value need
...@@ -2470,25 +2465,12 @@ pub const Value = extern union {...@@ -2470,25 +2465,12 @@ pub const Value = extern union {
24702465
2471 /// Returns a pointer to the element value at the index.2466 /// Returns a pointer to the element value at the index.
2472 pub fn elemPtr(val: Value, ty: Type, arena: Allocator, index: usize) Allocator.Error!Value {2467 pub fn elemPtr(val: Value, ty: Type, arena: Allocator, index: usize) Allocator.Error!Value {
2473 return val.elemPtrAdvanced(ty, arena, index, false);
2474 }
2475
2476 /// Returns a pointer to the element value at the index. The behavior
2477 /// of this is slightly different for comptime; the "direct" means that
2478 /// indexing indexes the referenced child value, not the parent array.
2479 pub fn elemPtrDirect(val: Value, ty: Type, arena: Allocator, index: usize) Allocator.Error!Value {
2480 return val.elemPtrAdvanced(ty, arena, index, true);
2481 }
2482
2483 pub fn elemPtrAdvanced(val: Value, ty: Type, arena: Allocator, index: usize, direct: bool) Allocator.Error!Value {
2484 const elem_ty = ty.elemType2();2468 const elem_ty = ty.elemType2();
2485 const ptr_val = switch (val.tag()) {2469 const ptr_val = switch (val.tag()) {
2486 .slice => val.castTag(.slice).?.data.ptr,2470 .slice => val.castTag(.slice).?.data.ptr,
2487 else => val,2471 else => val,
2488 };2472 };
24892473
2490 // If the val is already an elem ptr, then we do ptr arithmetic logic
2491 // and just move the index.
2492 if (ptr_val.tag() == .elem_ptr) {2474 if (ptr_val.tag() == .elem_ptr) {
2493 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;2475 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2494 if (elem_ptr.elem_ty.eql(elem_ty)) {2476 if (elem_ptr.elem_ty.eql(elem_ty)) {
...@@ -2496,12 +2478,6 @@ pub const Value = extern union {...@@ -2496,12 +2478,6 @@ pub const Value = extern union {
2496 .array_ptr = elem_ptr.array_ptr,2478 .array_ptr = elem_ptr.array_ptr,
2497 .elem_ty = elem_ptr.elem_ty,2479 .elem_ty = elem_ptr.elem_ty,
2498 .index = elem_ptr.index + index,2480 .index = elem_ptr.index + index,
2499
2500 // Retain the direct preference. This enables a direct
2501 // elem ptr (i.e. &arr[0]) to be bitcasted to a many-pointer
2502 // with pointer arithmetic then casted back to a single
2503 // pointer.
2504 .direct = elem_ptr.direct,
2505 });2481 });
2506 }2482 }
2507 }2483 }
...@@ -2509,7 +2485,6 @@ pub const Value = extern union {...@@ -2509,7 +2485,6 @@ pub const Value = extern union {
2509 .array_ptr = ptr_val,2485 .array_ptr = ptr_val,
2510 .elem_ty = elem_ty,2486 .elem_ty = elem_ty,
2511 .index = index,2487 .index = index,
2512 .direct = direct,
2513 });2488 });
2514 }2489 }
25152490
...@@ -4219,7 +4194,6 @@ pub const Value = extern union {...@@ -4219,7 +4194,6 @@ pub const Value = extern union {
4219 array_ptr: Value,4194 array_ptr: Value,
4220 elem_ty: Type,4195 elem_ty: Type,
4221 index: usize,4196 index: usize,
4222 direct: bool,
4223 },4197 },
4224 };4198 };
42254199