From ec0402e63bb2993ad8eb13101b46563dc6946d5c Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sat, 15 Jul 2023 09:30:05 +0300 Subject: [PATCH 1/6] ast,cgen: small speedup for the 1m_statements_in_1_fn.v --- vlib/v/ast/types.v | 43 +++++++++++++++++++++++----------- vlib/v/gen/c/auto_eq_methods.v | 12 +++++----- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/vlib/v/ast/types.v b/vlib/v/ast/types.v index 7e00250f8e36d8..feba6900367f99 100644 --- a/vlib/v/ast/types.v +++ b/vlib/v/ast/types.v @@ -272,10 +272,12 @@ pub fn (t Type) atomic_typename() string { } } +[inline] pub fn sharetype_from_flags(is_shared bool, is_atomic bool) ShareType { return unsafe { ShareType(int(u32(is_atomic) << 1) | int(is_shared)) } } +[inline] pub fn (t Type) share() ShareType { return sharetype_from_flags(t.has_flag(.shared_f), t.has_flag(.atomic_f)) } @@ -283,7 +285,7 @@ pub fn (t Type) share() ShareType { // return TypeSymbol idx for `t` [inline] pub fn (t Type) idx() int { - return u16(t) & 0xffff + return int(t) & 0xffff } [inline] @@ -307,13 +309,14 @@ pub fn (t Type) nr_muls() int { pub fn (t Type) is_ptr() bool { // any normal pointer, i.e. &Type, &&Type etc; // Note: voidptr, charptr and byteptr are NOT included! - return (int(t) >> 16) & 0xff > 0 + return (int(t) >> 16) & 0xff != 0 } [inline] pub fn (typ Type) is_pointer() bool { // builtin pointer types (voidptr, byteptr, charptr) - return typ.idx() in ast.pointer_type_idxs + return typ.idx() in [ast.voidptr_type_idx, ast.byteptr_type_idx, ast.charptr_type_idx, + ast.nil_type_idx] } [inline] @@ -323,7 +326,8 @@ pub fn (typ Type) is_voidptr() bool { [inline] pub fn (t Type) is_any_kind_of_pointer() bool { - return (int(t) >> 16) & 0xff > 0 || (u16(t) & 0xffff) in ast.pointer_type_idxs + return (int(t) >> 16) & 0xff != 0 + || u16(t) in [ast.voidptr_type_idx, ast.byteptr_type_idx, ast.charptr_type_idx, ast.nil_type_idx] } // set nr_muls on `t` and return it @@ -384,7 +388,7 @@ pub fn (t Type) clear_flags(flags ...TypeFlag) Type { // return true if `flag` is set on `t` [inline] pub fn (t Type) has_flag(flag TypeFlag) bool { - return int(t) & (1 << (int(flag) + 24)) > 0 + return int(t) & (1 << (int(flag) + 24)) != 0 } // debug returns a verbose representation of the information in ts, useful for tracing/debugging @@ -484,42 +488,50 @@ pub fn new_type_ptr(idx int, nr_muls int) Type { [inline] pub fn (typ Type) is_float() bool { - return !typ.is_ptr() && typ.idx() in ast.float_type_idxs + return !typ.is_ptr() + && typ.idx() in [ast.f32_type_idx, ast.f64_type_idx, ast.float_literal_type_idx] } [inline] pub fn (typ Type) is_int() bool { - return !typ.is_ptr() && typ.idx() in ast.integer_type_idxs + return !typ.is_ptr() + && typ.idx() in [ast.i8_type_idx, ast.i16_type_idx, ast.int_type_idx, ast.i64_type_idx, ast.u8_type_idx, ast.u16_type_idx, ast.u32_type_idx, ast.u64_type_idx, ast.isize_type_idx, ast.usize_type_idx, ast.int_literal_type_idx, ast.rune_type_idx] } [inline] pub fn (typ Type) is_int_valptr() bool { - return typ.is_ptr() && typ.idx() in ast.integer_type_idxs + return typ.is_ptr() + && typ.idx() in [ast.i8_type_idx, ast.i16_type_idx, ast.int_type_idx, ast.i64_type_idx, ast.u8_type_idx, ast.u16_type_idx, ast.u32_type_idx, ast.u64_type_idx, ast.isize_type_idx, ast.usize_type_idx, ast.int_literal_type_idx, ast.rune_type_idx] } [inline] pub fn (typ Type) is_float_valptr() bool { - return typ.is_ptr() && typ.idx() in ast.float_type_idxs + return typ.is_ptr() + && typ.idx() in [ast.f32_type_idx, ast.f64_type_idx, ast.float_literal_type_idx] } [inline] pub fn (typ Type) is_pure_int() bool { - return int(typ) in ast.integer_type_idxs + return int(typ) in [ast.i8_type_idx, ast.i16_type_idx, ast.int_type_idx, ast.i64_type_idx, + ast.u8_type_idx, ast.u16_type_idx, ast.u32_type_idx, ast.u64_type_idx, ast.isize_type_idx, + ast.usize_type_idx, ast.int_literal_type_idx, ast.rune_type_idx] } [inline] pub fn (typ Type) is_pure_float() bool { - return int(typ) in ast.float_type_idxs + return int(typ) in [ast.f32_type_idx, ast.f64_type_idx, ast.float_literal_type_idx] } [inline] pub fn (typ Type) is_signed() bool { - return typ.idx() in ast.signed_integer_type_idxs + return typ.idx() in [ast.char_type_idx, ast.i8_type_idx, ast.i16_type_idx, ast.int_type_idx, + ast.i64_type_idx, ast.isize_type_idx] } [inline] pub fn (typ Type) is_unsigned() bool { - return typ.idx() in ast.unsigned_integer_type_idxs + return typ.idx() in [ast.u8_type_idx, ast.u16_type_idx, ast.u32_type_idx, ast.u64_type_idx, + ast.usize_type_idx] } pub fn (typ Type) flip_signedness() Type { @@ -545,7 +557,10 @@ pub fn (typ Type) is_int_literal() bool { [inline] pub fn (typ Type) is_number() bool { - return typ.clear_flags() in ast.number_type_idxs + return (int(typ) & 0xffffff) in [ast.i8_type_idx, ast.i16_type_idx, ast.int_type_idx, + ast.i64_type_idx, ast.u8_type_idx, ast.char_type_idx, ast.u16_type_idx, ast.u32_type_idx, + ast.u64_type_idx, ast.isize_type_idx, ast.usize_type_idx, ast.f32_type_idx, ast.f64_type_idx, + ast.int_literal_type_idx, ast.float_literal_type_idx, ast.rune_type_idx] } [inline] diff --git a/vlib/v/gen/c/auto_eq_methods.v b/vlib/v/gen/c/auto_eq_methods.v index bcb619eb115439..35d3fdc48379e7 100644 --- a/vlib/v/gen/c/auto_eq_methods.v +++ b/vlib/v/gen/c/auto_eq_methods.v @@ -225,10 +225,10 @@ fn (mut g Gen) gen_alias_equality_fn(left_type ast.Type) string { } g.generated_eq_fns << left_type info := left.sym.info as ast.Alias - g.definitions.writeln('static bool ${ptr_styp}_alias_eq(${ptr_styp} a, ${ptr_styp} b); // auto') + g.definitions.writeln('static inline bool ${ptr_styp}_alias_eq(${ptr_styp} a, ${ptr_styp} b); // auto') mut fn_builder := strings.new_builder(512) - fn_builder.writeln('static bool ${ptr_styp}_alias_eq(${ptr_styp} a, ${ptr_styp} b) {') + fn_builder.writeln('static inline bool ${ptr_styp}_alias_eq(${ptr_styp} a, ${ptr_styp} b) {') is_option := left.typ.has_flag(.option) @@ -283,10 +283,10 @@ fn (mut g Gen) gen_array_equality_fn(left_type ast.Type) string { g.generated_eq_fns << left_type elem := g.unwrap(left.sym.array_info().elem_type) ptr_elem_styp := g.typ(elem.typ) - g.definitions.writeln('static bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b); // auto') + g.definitions.writeln('static inline bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b); // auto') mut fn_builder := strings.new_builder(512) - fn_builder.writeln('static bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b) {') + fn_builder.writeln('static inline bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b) {') left_len := g.read_field(left_type, 'len', 'a') right_len := g.read_field(left_type, 'len', 'b') @@ -353,13 +353,13 @@ fn (mut g Gen) gen_fixed_array_equality_fn(left_type ast.Type) string { elem_info := left_typ.sym.array_fixed_info() elem := g.unwrap(elem_info.elem_type) size := elem_info.size - g.definitions.writeln('static bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b); // auto') + g.definitions.writeln('static inline bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b); // auto') left := if left_type.has_flag(.option) { 'a.data' } else { 'a' } right := if left_type.has_flag(.option) { 'b.data' } else { 'b' } mut fn_builder := strings.new_builder(512) - fn_builder.writeln('static bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b) {') + fn_builder.writeln('static inline bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b) {') fn_builder.writeln('\tfor (int i = 0; i < ${size}; ++i) {') // compare every pair of elements of the two fixed arrays if elem.sym.kind == .string { From 400dececc9a7d7bb9db140f1054ba55643af108f Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sat, 15 Jul 2023 17:15:43 +0300 Subject: [PATCH 2/6] implement missing builtin _noscan fns/methods for array and map, so that cgen can work more uniformly --- vlib/builtin/array_notd_gcboehm_opt.v | 74 +++++++++++++++++++++++++++ vlib/builtin/map_notd_gcboehm_opt.v | 43 ++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 vlib/builtin/map_notd_gcboehm_opt.v diff --git a/vlib/builtin/array_notd_gcboehm_opt.v b/vlib/builtin/array_notd_gcboehm_opt.v index 2e45e2b1e90506..13ba28f796a7b0 100644 --- a/vlib/builtin/array_notd_gcboehm_opt.v +++ b/vlib/builtin/array_notd_gcboehm_opt.v @@ -5,18 +5,92 @@ module builtin // this is needed in `string.v` +[inline] fn __new_array_noscan(mylen int, cap int, elm_size int) array { return __new_array(mylen, cap, elm_size) } +[inline] fn __new_array_with_default_noscan(mylen int, cap int, elm_size int, val voidptr) array { return __new_array_with_default(mylen, cap, elm_size, val) } +[inline] fn __new_array_with_multi_default_noscan(mylen int, cap int, elm_size int, val voidptr) array { return __new_array_with_multi_default(mylen, cap, elm_size, val) } +[inline] fn __new_array_with_array_default_noscan(mylen int, cap int, elm_size int, val array, depth int) array { return __new_array_with_array_default(mylen, cap, elm_size, val, depth) } + +[inline] +fn new_array_from_c_array_noscan(len int, cap int, elm_size int, c_array voidptr) array { + return new_array_from_c_array(len, cap, elm_size, c_array) +} + +[inline] +fn (a array) repeat_to_depth_noscan(count int, depth int) array { + return unsafe { a.repeat_to_depth(count, depth) } +} + +[inline] +fn (mut a array) insert_noscan(i int, val voidptr) { + a.insert(i, val) +} + +[inline] +fn (mut a array) insert_many_noscan(i int, val voidptr, size int) { + unsafe { a.insert_many(i, val, size) } +} + +[inline] +fn (mut a array) prepend_noscan(val voidptr) { + a.prepend_noscan(val) +} + +[inline] +fn (mut a array) prepend_many_noscan(val voidptr, size int) { + unsafe { a.prepend_many_noscan(val, size) } +} + +[inline] +fn (mut a array) pop_noscan() voidptr { + return a.pop() +} + +[inline] +fn (a array) clone_static_to_depth_noscan(depth int) array { + return unsafe { a.clone_static_to_depth(depth) } +} + +[inline] +fn (a &array) clone_to_depth_noscan(depth int) array { + return unsafe { a.clone_to_depth(depth) } +} + +[inline] +fn (mut a array) push_noscan(val voidptr) { + a.push(val) +} + +[inline] +fn (mut a array) push_many_noscan(val voidptr, size int) { + unsafe { a.push_many(val, size) } +} + +[inline] +fn (a array) reverse_noscan() array { + return a.reverse() +} + +[inline] +fn (mut a array) grow_cap_noscan(amount int) { + a.grow_cap(amount) +} + +[inline] +fn (mut a array) grow_len_noscan(amount int) { + unsafe { a.grow_len(amount) } +} diff --git a/vlib/builtin/map_notd_gcboehm_opt.v b/vlib/builtin/map_notd_gcboehm_opt.v new file mode 100644 index 00000000000000..00617e992bfb74 --- /dev/null +++ b/vlib/builtin/map_notd_gcboehm_opt.v @@ -0,0 +1,43 @@ +module builtin + +// Dummy placeholder for functions from map_d_gcboehm_opt.v +// These functions will be called by cgen, for maps that have keys and values +// of primitive types, that do not require GC scanning, like ints, bools etc. + +[inline] +fn new_dense_array_noscan(key_bytes int, key_noscan bool, value_bytes int, value_noscan bool) DenseArray { + return new_dense_array(key_bytes, value_bytes) +} + +[inline] +fn new_map_noscan_key(key_bytes int, value_bytes int, hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn) map { + return new_map(key_bytes, value_bytes, hash_fn, key_eq_fn, clone_fn, free_fn) +} + +[inline] +fn new_map_noscan_value(key_bytes int, value_bytes int, hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn) map { + return new_map(key_bytes, value_bytes, hash_fn, key_eq_fn, clone_fn, free_fn) +} + +[inline] +fn new_map_noscan_key_value(key_bytes int, value_bytes int, hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn) map { + return new_map(key_bytes, value_bytes, hash_fn, key_eq_fn, clone_fn, free_fn) +} + +[inline] +fn new_map_init_noscan_key(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn, n int, key_bytes int, value_bytes int, keys voidptr, values voidptr) map { + return new_map_init(hash_fn, key_eq_fn, clone_fn, free_fn, n, key_bytes, value_bytes, + keys, values) +} + +[inline] +fn new_map_init_noscan_value(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn, n int, key_bytes int, value_bytes int, keys voidptr, values voidptr) map { + return new_map_init(hash_fn, key_eq_fn, clone_fn, free_fn, n, key_bytes, value_bytes, + keys, values) +} + +[inline] +fn new_map_init_noscan_key_value(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn, n int, key_bytes int, value_bytes int, keys voidptr, values voidptr) map { + return new_map_init(hash_fn, key_eq_fn, clone_fn, free_fn, n, key_bytes, value_bytes, + keys, values) +} From 2e3384aaefa0058ffcb5786e0e97979bf2fde52e Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sat, 15 Jul 2023 17:17:33 +0300 Subject: [PATCH 3/6] cgen: fix Gen.check_noscan to always return correct _noscan information, depending on the type --- vlib/v/gen/c/cgen.v | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 438c55491315c4..64121aa5b15d62 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -6219,11 +6219,10 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Ty [inline] fn c_name(name_ string) string { - name := util.no_dots(name_) - if c.c_reserved_chk.matches(name) { - return '_v_${name}' + if c.c_reserved_chk.matches(name_) { + return '_v_${name_}' } - return name + return util.no_dots(name_) } fn (mut g Gen) type_default(typ_ ast.Type) string { @@ -6973,10 +6972,8 @@ pub fn (mut g Gen) contains_ptr(el_typ ast.Type) bool { } fn (mut g Gen) check_noscan(elem_typ ast.Type) string { - if g.pref.gc_mode in [.boehm_full_opt, .boehm_incr_opt] { - if !g.contains_ptr(elem_typ) { - return '_noscan' - } + if !g.contains_ptr(elem_typ) { + return '_noscan' } return '' } From 11bffc957ac443ebba222aac597c1740b1ca37be Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sat, 15 Jul 2023 17:18:21 +0300 Subject: [PATCH 4/6] cgen,ast: reduce memory usage for compiling larger V programs --- vlib/v/ast/ast.v | 6 +++--- vlib/v/ast/comptime_const_values.v | 4 +--- vlib/v/gen/c/assign.v | 14 +++++++++++--- vlib/v/gen/c/infix.v | 8 ++++++-- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 5afaf2c04dc5a1..d86c5b9d86d246 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -349,7 +349,7 @@ pub mut: end_comments []Comment // comments that after const field // the comptime_expr_value field is filled by the checker, when it has enough // info to evaluate the constant at compile time - comptime_expr_value ComptTimeConstValue = empty_comptime_const_expr() + comptime_expr_value ComptTimeConstValue = empty_comptime_const_expr } // const declaration @@ -1006,9 +1006,9 @@ pub mut: or_block OrExpr ct_left_value_evaled bool - ct_left_value ComptTimeConstValue = empty_comptime_const_expr() + ct_left_value ComptTimeConstValue = empty_comptime_const_expr ct_right_value_evaled bool - ct_right_value ComptTimeConstValue = empty_comptime_const_expr() + ct_right_value ComptTimeConstValue = empty_comptime_const_expr before_op_comments []Comment after_op_comments []Comment diff --git a/vlib/v/ast/comptime_const_values.v b/vlib/v/ast/comptime_const_values.v index 4780b2a2178223..3b612b25b066a2 100644 --- a/vlib/v/ast/comptime_const_values.v +++ b/vlib/v/ast/comptime_const_values.v @@ -15,9 +15,7 @@ pub type ComptTimeConstValue = EmptyExpr | u8 | voidptr -pub fn empty_comptime_const_expr() ComptTimeConstValue { - return EmptyExpr(0) -} +pub const empty_comptime_const_expr = ComptTimeConstValue(EmptyExpr(0)) pub fn (val ComptTimeConstValue) i8() ?i8 { x := val.i64()? diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index 80b6845a2a336f..c9c0506ce7a43e 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -493,7 +493,9 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { concrete_types := (left_sym.info as ast.Struct).concrete_types mut method_name := left_sym.cname + '_' + util.replace_op(extracted_op) method_name = g.generic_fn_name(concrete_types, method_name) - g.write(' = ${method_name}(') + g.write(' = ') + g.write(method_name) + g.write('(') g.expr(left) g.write(', ') g.expr(val) @@ -504,7 +506,9 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { && !left_sym.has_method(extracted_op) { g.write(' = ') g.expr(left) - g.write(' ${extracted_op} ') + g.write(' ') + g.write(extracted_op) + g.write(' ') g.expr(val) g.write(';') return @@ -631,7 +635,11 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { g.writeln(';') } } else if !g.is_arraymap_set && !str_add && !op_overloaded { - g.write(' ${op} ') + // ordinary `=` in `x = 2 * y;` + // Note, that this branch *deliberately does not use interpolation* + g.write(' ') + g.write(op.str()) + g.write(' ') } else if str_add || op_overloaded { g.write(', ') } diff --git a/vlib/v/gen/c/infix.v b/vlib/v/gen/c/infix.v index 0d74b77a94badd..374d94503aa5c8 100644 --- a/vlib/v/gen/c/infix.v +++ b/vlib/v/gen/c/infix.v @@ -1016,7 +1016,9 @@ fn (mut g Gen) gen_is_none_check(node ast.InfixExpr) { g.write(' ') g.write('${left_var}.state') } - g.write(' ${node.op.str()} ') + g.write(' ') + g.write(node.op.str()) + g.write(' ') g.write('2') // none state } @@ -1030,7 +1032,9 @@ fn (mut g Gen) gen_plain_infix_expr(node ast.InfixExpr) { g.write('*') } g.expr(node.left) - g.write(' ${node.op.str()} ') + g.write(' ') + g.write(node.op.str()) + g.write(' ') if node.right_type.is_ptr() && node.right.is_auto_deref_var() { g.write('*') g.expr(node.right) From 8eded2e0258a03a40e0e10b7816a4f73d209c3c9 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sat, 15 Jul 2023 17:18:55 +0300 Subject: [PATCH 5/6] Revert "ast,cgen: small speedup for the 1m_statements_in_1_fn.v" This reverts commit 14b5cf433d12c59240e9fab6bd2ec68133f4a7c3. --- vlib/v/ast/types.v | 43 +++++++++++----------------------- vlib/v/gen/c/auto_eq_methods.v | 12 +++++----- 2 files changed, 20 insertions(+), 35 deletions(-) diff --git a/vlib/v/ast/types.v b/vlib/v/ast/types.v index feba6900367f99..7e00250f8e36d8 100644 --- a/vlib/v/ast/types.v +++ b/vlib/v/ast/types.v @@ -272,12 +272,10 @@ pub fn (t Type) atomic_typename() string { } } -[inline] pub fn sharetype_from_flags(is_shared bool, is_atomic bool) ShareType { return unsafe { ShareType(int(u32(is_atomic) << 1) | int(is_shared)) } } -[inline] pub fn (t Type) share() ShareType { return sharetype_from_flags(t.has_flag(.shared_f), t.has_flag(.atomic_f)) } @@ -285,7 +283,7 @@ pub fn (t Type) share() ShareType { // return TypeSymbol idx for `t` [inline] pub fn (t Type) idx() int { - return int(t) & 0xffff + return u16(t) & 0xffff } [inline] @@ -309,14 +307,13 @@ pub fn (t Type) nr_muls() int { pub fn (t Type) is_ptr() bool { // any normal pointer, i.e. &Type, &&Type etc; // Note: voidptr, charptr and byteptr are NOT included! - return (int(t) >> 16) & 0xff != 0 + return (int(t) >> 16) & 0xff > 0 } [inline] pub fn (typ Type) is_pointer() bool { // builtin pointer types (voidptr, byteptr, charptr) - return typ.idx() in [ast.voidptr_type_idx, ast.byteptr_type_idx, ast.charptr_type_idx, - ast.nil_type_idx] + return typ.idx() in ast.pointer_type_idxs } [inline] @@ -326,8 +323,7 @@ pub fn (typ Type) is_voidptr() bool { [inline] pub fn (t Type) is_any_kind_of_pointer() bool { - return (int(t) >> 16) & 0xff != 0 - || u16(t) in [ast.voidptr_type_idx, ast.byteptr_type_idx, ast.charptr_type_idx, ast.nil_type_idx] + return (int(t) >> 16) & 0xff > 0 || (u16(t) & 0xffff) in ast.pointer_type_idxs } // set nr_muls on `t` and return it @@ -388,7 +384,7 @@ pub fn (t Type) clear_flags(flags ...TypeFlag) Type { // return true if `flag` is set on `t` [inline] pub fn (t Type) has_flag(flag TypeFlag) bool { - return int(t) & (1 << (int(flag) + 24)) != 0 + return int(t) & (1 << (int(flag) + 24)) > 0 } // debug returns a verbose representation of the information in ts, useful for tracing/debugging @@ -488,50 +484,42 @@ pub fn new_type_ptr(idx int, nr_muls int) Type { [inline] pub fn (typ Type) is_float() bool { - return !typ.is_ptr() - && typ.idx() in [ast.f32_type_idx, ast.f64_type_idx, ast.float_literal_type_idx] + return !typ.is_ptr() && typ.idx() in ast.float_type_idxs } [inline] pub fn (typ Type) is_int() bool { - return !typ.is_ptr() - && typ.idx() in [ast.i8_type_idx, ast.i16_type_idx, ast.int_type_idx, ast.i64_type_idx, ast.u8_type_idx, ast.u16_type_idx, ast.u32_type_idx, ast.u64_type_idx, ast.isize_type_idx, ast.usize_type_idx, ast.int_literal_type_idx, ast.rune_type_idx] + return !typ.is_ptr() && typ.idx() in ast.integer_type_idxs } [inline] pub fn (typ Type) is_int_valptr() bool { - return typ.is_ptr() - && typ.idx() in [ast.i8_type_idx, ast.i16_type_idx, ast.int_type_idx, ast.i64_type_idx, ast.u8_type_idx, ast.u16_type_idx, ast.u32_type_idx, ast.u64_type_idx, ast.isize_type_idx, ast.usize_type_idx, ast.int_literal_type_idx, ast.rune_type_idx] + return typ.is_ptr() && typ.idx() in ast.integer_type_idxs } [inline] pub fn (typ Type) is_float_valptr() bool { - return typ.is_ptr() - && typ.idx() in [ast.f32_type_idx, ast.f64_type_idx, ast.float_literal_type_idx] + return typ.is_ptr() && typ.idx() in ast.float_type_idxs } [inline] pub fn (typ Type) is_pure_int() bool { - return int(typ) in [ast.i8_type_idx, ast.i16_type_idx, ast.int_type_idx, ast.i64_type_idx, - ast.u8_type_idx, ast.u16_type_idx, ast.u32_type_idx, ast.u64_type_idx, ast.isize_type_idx, - ast.usize_type_idx, ast.int_literal_type_idx, ast.rune_type_idx] + return int(typ) in ast.integer_type_idxs } [inline] pub fn (typ Type) is_pure_float() bool { - return int(typ) in [ast.f32_type_idx, ast.f64_type_idx, ast.float_literal_type_idx] + return int(typ) in ast.float_type_idxs } [inline] pub fn (typ Type) is_signed() bool { - return typ.idx() in [ast.char_type_idx, ast.i8_type_idx, ast.i16_type_idx, ast.int_type_idx, - ast.i64_type_idx, ast.isize_type_idx] + return typ.idx() in ast.signed_integer_type_idxs } [inline] pub fn (typ Type) is_unsigned() bool { - return typ.idx() in [ast.u8_type_idx, ast.u16_type_idx, ast.u32_type_idx, ast.u64_type_idx, - ast.usize_type_idx] + return typ.idx() in ast.unsigned_integer_type_idxs } pub fn (typ Type) flip_signedness() Type { @@ -557,10 +545,7 @@ pub fn (typ Type) is_int_literal() bool { [inline] pub fn (typ Type) is_number() bool { - return (int(typ) & 0xffffff) in [ast.i8_type_idx, ast.i16_type_idx, ast.int_type_idx, - ast.i64_type_idx, ast.u8_type_idx, ast.char_type_idx, ast.u16_type_idx, ast.u32_type_idx, - ast.u64_type_idx, ast.isize_type_idx, ast.usize_type_idx, ast.f32_type_idx, ast.f64_type_idx, - ast.int_literal_type_idx, ast.float_literal_type_idx, ast.rune_type_idx] + return typ.clear_flags() in ast.number_type_idxs } [inline] diff --git a/vlib/v/gen/c/auto_eq_methods.v b/vlib/v/gen/c/auto_eq_methods.v index 35d3fdc48379e7..bcb619eb115439 100644 --- a/vlib/v/gen/c/auto_eq_methods.v +++ b/vlib/v/gen/c/auto_eq_methods.v @@ -225,10 +225,10 @@ fn (mut g Gen) gen_alias_equality_fn(left_type ast.Type) string { } g.generated_eq_fns << left_type info := left.sym.info as ast.Alias - g.definitions.writeln('static inline bool ${ptr_styp}_alias_eq(${ptr_styp} a, ${ptr_styp} b); // auto') + g.definitions.writeln('static bool ${ptr_styp}_alias_eq(${ptr_styp} a, ${ptr_styp} b); // auto') mut fn_builder := strings.new_builder(512) - fn_builder.writeln('static inline bool ${ptr_styp}_alias_eq(${ptr_styp} a, ${ptr_styp} b) {') + fn_builder.writeln('static bool ${ptr_styp}_alias_eq(${ptr_styp} a, ${ptr_styp} b) {') is_option := left.typ.has_flag(.option) @@ -283,10 +283,10 @@ fn (mut g Gen) gen_array_equality_fn(left_type ast.Type) string { g.generated_eq_fns << left_type elem := g.unwrap(left.sym.array_info().elem_type) ptr_elem_styp := g.typ(elem.typ) - g.definitions.writeln('static inline bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b); // auto') + g.definitions.writeln('static bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b); // auto') mut fn_builder := strings.new_builder(512) - fn_builder.writeln('static inline bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b) {') + fn_builder.writeln('static bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b) {') left_len := g.read_field(left_type, 'len', 'a') right_len := g.read_field(left_type, 'len', 'b') @@ -353,13 +353,13 @@ fn (mut g Gen) gen_fixed_array_equality_fn(left_type ast.Type) string { elem_info := left_typ.sym.array_fixed_info() elem := g.unwrap(elem_info.elem_type) size := elem_info.size - g.definitions.writeln('static inline bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b); // auto') + g.definitions.writeln('static bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b); // auto') left := if left_type.has_flag(.option) { 'a.data' } else { 'a' } right := if left_type.has_flag(.option) { 'b.data' } else { 'b' } mut fn_builder := strings.new_builder(512) - fn_builder.writeln('static inline bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b) {') + fn_builder.writeln('static bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b) {') fn_builder.writeln('\tfor (int i = 0; i < ${size}; ++i) {') // compare every pair of elements of the two fixed arrays if elem.sym.kind == .string { From 46c07a5fac3621383caff39b1693b692a108e2e2 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sat, 15 Jul 2023 18:18:08 +0300 Subject: [PATCH 6/6] add the cmd/tools/gen_1long_fn.v script too --- cmd/tools/gen_1long_fn.v | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 cmd/tools/gen_1long_fn.v diff --git a/cmd/tools/gen_1long_fn.v b/cmd/tools/gen_1long_fn.v new file mode 100644 index 00000000000000..19d8a2ac52f7be --- /dev/null +++ b/cmd/tools/gen_1long_fn.v @@ -0,0 +1,15 @@ +import strings +import os + +n := os.args[1] or { '1_000_000' }.int() +stmt := os.args[2] or { 'a = b + c * d' } + +mut s := strings.new_builder(1000) +s.writeln('fn main() {') +s.writeln(' mut a,b,c,d := 0,1,2,3') +for _ in 0 .. n { + s.writeln(' ${stmt}') +} +s.writeln(' println("a: \${a}")') +s.writeln('}') +os.write_file('${n}.v', s.str())!