authorgravatar for matthew.h.borkowski@gmail.comMatthew Borkowski <matthew.h.borkowski@gmail.com> 2021-10-01 09:13:04-04:00
committergravatar for matthew.h.borkowski@gmail.comMatthew Borkowski <matthew.h.borkowski@gmail.com> 2021-10-02 08:20:43-04:00
logc64b885c829e38ed6033290cda916f6c9ffdab81
tree71788457aba3afba646e15993ed4d97b6f46d4f2
parenta3842cbafd25c29dd46954acda6cd7e3dfd18243

astgen.zig: have defer scopes cache source cursor to reduce redundant scanning during genDefers


1 files changed, 37 insertions(+), 7 deletions(-)

src/AstGen.zig+37-7
......@@ -1683,7 +1683,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
16831683 const defer_scope = scope.cast(Scope.Defer).?;
16841684 scope = defer_scope.parent;
16851685 const expr_node = node_datas[defer_scope.defer_node].rhs;
1686 _ = try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);
1686 try unusedResultDeferExpr(parent_gz, defer_scope, defer_scope.parent, expr_node);
16871687 },
16881688 .defer_error => scope = scope.cast(Scope.Defer).?.parent,
16891689 .top => unreachable,
......@@ -1736,7 +1736,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index)
17361736 const defer_scope = scope.cast(Scope.Defer).?;
17371737 scope = defer_scope.parent;
17381738 const expr_node = node_datas[defer_scope.defer_node].rhs;
1739 _ = try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);
1739 try unusedResultDeferExpr(parent_gz, defer_scope, defer_scope.parent, expr_node);
17401740 },
17411741 .defer_error => scope = scope.cast(Scope.Defer).?.parent,
17421742 .namespace => break,
......@@ -1922,8 +1922,8 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
19221922 .simple_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.simpleVarDecl(statement)),
19231923 .aligned_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.alignedVarDecl(statement)),
19241924
1925 .@"defer" => scope = try makeDeferScope(scope, statement, &block_arena.allocator, .defer_normal),
1926 .@"errdefer" => scope = try makeDeferScope(scope, statement, &block_arena.allocator, .defer_error),
1925 .@"defer" => scope = try makeDeferScope(gz.astgen, scope, statement, &block_arena.allocator, .defer_normal),
1926 .@"errdefer" => scope = try makeDeferScope(gz.astgen, scope, statement, &block_arena.allocator, .defer_error),
19271927
19281928 .assign => try assign(gz, scope, statement),
19291929
......@@ -1951,6 +1951,22 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
19511951 try checkUsed(gz, parent_scope, scope);
19521952}
19531953
1954fn unusedResultDeferExpr(gz: *GenZir, defer_scope: *Scope.Defer, expr_scope: *Scope, expr_node: Ast.Node.Index) InnerError!void {
1955 const astgen = gz.astgen;
1956 const prev_offset = astgen.source_offset;
1957 const prev_line = astgen.source_line;
1958 const prev_column = astgen.source_column;
1959 defer {
1960 astgen.source_offset = prev_offset;
1961 astgen.source_line = prev_line;
1962 astgen.source_column = prev_column;
1963 }
1964 astgen.source_offset = defer_scope.source_offset;
1965 astgen.source_line = defer_scope.source_line;
1966 astgen.source_column = defer_scope.source_column;
1967 _ = try unusedResultExpr(gz, expr_scope, expr_node);
1968}
1969
19541970/// Returns AST source node of the thing that is noreturn if the statement is definitely `noreturn`.
19551971/// Otherwise returns 0.
19561972fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) InnerError!Ast.Node.Index {
......@@ -2333,7 +2349,7 @@ fn genDefers(
23332349 const prev_in_defer = gz.in_defer;
23342350 gz.in_defer = true;
23352351 defer gz.in_defer = prev_in_defer;
2336 _ = try unusedResultExpr(gz, defer_scope.parent, expr_node);
2352 try unusedResultDeferExpr(gz, defer_scope, defer_scope.parent, expr_node);
23372353 },
23382354 .defer_error => {
23392355 const defer_scope = scope.cast(Scope.Defer).?;
......@@ -2344,7 +2360,7 @@ fn genDefers(
23442360 const prev_in_defer = gz.in_defer;
23452361 gz.in_defer = true;
23462362 defer gz.in_defer = prev_in_defer;
2347 _ = try unusedResultExpr(gz, defer_scope.parent, expr_node);
2363 try unusedResultDeferExpr(gz, defer_scope, defer_scope.parent, expr_node);
23482364 },
23492365 .both => |err_code| {
23502366 const expr_node = node_datas[defer_scope.defer_node].rhs;
......@@ -2365,7 +2381,7 @@ fn genDefers(
23652381 };
23662382 break :blk &local_val_scope.base;
23672383 };
2368 _ = try unusedResultExpr(gz, sub_scope, expr_node);
2384 try unusedResultDeferExpr(gz, defer_scope, sub_scope, expr_node);
23692385 },
23702386 .normal_only => continue,
23712387 }
......@@ -2409,16 +2425,27 @@ fn checkUsed(
24092425}
24102426
24112427fn makeDeferScope(
2428 astgen: *AstGen,
24122429 scope: *Scope,
24132430 node: Ast.Node.Index,
24142431 block_arena: *Allocator,
24152432 scope_tag: Scope.Tag,
24162433) InnerError!*Scope {
2434 const tree = astgen.tree;
2435 const node_datas = tree.nodes.items(.data);
2436 const expr_node = node_datas[node].rhs;
2437 const token_starts = tree.tokens.items(.start);
2438 const node_start = token_starts[tree.firstToken(expr_node)];
24172439 const defer_scope = try block_arena.create(Scope.Defer);
2440 astgen.advanceSourceCursor(tree.source, node_start);
2441
24182442 defer_scope.* = .{
24192443 .base = .{ .tag = scope_tag },
24202444 .parent = scope,
24212445 .defer_node = node,
2446 .source_offset = astgen.source_offset,
2447 .source_line = astgen.source_line,
2448 .source_column = astgen.source_column,
24222449 };
24232450 return &defer_scope.base;
24242451}
......@@ -9245,6 +9272,9 @@ const Scope = struct {
92459272 /// Parents can be: `LocalVal`, `LocalPtr`, `GenZir`, `Defer`, `Namespace`.
92469273 parent: *Scope,
92479274 defer_node: Ast.Node.Index,
9275 source_offset: u32,
9276 source_line: u32,
9277 source_column: u32,
92489278 };
92499279
92509280 /// Represents a global scope that has any number of declarations in it.