cgen: speed up auto generated Array_*_contains and Array_*_index methods

Uses a.data instead of array_get, since the auto generated methods
have the calls in a loop that guarantees that the bounds of the arrays
will not be exceeded, thus the inner bounds checking can be skipped.

Results in +5% improvement for V compiled with tcc, doing `v -o x.c cmd/v`,
more with -prod.
pull/9975/head
Delyan Angelov 2021-05-02 19:18:11 +03:00
parent feb60674b4
commit 53ae9dda4b
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
2 changed files with 13 additions and 12 deletions

View File

@ -471,20 +471,20 @@ fn (mut g Gen) gen_array_contains_method(left_type ast.Type) string {
fn_builder.writeln('static bool ${fn_name}($left_type_str a, $elem_type_str v) {')
fn_builder.writeln('\tfor (int i = 0; i < a.len; ++i) {')
if elem_sym.kind == .string {
fn_builder.writeln('\t\tif (string_eq((*(string*)array_get(a, i)), v)) {')
fn_builder.writeln('\t\tif (fast_string_eq(((string*)a.data)[i], v)) {')
} else if elem_sym.kind == .array && left_info.elem_type.nr_muls() == 0 {
ptr_typ := g.gen_array_equality_fn(left_info.elem_type)
fn_builder.writeln('\t\tif (${ptr_typ}_arr_eq(*($elem_type_str*)array_get(a, i), v)) {')
fn_builder.writeln('\t\tif (${ptr_typ}_arr_eq((($elem_type_str*)a.data)[i], v)) {')
} else if elem_sym.kind == .function {
fn_builder.writeln('\t\tif ((*(voidptr*)array_get(a, i)) == v) {')
fn_builder.writeln('\t\tif (((voidptr*)a.data)[i] == v) {')
} else if elem_sym.kind == .map && left_info.elem_type.nr_muls() == 0 {
ptr_typ := g.gen_map_equality_fn(left_info.elem_type)
fn_builder.writeln('\t\tif (${ptr_typ}_map_eq(*($elem_type_str*)array_get(a, i), v)) {')
fn_builder.writeln('\t\tif (${ptr_typ}_map_eq((($elem_type_str*)a.data)[i], v)) {')
} else if elem_sym.kind == .struct_ && left_info.elem_type.nr_muls() == 0 {
ptr_typ := g.gen_struct_equality_fn(left_info.elem_type)
fn_builder.writeln('\t\tif (${ptr_typ}_struct_eq(*($elem_type_str*)array_get(a, i), v)) {')
fn_builder.writeln('\t\tif (${ptr_typ}_struct_eq((($elem_type_str*)a.data)[i], v)) {')
} else {
fn_builder.writeln('\t\tif ((*($elem_type_str*)array_get(a, i)) == v) {')
fn_builder.writeln('\t\tif ((($elem_type_str*)a.data)[i] == v) {')
}
fn_builder.writeln('\t\t\treturn true;')
fn_builder.writeln('\t\t}')
@ -535,20 +535,20 @@ fn (mut g Gen) gen_array_index_method(left_type ast.Type) string {
fn_builder.writeln('static int ${fn_name}($left_type_str a, $elem_type_str v) {')
fn_builder.writeln('\tfor (int i = 0; i < a.len; ++i) {')
if elem_sym.kind == .string {
fn_builder.writeln('\t\tif (string_eq((*(string*)array_get(a, i)), v)) {')
fn_builder.writeln('\t\tif (fast_string_eq(((string*)a.data)[i], v)) {')
} else if elem_sym.kind == .array && !info.elem_type.is_ptr() {
ptr_typ := g.gen_array_equality_fn(info.elem_type)
fn_builder.writeln('\t\tif (${ptr_typ}_arr_eq(*($elem_type_str*)array_get(a, i), v)) {')
fn_builder.writeln('\t\tif (${ptr_typ}_arr_eq((($elem_type_str*)a.data)[i], v)) {')
} else if elem_sym.kind == .function && !info.elem_type.is_ptr() {
fn_builder.writeln('\t\tif ((*(voidptr*)array_get(a, i)) == v) {')
fn_builder.writeln('\t\tif (((voidptr*)a.data)[i] == v) {')
} else if elem_sym.kind == .map && !info.elem_type.is_ptr() {
ptr_typ := g.gen_map_equality_fn(info.elem_type)
fn_builder.writeln('\t\tif (${ptr_typ}_map_eq(*($elem_type_str*)array_get(a, i), v)) {')
fn_builder.writeln('\t\tif (${ptr_typ}_map_eq((($elem_type_str*)a.data)[i], v)) {')
} else if elem_sym.kind == .struct_ && !info.elem_type.is_ptr() {
ptr_typ := g.gen_struct_equality_fn(info.elem_type)
fn_builder.writeln('\t\tif (${ptr_typ}_struct_eq(*($elem_type_str*)array_get(a, i), v)) {')
fn_builder.writeln('\t\tif (${ptr_typ}_struct_eq((($elem_type_str*)a.data)[i], v)) {')
} else {
fn_builder.writeln('\t\tif ((*($elem_type_str*)array_get(a, i)) == v) {')
fn_builder.writeln('\t\tif ((($elem_type_str*)a.data)[i] == v) {')
}
fn_builder.writeln('\t\t\treturn i;')
fn_builder.writeln('\t\t}')

View File

@ -65,6 +65,7 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []ast.Fi
'18.gt',
'18.le',
'18.ge',
'fast_string_eq',
// ustring. ==, !=, etc...
'19.eq',
'19.ne',