authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-13 21:49:22-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-20 12:19:16-07:00
logdbd3529d1fa02d5e720df0fbf2436d646f5a4f57
treeb75125e6b9847fe962c69550ae9e9e9ce9169e79
parentf17a05bfb7ca0ff010fef9654264eed7342298d2

Sema: first pass reworking for AIR memory layout


3 files changed, 286 insertions(+), 297 deletions(-)

BRANCH_TODO-89
...@@ -569,95 +569,6 @@ const DumpAir = struct {...@@ -569,95 +569,6 @@ const DumpAir = struct {
569 }569 }
570};570};
571571
572pub fn constInst(mod: *Module, arena: *Allocator, src: LazySrcLoc, typed_value: TypedValue) !*ir.Inst {
573 _ = mod;
574 const const_inst = try arena.create(ir.Inst.Constant);
575 const_inst.* = .{
576 .base = .{
577 .tag = ir.Inst.Constant.base_tag,
578 .ty = typed_value.ty,
579 .src = src,
580 },
581 .val = typed_value.val,
582 };
583 return &const_inst.base;
584}
585
586pub fn constType(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type) !*ir.Inst {
587 return mod.constInst(arena, src, .{
588 .ty = Type.initTag(.type),
589 .val = try ty.toValue(arena),
590 });
591}
592
593pub fn constVoid(mod: *Module, arena: *Allocator, src: LazySrcLoc) !*ir.Inst {
594 return mod.constInst(arena, src, .{
595 .ty = Type.initTag(.void),
596 .val = Value.initTag(.void_value),
597 });
598}
599
600pub fn constNoReturn(mod: *Module, arena: *Allocator, src: LazySrcLoc) !*ir.Inst {
601 return mod.constInst(arena, src, .{
602 .ty = Type.initTag(.noreturn),
603 .val = Value.initTag(.unreachable_value),
604 });
605}
606
607pub fn constUndef(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type) !*ir.Inst {
608 return mod.constInst(arena, src, .{
609 .ty = ty,
610 .val = Value.initTag(.undef),
611 });
612}
613
614pub fn constBool(mod: *Module, arena: *Allocator, src: LazySrcLoc, v: bool) !*ir.Inst {
615 return mod.constInst(arena, src, .{
616 .ty = Type.initTag(.bool),
617 .val = ([2]Value{ Value.initTag(.bool_false), Value.initTag(.bool_true) })[@boolToInt(v)],
618 });
619}
620
621pub fn constIntUnsigned(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type, int: u64) !*ir.Inst {
622 return mod.constInst(arena, src, .{
623 .ty = ty,
624 .val = try Value.Tag.int_u64.create(arena, int),
625 });
626}
627
628pub fn constIntSigned(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type, int: i64) !*ir.Inst {
629 return mod.constInst(arena, src, .{
630 .ty = ty,
631 .val = try Value.Tag.int_i64.create(arena, int),
632 });
633}
634
635pub fn constIntBig(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type, big_int: BigIntConst) !*ir.Inst {
636 if (big_int.positive) {
637 if (big_int.to(u64)) |x| {
638 return mod.constIntUnsigned(arena, src, ty, x);
639 } else |err| switch (err) {
640 error.NegativeIntoUnsigned => unreachable,
641 error.TargetTooSmall => {}, // handled below
642 }
643 return mod.constInst(arena, src, .{
644 .ty = ty,
645 .val = try Value.Tag.int_big_positive.create(arena, big_int.limbs),
646 });
647 } else {
648 if (big_int.to(i64)) |x| {
649 return mod.constIntSigned(arena, src, ty, x);
650 } else |err| switch (err) {
651 error.NegativeIntoUnsigned => unreachable,
652 error.TargetTooSmall => {}, // handled below
653 }
654 return mod.constInst(arena, src, .{
655 .ty = ty,
656 .val = try Value.Tag.int_big_negative.create(arena, big_int.limbs),
657 });
658 }
659}
660
661pub fn dumpInst(mod: *Module, scope: *Scope, inst: *ir.Inst) void {572pub fn dumpInst(mod: *Module, scope: *Scope, inst: *ir.Inst) void {
662 const zir_module = scope.namespace();573 const zir_module = scope.namespace();
663 const source = zir_module.getSource(mod) catch @panic("dumpInst failed to get source");574 const source = zir_module.getSource(mod) catch @panic("dumpInst failed to get source");
src/Module.zig+40-10
...@@ -1232,22 +1232,52 @@ pub const Scope = struct {...@@ -1232,22 +1232,52 @@ pub const Scope = struct {
1232 ty: Type,1232 ty: Type,
1233 operand: Air.Inst.Ref,1233 operand: Air.Inst.Ref,
1234 ) error{OutOfMemory}!Air.Inst.Ref {1234 ) error{OutOfMemory}!Air.Inst.Ref {
1235 return block.addInst(.{
1236 .tag = tag,
1237 .data = .{ .ty_op = .{
1238 .ty = try block.sema.addType(ty),
1239 .operand = operand,
1240 } },
1241 });
1242 }
1243
1244 pub fn addUnOp(
1245 block: *Block,
1246 tag: Air.Inst.Tag,
1247 operand: Air.Inst.Ref,
1248 ) error{OutOfMemory}!Air.Inst.Ref {
1249 return block.addInst(.{
1250 .tag = tag,
1251 .data = .{ .un_op = operand },
1252 });
1253 }
1254
1255 pub fn addBinOp(
1256 block: *Block,
1257 tag: Air.Inst.Tag,
1258 lhs: Air.Inst.Ref,
1259 rhs: Air.Inst.Ref,
1260 ) error{OutOfMemory}!Air.Inst.Ref {
1261 return block.addInst(.{
1262 .tag = tag,
1263 .data = .{ .bin_op = .{
1264 .lhs = lhs,
1265 .rhs = rhs,
1266 } },
1267 });
1268 }
1269
1270 pub fn addInst(block: *Block, inst: Air.Inst) error{OutOfMemory}!Air.Inst.Ref {
1235 const sema = block.sema;1271 const sema = block.sema;
1236 const gpa = sema.gpa;1272 const gpa = sema.gpa;
12371273
1238 try sema.air_instructions.ensureUnusedCapacity(gpa, 1);1274 try sema.air_instructions.ensureUnusedCapacity(gpa, 1);
1239 try block.instructions.ensureUnusedCapacity(gpa, 1);1275 try block.instructions.ensureUnusedCapacity(gpa, 1);
12401276
1241 const inst = @intCast(Air.Inst.Index, sema.air_instructions.len);1277 const result_index = @intCast(Air.Inst.Index, sema.air_instructions.len);
1242 sema.air_instructions.appendAssumeCapacity(.{1278 sema.air_instructions.appendAssumeCapacity(inst);
1243 .tag = tag,1279 block.instructions.appendAssumeCapacity(result_index);
1244 .data = .{ .ty_op = .{1280 return Sema.indexToRef(result_index);
1245 .ty = try sema.addType(ty),
1246 .operand = operand,
1247 } },
1248 });
1249 block.instructions.appendAssumeCapacity(inst);
1250 return Sema.indexToRef(inst);
1251 }1281 }
1252 };1282 };
1253};1283};
src/Sema.zig+246-198
...@@ -534,7 +534,7 @@ pub fn analyzeBody(...@@ -534,7 +534,7 @@ pub fn analyzeBody(
534 //},534 //},
535 else => @panic("TODO finish updating Sema for AIR memory layout changes and then remove this else prong"),535 else => @panic("TODO finish updating Sema for AIR memory layout changes and then remove this else prong"),
536 };536 };
537 if (sema.getAirType(air_inst).isNoReturn())537 if (sema.getTypeOf(air_inst).isNoReturn())
538 return always_noreturn;538 return always_noreturn;
539 try map.put(sema.gpa, inst, air_inst);539 try map.put(sema.gpa, inst, air_inst);
540 i += 1;540 i += 1;
...@@ -664,7 +664,7 @@ fn resolvePossiblyUndefinedValue(...@@ -664,7 +664,7 @@ fn resolvePossiblyUndefinedValue(
664 src: LazySrcLoc,664 src: LazySrcLoc,
665 air_ref: Air.Inst.Ref,665 air_ref: Air.Inst.Ref,
666) !?Value {666) !?Value {
667 const ty = sema.getTypeOfAirRef(air_ref);667 const ty = sema.getTypeOf(air_ref);
668 if (try sema.typeHasOnePossibleValue(block, src, ty)) |opv| {668 if (try sema.typeHasOnePossibleValue(block, src, ty)) |opv| {
669 return opv;669 return opv;
670 }670 }
...@@ -737,7 +737,7 @@ pub fn resolveInstConst(...@@ -737,7 +737,7 @@ pub fn resolveInstConst(
737 const air_ref = sema.resolveInst(zir_ref);737 const air_ref = sema.resolveInst(zir_ref);
738 const val = try sema.resolveConstValue(block, src, air_ref);738 const val = try sema.resolveConstValue(block, src, air_ref);
739 return TypedValue{739 return TypedValue{
740 .ty = sema.getTypeOfAirRef(air_ref),740 .ty = sema.getTypeOf(air_ref),
741 .val = val,741 .val = val,
742 };742 };
743}743}
...@@ -1208,7 +1208,7 @@ fn zirRetType(...@@ -1208,7 +1208,7 @@ fn zirRetType(
1208 try sema.requireFunctionBlock(block, src);1208 try sema.requireFunctionBlock(block, src);
1209 const fn_ty = sema.func.?.owner_decl.ty;1209 const fn_ty = sema.func.?.owner_decl.ty;
1210 const ret_type = fn_ty.fnReturnType();1210 const ret_type = fn_ty.fnReturnType();
1211 return sema.mod.constType(sema.arena, src, ret_type);1211 return sema.addType(ret_type);
1212}1212}
12131213
1214fn zirEnsureResultUsed(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void {1214fn zirEnsureResultUsed(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void {
...@@ -1571,7 +1571,7 @@ fn zirStoreToBlockPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) In...@@ -1571,7 +1571,7 @@ fn zirStoreToBlockPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) In
1571 // if expressions should force it when the condition is compile-time known.1571 // if expressions should force it when the condition is compile-time known.
1572 const src: LazySrcLoc = .unneeded;1572 const src: LazySrcLoc = .unneeded;
1573 try sema.requireRuntimeBlock(block, src);1573 try sema.requireRuntimeBlock(block, src);
1574 const bitcasted_ptr = try block.addUnOp(src, ptr_ty, .bitcast, ptr);1574 const bitcasted_ptr = try block.addTyOp(.bitcast, ptr_ty, ptr);
1575 return sema.storePtr(block, src, bitcasted_ptr, value);1575 return sema.storePtr(block, src, bitcasted_ptr, value);
1576}1576}
15771577
...@@ -1590,7 +1590,7 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index)...@@ -1590,7 +1590,7 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index)
1590 // Create a runtime bitcast instruction with exactly the type the pointer wants.1590 // Create a runtime bitcast instruction with exactly the type the pointer wants.
1591 const ptr_ty = try Module.simplePtrType(sema.arena, value.ty, true, .One);1591 const ptr_ty = try Module.simplePtrType(sema.arena, value.ty, true, .One);
1592 try sema.requireRuntimeBlock(block, src);1592 try sema.requireRuntimeBlock(block, src);
1593 const bitcasted_ptr = try block.addUnOp(src, ptr_ty, .bitcast, ptr);1593 const bitcasted_ptr = try block.addTyOp(.bitcast, ptr_ty, ptr);
1594 return sema.storePtr(block, src, bitcasted_ptr, value);1594 return sema.storePtr(block, src, bitcasted_ptr, value);
1595}1595}
15961596
...@@ -1646,7 +1646,7 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr...@@ -1646,7 +1646,7 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr
1646 const param_count = fn_ty.fnParamLen();1646 const param_count = fn_ty.fnParamLen();
1647 if (param_index >= param_count) {1647 if (param_index >= param_count) {
1648 if (fn_ty.fnIsVarArgs()) {1648 if (fn_ty.fnIsVarArgs()) {
1649 return sema.mod.constType(sema.arena, src, Type.initTag(.var_args_param));1649 return sema.addType(Type.initTag(.var_args_param));
1650 }1650 }
1651 return sema.mod.fail(&block.base, src, "arg index {d} out of bounds; '{}' has {d} argument(s)", .{1651 return sema.mod.fail(&block.base, src, "arg index {d} out of bounds; '{}' has {d} argument(s)", .{
1652 param_index,1652 param_index,
...@@ -1657,7 +1657,7 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr...@@ -1657,7 +1657,7 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr
16571657
1658 // TODO support generic functions1658 // TODO support generic functions
1659 const param_type = fn_ty.fnParamType(param_index);1659 const param_type = fn_ty.fnParamType(param_index);
1660 return sema.mod.constType(sema.arena, src, param_type);1660 return sema.addType(param_type);
1661}1661}
16621662
1663fn zirStr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {1663fn zirStr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -1694,7 +1694,7 @@ fn zirInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air...@@ -1694,7 +1694,7 @@ fn zirInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air
1694 defer tracy.end();1694 defer tracy.end();
16951695
1696 const int = sema.code.instructions.items(.data)[inst].int;1696 const int = sema.code.instructions.items(.data)[inst].int;
1697 return sema.mod.constIntUnsigned(sema.arena, .unneeded, Type.initTag(.comptime_int), int);1697 return sema.addIntUnsigned(Type.initTag(.comptime_int), int);
1698}1698}
16991699
1700fn zirIntBig(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {1700fn zirIntBig(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -2418,10 +2418,9 @@ fn zirIntType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError...@@ -2418,10 +2418,9 @@ fn zirIntType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError
2418 defer tracy.end();2418 defer tracy.end();
24192419
2420 const int_type = sema.code.instructions.items(.data)[inst].int_type;2420 const int_type = sema.code.instructions.items(.data)[inst].int_type;
2421 const src = int_type.src();
2422 const ty = try Module.makeIntType(sema.arena, int_type.signedness, int_type.bit_count);2421 const ty = try Module.makeIntType(sema.arena, int_type.signedness, int_type.bit_count);
24232422
2424 return sema.mod.constType(sema.arena, src, ty);2423 return sema.addType(ty);
2425}2424}
24262425
2427fn zirOptionalType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {2426fn zirOptionalType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -2433,7 +2432,7 @@ fn zirOptionalType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner...@@ -2433,7 +2432,7 @@ fn zirOptionalType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner
2433 const child_type = try sema.resolveType(block, src, inst_data.operand);2432 const child_type = try sema.resolveType(block, src, inst_data.operand);
2434 const opt_type = try sema.mod.optionalType(sema.arena, child_type);2433 const opt_type = try sema.mod.optionalType(sema.arena, child_type);
24352434
2436 return sema.mod.constType(sema.arena, src, opt_type);2435 return sema.addType(opt_type);
2437}2436}
24382437
2439fn zirElemType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {2438fn zirElemType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -2441,12 +2440,11 @@ fn zirElemType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro...@@ -2441,12 +2440,11 @@ fn zirElemType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro
2441 const src = inst_data.src();2440 const src = inst_data.src();
2442 const array_type = try sema.resolveType(block, src, inst_data.operand);2441 const array_type = try sema.resolveType(block, src, inst_data.operand);
2443 const elem_type = array_type.elemType();2442 const elem_type = array_type.elemType();
2444 return sema.mod.constType(sema.arena, src, elem_type);2443 return sema.addType(elem_type);
2445}2444}
24462445
2447fn zirVectorType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {2446fn zirVectorType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
2448 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;2447 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
2449 const src = inst_data.src();
2450 const elem_type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };2448 const elem_type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
2451 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };2449 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
2452 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;2450 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
...@@ -2456,7 +2454,7 @@ fn zirVectorType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr...@@ -2456,7 +2454,7 @@ fn zirVectorType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr
2456 .len = len,2454 .len = len,
2457 .elem_type = elem_type,2455 .elem_type = elem_type,
2458 });2456 });
2459 return sema.mod.constType(sema.arena, src, vector_type);2457 return sema.addType(vector_type);
2460}2458}
24612459
2462fn zirArrayType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {2460fn zirArrayType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -2469,7 +2467,7 @@ fn zirArrayType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr...@@ -2469,7 +2467,7 @@ fn zirArrayType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr
2469 const elem_type = try sema.resolveType(block, .unneeded, bin_inst.rhs);2467 const elem_type = try sema.resolveType(block, .unneeded, bin_inst.rhs);
2470 const array_ty = try sema.mod.arrayType(sema.arena, len.val.toUnsignedInt(), null, elem_type);2468 const array_ty = try sema.mod.arrayType(sema.arena, len.val.toUnsignedInt(), null, elem_type);
24712469
2472 return sema.mod.constType(sema.arena, .unneeded, array_ty);2470 return sema.addType(array_ty);
2473}2471}
24742472
2475fn zirArrayTypeSentinel(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {2473fn zirArrayTypeSentinel(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -2484,7 +2482,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index)...@@ -2484,7 +2482,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index)
2484 const elem_type = try sema.resolveType(block, .unneeded, extra.elem_type);2482 const elem_type = try sema.resolveType(block, .unneeded, extra.elem_type);
2485 const array_ty = try sema.mod.arrayType(sema.arena, len.val.toUnsignedInt(), sentinel.val, elem_type);2483 const array_ty = try sema.mod.arrayType(sema.arena, len.val.toUnsignedInt(), sentinel.val, elem_type);
24862484
2487 return sema.mod.constType(sema.arena, .unneeded, array_ty);2485 return sema.addType(array_ty);
2488}2486}
24892487
2490fn zirAnyframeType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {2488fn zirAnyframeType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -2492,12 +2490,11 @@ fn zirAnyframeType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner...@@ -2492,12 +2490,11 @@ fn zirAnyframeType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner
2492 defer tracy.end();2490 defer tracy.end();
24932491
2494 const inst_data = sema.code.instructions.items(.data)[inst].un_node;2492 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
2495 const src = inst_data.src();
2496 const operand_src: LazySrcLoc = .{ .node_offset_anyframe_type = inst_data.src_node };2493 const operand_src: LazySrcLoc = .{ .node_offset_anyframe_type = inst_data.src_node };
2497 const return_type = try sema.resolveType(block, operand_src, inst_data.operand);2494 const return_type = try sema.resolveType(block, operand_src, inst_data.operand);
2498 const anyframe_type = try Type.Tag.anyframe_T.create(sema.arena, return_type);2495 const anyframe_type = try Type.Tag.anyframe_T.create(sema.arena, return_type);
24992496
2500 return sema.mod.constType(sema.arena, src, anyframe_type);2497 return sema.addType(anyframe_type);
2501}2498}
25022499
2503fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {2500fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -2506,7 +2503,6 @@ fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inn...@@ -2506,7 +2503,6 @@ fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inn
25062503
2507 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;2504 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
2508 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;2505 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2509 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
2510 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };2506 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
2511 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };2507 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
2512 const error_union = try sema.resolveType(block, lhs_src, extra.lhs);2508 const error_union = try sema.resolveType(block, lhs_src, extra.lhs);
...@@ -2518,7 +2514,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inn...@@ -2518,7 +2514,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inn
2518 });2514 });
2519 }2515 }
2520 const err_union_ty = try sema.mod.errorUnionType(sema.arena, error_union, payload);2516 const err_union_ty = try sema.mod.errorUnionType(sema.arena, error_union, payload);
2521 return sema.mod.constType(sema.arena, src, err_union_ty);2517 return sema.addType(err_union_ty);
2522}2518}
25232519
2524fn zirErrorValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {2520fn zirErrorValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -2553,7 +2549,7 @@ fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr...@@ -2553,7 +2549,7 @@ fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr
25532549
2554 if (try sema.resolvePossiblyUndefinedValue(block, src, op_coerced)) |val| {2550 if (try sema.resolvePossiblyUndefinedValue(block, src, op_coerced)) |val| {
2555 if (val.isUndef()) {2551 if (val.isUndef()) {
2556 return sema.mod.constUndef(sema.arena, src, result_ty);2552 return sema.addConstUndef(result_ty);
2557 }2553 }
2558 const payload = try sema.arena.create(Value.Payload.U64);2554 const payload = try sema.arena.create(Value.Payload.U64);
2559 payload.* = .{2555 payload.* = .{
...@@ -2567,7 +2563,7 @@ fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr...@@ -2567,7 +2563,7 @@ fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr
2567 }2563 }
25682564
2569 try sema.requireRuntimeBlock(block, src);2565 try sema.requireRuntimeBlock(block, src);
2570 return block.addUnOp(src, result_ty, .bitcast, op_coerced);2566 return block.addTyOp(.bitcast, result_ty, op_coerced);
2571}2567}
25722568
2573fn zirIntToError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {2569fn zirIntToError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -2600,7 +2596,7 @@ fn zirIntToError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr...@@ -2600,7 +2596,7 @@ fn zirIntToError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr
2600 // const is_gt_max = @panic("TODO get max errors in compilation");2596 // const is_gt_max = @panic("TODO get max errors in compilation");
2601 // try sema.addSafetyCheck(block, is_gt_max, .invalid_error_code);2597 // try sema.addSafetyCheck(block, is_gt_max, .invalid_error_code);
2602 }2598 }
2603 return block.addUnOp(src, Type.initTag(.anyerror), .bitcast, op);2599 return block.addTyOp(.bitcast, Type.initTag(.anyerror), op);
2604}2600}
26052601
2606fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {2602fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -2614,7 +2610,9 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inn...@@ -2614,7 +2610,9 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inn
2614 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };2610 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
2615 const lhs = sema.resolveInst(extra.lhs);2611 const lhs = sema.resolveInst(extra.lhs);
2616 const rhs = sema.resolveInst(extra.rhs);2612 const rhs = sema.resolveInst(extra.rhs);
2617 if (rhs.ty.zigTypeTag() == .Bool and lhs.ty.zigTypeTag() == .Bool) {2613 const lhs_ty = sema.getTypeOf(lhs);
2614 const rhs_ty = sema.getTypeOf(rhs);
2615 if (rhs_ty.zigTypeTag() == .Bool and lhs_ty.zigTypeTag() == .Bool) {
2618 const msg = msg: {2616 const msg = msg: {
2619 const msg = try sema.mod.errMsg(&block.base, lhs_src, "expected error set type, found 'bool'", .{});2617 const msg = try sema.mod.errMsg(&block.base, lhs_src, "expected error set type, found 'bool'", .{});
2620 errdefer msg.destroy(sema.gpa);2618 errdefer msg.destroy(sema.gpa);
...@@ -2623,8 +2621,6 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inn...@@ -2623,8 +2621,6 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inn
2623 };2621 };
2624 return sema.mod.failWithOwnedErrorMsg(&block.base, msg);2622 return sema.mod.failWithOwnedErrorMsg(&block.base, msg);
2625 }2623 }
2626 const rhs_ty = try sema.resolveAirAsType(block, rhs_src, rhs);
2627 const lhs_ty = try sema.resolveAirAsType(block, lhs_src, lhs);
2628 if (rhs_ty.zigTypeTag() != .ErrorSet)2624 if (rhs_ty.zigTypeTag() != .ErrorSet)
2629 return sema.mod.fail(&block.base, rhs_src, "expected error set type, found {}", .{rhs_ty});2625 return sema.mod.fail(&block.base, rhs_src, "expected error set type, found {}", .{rhs_ty});
2630 if (lhs_ty.zigTypeTag() != .ErrorSet)2626 if (lhs_ty.zigTypeTag() != .ErrorSet)
...@@ -2786,7 +2782,7 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr...@@ -2786,7 +2782,7 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr
2786 }2782 }
27872783
2788 try sema.requireRuntimeBlock(block, src);2784 try sema.requireRuntimeBlock(block, src);
2789 return block.addUnOp(src, int_tag_ty, .bitcast, enum_tag);2785 return block.addTyOp(.bitcast, int_tag_ty, enum_tag);
2790}2786}
27912787
2792fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {2788fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -2841,7 +2837,7 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr...@@ -2841,7 +2837,7 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr
2841 }2837 }
28422838
2843 try sema.requireRuntimeBlock(block, src);2839 try sema.requireRuntimeBlock(block, src);
2844 return block.addUnOp(src, dest_ty, .bitcast, operand);2840 return block.addTyOp(.bitcast, dest_ty, operand);
2845}2841}
28462842
2847/// Pointer in, pointer out.2843/// Pointer in, pointer out.
...@@ -2881,10 +2877,10 @@ fn zirOptionalPayloadPtr(...@@ -2881,10 +2877,10 @@ fn zirOptionalPayloadPtr(
28812877
2882 try sema.requireRuntimeBlock(block, src);2878 try sema.requireRuntimeBlock(block, src);
2883 if (safety_check and block.wantSafety()) {2879 if (safety_check and block.wantSafety()) {
2884 const is_non_null = try block.addUnOp(src, Type.initTag(.bool), .is_non_null_ptr, optional_ptr);2880 const is_non_null = try block.addUnOp(.is_non_null_ptr, optional_ptr);
2885 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);2881 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
2886 }2882 }
2887 return block.addUnOp(src, child_pointer, .optional_payload_ptr, optional_ptr);2883 return block.addTyOp(.optional_payload_ptr, child_pointer, optional_ptr);
2888}2884}
28892885
2890/// Value in, value out.2886/// Value in, value out.
...@@ -2919,10 +2915,10 @@ fn zirOptionalPayload(...@@ -2919,10 +2915,10 @@ fn zirOptionalPayload(
29192915
2920 try sema.requireRuntimeBlock(block, src);2916 try sema.requireRuntimeBlock(block, src);
2921 if (safety_check and block.wantSafety()) {2917 if (safety_check and block.wantSafety()) {
2922 const is_non_null = try block.addUnOp(src, Type.initTag(.bool), .is_non_null, operand);2918 const is_non_null = try block.addUnOp(.is_non_null, operand);
2923 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);2919 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
2924 }2920 }
2925 return block.addUnOp(src, child_type, .optional_payload, operand);2921 return block.addTyOp(.optional_payload, child_type, operand);
2926}2922}
29272923
2928/// Value in, value out2924/// Value in, value out
...@@ -2953,10 +2949,11 @@ fn zirErrUnionPayload(...@@ -2953,10 +2949,11 @@ fn zirErrUnionPayload(
2953 }2949 }
2954 try sema.requireRuntimeBlock(block, src);2950 try sema.requireRuntimeBlock(block, src);
2955 if (safety_check and block.wantSafety()) {2951 if (safety_check and block.wantSafety()) {
2956 const is_non_err = try block.addUnOp(src, Type.initTag(.bool), .is_err, operand);2952 const is_non_err = try block.addUnOp(.is_err, operand);
2957 try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion);2953 try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion);
2958 }2954 }
2959 return block.addUnOp(src, operand.ty.castTag(.error_union).?.data.payload, .unwrap_errunion_payload, operand);2955 const result_ty = operand.ty.castTag(.error_union).?.data.payload;
2956 return block.addTyOp(.unwrap_errunion_payload, result_ty, operand);
2960}2957}
29612958
2962/// Pointer in, pointer out.2959/// Pointer in, pointer out.
...@@ -2997,10 +2994,10 @@ fn zirErrUnionPayloadPtr(...@@ -2997,10 +2994,10 @@ fn zirErrUnionPayloadPtr(
29972994
2998 try sema.requireRuntimeBlock(block, src);2995 try sema.requireRuntimeBlock(block, src);
2999 if (safety_check and block.wantSafety()) {2996 if (safety_check and block.wantSafety()) {
3000 const is_non_err = try block.addUnOp(src, Type.initTag(.bool), .is_err, operand);2997 const is_non_err = try block.addUnOp(.is_err, operand);
3001 try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion);2998 try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion);
3002 }2999 }
3003 return block.addUnOp(src, operand_pointer_ty, .unwrap_errunion_payload_ptr, operand);3000 return block.addTyOp(.unwrap_errunion_payload_ptr, operand_pointer_ty, operand);
3004}3001}
30053002
3006/// Value in, value out3003/// Value in, value out
...@@ -3026,7 +3023,7 @@ fn zirErrUnionCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner...@@ -3026,7 +3023,7 @@ fn zirErrUnionCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner
3026 }3023 }
30273024
3028 try sema.requireRuntimeBlock(block, src);3025 try sema.requireRuntimeBlock(block, src);
3029 return block.addUnOp(src, result_ty, .unwrap_errunion_err, operand);3026 return block.addTyOp(.unwrap_errunion_err, result_ty, operand);
3030}3027}
30313028
3032/// Pointer in, value out3029/// Pointer in, value out
...@@ -3055,7 +3052,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) In...@@ -3055,7 +3052,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) In
3055 }3052 }
30563053
3057 try sema.requireRuntimeBlock(block, src);3054 try sema.requireRuntimeBlock(block, src);
3058 return block.addUnOp(src, result_ty, .unwrap_errunion_err_ptr, operand);3055 return block.addTyOp(.unwrap_errunion_err_ptr, result_ty, operand);
3059}3056}
30603057
3061fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void {3058fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void {
...@@ -3241,7 +3238,7 @@ fn funcCommon(...@@ -3241,7 +3238,7 @@ fn funcCommon(
3241 }3238 }
32423239
3243 if (body_inst == 0) {3240 if (body_inst == 0) {
3244 return mod.constType(sema.arena, src, fn_ty);3241 return sema.addType(fn_ty);
3245 }3242 }
32463243
3247 const is_inline = fn_ty.fnCallingConvention() == .Inline;3244 const is_inline = fn_ty.fnCallingConvention() == .Inline;
...@@ -3312,8 +3309,7 @@ fn zirPtrToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro...@@ -3312,8 +3309,7 @@ fn zirPtrToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro
3312 // TODO handle known-pointer-address3309 // TODO handle known-pointer-address
3313 const src = inst_data.src();3310 const src = inst_data.src();
3314 try sema.requireRuntimeBlock(block, src);3311 try sema.requireRuntimeBlock(block, src);
3315 const ty = Type.initTag(.usize);3312 return block.addUnOp(.ptrtoint, ptr);
3316 return block.addUnOp(src, ty, .ptrtoint, ptr);
3317}3313}
33183314
3319fn zirFieldVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {3315fn zirFieldVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -4244,15 +4240,14 @@ fn analyzeSwitch(...@@ -4244,15 +4240,14 @@ fn analyzeSwitch(
4244 case_block.instructions.shrinkRetainingCapacity(0);4240 case_block.instructions.shrinkRetainingCapacity(0);
42454241
4246 var any_ok: ?Air.Inst.Index = null;4242 var any_ok: ?Air.Inst.Index = null;
4247 const bool_ty = comptime Type.initTag(.bool);
42484243
4249 for (items) |item_ref| {4244 for (items) |item_ref| {
4250 const item = sema.resolveInst(item_ref);4245 const item = sema.resolveInst(item_ref);
4251 _ = try sema.resolveConstValue(&child_block, item.src, item);4246 _ = try sema.resolveConstValue(&child_block, item.src, item);
42524247
4253 const cmp_ok = try case_block.addBinOp(item.src, bool_ty, .cmp_eq, operand, item);4248 const cmp_ok = try case_block.addBinOp(.cmp_eq, operand, item);
4254 if (any_ok) |some| {4249 if (any_ok) |some| {
4255 any_ok = try case_block.addBinOp(item.src, bool_ty, .bool_or, some, cmp_ok);4250 any_ok = try case_block.addBinOp(.bool_or, some, cmp_ok);
4256 } else {4251 } else {
4257 any_ok = cmp_ok;4252 any_ok = cmp_ok;
4258 }4253 }
...@@ -4271,32 +4266,24 @@ fn analyzeSwitch(...@@ -4271,32 +4266,24 @@ fn analyzeSwitch(
4271 _ = try sema.resolveConstValue(&child_block, item_first.src, item_first);4266 _ = try sema.resolveConstValue(&child_block, item_first.src, item_first);
4272 _ = try sema.resolveConstValue(&child_block, item_last.src, item_last);4267 _ = try sema.resolveConstValue(&child_block, item_last.src, item_last);
42734268
4274 const range_src = item_first.src;
4275
4276 // operand >= first and operand <= last4269 // operand >= first and operand <= last
4277 const range_first_ok = try case_block.addBinOp(4270 const range_first_ok = try case_block.addBinOp(
4278 item_first.src,
4279 bool_ty,
4280 .cmp_gte,4271 .cmp_gte,
4281 operand,4272 operand,
4282 item_first,4273 item_first,
4283 );4274 );
4284 const range_last_ok = try case_block.addBinOp(4275 const range_last_ok = try case_block.addBinOp(
4285 item_last.src,
4286 bool_ty,
4287 .cmp_lte,4276 .cmp_lte,
4288 operand,4277 operand,
4289 item_last,4278 item_last,
4290 );4279 );
4291 const range_ok = try case_block.addBinOp(4280 const range_ok = try case_block.addBinOp(
4292 range_src,
4293 bool_ty,
4294 .bool_and,4281 .bool_and,
4295 range_first_ok,4282 range_first_ok,
4296 range_last_ok,4283 range_last_ok,
4297 );4284 );
4298 if (any_ok) |some| {4285 if (any_ok) |some| {
4299 any_ok = try case_block.addBinOp(range_src, bool_ty, .bool_or, some, range_ok);4286 any_ok = try case_block.addBinOp(.bool_or, some, range_ok);
4300 } else {4287 } else {
4301 any_ok = range_ok;4288 any_ok = range_ok;
4302 }4289 }
...@@ -4555,13 +4542,11 @@ fn zirHasField(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro...@@ -4555,13 +4542,11 @@ fn zirHasField(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro
4555fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {4542fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
4556 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;4543 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
4557 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;4544 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
4558 const src = inst_data.src();
4559 const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };4545 const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
4560 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };4546 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
4561 const container_type = try sema.resolveType(block, lhs_src, extra.lhs);4547 const container_type = try sema.resolveType(block, lhs_src, extra.lhs);
4562 const decl_name = try sema.resolveConstString(block, rhs_src, extra.rhs);4548 const decl_name = try sema.resolveConstString(block, rhs_src, extra.rhs);
4563 const mod = sema.mod;4549 const mod = sema.mod;
4564 const arena = sema.arena;
45654550
4566 const namespace = container_type.getNamespace() orelse return mod.fail(4551 const namespace = container_type.getNamespace() orelse return mod.fail(
4567 &block.base,4552 &block.base,
...@@ -4571,10 +4556,10 @@ fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError...@@ -4571,10 +4556,10 @@ fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError
4571 );4556 );
4572 if (try sema.lookupInNamespace(namespace, decl_name)) |decl| {4557 if (try sema.lookupInNamespace(namespace, decl_name)) |decl| {
4573 if (decl.is_pub or decl.namespace.file_scope == block.base.namespace().file_scope) {4558 if (decl.is_pub or decl.namespace.file_scope == block.base.namespace().file_scope) {
4574 return mod.constBool(arena, src, true);4559 return Air.Inst.Ref.bool_true;
4575 }4560 }
4576 }4561 }
4577 return mod.constBool(arena, src, false);4562 return Air.Inst.Ref.bool_false;
4578}4563}
45794564
4580fn zirImport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {4565fn zirImport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -4599,7 +4584,7 @@ fn zirImport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!...@@ -4599,7 +4584,7 @@ fn zirImport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!
4599 try mod.semaFile(result.file);4584 try mod.semaFile(result.file);
4600 const file_root_decl = result.file.root_decl.?;4585 const file_root_decl = result.file.root_decl.?;
4601 try sema.mod.declareDeclDependency(sema.owner_decl, file_root_decl);4586 try sema.mod.declareDeclDependency(sema.owner_decl, file_root_decl);
4602 return mod.constType(sema.arena, src, file_root_decl.ty);4587 return sema.addType(file_root_decl.ty);
4603}4588}
46044589
4605fn zirRetErrValueCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {4590fn zirRetErrValueCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -4641,6 +4626,8 @@ fn zirBitwise(...@@ -4641,6 +4626,8 @@ fn zirBitwise(
4641 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;4626 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
4642 const lhs = sema.resolveInst(extra.lhs);4627 const lhs = sema.resolveInst(extra.lhs);
4643 const rhs = sema.resolveInst(extra.rhs);4628 const rhs = sema.resolveInst(extra.rhs);
4629 const lhs_ty = sema.getTypeOf(lhs);
4630 const rhs_ty = sema.getTypeOf(rhs);
46444631
4645 const instructions = &[_]Air.Inst.Index{ lhs, rhs };4632 const instructions = &[_]Air.Inst.Index{ lhs, rhs };
4646 const resolved_type = try sema.resolvePeerTypes(block, src, instructions);4633 const resolved_type = try sema.resolvePeerTypes(block, src, instructions);
...@@ -4654,38 +4641,38 @@ fn zirBitwise(...@@ -4654,38 +4641,38 @@ fn zirBitwise(
46544641
4655 const scalar_tag = scalar_type.zigTypeTag();4642 const scalar_tag = scalar_type.zigTypeTag();
46564643
4657 if (lhs.ty.zigTypeTag() == .Vector and rhs.ty.zigTypeTag() == .Vector) {4644 if (lhs_ty.zigTypeTag() == .Vector and rhs_ty.zigTypeTag() == .Vector) {
4658 if (lhs.ty.arrayLen() != rhs.ty.arrayLen()) {4645 if (lhs_ty.arrayLen() != rhs_ty.arrayLen()) {
4659 return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{4646 return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{
4660 lhs.ty.arrayLen(),4647 lhs_ty.arrayLen(),
4661 rhs.ty.arrayLen(),4648 rhs_ty.arrayLen(),
4662 });4649 });
4663 }4650 }
4664 return sema.mod.fail(&block.base, src, "TODO implement support for vectors in zirBitwise", .{});4651 return sema.mod.fail(&block.base, src, "TODO implement support for vectors in zirBitwise", .{});
4665 } else if (lhs.ty.zigTypeTag() == .Vector or rhs.ty.zigTypeTag() == .Vector) {4652 } else if (lhs_ty.zigTypeTag() == .Vector or rhs_ty.zigTypeTag() == .Vector) {
4666 return sema.mod.fail(&block.base, src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{4653 return sema.mod.fail(&block.base, src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{
4667 lhs.ty,4654 lhs_ty,
4668 rhs.ty,4655 rhs_ty,
4669 });4656 });
4670 }4657 }
46714658
4672 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;4659 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
46734660
4674 if (!is_int) {4661 if (!is_int) {
4675 return sema.mod.fail(&block.base, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs.ty.zigTypeTag()), @tagName(rhs.ty.zigTypeTag()) });4662 return sema.mod.fail(&block.base, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag()), @tagName(rhs_ty.zigTypeTag()) });
4676 }4663 }
46774664
4678 if (casted_lhs.value()) |lhs_val| {4665 if (casted_lhs.value()) |lhs_val| {
4679 if (casted_rhs.value()) |rhs_val| {4666 if (casted_rhs.value()) |rhs_val| {
4680 if (lhs_val.isUndef() or rhs_val.isUndef()) {4667 if (lhs_val.isUndef() or rhs_val.isUndef()) {
4681 return sema.mod.constUndef(sema.arena, src, resolved_type);4668 return sema.addConstUndef(resolved_type);
4682 }4669 }
4683 return sema.mod.fail(&block.base, src, "TODO implement comptime bitwise operations", .{});4670 return sema.mod.fail(&block.base, src, "TODO implement comptime bitwise operations", .{});
4684 }4671 }
4685 }4672 }
46864673
4687 try sema.requireRuntimeBlock(block, src);4674 try sema.requireRuntimeBlock(block, src);
4688 return block.addBinOp(src, scalar_type, air_tag, casted_lhs, casted_rhs);4675 return block.addBinOp(air_tag, casted_lhs, casted_rhs);
4689}4676}
46904677
4691fn zirBitNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {4678fn zirBitNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -4783,18 +4770,18 @@ fn analyzeArithmetic(...@@ -4783,18 +4770,18 @@ fn analyzeArithmetic(
47834770
4784 const scalar_tag = scalar_type.zigTypeTag();4771 const scalar_tag = scalar_type.zigTypeTag();
47854772
4786 if (lhs.ty.zigTypeTag() == .Vector and rhs.ty.zigTypeTag() == .Vector) {4773 if (lhs_ty.zigTypeTag() == .Vector and rhs_ty.zigTypeTag() == .Vector) {
4787 if (lhs.ty.arrayLen() != rhs.ty.arrayLen()) {4774 if (lhs_ty.arrayLen() != rhs_ty.arrayLen()) {
4788 return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{4775 return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{
4789 lhs.ty.arrayLen(),4776 lhs_ty.arrayLen(),
4790 rhs.ty.arrayLen(),4777 rhs_ty.arrayLen(),
4791 });4778 });
4792 }4779 }
4793 return sema.mod.fail(&block.base, src, "TODO implement support for vectors in zirBinOp", .{});4780 return sema.mod.fail(&block.base, src, "TODO implement support for vectors in zirBinOp", .{});
4794 } else if (lhs.ty.zigTypeTag() == .Vector or rhs.ty.zigTypeTag() == .Vector) {4781 } else if (lhs_ty.zigTypeTag() == .Vector or rhs_ty.zigTypeTag() == .Vector) {
4795 return sema.mod.fail(&block.base, src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{4782 return sema.mod.fail(&block.base, src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{
4796 lhs.ty,4783 lhs_ty,
4797 rhs.ty,4784 rhs_ty,
4798 });4785 });
4799 }4786 }
48004787
...@@ -4802,13 +4789,13 @@ fn analyzeArithmetic(...@@ -4802,13 +4789,13 @@ fn analyzeArithmetic(
4802 const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat;4789 const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat;
48034790
4804 if (!is_int and !(is_float and floatOpAllowed(zir_tag))) {4791 if (!is_int and !(is_float and floatOpAllowed(zir_tag))) {
4805 return sema.mod.fail(&block.base, src, "invalid operands to binary expression: '{s}' and '{s}'", .{ @tagName(lhs.ty.zigTypeTag()), @tagName(rhs.ty.zigTypeTag()) });4792 return sema.mod.fail(&block.base, src, "invalid operands to binary expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag()), @tagName(rhs_ty.zigTypeTag()) });
4806 }4793 }
48074794
4808 if (casted_lhs.value()) |lhs_val| {4795 if (casted_lhs.value()) |lhs_val| {
4809 if (casted_rhs.value()) |rhs_val| {4796 if (casted_rhs.value()) |rhs_val| {
4810 if (lhs_val.isUndef() or rhs_val.isUndef()) {4797 if (lhs_val.isUndef() or rhs_val.isUndef()) {
4811 return sema.mod.constUndef(sema.arena, src, resolved_type);4798 return sema.addConstUndef(resolved_type);
4812 }4799 }
4813 // incase rhs is 0, simply return lhs without doing any calculations4800 // incase rhs is 0, simply return lhs without doing any calculations
4814 // TODO Once division is implemented we should throw an error when dividing by 0.4801 // TODO Once division is implemented we should throw an error when dividing by 0.
...@@ -4866,7 +4853,7 @@ fn analyzeArithmetic(...@@ -4866,7 +4853,7 @@ fn analyzeArithmetic(
4866 }4853 }
48674854
4868 try sema.requireRuntimeBlock(block, src);4855 try sema.requireRuntimeBlock(block, src);
4869 const ir_tag: Inst.Tag = switch (zir_tag) {4856 const air_tag: Air.Inst.Tag = switch (zir_tag) {
4870 .add => .add,4857 .add => .add,
4871 .addwrap => .addwrap,4858 .addwrap => .addwrap,
4872 .sub => .sub,4859 .sub => .sub,
...@@ -4877,7 +4864,7 @@ fn analyzeArithmetic(...@@ -4877,7 +4864,7 @@ fn analyzeArithmetic(
4877 else => return sema.mod.fail(&block.base, src, "TODO implement arithmetic for operand '{s}''", .{@tagName(zir_tag)}),4864 else => return sema.mod.fail(&block.base, src, "TODO implement arithmetic for operand '{s}''", .{@tagName(zir_tag)}),
4878 };4865 };
48794866
4880 return block.addBinOp(src, scalar_type, ir_tag, casted_lhs, casted_rhs);4867 return block.addBinOp(air_tag, casted_lhs, casted_rhs);
4881}4868}
48824869
4883fn zirLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {4870fn zirLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -4997,11 +4984,17 @@ fn zirCmp(...@@ -4997,11 +4984,17 @@ fn zirCmp(
4997 .eq, .neq => true,4984 .eq, .neq => true,
4998 else => false,4985 else => false,
4999 };4986 };
5000 const lhs_ty_tag = lhs.ty.zigTypeTag();4987 const lhs_ty = sema.getTypeOf(lhs);
5001 const rhs_ty_tag = rhs.ty.zigTypeTag();4988 const rhs_ty = sema.getTypeOf(rhs);
4989 const lhs_ty_tag = lhs_ty.zigTypeTag();
4990 const rhs_ty_tag = rhs_ty.zigTypeTag();
5002 if (is_equality_cmp and lhs_ty_tag == .Null and rhs_ty_tag == .Null) {4991 if (is_equality_cmp and lhs_ty_tag == .Null and rhs_ty_tag == .Null) {
5003 // null == null, null != null4992 // null == null, null != null
5004 return mod.constBool(sema.arena, src, op == .eq);4993 if (op == .eq) {
4994 return Air.Inst.Ref.bool_true;
4995 } else {
4996 return Air.Inst.Ref.bool_false;
4997 }
5005 } else if (is_equality_cmp and4998 } else if (is_equality_cmp and
5006 ((lhs_ty_tag == .Null and rhs_ty_tag == .Optional) or4999 ((lhs_ty_tag == .Null and rhs_ty_tag == .Optional) or
5007 rhs_ty_tag == .Null and lhs_ty_tag == .Optional))5000 rhs_ty_tag == .Null and lhs_ty_tag == .Optional))
...@@ -5010,11 +5003,11 @@ fn zirCmp(...@@ -5010,11 +5003,11 @@ fn zirCmp(
5010 const opt_operand = if (lhs_ty_tag == .Optional) lhs else rhs;5003 const opt_operand = if (lhs_ty_tag == .Optional) lhs else rhs;
5011 return sema.analyzeIsNull(block, src, opt_operand, op == .neq);5004 return sema.analyzeIsNull(block, src, opt_operand, op == .neq);
5012 } else if (is_equality_cmp and5005 } else if (is_equality_cmp and
5013 ((lhs_ty_tag == .Null and rhs.ty.isCPtr()) or (rhs_ty_tag == .Null and lhs.ty.isCPtr())))5006 ((lhs_ty_tag == .Null and rhs_ty.isCPtr()) or (rhs_ty_tag == .Null and lhs_ty.isCPtr())))
5014 {5007 {
5015 return mod.fail(&block.base, src, "TODO implement C pointer cmp", .{});5008 return mod.fail(&block.base, src, "TODO implement C pointer cmp", .{});
5016 } else if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) {5009 } else if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) {
5017 const non_null_type = if (lhs_ty_tag == .Null) rhs.ty else lhs.ty;5010 const non_null_type = if (lhs_ty_tag == .Null) rhs_ty else lhs_ty;
5018 return mod.fail(&block.base, src, "comparison of '{}' with null", .{non_null_type});5011 return mod.fail(&block.base, src, "comparison of '{}' with null", .{non_null_type});
5019 } else if (is_equality_cmp and5012 } else if (is_equality_cmp and
5020 ((lhs_ty_tag == .EnumLiteral and rhs_ty_tag == .Union) or5013 ((lhs_ty_tag == .EnumLiteral and rhs_ty_tag == .Union) or
...@@ -5025,27 +5018,45 @@ fn zirCmp(...@@ -5025,27 +5018,45 @@ fn zirCmp(
5025 if (!is_equality_cmp) {5018 if (!is_equality_cmp) {
5026 return mod.fail(&block.base, src, "{s} operator not allowed for errors", .{@tagName(op)});5019 return mod.fail(&block.base, src, "{s} operator not allowed for errors", .{@tagName(op)});
5027 }5020 }
5028 if (rhs.value()) |rval| {5021 if (try sema.resolvePossiblyUndefinedValue(block, lhs_src, lhs)) |lval| {
5029 if (lhs.value()) |lval| {5022 if (try sema.resolvePossiblyUndefinedValue(block, rhs_src, rhs)) |rval| {
5030 // TODO optimisation oppurtunity: evaluate if std.mem.eql is faster with the names, or calling to Module.getErrorValue to get the values and then compare them is faster5023 if (lval.isUndef() or rval.isUndef()) {
5031 return mod.constBool(sema.arena, src, std.mem.eql(u8, lval.castTag(.@"error").?.data.name, rval.castTag(.@"error").?.data.name) == (op == .eq));5024 return sema.addConstUndef(Type.initTag(.bool));
5025 }
5026 // TODO optimisation opportunity: evaluate if mem.eql is faster with the names,
5027 // or calling to Module.getErrorValue to get the values and then compare them is
5028 // faster.
5029 const lhs_name = lval.castTag(.@"error").?.data.name;
5030 const rhs_name = rval.castTag(.@"error").?.data.name;
5031 if (mem.eql(u8, lhs_name, rhs_name) == (op == .eq)) {
5032 return Air.Inst.Ref.bool_true;
5033 } else {
5034 return Air.Inst.Ref.bool_false;
5035 }
5032 }5036 }
5033 }5037 }
5034 try sema.requireRuntimeBlock(block, src);5038 try sema.requireRuntimeBlock(block, src);
5035 return block.addBinOp(src, Type.initTag(.bool), if (op == .eq) .cmp_eq else .cmp_neq, lhs, rhs);5039 const tag: Air.Inst.Tag = if (op == .eq) .cmp_eq else .cmp_neq;
5036 } else if (lhs.ty.isNumeric() and rhs.ty.isNumeric()) {5040 return block.addBinOp(tag, lhs, rhs);
5041 } else if (lhs_ty.isNumeric() and rhs_ty.isNumeric()) {
5037 // This operation allows any combination of integer and float types, regardless of the5042 // This operation allows any combination of integer and float types, regardless of the
5038 // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for5043 // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for
5039 // numeric types.5044 // numeric types.
5040 return sema.cmpNumeric(block, src, lhs, rhs, op);5045 return sema.cmpNumeric(block, src, lhs, rhs, op, lhs_src, rhs_src);
5041 } else if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) {5046 } else if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) {
5042 if (!is_equality_cmp) {5047 if (!is_equality_cmp) {
5043 return mod.fail(&block.base, src, "{s} operator not allowed for types", .{@tagName(op)});5048 return mod.fail(&block.base, src, "{s} operator not allowed for types", .{@tagName(op)});
5044 }5049 }
5045 return mod.constBool(sema.arena, src, lhs.value().?.eql(rhs.value().?) == (op == .eq));5050 const lhs_as_type = try sema.resolveAirAsType(block, lhs_src, lhs);
5051 const rhs_as_type = try sema.resolveAirAsType(block, rhs_src, rhs);
5052 if (lhs_as_type.eql(rhs_as_type) == (op == .eq)) {
5053 return Air.Inst.Ref.bool_true;
5054 } else {
5055 return Air.Inst.Ref.bool_false;
5056 }
5046 }5057 }
50475058
5048 const instructions = &[_]Air.Inst.Index{ lhs, rhs };5059 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
5049 const resolved_type = try sema.resolvePeerTypes(block, src, instructions);5060 const resolved_type = try sema.resolvePeerTypes(block, src, instructions);
5050 if (!resolved_type.isSelfComparable(is_equality_cmp)) {5061 if (!resolved_type.isSelfComparable(is_equality_cmp)) {
5051 return mod.fail(&block.base, src, "operator not allowed for type '{}'", .{resolved_type});5062 return mod.fail(&block.base, src, "operator not allowed for type '{}'", .{resolved_type});
...@@ -5057,15 +5068,18 @@ fn zirCmp(...@@ -5057,15 +5068,18 @@ fn zirCmp(
5057 if (casted_lhs.value()) |lhs_val| {5068 if (casted_lhs.value()) |lhs_val| {
5058 if (casted_rhs.value()) |rhs_val| {5069 if (casted_rhs.value()) |rhs_val| {
5059 if (lhs_val.isUndef() or rhs_val.isUndef()) {5070 if (lhs_val.isUndef() or rhs_val.isUndef()) {
5060 return sema.mod.constUndef(sema.arena, src, resolved_type);5071 return sema.addConstUndef(resolved_type);
5072 }
5073 if (lhs_val.compare(op, rhs_val)) {
5074 return Air.Inst.Ref.bool_true;
5075 } else {
5076 return Air.Inst.Ref.bool_false;
5061 }5077 }
5062 const result = lhs_val.compare(op, rhs_val);
5063 return sema.mod.constBool(sema.arena, src, result);
5064 }5078 }
5065 }5079 }
50665080
5067 try sema.requireRuntimeBlock(block, src);5081 try sema.requireRuntimeBlock(block, src);
5068 const tag: Inst.Tag = switch (op) {5082 const tag: Air.Inst.Tag = switch (op) {
5069 .lt => .cmp_lt,5083 .lt => .cmp_lt,
5070 .lte => .cmp_lte,5084 .lte => .cmp_lte,
5071 .eq => .cmp_eq,5085 .eq => .cmp_eq,
...@@ -5073,28 +5087,26 @@ fn zirCmp(...@@ -5073,28 +5087,26 @@ fn zirCmp(
5073 .gt => .cmp_gt,5087 .gt => .cmp_gt,
5074 .neq => .cmp_neq,5088 .neq => .cmp_neq,
5075 };5089 };
5076 const bool_type = Type.initTag(.bool); // TODO handle vectors5090 // TODO handle vectors
5077 return block.addBinOp(src, bool_type, tag, casted_lhs, casted_rhs);5091 return block.addBinOp(tag, casted_lhs, casted_rhs);
5078}5092}
50795093
5080fn zirSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {5094fn zirSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
5081 const inst_data = sema.code.instructions.items(.data)[inst].un_node;5095 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
5082 const src = inst_data.src();
5083 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };5096 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
5084 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);5097 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);
5085 const target = sema.mod.getTarget();5098 const target = sema.mod.getTarget();
5086 const abi_size = operand_ty.abiSize(target);5099 const abi_size = operand_ty.abiSize(target);
5087 return sema.mod.constIntUnsigned(sema.arena, src, Type.initTag(.comptime_int), abi_size);5100 return sema.addIntUnsigned(Type.initTag(.comptime_int), abi_size);
5088}5101}
50895102
5090fn zirBitSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {5103fn zirBitSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
5091 const inst_data = sema.code.instructions.items(.data)[inst].un_node;5104 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
5092 const src = inst_data.src();
5093 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };5105 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
5094 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);5106 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);
5095 const target = sema.mod.getTarget();5107 const target = sema.mod.getTarget();
5096 const bit_size = operand_ty.bitSize(target);5108 const bit_size = operand_ty.bitSize(target);
5097 return sema.mod.constIntUnsigned(sema.arena, src, Type.initTag(.comptime_int), bit_size);5109 return sema.addIntUnsigned(Type.initTag(.comptime_int), bit_size);
5098}5110}
50995111
5100fn zirThis(5112fn zirThis(
...@@ -5171,18 +5183,16 @@ fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!...@@ -5171,18 +5183,16 @@ fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!
5171 _ = block;5183 _ = block;
5172 const zir_datas = sema.code.instructions.items(.data);5184 const zir_datas = sema.code.instructions.items(.data);
5173 const inst_data = zir_datas[inst].un_node;5185 const inst_data = zir_datas[inst].un_node;
5174 const src = inst_data.src();
5175 const operand = sema.resolveInst(inst_data.operand);5186 const operand = sema.resolveInst(inst_data.operand);
5176 return sema.mod.constType(sema.arena, src, operand.ty);5187 return sema.addType(operand.ty);
5177}5188}
51785189
5179fn zirTypeofElem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {5190fn zirTypeofElem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
5180 _ = block;5191 _ = block;
5181 const inst_data = sema.code.instructions.items(.data)[inst].un_node;5192 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
5182 const src = inst_data.src();
5183 const operand_ptr = sema.resolveInst(inst_data.operand);5193 const operand_ptr = sema.resolveInst(inst_data.operand);
5184 const elem_ty = operand_ptr.ty.elemType();5194 const elem_ty = operand_ptr.ty.elemType();
5185 return sema.mod.constType(sema.arena, src, elem_ty);5195 return sema.addType(elem_ty);
5186}5196}
51875197
5188fn zirTypeofLog2IntType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {5198fn zirTypeofLog2IntType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -5217,7 +5227,7 @@ fn zirTypeofPeer(...@@ -5217,7 +5227,7 @@ fn zirTypeofPeer(
5217 }5227 }
52185228
5219 const result_type = try sema.resolvePeerTypes(block, src, inst_list);5229 const result_type = try sema.resolvePeerTypes(block, src, inst_list);
5220 return sema.mod.constType(sema.arena, src, result_type);5230 return sema.addType(result_type);
5221}5231}
52225232
5223fn zirBoolNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {5233fn zirBoolNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -5231,17 +5241,21 @@ fn zirBoolNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError...@@ -5231,17 +5241,21 @@ fn zirBoolNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError
5231 const bool_type = Type.initTag(.bool);5241 const bool_type = Type.initTag(.bool);
5232 const operand = try sema.coerce(block, bool_type, uncasted_operand, uncasted_operand.src);5242 const operand = try sema.coerce(block, bool_type, uncasted_operand, uncasted_operand.src);
5233 if (try sema.resolveDefinedValue(block, src, operand)) |val| {5243 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
5234 return sema.mod.constBool(sema.arena, src, !val.toBool());5244 if (val.toBool()) {
5245 return Air.Inst.Ref.bool_false;
5246 } else {
5247 return Air.Inst.Ref.bool_true;
5248 }
5235 }5249 }
5236 try sema.requireRuntimeBlock(block, src);5250 try sema.requireRuntimeBlock(block, src);
5237 return block.addUnOp(src, bool_type, .not, operand);5251 return block.addTyOp(.not, bool_type, operand);
5238}5252}
52395253
5240fn zirBoolOp(5254fn zirBoolOp(
5241 sema: *Sema,5255 sema: *Sema,
5242 block: *Scope.Block,5256 block: *Scope.Block,
5243 inst: Zir.Inst.Index,5257 inst: Zir.Inst.Index,
5244 comptime is_bool_or: bool,5258 is_bool_or: bool,
5245) InnerError!Air.Inst.Ref {5259) InnerError!Air.Inst.Ref {
5246 const tracy = trace(@src());5260 const tracy = trace(@src());
5247 defer tracy.end();5261 defer tracy.end();
...@@ -5257,15 +5271,23 @@ fn zirBoolOp(...@@ -5257,15 +5271,23 @@ fn zirBoolOp(
5257 if (lhs.value()) |lhs_val| {5271 if (lhs.value()) |lhs_val| {
5258 if (rhs.value()) |rhs_val| {5272 if (rhs.value()) |rhs_val| {
5259 if (is_bool_or) {5273 if (is_bool_or) {
5260 return sema.mod.constBool(sema.arena, src, lhs_val.toBool() or rhs_val.toBool());5274 if (lhs_val.toBool() or rhs_val.toBool()) {
5275 return Air.Inst.Ref.bool_true;
5276 } else {
5277 return Air.Inst.Ref.bool_false;
5278 }
5261 } else {5279 } else {
5262 return sema.mod.constBool(sema.arena, src, lhs_val.toBool() and rhs_val.toBool());5280 if (lhs_val.toBool() and rhs_val.toBool()) {
5281 return Air.Inst.Ref.bool_true;
5282 } else {
5283 return Air.Inst.Ref.bool_false;
5284 }
5263 }5285 }
5264 }5286 }
5265 }5287 }
5266 try sema.requireRuntimeBlock(block, src);5288 try sema.requireRuntimeBlock(block, src);
5267 const tag: Air.Inst.Tag = if (is_bool_or) .bool_or else .bool_and;5289 const tag: Air.Inst.Tag = if (is_bool_or) .bool_or else .bool_and;
5268 return block.addBinOp(src, bool_type, tag, lhs, rhs);5290 return block.addBinOp(tag, lhs, rhs);
5269}5291}
52705292
5271fn zirBoolBr(5293fn zirBoolBr(
...@@ -5286,7 +5308,11 @@ fn zirBoolBr(...@@ -5286,7 +5308,11 @@ fn zirBoolBr(
52865308
5287 if (try sema.resolveDefinedValue(parent_block, src, lhs)) |lhs_val| {5309 if (try sema.resolveDefinedValue(parent_block, src, lhs)) |lhs_val| {
5288 if (lhs_val.toBool() == is_bool_or) {5310 if (lhs_val.toBool() == is_bool_or) {
5289 return sema.mod.constBool(sema.arena, src, is_bool_or);5311 if (is_bool_or) {
5312 return Air.Inst.Ref.bool_true;
5313 } else {
5314 return Air.Inst.Ref.bool_false;
5315 }
5290 }5316 }
5291 // comptime-known left-hand side. No need for a block here; the result5317 // comptime-known left-hand side. No need for a block here; the result
5292 // is simply the rhs expression. Here we rely on there only being 15318 // is simply the rhs expression. Here we rely on there only being 1
...@@ -5522,14 +5548,11 @@ fn analyzeRet(...@@ -5522,14 +5548,11 @@ fn analyzeRet(
5522 const fn_ty = func.owner_decl.ty;5548 const fn_ty = func.owner_decl.ty;
5523 const fn_ret_ty = fn_ty.fnReturnType();5549 const fn_ret_ty = fn_ty.fnReturnType();
5524 const casted_operand = try sema.coerce(block, fn_ret_ty, operand, src);5550 const casted_operand = try sema.coerce(block, fn_ret_ty, operand, src);
5525 if (fn_ret_ty.zigTypeTag() == .Void)5551 _ = try block.addUnOp(.ret, casted_operand);
5526 _ = try block.addNoOp(src, Type.initTag(.noreturn), .retvoid)
5527 else
5528 _ = try block.addUnOp(src, Type.initTag(.noreturn), .ret, casted_operand);
5529 return always_noreturn;5552 return always_noreturn;
5530 }5553 }
5531 }5554 }
5532 _ = try block.addUnOp(src, Type.initTag(.noreturn), .ret, operand);5555 _ = try block.addUnOp(.ret, operand);
5533 return always_noreturn;5556 return always_noreturn;
5534}5557}
55355558
...@@ -5559,7 +5582,7 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inne...@@ -5559,7 +5582,7 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inne
5559 inst_data.is_volatile,5582 inst_data.is_volatile,
5560 inst_data.size,5583 inst_data.size,
5561 );5584 );
5562 return sema.mod.constType(sema.arena, .unneeded, ty);5585 return sema.addType(ty);
5563}5586}
55645587
5565fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {5588fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -5613,7 +5636,7 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError...@@ -5613,7 +5636,7 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError
5613 inst_data.flags.is_volatile,5636 inst_data.flags.is_volatile,
5614 inst_data.size,5637 inst_data.size,
5615 );5638 );
5616 return sema.mod.constType(sema.arena, src, ty);5639 return sema.addType(ty);
5617}5640}
56185641
5619fn zirStructInitEmpty(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {5642fn zirStructInitEmpty(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -5794,7 +5817,7 @@ fn zirFieldType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr...@@ -5794,7 +5817,7 @@ fn zirFieldType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr
5794 const struct_obj = struct_ty.castTag(.@"struct").?.data;5817 const struct_obj = struct_ty.castTag(.@"struct").?.data;
5795 const field = struct_obj.fields.get(field_name) orelse5818 const field = struct_obj.fields.get(field_name) orelse
5796 return sema.failWithBadFieldAccess(block, struct_obj, src, field_name);5819 return sema.failWithBadFieldAccess(block, struct_obj, src, field_name);
5797 return sema.mod.constType(sema.arena, src, field.ty);5820 return sema.addType(field.ty);
5798}5821}
57995822
5800fn zirErrorReturnTrace(5823fn zirErrorReturnTrace(
...@@ -5937,7 +5960,7 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro...@@ -5937,7 +5960,7 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro
5937 .val = Value.initTag(.zero),5960 .val = Value.initTag(.zero),
5938 });5961 });
5939 if (!type_res.isAllowzeroPtr()) {5962 if (!type_res.isAllowzeroPtr()) {
5940 const is_non_zero = try block.addBinOp(src, Type.initTag(.bool), .cmp_neq, operand_coerced, zero);5963 const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, zero);
5941 try sema.addSafetyCheck(block, is_non_zero, .cast_to_null);5964 try sema.addSafetyCheck(block, is_non_zero, .cast_to_null);
5942 }5965 }
59435966
...@@ -5951,12 +5974,12 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro...@@ -5951,12 +5974,12 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro
5951 .ty = Type.initTag(.u64),5974 .ty = Type.initTag(.u64),
5952 .val = Value.initPayload(&val_payload.base),5975 .val = Value.initPayload(&val_payload.base),
5953 });5976 });
5954 const remainder = try block.addBinOp(src, Type.initTag(.u64), .bit_and, operand_coerced, align_minus_1);5977 const remainder = try block.addBinOp(.bit_and, operand_coerced, align_minus_1);
5955 const is_aligned = try block.addBinOp(src, Type.initTag(.bool), .cmp_eq, remainder, zero);5978 const is_aligned = try block.addBinOp(.cmp_eq, remainder, zero);
5956 try sema.addSafetyCheck(block, is_aligned, .incorrect_alignment);5979 try sema.addSafetyCheck(block, is_aligned, .incorrect_alignment);
5957 }5980 }
5958 }5981 }
5959 return block.addUnOp(src, type_res, .bitcast, operand_coerced);5982 return block.addTyOp(.bitcast, type_res, operand_coerced);
5960}5983}
59615984
5962fn zirErrSetCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {5985fn zirErrSetCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
...@@ -6841,7 +6864,7 @@ fn coerce(...@@ -6841,7 +6864,7 @@ fn coerce(
6841 return sema.coerceVarArgParam(block, inst, inst_src);6864 return sema.coerceVarArgParam(block, inst, inst_src);
6842 }6865 }
68436866
6844 const inst_ty = sema.getTypeOfAirRef(inst);6867 const inst_ty = sema.getTypeOf(inst);
6845 // If the types are the same, we can return the operand.6868 // If the types are the same, we can return the operand.
6846 if (dest_type.eql(inst_ty))6869 if (dest_type.eql(inst_ty))
6847 return inst;6870 return inst;
...@@ -6950,7 +6973,7 @@ fn coerce(...@@ -6950,7 +6973,7 @@ fn coerce(
6950 (src_info.signedness == .signed and dst_info.signedness == .unsigned and dst_info.bits > src_info.bits))6973 (src_info.signedness == .signed and dst_info.signedness == .unsigned and dst_info.bits > src_info.bits))
6951 {6974 {
6952 try sema.requireRuntimeBlock(block, inst_src);6975 try sema.requireRuntimeBlock(block, inst_src);
6953 return block.addUnOp(inst_src, dest_type, .intcast, inst);6976 return block.addTyOp(.intcast, dest_type, inst);
6954 }6977 }
6955 }6978 }
6956 },6979 },
...@@ -6963,7 +6986,7 @@ fn coerce(...@@ -6963,7 +6986,7 @@ fn coerce(
6963 const dst_bits = dest_type.floatBits(target);6986 const dst_bits = dest_type.floatBits(target);
6964 if (dst_bits >= src_bits) {6987 if (dst_bits >= src_bits) {
6965 try sema.requireRuntimeBlock(block, inst_src);6988 try sema.requireRuntimeBlock(block, inst_src);
6966 return block.addUnOp(inst_src, dest_type, .floatcast, inst);6989 return block.addTyOp(.floatcast, dest_type, inst);
6967 }6990 }
6968 }6991 }
6969 },6992 },
...@@ -7062,7 +7085,7 @@ fn coerceVarArgParam(...@@ -7062,7 +7085,7 @@ fn coerceVarArgParam(
7062 inst: Air.Inst.Ref,7085 inst: Air.Inst.Ref,
7063 inst_src: LazySrcLoc,7086 inst_src: LazySrcLoc,
7064) !Air.Inst.Ref {7087) !Air.Inst.Ref {
7065 const inst_ty = sema.getTypeOfAirRef(inst);7088 const inst_ty = sema.getTypeOf(inst);
7066 switch (inst_ty.zigTypeTag()) {7089 switch (inst_ty.zigTypeTag()) {
7067 .ComptimeInt, .ComptimeFloat => return sema.mod.fail(&block.base, inst_src, "integer and float literals in var args function must be casted", .{}),7090 .ComptimeInt, .ComptimeFloat => return sema.mod.fail(&block.base, inst_src, "integer and float literals in var args function must be casted", .{}),
7068 else => {},7091 else => {},
...@@ -7121,7 +7144,7 @@ fn storePtr(...@@ -7121,7 +7144,7 @@ fn storePtr(
7121 // TODO handle if the element type requires comptime7144 // TODO handle if the element type requires comptime
71227145
7123 try sema.requireRuntimeBlock(block, src);7146 try sema.requireRuntimeBlock(block, src);
7124 _ = try block.addBinOp(src, Type.initTag(.void), .store, ptr, value);7147 _ = try block.addBinOp(.store, ptr, value);
7125}7148}
71267149
7127fn bitcast(7150fn bitcast(
...@@ -7221,7 +7244,7 @@ fn analyzeRef(...@@ -7221,7 +7244,7 @@ fn analyzeRef(
7221 }7244 }
72227245
7223 try sema.requireRuntimeBlock(block, src);7246 try sema.requireRuntimeBlock(block, src);
7224 return block.addUnOp(src, ptr_type, .ref, operand);7247 return block.addTyOp(.ref, ptr_type, operand);
7225}7248}
72267249
7227fn analyzeLoad(7250fn analyzeLoad(
...@@ -7231,7 +7254,7 @@ fn analyzeLoad(...@@ -7231,7 +7254,7 @@ fn analyzeLoad(
7231 ptr: Air.Inst.Ref,7254 ptr: Air.Inst.Ref,
7232 ptr_src: LazySrcLoc,7255 ptr_src: LazySrcLoc,
7233) InnerError!Air.Inst.Ref {7256) InnerError!Air.Inst.Ref {
7234 const ptr_ty = sema.getTypeOfAirRef(ptr);7257 const ptr_ty = sema.getTypeOf(ptr);
7235 const elem_ty = switch (ptr_ty.zigTypeTag()) {7258 const elem_ty = switch (ptr_ty.zigTypeTag()) {
7236 .Pointer => ptr_ty.elemType(),7259 .Pointer => ptr_ty.elemType(),
7237 else => return sema.mod.fail(&block.base, ptr_src, "expected pointer, found '{}'", .{ptr_ty}),7260 else => return sema.mod.fail(&block.base, ptr_src, "expected pointer, found '{}'", .{ptr_ty}),
...@@ -7257,15 +7280,19 @@ fn analyzeIsNull(...@@ -7257,15 +7280,19 @@ fn analyzeIsNull(
7257 const result_ty = Type.initTag(.bool);7280 const result_ty = Type.initTag(.bool);
7258 if (try sema.resolvePossiblyUndefinedValue(block, src, operand)) |opt_val| {7281 if (try sema.resolvePossiblyUndefinedValue(block, src, operand)) |opt_val| {
7259 if (opt_val.isUndef()) {7282 if (opt_val.isUndef()) {
7260 return sema.mod.constUndef(sema.arena, src, result_ty);7283 return sema.addConstUndef(result_ty);
7261 }7284 }
7262 const is_null = opt_val.isNull();7285 const is_null = opt_val.isNull();
7263 const bool_value = if (invert_logic) !is_null else is_null;7286 const bool_value = if (invert_logic) !is_null else is_null;
7264 return sema.mod.constBool(sema.arena, src, bool_value);7287 if (bool_value) {
7288 return Air.Inst.Ref.bool_true;
7289 } else {
7290 return Air.Inst.Ref.bool_false;
7291 }
7265 }7292 }
7266 try sema.requireRuntimeBlock(block, src);7293 try sema.requireRuntimeBlock(block, src);
7267 const inst_tag: Inst.Tag = if (invert_logic) .is_non_null else .is_null;7294 const air_tag: Air.Inst.Tag = if (invert_logic) .is_non_null else .is_null;
7268 return block.addUnOp(src, result_ty, inst_tag, operand);7295 return block.addUnOp(air_tag, operand);
7269}7296}
72707297
7271fn analyzeIsNonErr(7298fn analyzeIsNonErr(
...@@ -7275,18 +7302,22 @@ fn analyzeIsNonErr(...@@ -7275,18 +7302,22 @@ fn analyzeIsNonErr(
7275 operand: Air.Inst.Ref,7302 operand: Air.Inst.Ref,
7276) InnerError!Air.Inst.Ref {7303) InnerError!Air.Inst.Ref {
7277 const ot = operand.ty.zigTypeTag();7304 const ot = operand.ty.zigTypeTag();
7278 if (ot != .ErrorSet and ot != .ErrorUnion) return sema.mod.constBool(sema.arena, src, true);7305 if (ot != .ErrorSet and ot != .ErrorUnion) return Air.Inst.Ref.bool_true;
7279 if (ot == .ErrorSet) return sema.mod.constBool(sema.arena, src, false);7306 if (ot == .ErrorSet) return Air.Inst.Ref.bool_false;
7280 assert(ot == .ErrorUnion);7307 assert(ot == .ErrorUnion);
7281 const result_ty = Type.initTag(.bool);7308 const result_ty = Type.initTag(.bool);
7282 if (try sema.resolvePossiblyUndefinedValue(block, src, operand)) |err_union| {7309 if (try sema.resolvePossiblyUndefinedValue(block, src, operand)) |err_union| {
7283 if (err_union.isUndef()) {7310 if (err_union.isUndef()) {
7284 return sema.mod.constUndef(sema.arena, src, result_ty);7311 return sema.addConstUndef(result_ty);
7312 }
7313 if (err_union.getError() == null) {
7314 return Air.Inst.Ref.bool_true;
7315 } else {
7316 return Air.Inst.Ref.bool_false;
7285 }7317 }
7286 return sema.mod.constBool(sema.arena, src, err_union.getError() == null);
7287 }7318 }
7288 try sema.requireRuntimeBlock(block, src);7319 try sema.requireRuntimeBlock(block, src);
7289 return block.addUnOp(src, result_ty, .is_non_err, operand);7320 return block.addUnOp(.is_non_err, operand);
7290}7321}
72917322
7292fn analyzeSlice(7323fn analyzeSlice(
...@@ -7372,31 +7403,43 @@ fn cmpNumeric(...@@ -7372,31 +7403,43 @@ fn cmpNumeric(
7372 lhs: Air.Inst.Ref,7403 lhs: Air.Inst.Ref,
7373 rhs: Air.Inst.Ref,7404 rhs: Air.Inst.Ref,
7374 op: std.math.CompareOperator,7405 op: std.math.CompareOperator,
7406 lhs_src: LazySrcLoc,
7407 rhs_src: LazySrcLoc,
7375) InnerError!Air.Inst.Ref {7408) InnerError!Air.Inst.Ref {
7376 assert(lhs.ty.isNumeric());7409 const lhs_ty = sema.getTypeOf(lhs);
7377 assert(rhs.ty.isNumeric());7410 const rhs_ty = sema.getTypeOf(rhs);
7411
7412 assert(lhs_ty.isNumeric());
7413 assert(rhs_ty.isNumeric());
73787414
7379 const lhs_ty_tag = lhs.ty.zigTypeTag();7415 const lhs_ty_tag = lhs_ty.zigTypeTag();
7380 const rhs_ty_tag = rhs.ty.zigTypeTag();7416 const rhs_ty_tag = rhs_ty.zigTypeTag();
73817417
7382 if (lhs_ty_tag == .Vector and rhs_ty_tag == .Vector) {7418 if (lhs_ty_tag == .Vector and rhs_ty_tag == .Vector) {
7383 if (lhs.ty.arrayLen() != rhs.ty.arrayLen()) {7419 if (lhs_ty.arrayLen() != rhs_ty.arrayLen()) {
7384 return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{7420 return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{
7385 lhs.ty.arrayLen(),7421 lhs_ty.arrayLen(),
7386 rhs.ty.arrayLen(),7422 rhs_ty.arrayLen(),
7387 });7423 });
7388 }7424 }
7389 return sema.mod.fail(&block.base, src, "TODO implement support for vectors in cmpNumeric", .{});7425 return sema.mod.fail(&block.base, src, "TODO implement support for vectors in cmpNumeric", .{});
7390 } else if (lhs_ty_tag == .Vector or rhs_ty_tag == .Vector) {7426 } else if (lhs_ty_tag == .Vector or rhs_ty_tag == .Vector) {
7391 return sema.mod.fail(&block.base, src, "mixed scalar and vector operands to comparison operator: '{}' and '{}'", .{7427 return sema.mod.fail(&block.base, src, "mixed scalar and vector operands to comparison operator: '{}' and '{}'", .{
7392 lhs.ty,7428 lhs_ty,
7393 rhs.ty,7429 rhs_ty,
7394 });7430 });
7395 }7431 }
73967432
7397 if (lhs.value()) |lhs_val| {7433 if (try sema.resolvePossiblyUndefinedValue(block, lhs_src, lhs)) |lhs_val| {
7398 if (rhs.value()) |rhs_val| {7434 if (try sema.resolvePossiblyUndefinedValue(block, rhs_src, rhs)) |rhs_val| {
7399 return sema.mod.constBool(sema.arena, src, Value.compare(lhs_val, op, rhs_val));7435 if (lhs_val.isUndef() or rhs_val.isUndef()) {
7436 return sema.addConstUndef(Type.initTag(.bool));
7437 }
7438 if (Value.compare(lhs_val, op, rhs_val)) {
7439 return Air.Inst.Ref.bool_true;
7440 } else {
7441 return Air.Inst.Ref.bool_false;
7442 }
7400 }7443 }
7401 }7444 }
74027445
...@@ -7422,19 +7465,19 @@ fn cmpNumeric(...@@ -7422,19 +7465,19 @@ fn cmpNumeric(
7422 // Implicit cast the smaller one to the larger one.7465 // Implicit cast the smaller one to the larger one.
7423 const dest_type = x: {7466 const dest_type = x: {
7424 if (lhs_ty_tag == .ComptimeFloat) {7467 if (lhs_ty_tag == .ComptimeFloat) {
7425 break :x rhs.ty;7468 break :x rhs_ty;
7426 } else if (rhs_ty_tag == .ComptimeFloat) {7469 } else if (rhs_ty_tag == .ComptimeFloat) {
7427 break :x lhs.ty;7470 break :x lhs_ty;
7428 }7471 }
7429 if (lhs.ty.floatBits(target) >= rhs.ty.floatBits(target)) {7472 if (lhs_ty.floatBits(target) >= rhs_ty.floatBits(target)) {
7430 break :x lhs.ty;7473 break :x lhs_ty;
7431 } else {7474 } else {
7432 break :x rhs.ty;7475 break :x rhs_ty;
7433 }7476 }
7434 };7477 };
7435 const casted_lhs = try sema.coerce(block, dest_type, lhs, lhs.src);7478 const casted_lhs = try sema.coerce(block, dest_type, lhs, lhs_src);
7436 const casted_rhs = try sema.coerce(block, dest_type, rhs, rhs.src);7479 const casted_rhs = try sema.coerce(block, dest_type, rhs, rhs_src);
7437 return block.addBinOp(src, dest_type, Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs);7480 return block.addBinOp(Air.Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs);
7438 }7481 }
7439 // For mixed unsigned integer sizes, implicit cast both operands to the larger integer.7482 // For mixed unsigned integer sizes, implicit cast both operands to the larger integer.
7440 // For mixed signed and unsigned integers, implicit cast both operands to a signed7483 // For mixed signed and unsigned integers, implicit cast both operands to a signed
...@@ -7445,11 +7488,11 @@ fn cmpNumeric(...@@ -7445,11 +7488,11 @@ fn cmpNumeric(
7445 const lhs_is_signed = if (lhs.value()) |lhs_val|7488 const lhs_is_signed = if (lhs.value()) |lhs_val|
7446 lhs_val.compareWithZero(.lt)7489 lhs_val.compareWithZero(.lt)
7447 else7490 else
7448 (lhs.ty.isFloat() or lhs.ty.isSignedInt());7491 (lhs_ty.isFloat() or lhs_ty.isSignedInt());
7449 const rhs_is_signed = if (rhs.value()) |rhs_val|7492 const rhs_is_signed = if (rhs.value()) |rhs_val|
7450 rhs_val.compareWithZero(.lt)7493 rhs_val.compareWithZero(.lt)
7451 else7494 else
7452 (rhs.ty.isFloat() or rhs.ty.isSignedInt());7495 (rhs_ty.isFloat() or rhs_ty.isSignedInt());
7453 const dest_int_is_signed = lhs_is_signed or rhs_is_signed;7496 const dest_int_is_signed = lhs_is_signed or rhs_is_signed;
74547497
7455 var dest_float_type: ?Type = null;7498 var dest_float_type: ?Type = null;
...@@ -7457,7 +7500,7 @@ fn cmpNumeric(...@@ -7457,7 +7500,7 @@ fn cmpNumeric(
7457 var lhs_bits: usize = undefined;7500 var lhs_bits: usize = undefined;
7458 if (lhs.value()) |lhs_val| {7501 if (lhs.value()) |lhs_val| {
7459 if (lhs_val.isUndef())7502 if (lhs_val.isUndef())
7460 return sema.mod.constUndef(sema.arena, src, Type.initTag(.bool));7503 return sema.addConstUndef(Type.initTag(.bool));
7461 const is_unsigned = if (lhs_is_float) x: {7504 const is_unsigned = if (lhs_is_float) x: {
7462 var bigint_space: Value.BigIntSpace = undefined;7505 var bigint_space: Value.BigIntSpace = undefined;
7463 var bigint = try lhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);7506 var bigint = try lhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);
...@@ -7465,8 +7508,8 @@ fn cmpNumeric(...@@ -7465,8 +7508,8 @@ fn cmpNumeric(
7465 const zcmp = lhs_val.orderAgainstZero();7508 const zcmp = lhs_val.orderAgainstZero();
7466 if (lhs_val.floatHasFraction()) {7509 if (lhs_val.floatHasFraction()) {
7467 switch (op) {7510 switch (op) {
7468 .eq => return sema.mod.constBool(sema.arena, src, false),7511 .eq => return Air.Inst.Ref.bool_false,
7469 .neq => return sema.mod.constBool(sema.arena, src, true),7512 .neq => return Air.Inst.Ref.bool_true,
7470 else => {},7513 else => {},
7471 }7514 }
7472 if (zcmp == .lt) {7515 if (zcmp == .lt) {
...@@ -7483,16 +7526,16 @@ fn cmpNumeric(...@@ -7483,16 +7526,16 @@ fn cmpNumeric(
7483 };7526 };
7484 lhs_bits += @boolToInt(is_unsigned and dest_int_is_signed);7527 lhs_bits += @boolToInt(is_unsigned and dest_int_is_signed);
7485 } else if (lhs_is_float) {7528 } else if (lhs_is_float) {
7486 dest_float_type = lhs.ty;7529 dest_float_type = lhs_ty;
7487 } else {7530 } else {
7488 const int_info = lhs.ty.intInfo(target);7531 const int_info = lhs_ty.intInfo(target);
7489 lhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);7532 lhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);
7490 }7533 }
74917534
7492 var rhs_bits: usize = undefined;7535 var rhs_bits: usize = undefined;
7493 if (rhs.value()) |rhs_val| {7536 if (rhs.value()) |rhs_val| {
7494 if (rhs_val.isUndef())7537 if (rhs_val.isUndef())
7495 return sema.mod.constUndef(sema.arena, src, Type.initTag(.bool));7538 return sema.addConstUndef(Type.initTag(.bool));
7496 const is_unsigned = if (rhs_is_float) x: {7539 const is_unsigned = if (rhs_is_float) x: {
7497 var bigint_space: Value.BigIntSpace = undefined;7540 var bigint_space: Value.BigIntSpace = undefined;
7498 var bigint = try rhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);7541 var bigint = try rhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);
...@@ -7500,8 +7543,8 @@ fn cmpNumeric(...@@ -7500,8 +7543,8 @@ fn cmpNumeric(
7500 const zcmp = rhs_val.orderAgainstZero();7543 const zcmp = rhs_val.orderAgainstZero();
7501 if (rhs_val.floatHasFraction()) {7544 if (rhs_val.floatHasFraction()) {
7502 switch (op) {7545 switch (op) {
7503 .eq => return sema.mod.constBool(sema.arena, src, false),7546 .eq => return Air.Inst.Ref.bool_false,
7504 .neq => return sema.mod.constBool(sema.arena, src, true),7547 .neq => return Air.Inst.Ref.bool_true,
7505 else => {},7548 else => {},
7506 }7549 }
7507 if (zcmp == .lt) {7550 if (zcmp == .lt) {
...@@ -7518,9 +7561,9 @@ fn cmpNumeric(...@@ -7518,9 +7561,9 @@ fn cmpNumeric(
7518 };7561 };
7519 rhs_bits += @boolToInt(is_unsigned and dest_int_is_signed);7562 rhs_bits += @boolToInt(is_unsigned and dest_int_is_signed);
7520 } else if (rhs_is_float) {7563 } else if (rhs_is_float) {
7521 dest_float_type = rhs.ty;7564 dest_float_type = rhs_ty;
7522 } else {7565 } else {
7523 const int_info = rhs.ty.intInfo(target);7566 const int_info = rhs_ty.intInfo(target);
7524 rhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);7567 rhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);
7525 }7568 }
75267569
...@@ -7532,10 +7575,10 @@ fn cmpNumeric(...@@ -7532,10 +7575,10 @@ fn cmpNumeric(
7532 const signedness: std.builtin.Signedness = if (dest_int_is_signed) .signed else .unsigned;7575 const signedness: std.builtin.Signedness = if (dest_int_is_signed) .signed else .unsigned;
7533 break :blk try Module.makeIntType(sema.arena, signedness, casted_bits);7576 break :blk try Module.makeIntType(sema.arena, signedness, casted_bits);
7534 };7577 };
7535 const casted_lhs = try sema.coerce(block, dest_type, lhs, lhs.src);7578 const casted_lhs = try sema.coerce(block, dest_type, lhs, lhs_src);
7536 const casted_rhs = try sema.coerce(block, dest_type, rhs, rhs.src);7579 const casted_rhs = try sema.coerce(block, dest_type, rhs, rhs_src);
75377580
7538 return block.addBinOp(src, Type.initTag(.bool), Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs);7581 return block.addBinOp(Air.Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs);
7539}7582}
75407583
7541fn wrapOptional(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) !Air.Inst.Index {7584fn wrapOptional(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) !Air.Inst.Index {
...@@ -7544,7 +7587,7 @@ fn wrapOptional(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Ins...@@ -7544,7 +7587,7 @@ fn wrapOptional(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Ins
7544 }7587 }
75457588
7546 try sema.requireRuntimeBlock(block, inst.src);7589 try sema.requireRuntimeBlock(block, inst.src);
7547 return block.addUnOp(inst.src, dest_type, .wrap_optional, inst);7590 return block.addTyOp(.wrap_optional, dest_type, inst);
7548}7591}
75497592
7550fn wrapErrorUnion(7593fn wrapErrorUnion(
...@@ -7617,19 +7660,24 @@ fn wrapErrorUnion(...@@ -7617,19 +7660,24 @@ fn wrapErrorUnion(
7617 // we are coercing from E to E!T7660 // we are coercing from E to E!T
7618 if (inst.ty.zigTypeTag() == .ErrorSet) {7661 if (inst.ty.zigTypeTag() == .ErrorSet) {
7619 var coerced = try sema.coerce(block, err_union.data.error_set, inst, inst.src);7662 var coerced = try sema.coerce(block, err_union.data.error_set, inst, inst.src);
7620 return block.addUnOp(inst.src, dest_type, .wrap_errunion_err, coerced);7663 return block.addTyOp(.wrap_errunion_err, dest_type, coerced);
7621 } else {7664 } else {
7622 var coerced = try sema.coerce(block, err_union.data.payload, inst, inst.src);7665 var coerced = try sema.coerce(block, err_union.data.payload, inst, inst.src);
7623 return block.addUnOp(inst.src, dest_type, .wrap_errunion_payload, coerced);7666 return block.addTyOp(.wrap_errunion_payload, dest_type, coerced);
7624 }7667 }
7625}7668}
76267669
7627fn resolvePeerTypes(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, instructions: []Air.Inst.Index) !Type {7670fn resolvePeerTypes(
7671 sema: *Sema,
7672 block: *Scope.Block,
7673 src: LazySrcLoc,
7674 instructions: []Air.Inst.Ref,
7675) !Type {
7628 if (instructions.len == 0)7676 if (instructions.len == 0)
7629 return Type.initTag(.noreturn);7677 return Type.initTag(.noreturn);
76307678
7631 if (instructions.len == 1)7679 if (instructions.len == 1)
7632 return instructions[0].ty;7680 return sema.getTypeOf(instructions[0]);
76337681
7634 const target = sema.mod.getTarget();7682 const target = sema.mod.getTarget();
76357683
...@@ -7989,7 +8037,7 @@ fn enumFieldSrcLoc(...@@ -7989,7 +8037,7 @@ fn enumFieldSrcLoc(
7989}8037}
79908038
7991/// Returns the type of the AIR instruction.8039/// Returns the type of the AIR instruction.
7992fn getTypeOfAirRef(sema: *Sema, air_ref: Air.Inst.Ref) Type {8040fn getTypeOf(sema: *Sema, air_ref: Air.Inst.Ref) Type {
7993 switch (air_ref) {8041 switch (air_ref) {
7994 .none => unreachable,8042 .none => unreachable,
7995 .u8_type => return Type.initTag(.u8),8043 .u8_type => return Type.initTag(.u8),
...@@ -8045,21 +8093,13 @@ fn getTypeOfAirRef(sema: *Sema, air_ref: Air.Inst.Ref) Type {...@@ -8045,21 +8093,13 @@ fn getTypeOfAirRef(sema: *Sema, air_ref: Air.Inst.Ref) Type {
8045 .fn_ccc_void_no_args_type => return Type.initTag(.fn_ccc_void_no_args),8093 .fn_ccc_void_no_args_type => return Type.initTag(.fn_ccc_void_no_args),
8046 .single_const_pointer_to_comptime_int_type => return Type.initTag(.single_const_pointer_to_comptime_int),8094 .single_const_pointer_to_comptime_int_type => return Type.initTag(.single_const_pointer_to_comptime_int),
8047 .const_slice_u8_type => return Type.initTag(.const_slice_u8),8095 .const_slice_u8_type => return Type.initTag(.const_slice_u8),
8048 else => return sema.getAirType(air_ref),8096 else => {},
8049 }
8050}
8051
8052/// Asserts the AIR instruction is a `const_ty` and returns the type.
8053fn getAirType(sema: *Sema, air_ref: Air.Inst.Ref) Type {
8054 var i: usize = @enumToInt(air_ref);
8055 if (i < Air.Inst.Ref.typed_value_map.len) {
8056 return Air.Inst.Ref.typed_value_map[i].val.toType(undefined) catch unreachable;
8057 }8097 }
8058 i -= Air.Inst.Ref.typed_value_map.len;8098 const air_index = @as(usize, @enumToInt(air_ref)) - Air.Inst.Ref.typed_value_map.len;
8059 const air_tags = sema.air_instructions.items(.tag);8099 const air_tags = sema.air_instructions.items(.tag);
8060 const air_datas = sema.air_instructions.items(.data);8100 const air_datas = sema.air_instructions.items(.data);
8061 assert(air_tags[i] == .const_ty);8101 assert(air_tags[air_index] == .const_ty);
8062 return air_datas[i].ty;8102 return air_datas[air_index].ty;
8063}8103}
80648104
8065pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {8105pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
...@@ -8126,7 +8166,15 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {...@@ -8126,7 +8166,15 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
8126 return indexToRef(@intCast(u32, sema.air_instructions.len - 1));8166 return indexToRef(@intCast(u32, sema.air_instructions.len - 1));
8127}8167}
81288168
8129pub fn addConstant(sema: *Sema, ty: Type, val: Value) InnerError!Air.Inst.Ref {8169fn addIntUnsigned(sema: *Sema, ty: Type, int: u64) InnerError!Air.Inst.Ref {
8170 return sema.addConstant(ty, try Value.Tag.int_u64.create(sema.arena, int));
8171}
8172
8173fn addConstUndef(sema: *Sema, ty: Type) InnerError!Air.Inst.Ref {
8174 return sema.addConstant(ty, Value.initTag(.undef));
8175}
8176
8177fn addConstant(sema: *Sema, ty: Type, val: Value) InnerError!Air.Inst.Ref {
8130 const gpa = sema.gpa;8178 const gpa = sema.gpa;
8131 const ty_inst = try sema.addType(ty);8179 const ty_inst = try sema.addType(ty);
8132 try sema.air_values.append(gpa, val);8180 try sema.air_values.append(gpa, val);