authorgravatar for matthew.h.borkowski@gmail.comMatthew Borkowski <matthew.h.borkowski@gmail.com> 2021-10-31 21:29:33-04:00
committergravatar for matthew.h.borkowski@gmail.comMatthew Borkowski <matthew.h.borkowski@gmail.com> 2021-11-01 05:09:19-04:00
log2561be2e34ecdbdb11b9de7790089d844739eaea
tree576644ece4e56b877345512c8ce9339442647c17
parent83dcfd62053a80024b1cb282fddf399a36c9c58e

astgen.zig: avoid temporary allocations in arrayInit* and structInit*, callExpr, errorSetDecl, typeOf, and builtinCall's compile_log branch


1 files changed, 162 insertions(+), 147 deletions(-)

src/AstGen.zig+162-147
...@@ -53,16 +53,30 @@ fn addExtra(astgen: *AstGen, extra: anytype) Allocator.Error!u32 {...@@ -53,16 +53,30 @@ fn addExtra(astgen: *AstGen, extra: anytype) Allocator.Error!u32 {
53fn addExtraAssumeCapacity(astgen: *AstGen, extra: anytype) u32 {53fn addExtraAssumeCapacity(astgen: *AstGen, extra: anytype) u32 {
54 const fields = std.meta.fields(@TypeOf(extra));54 const fields = std.meta.fields(@TypeOf(extra));
55 const result = @intCast(u32, astgen.extra.items.len);55 const result = @intCast(u32, astgen.extra.items.len);
56 astgen.extra.items.len += fields.len;
57 setExtra(astgen, result, extra);
58 return result;
59}
60
61fn setExtra(astgen: *AstGen, index: usize, extra: anytype) void {
62 const fields = std.meta.fields(@TypeOf(extra));
63 var i = index;
56 inline for (fields) |field| {64 inline for (fields) |field| {
57 astgen.extra.appendAssumeCapacity(switch (field.field_type) {65 astgen.extra.items[i] = switch (field.field_type) {
58 u32 => @field(extra, field.name),66 u32 => @field(extra, field.name),
59 Zir.Inst.Ref => @enumToInt(@field(extra, field.name)),67 Zir.Inst.Ref => @enumToInt(@field(extra, field.name)),
60 i32 => @bitCast(u32, @field(extra, field.name)),68 i32 => @bitCast(u32, @field(extra, field.name)),
61 Zir.Inst.Call.Flags => @bitCast(u32, @field(extra, field.name)),69 Zir.Inst.Call.Flags => @bitCast(u32, @field(extra, field.name)),
62 Zir.Inst.SwitchBlock.Bits => @bitCast(u32, @field(extra, field.name)),70 Zir.Inst.SwitchBlock.Bits => @bitCast(u32, @field(extra, field.name)),
63 else => @compileError("bad field type"),71 else => @compileError("bad field type"),
64 });72 };
73 i += 1;
65 }74 }
75}
76
77fn reserveExtra(astgen: *AstGen, size: usize) Allocator.Error!u32 {
78 const result = @intCast(u32, astgen.extra.items.len);
79 try astgen.extra.resize(astgen.gpa, result + size);
66 return result;80 return result;
67}81}
6882
...@@ -1307,18 +1321,18 @@ fn arrayInitExprRlNone(...@@ -1307,18 +1321,18 @@ fn arrayInitExprRlNone(
1307 tag: Zir.Inst.Tag,1321 tag: Zir.Inst.Tag,
1308) InnerError!Zir.Inst.Ref {1322) InnerError!Zir.Inst.Ref {
1309 const astgen = gz.astgen;1323 const astgen = gz.astgen;
1310 const gpa = astgen.gpa;
1311 const elem_list = try gpa.alloc(Zir.Inst.Ref, elements.len);
1312 defer gpa.free(elem_list);
13131324
1314 for (elements) |elem_init, i| {1325 const payload_index = try addExtra(astgen, Zir.Inst.MultiOp{
1315 elem_list[i] = try expr(gz, scope, .none, elem_init);1326 .operands_len = @intCast(u32, elements.len),
1316 }
1317 const init_inst = try gz.addPlNode(tag, node, Zir.Inst.MultiOp{
1318 .operands_len = @intCast(u32, elem_list.len),
1319 });1327 });
1320 try astgen.appendRefs(elem_list);1328 var extra_index = try reserveExtra(astgen, elements.len);
1321 return init_inst;1329
1330 for (elements) |elem_init| {
1331 const elem_ref = try expr(gz, scope, .none, elem_init);
1332 astgen.extra.items[extra_index] = @enumToInt(elem_ref);
1333 extra_index += 1;
1334 }
1335 return try gz.addPlNodePayloadIndex(tag, node, payload_index);
1322}1336}
13231337
1324fn arrayInitExprRlTy(1338fn arrayInitExprRlTy(
...@@ -1330,21 +1344,19 @@ fn arrayInitExprRlTy(...@@ -1330,21 +1344,19 @@ fn arrayInitExprRlTy(
1330 tag: Zir.Inst.Tag,1344 tag: Zir.Inst.Tag,
1331) InnerError!Zir.Inst.Ref {1345) InnerError!Zir.Inst.Ref {
1332 const astgen = gz.astgen;1346 const astgen = gz.astgen;
1333 const gpa = astgen.gpa;
13341347
1335 const elem_list = try gpa.alloc(Zir.Inst.Ref, elements.len);1348 const payload_index = try addExtra(astgen, Zir.Inst.MultiOp{
1336 defer gpa.free(elem_list);1349 .operands_len = @intCast(u32, elements.len),
1350 });
1351 var extra_index = try reserveExtra(astgen, elements.len);
13371352
1338 const elem_rl: ResultLoc = .{ .ty = elem_ty_inst };1353 const elem_rl: ResultLoc = .{ .ty = elem_ty_inst };
13391354 for (elements) |elem_init| {
1340 for (elements) |elem_init, i| {1355 const elem_ref = try expr(gz, scope, elem_rl, elem_init);
1341 elem_list[i] = try expr(gz, scope, elem_rl, elem_init);1356 astgen.extra.items[extra_index] = @enumToInt(elem_ref);
1357 extra_index += 1;
1342 }1358 }
1343 const init_inst = try gz.addPlNode(tag, node, Zir.Inst.MultiOp{1359 return try gz.addPlNodePayloadIndex(tag, node, payload_index);
1344 .operands_len = @intCast(u32, elem_list.len),
1345 });
1346 try astgen.appendRefs(elem_list);
1347 return init_inst;
1348}1360}
13491361
1350fn arrayInitExprRlPtr(1362fn arrayInitExprRlPtr(
...@@ -1375,23 +1387,22 @@ fn arrayInitExprRlPtrInner(...@@ -1375,23 +1387,22 @@ fn arrayInitExprRlPtrInner(
1375 elements: []const Ast.Node.Index,1387 elements: []const Ast.Node.Index,
1376) InnerError!Zir.Inst.Ref {1388) InnerError!Zir.Inst.Ref {
1377 const astgen = gz.astgen;1389 const astgen = gz.astgen;
1378 const gpa = astgen.gpa;
13791390
1380 const elem_ptr_list = try gpa.alloc(Zir.Inst.Index, elements.len);1391 const payload_index = try addExtra(astgen, Zir.Inst.Block{
1381 defer gpa.free(elem_ptr_list);1392 .body_len = @intCast(u32, elements.len),
1393 });
1394 var extra_index = try reserveExtra(astgen, elements.len);
13821395
1383 for (elements) |elem_init, i| {1396 for (elements) |elem_init, i| {
1384 const elem_ptr = try gz.addPlNode(.elem_ptr_imm, elem_init, Zir.Inst.ElemPtrImm{1397 const elem_ptr = try gz.addPlNode(.elem_ptr_imm, elem_init, Zir.Inst.ElemPtrImm{
1385 .ptr = result_ptr,1398 .ptr = result_ptr,
1386 .index = @intCast(u32, i),1399 .index = @intCast(u32, i),
1387 });1400 });
1388 elem_ptr_list[i] = refToIndex(elem_ptr).?;1401 astgen.extra.items[extra_index] = refToIndex(elem_ptr).?;
1402 extra_index += 1;
1389 _ = try expr(gz, scope, .{ .ptr = elem_ptr }, elem_init);1403 _ = try expr(gz, scope, .{ .ptr = elem_ptr }, elem_init);
1390 }1404 }
1391 _ = try gz.addPlNode(.validate_array_init, node, Zir.Inst.Block{1405 _ = try gz.addPlNodePayloadIndex(.validate_array_init, node, payload_index);
1392 .body_len = @intCast(u32, elem_ptr_list.len),
1393 });
1394 try astgen.extra.appendSlice(gpa, elem_ptr_list);
1395 return .void_value;1406 return .void_value;
1396}1407}
13971408
...@@ -1505,30 +1516,25 @@ fn structInitExprRlNone(...@@ -1505,30 +1516,25 @@ fn structInitExprRlNone(
1505 tag: Zir.Inst.Tag,1516 tag: Zir.Inst.Tag,
1506) InnerError!Zir.Inst.Ref {1517) InnerError!Zir.Inst.Ref {
1507 const astgen = gz.astgen;1518 const astgen = gz.astgen;
1508 const gpa = astgen.gpa;
1509 const tree = astgen.tree;1519 const tree = astgen.tree;
15101520
1511 const fields_list = try gpa.alloc(Zir.Inst.StructInitAnon.Item, struct_init.ast.fields.len);1521 const payload_index = try addExtra(astgen, Zir.Inst.StructInitAnon{
1512 defer gpa.free(fields_list);1522 .fields_len = @intCast(u32, struct_init.ast.fields.len),
1523 });
1524 const field_size = @typeInfo(Zir.Inst.StructInitAnon.Item).Struct.fields.len;
1525 var extra_index: usize = try reserveExtra(astgen, struct_init.ast.fields.len * field_size);
15131526
1514 for (struct_init.ast.fields) |field_init, i| {1527 for (struct_init.ast.fields) |field_init| {
1515 const name_token = tree.firstToken(field_init) - 2;1528 const name_token = tree.firstToken(field_init) - 2;
1516 const str_index = try astgen.identAsString(name_token);1529 const str_index = try astgen.identAsString(name_token);
15171530 setExtra(astgen, extra_index, Zir.Inst.StructInitAnon.Item{
1518 fields_list[i] = .{
1519 .field_name = str_index,1531 .field_name = str_index,
1520 .init = try expr(gz, scope, .none, field_init),1532 .init = try expr(gz, scope, .none, field_init),
1521 };1533 });
1522 }1534 extra_index += field_size;
1523 const init_inst = try gz.addPlNode(tag, node, Zir.Inst.StructInitAnon{
1524 .fields_len = @intCast(u32, fields_list.len),
1525 });
1526 try astgen.extra.ensureUnusedCapacity(gpa, fields_list.len *
1527 @typeInfo(Zir.Inst.StructInitAnon.Item).Struct.fields.len);
1528 for (fields_list) |field| {
1529 _ = gz.astgen.addExtraAssumeCapacity(field);
1530 }1535 }
1531 return init_inst;1536
1537 return try gz.addPlNodePayloadIndex(tag, node, payload_index);
1532}1538}
15331539
1534fn structInitExprRlPtr(1540fn structInitExprRlPtr(
...@@ -1559,26 +1565,26 @@ fn structInitExprRlPtrInner(...@@ -1559,26 +1565,26 @@ fn structInitExprRlPtrInner(
1559 result_ptr: Zir.Inst.Ref,1565 result_ptr: Zir.Inst.Ref,
1560) InnerError!Zir.Inst.Ref {1566) InnerError!Zir.Inst.Ref {
1561 const astgen = gz.astgen;1567 const astgen = gz.astgen;
1562 const gpa = astgen.gpa;
1563 const tree = astgen.tree;1568 const tree = astgen.tree;
15641569
1565 const field_ptr_list = try gpa.alloc(Zir.Inst.Index, struct_init.ast.fields.len);1570 const payload_index = try addExtra(astgen, Zir.Inst.Block{
1566 defer gpa.free(field_ptr_list);1571 .body_len = @intCast(u32, struct_init.ast.fields.len),
1572 });
1573 var extra_index = try reserveExtra(astgen, struct_init.ast.fields.len);
15671574
1568 for (struct_init.ast.fields) |field_init, i| {1575 for (struct_init.ast.fields) |field_init| {
1569 const name_token = tree.firstToken(field_init) - 2;1576 const name_token = tree.firstToken(field_init) - 2;
1570 const str_index = try astgen.identAsString(name_token);1577 const str_index = try astgen.identAsString(name_token);
1571 const field_ptr = try gz.addPlNode(.field_ptr, field_init, Zir.Inst.Field{1578 const field_ptr = try gz.addPlNode(.field_ptr, field_init, Zir.Inst.Field{
1572 .lhs = result_ptr,1579 .lhs = result_ptr,
1573 .field_name_start = str_index,1580 .field_name_start = str_index,
1574 });1581 });
1575 field_ptr_list[i] = refToIndex(field_ptr).?;1582 astgen.extra.items[extra_index] = refToIndex(field_ptr).?;
1583 extra_index += 1;
1576 _ = try expr(gz, scope, .{ .ptr = field_ptr }, field_init);1584 _ = try expr(gz, scope, .{ .ptr = field_ptr }, field_init);
1577 }1585 }
1578 _ = try gz.addPlNode(.validate_struct_init, node, Zir.Inst.Block{1586
1579 .body_len = @intCast(u32, field_ptr_list.len),1587 _ = try gz.addPlNodePayloadIndex(.validate_struct_init, node, payload_index);
1580 });
1581 try astgen.extra.appendSlice(gpa, field_ptr_list);
1582 return Zir.Inst.Ref.void_value;1588 return Zir.Inst.Ref.void_value;
1583}1589}
15841590
...@@ -1591,34 +1597,29 @@ fn structInitExprRlTy(...@@ -1591,34 +1597,29 @@ fn structInitExprRlTy(
1591 tag: Zir.Inst.Tag,1597 tag: Zir.Inst.Tag,
1592) InnerError!Zir.Inst.Ref {1598) InnerError!Zir.Inst.Ref {
1593 const astgen = gz.astgen;1599 const astgen = gz.astgen;
1594 const gpa = astgen.gpa;
1595 const tree = astgen.tree;1600 const tree = astgen.tree;
15961601
1597 const fields_list = try gpa.alloc(Zir.Inst.StructInit.Item, struct_init.ast.fields.len);1602 const payload_index = try addExtra(astgen, Zir.Inst.StructInit{
1598 defer gpa.free(fields_list);1603 .fields_len = @intCast(u32, struct_init.ast.fields.len),
1604 });
1605 const field_size = @typeInfo(Zir.Inst.StructInit.Item).Struct.fields.len;
1606 var extra_index: usize = try reserveExtra(astgen, struct_init.ast.fields.len * field_size);
15991607
1600 for (struct_init.ast.fields) |field_init, i| {1608 for (struct_init.ast.fields) |field_init| {
1601 const name_token = tree.firstToken(field_init) - 2;1609 const name_token = tree.firstToken(field_init) - 2;
1602 const str_index = try astgen.identAsString(name_token);1610 const str_index = try astgen.identAsString(name_token);
1603
1604 const field_ty_inst = try gz.addPlNode(.field_type, field_init, Zir.Inst.FieldType{1611 const field_ty_inst = try gz.addPlNode(.field_type, field_init, Zir.Inst.FieldType{
1605 .container_type = ty_inst,1612 .container_type = ty_inst,
1606 .name_start = str_index,1613 .name_start = str_index,
1607 });1614 });
1608 fields_list[i] = .{1615 setExtra(astgen, extra_index, Zir.Inst.StructInit.Item{
1609 .field_type = refToIndex(field_ty_inst).?,1616 .field_type = refToIndex(field_ty_inst).?,
1610 .init = try expr(gz, scope, .{ .ty = field_ty_inst }, field_init),1617 .init = try expr(gz, scope, .{ .ty = field_ty_inst }, field_init),
1611 };1618 });
1612 }1619 extra_index += field_size;
1613 const init_inst = try gz.addPlNode(tag, node, Zir.Inst.StructInit{
1614 .fields_len = @intCast(u32, fields_list.len),
1615 });
1616 try astgen.extra.ensureUnusedCapacity(gpa, fields_list.len *
1617 @typeInfo(Zir.Inst.StructInit.Item).Struct.fields.len);
1618 for (fields_list) |field| {
1619 _ = gz.astgen.addExtraAssumeCapacity(field);
1620 }1620 }
1621 return init_inst;1621
1622 return try gz.addPlNodePayloadIndex(tag, node, payload_index);
1622}1623}
16231624
1624/// This calls expr in a comptime scope, and is intended to be called as a helper function.1625/// This calls expr in a comptime scope, and is intended to be called as a helper function.
...@@ -4851,20 +4852,18 @@ fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir...@@ -4851,20 +4852,18 @@ fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir
4851 const main_tokens = tree.nodes.items(.main_token);4852 const main_tokens = tree.nodes.items(.main_token);
4852 const token_tags = tree.tokens.items(.tag);4853 const token_tags = tree.tokens.items(.tag);
48534854
4854 var field_names: std.ArrayListUnmanaged(u32) = .{};4855 const payload_index = try reserveExtra(astgen, @typeInfo(Zir.Inst.ErrorSetDecl).Struct.fields.len);
4855 defer field_names.deinit(gpa);4856 var fields_len: usize = 0;
4856
4857 {4857 {
4858 const error_token = main_tokens[node];4858 const error_token = main_tokens[node];
4859 var tok_i = error_token + 2;4859 var tok_i = error_token + 2;
4860 var field_i: usize = 0;
4861 while (true) : (tok_i += 1) {4860 while (true) : (tok_i += 1) {
4862 switch (token_tags[tok_i]) {4861 switch (token_tags[tok_i]) {
4863 .doc_comment, .comma => {},4862 .doc_comment, .comma => {},
4864 .identifier => {4863 .identifier => {
4865 const str_index = try astgen.identAsString(tok_i);4864 const str_index = try astgen.identAsString(tok_i);
4866 try field_names.append(gpa, str_index);4865 try astgen.extra.append(gpa, str_index);
4867 field_i += 1;4866 fields_len += 1;
4868 },4867 },
4869 .r_brace => break,4868 .r_brace => break,
4870 else => unreachable,4869 else => unreachable,
...@@ -4872,10 +4871,10 @@ fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir...@@ -4872,10 +4871,10 @@ fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir
4872 }4871 }
4873 }4872 }
48744873
4875 const result = try gz.addPlNode(.error_set_decl, node, Zir.Inst.ErrorSetDecl{4874 setExtra(astgen, payload_index, Zir.Inst.ErrorSetDecl{
4876 .fields_len = @intCast(u32, field_names.items.len),4875 .fields_len = @intCast(u32, fields_len),
4877 });4876 });
4878 try astgen.extra.appendSlice(gpa, field_names.items);4877 const result = try gz.addPlNodePayloadIndex(.error_set_decl, node, payload_index);
4879 return rvalue(gz, rl, result, node);4878 return rvalue(gz, rl, result, node);
4880}4879}
48814880
...@@ -7196,13 +7195,18 @@ fn typeOf(...@@ -7196,13 +7195,18 @@ fn typeOf(
7196 const result = try gz.addUnNode(.typeof, expr_result, node);7195 const result = try gz.addUnNode(.typeof, expr_result, node);
7197 return rvalue(gz, rl, result, node);7196 return rvalue(gz, rl, result, node);
7198 }7197 }
7199 const arena = gz.astgen.arena;7198
7200 var items = try arena.alloc(Zir.Inst.Ref, params.len);7199 const payload_index = try addExtra(gz.astgen, Zir.Inst.NodeMultiOp{
7201 for (params) |param, param_i| {7200 .src_node = gz.nodeIndexToRelative(node),
7202 items[param_i] = try reachableExpr(gz, scope, .none, param, node);7201 });
7202 var extra_index = try reserveExtra(gz.astgen, params.len);
7203 for (params) |param| {
7204 const param_ref = try reachableExpr(gz, scope, .none, param, node);
7205 gz.astgen.extra.items[extra_index] = @enumToInt(param_ref);
7206 extra_index += 1;
7203 }7207 }
72047208
7205 const result = try gz.addExtendedMultiOp(.typeof_peer, node, items);7209 const result = try gz.addExtendedMultiOpPayloadIndex(.typeof_peer, payload_index, params.len);
7206 return rvalue(gz, rl, result, node);7210 return rvalue(gz, rl, result, node);
7207}7211}
72087212
...@@ -7259,12 +7263,16 @@ fn builtinCall(...@@ -7259,12 +7263,16 @@ fn builtinCall(
7259 return rvalue(gz, rl, result, node);7263 return rvalue(gz, rl, result, node);
7260 },7264 },
7261 .compile_log => {7265 .compile_log => {
7262 const arg_refs = try astgen.gpa.alloc(Zir.Inst.Ref, params.len);7266 const payload_index = try addExtra(gz.astgen, Zir.Inst.NodeMultiOp{
7263 defer astgen.gpa.free(arg_refs);7267 .src_node = gz.nodeIndexToRelative(node),
72647268 });
7265 for (params) |param, i| arg_refs[i] = try expr(gz, scope, .none, param);7269 var extra_index = try reserveExtra(gz.astgen, params.len);
72667270 for (params) |param| {
7267 const result = try gz.addExtendedMultiOp(.compile_log, node, arg_refs);7271 const param_ref = try expr(gz, scope, .none, param);
7272 astgen.extra.items[extra_index] = @enumToInt(param_ref);
7273 extra_index += 1;
7274 }
7275 const result = try gz.addExtendedMultiOpPayloadIndex(.compile_log,payload_index, params.len);
7268 return rvalue(gz, rl, result, node);7276 return rvalue(gz, rl, result, node);
7269 },7277 },
7270 .field => {7278 .field => {
...@@ -7974,22 +7982,6 @@ fn callExpr(...@@ -7974,22 +7982,6 @@ fn callExpr(
7974 const astgen = gz.astgen;7982 const astgen = gz.astgen;
79757983
7976 const callee = try calleeExpr(gz, scope, call.ast.fn_expr);7984 const callee = try calleeExpr(gz, scope, call.ast.fn_expr);
7977
7978 // A large proportion of calls have 5 or less arguments, due to this preventing allocations
7979 // for calls with few arguments has a sizeable effect on the aggregated runtime of this function
7980 var arg_buffer: [5]Zir.Inst.Ref = undefined;
7981 const args: []Zir.Inst.Ref = if (call.ast.params.len <= arg_buffer.len)
7982 arg_buffer[0..call.ast.params.len]
7983 else
7984 try astgen.gpa.alloc(Zir.Inst.Ref, call.ast.params.len);
7985 defer if (call.ast.params.len > arg_buffer.len) astgen.gpa.free(args);
7986
7987 for (call.ast.params) |param_node, i| {
7988 // Parameters are always temporary values, they have no
7989 // meaningful result location. Sema will coerce them.
7990 args[i] = try expr(gz, scope, .none, param_node);
7991 }
7992
7993 const modifier: std.builtin.CallOptions.Modifier = blk: {7985 const modifier: std.builtin.CallOptions.Modifier = blk: {
7994 if (gz.force_comptime) {7986 if (gz.force_comptime) {
7995 break :blk .compile_time;7987 break :blk .compile_time;
...@@ -8002,7 +7994,28 @@ fn callExpr(...@@ -8002,7 +7994,28 @@ fn callExpr(
8002 }7994 }
8003 break :blk .auto;7995 break :blk .auto;
8004 };7996 };
8005 const call_inst = try gz.addCall(modifier, callee, args, node);7997
7998 assert(callee != .none);
7999 assert(node != 0);
8000
8001 const payload_index = try addExtra(astgen, Zir.Inst.Call{
8002 .callee = callee,
8003 .flags = .{
8004 .packed_modifier = @intCast(Zir.Inst.Call.Flags.PackedModifier, @enumToInt(modifier)),
8005 .args_len = @intCast(Zir.Inst.Call.Flags.PackedArgsLen, call.ast.params.len),
8006 },
8007 });
8008 var extra_index = try reserveExtra(astgen, call.ast.params.len);
8009
8010 for (call.ast.params) |param_node| {
8011 // Parameters are always temporary values, they have no
8012 // meaningful result location. Sema will coerce them.
8013 const arg_ref = try expr(gz, scope, .none, param_node);
8014 astgen.extra.items[extra_index] = @enumToInt(arg_ref);
8015 extra_index += 1;
8016 }
8017
8018 const call_inst = try gz.addPlNodePayloadIndex(.call, node, payload_index);
8006 return rvalue(gz, rl, call_inst, node); // TODO function call with result location8019 return rvalue(gz, rl, call_inst, node); // TODO function call with result location
8007}8020}
80088021
...@@ -9765,44 +9778,6 @@ const GenZir = struct {...@@ -9765,44 +9778,6 @@ const GenZir = struct {
9765 return indexToRef(new_index);9778 return indexToRef(new_index);
9766 }9779 }
97679780
9768 fn addCall(
9769 gz: *GenZir,
9770 modifier: std.builtin.CallOptions.Modifier,
9771 callee: Zir.Inst.Ref,
9772 args: []const Zir.Inst.Ref,
9773 /// Absolute node index. This function does the conversion to offset from Decl.
9774 src_node: Ast.Node.Index,
9775 ) !Zir.Inst.Ref {
9776 assert(callee != .none);
9777 assert(src_node != 0);
9778 const gpa = gz.astgen.gpa;
9779 const Call = Zir.Inst.Call;
9780 try gz.instructions.ensureUnusedCapacity(gpa, 1);
9781 try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
9782 try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Call).Struct.fields.len +
9783 args.len);
9784
9785 const payload_index = gz.astgen.addExtraAssumeCapacity(Call{
9786 .callee = callee,
9787 .flags = .{
9788 .packed_modifier = @intCast(Call.Flags.PackedModifier, @enumToInt(modifier)),
9789 .args_len = @intCast(Call.Flags.PackedArgsLen, args.len),
9790 },
9791 });
9792 gz.astgen.appendRefsAssumeCapacity(args);
9793
9794 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
9795 gz.astgen.instructions.appendAssumeCapacity(.{
9796 .tag = .call,
9797 .data = .{ .pl_node = .{
9798 .src_node = gz.nodeIndexToRelative(src_node),
9799 .payload_index = payload_index,
9800 } },
9801 });
9802 gz.instructions.appendAssumeCapacity(new_index);
9803 return indexToRef(new_index);
9804 }
9805
9806 /// Note that this returns a `Zir.Inst.Index` not a ref.9781 /// Note that this returns a `Zir.Inst.Index` not a ref.
9807 /// Leaves the `payload_index` field undefined.9782 /// Leaves the `payload_index` field undefined.
9808 fn addBoolBr(9783 fn addBoolBr(
...@@ -9902,6 +9877,22 @@ const GenZir = struct {...@@ -9902,6 +9877,22 @@ const GenZir = struct {
9902 return indexToRef(new_index);9877 return indexToRef(new_index);
9903 }9878 }
99049879
9880 fn addPlNodePayloadIndex(
9881 gz: *GenZir,
9882 tag: Zir.Inst.Tag,
9883 /// Absolute node index. This function does the conversion to offset from Decl.
9884 src_node: Ast.Node.Index,
9885 payload_index: u32,
9886 ) !Zir.Inst.Ref {
9887 return try gz.add(.{
9888 .tag = tag,
9889 .data = .{ .pl_node = .{
9890 .src_node = gz.nodeIndexToRelative(src_node),
9891 .payload_index = payload_index,
9892 } },
9893 });
9894 }
9895
9905 fn addParam(9896 fn addParam(
9906 gz: *GenZir,9897 gz: *GenZir,
9907 tag: Zir.Inst.Tag,9898 tag: Zir.Inst.Tag,
...@@ -9991,6 +9982,30 @@ const GenZir = struct {...@@ -9991,6 +9982,30 @@ const GenZir = struct {
9991 return indexToRef(new_index);9982 return indexToRef(new_index);
9992 }9983 }
99939984
9985 fn addExtendedMultiOpPayloadIndex(
9986 gz: *GenZir,
9987 opcode: Zir.Inst.Extended,
9988 payload_index: u32,
9989 trailing_len: usize,
9990 ) !Zir.Inst.Ref {
9991 const astgen = gz.astgen;
9992 const gpa = astgen.gpa;
9993
9994 try gz.instructions.ensureUnusedCapacity(gpa, 1);
9995 try astgen.instructions.ensureUnusedCapacity(gpa, 1);
9996 const new_index = @intCast(Zir.Inst.Index, astgen.instructions.len);
9997 astgen.instructions.appendAssumeCapacity(.{
9998 .tag = .extended,
9999 .data = .{ .extended = .{
10000 .opcode = opcode,
10001 .small = @intCast(u16, trailing_len),
10002 .operand = payload_index,
10003 } },
10004 });
10005 gz.instructions.appendAssumeCapacity(new_index);
10006 return indexToRef(new_index);
10007 }
10008
9994 fn addUnTok(10009 fn addUnTok(
9995 gz: *GenZir,10010 gz: *GenZir,
9996 tag: Zir.Inst.Tag,10011 tag: Zir.Inst.Tag,