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:...@@ -17,6 +17,7 @@ Merge TODO list:
1717
1818
19Performance optimizations to look into:19Performance optimizations to look into:
20 * astgen: pass *GenZir as the first arg, not *Module
20 * don't store end index for blocks; rely on last instruction being noreturn21 * don't store end index for blocks; rely on last instruction being noreturn
21 * look into not storing the field name of field access as a string in zir22 * look into not storing the field name of field access as a string in zir
22 instructions. or, look into introducing interning to string_bytes (local23 instructions. or, look into introducing interning to string_bytes (local
src/Module.zig-4
...@@ -416,10 +416,6 @@ pub const Scope = struct {...@@ -416,10 +416,6 @@ pub const Scope = struct {
416 }416 }
417 }417 }
418418
419 pub fn isComptime(scope: *Scope) bool {
420 return scope.getGenZir().force_comptime;
421 }
422
423 pub fn ownerDecl(scope: *Scope) ?*Decl {419 pub fn ownerDecl(scope: *Scope) ?*Decl {
424 return switch (scope.tag) {420 return switch (scope.tag) {
425 .block => scope.cast(Block).?.sema.owner_decl,421 .block => scope.cast(Block).?.sema.owner_decl,
src/Sema.zig+7-5
...@@ -1133,7 +1133,6 @@ fn analyzeCall(...@@ -1133,7 +1133,6 @@ fn analyzeCall(
11331133
1134 const ret_type = func.ty.fnReturnType();1134 const ret_type = func.ty.fnReturnType();
11351135
1136 try sema.requireFunctionBlock(block, call_src);
1137 const is_comptime_call = block.is_comptime or modifier == .compile_time;1136 const is_comptime_call = block.is_comptime or modifier == .compile_time;
1138 const is_inline_call = is_comptime_call or modifier == .always_inline or1137 const is_inline_call = is_comptime_call or modifier == .always_inline or
1139 func.ty.fnCallingConvention() == .Inline;1138 func.ty.fnCallingConvention() == .Inline;
...@@ -1205,14 +1204,17 @@ fn analyzeCall(...@@ -1205,14 +1204,17 @@ fn analyzeCall(
1205 defer merges.results.deinit(sema.gpa);1204 defer merges.results.deinit(sema.gpa);
1206 defer merges.br_list.deinit(sema.gpa);1205 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
1210 // This will have return instructions analyzed as break instructions to1209 // This will have return instructions analyzed as break instructions to
1211 // the block_inst above.1210 // 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);1213 break :res try inline_sema.analyzeBlockBody(block, &child_block, merges);
1215 } else try block.addCall(call_src, ret_type, func, casted_args);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
1217 if (ensure_result_used) {1219 if (ensure_result_used) {
1218 try sema.ensureResultUsed(block, result, call_src);1220 try sema.ensureResultUsed(block, result, call_src);
src/astgen.zig+22-38
...@@ -672,34 +672,13 @@ pub fn comptimeExpr(...@@ -672,34 +672,13 @@ pub fn comptimeExpr(
672 rl: ResultLoc,672 rl: ResultLoc,
673 node: ast.Node.Index,673 node: ast.Node.Index,
674) InnerError!zir.Inst.Ref {674) 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
682 const gz = parent_scope.getGenZir();675 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;
703}682}
704683
705fn breakExpr(684fn breakExpr(
...@@ -928,7 +907,7 @@ fn labeledBlockExpr(...@@ -928,7 +907,7 @@ fn labeledBlockExpr(
928 var block_scope: Scope.GenZir = .{907 var block_scope: Scope.GenZir = .{
929 .parent = parent_scope,908 .parent = parent_scope,
930 .zir_code = gz.zir_code,909 .zir_code = gz.zir_code,
931 .force_comptime = parent_scope.isComptime(),910 .force_comptime = gz.force_comptime,
932 .instructions = .{},911 .instructions = .{},
933 // TODO @as here is working around a stage1 miscompilation bug :(912 // TODO @as here is working around a stage1 miscompilation bug :(
934 .label = @as(?Scope.GenZir.Label, Scope.GenZir.Label{913 .label = @as(?Scope.GenZir.Label, Scope.GenZir.Label{
...@@ -1296,7 +1275,7 @@ fn varDecl(...@@ -1296,7 +1275,7 @@ fn varDecl(
1296 // result location pointer.1275 // result location pointer.
1297 var init_scope: Scope.GenZir = .{1276 var init_scope: Scope.GenZir = .{
1298 .parent = scope,1277 .parent = scope,
1299 .force_comptime = scope.isComptime(),1278 .force_comptime = gz.force_comptime,
1300 .zir_code = gz.zir_code,1279 .zir_code = gz.zir_code,
1301 };1280 };
1302 defer init_scope.instructions.deinit(mod.gpa);1281 defer init_scope.instructions.deinit(mod.gpa);
...@@ -1675,13 +1654,14 @@ fn orelseCatchExpr(...@@ -1675,13 +1654,14 @@ fn orelseCatchExpr(
1675) InnerError!zir.Inst.Ref {1654) InnerError!zir.Inst.Ref {
1676 if (true) @panic("TODO update for zir-memory-layout");1655 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
1680 var block_scope: Scope.GenZir = .{1660 var block_scope: Scope.GenZir = .{
1681 .parent = scope,1661 .parent = scope,
1682 .decl = scope.ownerDecl().?,1662 .decl = scope.ownerDecl().?,
1683 .arena = scope.arena(),1663 .arena = scope.arena(),
1684 .force_comptime = scope.isComptime(),1664 .force_comptime = gz.force_comptime,
1685 .instructions = .{},1665 .instructions = .{},
1686 };1666 };
1687 setBlockResultLoc(&block_scope, rl);1667 setBlockResultLoc(&block_scope, rl);
...@@ -2019,7 +1999,7 @@ fn ifExpr(...@@ -2019,7 +1999,7 @@ fn ifExpr(
2019 var block_scope: Scope.GenZir = .{1999 var block_scope: Scope.GenZir = .{
2020 .parent = scope,2000 .parent = scope,
2021 .zir_code = parent_gz.zir_code,2001 .zir_code = parent_gz.zir_code,
2022 .force_comptime = scope.isComptime(),2002 .force_comptime = parent_gz.force_comptime,
2023 .instructions = .{},2003 .instructions = .{},
2024 };2004 };
2025 setBlockResultLoc(&block_scope, rl);2005 setBlockResultLoc(&block_scope, rl);
...@@ -2169,11 +2149,13 @@ fn whileExpr(...@@ -2169,11 +2149,13 @@ fn whileExpr(
2169 return mod.failTok(scope, inline_token, "TODO inline while", .{});2149 return mod.failTok(scope, inline_token, "TODO inline while", .{});
2170 }2150 }
21712151
2152 const parent_gz = scope.getGenZir();
2153
2172 var loop_scope: Scope.GenZir = .{2154 var loop_scope: Scope.GenZir = .{
2173 .parent = scope,2155 .parent = scope,
2174 .decl = scope.ownerDecl().?,2156 .decl = scope.ownerDecl().?,
2175 .arena = scope.arena(),2157 .arena = scope.arena(),
2176 .force_comptime = scope.isComptime(),2158 .force_comptime = parent_gz.force_comptime,
2177 .instructions = .{},2159 .instructions = .{},
2178 };2160 };
2179 setBlockResultLoc(&loop_scope, rl);2161 setBlockResultLoc(&loop_scope, rl);
...@@ -2188,7 +2170,7 @@ fn whileExpr(...@@ -2188,7 +2170,7 @@ fn whileExpr(
2188 };2170 };
2189 defer continue_scope.instructions.deinit(mod.gpa);2171 defer continue_scope.instructions.deinit(mod.gpa);
21902172
2191 const tree = scope.tree();2173 const tree = gz.tree();
2192 const main_tokens = tree.nodes.items(.main_token);2174 const main_tokens = tree.nodes.items(.main_token);
21932175
2194 const while_src = token_starts[while_full.ast.while_token];2176 const while_src = token_starts[while_full.ast.while_token];
...@@ -2328,7 +2310,8 @@ fn forExpr(...@@ -2328,7 +2310,8 @@ fn forExpr(
2328 }2310 }
23292311
2330 // Set up variables and constants.2312 // Set up variables and constants.
2331 const tree = scope.tree();2313 const parent_gz = scope.getGenZir();
2314 const tree = parent_gz.tree();
2332 const main_tokens = tree.nodes.items(.main_token);2315 const main_tokens = tree.nodes.items(.main_token);
2333 const token_tags = tree.tokens.items(.tag);2316 const token_tags = tree.tokens.items(.tag);
23342317
...@@ -2355,7 +2338,7 @@ fn forExpr(...@@ -2355,7 +2338,7 @@ fn forExpr(
2355 .parent = scope,2338 .parent = scope,
2356 .decl = scope.ownerDecl().?,2339 .decl = scope.ownerDecl().?,
2357 .arena = scope.arena(),2340 .arena = scope.arena(),
2358 .force_comptime = scope.isComptime(),2341 .force_comptime = parent_gz.force_comptime,
2359 .instructions = .{},2342 .instructions = .{},
2360 };2343 };
2361 setBlockResultLoc(&loop_scope, rl);2344 setBlockResultLoc(&loop_scope, rl);
...@@ -2531,7 +2514,8 @@ fn switchExpr(...@@ -2531,7 +2514,8 @@ fn switchExpr(
2531 switch_node: ast.Node.Index,2514 switch_node: ast.Node.Index,
2532) InnerError!zir.Inst.Ref {2515) InnerError!zir.Inst.Ref {
2533 if (true) @panic("TODO update for zir-memory-layout");2516 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();
2535 const node_datas = tree.nodes.items(.data);2519 const node_datas = tree.nodes.items(.data);
2536 const main_tokens = tree.nodes.items(.main_token);2520 const main_tokens = tree.nodes.items(.main_token);
2537 const token_tags = tree.tokens.items(.tag);2521 const token_tags = tree.tokens.items(.tag);
...@@ -2548,7 +2532,7 @@ fn switchExpr(...@@ -2548,7 +2532,7 @@ fn switchExpr(
2548 .parent = scope,2532 .parent = scope,
2549 .decl = scope.ownerDecl().?,2533 .decl = scope.ownerDecl().?,
2550 .arena = scope.arena(),2534 .arena = scope.arena(),
2551 .force_comptime = scope.isComptime(),2535 .force_comptime = parent_gz.force_comptime,
2552 .instructions = .{},2536 .instructions = .{},
2553 };2537 };
2554 setBlockResultLoc(&block_scope, rl);2538 setBlockResultLoc(&block_scope, rl);
...@@ -3196,7 +3180,7 @@ fn asRlPtr(...@@ -3196,7 +3180,7 @@ fn asRlPtr(
3196 var as_scope: Scope.GenZir = .{3180 var as_scope: Scope.GenZir = .{
3197 .parent = scope,3181 .parent = scope,
3198 .zir_code = parent_gz.zir_code,3182 .zir_code = parent_gz.zir_code,
3199 .force_comptime = scope.isComptime(),3183 .force_comptime = parent_gz.force_comptime,
3200 .instructions = .{},3184 .instructions = .{},
3201 };3185 };
3202 defer as_scope.instructions.deinit(mod.gpa);3186 defer as_scope.instructions.deinit(mod.gpa);