From a7c2aaf35b278c8fea79ae985b7b7df6dea6dd7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kr=C3=BCger?= <45282134+UweKrueger@users.noreply.github.com> Date: Fri, 30 Jul 2021 18:20:45 +0200 Subject: [PATCH] cgen: initialize globals directly for simple cases (#11002) --- vlib/v/ast/ast.v | 29 +++++++++++++++++++++++++++++ vlib/v/gen/c/cgen.v | 9 +++++++-- vlib/v/tests/init_global_test.v | 3 ++- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 1dd1883ad6..b2e1e3bf8a 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -1989,3 +1989,32 @@ fn gen_all_registers(mut t Table, without_numbers []string, with_numbers map[str } return res } + +// is `expr` a literal, i.e. it does not depend on any other declarations (C compile time constant) +pub fn (expr Expr) is_literal() bool { + match expr { + BoolLiteral, CharLiteral, FloatLiteral, IntegerLiteral { + return true + } + PrefixExpr { + return expr.right.is_literal() + } + InfixExpr { + return expr.left.is_literal() && expr.right.is_literal() + } + ParExpr { + return expr.expr.is_literal() + } + CastExpr { + return !expr.has_arg && expr.expr.is_literal() + && (expr.typ.is_ptr() || expr.typ.is_pointer() + || expr.typ in [i8_type, i16_type, int_type, i64_type, byte_type, u8_type, u16_type, u32_type, u64_type, f32_type, f64_type, char_type, bool_type, rune_type]) + } + SizeOf, IsRefType { + return expr.is_type || expr.expr.is_literal() + } + else { + return false + } + } +} diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 52b29a54da..1096dc8068 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5156,8 +5156,13 @@ fn (mut g Gen) global_decl(node ast.GlobalDecl) { } styp := g.typ(field.typ) if field.has_expr { - g.definitions.writeln('$mod$styp $field.name;') - g.global_inits[key].writeln('\t$field.name = ${g.expr_string(field.expr)}; // global') + g.definitions.write_string('$mod$styp $field.name') + if field.expr.is_literal() { + g.definitions.writeln(' = ${g.expr_string(field.expr)}; // global') + } else { + g.definitions.writeln(';') + g.global_inits[key].writeln('\t$field.name = ${g.expr_string(field.expr)}; // global') + } } else { default_initializer := g.type_default(field.typ) if default_initializer == '{0}' { diff --git a/vlib/v/tests/init_global_test.v b/vlib/v/tests/init_global_test.v index 227f0e3ff4..a6d47267ca 100644 --- a/vlib/v/tests/init_global_test.v +++ b/vlib/v/tests/init_global_test.v @@ -36,7 +36,7 @@ __global ( sem sync.Semaphore shmap shared map[string]f64 mtx sync.RwMutex - f1 = f64(34.0625) + f1 = f64(545 / (sizeof(f64) + f32(8))) // directly initialized f2 f64 ) @@ -116,6 +116,7 @@ fn switch2() u64 { } fn test_global_mutex() { + assert f1 == 34.0625 t := go switch2() for _ in 0 .. 2500000 { mtx.@lock()