Skip to content

Commit c4fd61c

Browse files
authored
v: adjust some checks, based on branch prediction analysis (#22848)
1 parent 561efd1 commit c4fd61c

File tree

8 files changed

+117
-124
lines changed

8 files changed

+117
-124
lines changed

vlib/v/ast/scope.v

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,9 @@ pub fn (mut s Scope) register_struct_field(name string, field ScopeStructField)
158158
}
159159

160160
pub fn (mut s Scope) register(obj ScopeObject) {
161-
if obj.name == '_' || obj.name in s.objects {
162-
return
161+
if !(obj.name == '_' || obj.name in s.objects) {
162+
s.objects[obj.name] = obj
163163
}
164-
s.objects[obj.name] = obj
165164
}
166165

167166
// returns the innermost scope containing pos

vlib/v/checker/assign.v

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
307307
for left is ast.ParExpr {
308308
left = (left as ast.ParExpr).expr
309309
}
310+
is_assign := node.op in [.assign, .decl_assign]
310311
match mut left {
311312
ast.Ident {
312313
if (is_decl || left.kind == .blank_ident) && left_type.is_ptr()
@@ -326,7 +327,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
326327
}
327328
left_type = right_type
328329
node.left_types[i] = right_type
329-
if node.op !in [.assign, .decl_assign] {
330+
if !is_assign {
330331
c.error('cannot modify blank `_` identifier', left.pos)
331332
}
332333
} else if left.info !is ast.IdentVar {
@@ -601,18 +602,8 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
601602
}
602603
}
603604
}
604-
if left_sym.kind == .array_fixed && !c.inside_unsafe && node.op in [.assign, .decl_assign]
605-
&& right_sym.kind == .array_fixed && left is ast.Ident && !left.is_blank_ident()
606-
&& right is ast.Ident {
607-
if right_sym.info is ast.ArrayFixed {
608-
if right_sym.info.elem_type.is_ptr() {
609-
c.error('assignment from one fixed array to another with a pointer element type is prohibited outside of `unsafe`',
610-
node.pos)
611-
}
612-
}
613-
}
614-
if left_sym.kind == .map && node.op in [.assign, .decl_assign] && right_sym.kind == .map
615-
&& !left.is_blank_ident() && right.is_lvalue() && right !is ast.ComptimeSelector
605+
if left_sym.kind == .map && is_assign && right_sym.kind == .map && !left.is_blank_ident()
606+
&& right.is_lvalue() && right !is ast.ComptimeSelector
616607
&& (!right_type.is_ptr() || (right is ast.Ident && right.is_auto_deref_var())) {
617608
// Do not allow `a = b`
618609
c.error('cannot copy map: call `move` or `clone` method (or use a reference)',
@@ -628,6 +619,16 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
628619
c.error('cannot assign `${right}` as a generic function variable', right.pos())
629620
}
630621
}
622+
if left_sym.kind == .array_fixed && !c.inside_unsafe && is_assign
623+
&& right_sym.kind == .array_fixed && left is ast.Ident && !left.is_blank_ident()
624+
&& right is ast.Ident {
625+
if right_sym.info is ast.ArrayFixed {
626+
if right_sym.info.elem_type.is_ptr() {
627+
c.error('assignment from one fixed array to another with a pointer element type is prohibited outside of `unsafe`',
628+
node.pos)
629+
}
630+
}
631+
}
631632
if left_type.is_any_kind_of_pointer() && !left.is_auto_deref_var() {
632633
if !c.inside_unsafe && node.op !in [.assign, .decl_assign] {
633634
// ptr op=

vlib/v/checker/checker.v

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2748,10 +2748,8 @@ fn (mut c Checker) stmts_ending_with_expression(mut stmts []ast.Stmt, expected_o
27482748
c.stmt_level++
27492749
for i, mut stmt in stmts {
27502750
c.is_last_stmt = i == stmts.len - 1
2751-
if c.scope_returns {
2752-
if unreachable.line_nr == -1 {
2753-
unreachable = stmt.pos
2754-
}
2751+
if c.scope_returns && unreachable.line_nr == -1 {
2752+
unreachable = stmt.pos
27552753
}
27562754
prev_expected_or_type := c.expected_or_type
27572755
c.expected_or_type = expected_or_type

vlib/v/gen/c/cgen.v

Lines changed: 62 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2169,31 +2169,26 @@ fn (mut g Gen) stmt(node ast.Stmt) {
21692169
g.set_current_pos_as_last_stmt_pos()
21702170
}
21712171
match node {
2172-
ast.AsmStmt {
2173-
g.write_v_source_line_info_stmt(node)
2174-
g.asm_stmt(node)
2175-
}
2176-
ast.AssertStmt {
2177-
g.write_v_source_line_info_stmt(node)
2178-
g.assert_stmt(node)
2179-
}
2180-
ast.AssignStmt {
2181-
g.write_v_source_line_info_stmt(node)
2182-
g.assign_stmt(node)
2172+
ast.FnDecl {
2173+
g.fn_decl(node)
21832174
}
21842175
ast.Block {
21852176
g.write_v_source_line_info_stmt(node)
2186-
if node.is_unsafe {
2187-
g.writeln('{ // Unsafe block')
2188-
} else {
2177+
if !node.is_unsafe {
21892178
g.writeln('{')
2179+
} else {
2180+
g.writeln('{ // Unsafe block')
21902181
}
21912182
g.stmts(node.stmts)
21922183
g.writeln('}')
21932184
}
2194-
ast.BranchStmt {
2185+
ast.AssignStmt {
21952186
g.write_v_source_line_info_stmt(node)
2196-
g.branch_stmt(node)
2187+
g.assign_stmt(node)
2188+
}
2189+
ast.AssertStmt {
2190+
g.write_v_source_line_info_stmt(node)
2191+
g.assert_stmt(node)
21972192
}
21982193
ast.ConstDecl {
21992194
g.write_v_source_line_info_stmt(node)
@@ -2202,18 +2197,9 @@ fn (mut g Gen) stmt(node ast.Stmt) {
22022197
ast.ComptimeFor {
22032198
g.comptime_for(node)
22042199
}
2205-
ast.DebuggerStmt {
2206-
g.debugger_stmt(node)
2207-
}
2208-
ast.DeferStmt {
2209-
mut defer_stmt := node
2210-
defer_stmt.ifdef = g.defer_ifdef
2211-
g.writeln('${g.defer_flag_var(defer_stmt)} = true;')
2212-
g.defer_stmts << defer_stmt
2213-
}
2214-
ast.EmptyStmt {}
2215-
ast.EnumDecl {
2216-
g.enum_decl(node)
2200+
ast.BranchStmt {
2201+
g.write_v_source_line_info_stmt(node)
2202+
g.branch_stmt(node)
22172203
}
22182204
ast.ExprStmt {
22192205
g.write_v_source_line_info_stmt(node)
@@ -2246,9 +2232,6 @@ fn (mut g Gen) stmt(node ast.Stmt) {
22462232
}
22472233
}
22482234
}
2249-
ast.FnDecl {
2250-
g.fn_decl(node)
2251-
}
22522235
ast.ForCStmt {
22532236
prev_branch_parent_pos := g.branch_parent_pos
22542237
g.branch_parent_pos = node.pos.pos
@@ -2297,18 +2280,20 @@ fn (mut g Gen) stmt(node ast.Stmt) {
22972280
g.labeled_loops.delete(node.label)
22982281
g.inner_loop = save_inner_loop
22992282
}
2300-
ast.GlobalDecl {
2301-
g.global_decl(node)
2283+
ast.Return {
2284+
g.return_stmt(node)
23022285
}
2303-
ast.GotoLabel {
2304-
g.writeln('${c_name(node.name)}: {}')
2286+
ast.DeferStmt {
2287+
mut defer_stmt := node
2288+
defer_stmt.ifdef = g.defer_ifdef
2289+
g.writeln('${g.defer_flag_var(defer_stmt)} = true;')
2290+
g.defer_stmts << defer_stmt
23052291
}
2306-
ast.GotoStmt {
2307-
g.write_v_source_line_info_stmt(node)
2308-
g.writeln('goto ${c_name(node.name)};')
2292+
ast.EnumDecl {
2293+
g.enum_decl(node)
23092294
}
2310-
ast.HashStmt {
2311-
g.hash_stmt(node)
2295+
ast.GlobalDecl {
2296+
g.global_decl(node)
23122297
}
23132298
ast.Import {}
23142299
ast.InterfaceDecl {
@@ -2327,20 +2312,6 @@ fn (mut g Gen) stmt(node ast.Stmt) {
23272312
}
23282313
}
23292314
}
2330-
ast.Module {
2331-
g.is_builtin_mod = util.module_is_builtin(node.name)
2332-
g.cur_mod = node
2333-
}
2334-
ast.NodeError {}
2335-
ast.Return {
2336-
g.return_stmt(node)
2337-
}
2338-
ast.SemicolonStmt {
2339-
g.writeln(';')
2340-
}
2341-
ast.SqlStmt {
2342-
g.sql_stmt(node)
2343-
}
23442315
ast.StructDecl {
23452316
name := if node.language == .c {
23462317
util.no_dots(node.name)
@@ -2369,11 +2340,40 @@ fn (mut g Gen) stmt(node ast.Stmt) {
23692340
g.typedefs.writeln('typedef struct ${name} ${name};')
23702341
}
23712342
}
2343+
ast.GotoLabel {
2344+
g.writeln('${c_name(node.name)}: {}')
2345+
}
2346+
ast.GotoStmt {
2347+
g.write_v_source_line_info_stmt(node)
2348+
g.writeln('goto ${c_name(node.name)};')
2349+
}
2350+
ast.AsmStmt {
2351+
g.write_v_source_line_info_stmt(node)
2352+
g.asm_stmt(node)
2353+
}
2354+
ast.HashStmt {
2355+
g.hash_stmt(node)
2356+
}
23722357
ast.TypeDecl {
23732358
if !g.pref.skip_unused {
23742359
g.writeln('// TypeDecl')
23752360
}
23762361
}
2362+
ast.SemicolonStmt {
2363+
g.writeln(';')
2364+
}
2365+
ast.SqlStmt {
2366+
g.sql_stmt(node)
2367+
}
2368+
ast.Module {
2369+
g.is_builtin_mod = util.module_is_builtin(node.name)
2370+
g.cur_mod = node
2371+
}
2372+
ast.EmptyStmt {}
2373+
ast.DebuggerStmt {
2374+
g.debugger_stmt(node)
2375+
}
2376+
ast.NodeError {}
23772377
}
23782378
if !g.skip_stmt_pos { // && g.stmt_path_pos.len > 0 {
23792379
g.stmt_path_pos.delete_last()
@@ -3555,7 +3555,11 @@ fn (mut g Gen) expr(node_ ast.Expr) {
35553555
g.ident(node)
35563556
}
35573557
ast.IfExpr {
3558-
g.if_expr(node)
3558+
if !node.is_comptime {
3559+
g.if_expr(node)
3560+
} else {
3561+
g.comptime_if(node)
3562+
}
35593563
}
35603564
ast.IfGuardExpr {
35613565
g.write('/* guard */')
@@ -3564,12 +3568,12 @@ fn (mut g Gen) expr(node_ ast.Expr) {
35643568
g.index_expr(node)
35653569
}
35663570
ast.InfixExpr {
3567-
if node.op in [.left_shift, .plus_assign, .minus_assign] {
3568-
g.inside_map_infix = true
3571+
if node.op !in [.left_shift, .plus_assign, .minus_assign] {
35693572
g.infix_expr(node)
3570-
g.inside_map_infix = false
35713573
} else {
3574+
g.inside_map_infix = true
35723575
g.infix_expr(node)
3576+
g.inside_map_infix = false
35733577
}
35743578
}
35753579
ast.IntegerLiteral {

vlib/v/gen/c/if.v

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,6 @@ fn (mut g Gen) needs_conds_order(node ast.IfExpr) bool {
176176
}
177177

178178
fn (mut g Gen) if_expr(node ast.IfExpr) {
179-
if node.is_comptime {
180-
g.comptime_if(node)
181-
return
182-
}
183179
// For simple if expressions we can use C's `?:`
184180
// `if x > 0 { 1 } else { 2 }` => `(x > 0)? (1) : (2)`
185181
// For if expressions with multiple statements or another if expression inside, it's much

0 commit comments

Comments
 (0)