authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-23 13:25:58-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-23 13:25:58-07:00
logaf73f79490aa9b998bfe1e3a6f9353742289f1bd
tree5ee799e1fa451477743733a848618480937f20ce
parent866be099f8a16389e83ba4f5d8b3122b14b09e77

stage2: fix comptimeExpr and comptime function calls


4 files changed, 30 insertions(+), 47 deletions(-)

BRANCH_TODO+1
......@@ -17,6 +17,7 @@ Merge TODO list:
1717
1818
1919Performance optimizations to look into:
20 * astgen: pass *GenZir as the first arg, not *Module
2021 * don't store end index for blocks; rely on last instruction being noreturn
2122 * look into not storing the field name of field access as a string in zir
2223 instructions. or, look into introducing interning to string_bytes (local
src/Module.zig-4
......@@ -416,10 +416,6 @@ pub const Scope = struct {
416416 }
417417 }
418418
419 pub fn isComptime(scope: *Scope) bool {
420 return scope.getGenZir().force_comptime;
421 }
422
423419 pub fn ownerDecl(scope: *Scope) ?*Decl {
424420 return switch (scope.tag) {
425421 .block => scope.cast(Block).?.sema.owner_decl,
src/Sema.zig+7-5
......@@ -1133,7 +1133,6 @@ fn analyzeCall(
11331133
11341134 const ret_type = func.ty.fnReturnType();
11351135
1136 try sema.requireFunctionBlock(block, call_src);
11371136 const is_comptime_call = block.is_comptime or modifier == .compile_time;
11381137 const is_inline_call = is_comptime_call or modifier == .always_inline or
11391138 func.ty.fnCallingConvention() == .Inline;
......@@ -1205,14 +1204,17 @@ fn analyzeCall(
12051204 defer merges.results.deinit(sema.gpa);
12061205 defer merges.br_list.deinit(sema.gpa);
12071206
1208 try sema.emitBackwardBranch(&child_block, call_src);
1207 try inline_sema.emitBackwardBranch(&child_block, call_src);
12091208
12101209 // This will have return instructions analyzed as break instructions to
12111210 // the block_inst above.
1212 _ = try sema.root(&child_block);
1211 _ = try inline_sema.root(&child_block);
12131212
1214 break :res try sema.analyzeBlockBody(block, &child_block, merges);
1215 } else try block.addCall(call_src, ret_type, func, casted_args);
1213 break :res try inline_sema.analyzeBlockBody(block, &child_block, merges);
1214 } else res: {
1215 try sema.requireRuntimeBlock(block, call_src);
1216 break :res try block.addCall(call_src, ret_type, func, casted_args);
1217 };
12161218
12171219 if (ensure_result_used) {
12181220 try sema.ensureResultUsed(block, result, call_src);
src/astgen.zig+22-38
......@@ -672,34 +672,13 @@ pub fn comptimeExpr(
672672 rl: ResultLoc,
673673 node: ast.Node.Index,
674674) InnerError!zir.Inst.Ref {
675 if (true) @panic("TODO update for zir-memory-layout branch");
676
677 // If we are already in a comptime scope, no need to make another one.
678 if (parent_scope.isComptime()) {
679 return expr(mod, parent_scope, rl, node);
680 }
681
682675 const gz = parent_scope.getGenZir();
683 const tree = parent_scope.tree();
684
685 // Make a scope to collect generated instructions in the sub-expression.
686 var block_scope: Scope.GenZir = .{
687 .parent = parent_scope,
688 .zir_code = gz.zir_code,
689 .force_comptime = true,
690 .instructions = .{},
691 };
692 defer block_scope.instructions.deinit(mod.gpa);
693
694 // No need to capture the result here because block_comptime_flat implies that the final
695 // instruction is the block's result value.
696 _ = try expr(mod, &block_scope.base, rl, node);
697
698 const block = try addZIRInstBlock(mod, parent_scope, src, .block_comptime_flat, .{
699 .instructions = try block_scope.arena.dupe(zir.Inst.Ref, block_scope.instructions.items),
700 });
701676
702 return &block.base;
677 const prev_force_comptime = gz.force_comptime;
678 gz.force_comptime = true;
679 const result = try expr(mod, parent_scope, rl, node);
680 gz.force_comptime = prev_force_comptime;
681 return result;
703682}
704683
705684fn breakExpr(
......@@ -928,7 +907,7 @@ fn labeledBlockExpr(
928907 var block_scope: Scope.GenZir = .{
929908 .parent = parent_scope,
930909 .zir_code = gz.zir_code,
931 .force_comptime = parent_scope.isComptime(),
910 .force_comptime = gz.force_comptime,
932911 .instructions = .{},
933912 // TODO @as here is working around a stage1 miscompilation bug :(
934913 .label = @as(?Scope.GenZir.Label, Scope.GenZir.Label{
......@@ -1296,7 +1275,7 @@ fn varDecl(
12961275 // result location pointer.
12971276 var init_scope: Scope.GenZir = .{
12981277 .parent = scope,
1299 .force_comptime = scope.isComptime(),
1278 .force_comptime = gz.force_comptime,
13001279 .zir_code = gz.zir_code,
13011280 };
13021281 defer init_scope.instructions.deinit(mod.gpa);
......@@ -1675,13 +1654,14 @@ fn orelseCatchExpr(
16751654) InnerError!zir.Inst.Ref {
16761655 if (true) @panic("TODO update for zir-memory-layout");
16771656
1678 const tree = scope.tree();
1657 const gz = scope.getGenZir();
1658 const tree = gz.tree();
16791659
16801660 var block_scope: Scope.GenZir = .{
16811661 .parent = scope,
16821662 .decl = scope.ownerDecl().?,
16831663 .arena = scope.arena(),
1684 .force_comptime = scope.isComptime(),
1664 .force_comptime = gz.force_comptime,
16851665 .instructions = .{},
16861666 };
16871667 setBlockResultLoc(&block_scope, rl);
......@@ -2019,7 +1999,7 @@ fn ifExpr(
20191999 var block_scope: Scope.GenZir = .{
20202000 .parent = scope,
20212001 .zir_code = parent_gz.zir_code,
2022 .force_comptime = scope.isComptime(),
2002 .force_comptime = parent_gz.force_comptime,
20232003 .instructions = .{},
20242004 };
20252005 setBlockResultLoc(&block_scope, rl);
......@@ -2169,11 +2149,13 @@ fn whileExpr(
21692149 return mod.failTok(scope, inline_token, "TODO inline while", .{});
21702150 }
21712151
2152 const parent_gz = scope.getGenZir();
2153
21722154 var loop_scope: Scope.GenZir = .{
21732155 .parent = scope,
21742156 .decl = scope.ownerDecl().?,
21752157 .arena = scope.arena(),
2176 .force_comptime = scope.isComptime(),
2158 .force_comptime = parent_gz.force_comptime,
21772159 .instructions = .{},
21782160 };
21792161 setBlockResultLoc(&loop_scope, rl);
......@@ -2188,7 +2170,7 @@ fn whileExpr(
21882170 };
21892171 defer continue_scope.instructions.deinit(mod.gpa);
21902172
2191 const tree = scope.tree();
2173 const tree = gz.tree();
21922174 const main_tokens = tree.nodes.items(.main_token);
21932175
21942176 const while_src = token_starts[while_full.ast.while_token];
......@@ -2328,7 +2310,8 @@ fn forExpr(
23282310 }
23292311
23302312 // Set up variables and constants.
2331 const tree = scope.tree();
2313 const parent_gz = scope.getGenZir();
2314 const tree = parent_gz.tree();
23322315 const main_tokens = tree.nodes.items(.main_token);
23332316 const token_tags = tree.tokens.items(.tag);
23342317
......@@ -2355,7 +2338,7 @@ fn forExpr(
23552338 .parent = scope,
23562339 .decl = scope.ownerDecl().?,
23572340 .arena = scope.arena(),
2358 .force_comptime = scope.isComptime(),
2341 .force_comptime = parent_gz.force_comptime,
23592342 .instructions = .{},
23602343 };
23612344 setBlockResultLoc(&loop_scope, rl);
......@@ -2531,7 +2514,8 @@ fn switchExpr(
25312514 switch_node: ast.Node.Index,
25322515) InnerError!zir.Inst.Ref {
25332516 if (true) @panic("TODO update for zir-memory-layout");
2534 const tree = scope.tree();
2517 const parent_gz = scope.getGenZir();
2518 const tree = parent_gz.tree();
25352519 const node_datas = tree.nodes.items(.data);
25362520 const main_tokens = tree.nodes.items(.main_token);
25372521 const token_tags = tree.tokens.items(.tag);
......@@ -2548,7 +2532,7 @@ fn switchExpr(
25482532 .parent = scope,
25492533 .decl = scope.ownerDecl().?,
25502534 .arena = scope.arena(),
2551 .force_comptime = scope.isComptime(),
2535 .force_comptime = parent_gz.force_comptime,
25522536 .instructions = .{},
25532537 };
25542538 setBlockResultLoc(&block_scope, rl);
......@@ -3196,7 +3180,7 @@ fn asRlPtr(
31963180 var as_scope: Scope.GenZir = .{
31973181 .parent = scope,
31983182 .zir_code = parent_gz.zir_code,
3199 .force_comptime = scope.isComptime(),
3183 .force_comptime = parent_gz.force_comptime,
32003184 .instructions = .{},
32013185 };
32023186 defer as_scope.instructions.deinit(mod.gpa);