authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-20 20:37:44-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-31 21:09:22-07:00
logb7452fe35f514d4c04aae4582bc8071bc9e70f1b
treeb125fa735b9d2f9ea3791687f8ef22d75aca590a
parentfdc875ed0080cd2542a854a8cd6c627b25e9b7a4

stage2: rework astgen result locations

Motivating test case: ```zig export fn _start() noreturn { var x: u64 = 1; var y: u32 = 2; var thing: u32 = 1; const result = if (thing == 1) x else y; exit(); } ``` The main idea here is for astgen to output ideal ZIR depending on whether or not the sub-expressions of a block consume the result location. Here, neither `x` nor `y` consume the result location of the conditional expression block, and so the ZIR should communicate the result of the condbr using break instructions, not with the result location pointer. With this commit, this is accomplished: ``` %22 = alloc_inferred() %23 = block({ %24 = const(TypedValue{ .ty = type, .val = bool}) %25 = deref(%18) %26 = const(TypedValue{ .ty = comptime_int, .val = 1}) %27 = cmp_eq(%25, %26) %28 = as(%24, %27) %29 = condbr(%28, { %30 = deref(%4) < there is no longer a store instruction here > %31 = break("label_23", %30) }, { %32 = deref(%11) < there is no longer a store instruction here > %33 = break("label_23", %32) }) }) %34 = store_to_inferred_ptr(%22, %23) <-- the store is only here %35 = resolve_inferred_alloc(%22) ``` However if the result location gets consumed, the break instructions change to break_void, and the result value is communicated only by the stores, not by the break instructions. Implementation: * The GenZIR scope that conditional branches uses now has an optional result location pointer field and a count of how many times the result location ended up being an rvalue (not consumed). * When rvalue() is called on a result location for a block, it increments this counter. After generating the branches of a block, astgen for the conditional branch checks this count and if it is 2 then the store_to_block_ptr instructions are elided and it calls rvalue() using the block result (which will account for peer type resolution on the break operands). astgen has many functions disabled until they can be reworked with these new semantics. That will be done before merging the branch. There are some new rules for astgen to follow regarding result locations and what you are allowed/required to do depending on which one is passed to expr(). See the updated doc comments of ResultLoc for details. I also changed naming conventions of stuff in this commit, sorry about that.

6 files changed, 649 insertions(+), 529 deletions(-)

src/Module.zig+8-1
......@@ -697,6 +697,13 @@ pub const Scope = struct {
697697 continue_block: ?*zir.Inst.Block = null,
698698 /// only valid if label != null or (continue_block and break_block) != null
699699 break_result_loc: astgen.ResultLoc = undefined,
700 /// When a block has a pointer result location, here it is.
701 rl_ptr: ?*zir.Inst = null,
702 /// Keeps track of how many branches of a block did not actually
703 /// consume the result location. astgen uses this to figure out
704 /// whether to rely on break instructions or writing to the result
705 /// pointer for the result instruction.
706 rvalue_rl_count: usize = 0,
700707
701708 pub const Label = struct {
702709 token: ast.TokenIndex,
......@@ -1171,7 +1178,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
11711178 !gen_scope.instructions.items[gen_scope.instructions.items.len - 1].tag.isNoReturn())
11721179 {
11731180 const src = tree.token_locs[body_block.rbrace].start;
1174 _ = try astgen.addZIRNoOp(self, &gen_scope.base, src, .returnvoid);
1181 _ = try astgen.addZIRNoOp(self, &gen_scope.base, src, .return_void);
11751182 }
11761183
11771184 if (std.builtin.mode == .Debug and self.comp.verbose_ir) {
src/astgen.zig+259-143
......@@ -14,25 +14,30 @@ const InnerError = Module.InnerError;
1414
1515pub const ResultLoc = union(enum) {
1616 /// The expression is the right-hand side of assignment to `_`. Only the side-effects of the
17 /// expression should be generated.
17 /// expression should be generated. The result instruction from the expression must
18 /// be ignored.
1819 discard,
1920 /// The expression has an inferred type, and it will be evaluated as an rvalue.
2021 none,
2122 /// The expression must generate a pointer rather than a value. For example, the left hand side
2223 /// of an assignment uses this kind of result location.
2324 ref,
24 /// The expression will be type coerced into this type, but it will be evaluated as an rvalue.
25 /// The expression will be coerced into this type, but it will be evaluated as an rvalue.
2526 ty: *zir.Inst,
26 /// The expression must store its result into this typed pointer.
27 /// The expression must store its result into this typed pointer. The result instruction
28 /// from the expression must be ignored.
2729 ptr: *zir.Inst,
2830 /// The expression must store its result into this allocation, which has an inferred type.
31 /// The result instruction from the expression must be ignored.
2932 inferred_ptr: *zir.Inst.Tag.alloc_inferred.Type(),
3033 /// The expression must store its result into this pointer, which is a typed pointer that
3134 /// has been bitcasted to whatever the expression's type is.
35 /// The result instruction from the expression must be ignored.
3236 bitcasted_ptr: *zir.Inst.UnOp,
3337 /// There is a pointer for the expression to store its result into, however, its type
3438 /// is inferred based on peer type resolution for a `zir.Inst.Block`.
35 block_ptr: *zir.Inst.Block,
39 /// The result instruction from the expression must be ignored.
40 block_ptr: *Module.Scope.GenZIR,
3641};
3742
3843pub fn typeExpr(mod: *Module, scope: *Scope, type_node: *ast.Node) InnerError!*zir.Inst {
......@@ -179,6 +184,9 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst {
179184}
180185
181186/// Turn Zig AST into untyped ZIR istructions.
187/// When `rl` is discard, ptr, inferred_ptr, bitcasted_ptr, or inferred_ptr, the
188/// result instruction can be used to inspect whether it is isNoReturn() but that is it,
189/// it must otherwise not be used.
182190pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerError!*zir.Inst {
183191 switch (node.tag) {
184192 .Root => unreachable, // Top-level declaration.
......@@ -197,20 +205,20 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
197205 .FieldInitializer => unreachable, // Handled explicitly.
198206 .ContainerField => unreachable, // Handled explicitly.
199207
200 .Assign => return rlWrapVoid(mod, scope, rl, node, try assign(mod, scope, node.castTag(.Assign).?)),
201 .AssignBitAnd => return rlWrapVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitAnd).?, .bitand)),
202 .AssignBitOr => return rlWrapVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitOr).?, .bitor)),
203 .AssignBitShiftLeft => return rlWrapVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitShiftLeft).?, .shl)),
204 .AssignBitShiftRight => return rlWrapVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitShiftRight).?, .shr)),
205 .AssignBitXor => return rlWrapVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitXor).?, .xor)),
206 .AssignDiv => return rlWrapVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignDiv).?, .div)),
207 .AssignSub => return rlWrapVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignSub).?, .sub)),
208 .AssignSubWrap => return rlWrapVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignSubWrap).?, .subwrap)),
209 .AssignMod => return rlWrapVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignMod).?, .mod_rem)),
210 .AssignAdd => return rlWrapVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignAdd).?, .add)),
211 .AssignAddWrap => return rlWrapVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignAddWrap).?, .addwrap)),
212 .AssignMul => return rlWrapVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignMul).?, .mul)),
213 .AssignMulWrap => return rlWrapVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignMulWrap).?, .mulwrap)),
208 .Assign => return rvalueVoid(mod, scope, rl, node, try assign(mod, scope, node.castTag(.Assign).?)),
209 .AssignBitAnd => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitAnd).?, .bit_and)),
210 .AssignBitOr => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitOr).?, .bit_or)),
211 .AssignBitShiftLeft => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitShiftLeft).?, .shl)),
212 .AssignBitShiftRight => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitShiftRight).?, .shr)),
213 .AssignBitXor => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitXor).?, .xor)),
214 .AssignDiv => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignDiv).?, .div)),
215 .AssignSub => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignSub).?, .sub)),
216 .AssignSubWrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignSubWrap).?, .subwrap)),
217 .AssignMod => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignMod).?, .mod_rem)),
218 .AssignAdd => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignAdd).?, .add)),
219 .AssignAddWrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignAddWrap).?, .addwrap)),
220 .AssignMul => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignMul).?, .mul)),
221 .AssignMulWrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignMulWrap).?, .mulwrap)),
214222
215223 .Add => return simpleBinOp(mod, scope, rl, node.castTag(.Add).?, .add),
216224 .AddWrap => return simpleBinOp(mod, scope, rl, node.castTag(.AddWrap).?, .addwrap),
......@@ -220,8 +228,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
220228 .MulWrap => return simpleBinOp(mod, scope, rl, node.castTag(.MulWrap).?, .mulwrap),
221229 .Div => return simpleBinOp(mod, scope, rl, node.castTag(.Div).?, .div),
222230 .Mod => return simpleBinOp(mod, scope, rl, node.castTag(.Mod).?, .mod_rem),
223 .BitAnd => return simpleBinOp(mod, scope, rl, node.castTag(.BitAnd).?, .bitand),
224 .BitOr => return simpleBinOp(mod, scope, rl, node.castTag(.BitOr).?, .bitor),
231 .BitAnd => return simpleBinOp(mod, scope, rl, node.castTag(.BitAnd).?, .bit_and),
232 .BitOr => return simpleBinOp(mod, scope, rl, node.castTag(.BitOr).?, .bit_or),
225233 .BitShiftLeft => return simpleBinOp(mod, scope, rl, node.castTag(.BitShiftLeft).?, .shl),
226234 .BitShiftRight => return simpleBinOp(mod, scope, rl, node.castTag(.BitShiftRight).?, .shr),
227235 .BitXor => return simpleBinOp(mod, scope, rl, node.castTag(.BitXor).?, .xor),
......@@ -239,15 +247,15 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
239247 .BoolAnd => return boolBinOp(mod, scope, rl, node.castTag(.BoolAnd).?),
240248 .BoolOr => return boolBinOp(mod, scope, rl, node.castTag(.BoolOr).?),
241249
242 .BoolNot => return rlWrap(mod, scope, rl, try boolNot(mod, scope, node.castTag(.BoolNot).?)),
243 .BitNot => return rlWrap(mod, scope, rl, try bitNot(mod, scope, node.castTag(.BitNot).?)),
244 .Negation => return rlWrap(mod, scope, rl, try negation(mod, scope, node.castTag(.Negation).?, .sub)),
245 .NegationWrap => return rlWrap(mod, scope, rl, try negation(mod, scope, node.castTag(.NegationWrap).?, .subwrap)),
250 .BoolNot => return rvalue(mod, scope, rl, try boolNot(mod, scope, node.castTag(.BoolNot).?)),
251 .BitNot => return rvalue(mod, scope, rl, try bitNot(mod, scope, node.castTag(.BitNot).?)),
252 .Negation => return rvalue(mod, scope, rl, try negation(mod, scope, node.castTag(.Negation).?, .sub)),
253 .NegationWrap => return rvalue(mod, scope, rl, try negation(mod, scope, node.castTag(.NegationWrap).?, .subwrap)),
246254
247255 .Identifier => return try identifier(mod, scope, rl, node.castTag(.Identifier).?),
248 .Asm => return rlWrap(mod, scope, rl, try assembly(mod, scope, node.castTag(.Asm).?)),
249 .StringLiteral => return rlWrap(mod, scope, rl, try stringLiteral(mod, scope, node.castTag(.StringLiteral).?)),
250 .IntegerLiteral => return rlWrap(mod, scope, rl, try integerLiteral(mod, scope, node.castTag(.IntegerLiteral).?)),
256 .Asm => return rvalue(mod, scope, rl, try assembly(mod, scope, node.castTag(.Asm).?)),
257 .StringLiteral => return rvalue(mod, scope, rl, try stringLiteral(mod, scope, node.castTag(.StringLiteral).?)),
258 .IntegerLiteral => return rvalue(mod, scope, rl, try integerLiteral(mod, scope, node.castTag(.IntegerLiteral).?)),
251259 .BuiltinCall => return builtinCall(mod, scope, rl, node.castTag(.BuiltinCall).?),
252260 .Call => return callExpr(mod, scope, rl, node.castTag(.Call).?),
253261 .Unreachable => return unreach(mod, scope, node.castTag(.Unreachable).?),
......@@ -255,34 +263,34 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
255263 .If => return ifExpr(mod, scope, rl, node.castTag(.If).?),
256264 .While => return whileExpr(mod, scope, rl, node.castTag(.While).?),
257265 .Period => return field(mod, scope, rl, node.castTag(.Period).?),
258 .Deref => return rlWrap(mod, scope, rl, try deref(mod, scope, node.castTag(.Deref).?)),
259 .AddressOf => return rlWrap(mod, scope, rl, try addressOf(mod, scope, node.castTag(.AddressOf).?)),
260 .FloatLiteral => return rlWrap(mod, scope, rl, try floatLiteral(mod, scope, node.castTag(.FloatLiteral).?)),
261 .UndefinedLiteral => return rlWrap(mod, scope, rl, try undefLiteral(mod, scope, node.castTag(.UndefinedLiteral).?)),
262 .BoolLiteral => return rlWrap(mod, scope, rl, try boolLiteral(mod, scope, node.castTag(.BoolLiteral).?)),
263 .NullLiteral => return rlWrap(mod, scope, rl, try nullLiteral(mod, scope, node.castTag(.NullLiteral).?)),
264 .OptionalType => return rlWrap(mod, scope, rl, try optionalType(mod, scope, node.castTag(.OptionalType).?)),
266 .Deref => return rvalue(mod, scope, rl, try deref(mod, scope, node.castTag(.Deref).?)),
267 .AddressOf => return rvalue(mod, scope, rl, try addressOf(mod, scope, node.castTag(.AddressOf).?)),
268 .FloatLiteral => return rvalue(mod, scope, rl, try floatLiteral(mod, scope, node.castTag(.FloatLiteral).?)),
269 .UndefinedLiteral => return rvalue(mod, scope, rl, try undefLiteral(mod, scope, node.castTag(.UndefinedLiteral).?)),
270 .BoolLiteral => return rvalue(mod, scope, rl, try boolLiteral(mod, scope, node.castTag(.BoolLiteral).?)),
271 .NullLiteral => return rvalue(mod, scope, rl, try nullLiteral(mod, scope, node.castTag(.NullLiteral).?)),
272 .OptionalType => return rvalue(mod, scope, rl, try optionalType(mod, scope, node.castTag(.OptionalType).?)),
265273 .UnwrapOptional => return unwrapOptional(mod, scope, rl, node.castTag(.UnwrapOptional).?),
266 .Block => return rlWrapVoid(mod, scope, rl, node, try blockExpr(mod, scope, node.castTag(.Block).?)),
274 .Block => return rvalueVoid(mod, scope, rl, node, try blockExpr(mod, scope, node.castTag(.Block).?)),
267275 .LabeledBlock => return labeledBlockExpr(mod, scope, rl, node.castTag(.LabeledBlock).?, .block),
268 .Break => return rlWrap(mod, scope, rl, try breakExpr(mod, scope, node.castTag(.Break).?)),
269 .Continue => return rlWrap(mod, scope, rl, try continueExpr(mod, scope, node.castTag(.Continue).?)),
270 .PtrType => return rlWrap(mod, scope, rl, try ptrType(mod, scope, node.castTag(.PtrType).?)),
276 .Break => return rvalue(mod, scope, rl, try breakExpr(mod, scope, node.castTag(.Break).?)),
277 .Continue => return rvalue(mod, scope, rl, try continueExpr(mod, scope, node.castTag(.Continue).?)),
278 .PtrType => return rvalue(mod, scope, rl, try ptrType(mod, scope, node.castTag(.PtrType).?)),
271279 .GroupedExpression => return expr(mod, scope, rl, node.castTag(.GroupedExpression).?.expr),
272 .ArrayType => return rlWrap(mod, scope, rl, try arrayType(mod, scope, node.castTag(.ArrayType).?)),
273 .ArrayTypeSentinel => return rlWrap(mod, scope, rl, try arrayTypeSentinel(mod, scope, node.castTag(.ArrayTypeSentinel).?)),
274 .EnumLiteral => return rlWrap(mod, scope, rl, try enumLiteral(mod, scope, node.castTag(.EnumLiteral).?)),
275 .MultilineStringLiteral => return rlWrap(mod, scope, rl, try multilineStrLiteral(mod, scope, node.castTag(.MultilineStringLiteral).?)),
276 .CharLiteral => return rlWrap(mod, scope, rl, try charLiteral(mod, scope, node.castTag(.CharLiteral).?)),
277 .SliceType => return rlWrap(mod, scope, rl, try sliceType(mod, scope, node.castTag(.SliceType).?)),
278 .ErrorUnion => return rlWrap(mod, scope, rl, try typeInixOp(mod, scope, node.castTag(.ErrorUnion).?, .error_union_type)),
279 .MergeErrorSets => return rlWrap(mod, scope, rl, try typeInixOp(mod, scope, node.castTag(.MergeErrorSets).?, .merge_error_sets)),
280 .AnyFrameType => return rlWrap(mod, scope, rl, try anyFrameType(mod, scope, node.castTag(.AnyFrameType).?)),
281 .ErrorSetDecl => return rlWrap(mod, scope, rl, try errorSetDecl(mod, scope, node.castTag(.ErrorSetDecl).?)),
282 .ErrorType => return rlWrap(mod, scope, rl, try errorType(mod, scope, node.castTag(.ErrorType).?)),
280 .ArrayType => return rvalue(mod, scope, rl, try arrayType(mod, scope, node.castTag(.ArrayType).?)),
281 .ArrayTypeSentinel => return rvalue(mod, scope, rl, try arrayTypeSentinel(mod, scope, node.castTag(.ArrayTypeSentinel).?)),
282 .EnumLiteral => return rvalue(mod, scope, rl, try enumLiteral(mod, scope, node.castTag(.EnumLiteral).?)),
283 .MultilineStringLiteral => return rvalue(mod, scope, rl, try multilineStrLiteral(mod, scope, node.castTag(.MultilineStringLiteral).?)),
284 .CharLiteral => return rvalue(mod, scope, rl, try charLiteral(mod, scope, node.castTag(.CharLiteral).?)),
285 .SliceType => return rvalue(mod, scope, rl, try sliceType(mod, scope, node.castTag(.SliceType).?)),
286 .ErrorUnion => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node.castTag(.ErrorUnion).?, .error_union_type)),
287 .MergeErrorSets => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node.castTag(.MergeErrorSets).?, .merge_error_sets)),
288 .AnyFrameType => return rvalue(mod, scope, rl, try anyFrameType(mod, scope, node.castTag(.AnyFrameType).?)),
289 .ErrorSetDecl => return rvalue(mod, scope, rl, try errorSetDecl(mod, scope, node.castTag(.ErrorSetDecl).?)),
290 .ErrorType => return rvalue(mod, scope, rl, try errorType(mod, scope, node.castTag(.ErrorType).?)),
283291 .For => return forExpr(mod, scope, rl, node.castTag(.For).?),
284292 .ArrayAccess => return arrayAccess(mod, scope, rl, node.castTag(.ArrayAccess).?),
285 .Slice => return rlWrap(mod, scope, rl, try sliceExpr(mod, scope, node.castTag(.Slice).?)),
293 .Slice => return rvalue(mod, scope, rl, try sliceExpr(mod, scope, node.castTag(.Slice).?)),
286294 .Catch => return catchExpr(mod, scope, rl, node.castTag(.Catch).?),
287295 .Comptime => return comptimeKeyword(mod, scope, rl, node.castTag(.Comptime).?),
288296 .OrElse => return orelseExpr(mod, scope, rl, node.castTag(.OrElse).?),
......@@ -341,6 +349,9 @@ pub fn comptimeExpr(mod: *Module, parent_scope: *Scope, rl: ResultLoc, node: *as
341349}
342350
343351fn breakExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowExpression) InnerError!*zir.Inst {
352 if (true) {
353 @panic("TODO reimplement this");
354 }
344355 const tree = parent_scope.tree();
345356 const src = tree.token_locs[node.ltoken].start;
346357
......@@ -563,8 +574,8 @@ fn blockExprStmts(mod: *Module, parent_scope: *Scope, node: *ast.Node, statement
563574 scope = try varDecl(mod, scope, var_decl_node, &block_arena.allocator);
564575 },
565576 .Assign => try assign(mod, scope, statement.castTag(.Assign).?),
566 .AssignBitAnd => try assignOp(mod, scope, statement.castTag(.AssignBitAnd).?, .bitand),
567 .AssignBitOr => try assignOp(mod, scope, statement.castTag(.AssignBitOr).?, .bitor),
577 .AssignBitAnd => try assignOp(mod, scope, statement.castTag(.AssignBitAnd).?, .bit_and),
578 .AssignBitOr => try assignOp(mod, scope, statement.castTag(.AssignBitOr).?, .bit_or),
568579 .AssignBitShiftLeft => try assignOp(mod, scope, statement.castTag(.AssignBitShiftLeft).?, .shl),
569580 .AssignBitShiftRight => try assignOp(mod, scope, statement.castTag(.AssignBitShiftRight).?, .shr),
570581 .AssignBitXor => try assignOp(mod, scope, statement.castTag(.AssignBitXor).?, .xor),
......@@ -644,6 +655,7 @@ fn varDecl(
644655
645656 // Namespace vars shadowing detection
646657 if (mod.lookupDeclName(scope, ident_name)) |_| {
658 // TODO add note for other definition
647659 return mod.fail(scope, name_src, "redefinition of '{s}'", .{ident_name});
648660 }
649661 const init_node = node.getInitNode() orelse
......@@ -751,14 +763,14 @@ fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerErr
751763 .val = Value.initTag(.bool_type),
752764 });
753765 const operand = try expr(mod, scope, .{ .ty = bool_type }, node.rhs);
754 return addZIRUnOp(mod, scope, src, .boolnot, operand);
766 return addZIRUnOp(mod, scope, src, .bool_not, operand);
755767}
756768
757769fn bitNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst {
758770 const tree = scope.tree();
759771 const src = tree.token_locs[node.op_token].start;
760772 const operand = try expr(mod, scope, .none, node.rhs);
761 return addZIRUnOp(mod, scope, src, .bitnot, operand);
773 return addZIRUnOp(mod, scope, src, .bit_not, operand);
762774}
763775
764776fn negation(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp, op_inst_tag: zir.Inst.Tag) InnerError!*zir.Inst {
......@@ -1101,7 +1113,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
11011113 if (rl == .ref) {
11021114 return addZIRInst(mod, scope, src, zir.Inst.DeclRef, .{ .decl = decl }, .{});
11031115 } else {
1104 return rlWrap(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.DeclVal, .{
1116 return rvalue(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.DeclVal, .{
11051117 .decl = decl,
11061118 }, .{}));
11071119 }
......@@ -1200,6 +1212,9 @@ fn orelseCatchExpr(
12001212 rhs: *ast.Node,
12011213 payload_node: ?*ast.Node,
12021214) InnerError!*zir.Inst {
1215 if (true) {
1216 @panic("TODO reimplement this");
1217 }
12031218 const tree = scope.tree();
12041219 const src = tree.token_locs[op_token].start;
12051220
......@@ -1308,7 +1323,7 @@ pub fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleI
13081323 .field_name = field_name,
13091324 });
13101325 }
1311 return rlWrap(mod, scope, rl, try addZirInstTag(mod, scope, src, .field_val, .{
1326 return rvalue(mod, scope, rl, try addZirInstTag(mod, scope, src, .field_val, .{
13121327 .object = try expr(mod, scope, .none, node.lhs),
13131328 .field_name = field_name,
13141329 }));
......@@ -1338,7 +1353,7 @@ fn namedField(
13381353 .field_name = try comptimeExpr(mod, scope, string_rl, params[1]),
13391354 });
13401355 }
1341 return rlWrap(mod, scope, rl, try addZirInstTag(mod, scope, src, .field_val_named, .{
1356 return rvalue(mod, scope, rl, try addZirInstTag(mod, scope, src, .field_val_named, .{
13421357 .object = try expr(mod, scope, .none, params[0]),
13431358 .field_name = try comptimeExpr(mod, scope, string_rl, params[1]),
13441359 }));
......@@ -1359,7 +1374,7 @@ fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Array
13591374 .index = try expr(mod, scope, index_rl, node.index_expr),
13601375 });
13611376 }
1362 return rlWrap(mod, scope, rl, try addZirInstTag(mod, scope, src, .elem_val, .{
1377 return rvalue(mod, scope, rl, try addZirInstTag(mod, scope, src, .elem_val, .{
13631378 .array = try expr(mod, scope, .none, node.lhs),
13641379 .index = try expr(mod, scope, index_rl, node.index_expr),
13651380 }));
......@@ -1416,7 +1431,7 @@ fn simpleBinOp(
14161431 const rhs = try expr(mod, scope, .none, infix_node.rhs);
14171432
14181433 const result = try addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);
1419 return rlWrap(mod, scope, rl, result);
1434 return rvalue(mod, scope, rl, result);
14201435}
14211436
14221437fn boolBinOp(
......@@ -1498,7 +1513,7 @@ fn boolBinOp(
14981513 condbr.positionals.else_body = .{ .instructions = try rhs_scope.arena.dupe(*zir.Inst, rhs_scope.instructions.items) };
14991514 }
15001515
1501 return rlWrap(mod, scope, rl, &block.base);
1516 return rvalue(mod, scope, rl, &block.base);
15021517}
15031518
15041519const CondKind = union(enum) {
......@@ -1578,6 +1593,7 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn
15781593 cond_kind = .{ .err_union = null };
15791594 }
15801595 }
1596 const block_branch_count = 2; // then and else
15811597 var block_scope: Scope.GenZIR = .{
15821598 .parent = scope,
15831599 .decl = scope.ownerDecl().?,
......@@ -1600,6 +1616,33 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn
16001616 .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items),
16011617 });
16021618
1619 // Depending on whether the result location is a pointer or value, different
1620 // ZIR needs to be generated. In the former case we rely on storing to the
1621 // pointer to communicate the result, and use breakvoid; in the latter case
1622 // the block break instructions will have the result values.
1623 // One more complication: when the result location is a pointer, we detect
1624 // the scenario where the result location is not consumed. In this case
1625 // we emit ZIR for the block break instructions to have the result values,
1626 // and then rvalue() on that to pass the value to the result location.
1627 const branch_rl: ResultLoc = switch (rl) {
1628 .discard, .none, .ty, .ptr, .ref => rl,
1629
1630 .inferred_ptr => |ptr| blk: {
1631 block_scope.rl_ptr = &ptr.base;
1632 break :blk .{ .block_ptr = &block_scope };
1633 },
1634
1635 .bitcasted_ptr => |ptr| blk: {
1636 block_scope.rl_ptr = &ptr.base;
1637 break :blk .{ .block_ptr = &block_scope };
1638 },
1639
1640 .block_ptr => |parent_block_scope| blk: {
1641 block_scope.rl_ptr = parent_block_scope.rl_ptr.?;
1642 break :blk .{ .block_ptr = &block_scope };
1643 },
1644 };
1645
16031646 const then_src = tree.token_locs[if_node.body.lastToken()].start;
16041647 var then_scope: Scope.GenZIR = .{
16051648 .parent = scope,
......@@ -1612,25 +1655,10 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn
16121655 // declare payload to the then_scope
16131656 const then_sub_scope = try cond_kind.thenSubScope(mod, &then_scope, then_src, if_node.payload);
16141657
1615 // Most result location types can be forwarded directly; however
1616 // if we need to write to a pointer which has an inferred type,
1617 // proper type inference requires peer type resolution on the if's
1618 // branches.
1619 const branch_rl: ResultLoc = switch (rl) {
1620 .discard, .none, .ty, .ptr, .ref => rl,
1621 .inferred_ptr, .bitcasted_ptr, .block_ptr => .{ .block_ptr = block },
1622 };
1623
16241658 const then_result = try expr(mod, then_sub_scope, branch_rl, if_node.body);
1625 if (!then_result.tag.isNoReturn()) {
1626 _ = try addZIRInst(mod, then_sub_scope, then_src, zir.Inst.Break, .{
1627 .block = block,
1628 .operand = then_result,
1629 }, .{});
1630 }
1631 condbr.positionals.then_body = .{
1632 .instructions = try then_scope.arena.dupe(*zir.Inst, then_scope.instructions.items),
1633 };
1659 // We hold off on the break instructions as well as copying the then/else
1660 // instructions into place until we know whether to keep store_to_block_ptr
1661 // instructions or not.
16341662
16351663 var else_scope: Scope.GenZIR = .{
16361664 .parent = scope,
......@@ -1640,34 +1668,127 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn
16401668 };
16411669 defer else_scope.instructions.deinit(mod.gpa);
16421670
1643 if (if_node.@"else") |else_node| {
1644 const else_src = tree.token_locs[else_node.body.lastToken()].start;
1671 var else_src: usize = undefined;
1672 var else_sub_scope: *Module.Scope = undefined;
1673 const else_result: ?*zir.Inst = if (if_node.@"else") |else_node| blk: {
1674 else_src = tree.token_locs[else_node.body.lastToken()].start;
16451675 // declare payload to the then_scope
1646 const else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload);
1676 else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload);
1677
1678 break :blk try expr(mod, else_sub_scope, branch_rl, else_node.body);
1679 } else blk: {
1680 else_src = tree.token_locs[if_node.lastToken()].start;
1681 else_sub_scope = &else_scope.base;
1682 block_scope.rvalue_rl_count += 1;
1683 break :blk null;
1684 };
16471685
1648 const else_result = try expr(mod, else_sub_scope, branch_rl, else_node.body);
1649 if (!else_result.tag.isNoReturn()) {
1650 _ = try addZIRInst(mod, else_sub_scope, else_src, zir.Inst.Break, .{
1651 .block = block,
1652 .operand = else_result,
1653 }, .{});
1654 }
1655 } else {
1656 // TODO Optimization opportunity: we can avoid an allocation and a memcpy here
1657 // by directly allocating the body for this one instruction.
1658 const else_src = tree.token_locs[if_node.lastToken()].start;
1659 _ = try addZIRInst(mod, &else_scope.base, else_src, zir.Inst.BreakVoid, .{
1660 .block = block,
1661 }, .{});
1686 // We now have enough information to decide whether the result instruction should
1687 // be communicated via result location pointer or break instructions.
1688 const Strategy = enum {
1689 /// Both branches will use break_void; result location is used to communicate the
1690 /// result instruction.
1691 break_void,
1692 /// Use break statements to pass the block result value, and call rvalue() at
1693 /// the end depending on rl. Also elide the store_to_block_ptr instructions
1694 /// depending on rl.
1695 break_operand,
1696 };
1697 var elide_store_to_block_ptr_instructions = false;
1698 const strategy: Strategy = switch (rl) {
1699 // In this branch there will not be any store_to_block_ptr instructions.
1700 .discard, .none, .ty, .ref => .break_operand,
1701 // The pointer got passed through to the sub-expressions, so we will use
1702 // break_void here.
1703 // In this branch there will not be any store_to_block_ptr instructions.
1704 .ptr => .break_void,
1705 .inferred_ptr, .bitcasted_ptr, .block_ptr => blk: {
1706 if (block_scope.rvalue_rl_count == 2) {
1707 // Neither prong of the if consumed the result location, so we can
1708 // use break instructions to create an rvalue.
1709 elide_store_to_block_ptr_instructions = true;
1710 break :blk Strategy.break_operand;
1711 } else {
1712 // Allow the store_to_block_ptr instructions to remain so that
1713 // semantic analysis can turn them into bitcasts.
1714 break :blk Strategy.break_void;
1715 }
1716 },
1717 };
1718 switch (strategy) {
1719 .break_void => {
1720 if (!then_result.tag.isNoReturn()) {
1721 _ = try addZIRNoOp(mod, then_sub_scope, then_src, .break_void);
1722 }
1723 if (else_result) |inst| {
1724 if (!inst.tag.isNoReturn()) {
1725 _ = try addZIRNoOp(mod, else_sub_scope, else_src, .break_void);
1726 }
1727 } else {
1728 _ = try addZIRNoOp(mod, else_sub_scope, else_src, .break_void);
1729 }
1730 assert(!elide_store_to_block_ptr_instructions);
1731 try copyBodyNoEliding(&condbr.positionals.then_body, then_scope);
1732 try copyBodyNoEliding(&condbr.positionals.else_body, else_scope);
1733 return &block.base;
1734 },
1735 .break_operand => {
1736 if (!then_result.tag.isNoReturn()) {
1737 _ = try addZirInstTag(mod, then_sub_scope, then_src, .@"break", .{
1738 .block = block,
1739 .operand = then_result,
1740 });
1741 }
1742 if (else_result) |inst| {
1743 if (!inst.tag.isNoReturn()) {
1744 _ = try addZirInstTag(mod, else_sub_scope, else_src, .@"break", .{
1745 .block = block,
1746 .operand = inst,
1747 });
1748 }
1749 } else {
1750 _ = try addZIRNoOp(mod, else_sub_scope, else_src, .break_void);
1751 }
1752 if (elide_store_to_block_ptr_instructions) {
1753 try copyBodyWithElidedStoreBlockPtr(&condbr.positionals.then_body, then_scope);
1754 try copyBodyWithElidedStoreBlockPtr(&condbr.positionals.else_body, else_scope);
1755 } else {
1756 try copyBodyNoEliding(&condbr.positionals.then_body, then_scope);
1757 try copyBodyNoEliding(&condbr.positionals.else_body, else_scope);
1758 }
1759 switch (rl) {
1760 .ref => return &block.base,
1761 else => return rvalue(mod, scope, rl, &block.base),
1762 }
1763 },
16621764 }
1663 condbr.positionals.else_body = .{
1664 .instructions = try else_scope.arena.dupe(*zir.Inst, else_scope.instructions.items),
1765}
1766
1767/// Expects to find exactly 1 .store_to_block_ptr instruction.
1768fn copyBodyWithElidedStoreBlockPtr(body: *zir.Body, scope: Module.Scope.GenZIR) !void {
1769 body.* = .{
1770 .instructions = try scope.arena.alloc(*zir.Inst, scope.instructions.items.len - 1),
16651771 };
1772 var dst_index: usize = 0;
1773 for (scope.instructions.items) |src_inst| {
1774 if (src_inst.tag != .store_to_block_ptr) {
1775 body.instructions[dst_index] = src_inst;
1776 dst_index += 1;
1777 }
1778 }
1779 assert(dst_index == body.instructions.len);
1780}
16661781
1667 return &block.base;
1782fn copyBodyNoEliding(body: *zir.Body, scope: Module.Scope.GenZIR) !void {
1783 body.* = .{
1784 .instructions = try scope.arena.dupe(*zir.Inst, scope.instructions.items),
1785 };
16681786}
16691787
16701788fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.While) InnerError!*zir.Inst {
1789 if (true) {
1790 @panic("TODO reimplement this");
1791 }
16711792 var cond_kind: CondKind = .bool;
16721793 if (while_node.payload) |_| cond_kind = .{ .optional = null };
16731794 if (while_node.@"else") |else_node| {
......@@ -1821,6 +1942,9 @@ fn forExpr(
18211942 rl: ResultLoc,
18221943 for_node: *ast.Node.For,
18231944) InnerError!*zir.Inst {
1945 if (true) {
1946 @panic("TODO reimplement this");
1947 }
18241948 if (for_node.label) |label| {
18251949 try checkLabelRedefinition(mod, scope, label);
18261950 }
......@@ -2017,6 +2141,9 @@ fn getRangeNode(node: *ast.Node) ?*ast.Node.SimpleInfixOp {
20172141}
20182142
20192143fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node.Switch) InnerError!*zir.Inst {
2144 if (true) {
2145 @panic("TODO reimplement this");
2146 }
20202147 var block_scope: Scope.GenZIR = .{
20212148 .parent = scope,
20222149 .decl = scope.ownerDecl().?,
......@@ -2186,10 +2313,10 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
21862313 // target >= start and target <= end
21872314 const range_start_ok = try addZIRBinOp(mod, &else_scope.base, range_src, .cmp_gte, target, start);
21882315 const range_end_ok = try addZIRBinOp(mod, &else_scope.base, range_src, .cmp_lte, target, end);
2189 const range_ok = try addZIRBinOp(mod, &else_scope.base, range_src, .booland, range_start_ok, range_end_ok);
2316 const range_ok = try addZIRBinOp(mod, &else_scope.base, range_src, .bool_and, range_start_ok, range_end_ok);
21902317
21912318 if (any_ok) |some| {
2192 any_ok = try addZIRBinOp(mod, &else_scope.base, range_src, .boolor, some, range_ok);
2319 any_ok = try addZIRBinOp(mod, &else_scope.base, range_src, .bool_or, some, range_ok);
21932320 } else {
21942321 any_ok = range_ok;
21952322 }
......@@ -2201,7 +2328,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
22012328 const cpm_ok = try addZIRBinOp(mod, &else_scope.base, item_inst.src, .cmp_eq, target, item_inst);
22022329
22032330 if (any_ok) |some| {
2204 any_ok = try addZIRBinOp(mod, &else_scope.base, item_inst.src, .boolor, some, cpm_ok);
2331 any_ok = try addZIRBinOp(mod, &else_scope.base, item_inst.src, .bool_or, some, cpm_ok);
22052332 } else {
22062333 any_ok = cpm_ok;
22072334 }
......@@ -2238,7 +2365,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
22382365 try switchCaseExpr(mod, &else_scope.base, case_rl, block, case);
22392366 } else {
22402367 // Not handling all possible cases is a compile error.
2241 _ = try addZIRNoOp(mod, &else_scope.base, switch_src, .unreach_nocheck);
2368 _ = try addZIRNoOp(mod, &else_scope.base, switch_src, .unreachable_unsafe);
22422369 }
22432370
22442371 // All items have been generated, add the instructions to the comptime block.
......@@ -2288,7 +2415,7 @@ fn ret(mod: *Module, scope: *Scope, cfe: *ast.Node.ControlFlowExpression) InnerE
22882415 return addZIRUnOp(mod, scope, src, .@"return", operand);
22892416 }
22902417 } else {
2291 return addZIRNoOp(mod, scope, src, .returnvoid);
2418 return addZIRNoOp(mod, scope, src, .return_void);
22922419 }
22932420}
22942421
......@@ -2305,7 +2432,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo
23052432
23062433 if (getSimplePrimitiveValue(ident_name)) |typed_value| {
23072434 const result = try addZIRInstConst(mod, scope, src, typed_value);
2308 return rlWrap(mod, scope, rl, result);
2435 return rvalue(mod, scope, rl, result);
23092436 }
23102437
23112438 if (ident_name.len >= 2) integer: {
......@@ -2327,7 +2454,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo
23272454 32 => if (is_signed) Value.initTag(.i32_type) else Value.initTag(.u32_type),
23282455 64 => if (is_signed) Value.initTag(.i64_type) else Value.initTag(.u64_type),
23292456 else => {
2330 return rlWrap(mod, scope, rl, try addZIRInstConst(mod, scope, src, .{
2457 return rvalue(mod, scope, rl, try addZIRInstConst(mod, scope, src, .{
23312458 .ty = Type.initTag(.type),
23322459 .val = try Value.Tag.int_type.create(scope.arena(), .{
23332460 .signed = is_signed,
......@@ -2340,7 +2467,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo
23402467 .ty = Type.initTag(.type),
23412468 .val = val,
23422469 });
2343 return rlWrap(mod, scope, rl, result);
2470 return rvalue(mod, scope, rl, result);
23442471 }
23452472 }
23462473
......@@ -2351,7 +2478,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo
23512478 .local_val => {
23522479 const local_val = s.cast(Scope.LocalVal).?;
23532480 if (mem.eql(u8, local_val.name, ident_name)) {
2354 return rlWrap(mod, scope, rl, local_val.inst);
2481 return rvalue(mod, scope, rl, local_val.inst);
23552482 }
23562483 s = local_val.parent;
23572484 },
......@@ -2360,7 +2487,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo
23602487 if (mem.eql(u8, local_ptr.name, ident_name)) {
23612488 if (rl == .ref) return local_ptr.ptr;
23622489 const loaded = try addZIRUnOp(mod, scope, src, .deref, local_ptr.ptr);
2363 return rlWrap(mod, scope, rl, loaded);
2490 return rvalue(mod, scope, rl, loaded);
23642491 }
23652492 s = local_ptr.parent;
23662493 },
......@@ -2373,7 +2500,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo
23732500 if (rl == .ref) {
23742501 return addZIRInst(mod, scope, src, zir.Inst.DeclRef, .{ .decl = decl }, .{});
23752502 } else {
2376 return rlWrap(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.DeclVal, .{
2503 return rvalue(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.DeclVal, .{
23772504 .decl = decl,
23782505 }, .{}));
23792506 }
......@@ -2590,7 +2717,7 @@ fn simpleCast(
25902717 const dest_type = try typeExpr(mod, scope, params[0]);
25912718 const rhs = try expr(mod, scope, .none, params[1]);
25922719 const result = try addZIRBinOp(mod, scope, src, inst_tag, dest_type, rhs);
2593 return rlWrap(mod, scope, rl, result);
2720 return rvalue(mod, scope, rl, result);
25942721}
25952722
25962723fn ptrToInt(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {
......@@ -2634,11 +2761,11 @@ fn as(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCall) I
26342761 // TODO here we should be able to resolve the inference; we now have a type for the result.
26352762 return mod.failTok(scope, call.builtin_token, "TODO implement @as with inferred-type result location pointer", .{});
26362763 },
2637 .block_ptr => |block_ptr| {
2638 const casted_block_ptr = try addZIRInst(mod, scope, src, zir.Inst.CoerceResultBlockPtr, .{
2764 .block_ptr => |block_scope| {
2765 const casted_block_ptr = try addZirInstTag(mod, scope, src, .coerce_result_block_ptr, .{
26392766 .dest_type = dest_type,
2640 .block = block_ptr,
2641 }, .{});
2767 .block_ptr = block_scope.rl_ptr.?,
2768 });
26422769 return expr(mod, scope, .{ .ptr = casted_block_ptr }, params[1]);
26432770 },
26442771 }
......@@ -2703,7 +2830,7 @@ fn compileError(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerE
27032830 const src = tree.token_locs[call.builtin_token].start;
27042831 const params = call.params();
27052832 const target = try expr(mod, scope, .none, params[0]);
2706 return addZIRUnOp(mod, scope, src, .compileerror, target);
2833 return addZIRUnOp(mod, scope, src, .compile_error, target);
27072834}
27082835
27092836fn setEvalBranchQuota(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {
......@@ -2728,12 +2855,12 @@ fn typeOf(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCal
27282855 return mod.failTok(scope, call.builtin_token, "expected at least 1 argument, found 0", .{});
27292856 }
27302857 if (params.len == 1) {
2731 return rlWrap(mod, scope, rl, try addZIRUnOp(mod, scope, src, .typeof, try expr(mod, scope, .none, params[0])));
2858 return rvalue(mod, scope, rl, try addZIRUnOp(mod, scope, src, .typeof, try expr(mod, scope, .none, params[0])));
27322859 }
27332860 var items = try arena.alloc(*zir.Inst, params.len);
27342861 for (params) |param, param_i|
27352862 items[param_i] = try expr(mod, scope, .none, param);
2736 return rlWrap(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.TypeOfPeer, .{ .items = items }, .{}));
2863 return rvalue(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.TypeOfPeer, .{ .items = items }, .{}));
27372864}
27382865fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {
27392866 const tree = scope.tree();
......@@ -2756,7 +2883,7 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.Built
27562883 // Also, some builtins have a variable number of parameters.
27572884
27582885 if (mem.eql(u8, builtin_name, "@ptrToInt")) {
2759 return rlWrap(mod, scope, rl, try ptrToInt(mod, scope, call));
2886 return rvalue(mod, scope, rl, try ptrToInt(mod, scope, call));
27602887 } else if (mem.eql(u8, builtin_name, "@as")) {
27612888 return as(mod, scope, rl, call);
27622889 } else if (mem.eql(u8, builtin_name, "@floatCast")) {
......@@ -2769,9 +2896,9 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.Built
27692896 return typeOf(mod, scope, rl, call);
27702897 } else if (mem.eql(u8, builtin_name, "@breakpoint")) {
27712898 const src = tree.token_locs[call.builtin_token].start;
2772 return rlWrap(mod, scope, rl, try addZIRNoOp(mod, scope, src, .breakpoint));
2899 return rvalue(mod, scope, rl, try addZIRNoOp(mod, scope, src, .breakpoint));
27732900 } else if (mem.eql(u8, builtin_name, "@import")) {
2774 return rlWrap(mod, scope, rl, try import(mod, scope, call));
2901 return rvalue(mod, scope, rl, try import(mod, scope, call));
27752902 } else if (mem.eql(u8, builtin_name, "@compileError")) {
27762903 return compileError(mod, scope, call);
27772904 } else if (mem.eql(u8, builtin_name, "@setEvalBranchQuota")) {
......@@ -2806,13 +2933,13 @@ fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Call) In
28062933 .args = args,
28072934 }, .{});
28082935 // TODO function call with result location
2809 return rlWrap(mod, scope, rl, result);
2936 return rvalue(mod, scope, rl, result);
28102937}
28112938
28122939fn unreach(mod: *Module, scope: *Scope, unreach_node: *ast.Node.OneToken) InnerError!*zir.Inst {
28132940 const tree = scope.tree();
28142941 const src = tree.token_locs[unreach_node.token].start;
2815 return addZIRNoOp(mod, scope, src, .@"unreachable");
2942 return addZIRNoOp(mod, scope, src, .unreachable_safe);
28162943}
28172944
28182945fn getSimplePrimitiveValue(name: []const u8) ?TypedValue {
......@@ -3099,7 +3226,7 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
30993226/// result locations must call this function on their result.
31003227/// As an example, if the `ResultLoc` is `ptr`, it will write the result to the pointer.
31013228/// If the `ResultLoc` is `ty`, it will coerce the result to the type.
3102fn rlWrap(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerError!*zir.Inst {
3229fn rvalue(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerError!*zir.Inst {
31033230 switch (rl) {
31043231 .none => return result,
31053232 .discard => {
......@@ -3113,42 +3240,31 @@ fn rlWrap(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerEr
31133240 },
31143241 .ty => |ty_inst| return addZIRBinOp(mod, scope, result.src, .as, ty_inst, result),
31153242 .ptr => |ptr_inst| {
3116 const casted_result = try addZIRInst(mod, scope, result.src, zir.Inst.CoerceToPtrElem, .{
3117 .ptr = ptr_inst,
3118 .value = result,
3119 }, .{});
3120 _ = try addZIRBinOp(mod, scope, result.src, .store, ptr_inst, casted_result);
3121 return casted_result;
3243 _ = try addZIRBinOp(mod, scope, result.src, .store, ptr_inst, result);
3244 return result;
31223245 },
31233246 .bitcasted_ptr => |bitcasted_ptr| {
3124 return mod.fail(scope, result.src, "TODO implement rlWrap .bitcasted_ptr", .{});
3247 return mod.fail(scope, result.src, "TODO implement rvalue .bitcasted_ptr", .{});
31253248 },
31263249 .inferred_ptr => |alloc| {
31273250 _ = try addZIRBinOp(mod, scope, result.src, .store_to_inferred_ptr, &alloc.base, result);
31283251 return result;
31293252 },
3130 .block_ptr => |block_ptr| {
3131 return mod.fail(scope, result.src, "TODO implement rlWrap .block_ptr", .{});
3253 .block_ptr => |block_scope| {
3254 block_scope.rvalue_rl_count += 1;
3255 _ = try addZIRBinOp(mod, scope, result.src, .store_to_block_ptr, block_scope.rl_ptr.?, result);
3256 return result;
31323257 },
31333258 }
31343259}
31353260
3136fn rlWrapVoid(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node, result: void) InnerError!*zir.Inst {
3261fn rvalueVoid(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node, result: void) InnerError!*zir.Inst {
31373262 const src = scope.tree().token_locs[node.firstToken()].start;
31383263 const void_inst = try addZIRInstConst(mod, scope, src, .{
31393264 .ty = Type.initTag(.void),
31403265 .val = Value.initTag(.void_value),
31413266 });
3142 return rlWrap(mod, scope, rl, void_inst);
3143}
3144
3145/// TODO go over all the callsites and see where we can introduce "by-value" ZIR instructions
3146/// to save ZIR memory. For example, see DeclVal vs DeclRef.
3147/// Do not add additional callsites to this function.
3148fn rlWrapPtr(mod: *Module, scope: *Scope, rl: ResultLoc, ptr: *zir.Inst) InnerError!*zir.Inst {
3149 if (rl == .ref) return ptr;
3150
3151 return rlWrap(mod, scope, rl, try addZIRUnOp(mod, scope, ptr.src, .deref, ptr));
3267 return rvalue(mod, scope, rl, void_inst);
31523268}
31533269
31543270pub fn addZirInstTag(
src/codegen.zig+12-12
......@@ -840,14 +840,14 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
840840 .arg => return self.genArg(inst.castTag(.arg).?),
841841 .assembly => return self.genAsm(inst.castTag(.assembly).?),
842842 .bitcast => return self.genBitCast(inst.castTag(.bitcast).?),
843 .bitand => return self.genBitAnd(inst.castTag(.bitand).?),
844 .bitor => return self.genBitOr(inst.castTag(.bitor).?),
843 .bit_and => return self.genBitAnd(inst.castTag(.bit_and).?),
844 .bit_or => return self.genBitOr(inst.castTag(.bit_or).?),
845845 .block => return self.genBlock(inst.castTag(.block).?),
846846 .br => return self.genBr(inst.castTag(.br).?),
847847 .breakpoint => return self.genBreakpoint(inst.src),
848848 .brvoid => return self.genBrVoid(inst.castTag(.brvoid).?),
849 .booland => return self.genBoolOp(inst.castTag(.booland).?),
850 .boolor => return self.genBoolOp(inst.castTag(.boolor).?),
849 .bool_and => return self.genBoolOp(inst.castTag(.bool_and).?),
850 .bool_or => return self.genBoolOp(inst.castTag(.bool_or).?),
851851 .call => return self.genCall(inst.castTag(.call).?),
852852 .cmp_lt => return self.genCmp(inst.castTag(.cmp_lt).?, .lt),
853853 .cmp_lte => return self.genCmp(inst.castTag(.cmp_lte).?, .lte),
......@@ -1097,7 +1097,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
10971097 if (inst.base.isUnused())
10981098 return MCValue.dead;
10991099 switch (arch) {
1100 .arm, .armeb => return try self.genArmBinOp(&inst.base, inst.lhs, inst.rhs, .bitand),
1100 .arm, .armeb => return try self.genArmBinOp(&inst.base, inst.lhs, inst.rhs, .bit_and),
11011101 else => return self.fail(inst.base.src, "TODO implement bitwise and for {}", .{self.target.cpu.arch}),
11021102 }
11031103 }
......@@ -1107,7 +1107,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
11071107 if (inst.base.isUnused())
11081108 return MCValue.dead;
11091109 switch (arch) {
1110 .arm, .armeb => return try self.genArmBinOp(&inst.base, inst.lhs, inst.rhs, .bitor),
1110 .arm, .armeb => return try self.genArmBinOp(&inst.base, inst.lhs, inst.rhs, .bit_or),
11111111 else => return self.fail(inst.base.src, "TODO implement bitwise or for {}", .{self.target.cpu.arch}),
11121112 }
11131113 }
......@@ -1371,10 +1371,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
13711371 writeInt(u32, try self.code.addManyAsArray(4), Instruction.rsb(.al, dst_reg, dst_reg, operand).toU32());
13721372 }
13731373 },
1374 .booland, .bitand => {
1374 .bool_and, .bit_and => {
13751375 writeInt(u32, try self.code.addManyAsArray(4), Instruction.@"and"(.al, dst_reg, dst_reg, operand).toU32());
13761376 },
1377 .boolor, .bitor => {
1377 .bool_or, .bit_or => {
13781378 writeInt(u32, try self.code.addManyAsArray(4), Instruction.orr(.al, dst_reg, dst_reg, operand).toU32());
13791379 },
13801380 .not, .xor => {
......@@ -2464,14 +2464,14 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
24642464 switch (arch) {
24652465 .x86_64 => switch (inst.base.tag) {
24662466 // lhs AND rhs
2467 .booland => return try self.genX8664BinMath(&inst.base, inst.lhs, inst.rhs, 4, 0x20),
2467 .bool_and => return try self.genX8664BinMath(&inst.base, inst.lhs, inst.rhs, 4, 0x20),
24682468 // lhs OR rhs
2469 .boolor => return try self.genX8664BinMath(&inst.base, inst.lhs, inst.rhs, 1, 0x08),
2469 .bool_or => return try self.genX8664BinMath(&inst.base, inst.lhs, inst.rhs, 1, 0x08),
24702470 else => unreachable, // Not a boolean operation
24712471 },
24722472 .arm, .armeb => switch (inst.base.tag) {
2473 .booland => return try self.genArmBinOp(&inst.base, inst.lhs, inst.rhs, .booland),
2474 .boolor => return try self.genArmBinOp(&inst.base, inst.lhs, inst.rhs, .boolor),
2473 .bool_and => return try self.genArmBinOp(&inst.base, inst.lhs, inst.rhs, .bool_and),
2474 .bool_or => return try self.genArmBinOp(&inst.base, inst.lhs, inst.rhs, .bool_or),
24752475 else => unreachable, // Not a boolean operation
24762476 },
24772477 else => return self.fail(inst.base.src, "TODO implement boolean operations for {}", .{self.target.cpu.arch}),
src/ir.zig+8-8
......@@ -56,9 +56,9 @@ pub const Inst = struct {
5656 alloc,
5757 arg,
5858 assembly,
59 bitand,
59 bit_and,
6060 bitcast,
61 bitor,
61 bit_or,
6262 block,
6363 br,
6464 breakpoint,
......@@ -85,8 +85,8 @@ pub const Inst = struct {
8585 is_err,
8686 // *E!T => bool
8787 is_err_ptr,
88 booland,
89 boolor,
88 bool_and,
89 bool_or,
9090 /// Read a value from a pointer.
9191 load,
9292 loop,
......@@ -147,10 +147,10 @@ pub const Inst = struct {
147147 .cmp_gt,
148148 .cmp_neq,
149149 .store,
150 .booland,
151 .boolor,
152 .bitand,
153 .bitor,
150 .bool_and,
151 .bool_or,
152 .bit_and,
153 .bit_or,
154154 .xor,
155155 => BinOp,
156156
src/zir.zig+73-82
......@@ -59,7 +59,7 @@ pub const Inst = struct {
5959 /// Inline assembly.
6060 @"asm",
6161 /// Bitwise AND. `&`
62 bitand,
62 bit_and,
6363 /// TODO delete this instruction, it has no purpose.
6464 bitcast,
6565 /// An arbitrary typed pointer is pointer-casted to a new Pointer.
......@@ -71,9 +71,9 @@ pub const Inst = struct {
7171 /// The new result location pointer has an inferred type.
7272 bitcast_result_ptr,
7373 /// Bitwise NOT. `~`
74 bitnot,
74 bit_not,
7575 /// Bitwise OR. `|`
76 bitor,
76 bit_or,
7777 /// A labeled block of code, which can return a value.
7878 block,
7979 /// A block of code, which can return a value. There are no instructions that break out of
......@@ -83,17 +83,17 @@ pub const Inst = struct {
8383 block_comptime,
8484 /// Same as `block_flat` but additionally makes the inner instructions execute at comptime.
8585 block_comptime_flat,
86 /// Boolean AND. See also `bitand`.
87 booland,
88 /// Boolean NOT. See also `bitnot`.
89 boolnot,
90 /// Boolean OR. See also `bitor`.
91 boolor,
86 /// Boolean AND. See also `bit_and`.
87 bool_and,
88 /// Boolean NOT. See also `bit_not`.
89 bool_not,
90 /// Boolean OR. See also `bit_or`.
91 bool_or,
9292 /// Return a value from a `Block`.
9393 @"break",
9494 breakpoint,
9595 /// Same as `break` but without an operand; the operand is assumed to be the void value.
96 breakvoid,
96 break_void,
9797 /// Function call.
9898 call,
9999 /// `<`
......@@ -116,12 +116,10 @@ pub const Inst = struct {
116116 /// result location pointer, whose type is inferred by peer type resolution on the
117117 /// `Block`'s corresponding `break` instructions.
118118 coerce_result_block_ptr,
119 /// Equivalent to `as(ptr_child_type(typeof(ptr)), value)`.
120 coerce_to_ptr_elem,
121119 /// Emit an error message and fail compilation.
122 compileerror,
120 compile_error,
123121 /// Log compile time variables and emit an error message.
124 compilelog,
122 compile_log,
125123 /// Conditional branch. Splits control flow based on a boolean condition value.
126124 condbr,
127125 /// Special case, has no textual representation.
......@@ -135,11 +133,11 @@ pub const Inst = struct {
135133 /// Declares the beginning of a statement. Used for debug info.
136134 dbg_stmt,
137135 /// Represents a pointer to a global decl.
138 declref,
136 decl_ref,
139137 /// Represents a pointer to a global decl by string name.
140 declref_str,
141 /// Equivalent to a declref followed by deref.
142 declval,
138 decl_ref_str,
139 /// Equivalent to a decl_ref followed by deref.
140 decl_val,
143141 /// Load the value from a pointer.
144142 deref,
145143 /// Arithmetic division. Asserts no integer overflow.
......@@ -185,7 +183,7 @@ pub const Inst = struct {
185183 /// can hold the same mathematical value.
186184 intcast,
187185 /// Make an integer type out of signedness and bit count.
188 inttype,
186 int_type,
189187 /// Return a boolean false if an optional is null. `x != null`
190188 is_non_null,
191189 /// Return a boolean true if an optional is null. `x == null`
......@@ -232,7 +230,7 @@ pub const Inst = struct {
232230 /// Sends control flow back to the function's callee. Takes an operand as the return value.
233231 @"return",
234232 /// Same as `return` but there is no operand; the operand is implicitly the void value.
235 returnvoid,
233 return_void,
236234 /// Changes the maximum number of backwards branches that compile-time
237235 /// code execution can use before giving up and making a compile error.
238236 set_eval_branch_quota,
......@@ -270,6 +268,10 @@ pub const Inst = struct {
270268 /// Write a value to a pointer. For loading, see `deref`.
271269 store,
272270 /// Same as `store` but the type of the value being stored will be used to infer
271 /// the block type. The LHS is a block instruction, whose result location is
272 /// being stored to.
273 store_to_block_ptr,
274 /// Same as `store` but the type of the value being stored will be used to infer
273275 /// the pointer type.
274276 store_to_inferred_ptr,
275277 /// String Literal. Makes an anonymous Decl and then takes a pointer to it.
......@@ -286,11 +288,11 @@ pub const Inst = struct {
286288 typeof_peer,
287289 /// Asserts control-flow will not reach this instruction. Not safety checked - the compiler
288290 /// will assume the correctness of this instruction.
289 unreach_nocheck,
291 unreachable_unsafe,
290292 /// Asserts control-flow will not reach this instruction. In safety-checked modes,
291293 /// this will generate a call to the panic function unless it can be proven unreachable
292294 /// by the compiler.
293 @"unreachable",
295 unreachable_safe,
294296 /// Bitwise XOR. `^`
295297 xor,
296298 /// Create an optional type '?T'
......@@ -352,17 +354,17 @@ pub const Inst = struct {
352354 .alloc_inferred_mut,
353355 .breakpoint,
354356 .dbg_stmt,
355 .returnvoid,
357 .return_void,
356358 .ret_ptr,
357359 .ret_type,
358 .unreach_nocheck,
359 .@"unreachable",
360 .unreachable_unsafe,
361 .unreachable_safe,
360362 => NoOp,
361363
362364 .alloc,
363365 .alloc_mut,
364 .boolnot,
365 .compileerror,
366 .bool_not,
367 .compile_error,
366368 .deref,
367369 .@"return",
368370 .is_null,
......@@ -400,7 +402,7 @@ pub const Inst = struct {
400402 .err_union_code_ptr,
401403 .ensure_err_payload_void,
402404 .anyframe_type,
403 .bitnot,
405 .bit_not,
404406 .import,
405407 .set_eval_branch_quota,
406408 .indexable_ptr_len,
......@@ -411,10 +413,10 @@ pub const Inst = struct {
411413 .array_cat,
412414 .array_mul,
413415 .array_type,
414 .bitand,
415 .bitor,
416 .booland,
417 .boolor,
416 .bit_and,
417 .bit_or,
418 .bool_and,
419 .bool_or,
418420 .div,
419421 .mod_rem,
420422 .mul,
......@@ -422,6 +424,7 @@ pub const Inst = struct {
422424 .shl,
423425 .shr,
424426 .store,
427 .store_to_block_ptr,
425428 .store_to_inferred_ptr,
426429 .sub,
427430 .subwrap,
......@@ -452,19 +455,18 @@ pub const Inst = struct {
452455 .arg => Arg,
453456 .array_type_sentinel => ArrayTypeSentinel,
454457 .@"break" => Break,
455 .breakvoid => BreakVoid,
458 .break_void => BreakVoid,
456459 .call => Call,
457 .coerce_to_ptr_elem => CoerceToPtrElem,
458 .declref => DeclRef,
459 .declref_str => DeclRefStr,
460 .declval => DeclVal,
460 .decl_ref => DeclRef,
461 .decl_ref_str => DeclRefStr,
462 .decl_val => DeclVal,
461463 .coerce_result_block_ptr => CoerceResultBlockPtr,
462 .compilelog => CompileLog,
464 .compile_log => CompileLog,
463465 .loop => Loop,
464466 .@"const" => Const,
465467 .str => Str,
466468 .int => Int,
467 .inttype => IntType,
469 .int_type => IntType,
468470 .field_ptr, .field_val => Field,
469471 .field_ptr_named, .field_val_named => FieldNamed,
470472 .@"asm" => Asm,
......@@ -508,18 +510,18 @@ pub const Inst = struct {
508510 .arg,
509511 .as,
510512 .@"asm",
511 .bitand,
513 .bit_and,
512514 .bitcast,
513515 .bitcast_ref,
514516 .bitcast_result_ptr,
515 .bitor,
517 .bit_or,
516518 .block,
517519 .block_flat,
518520 .block_comptime,
519521 .block_comptime_flat,
520 .boolnot,
521 .booland,
522 .boolor,
522 .bool_not,
523 .bool_and,
524 .bool_or,
523525 .breakpoint,
524526 .call,
525527 .cmp_lt,
......@@ -530,12 +532,11 @@ pub const Inst = struct {
530532 .cmp_neq,
531533 .coerce_result_ptr,
532534 .coerce_result_block_ptr,
533 .coerce_to_ptr_elem,
534535 .@"const",
535536 .dbg_stmt,
536 .declref,
537 .declref_str,
538 .declval,
537 .decl_ref,
538 .decl_ref_str,
539 .decl_val,
539540 .deref,
540541 .div,
541542 .elem_ptr,
......@@ -552,7 +553,7 @@ pub const Inst = struct {
552553 .fntype,
553554 .int,
554555 .intcast,
555 .inttype,
556 .int_type,
556557 .is_non_null,
557558 .is_null,
558559 .is_non_null_ptr,
......@@ -579,6 +580,7 @@ pub const Inst = struct {
579580 .mut_slice_type,
580581 .const_slice_type,
581582 .store,
583 .store_to_block_ptr,
582584 .store_to_inferred_ptr,
583585 .str,
584586 .sub,
......@@ -602,7 +604,7 @@ pub const Inst = struct {
602604 .merge_error_sets,
603605 .anyframe_type,
604606 .error_union_type,
605 .bitnot,
607 .bit_not,
606608 .error_set,
607609 .slice,
608610 .slice_start,
......@@ -611,20 +613,20 @@ pub const Inst = struct {
611613 .typeof_peer,
612614 .resolve_inferred_alloc,
613615 .set_eval_branch_quota,
614 .compilelog,
616 .compile_log,
615617 .enum_type,
616618 .union_type,
617619 .struct_type,
618620 => false,
619621
620622 .@"break",
621 .breakvoid,
623 .break_void,
622624 .condbr,
623 .compileerror,
625 .compile_error,
624626 .@"return",
625 .returnvoid,
626 .unreach_nocheck,
627 .@"unreachable",
627 .return_void,
628 .unreachable_unsafe,
629 .unreachable_safe,
628630 .loop,
629631 .switchbr,
630632 .container_field_named,
......@@ -717,7 +719,7 @@ pub const Inst = struct {
717719 };
718720
719721 pub const BreakVoid = struct {
720 pub const base_tag = Tag.breakvoid;
722 pub const base_tag = Tag.break_void;
721723 base: Inst,
722724
723725 positionals: struct {
......@@ -739,19 +741,8 @@ pub const Inst = struct {
739741 },
740742 };
741743
742 pub const CoerceToPtrElem = struct {
743 pub const base_tag = Tag.coerce_to_ptr_elem;
744 base: Inst,
745
746 positionals: struct {
747 ptr: *Inst,
748 value: *Inst,
749 },
750 kw_args: struct {},
751 };
752
753744 pub const DeclRef = struct {
754 pub const base_tag = Tag.declref;
745 pub const base_tag = Tag.decl_ref;
755746 base: Inst,
756747
757748 positionals: struct {
......@@ -761,7 +752,7 @@ pub const Inst = struct {
761752 };
762753
763754 pub const DeclRefStr = struct {
764 pub const base_tag = Tag.declref_str;
755 pub const base_tag = Tag.decl_ref_str;
765756 base: Inst,
766757
767758 positionals: struct {
......@@ -771,7 +762,7 @@ pub const Inst = struct {
771762 };
772763
773764 pub const DeclVal = struct {
774 pub const base_tag = Tag.declval;
765 pub const base_tag = Tag.decl_val;
775766 base: Inst,
776767
777768 positionals: struct {
......@@ -786,13 +777,13 @@ pub const Inst = struct {
786777
787778 positionals: struct {
788779 dest_type: *Inst,
789 block: *Block,
780 block_ptr: *Inst,
790781 },
791782 kw_args: struct {},
792783 };
793784
794785 pub const CompileLog = struct {
795 pub const base_tag = Tag.compilelog;
786 pub const base_tag = Tag.compile_log;
796787 base: Inst,
797788
798789 positionals: struct {
......@@ -905,7 +896,7 @@ pub const Inst = struct {
905896 };
906897
907898 pub const IntType = struct {
908 pub const base_tag = Tag.inttype;
899 pub const base_tag = Tag.int_type;
909900 base: Inst,
910901
911902 positionals: struct {
......@@ -1641,10 +1632,10 @@ const DumpTzir = struct {
16411632 .cmp_gt,
16421633 .cmp_neq,
16431634 .store,
1644 .booland,
1645 .boolor,
1646 .bitand,
1647 .bitor,
1635 .bool_and,
1636 .bool_or,
1637 .bit_and,
1638 .bit_or,
16481639 .xor,
16491640 => {
16501641 const bin_op = inst.cast(ir.Inst.BinOp).?;
......@@ -1753,10 +1744,10 @@ const DumpTzir = struct {
17531744 .cmp_gt,
17541745 .cmp_neq,
17551746 .store,
1756 .booland,
1757 .boolor,
1758 .bitand,
1759 .bitor,
1747 .bool_and,
1748 .bool_or,
1749 .bit_and,
1750 .bit_or,
17601751 .xor,
17611752 => {
17621753 const bin_op = inst.cast(ir.Inst.BinOp).?;
src/zir_sema.zig+289-283
......@@ -28,144 +28,134 @@ const Decl = Module.Decl;
2828
2929pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*Inst {
3030 switch (old_inst.tag) {
31 .alloc => return analyzeInstAlloc(mod, scope, old_inst.castTag(.alloc).?),
32 .alloc_mut => return analyzeInstAllocMut(mod, scope, old_inst.castTag(.alloc_mut).?),
33 .alloc_inferred => return analyzeInstAllocInferred(
34 mod,
35 scope,
36 old_inst.castTag(.alloc_inferred).?,
37 .inferred_alloc_const,
38 ),
39 .alloc_inferred_mut => return analyzeInstAllocInferred(
40 mod,
41 scope,
42 old_inst.castTag(.alloc_inferred_mut).?,
43 .inferred_alloc_mut,
44 ),
45 .arg => return analyzeInstArg(mod, scope, old_inst.castTag(.arg).?),
46 .bitcast_ref => return bitCastRef(mod, scope, old_inst.castTag(.bitcast_ref).?),
47 .bitcast_result_ptr => return bitCastResultPtr(mod, scope, old_inst.castTag(.bitcast_result_ptr).?),
48 .block => return analyzeInstBlock(mod, scope, old_inst.castTag(.block).?, false),
49 .block_comptime => return analyzeInstBlock(mod, scope, old_inst.castTag(.block_comptime).?, true),
50 .block_flat => return analyzeInstBlockFlat(mod, scope, old_inst.castTag(.block_flat).?, false),
51 .block_comptime_flat => return analyzeInstBlockFlat(mod, scope, old_inst.castTag(.block_comptime_flat).?, true),
52 .@"break" => return analyzeInstBreak(mod, scope, old_inst.castTag(.@"break").?),
53 .breakpoint => return analyzeInstBreakpoint(mod, scope, old_inst.castTag(.breakpoint).?),
54 .breakvoid => return analyzeInstBreakVoid(mod, scope, old_inst.castTag(.breakvoid).?),
55 .call => return call(mod, scope, old_inst.castTag(.call).?),
56 .coerce_result_block_ptr => return analyzeInstCoerceResultBlockPtr(mod, scope, old_inst.castTag(.coerce_result_block_ptr).?),
57 .coerce_result_ptr => return analyzeInstCoerceResultPtr(mod, scope, old_inst.castTag(.coerce_result_ptr).?),
58 .coerce_to_ptr_elem => return analyzeInstCoerceToPtrElem(mod, scope, old_inst.castTag(.coerce_to_ptr_elem).?),
59 .compileerror => return analyzeInstCompileError(mod, scope, old_inst.castTag(.compileerror).?),
60 .compilelog => return analyzeInstCompileLog(mod, scope, old_inst.castTag(.compilelog).?),
61 .@"const" => return analyzeInstConst(mod, scope, old_inst.castTag(.@"const").?),
62 .dbg_stmt => return analyzeInstDbgStmt(mod, scope, old_inst.castTag(.dbg_stmt).?),
63 .declref => return declRef(mod, scope, old_inst.castTag(.declref).?),
64 .declref_str => return analyzeInstDeclRefStr(mod, scope, old_inst.castTag(.declref_str).?),
65 .declval => return declVal(mod, scope, old_inst.castTag(.declval).?),
66 .ensure_result_used => return analyzeInstEnsureResultUsed(mod, scope, old_inst.castTag(.ensure_result_used).?),
67 .ensure_result_non_error => return analyzeInstEnsureResultNonError(mod, scope, old_inst.castTag(.ensure_result_non_error).?),
68 .indexable_ptr_len => return indexablePtrLen(mod, scope, old_inst.castTag(.indexable_ptr_len).?),
69 .ref => return ref(mod, scope, old_inst.castTag(.ref).?),
70 .resolve_inferred_alloc => return analyzeInstResolveInferredAlloc(mod, scope, old_inst.castTag(.resolve_inferred_alloc).?),
71 .ret_ptr => return analyzeInstRetPtr(mod, scope, old_inst.castTag(.ret_ptr).?),
72 .ret_type => return analyzeInstRetType(mod, scope, old_inst.castTag(.ret_type).?),
73 .store_to_inferred_ptr => return analyzeInstStoreToInferredPtr(mod, scope, old_inst.castTag(.store_to_inferred_ptr).?),
74 .single_const_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.single_const_ptr_type).?, false, .One),
75 .single_mut_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.single_mut_ptr_type).?, true, .One),
76 .many_const_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.many_const_ptr_type).?, false, .Many),
77 .many_mut_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.many_mut_ptr_type).?, true, .Many),
78 .c_const_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.c_const_ptr_type).?, false, .C),
79 .c_mut_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.c_mut_ptr_type).?, true, .C),
80 .const_slice_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.const_slice_type).?, false, .Slice),
81 .mut_slice_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.mut_slice_type).?, true, .Slice),
82 .ptr_type => return analyzeInstPtrType(mod, scope, old_inst.castTag(.ptr_type).?),
83 .store => return analyzeInstStore(mod, scope, old_inst.castTag(.store).?),
84 .set_eval_branch_quota => return analyzeInstSetEvalBranchQuota(mod, scope, old_inst.castTag(.set_eval_branch_quota).?),
85 .str => return analyzeInstStr(mod, scope, old_inst.castTag(.str).?),
86 .int => return analyzeInstInt(mod, scope, old_inst.castTag(.int).?),
87 .inttype => return analyzeInstIntType(mod, scope, old_inst.castTag(.inttype).?),
88 .loop => return analyzeInstLoop(mod, scope, old_inst.castTag(.loop).?),
89 .param_type => return analyzeInstParamType(mod, scope, old_inst.castTag(.param_type).?),
90 .ptrtoint => return analyzeInstPtrToInt(mod, scope, old_inst.castTag(.ptrtoint).?),
91 .field_ptr => return fieldPtr(mod, scope, old_inst.castTag(.field_ptr).?),
92 .field_val => return fieldVal(mod, scope, old_inst.castTag(.field_val).?),
93 .field_ptr_named => return fieldPtrNamed(mod, scope, old_inst.castTag(.field_ptr_named).?),
94 .field_val_named => return fieldValNamed(mod, scope, old_inst.castTag(.field_val_named).?),
95 .deref => return analyzeInstDeref(mod, scope, old_inst.castTag(.deref).?),
96 .as => return analyzeInstAs(mod, scope, old_inst.castTag(.as).?),
97 .@"asm" => return analyzeInstAsm(mod, scope, old_inst.castTag(.@"asm").?),
98 .@"unreachable" => return analyzeInstUnreachable(mod, scope, old_inst.castTag(.@"unreachable").?, true),
99 .unreach_nocheck => return analyzeInstUnreachable(mod, scope, old_inst.castTag(.unreach_nocheck).?, false),
100 .@"return" => return analyzeInstRet(mod, scope, old_inst.castTag(.@"return").?),
101 .returnvoid => return analyzeInstRetVoid(mod, scope, old_inst.castTag(.returnvoid).?),
102 .@"fn" => return analyzeInstFn(mod, scope, old_inst.castTag(.@"fn").?),
103 .@"export" => return analyzeInstExport(mod, scope, old_inst.castTag(.@"export").?),
104 .primitive => return analyzeInstPrimitive(mod, scope, old_inst.castTag(.primitive).?),
105 .fntype => return analyzeInstFnType(mod, scope, old_inst.castTag(.fntype).?),
106 .intcast => return analyzeInstIntCast(mod, scope, old_inst.castTag(.intcast).?),
107 .bitcast => return analyzeInstBitCast(mod, scope, old_inst.castTag(.bitcast).?),
108 .floatcast => return analyzeInstFloatCast(mod, scope, old_inst.castTag(.floatcast).?),
109 .elem_ptr => return elemPtr(mod, scope, old_inst.castTag(.elem_ptr).?),
110 .elem_val => return elemVal(mod, scope, old_inst.castTag(.elem_val).?),
111 .add => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.add).?),
112 .addwrap => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.addwrap).?),
113 .sub => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.sub).?),
114 .subwrap => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.subwrap).?),
115 .mul => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.mul).?),
116 .mulwrap => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.mulwrap).?),
117 .div => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.div).?),
118 .mod_rem => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.mod_rem).?),
119 .array_cat => return analyzeInstArrayCat(mod, scope, old_inst.castTag(.array_cat).?),
120 .array_mul => return analyzeInstArrayMul(mod, scope, old_inst.castTag(.array_mul).?),
121 .bitand => return analyzeInstBitwise(mod, scope, old_inst.castTag(.bitand).?),
122 .bitnot => return analyzeInstBitNot(mod, scope, old_inst.castTag(.bitnot).?),
123 .bitor => return analyzeInstBitwise(mod, scope, old_inst.castTag(.bitor).?),
124 .xor => return analyzeInstBitwise(mod, scope, old_inst.castTag(.xor).?),
125 .shl => return analyzeInstShl(mod, scope, old_inst.castTag(.shl).?),
126 .shr => return analyzeInstShr(mod, scope, old_inst.castTag(.shr).?),
127 .cmp_lt => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_lt).?, .lt),
128 .cmp_lte => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_lte).?, .lte),
129 .cmp_eq => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_eq).?, .eq),
130 .cmp_gte => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_gte).?, .gte),
131 .cmp_gt => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_gt).?, .gt),
132 .cmp_neq => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_neq).?, .neq),
133 .condbr => return analyzeInstCondBr(mod, scope, old_inst.castTag(.condbr).?),
134 .is_null => return isNull(mod, scope, old_inst.castTag(.is_null).?, false),
135 .is_non_null => return isNull(mod, scope, old_inst.castTag(.is_non_null).?, true),
136 .is_null_ptr => return isNullPtr(mod, scope, old_inst.castTag(.is_null_ptr).?, false),
137 .is_non_null_ptr => return isNullPtr(mod, scope, old_inst.castTag(.is_non_null_ptr).?, true),
138 .is_err => return isErr(mod, scope, old_inst.castTag(.is_err).?),
139 .is_err_ptr => return isErrPtr(mod, scope, old_inst.castTag(.is_err_ptr).?),
140 .boolnot => return analyzeInstBoolNot(mod, scope, old_inst.castTag(.boolnot).?),
141 .typeof => return analyzeInstTypeOf(mod, scope, old_inst.castTag(.typeof).?),
142 .typeof_peer => return analyzeInstTypeOfPeer(mod, scope, old_inst.castTag(.typeof_peer).?),
143 .optional_type => return analyzeInstOptionalType(mod, scope, old_inst.castTag(.optional_type).?),
144 .optional_payload_safe => return optionalPayload(mod, scope, old_inst.castTag(.optional_payload_safe).?, true),
145 .optional_payload_unsafe => return optionalPayload(mod, scope, old_inst.castTag(.optional_payload_unsafe).?, false),
146 .optional_payload_safe_ptr => return optionalPayloadPtr(mod, scope, old_inst.castTag(.optional_payload_safe_ptr).?, true),
147 .optional_payload_unsafe_ptr => return optionalPayloadPtr(mod, scope, old_inst.castTag(.optional_payload_unsafe_ptr).?, false),
148 .err_union_payload_safe => return errorUnionPayload(mod, scope, old_inst.castTag(.err_union_payload_safe).?, true),
149 .err_union_payload_unsafe => return errorUnionPayload(mod, scope, old_inst.castTag(.err_union_payload_unsafe).?, false),
150 .err_union_payload_safe_ptr => return errorUnionPayloadPtr(mod, scope, old_inst.castTag(.err_union_payload_safe_ptr).?, true),
151 .err_union_payload_unsafe_ptr => return errorUnionPayloadPtr(mod, scope, old_inst.castTag(.err_union_payload_unsafe_ptr).?, false),
152 .err_union_code => return errorUnionCode(mod, scope, old_inst.castTag(.err_union_code).?),
153 .err_union_code_ptr => return errorUnionCodePtr(mod, scope, old_inst.castTag(.err_union_code_ptr).?),
154 .ensure_err_payload_void => return analyzeInstEnsureErrPayloadVoid(mod, scope, old_inst.castTag(.ensure_err_payload_void).?),
155 .array_type => return analyzeInstArrayType(mod, scope, old_inst.castTag(.array_type).?),
156 .array_type_sentinel => return analyzeInstArrayTypeSentinel(mod, scope, old_inst.castTag(.array_type_sentinel).?),
157 .enum_literal => return analyzeInstEnumLiteral(mod, scope, old_inst.castTag(.enum_literal).?),
158 .merge_error_sets => return analyzeInstMergeErrorSets(mod, scope, old_inst.castTag(.merge_error_sets).?),
159 .error_union_type => return analyzeInstErrorUnionType(mod, scope, old_inst.castTag(.error_union_type).?),
160 .anyframe_type => return analyzeInstAnyframeType(mod, scope, old_inst.castTag(.anyframe_type).?),
161 .error_set => return analyzeInstErrorSet(mod, scope, old_inst.castTag(.error_set).?),
162 .slice => return analyzeInstSlice(mod, scope, old_inst.castTag(.slice).?),
163 .slice_start => return analyzeInstSliceStart(mod, scope, old_inst.castTag(.slice_start).?),
164 .import => return analyzeInstImport(mod, scope, old_inst.castTag(.import).?),
165 .switchbr => return analyzeInstSwitchBr(mod, scope, old_inst.castTag(.switchbr).?),
166 .switch_range => return analyzeInstSwitchRange(mod, scope, old_inst.castTag(.switch_range).?),
167 .booland => return analyzeInstBoolOp(mod, scope, old_inst.castTag(.booland).?),
168 .boolor => return analyzeInstBoolOp(mod, scope, old_inst.castTag(.boolor).?),
31 .alloc => return zirAlloc(mod, scope, old_inst.castTag(.alloc).?),
32 .alloc_mut => return zirAllocMut(mod, scope, old_inst.castTag(.alloc_mut).?),
33 .alloc_inferred => return zirAllocInferred(mod, scope, old_inst.castTag(.alloc_inferred).?, .inferred_alloc_const),
34 .alloc_inferred_mut => return zirAllocInferred(mod, scope, old_inst.castTag(.alloc_inferred_mut).?, .inferred_alloc_mut),
35 .arg => return zirArg(mod, scope, old_inst.castTag(.arg).?),
36 .bitcast_ref => return zirBitcastRef(mod, scope, old_inst.castTag(.bitcast_ref).?),
37 .bitcast_result_ptr => return zirBitcastResultPtr(mod, scope, old_inst.castTag(.bitcast_result_ptr).?),
38 .block => return zirBlock(mod, scope, old_inst.castTag(.block).?, false),
39 .block_comptime => return zirBlock(mod, scope, old_inst.castTag(.block_comptime).?, true),
40 .block_flat => return zirBlockFlat(mod, scope, old_inst.castTag(.block_flat).?, false),
41 .block_comptime_flat => return zirBlockFlat(mod, scope, old_inst.castTag(.block_comptime_flat).?, true),
42 .@"break" => return zirBreak(mod, scope, old_inst.castTag(.@"break").?),
43 .breakpoint => return zirBreakpoint(mod, scope, old_inst.castTag(.breakpoint).?),
44 .break_void => return zirBreakVoid(mod, scope, old_inst.castTag(.break_void).?),
45 .call => return zirCall(mod, scope, old_inst.castTag(.call).?),
46 .coerce_result_block_ptr => return zirCoerceResultBlockPtr(mod, scope, old_inst.castTag(.coerce_result_block_ptr).?),
47 .coerce_result_ptr => return zirCoerceResultPtr(mod, scope, old_inst.castTag(.coerce_result_ptr).?),
48 .compile_error => return zirCompileError(mod, scope, old_inst.castTag(.compile_error).?),
49 .compile_log => return zirCompileLog(mod, scope, old_inst.castTag(.compile_log).?),
50 .@"const" => return zirConst(mod, scope, old_inst.castTag(.@"const").?),
51 .dbg_stmt => return zirDbgStmt(mod, scope, old_inst.castTag(.dbg_stmt).?),
52 .decl_ref => return zirDeclRef(mod, scope, old_inst.castTag(.decl_ref).?),
53 .decl_ref_str => return zirDeclRefStr(mod, scope, old_inst.castTag(.decl_ref_str).?),
54 .decl_val => return zirDeclVal(mod, scope, old_inst.castTag(.decl_val).?),
55 .ensure_result_used => return zirEnsureResultUsed(mod, scope, old_inst.castTag(.ensure_result_used).?),
56 .ensure_result_non_error => return zirEnsureResultNonError(mod, scope, old_inst.castTag(.ensure_result_non_error).?),
57 .indexable_ptr_len => return zirIndexablePtrLen(mod, scope, old_inst.castTag(.indexable_ptr_len).?),
58 .ref => return zirRef(mod, scope, old_inst.castTag(.ref).?),
59 .resolve_inferred_alloc => return zirResolveInferredAlloc(mod, scope, old_inst.castTag(.resolve_inferred_alloc).?),
60 .ret_ptr => return zirRetPtr(mod, scope, old_inst.castTag(.ret_ptr).?),
61 .ret_type => return zirRetType(mod, scope, old_inst.castTag(.ret_type).?),
62 .store_to_block_ptr => return zirStoreToBlockPtr(mod, scope, old_inst.castTag(.store_to_block_ptr).?),
63 .store_to_inferred_ptr => return zirStoreToInferredPtr(mod, scope, old_inst.castTag(.store_to_inferred_ptr).?),
64 .single_const_ptr_type => return zirSimplePtrType(mod, scope, old_inst.castTag(.single_const_ptr_type).?, false, .One),
65 .single_mut_ptr_type => return zirSimplePtrType(mod, scope, old_inst.castTag(.single_mut_ptr_type).?, true, .One),
66 .many_const_ptr_type => return zirSimplePtrType(mod, scope, old_inst.castTag(.many_const_ptr_type).?, false, .Many),
67 .many_mut_ptr_type => return zirSimplePtrType(mod, scope, old_inst.castTag(.many_mut_ptr_type).?, true, .Many),
68 .c_const_ptr_type => return zirSimplePtrType(mod, scope, old_inst.castTag(.c_const_ptr_type).?, false, .C),
69 .c_mut_ptr_type => return zirSimplePtrType(mod, scope, old_inst.castTag(.c_mut_ptr_type).?, true, .C),
70 .const_slice_type => return zirSimplePtrType(mod, scope, old_inst.castTag(.const_slice_type).?, false, .Slice),
71 .mut_slice_type => return zirSimplePtrType(mod, scope, old_inst.castTag(.mut_slice_type).?, true, .Slice),
72 .ptr_type => return zirPtrType(mod, scope, old_inst.castTag(.ptr_type).?),
73 .store => return zirStore(mod, scope, old_inst.castTag(.store).?),
74 .set_eval_branch_quota => return zirSetEvalBranchQuota(mod, scope, old_inst.castTag(.set_eval_branch_quota).?),
75 .str => return zirStr(mod, scope, old_inst.castTag(.str).?),
76 .int => return zirInt(mod, scope, old_inst.castTag(.int).?),
77 .int_type => return zirIntType(mod, scope, old_inst.castTag(.int_type).?),
78 .loop => return zirLoop(mod, scope, old_inst.castTag(.loop).?),
79 .param_type => return zirParamType(mod, scope, old_inst.castTag(.param_type).?),
80 .ptrtoint => return zirPtrtoint(mod, scope, old_inst.castTag(.ptrtoint).?),
81 .field_ptr => return zirFieldPtr(mod, scope, old_inst.castTag(.field_ptr).?),
82 .field_val => return zirFieldVal(mod, scope, old_inst.castTag(.field_val).?),
83 .field_ptr_named => return zirFieldPtrNamed(mod, scope, old_inst.castTag(.field_ptr_named).?),
84 .field_val_named => return zirFieldValNamed(mod, scope, old_inst.castTag(.field_val_named).?),
85 .deref => return zirDeref(mod, scope, old_inst.castTag(.deref).?),
86 .as => return zirAs(mod, scope, old_inst.castTag(.as).?),
87 .@"asm" => return zirAsm(mod, scope, old_inst.castTag(.@"asm").?),
88 .unreachable_safe => return zirUnreachable(mod, scope, old_inst.castTag(.unreachable_safe).?, true),
89 .unreachable_unsafe => return zirUnreachable(mod, scope, old_inst.castTag(.unreachable_unsafe).?, false),
90 .@"return" => return zirReturn(mod, scope, old_inst.castTag(.@"return").?),
91 .return_void => return zirReturnVoid(mod, scope, old_inst.castTag(.return_void).?),
92 .@"fn" => return zirFn(mod, scope, old_inst.castTag(.@"fn").?),
93 .@"export" => return zirExport(mod, scope, old_inst.castTag(.@"export").?),
94 .primitive => return zirPrimitive(mod, scope, old_inst.castTag(.primitive).?),
95 .fntype => return zirFnType(mod, scope, old_inst.castTag(.fntype).?),
96 .intcast => return zirIntcast(mod, scope, old_inst.castTag(.intcast).?),
97 .bitcast => return zirBitcast(mod, scope, old_inst.castTag(.bitcast).?),
98 .floatcast => return zirFloatcast(mod, scope, old_inst.castTag(.floatcast).?),
99 .elem_ptr => return zirElemPtr(mod, scope, old_inst.castTag(.elem_ptr).?),
100 .elem_val => return zirElemVal(mod, scope, old_inst.castTag(.elem_val).?),
101 .add => return zirArithmetic(mod, scope, old_inst.castTag(.add).?),
102 .addwrap => return zirArithmetic(mod, scope, old_inst.castTag(.addwrap).?),
103 .sub => return zirArithmetic(mod, scope, old_inst.castTag(.sub).?),
104 .subwrap => return zirArithmetic(mod, scope, old_inst.castTag(.subwrap).?),
105 .mul => return zirArithmetic(mod, scope, old_inst.castTag(.mul).?),
106 .mulwrap => return zirArithmetic(mod, scope, old_inst.castTag(.mulwrap).?),
107 .div => return zirArithmetic(mod, scope, old_inst.castTag(.div).?),
108 .mod_rem => return zirArithmetic(mod, scope, old_inst.castTag(.mod_rem).?),
109 .array_cat => return zirArrayCat(mod, scope, old_inst.castTag(.array_cat).?),
110 .array_mul => return zirArrayMul(mod, scope, old_inst.castTag(.array_mul).?),
111 .bit_and => return zirBitwise(mod, scope, old_inst.castTag(.bit_and).?),
112 .bit_not => return zirBitNot(mod, scope, old_inst.castTag(.bit_not).?),
113 .bit_or => return zirBitwise(mod, scope, old_inst.castTag(.bit_or).?),
114 .xor => return zirBitwise(mod, scope, old_inst.castTag(.xor).?),
115 .shl => return zirShl(mod, scope, old_inst.castTag(.shl).?),
116 .shr => return zirShr(mod, scope, old_inst.castTag(.shr).?),
117 .cmp_lt => return zirCmp(mod, scope, old_inst.castTag(.cmp_lt).?, .lt),
118 .cmp_lte => return zirCmp(mod, scope, old_inst.castTag(.cmp_lte).?, .lte),
119 .cmp_eq => return zirCmp(mod, scope, old_inst.castTag(.cmp_eq).?, .eq),
120 .cmp_gte => return zirCmp(mod, scope, old_inst.castTag(.cmp_gte).?, .gte),
121 .cmp_gt => return zirCmp(mod, scope, old_inst.castTag(.cmp_gt).?, .gt),
122 .cmp_neq => return zirCmp(mod, scope, old_inst.castTag(.cmp_neq).?, .neq),
123 .condbr => return zirCondbr(mod, scope, old_inst.castTag(.condbr).?),
124 .is_null => return zirIsNull(mod, scope, old_inst.castTag(.is_null).?, false),
125 .is_non_null => return zirIsNull(mod, scope, old_inst.castTag(.is_non_null).?, true),
126 .is_null_ptr => return zirIsNullPtr(mod, scope, old_inst.castTag(.is_null_ptr).?, false),
127 .is_non_null_ptr => return zirIsNullPtr(mod, scope, old_inst.castTag(.is_non_null_ptr).?, true),
128 .is_err => return zirIsErr(mod, scope, old_inst.castTag(.is_err).?),
129 .is_err_ptr => return zirIsErrPtr(mod, scope, old_inst.castTag(.is_err_ptr).?),
130 .bool_not => return zirBoolNot(mod, scope, old_inst.castTag(.bool_not).?),
131 .typeof => return zirTypeof(mod, scope, old_inst.castTag(.typeof).?),
132 .typeof_peer => return zirTypeofPeer(mod, scope, old_inst.castTag(.typeof_peer).?),
133 .optional_type => return zirOptionalType(mod, scope, old_inst.castTag(.optional_type).?),
134 .optional_payload_safe => return zirOptionalPayload(mod, scope, old_inst.castTag(.optional_payload_safe).?, true),
135 .optional_payload_unsafe => return zirOptionalPayload(mod, scope, old_inst.castTag(.optional_payload_unsafe).?, false),
136 .optional_payload_safe_ptr => return zirOptionalPayloadPtr(mod, scope, old_inst.castTag(.optional_payload_safe_ptr).?, true),
137 .optional_payload_unsafe_ptr => return zirOptionalPayloadPtr(mod, scope, old_inst.castTag(.optional_payload_unsafe_ptr).?, false),
138 .err_union_payload_safe => return zirErrUnionPayload(mod, scope, old_inst.castTag(.err_union_payload_safe).?, true),
139 .err_union_payload_unsafe => return zirErrUnionPayload(mod, scope, old_inst.castTag(.err_union_payload_unsafe).?, false),
140 .err_union_payload_safe_ptr => return zirErrUnionPayloadPtr(mod, scope, old_inst.castTag(.err_union_payload_safe_ptr).?, true),
141 .err_union_payload_unsafe_ptr => return zirErrUnionPayloadPtr(mod, scope, old_inst.castTag(.err_union_payload_unsafe_ptr).?, false),
142 .err_union_code => return zirErrUnionCode(mod, scope, old_inst.castTag(.err_union_code).?),
143 .err_union_code_ptr => return zirErrUnionCodePtr(mod, scope, old_inst.castTag(.err_union_code_ptr).?),
144 .ensure_err_payload_void => return zirEnsureErrPayloadVoid(mod, scope, old_inst.castTag(.ensure_err_payload_void).?),
145 .array_type => return zirArrayType(mod, scope, old_inst.castTag(.array_type).?),
146 .array_type_sentinel => return zirArrayTypeSentinel(mod, scope, old_inst.castTag(.array_type_sentinel).?),
147 .enum_literal => return zirEnumLiteral(mod, scope, old_inst.castTag(.enum_literal).?),
148 .merge_error_sets => return zirMergeErrorSets(mod, scope, old_inst.castTag(.merge_error_sets).?),
149 .error_union_type => return zirErrorUnionType(mod, scope, old_inst.castTag(.error_union_type).?),
150 .anyframe_type => return zirAnyframeType(mod, scope, old_inst.castTag(.anyframe_type).?),
151 .error_set => return zirErrorSet(mod, scope, old_inst.castTag(.error_set).?),
152 .slice => return zirSlice(mod, scope, old_inst.castTag(.slice).?),
153 .slice_start => return zirSliceStart(mod, scope, old_inst.castTag(.slice_start).?),
154 .import => return zirImport(mod, scope, old_inst.castTag(.import).?),
155 .switchbr => return zirSwitchbr(mod, scope, old_inst.castTag(.switchbr).?),
156 .switch_range => return zirSwitchRange(mod, scope, old_inst.castTag(.switch_range).?),
157 .bool_and => return zirBoolOp(mod, scope, old_inst.castTag(.bool_and).?),
158 .bool_or => return zirBoolOp(mod, scope, old_inst.castTag(.bool_or).?),
169159
170160 .container_field_named,
171161 .container_field_typed,
......@@ -258,7 +248,7 @@ pub fn resolveInstConst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerE
258248 };
259249}
260250
261fn analyzeInstConst(mod: *Module, scope: *Scope, const_inst: *zir.Inst.Const) InnerError!*Inst {
251fn zirConst(mod: *Module, scope: *Scope, const_inst: *zir.Inst.Const) InnerError!*Inst {
262252 const tracy = trace(@src());
263253 defer tracy.end();
264254 // Move the TypedValue from old memory to new memory. This allows freeing the ZIR instructions
......@@ -275,44 +265,35 @@ fn analyzeConstInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError
275265 };
276266}
277267
278fn analyzeInstCoerceResultBlockPtr(
268fn zirCoerceResultBlockPtr(
279269 mod: *Module,
280270 scope: *Scope,
281271 inst: *zir.Inst.CoerceResultBlockPtr,
282272) InnerError!*Inst {
283273 const tracy = trace(@src());
284274 defer tracy.end();
285 return mod.fail(scope, inst.base.src, "TODO implement analyzeInstCoerceResultBlockPtr", .{});
275 return mod.fail(scope, inst.base.src, "TODO implement zirCoerceResultBlockPtr", .{});
286276}
287277
288fn bitCastRef(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
278fn zirBitcastRef(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
289279 const tracy = trace(@src());
290280 defer tracy.end();
291 return mod.fail(scope, inst.base.src, "TODO implement zir_sema.bitCastRef", .{});
281 return mod.fail(scope, inst.base.src, "TODO implement zir_sema.zirBitcastRef", .{});
292282}
293283
294fn bitCastResultPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
284fn zirBitcastResultPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
295285 const tracy = trace(@src());
296286 defer tracy.end();
297 return mod.fail(scope, inst.base.src, "TODO implement zir_sema.bitCastResultPtr", .{});
287 return mod.fail(scope, inst.base.src, "TODO implement zir_sema.zirBitcastResultPtr", .{});
298288}
299289
300fn analyzeInstCoerceResultPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
290fn zirCoerceResultPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
301291 const tracy = trace(@src());
302292 defer tracy.end();
303 return mod.fail(scope, inst.base.src, "TODO implement analyzeInstCoerceResultPtr", .{});
293 return mod.fail(scope, inst.base.src, "TODO implement zirCoerceResultPtr", .{});
304294}
305295
306/// Equivalent to `as(ptr_child_type(typeof(ptr)), value)`.
307fn analyzeInstCoerceToPtrElem(mod: *Module, scope: *Scope, inst: *zir.Inst.CoerceToPtrElem) InnerError!*Inst {
308 const tracy = trace(@src());
309 defer tracy.end();
310 const ptr = try resolveInst(mod, scope, inst.positionals.ptr);
311 const operand = try resolveInst(mod, scope, inst.positionals.value);
312 return mod.coerce(scope, ptr.ty.elemType(), operand);
313}
314
315fn analyzeInstRetPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
296fn zirRetPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
316297 const tracy = trace(@src());
317298 defer tracy.end();
318299 const b = try mod.requireFunctionBlock(scope, inst.base.src);
......@@ -322,7 +303,7 @@ fn analyzeInstRetPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerErr
322303 return mod.addNoOp(b, inst.base.src, ptr_type, .alloc);
323304}
324305
325fn ref(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
306fn zirRef(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
326307 const tracy = trace(@src());
327308 defer tracy.end();
328309
......@@ -330,7 +311,7 @@ fn ref(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
330311 return mod.analyzeRef(scope, inst.base.src, operand);
331312}
332313
333fn analyzeInstRetType(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
314fn zirRetType(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
334315 const tracy = trace(@src());
335316 defer tracy.end();
336317 const b = try mod.requireFunctionBlock(scope, inst.base.src);
......@@ -339,7 +320,7 @@ fn analyzeInstRetType(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerEr
339320 return mod.constType(scope, inst.base.src, ret_type);
340321}
341322
342fn analyzeInstEnsureResultUsed(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
323fn zirEnsureResultUsed(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
343324 const tracy = trace(@src());
344325 defer tracy.end();
345326 const operand = try resolveInst(mod, scope, inst.positionals.operand);
......@@ -349,7 +330,7 @@ fn analyzeInstEnsureResultUsed(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp
349330 }
350331}
351332
352fn analyzeInstEnsureResultNonError(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
333fn zirEnsureResultNonError(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
353334 const tracy = trace(@src());
354335 defer tracy.end();
355336 const operand = try resolveInst(mod, scope, inst.positionals.operand);
......@@ -359,7 +340,7 @@ fn analyzeInstEnsureResultNonError(mod: *Module, scope: *Scope, inst: *zir.Inst.
359340 }
360341}
361342
362fn indexablePtrLen(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
343fn zirIndexablePtrLen(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
363344 const tracy = trace(@src());
364345 defer tracy.end();
365346
......@@ -389,7 +370,7 @@ fn indexablePtrLen(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError
389370 return mod.analyzeDeref(scope, inst.base.src, result_ptr, result_ptr.src);
390371}
391372
392fn analyzeInstAlloc(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
373fn zirAlloc(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
393374 const tracy = trace(@src());
394375 defer tracy.end();
395376 const var_type = try resolveType(mod, scope, inst.positionals.operand);
......@@ -398,7 +379,7 @@ fn analyzeInstAlloc(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerErro
398379 return mod.addNoOp(b, inst.base.src, ptr_type, .alloc);
399380}
400381
401fn analyzeInstAllocMut(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
382fn zirAllocMut(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
402383 const tracy = trace(@src());
403384 defer tracy.end();
404385 const var_type = try resolveType(mod, scope, inst.positionals.operand);
......@@ -408,7 +389,7 @@ fn analyzeInstAllocMut(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerE
408389 return mod.addNoOp(b, inst.base.src, ptr_type, .alloc);
409390}
410391
411fn analyzeInstAllocInferred(
392fn zirAllocInferred(
412393 mod: *Module,
413394 scope: *Scope,
414395 inst: *zir.Inst.NoOp,
......@@ -437,7 +418,7 @@ fn analyzeInstAllocInferred(
437418 return result;
438419}
439420
440fn analyzeInstResolveInferredAlloc(
421fn zirResolveInferredAlloc(
441422 mod: *Module,
442423 scope: *Scope,
443424 inst: *zir.Inst.UnOp,
......@@ -466,28 +447,44 @@ fn analyzeInstResolveInferredAlloc(
466447 return mod.constVoid(scope, inst.base.src);
467448}
468449
469fn analyzeInstStoreToInferredPtr(
450fn zirStoreToBlockPtr(
451 mod: *Module,
452 scope: *Scope,
453 inst: *zir.Inst.BinOp,
454) InnerError!*Inst {
455 const tracy = trace(@src());
456 defer tracy.end();
457
458 const ptr = try resolveInst(mod, scope, inst.positionals.lhs);
459 const value = try resolveInst(mod, scope, inst.positionals.rhs);
460 const ptr_ty = try mod.simplePtrType(scope, inst.base.src, value.ty, true, .One);
461 const b = try mod.requireRuntimeBlock(scope, inst.base.src);
462 const bitcasted_ptr = try mod.addUnOp(b, inst.base.src, ptr_ty, .bitcast, ptr);
463 return mod.storePtr(scope, inst.base.src, bitcasted_ptr, value);
464}
465
466fn zirStoreToInferredPtr(
470467 mod: *Module,
471468 scope: *Scope,
472469 inst: *zir.Inst.BinOp,
473470) InnerError!*Inst {
474471 const tracy = trace(@src());
475472 defer tracy.end();
473
476474 const ptr = try resolveInst(mod, scope, inst.positionals.lhs);
477475 const value = try resolveInst(mod, scope, inst.positionals.rhs);
478476 const inferred_alloc = ptr.castTag(.constant).?.val.castTag(.inferred_alloc).?;
479477 // Add the stored instruction to the set we will use to resolve peer types
480478 // for the inferred allocation.
481479 try inferred_alloc.data.stored_inst_list.append(scope.arena(), value);
482 // Create a new alloc with exactly the type the pointer wants.
483 // Later it gets cleaned up by aliasing the alloc we are supposed to be storing to.
480 // Create a runtime bitcast instruction with exactly the type the pointer wants.
484481 const ptr_ty = try mod.simplePtrType(scope, inst.base.src, value.ty, true, .One);
485482 const b = try mod.requireRuntimeBlock(scope, inst.base.src);
486483 const bitcasted_ptr = try mod.addUnOp(b, inst.base.src, ptr_ty, .bitcast, ptr);
487484 return mod.storePtr(scope, inst.base.src, bitcasted_ptr, value);
488485}
489486
490fn analyzeInstSetEvalBranchQuota(
487fn zirSetEvalBranchQuota(
491488 mod: *Module,
492489 scope: *Scope,
493490 inst: *zir.Inst.UnOp,
......@@ -499,15 +496,16 @@ fn analyzeInstSetEvalBranchQuota(
499496 return mod.constVoid(scope, inst.base.src);
500497}
501498
502fn analyzeInstStore(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
499fn zirStore(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
503500 const tracy = trace(@src());
504501 defer tracy.end();
502
505503 const ptr = try resolveInst(mod, scope, inst.positionals.lhs);
506504 const value = try resolveInst(mod, scope, inst.positionals.rhs);
507505 return mod.storePtr(scope, inst.base.src, ptr, value);
508506}
509507
510fn analyzeInstParamType(mod: *Module, scope: *Scope, inst: *zir.Inst.ParamType) InnerError!*Inst {
508fn zirParamType(mod: *Module, scope: *Scope, inst: *zir.Inst.ParamType) InnerError!*Inst {
511509 const tracy = trace(@src());
512510 defer tracy.end();
513511 const fn_inst = try resolveInst(mod, scope, inst.positionals.func);
......@@ -516,7 +514,7 @@ fn analyzeInstParamType(mod: *Module, scope: *Scope, inst: *zir.Inst.ParamType)
516514 const fn_ty: Type = switch (fn_inst.ty.zigTypeTag()) {
517515 .Fn => fn_inst.ty,
518516 .BoundFn => {
519 return mod.fail(scope, fn_inst.src, "TODO implement analyzeInstParamType for method call syntax", .{});
517 return mod.fail(scope, fn_inst.src, "TODO implement zirParamType for method call syntax", .{});
520518 },
521519 else => {
522520 return mod.fail(scope, fn_inst.src, "expected function, found '{}'", .{fn_inst.ty});
......@@ -538,7 +536,7 @@ fn analyzeInstParamType(mod: *Module, scope: *Scope, inst: *zir.Inst.ParamType)
538536 return mod.constType(scope, inst.base.src, param_type);
539537}
540538
541fn analyzeInstStr(mod: *Module, scope: *Scope, str_inst: *zir.Inst.Str) InnerError!*Inst {
539fn zirStr(mod: *Module, scope: *Scope, str_inst: *zir.Inst.Str) InnerError!*Inst {
542540 const tracy = trace(@src());
543541 defer tracy.end();
544542 // The bytes references memory inside the ZIR module, which can get deallocated
......@@ -557,14 +555,14 @@ fn analyzeInstStr(mod: *Module, scope: *Scope, str_inst: *zir.Inst.Str) InnerErr
557555 return mod.analyzeDeclRef(scope, str_inst.base.src, new_decl);
558556}
559557
560fn analyzeInstInt(mod: *Module, scope: *Scope, inst: *zir.Inst.Int) InnerError!*Inst {
558fn zirInt(mod: *Module, scope: *Scope, inst: *zir.Inst.Int) InnerError!*Inst {
561559 const tracy = trace(@src());
562560 defer tracy.end();
563561
564562 return mod.constIntBig(scope, inst.base.src, Type.initTag(.comptime_int), inst.positionals.int);
565563}
566564
567fn analyzeInstExport(mod: *Module, scope: *Scope, export_inst: *zir.Inst.Export) InnerError!*Inst {
565fn zirExport(mod: *Module, scope: *Scope, export_inst: *zir.Inst.Export) InnerError!*Inst {
568566 const tracy = trace(@src());
569567 defer tracy.end();
570568 const symbol_name = try resolveConstString(mod, scope, export_inst.positionals.symbol_name);
......@@ -574,14 +572,14 @@ fn analyzeInstExport(mod: *Module, scope: *Scope, export_inst: *zir.Inst.Export)
574572 return mod.constVoid(scope, export_inst.base.src);
575573}
576574
577fn analyzeInstCompileError(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
575fn zirCompileError(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
578576 const tracy = trace(@src());
579577 defer tracy.end();
580578 const msg = try resolveConstString(mod, scope, inst.positionals.operand);
581579 return mod.fail(scope, inst.base.src, "{s}", .{msg});
582580}
583581
584fn analyzeInstCompileLog(mod: *Module, scope: *Scope, inst: *zir.Inst.CompileLog) InnerError!*Inst {
582fn zirCompileLog(mod: *Module, scope: *Scope, inst: *zir.Inst.CompileLog) InnerError!*Inst {
585583 var managed = mod.compile_log_text.toManaged(mod.gpa);
586584 defer mod.compile_log_text = managed.moveToUnmanaged();
587585 const writer = managed.writer();
......@@ -608,7 +606,7 @@ fn analyzeInstCompileLog(mod: *Module, scope: *Scope, inst: *zir.Inst.CompileLog
608606 return mod.constVoid(scope, inst.base.src);
609607}
610608
611fn analyzeInstArg(mod: *Module, scope: *Scope, inst: *zir.Inst.Arg) InnerError!*Inst {
609fn zirArg(mod: *Module, scope: *Scope, inst: *zir.Inst.Arg) InnerError!*Inst {
612610 const tracy = trace(@src());
613611 defer tracy.end();
614612 const b = try mod.requireFunctionBlock(scope, inst.base.src);
......@@ -631,7 +629,7 @@ fn analyzeInstArg(mod: *Module, scope: *Scope, inst: *zir.Inst.Arg) InnerError!*
631629 return mod.addArg(b, inst.base.src, param_type, name);
632630}
633631
634fn analyzeInstLoop(mod: *Module, scope: *Scope, inst: *zir.Inst.Loop) InnerError!*Inst {
632fn zirLoop(mod: *Module, scope: *Scope, inst: *zir.Inst.Loop) InnerError!*Inst {
635633 const tracy = trace(@src());
636634 defer tracy.end();
637635 const parent_block = scope.cast(Scope.Block).?;
......@@ -672,7 +670,7 @@ fn analyzeInstLoop(mod: *Module, scope: *Scope, inst: *zir.Inst.Loop) InnerError
672670 return &loop_inst.base;
673671}
674672
675fn analyzeInstBlockFlat(mod: *Module, scope: *Scope, inst: *zir.Inst.Block, is_comptime: bool) InnerError!*Inst {
673fn zirBlockFlat(mod: *Module, scope: *Scope, inst: *zir.Inst.Block, is_comptime: bool) InnerError!*Inst {
676674 const tracy = trace(@src());
677675 defer tracy.end();
678676 const parent_block = scope.cast(Scope.Block).?;
......@@ -704,9 +702,15 @@ fn analyzeInstBlockFlat(mod: *Module, scope: *Scope, inst: *zir.Inst.Block, is_c
704702 return resolveInst(mod, scope, last_zir_inst);
705703}
706704
707fn analyzeInstBlock(mod: *Module, scope: *Scope, inst: *zir.Inst.Block, is_comptime: bool) InnerError!*Inst {
705fn zirBlock(
706 mod: *Module,
707 scope: *Scope,
708 inst: *zir.Inst.Block,
709 is_comptime: bool,
710) InnerError!*Inst {
708711 const tracy = trace(@src());
709712 defer tracy.end();
713
710714 const parent_block = scope.cast(Scope.Block).?;
711715
712716 // Reserve space for a Block instruction so that generated Break instructions can
......@@ -798,30 +802,52 @@ fn analyzeBlockBody(
798802 return &merges.block_inst.base;
799803}
800804
801fn analyzeInstBreakpoint(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
805fn zirBreakpoint(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
802806 const tracy = trace(@src());
803807 defer tracy.end();
804808 const b = try mod.requireRuntimeBlock(scope, inst.base.src);
805809 return mod.addNoOp(b, inst.base.src, Type.initTag(.void), .breakpoint);
806810}
807811
808fn analyzeInstBreak(mod: *Module, scope: *Scope, inst: *zir.Inst.Break) InnerError!*Inst {
812fn zirBreak(mod: *Module, scope: *Scope, inst: *zir.Inst.Break) InnerError!*Inst {
809813 const tracy = trace(@src());
810814 defer tracy.end();
815
811816 const operand = try resolveInst(mod, scope, inst.positionals.operand);
812817 const block = inst.positionals.block;
813818 return analyzeBreak(mod, scope, inst.base.src, block, operand);
814819}
815820
816fn analyzeInstBreakVoid(mod: *Module, scope: *Scope, inst: *zir.Inst.BreakVoid) InnerError!*Inst {
821fn zirBreakVoid(mod: *Module, scope: *Scope, inst: *zir.Inst.BreakVoid) InnerError!*Inst {
817822 const tracy = trace(@src());
818823 defer tracy.end();
824
819825 const block = inst.positionals.block;
820826 const void_inst = try mod.constVoid(scope, inst.base.src);
821827 return analyzeBreak(mod, scope, inst.base.src, block, void_inst);
822828}
823829
824fn analyzeInstDbgStmt(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
830fn analyzeBreak(
831 mod: *Module,
832 scope: *Scope,
833 src: usize,
834 zir_block: *zir.Inst.Block,
835 operand: *Inst,
836) InnerError!*Inst {
837 var opt_block = scope.cast(Scope.Block);
838 while (opt_block) |block| {
839 if (block.label) |*label| {
840 if (label.zir_block == zir_block) {
841 try label.merges.results.append(mod.gpa, operand);
842 const b = try mod.requireFunctionBlock(scope, src);
843 return mod.addBr(b, src, label.merges.block_inst, operand);
844 }
845 }
846 opt_block = block.parent;
847 } else unreachable;
848}
849
850fn zirDbgStmt(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
825851 const tracy = trace(@src());
826852 defer tracy.end();
827853 if (scope.cast(Scope.Block)) |b| {
......@@ -832,26 +858,26 @@ fn analyzeInstDbgStmt(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerEr
832858 return mod.constVoid(scope, inst.base.src);
833859}
834860
835fn analyzeInstDeclRefStr(mod: *Module, scope: *Scope, inst: *zir.Inst.DeclRefStr) InnerError!*Inst {
861fn zirDeclRefStr(mod: *Module, scope: *Scope, inst: *zir.Inst.DeclRefStr) InnerError!*Inst {
836862 const tracy = trace(@src());
837863 defer tracy.end();
838864 const decl_name = try resolveConstString(mod, scope, inst.positionals.name);
839865 return mod.analyzeDeclRefByName(scope, inst.base.src, decl_name);
840866}
841867
842fn declRef(mod: *Module, scope: *Scope, inst: *zir.Inst.DeclRef) InnerError!*Inst {
868fn zirDeclRef(mod: *Module, scope: *Scope, inst: *zir.Inst.DeclRef) InnerError!*Inst {
843869 const tracy = trace(@src());
844870 defer tracy.end();
845871 return mod.analyzeDeclRef(scope, inst.base.src, inst.positionals.decl);
846872}
847873
848fn declVal(mod: *Module, scope: *Scope, inst: *zir.Inst.DeclVal) InnerError!*Inst {
874fn zirDeclVal(mod: *Module, scope: *Scope, inst: *zir.Inst.DeclVal) InnerError!*Inst {
849875 const tracy = trace(@src());
850876 defer tracy.end();
851877 return mod.analyzeDeclVal(scope, inst.base.src, inst.positionals.decl);
852878}
853879
854fn call(mod: *Module, scope: *Scope, inst: *zir.Inst.Call) InnerError!*Inst {
880fn zirCall(mod: *Module, scope: *Scope, inst: *zir.Inst.Call) InnerError!*Inst {
855881 const tracy = trace(@src());
856882 defer tracy.end();
857883
......@@ -1002,7 +1028,7 @@ fn call(mod: *Module, scope: *Scope, inst: *zir.Inst.Call) InnerError!*Inst {
10021028 return mod.addCall(b, inst.base.src, ret_type, func, casted_args);
10031029}
10041030
1005fn analyzeInstFn(mod: *Module, scope: *Scope, fn_inst: *zir.Inst.Fn) InnerError!*Inst {
1031fn zirFn(mod: *Module, scope: *Scope, fn_inst: *zir.Inst.Fn) InnerError!*Inst {
10061032 const tracy = trace(@src());
10071033 defer tracy.end();
10081034 const fn_type = try resolveType(mod, scope, fn_inst.positionals.fn_type);
......@@ -1019,13 +1045,13 @@ fn analyzeInstFn(mod: *Module, scope: *Scope, fn_inst: *zir.Inst.Fn) InnerError!
10191045 });
10201046}
10211047
1022fn analyzeInstIntType(mod: *Module, scope: *Scope, inttype: *zir.Inst.IntType) InnerError!*Inst {
1048fn zirIntType(mod: *Module, scope: *Scope, inttype: *zir.Inst.IntType) InnerError!*Inst {
10231049 const tracy = trace(@src());
10241050 defer tracy.end();
10251051 return mod.fail(scope, inttype.base.src, "TODO implement inttype", .{});
10261052}
10271053
1028fn analyzeInstOptionalType(mod: *Module, scope: *Scope, optional: *zir.Inst.UnOp) InnerError!*Inst {
1054fn zirOptionalType(mod: *Module, scope: *Scope, optional: *zir.Inst.UnOp) InnerError!*Inst {
10291055 const tracy = trace(@src());
10301056 defer tracy.end();
10311057 const child_type = try resolveType(mod, scope, optional.positionals.operand);
......@@ -1033,7 +1059,7 @@ fn analyzeInstOptionalType(mod: *Module, scope: *Scope, optional: *zir.Inst.UnOp
10331059 return mod.constType(scope, optional.base.src, try mod.optionalType(scope, child_type));
10341060}
10351061
1036fn analyzeInstArrayType(mod: *Module, scope: *Scope, array: *zir.Inst.BinOp) InnerError!*Inst {
1062fn zirArrayType(mod: *Module, scope: *Scope, array: *zir.Inst.BinOp) InnerError!*Inst {
10371063 const tracy = trace(@src());
10381064 defer tracy.end();
10391065 // TODO these should be lazily evaluated
......@@ -1043,7 +1069,7 @@ fn analyzeInstArrayType(mod: *Module, scope: *Scope, array: *zir.Inst.BinOp) Inn
10431069 return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), null, elem_type));
10441070}
10451071
1046fn analyzeInstArrayTypeSentinel(mod: *Module, scope: *Scope, array: *zir.Inst.ArrayTypeSentinel) InnerError!*Inst {
1072fn zirArrayTypeSentinel(mod: *Module, scope: *Scope, array: *zir.Inst.ArrayTypeSentinel) InnerError!*Inst {
10471073 const tracy = trace(@src());
10481074 defer tracy.end();
10491075 // TODO these should be lazily evaluated
......@@ -1054,7 +1080,7 @@ fn analyzeInstArrayTypeSentinel(mod: *Module, scope: *Scope, array: *zir.Inst.Ar
10541080 return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), sentinel.val, elem_type));
10551081}
10561082
1057fn analyzeInstErrorUnionType(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
1083fn zirErrorUnionType(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
10581084 const tracy = trace(@src());
10591085 defer tracy.end();
10601086 const error_union = try resolveType(mod, scope, inst.positionals.lhs);
......@@ -1067,7 +1093,7 @@ fn analyzeInstErrorUnionType(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp)
10671093 return mod.constType(scope, inst.base.src, try mod.errorUnionType(scope, error_union, payload));
10681094}
10691095
1070fn analyzeInstAnyframeType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
1096fn zirAnyframeType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
10711097 const tracy = trace(@src());
10721098 defer tracy.end();
10731099 const return_type = try resolveType(mod, scope, inst.positionals.operand);
......@@ -1075,7 +1101,7 @@ fn analyzeInstAnyframeType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) In
10751101 return mod.constType(scope, inst.base.src, try mod.anyframeType(scope, return_type));
10761102}
10771103
1078fn analyzeInstErrorSet(mod: *Module, scope: *Scope, inst: *zir.Inst.ErrorSet) InnerError!*Inst {
1104fn zirErrorSet(mod: *Module, scope: *Scope, inst: *zir.Inst.ErrorSet) InnerError!*Inst {
10791105 const tracy = trace(@src());
10801106 defer tracy.end();
10811107 // The declarations arena will store the hashmap.
......@@ -1107,13 +1133,13 @@ fn analyzeInstErrorSet(mod: *Module, scope: *Scope, inst: *zir.Inst.ErrorSet) In
11071133 return mod.analyzeDeclVal(scope, inst.base.src, new_decl);
11081134}
11091135
1110fn analyzeInstMergeErrorSets(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
1136fn zirMergeErrorSets(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
11111137 const tracy = trace(@src());
11121138 defer tracy.end();
11131139 return mod.fail(scope, inst.base.src, "TODO implement merge_error_sets", .{});
11141140}
11151141
1116fn analyzeInstEnumLiteral(mod: *Module, scope: *Scope, inst: *zir.Inst.EnumLiteral) InnerError!*Inst {
1142fn zirEnumLiteral(mod: *Module, scope: *Scope, inst: *zir.Inst.EnumLiteral) InnerError!*Inst {
11171143 const tracy = trace(@src());
11181144 defer tracy.end();
11191145 const duped_name = try scope.arena().dupe(u8, inst.positionals.name);
......@@ -1124,7 +1150,7 @@ fn analyzeInstEnumLiteral(mod: *Module, scope: *Scope, inst: *zir.Inst.EnumLiter
11241150}
11251151
11261152/// Pointer in, pointer out.
1127fn optionalPayloadPtr(
1153fn zirOptionalPayloadPtr(
11281154 mod: *Module,
11291155 scope: *Scope,
11301156 unwrap: *zir.Inst.UnOp,
......@@ -1165,7 +1191,7 @@ fn optionalPayloadPtr(
11651191}
11661192
11671193/// Value in, value out.
1168fn optionalPayload(
1194fn zirOptionalPayload(
11691195 mod: *Module,
11701196 scope: *Scope,
11711197 unwrap: *zir.Inst.UnOp,
......@@ -1201,40 +1227,40 @@ fn optionalPayload(
12011227}
12021228
12031229/// Value in, value out
1204fn errorUnionPayload(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp, safety_check: bool) InnerError!*Inst {
1230fn zirErrUnionPayload(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp, safety_check: bool) InnerError!*Inst {
12051231 const tracy = trace(@src());
12061232 defer tracy.end();
1207 return mod.fail(scope, unwrap.base.src, "TODO implement zir_sema.errorUnionPayload", .{});
1233 return mod.fail(scope, unwrap.base.src, "TODO implement zir_sema.zirErrUnionPayload", .{});
12081234}
12091235
12101236/// Pointer in, pointer out
1211fn errorUnionPayloadPtr(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp, safety_check: bool) InnerError!*Inst {
1237fn zirErrUnionPayloadPtr(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp, safety_check: bool) InnerError!*Inst {
12121238 const tracy = trace(@src());
12131239 defer tracy.end();
1214 return mod.fail(scope, unwrap.base.src, "TODO implement zir_sema.errorUnionPayloadPtr", .{});
1240 return mod.fail(scope, unwrap.base.src, "TODO implement zir_sema.zirErrUnionPayloadPtr", .{});
12151241}
12161242
12171243/// Value in, value out
1218fn errorUnionCode(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp) InnerError!*Inst {
1244fn zirErrUnionCode(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp) InnerError!*Inst {
12191245 const tracy = trace(@src());
12201246 defer tracy.end();
1221 return mod.fail(scope, unwrap.base.src, "TODO implement zir_sema.errorUnionCode", .{});
1247 return mod.fail(scope, unwrap.base.src, "TODO implement zir_sema.zirErrUnionCode", .{});
12221248}
12231249
12241250/// Pointer in, value out
1225fn errorUnionCodePtr(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp) InnerError!*Inst {
1251fn zirErrUnionCodePtr(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp) InnerError!*Inst {
12261252 const tracy = trace(@src());
12271253 defer tracy.end();
1228 return mod.fail(scope, unwrap.base.src, "TODO implement zir_sema.errorUnionCodePtr", .{});
1254 return mod.fail(scope, unwrap.base.src, "TODO implement zir_sema.zirErrUnionCodePtr", .{});
12291255}
12301256
1231fn analyzeInstEnsureErrPayloadVoid(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp) InnerError!*Inst {
1257fn zirEnsureErrPayloadVoid(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp) InnerError!*Inst {
12321258 const tracy = trace(@src());
12331259 defer tracy.end();
1234 return mod.fail(scope, unwrap.base.src, "TODO implement analyzeInstEnsureErrPayloadVoid", .{});
1260 return mod.fail(scope, unwrap.base.src, "TODO implement zirEnsureErrPayloadVoid", .{});
12351261}
12361262
1237fn analyzeInstFnType(mod: *Module, scope: *Scope, fntype: *zir.Inst.FnType) InnerError!*Inst {
1263fn zirFnType(mod: *Module, scope: *Scope, fntype: *zir.Inst.FnType) InnerError!*Inst {
12381264 const tracy = trace(@src());
12391265 defer tracy.end();
12401266 const return_type = try resolveType(mod, scope, fntype.positionals.return_type);
......@@ -1277,13 +1303,13 @@ fn analyzeInstFnType(mod: *Module, scope: *Scope, fntype: *zir.Inst.FnType) Inne
12771303 return mod.constType(scope, fntype.base.src, fn_ty);
12781304}
12791305
1280fn analyzeInstPrimitive(mod: *Module, scope: *Scope, primitive: *zir.Inst.Primitive) InnerError!*Inst {
1306fn zirPrimitive(mod: *Module, scope: *Scope, primitive: *zir.Inst.Primitive) InnerError!*Inst {
12811307 const tracy = trace(@src());
12821308 defer tracy.end();
12831309 return mod.constInst(scope, primitive.base.src, primitive.positionals.tag.toTypedValue());
12841310}
12851311
1286fn analyzeInstAs(mod: *Module, scope: *Scope, as: *zir.Inst.BinOp) InnerError!*Inst {
1312fn zirAs(mod: *Module, scope: *Scope, as: *zir.Inst.BinOp) InnerError!*Inst {
12871313 const tracy = trace(@src());
12881314 defer tracy.end();
12891315 const dest_type = try resolveType(mod, scope, as.positionals.lhs);
......@@ -1291,7 +1317,7 @@ fn analyzeInstAs(mod: *Module, scope: *Scope, as: *zir.Inst.BinOp) InnerError!*I
12911317 return mod.coerce(scope, dest_type, new_inst);
12921318}
12931319
1294fn analyzeInstPtrToInt(mod: *Module, scope: *Scope, ptrtoint: *zir.Inst.UnOp) InnerError!*Inst {
1320fn zirPtrtoint(mod: *Module, scope: *Scope, ptrtoint: *zir.Inst.UnOp) InnerError!*Inst {
12951321 const tracy = trace(@src());
12961322 defer tracy.end();
12971323 const ptr = try resolveInst(mod, scope, ptrtoint.positionals.operand);
......@@ -1304,7 +1330,7 @@ fn analyzeInstPtrToInt(mod: *Module, scope: *Scope, ptrtoint: *zir.Inst.UnOp) In
13041330 return mod.addUnOp(b, ptrtoint.base.src, ty, .ptrtoint, ptr);
13051331}
13061332
1307fn fieldVal(mod: *Module, scope: *Scope, inst: *zir.Inst.Field) InnerError!*Inst {
1333fn zirFieldVal(mod: *Module, scope: *Scope, inst: *zir.Inst.Field) InnerError!*Inst {
13081334 const tracy = trace(@src());
13091335 defer tracy.end();
13101336
......@@ -1315,7 +1341,7 @@ fn fieldVal(mod: *Module, scope: *Scope, inst: *zir.Inst.Field) InnerError!*Inst
13151341 return mod.analyzeDeref(scope, inst.base.src, result_ptr, result_ptr.src);
13161342}
13171343
1318fn fieldPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.Field) InnerError!*Inst {
1344fn zirFieldPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.Field) InnerError!*Inst {
13191345 const tracy = trace(@src());
13201346 defer tracy.end();
13211347
......@@ -1324,7 +1350,7 @@ fn fieldPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.Field) InnerError!*Inst
13241350 return mod.namedFieldPtr(scope, inst.base.src, object_ptr, field_name, inst.base.src);
13251351}
13261352
1327fn fieldValNamed(mod: *Module, scope: *Scope, inst: *zir.Inst.FieldNamed) InnerError!*Inst {
1353fn zirFieldValNamed(mod: *Module, scope: *Scope, inst: *zir.Inst.FieldNamed) InnerError!*Inst {
13281354 const tracy = trace(@src());
13291355 defer tracy.end();
13301356
......@@ -1336,7 +1362,7 @@ fn fieldValNamed(mod: *Module, scope: *Scope, inst: *zir.Inst.FieldNamed) InnerE
13361362 return mod.analyzeDeref(scope, inst.base.src, result_ptr, result_ptr.src);
13371363}
13381364
1339fn fieldPtrNamed(mod: *Module, scope: *Scope, inst: *zir.Inst.FieldNamed) InnerError!*Inst {
1365fn zirFieldPtrNamed(mod: *Module, scope: *Scope, inst: *zir.Inst.FieldNamed) InnerError!*Inst {
13401366 const tracy = trace(@src());
13411367 defer tracy.end();
13421368
......@@ -1346,7 +1372,7 @@ fn fieldPtrNamed(mod: *Module, scope: *Scope, inst: *zir.Inst.FieldNamed) InnerE
13461372 return mod.namedFieldPtr(scope, inst.base.src, object_ptr, field_name, fsrc);
13471373}
13481374
1349fn analyzeInstIntCast(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
1375fn zirIntcast(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
13501376 const tracy = trace(@src());
13511377 defer tracy.end();
13521378 const dest_type = try resolveType(mod, scope, inst.positionals.lhs);
......@@ -1384,7 +1410,7 @@ fn analyzeInstIntCast(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerE
13841410 return mod.fail(scope, inst.base.src, "TODO implement analyze widen or shorten int", .{});
13851411}
13861412
1387fn analyzeInstBitCast(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
1413fn zirBitcast(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
13881414 const tracy = trace(@src());
13891415 defer tracy.end();
13901416 const dest_type = try resolveType(mod, scope, inst.positionals.lhs);
......@@ -1392,7 +1418,7 @@ fn analyzeInstBitCast(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerE
13921418 return mod.bitcast(scope, dest_type, operand);
13931419}
13941420
1395fn analyzeInstFloatCast(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
1421fn zirFloatcast(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
13961422 const tracy = trace(@src());
13971423 defer tracy.end();
13981424 const dest_type = try resolveType(mod, scope, inst.positionals.lhs);
......@@ -1430,7 +1456,7 @@ fn analyzeInstFloatCast(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) Inne
14301456 return mod.fail(scope, inst.base.src, "TODO implement analyze widen or shorten float", .{});
14311457}
14321458
1433fn elemVal(mod: *Module, scope: *Scope, inst: *zir.Inst.Elem) InnerError!*Inst {
1459fn zirElemVal(mod: *Module, scope: *Scope, inst: *zir.Inst.Elem) InnerError!*Inst {
14341460 const tracy = trace(@src());
14351461 defer tracy.end();
14361462
......@@ -1441,7 +1467,7 @@ fn elemVal(mod: *Module, scope: *Scope, inst: *zir.Inst.Elem) InnerError!*Inst {
14411467 return mod.analyzeDeref(scope, inst.base.src, result_ptr, result_ptr.src);
14421468}
14431469
1444fn elemPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.Elem) InnerError!*Inst {
1470fn zirElemPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.Elem) InnerError!*Inst {
14451471 const tracy = trace(@src());
14461472 defer tracy.end();
14471473
......@@ -1450,7 +1476,7 @@ fn elemPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.Elem) InnerError!*Inst {
14501476 return mod.elemPtr(scope, inst.base.src, array_ptr, elem_index);
14511477}
14521478
1453fn analyzeInstSlice(mod: *Module, scope: *Scope, inst: *zir.Inst.Slice) InnerError!*Inst {
1479fn zirSlice(mod: *Module, scope: *Scope, inst: *zir.Inst.Slice) InnerError!*Inst {
14541480 const tracy = trace(@src());
14551481 defer tracy.end();
14561482 const array_ptr = try resolveInst(mod, scope, inst.positionals.array_ptr);
......@@ -1461,7 +1487,7 @@ fn analyzeInstSlice(mod: *Module, scope: *Scope, inst: *zir.Inst.Slice) InnerErr
14611487 return mod.analyzeSlice(scope, inst.base.src, array_ptr, start, end, sentinel);
14621488}
14631489
1464fn analyzeInstSliceStart(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
1490fn zirSliceStart(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
14651491 const tracy = trace(@src());
14661492 defer tracy.end();
14671493 const array_ptr = try resolveInst(mod, scope, inst.positionals.lhs);
......@@ -1470,7 +1496,7 @@ fn analyzeInstSliceStart(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) Inn
14701496 return mod.analyzeSlice(scope, inst.base.src, array_ptr, start, null, null);
14711497}
14721498
1473fn analyzeInstSwitchRange(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
1499fn zirSwitchRange(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
14741500 const tracy = trace(@src());
14751501 defer tracy.end();
14761502 const start = try resolveInst(mod, scope, inst.positionals.lhs);
......@@ -1494,7 +1520,7 @@ fn analyzeInstSwitchRange(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) In
14941520 return mod.constVoid(scope, inst.base.src);
14951521}
14961522
1497fn analyzeInstSwitchBr(mod: *Module, scope: *Scope, inst: *zir.Inst.SwitchBr) InnerError!*Inst {
1523fn zirSwitchbr(mod: *Module, scope: *Scope, inst: *zir.Inst.SwitchBr) InnerError!*Inst {
14981524 const tracy = trace(@src());
14991525 defer tracy.end();
15001526 const target_ptr = try resolveInst(mod, scope, inst.positionals.target_ptr);
......@@ -1698,7 +1724,7 @@ fn validateSwitch(mod: *Module, scope: *Scope, target: *Inst, inst: *zir.Inst.Sw
16981724 }
16991725}
17001726
1701fn analyzeInstImport(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
1727fn zirImport(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
17021728 const tracy = trace(@src());
17031729 defer tracy.end();
17041730 const operand = try resolveConstString(mod, scope, inst.positionals.operand);
......@@ -1718,19 +1744,19 @@ fn analyzeInstImport(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerErr
17181744 return mod.constType(scope, inst.base.src, file_scope.root_container.ty);
17191745}
17201746
1721fn analyzeInstShl(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
1747fn zirShl(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
17221748 const tracy = trace(@src());
17231749 defer tracy.end();
1724 return mod.fail(scope, inst.base.src, "TODO implement analyzeInstShl", .{});
1750 return mod.fail(scope, inst.base.src, "TODO implement zirShl", .{});
17251751}
17261752
1727fn analyzeInstShr(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
1753fn zirShr(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
17281754 const tracy = trace(@src());
17291755 defer tracy.end();
1730 return mod.fail(scope, inst.base.src, "TODO implement analyzeInstShr", .{});
1756 return mod.fail(scope, inst.base.src, "TODO implement zirShr", .{});
17311757}
17321758
1733fn analyzeInstBitwise(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
1759fn zirBitwise(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
17341760 const tracy = trace(@src());
17351761 defer tracy.end();
17361762
......@@ -1784,8 +1810,8 @@ fn analyzeInstBitwise(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerE
17841810
17851811 const b = try mod.requireRuntimeBlock(scope, inst.base.src);
17861812 const ir_tag = switch (inst.base.tag) {
1787 .bitand => Inst.Tag.bitand,
1788 .bitor => Inst.Tag.bitor,
1813 .bit_and => Inst.Tag.bit_and,
1814 .bit_or => Inst.Tag.bit_or,
17891815 .xor => Inst.Tag.xor,
17901816 else => unreachable,
17911817 };
......@@ -1793,25 +1819,25 @@ fn analyzeInstBitwise(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerE
17931819 return mod.addBinOp(b, inst.base.src, scalar_type, ir_tag, casted_lhs, casted_rhs);
17941820}
17951821
1796fn analyzeInstBitNot(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
1822fn zirBitNot(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
17971823 const tracy = trace(@src());
17981824 defer tracy.end();
1799 return mod.fail(scope, inst.base.src, "TODO implement analyzeInstBitNot", .{});
1825 return mod.fail(scope, inst.base.src, "TODO implement zirBitNot", .{});
18001826}
18011827
1802fn analyzeInstArrayCat(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
1828fn zirArrayCat(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
18031829 const tracy = trace(@src());
18041830 defer tracy.end();
1805 return mod.fail(scope, inst.base.src, "TODO implement analyzeInstArrayCat", .{});
1831 return mod.fail(scope, inst.base.src, "TODO implement zirArrayCat", .{});
18061832}
18071833
1808fn analyzeInstArrayMul(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
1834fn zirArrayMul(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
18091835 const tracy = trace(@src());
18101836 defer tracy.end();
1811 return mod.fail(scope, inst.base.src, "TODO implement analyzeInstArrayMul", .{});
1837 return mod.fail(scope, inst.base.src, "TODO implement zirArrayMul", .{});
18121838}
18131839
1814fn analyzeInstArithmetic(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
1840fn zirArithmetic(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
18151841 const tracy = trace(@src());
18161842 defer tracy.end();
18171843
......@@ -1912,14 +1938,14 @@ fn analyzeInstComptimeOp(mod: *Module, scope: *Scope, res_type: Type, inst: *zir
19121938 });
19131939}
19141940
1915fn analyzeInstDeref(mod: *Module, scope: *Scope, deref: *zir.Inst.UnOp) InnerError!*Inst {
1941fn zirDeref(mod: *Module, scope: *Scope, deref: *zir.Inst.UnOp) InnerError!*Inst {
19161942 const tracy = trace(@src());
19171943 defer tracy.end();
19181944 const ptr = try resolveInst(mod, scope, deref.positionals.operand);
19191945 return mod.analyzeDeref(scope, deref.base.src, ptr, deref.positionals.operand.src);
19201946}
19211947
1922fn analyzeInstAsm(mod: *Module, scope: *Scope, assembly: *zir.Inst.Asm) InnerError!*Inst {
1948fn zirAsm(mod: *Module, scope: *Scope, assembly: *zir.Inst.Asm) InnerError!*Inst {
19231949 const tracy = trace(@src());
19241950 defer tracy.end();
19251951 const return_type = try resolveType(mod, scope, assembly.positionals.return_type);
......@@ -1960,7 +1986,7 @@ fn analyzeInstAsm(mod: *Module, scope: *Scope, assembly: *zir.Inst.Asm) InnerErr
19601986 return &inst.base;
19611987}
19621988
1963fn analyzeInstCmp(
1989fn zirCmp(
19641990 mod: *Module,
19651991 scope: *Scope,
19661992 inst: *zir.Inst.BinOp,
......@@ -2018,14 +2044,14 @@ fn analyzeInstCmp(
20182044 return mod.fail(scope, inst.base.src, "TODO implement more cmp analysis", .{});
20192045}
20202046
2021fn analyzeInstTypeOf(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
2047fn zirTypeof(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
20222048 const tracy = trace(@src());
20232049 defer tracy.end();
20242050 const operand = try resolveInst(mod, scope, inst.positionals.operand);
20252051 return mod.constType(scope, inst.base.src, operand.ty);
20262052}
20272053
2028fn analyzeInstTypeOfPeer(mod: *Module, scope: *Scope, inst: *zir.Inst.TypeOfPeer) InnerError!*Inst {
2054fn zirTypeofPeer(mod: *Module, scope: *Scope, inst: *zir.Inst.TypeOfPeer) InnerError!*Inst {
20292055 const tracy = trace(@src());
20302056 defer tracy.end();
20312057 var insts_to_res = try mod.gpa.alloc(*ir.Inst, inst.positionals.items.len);
......@@ -2037,7 +2063,7 @@ fn analyzeInstTypeOfPeer(mod: *Module, scope: *Scope, inst: *zir.Inst.TypeOfPeer
20372063 return mod.constType(scope, inst.base.src, pt_res);
20382064}
20392065
2040fn analyzeInstBoolNot(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
2066fn zirBoolNot(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
20412067 const tracy = trace(@src());
20422068 defer tracy.end();
20432069 const uncasted_operand = try resolveInst(mod, scope, inst.positionals.operand);
......@@ -2050,7 +2076,7 @@ fn analyzeInstBoolNot(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerEr
20502076 return mod.addUnOp(b, inst.base.src, bool_type, .not, operand);
20512077}
20522078
2053fn analyzeInstBoolOp(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
2079fn zirBoolOp(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
20542080 const tracy = trace(@src());
20552081 defer tracy.end();
20562082 const bool_type = Type.initTag(.bool);
......@@ -2059,7 +2085,7 @@ fn analyzeInstBoolOp(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerEr
20592085 const uncasted_rhs = try resolveInst(mod, scope, inst.positionals.rhs);
20602086 const rhs = try mod.coerce(scope, bool_type, uncasted_rhs);
20612087
2062 const is_bool_or = inst.base.tag == .boolor;
2088 const is_bool_or = inst.base.tag == .bool_or;
20632089
20642090 if (lhs.value()) |lhs_val| {
20652091 if (rhs.value()) |rhs_val| {
......@@ -2071,17 +2097,17 @@ fn analyzeInstBoolOp(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerEr
20712097 }
20722098 }
20732099 const b = try mod.requireRuntimeBlock(scope, inst.base.src);
2074 return mod.addBinOp(b, inst.base.src, bool_type, if (is_bool_or) .boolor else .booland, lhs, rhs);
2100 return mod.addBinOp(b, inst.base.src, bool_type, if (is_bool_or) .bool_or else .bool_and, lhs, rhs);
20752101}
20762102
2077fn isNull(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, invert_logic: bool) InnerError!*Inst {
2103fn zirIsNull(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, invert_logic: bool) InnerError!*Inst {
20782104 const tracy = trace(@src());
20792105 defer tracy.end();
20802106 const operand = try resolveInst(mod, scope, inst.positionals.operand);
20812107 return mod.analyzeIsNull(scope, inst.base.src, operand, invert_logic);
20822108}
20832109
2084fn isNullPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, invert_logic: bool) InnerError!*Inst {
2110fn zirIsNullPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, invert_logic: bool) InnerError!*Inst {
20852111 const tracy = trace(@src());
20862112 defer tracy.end();
20872113 const ptr = try resolveInst(mod, scope, inst.positionals.operand);
......@@ -2089,14 +2115,14 @@ fn isNullPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, invert_logic: bo
20892115 return mod.analyzeIsNull(scope, inst.base.src, loaded, invert_logic);
20902116}
20912117
2092fn isErr(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
2118fn zirIsErr(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
20932119 const tracy = trace(@src());
20942120 defer tracy.end();
20952121 const operand = try resolveInst(mod, scope, inst.positionals.operand);
20962122 return mod.analyzeIsErr(scope, inst.base.src, operand);
20972123}
20982124
2099fn isErrPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
2125fn zirIsErrPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
21002126 const tracy = trace(@src());
21012127 defer tracy.end();
21022128 const ptr = try resolveInst(mod, scope, inst.positionals.operand);
......@@ -2104,7 +2130,7 @@ fn isErrPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst
21042130 return mod.analyzeIsErr(scope, inst.base.src, loaded);
21052131}
21062132
2107fn analyzeInstCondBr(mod: *Module, scope: *Scope, inst: *zir.Inst.CondBr) InnerError!*Inst {
2133fn zirCondbr(mod: *Module, scope: *Scope, inst: *zir.Inst.CondBr) InnerError!*Inst {
21082134 const tracy = trace(@src());
21092135 defer tracy.end();
21102136 const uncasted_cond = try resolveInst(mod, scope, inst.positionals.condition);
......@@ -2153,7 +2179,7 @@ fn analyzeInstCondBr(mod: *Module, scope: *Scope, inst: *zir.Inst.CondBr) InnerE
21532179 return mod.addCondBr(parent_block, inst.base.src, cond, then_body, else_body);
21542180}
21552181
2156fn analyzeInstUnreachable(
2182fn zirUnreachable(
21572183 mod: *Module,
21582184 scope: *Scope,
21592185 unreach: *zir.Inst.NoOp,
......@@ -2170,7 +2196,7 @@ fn analyzeInstUnreachable(
21702196 }
21712197}
21722198
2173fn analyzeInstRet(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
2199fn zirReturn(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
21742200 const tracy = trace(@src());
21752201 defer tracy.end();
21762202 const operand = try resolveInst(mod, scope, inst.positionals.operand);
......@@ -2185,7 +2211,7 @@ fn analyzeInstRet(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!
21852211 return mod.addUnOp(b, inst.base.src, Type.initTag(.noreturn), .ret, operand);
21862212}
21872213
2188fn analyzeInstRetVoid(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
2214fn zirReturnVoid(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
21892215 const tracy = trace(@src());
21902216 defer tracy.end();
21912217 const b = try mod.requireFunctionBlock(scope, inst.base.src);
......@@ -2216,27 +2242,7 @@ fn floatOpAllowed(tag: zir.Inst.Tag) bool {
22162242 };
22172243}
22182244
2219fn analyzeBreak(
2220 mod: *Module,
2221 scope: *Scope,
2222 src: usize,
2223 zir_block: *zir.Inst.Block,
2224 operand: *Inst,
2225) InnerError!*Inst {
2226 var opt_block = scope.cast(Scope.Block);
2227 while (opt_block) |block| {
2228 if (block.label) |*label| {
2229 if (label.zir_block == zir_block) {
2230 try label.merges.results.append(mod.gpa, operand);
2231 const b = try mod.requireFunctionBlock(scope, src);
2232 return mod.addBr(b, src, label.merges.block_inst, operand);
2233 }
2234 }
2235 opt_block = block.parent;
2236 } else unreachable;
2237}
2238
2239fn analyzeInstSimplePtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, mutable: bool, size: std.builtin.TypeInfo.Pointer.Size) InnerError!*Inst {
2245fn zirSimplePtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, mutable: bool, size: std.builtin.TypeInfo.Pointer.Size) InnerError!*Inst {
22402246 const tracy = trace(@src());
22412247 defer tracy.end();
22422248 const elem_type = try resolveType(mod, scope, inst.positionals.operand);
......@@ -2244,7 +2250,7 @@ fn analyzeInstSimplePtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, m
22442250 return mod.constType(scope, inst.base.src, ty);
22452251}
22462252
2247fn analyzeInstPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.PtrType) InnerError!*Inst {
2253fn zirPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.PtrType) InnerError!*Inst {
22482254 const tracy = trace(@src());
22492255 defer tracy.end();
22502256 // TODO lazy values