| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | //! Semantic analysis of ZIR instructions. | 1 | //! Semantic analysis of ZIR instructions. |
| 2 | //! Shared to every Block. Stored on the stack. | 2 | //! Shared to every Block. Stored on the stack. |
| 3 | //! State used for compiling a `Zir` into TZIR. | 3 | //! State used for compiling a `Zir` into AIR. |
| 4 | //! Transforms untyped ZIR instructions into semantically-analyzed TZIR instructions. | 4 | //! Transforms untyped ZIR instructions into semantically-analyzed AIR instructions. |
| 5 | //! Does type checking, comptime control flow, and safety-check generation. | 5 | //! Does type checking, comptime control flow, and safety-check generation. |
| 6 | //! This is the the heart of the Zig compiler. | 6 | //! This is the the heart of the Zig compiler. |
| 7 | | 7 | |
| ... | @@ -11,7 +11,7 @@ gpa: *Allocator, | ... | @@ -11,7 +11,7 @@ gpa: *Allocator, |
| 11 | /// Points to the arena allocator of the Decl. | 11 | /// Points to the arena allocator of the Decl. |
| 12 | arena: *Allocator, | 12 | arena: *Allocator, |
| 13 | code: Zir, | 13 | code: Zir, |
| 14 | /// Maps ZIR to TZIR. | 14 | /// Maps ZIR to AIR. |
| 15 | inst_map: []*Inst, | 15 | inst_map: []*Inst, |
| 16 | /// When analyzing an inline function call, owner_decl is the Decl of the caller | 16 | /// When analyzing an inline function call, owner_decl is the Decl of the caller |
| 17 | /// and `src_decl` of `Scope.Block` is the `Decl` of the callee. | 17 | /// and `src_decl` of `Scope.Block` is the `Decl` of the callee. |
| ... | @@ -26,9 +26,9 @@ owner_func: ?*Module.Fn, | ... | @@ -26,9 +26,9 @@ owner_func: ?*Module.Fn, |
| 26 | /// This starts out the same as `owner_func` and then diverges in the case of | 26 | /// This starts out the same as `owner_func` and then diverges in the case of |
| 27 | /// an inline or comptime function call. | 27 | /// an inline or comptime function call. |
| 28 | func: ?*Module.Fn, | 28 | func: ?*Module.Fn, |
| 29 | /// For now, TZIR requires arg instructions to be the first N instructions in the | 29 | /// For now, AIR requires arg instructions to be the first N instructions in the |
| 30 | /// TZIR code. We store references here for the purpose of `resolveInst`. | 30 | /// AIR code. We store references here for the purpose of `resolveInst`. |
| 31 | /// This can get reworked with TZIR memory layout changes, into simply: | 31 | /// This can get reworked with AIR memory layout changes, into simply: |
| 32 | /// > Denormalized data to make `resolveInst` faster. This is 0 if not inside a function, | 32 | /// > Denormalized data to make `resolveInst` faster. This is 0 if not inside a function, |
| 33 | /// > otherwise it is the number of parameters of the function. | 33 | /// > otherwise it is the number of parameters of the function. |
| 34 | /// > param_count: u32 | 34 | /// > param_count: u32 |
| ... | @@ -505,17 +505,17 @@ fn zirExtended(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro | ... | @@ -505,17 +505,17 @@ fn zirExtended(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro |
| 505 | } | 505 | } |
| 506 | } | 506 | } |
| 507 | | 507 | |
| 508 | /// TODO when we rework TZIR memory layout, this function will no longer have a possible error. | 508 | /// TODO when we rework AIR memory layout, this function will no longer have a possible error. |
| 509 | pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) error{OutOfMemory}!*ir.Inst { | 509 | pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) error{OutOfMemory}!*ir.Inst { |
| 510 | var i: usize = @enumToInt(zir_ref); | 510 | var i: usize = @enumToInt(zir_ref); |
| 511 | | 511 | |
| 512 | // First section of indexes correspond to a set number of constant values. | 512 | // First section of indexes correspond to a set number of constant values. |
| 513 | if (i < Zir.Inst.Ref.typed_value_map.len) { | 513 | if (i < Zir.Inst.Ref.typed_value_map.len) { |
| 514 | // TODO when we rework TZIR memory layout, this function can be as simple as: | 514 | // TODO when we rework AIR memory layout, this function can be as simple as: |
| 515 | // if (zir_ref < Zir.const_inst_list.len + sema.param_count) | 515 | // if (zir_ref < Zir.const_inst_list.len + sema.param_count) |
| 516 | // return zir_ref; | 516 | // return zir_ref; |
| 517 | // Until then we allocate memory for a new, mutable `ir.Inst` to match what | 517 | // Until then we allocate memory for a new, mutable `ir.Inst` to match what |
| 518 | // TZIR expects. | 518 | // AIR expects. |
| 519 | return sema.mod.constInst(sema.arena, .unneeded, Zir.Inst.Ref.typed_value_map[i]); | 519 | return sema.mod.constInst(sema.arena, .unneeded, Zir.Inst.Ref.typed_value_map[i]); |
| 520 | } | 520 | } |
| 521 | i -= Zir.Inst.Ref.typed_value_map.len; | 521 | i -= Zir.Inst.Ref.typed_value_map.len; |
| ... | @@ -526,7 +526,7 @@ pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) error{OutOfMemory}!*ir.In | ... | @@ -526,7 +526,7 @@ pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) error{OutOfMemory}!*ir.In |
| 526 | } | 526 | } |
| 527 | i -= sema.param_inst_list.len; | 527 | i -= sema.param_inst_list.len; |
| 528 | | 528 | |
| 529 | // Finally, the last section of indexes refers to the map of ZIR=>TZIR. | 529 | // Finally, the last section of indexes refers to the map of ZIR=>AIR. |
| 530 | return sema.inst_map[i]; | 530 | return sema.inst_map[i]; |
| 531 | } | 531 | } |
| 532 | | 532 | |
| ... | @@ -536,17 +536,17 @@ fn resolveConstString( | ... | @@ -536,17 +536,17 @@ fn resolveConstString( |
| 536 | src: LazySrcLoc, | 536 | src: LazySrcLoc, |
| 537 | zir_ref: Zir.Inst.Ref, | 537 | zir_ref: Zir.Inst.Ref, |
| 538 | ) ![]u8 { | 538 | ) ![]u8 { |
| 539 | const tzir_inst = try sema.resolveInst(zir_ref); | 539 | const air_inst = try sema.resolveInst(zir_ref); |
| 540 | const wanted_type = Type.initTag(.const_slice_u8); | 540 | const wanted_type = Type.initTag(.const_slice_u8); |
| 541 | const coerced_inst = try sema.coerce(block, wanted_type, tzir_inst, src); | 541 | const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); |
| 542 | const val = try sema.resolveConstValue(block, src, coerced_inst); | 542 | const val = try sema.resolveConstValue(block, src, coerced_inst); |
| 543 | return val.toAllocatedBytes(sema.arena); | 543 | return val.toAllocatedBytes(sema.arena); |
| 544 | } | 544 | } |
| 545 | | 545 | |
| 546 | fn resolveType(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type { | 546 | fn resolveType(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type { |
| 547 | const tzir_inst = try sema.resolveInst(zir_ref); | 547 | const air_inst = try sema.resolveInst(zir_ref); |
| 548 | const wanted_type = Type.initTag(.@"type"); | 548 | const wanted_type = Type.initTag(.@"type"); |
| 549 | const coerced_inst = try sema.coerce(block, wanted_type, tzir_inst, src); | 549 | const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); |
| 550 | const val = try sema.resolveConstValue(block, src, coerced_inst); | 550 | const val = try sema.resolveConstValue(block, src, coerced_inst); |
| 551 | return val.toType(sema.arena); | 551 | return val.toType(sema.arena); |
| 552 | } | 552 | } |
| ... | @@ -585,8 +585,8 @@ fn resolveAlreadyCoercedInt( | ... | @@ -585,8 +585,8 @@ fn resolveAlreadyCoercedInt( |
| 585 | comptime Int: type, | 585 | comptime Int: type, |
| 586 | ) !Int { | 586 | ) !Int { |
| 587 | comptime assert(@typeInfo(Int).Int.bits <= 64); | 587 | comptime assert(@typeInfo(Int).Int.bits <= 64); |
| 588 | const tzir_inst = try sema.resolveInst(zir_ref); | 588 | const air_inst = try sema.resolveInst(zir_ref); |
| 589 | const val = try sema.resolveConstValue(block, src, tzir_inst); | 589 | const val = try sema.resolveConstValue(block, src, air_inst); |
| 590 | switch (@typeInfo(Int).Int.signedness) { | 590 | switch (@typeInfo(Int).Int.signedness) { |
| 591 | .signed => return @intCast(Int, val.toSignedInt()), | 591 | .signed => return @intCast(Int, val.toSignedInt()), |
| 592 | .unsigned => return @intCast(Int, val.toUnsignedInt()), | 592 | .unsigned => return @intCast(Int, val.toUnsignedInt()), |
| ... | @@ -600,8 +600,8 @@ fn resolveInt( | ... | @@ -600,8 +600,8 @@ fn resolveInt( |
| 600 | zir_ref: Zir.Inst.Ref, | 600 | zir_ref: Zir.Inst.Ref, |
| 601 | dest_type: Type, | 601 | dest_type: Type, |
| 602 | ) !u64 { | 602 | ) !u64 { |
| 603 | const tzir_inst = try sema.resolveInst(zir_ref); | 603 | const air_inst = try sema.resolveInst(zir_ref); |
| 604 | const coerced = try sema.coerce(block, dest_type, tzir_inst, src); | 604 | const coerced = try sema.coerce(block, dest_type, air_inst, src); |
| 605 | const val = try sema.resolveConstValue(block, src, coerced); | 605 | const val = try sema.resolveConstValue(block, src, coerced); |
| 606 | | 606 | |
| 607 | return val.toUnsignedInt(); | 607 | return val.toUnsignedInt(); |
| ... | @@ -613,10 +613,10 @@ pub fn resolveInstConst( | ... | @@ -613,10 +613,10 @@ pub fn resolveInstConst( |
| 613 | src: LazySrcLoc, | 613 | src: LazySrcLoc, |
| 614 | zir_ref: Zir.Inst.Ref, | 614 | zir_ref: Zir.Inst.Ref, |
| 615 | ) InnerError!TypedValue { | 615 | ) InnerError!TypedValue { |
| 616 | const tzir_inst = try sema.resolveInst(zir_ref); | 616 | const air_inst = try sema.resolveInst(zir_ref); |
| 617 | const val = try sema.resolveConstValue(block, src, tzir_inst); | 617 | const val = try sema.resolveConstValue(block, src, air_inst); |
| 618 | return TypedValue{ | 618 | return TypedValue{ |
| 619 | .ty = tzir_inst.ty, | 619 | .ty = air_inst.ty, |
| 620 | .val = val, | 620 | .val = val, |
| 621 | }; | 621 | }; |
| 622 | } | 622 | } |
| ... | @@ -1552,7 +1552,7 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) InnerE | ... | @@ -1552,7 +1552,7 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) InnerE |
| 1552 | const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); | 1552 | const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); |
| 1553 | const body = sema.code.extra[extra.end..][0..extra.data.body_len]; | 1553 | const body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| 1554 | | 1554 | |
| 1555 | // TZIR expects a block outside the loop block too. | 1555 | // AIR expects a block outside the loop block too. |
| 1556 | const block_inst = try sema.arena.create(Inst.Block); | 1556 | const block_inst = try sema.arena.create(Inst.Block); |
| 1557 | block_inst.* = .{ | 1557 | block_inst.* = .{ |
| 1558 | .base = .{ | 1558 | .base = .{ |
| ... | @@ -3723,7 +3723,7 @@ fn analyzeSwitch( | ... | @@ -3723,7 +3723,7 @@ fn analyzeSwitch( |
| 3723 | defer merges.results.deinit(gpa); | 3723 | defer merges.results.deinit(gpa); |
| 3724 | defer merges.br_list.deinit(gpa); | 3724 | defer merges.br_list.deinit(gpa); |
| 3725 | | 3725 | |
| 3726 | // TODO when reworking TZIR memory layout make multi cases get generated as cases, | 3726 | // TODO when reworking AIR memory layout make multi cases get generated as cases, |
| 3727 | // not as part of the "else" block. | 3727 | // not as part of the "else" block. |
| 3728 | const cases = try sema.arena.alloc(Inst.SwitchBr.Case, scalar_cases_len); | 3728 | const cases = try sema.arena.alloc(Inst.SwitchBr.Case, scalar_cases_len); |
| 3729 | | 3729 | |
| ... | @@ -4788,9 +4788,9 @@ fn zirBoolBr( | ... | @@ -4788,9 +4788,9 @@ fn zirBoolBr( |
| 4788 | const rhs_result = try sema.resolveBody(rhs_block, body); | 4788 | const rhs_result = try sema.resolveBody(rhs_block, body); |
| 4789 | _ = try rhs_block.addBr(src, block_inst, rhs_result); | 4789 | _ = try rhs_block.addBr(src, block_inst, rhs_result); |
| 4790 | | 4790 | |
| 4791 | const tzir_then_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, then_block.instructions.items) }; | 4791 | const air_then_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, then_block.instructions.items) }; |
| 4792 | const tzir_else_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, else_block.instructions.items) }; | 4792 | const air_else_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, else_block.instructions.items) }; |
| 4793 | _ = try child_block.addCondBr(src, lhs, tzir_then_body, tzir_else_body); | 4793 | _ = try child_block.addCondBr(src, lhs, air_then_body, air_else_body); |
| 4794 | | 4794 | |
| 4795 | block_inst.body = .{ | 4795 | block_inst.body = .{ |
| 4796 | .instructions = try sema.arena.dupe(*Inst, child_block.instructions.items), | 4796 | .instructions = try sema.arena.dupe(*Inst, child_block.instructions.items), |
| ... | @@ -4879,18 +4879,18 @@ fn zirCondbr( | ... | @@ -4879,18 +4879,18 @@ fn zirCondbr( |
| 4879 | defer sub_block.instructions.deinit(sema.gpa); | 4879 | defer sub_block.instructions.deinit(sema.gpa); |
| 4880 | | 4880 | |
| 4881 | _ = try sema.analyzeBody(&sub_block, then_body); | 4881 | _ = try sema.analyzeBody(&sub_block, then_body); |
| 4882 | const tzir_then_body: ir.Body = .{ | 4882 | const air_then_body: ir.Body = .{ |
| 4883 | .instructions = try sema.arena.dupe(*Inst, sub_block.instructions.items), | 4883 | .instructions = try sema.arena.dupe(*Inst, sub_block.instructions.items), |
| 4884 | }; | 4884 | }; |
| 4885 | | 4885 | |
| 4886 | sub_block.instructions.shrinkRetainingCapacity(0); | 4886 | sub_block.instructions.shrinkRetainingCapacity(0); |
| 4887 | | 4887 | |
| 4888 | _ = try sema.analyzeBody(&sub_block, else_body); | 4888 | _ = try sema.analyzeBody(&sub_block, else_body); |
| 4889 | const tzir_else_body: ir.Body = .{ | 4889 | const air_else_body: ir.Body = .{ |
| 4890 | .instructions = try sema.arena.dupe(*Inst, sub_block.instructions.items), | 4890 | .instructions = try sema.arena.dupe(*Inst, sub_block.instructions.items), |
| 4891 | }; | 4891 | }; |
| 4892 | | 4892 | |
| 4893 | _ = try parent_block.addCondBr(src, cond, tzir_then_body, tzir_else_body); | 4893 | _ = try parent_block.addCondBr(src, cond, air_then_body, air_else_body); |
| 4894 | return always_noreturn; | 4894 | return always_noreturn; |
| 4895 | } | 4895 | } |
| 4896 | | 4896 | |