authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-10-26 00:30:17+03:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-10-27 21:08:25-04:00
logd03c47bf85b17f7727d2f1fe5bd497b311c9eba7
treefc2008e0adbee552fd72215614eefe7e111dbf5d
parent398a3aae40bc03f6b7c6cd86d78a4cde125f2811

Sema: use `runtime_value` instead of creating allocs


12 files changed, 126 insertions(+), 52 deletions(-)

src/Sema.zig+43-33
...@@ -1827,6 +1827,22 @@ fn resolveMaybeUndefValAllowVariables(...@@ -1827,6 +1827,22 @@ fn resolveMaybeUndefValAllowVariables(
1827 block: *Block,1827 block: *Block,
1828 src: LazySrcLoc,1828 src: LazySrcLoc,
1829 inst: Air.Inst.Ref,1829 inst: Air.Inst.Ref,
1830) CompileError!?Value {
1831 var make_runtime = false;
1832 if (try sema.resolveMaybeUndefValAllowVariablesMaybeRuntime(block, src, inst, &make_runtime)) |val| {
1833 if (make_runtime) return null;
1834 return val;
1835 }
1836 return null;
1837}
1838
1839/// Returns all Value tags including `variable`, `undef` and `runtime_value`.
1840fn resolveMaybeUndefValAllowVariablesMaybeRuntime(
1841 sema: *Sema,
1842 block: *Block,
1843 src: LazySrcLoc,
1844 inst: Air.Inst.Ref,
1845 make_runtime: *bool,
1830) CompileError!?Value {1846) CompileError!?Value {
1831 // First section of indexes correspond to a set number of constant values.1847 // First section of indexes correspond to a set number of constant values.
1832 var i: usize = @enumToInt(inst);1848 var i: usize = @enumToInt(inst);
...@@ -1843,7 +1859,7 @@ fn resolveMaybeUndefValAllowVariables(...@@ -1843,7 +1859,7 @@ fn resolveMaybeUndefValAllowVariables(
1843 .constant => {1859 .constant => {
1844 const ty_pl = sema.air_instructions.items(.data)[i].ty_pl;1860 const ty_pl = sema.air_instructions.items(.data)[i].ty_pl;
1845 const val = sema.air_values.items[ty_pl.payload];1861 const val = sema.air_values.items[ty_pl.payload];
1846 if (val.tag() == .runtime_int) return null;1862 if (val.tag() == .runtime_value) make_runtime.* = true;
1847 return val;1863 return val;
1848 },1864 },
1849 .const_ty => {1865 .const_ty => {
...@@ -3896,6 +3912,7 @@ fn validateUnionInit(...@@ -3896,6 +3912,7 @@ fn validateUnionInit(
3896 var first_block_index = block.instructions.items.len;3912 var first_block_index = block.instructions.items.len;
3897 var block_index = block.instructions.items.len - 1;3913 var block_index = block.instructions.items.len - 1;
3898 var init_val: ?Value = null;3914 var init_val: ?Value = null;
3915 var make_runtime = false;
3899 while (block_index > 0) : (block_index -= 1) {3916 while (block_index > 0) : (block_index -= 1) {
3900 const store_inst = block.instructions.items[block_index];3917 const store_inst = block.instructions.items[block_index];
3901 if (store_inst == field_ptr_air_inst) break;3918 if (store_inst == field_ptr_air_inst) break;
...@@ -3920,7 +3937,7 @@ fn validateUnionInit(...@@ -3920,7 +3937,7 @@ fn validateUnionInit(
3920 } else {3937 } else {
3921 first_block_index = @min(first_block_index, block_index);3938 first_block_index = @min(first_block_index, block_index);
3922 }3939 }
3923 init_val = try sema.resolveMaybeUndefValAllowVariables(block, init_src, bin_op.rhs);3940 init_val = try sema.resolveMaybeUndefValAllowVariablesMaybeRuntime(block, init_src, bin_op.rhs, &make_runtime);
3924 break;3941 break;
3925 }3942 }
39263943
...@@ -3933,10 +3950,11 @@ fn validateUnionInit(...@@ -3933,10 +3950,11 @@ fn validateUnionInit(
3933 // instead a single `store` to the result ptr with a comptime union value.3950 // instead a single `store` to the result ptr with a comptime union value.
3934 block.instructions.shrinkRetainingCapacity(first_block_index);3951 block.instructions.shrinkRetainingCapacity(first_block_index);
39353952
3936 const union_val = try Value.Tag.@"union".create(sema.arena, .{3953 var union_val = try Value.Tag.@"union".create(sema.arena, .{
3937 .tag = tag_val,3954 .tag = tag_val,
3938 .val = val,3955 .val = val,
3939 });3956 });
3957 if (make_runtime) union_val = try Value.Tag.runtime_value.create(sema.arena, union_val);
3940 const union_init = try sema.addConstant(union_ty, union_val);3958 const union_init = try sema.addConstant(union_ty, union_val);
3941 try sema.storePtr2(block, init_src, union_ptr, init_src, union_init, init_src, .store);3959 try sema.storePtr2(block, init_src, union_ptr, init_src, union_init, init_src, .store);
3942 return;3960 return;
...@@ -4054,6 +4072,7 @@ fn validateStructInit(...@@ -4054,6 +4072,7 @@ fn validateStructInit(
40544072
4055 var struct_is_comptime = true;4073 var struct_is_comptime = true;
4056 var first_block_index = block.instructions.items.len;4074 var first_block_index = block.instructions.items.len;
4075 var make_runtime = false;
40574076
4058 const air_tags = sema.air_instructions.items(.tag);4077 const air_tags = sema.air_instructions.items(.tag);
4059 const air_datas = sema.air_instructions.items(.data);4078 const air_datas = sema.air_instructions.items(.data);
...@@ -4130,7 +4149,7 @@ fn validateStructInit(...@@ -4130,7 +4149,7 @@ fn validateStructInit(
4130 } else {4149 } else {
4131 first_block_index = @min(first_block_index, block_index);4150 first_block_index = @min(first_block_index, block_index);
4132 }4151 }
4133 if (try sema.resolveMaybeUndefValAllowVariables(block, field_src, bin_op.rhs)) |val| {4152 if (try sema.resolveMaybeUndefValAllowVariablesMaybeRuntime(block, field_src, bin_op.rhs, &make_runtime)) |val| {
4134 field_values[i] = val;4153 field_values[i] = val;
4135 } else {4154 } else {
4136 struct_is_comptime = false;4155 struct_is_comptime = false;
...@@ -4185,7 +4204,8 @@ fn validateStructInit(...@@ -4185,7 +4204,8 @@ fn validateStructInit(
4185 // instead a single `store` to the struct_ptr with a comptime struct value.4204 // instead a single `store` to the struct_ptr with a comptime struct value.
41864205
4187 block.instructions.shrinkRetainingCapacity(first_block_index);4206 block.instructions.shrinkRetainingCapacity(first_block_index);
4188 const struct_val = try Value.Tag.aggregate.create(sema.arena, field_values);4207 var struct_val = try Value.Tag.aggregate.create(sema.arena, field_values);
4208 if (make_runtime) struct_val = try Value.Tag.runtime_value.create(sema.arena, struct_val);
4189 const struct_init = try sema.addConstant(struct_ty, struct_val);4209 const struct_init = try sema.addConstant(struct_ty, struct_val);
4190 try sema.storePtr2(block, init_src, struct_ptr, init_src, struct_init, init_src, .store);4210 try sema.storePtr2(block, init_src, struct_ptr, init_src, struct_init, init_src, .store);
4191 return;4211 return;
...@@ -4265,6 +4285,7 @@ fn zirValidateArrayInit(...@@ -4265,6 +4285,7 @@ fn zirValidateArrayInit(
42654285
4266 var array_is_comptime = true;4286 var array_is_comptime = true;
4267 var first_block_index = block.instructions.items.len;4287 var first_block_index = block.instructions.items.len;
4288 var make_runtime = false;
42684289
4269 // Collect the comptime element values in case the array literal ends up4290 // Collect the comptime element values in case the array literal ends up
4270 // being comptime-known.4291 // being comptime-known.
...@@ -4326,7 +4347,7 @@ fn zirValidateArrayInit(...@@ -4326,7 +4347,7 @@ fn zirValidateArrayInit(
4326 array_is_comptime = false;4347 array_is_comptime = false;
4327 continue;4348 continue;
4328 }4349 }
4329 if (try sema.resolveMaybeUndefValAllowVariables(block, elem_src, bin_op.rhs)) |val| {4350 if (try sema.resolveMaybeUndefValAllowVariablesMaybeRuntime(block, elem_src, bin_op.rhs, &make_runtime)) |val| {
4330 element_vals[i] = val;4351 element_vals[i] = val;
4331 } else {4352 } else {
4332 array_is_comptime = false;4353 array_is_comptime = false;
...@@ -4352,7 +4373,7 @@ fn zirValidateArrayInit(...@@ -4352,7 +4373,7 @@ fn zirValidateArrayInit(
4352 array_is_comptime = false;4373 array_is_comptime = false;
4353 continue;4374 continue;
4354 }4375 }
4355 if (try sema.resolveMaybeUndefValAllowVariables(block, elem_src, bin_op.rhs)) |val| {4376 if (try sema.resolveMaybeUndefValAllowVariablesMaybeRuntime(block, elem_src, bin_op.rhs, &make_runtime)) |val| {
4356 element_vals[i] = val;4377 element_vals[i] = val;
4357 } else {4378 } else {
4358 array_is_comptime = false;4379 array_is_comptime = false;
...@@ -4383,7 +4404,8 @@ fn zirValidateArrayInit(...@@ -4383,7 +4404,8 @@ fn zirValidateArrayInit(
43834404
4384 block.instructions.shrinkRetainingCapacity(first_block_index);4405 block.instructions.shrinkRetainingCapacity(first_block_index);
43854406
4386 const array_val = try Value.Tag.aggregate.create(sema.arena, element_vals);4407 var array_val = try Value.Tag.aggregate.create(sema.arena, element_vals);
4408 if (make_runtime) array_val = try Value.Tag.runtime_value.create(sema.arena, array_val);
4387 const array_init = try sema.addConstant(array_ty, array_val);4409 const array_init = try sema.addConstant(array_ty, array_val);
4388 try sema.storePtr2(block, init_src, array_ptr, init_src, array_init, init_src, .store);4410 try sema.storePtr2(block, init_src, array_ptr, init_src, array_init, init_src, .store);
4389 }4411 }
...@@ -6635,20 +6657,14 @@ fn analyzeInlineCallArg(...@@ -6635,20 +6657,14 @@ fn analyzeInlineCallArg(
6635 .ty = param_ty,6657 .ty = param_ty,
6636 .val = arg_val,6658 .val = arg_val,
6637 };6659 };
6638 } else if (((try sema.resolveMaybeUndefVal(arg_block, arg_src, casted_arg)) == null) or6660 } else if (zir_tags[inst] == .param_comptime or try sema.typeRequiresComptime(param_ty)) {
6639 try sema.typeRequiresComptime(param_ty) or zir_tags[inst] == .param_comptime)
6640 {
6641 try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg);6661 try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg);
6642 } else {6662 } else if (try sema.resolveMaybeUndefVal(arg_block, arg_src, casted_arg)) |val| {
6643 // We have a comptime value but we need a runtime value to preserve inlining semantics,6663 // We have a comptime value but we need a runtime value to preserve inlining semantics,
6644 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{6664 const wrapped = try sema.addConstant(param_ty, try Value.Tag.runtime_value.create(sema.arena, val));
6645 .pointee_type = param_ty,6665 try sema.inst_map.putNoClobber(sema.gpa, inst, wrapped);
6646 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local),6666 } else {
6647 });6667 try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg);
6648 const alloc = try arg_block.addTy(.alloc, ptr_type);
6649 _ = try arg_block.addBinOp(.store, alloc, casted_arg);
6650 const loaded = try arg_block.addTyOp(.load, param_ty, alloc);
6651 try sema.inst_map.putNoClobber(sema.gpa, inst, loaded);
6652 }6668 }
66536669
6654 arg_i.* += 1;6670 arg_i.* += 1;
...@@ -6685,20 +6701,14 @@ fn analyzeInlineCallArg(...@@ -6685,20 +6701,14 @@ fn analyzeInlineCallArg(
6685 .ty = sema.typeOf(uncasted_arg),6701 .ty = sema.typeOf(uncasted_arg),
6686 .val = arg_val,6702 .val = arg_val,
6687 };6703 };
6688 } else if ((try sema.resolveMaybeUndefVal(arg_block, arg_src, uncasted_arg)) == null or6704 } else if (zir_tags[inst] == .param_anytype_comptime or try sema.typeRequiresComptime(param_ty)) {
6689 try sema.typeRequiresComptime(param_ty) or zir_tags[inst] == .param_anytype_comptime)
6690 {
6691 try sema.inst_map.putNoClobber(sema.gpa, inst, uncasted_arg);6705 try sema.inst_map.putNoClobber(sema.gpa, inst, uncasted_arg);
6692 } else {6706 } else if (try sema.resolveMaybeUndefVal(arg_block, arg_src, uncasted_arg)) |val| {
6693 // We have a comptime value but we need a runtime value to preserve inlining semantics,6707 // We have a comptime value but we need a runtime value to preserve inlining semantics,
6694 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{6708 const wrapped = try sema.addConstant(param_ty, try Value.Tag.runtime_value.create(sema.arena, val));
6695 .pointee_type = param_ty,6709 try sema.inst_map.putNoClobber(sema.gpa, inst, wrapped);
6696 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local),6710 } else {
6697 });6711 try sema.inst_map.putNoClobber(sema.gpa, inst, uncasted_arg);
6698 const alloc = try arg_block.addTy(.alloc, ptr_type);
6699 _ = try arg_block.addBinOp(.store, alloc, uncasted_arg);
6700 const loaded = try arg_block.addTyOp(.load, param_ty, alloc);
6701 try sema.inst_map.putNoClobber(sema.gpa, inst, loaded);
6702 }6712 }
67036713
6704 arg_i.* += 1;6714 arg_i.* += 1;
...@@ -14826,7 +14836,7 @@ fn zirBuiltinSrc(...@@ -14826,7 +14836,7 @@ fn zirBuiltinSrc(
14826 // fn_name: [:0]const u8,14836 // fn_name: [:0]const u8,
14827 field_values[1] = func_name_val;14837 field_values[1] = func_name_val;
14828 // line: u3214838 // line: u32
14829 field_values[2] = try Value.Tag.runtime_int.create(sema.arena, extra.line + 1);14839 field_values[2] = try Value.Tag.runtime_value.create(sema.arena, try Value.Tag.int_u64.create(sema.arena, extra.line + 1));
14830 // column: u32,14840 // column: u32,
14831 field_values[3] = try Value.Tag.int_u64.create(sema.arena, extra.column + 1);14841 field_values[3] = try Value.Tag.int_u64.create(sema.arena, extra.column + 1);
1483214842
src/TypedValue.zig+1-1
...@@ -477,6 +477,6 @@ pub fn print(...@@ -477,6 +477,6 @@ pub fn print(
477 },477 },
478 .generic_poison_type => return writer.writeAll("(generic poison type)"),478 .generic_poison_type => return writer.writeAll("(generic poison type)"),
479 .generic_poison => return writer.writeAll("(generic poison)"),479 .generic_poison => return writer.writeAll("(generic poison)"),
480 .runtime_int => return writer.writeAll("[runtime value]"),480 .runtime_value => return writer.writeAll("[runtime value]"),
481 };481 };
482}482}
src/arch/aarch64/CodeGen.zig+5-1
...@@ -5401,7 +5401,11 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {...@@ -5401,7 +5401,11 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {
5401 }5401 }
5402}5402}
54035403
5404fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {5404fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
5405 var typed_value = arg_tv;
5406 if (typed_value.val.castTag(.runtime_value)) |rt| {
5407 typed_value.val = rt.data;
5408 }
5405 log.debug("genTypedValue: ty = {}, val = {}", .{ typed_value.ty.fmtDebug(), typed_value.val.fmtDebug() });5409 log.debug("genTypedValue: ty = {}, val = {}", .{ typed_value.ty.fmtDebug(), typed_value.val.fmtDebug() });
5406 if (typed_value.val.isUndef())5410 if (typed_value.val.isUndef())
5407 return MCValue{ .undef = {} };5411 return MCValue{ .undef = {} };
src/arch/arm/CodeGen.zig+5-1
...@@ -6047,7 +6047,11 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {...@@ -6047,7 +6047,11 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {
6047 }6047 }
6048}6048}
60496049
6050fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {6050fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
6051 var typed_value = arg_tv;
6052 if (typed_value.val.castTag(.runtime_value)) |rt| {
6053 typed_value.val = rt.data;
6054 }
6051 log.debug("genTypedValue: ty = {}, val = {}", .{ typed_value.ty.fmtDebug(), typed_value.val.fmtDebug() });6055 log.debug("genTypedValue: ty = {}, val = {}", .{ typed_value.ty.fmtDebug(), typed_value.val.fmtDebug() });
6052 if (typed_value.val.isUndef())6056 if (typed_value.val.isUndef())
6053 return MCValue{ .undef = {} };6057 return MCValue{ .undef = {} };
src/arch/wasm/CodeGen.zig+5-1
...@@ -2582,7 +2582,11 @@ fn toTwosComplement(value: anytype, bits: u7) std.meta.Int(.unsigned, @typeInfo(...@@ -2582,7 +2582,11 @@ fn toTwosComplement(value: anytype, bits: u7) std.meta.Int(.unsigned, @typeInfo(
2582 return @intCast(WantedT, result);2582 return @intCast(WantedT, result);
2583}2583}
25842584
2585fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {2585fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
2586 var val = arg_val;
2587 if (val.castTag(.runtime_value)) |rt| {
2588 val = rt.data;
2589 }
2586 if (val.isUndefDeep()) return func.emitUndefined(ty);2590 if (val.isUndefDeep()) return func.emitUndefined(ty);
2587 if (val.castTag(.decl_ref)) |decl_ref| {2591 if (val.castTag(.decl_ref)) |decl_ref| {
2588 const decl_index = decl_ref.data;2592 const decl_index = decl_ref.data;
src/arch/x86_64/CodeGen.zig+5-1
...@@ -6960,7 +6960,11 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {...@@ -6960,7 +6960,11 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {
6960 }6960 }
6961}6961}
69626962
6963fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {6963fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
6964 var typed_value = arg_tv;
6965 if (typed_value.val.castTag(.runtime_value)) |rt| {
6966 typed_value.val = rt.data;
6967 }
6964 log.debug("genTypedValue: ty = {}, val = {}", .{ typed_value.ty.fmtDebug(), typed_value.val.fmtDebug() });6968 log.debug("genTypedValue: ty = {}, val = {}", .{ typed_value.ty.fmtDebug(), typed_value.val.fmtDebug() });
6965 if (typed_value.val.isUndef())6969 if (typed_value.val.isUndef())
6966 return MCValue{ .undef = {} };6970 return MCValue{ .undef = {} };
src/codegen.zig+6-1
...@@ -149,7 +149,7 @@ fn writeFloat(comptime F: type, f: F, target: Target, endian: std.builtin.Endian...@@ -149,7 +149,7 @@ fn writeFloat(comptime F: type, f: F, target: Target, endian: std.builtin.Endian
149pub fn generateSymbol(149pub fn generateSymbol(
150 bin_file: *link.File,150 bin_file: *link.File,
151 src_loc: Module.SrcLoc,151 src_loc: Module.SrcLoc,
152 typed_value: TypedValue,152 arg_tv: TypedValue,
153 code: *std.ArrayList(u8),153 code: *std.ArrayList(u8),
154 debug_output: DebugInfoOutput,154 debug_output: DebugInfoOutput,
155 reloc_info: RelocInfo,155 reloc_info: RelocInfo,
...@@ -157,6 +157,11 @@ pub fn generateSymbol(...@@ -157,6 +157,11 @@ pub fn generateSymbol(
157 const tracy = trace(@src());157 const tracy = trace(@src());
158 defer tracy.end();158 defer tracy.end();
159159
160 var typed_value = arg_tv;
161 if (arg_tv.val.castTag(.runtime_value)) |rt| {
162 typed_value.val = rt.data;
163 }
164
160 const target = bin_file.options.target;165 const target = bin_file.options.target;
161 const endian = target.cpu.arch.endian();166 const endian = target.cpu.arch.endian();
162167
src/codegen/c.zig+5-1
...@@ -555,9 +555,13 @@ pub const DeclGen = struct {...@@ -555,9 +555,13 @@ pub const DeclGen = struct {
555 dg: *DeclGen,555 dg: *DeclGen,
556 writer: anytype,556 writer: anytype,
557 ty: Type,557 ty: Type,
558 val: Value,558 arg_val: Value,
559 location: ValueRenderLocation,559 location: ValueRenderLocation,
560 ) error{ OutOfMemory, AnalysisFail }!void {560 ) error{ OutOfMemory, AnalysisFail }!void {
561 var val = arg_val;
562 if (val.castTag(.runtime_value)) |rt| {
563 val = rt.data;
564 }
561 const target = dg.module.getTarget();565 const target = dg.module.getTarget();
562 if (val.isUndefDeep()) {566 if (val.isUndefDeep()) {
563 switch (ty.zigTypeTag()) {567 switch (ty.zigTypeTag()) {
src/codegen/llvm.zig+5-1
...@@ -3187,7 +3187,11 @@ pub const DeclGen = struct {...@@ -3187,7 +3187,11 @@ pub const DeclGen = struct {
3187 return llvm_elem_ty;3187 return llvm_elem_ty;
3188 }3188 }
31893189
3190 fn lowerValue(dg: *DeclGen, tv: TypedValue) Error!*llvm.Value {3190 fn lowerValue(dg: *DeclGen, arg_tv: TypedValue) Error!*llvm.Value {
3191 var tv = arg_tv;
3192 if (tv.val.castTag(.runtime_value)) |rt| {
3193 tv.val = rt.data;
3194 }
3191 if (tv.val.isUndef()) {3195 if (tv.val.isUndef()) {
3192 const llvm_type = try dg.lowerType(tv.ty);3196 const llvm_type = try dg.lowerType(tv.ty);
3193 return llvm_type.getUndef();3197 return llvm_type.getUndef();
src/value.zig+8-11
...@@ -111,10 +111,12 @@ pub const Value = extern union {...@@ -111,10 +111,12 @@ pub const Value = extern union {
111 int_i64,111 int_i64,
112 int_big_positive,112 int_big_positive,
113 int_big_negative,113 int_big_negative,
114 runtime_int,
115 function,114 function,
116 extern_fn,115 extern_fn,
117 variable,116 variable,
117 /// A wrapper for values which are comptime-known but should
118 /// semantically be runtime-known.
119 runtime_value,
118 /// Represents a pointer to a Decl.120 /// Represents a pointer to a Decl.
119 /// When machine codegen backend sees this, it must set the Decl's `alive` field to true.121 /// When machine codegen backend sees this, it must set the Decl's `alive` field to true.
120 decl_ref,122 decl_ref,
...@@ -282,6 +284,7 @@ pub const Value = extern union {...@@ -282,6 +284,7 @@ pub const Value = extern union {
282 .eu_payload,284 .eu_payload,
283 .opt_payload,285 .opt_payload,
284 .empty_array_sentinel,286 .empty_array_sentinel,
287 .runtime_value,
285 => Payload.SubValue,288 => Payload.SubValue,
286289
287 .eu_payload_ptr,290 .eu_payload_ptr,
...@@ -305,7 +308,6 @@ pub const Value = extern union {...@@ -305,7 +308,6 @@ pub const Value = extern union {
305 .int_type => Payload.IntType,308 .int_type => Payload.IntType,
306 .int_u64 => Payload.U64,309 .int_u64 => Payload.U64,
307 .int_i64 => Payload.I64,310 .int_i64 => Payload.I64,
308 .runtime_int => Payload.U64,
309 .function => Payload.Function,311 .function => Payload.Function,
310 .variable => Payload.Variable,312 .variable => Payload.Variable,
311 .decl_ref_mut => Payload.DeclRefMut,313 .decl_ref_mut => Payload.DeclRefMut,
...@@ -485,7 +487,6 @@ pub const Value = extern union {...@@ -485,7 +487,6 @@ pub const Value = extern union {
485 },487 },
486 .int_type => return self.copyPayloadShallow(arena, Payload.IntType),488 .int_type => return self.copyPayloadShallow(arena, Payload.IntType),
487 .int_u64 => return self.copyPayloadShallow(arena, Payload.U64),489 .int_u64 => return self.copyPayloadShallow(arena, Payload.U64),
488 .runtime_int => return self.copyPayloadShallow(arena, Payload.U64),
489 .int_i64 => return self.copyPayloadShallow(arena, Payload.I64),490 .int_i64 => return self.copyPayloadShallow(arena, Payload.I64),
490 .int_big_positive, .int_big_negative => {491 .int_big_positive, .int_big_negative => {
491 const old_payload = self.cast(Payload.BigInt).?;492 const old_payload = self.cast(Payload.BigInt).?;
...@@ -567,6 +568,7 @@ pub const Value = extern union {...@@ -567,6 +568,7 @@ pub const Value = extern union {
567 .eu_payload,568 .eu_payload,
568 .opt_payload,569 .opt_payload,
569 .empty_array_sentinel,570 .empty_array_sentinel,
571 .runtime_value,
570 => {572 => {
571 const payload = self.cast(Payload.SubValue).?;573 const payload = self.cast(Payload.SubValue).?;
572 const new_payload = try arena.create(Payload.SubValue);574 const new_payload = try arena.create(Payload.SubValue);
...@@ -765,7 +767,7 @@ pub const Value = extern union {...@@ -765,7 +767,7 @@ pub const Value = extern union {
765 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", options, out_stream),767 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", options, out_stream),
766 .int_big_positive => return out_stream.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),768 .int_big_positive => return out_stream.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),
767 .int_big_negative => return out_stream.print("{}", .{val.castTag(.int_big_negative).?.asBigInt()}),769 .int_big_negative => return out_stream.print("{}", .{val.castTag(.int_big_negative).?.asBigInt()}),
768 .runtime_int => return out_stream.writeAll("[runtime value]"),770 .runtime_value => return out_stream.writeAll("[runtime value]"),
769 .function => return out_stream.print("(function decl={d})", .{val.castTag(.function).?.data.owner_decl}),771 .function => return out_stream.print("(function decl={d})", .{val.castTag(.function).?.data.owner_decl}),
770 .extern_fn => return out_stream.writeAll("(extern function)"),772 .extern_fn => return out_stream.writeAll("(extern function)"),
771 .variable => return out_stream.writeAll("(variable)"),773 .variable => return out_stream.writeAll("(variable)"),
...@@ -1081,8 +1083,6 @@ pub const Value = extern union {...@@ -1081,8 +1083,6 @@ pub const Value = extern union {
1081 .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt(),1083 .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt(),
1082 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt(),1084 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt(),
10831085
1084 .runtime_int => return BigIntMutable.init(&space.limbs, val.castTag(.runtime_int).?.data).toConst(),
1085
1086 .undef => unreachable,1086 .undef => unreachable,
10871087
1088 .lazy_align => {1088 .lazy_align => {
...@@ -1138,8 +1138,6 @@ pub const Value = extern union {...@@ -1138,8 +1138,6 @@ pub const Value = extern union {
1138 .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt().to(u64) catch null,1138 .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt().to(u64) catch null,
1139 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(u64) catch null,1139 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(u64) catch null,
11401140
1141 .runtime_int => return val.castTag(.runtime_int).?.data,
1142
1143 .undef => unreachable,1141 .undef => unreachable,
11441142
1145 .lazy_align => {1143 .lazy_align => {
...@@ -2357,6 +2355,8 @@ pub const Value = extern union {...@@ -2357,6 +2355,8 @@ pub const Value = extern union {
2357 const zig_ty_tag = ty.zigTypeTag();2355 const zig_ty_tag = ty.zigTypeTag();
2358 std.hash.autoHash(hasher, zig_ty_tag);2356 std.hash.autoHash(hasher, zig_ty_tag);
2359 if (val.isUndef()) return;2357 if (val.isUndef()) return;
2358 // The value is runtime-known and shouldn't affect the hash.
2359 if (val.tag() == .runtime_value) return;
23602360
2361 switch (zig_ty_tag) {2361 switch (zig_ty_tag) {
2362 .BoundFn => unreachable, // TODO remove this from the language2362 .BoundFn => unreachable, // TODO remove this from the language
...@@ -2632,9 +2632,6 @@ pub const Value = extern union {...@@ -2632,9 +2632,6 @@ pub const Value = extern union {
2632 .lazy_size,2632 .lazy_size,
2633 => return hashInt(ptr_val, hasher, target),2633 => return hashInt(ptr_val, hasher, target),
26342634
2635 // The value is runtime-known and shouldn't affect the hash.
2636 .runtime_int => {},
2637
2638 else => unreachable,2635 else => unreachable,
2639 }2636 }
2640 }2637 }
test/behavior/bugs/13164.zig+1
...@@ -10,6 +10,7 @@ inline fn setLimits(min: ?u32, max: ?u32) !void {...@@ -10,6 +10,7 @@ inline fn setLimits(min: ?u32, max: ?u32) !void {
10test {10test {
11 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO11 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
12 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO12 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1314
14 var x: u32 = 42;15 var x: u32 = 42;
15 try setLimits(x, null);16 try setLimits(x, null);
test/behavior/vector.zig+37
...@@ -1135,3 +1135,40 @@ test "array of vectors is copied" {...@@ -1135,3 +1135,40 @@ test "array of vectors is copied" {
1135 points2[0..points.len].* = points;1135 points2[0..points.len].* = points;
1136 try std.testing.expectEqual(points2[6], Vec3{ -345, -311, 381 });1136 try std.testing.expectEqual(points2[6], Vec3{ -345, -311, 381 });
1137}1137}
1138
1139test "byte vector initialized in inline function" {
1140 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1141 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1142 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1143 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1144 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1145
1146 const S = struct {
1147 inline fn boolx4(e0: bool, e1: bool, e2: bool, e3: bool) @Vector(4, bool) {
1148 return .{ e0, e1, e2, e3 };
1149 }
1150
1151 fn all(vb: @Vector(4, bool)) bool {
1152 return @reduce(.And, vb);
1153 }
1154 };
1155
1156 try expect(S.all(S.boolx4(true, true, true, true)));
1157}
1158
1159test "byte vector initialized in inline function" {
1160 // TODO https://github.com/ziglang/zig/issues/13279
1161 if (true) return error.SkipZigTest;
1162
1163 const S = struct {
1164 fn boolx4(e0: bool, e1: bool, e2: bool, e3: bool) @Vector(4, bool) {
1165 return .{ e0, e1, e2, e3 };
1166 }
1167
1168 fn all(vb: @Vector(4, bool)) bool {
1169 return @reduce(.And, vb);
1170 }
1171 };
1172
1173 try expect(S.all(S.boolx4(true, true, true, true)));
1174}