Skip to content

Commit

Permalink
v.markused: cleanup, extract more fields from ast.Table to ast.UsedFe…
Browse files Browse the repository at this point in the history
…atures, to reduce its size
  • Loading branch information
spytheman committed Nov 19, 2024
1 parent b0dc186 commit 09f8b56
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 64 deletions.
65 changes: 37 additions & 28 deletions vlib/v/ast/table.v
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,39 @@ import v.util
@[heap; minify]
pub struct UsedFeatures {
pub mut:
interfaces bool // interface
dump bool // dump()
builtin_types bool // uses any builtin type
index bool // string[0]
range_index bool // string[0..1]
cast_ptr bool // &u8(...)
as_cast bool // expr as Type
anon_fn bool // fn () { }
auto_str bool // auto str fns
auto_str_ptr bool // auto str fns for ptr type
arr_prepend bool // arr.prepend()
arr_first bool // arr.first()
arr_last bool // arr.last()
arr_pop bool // arr.pop()
option_or_result bool // has panic call
print_types map[int]bool // print() idx types
interfaces bool // interface
dump bool // dump()
builtin_types bool // uses any builtin type
index bool // string[0]
range_index bool // string[0..1]
cast_ptr bool // &u8(...)
as_cast bool // expr as Type
anon_fn bool // fn () { }
auto_str bool // auto str fns
auto_str_ptr bool // auto str fns for ptr type
arr_prepend bool // arr.prepend()
arr_first bool // arr.first()
arr_last bool // arr.last()
arr_pop bool // arr.pop()
option_or_result bool // has panic call
print_types map[int]bool // print() idx types
used_fns map[string]bool // filled in by markused
used_consts map[string]bool // filled in by markused
used_globals map[string]bool // filled in by markused
used_veb_types []Type // veb context types, filled in by checker
used_maps int // how many times maps were used, filled in by markused
used_arrays int // how many times arrays were used, filled in by markused
}

@[unsafe]
pub fn (mut uf UsedFeatures) free() {
unsafe {
uf.print_types.free()
uf.used_fns.free()
uf.used_consts.free()
uf.used_globals.free()
uf.used_veb_types.free()
}
}

@[heap; minify]
Expand All @@ -48,14 +65,9 @@ pub mut:
sumtypes map[int]SumTypeDecl
cmod_prefix string // needed for ast.type_to_str(Type) while vfmt; contains `os.`
is_fmt bool
used_fns map[string]bool // filled in by the checker, when pref.skip_unused = true;
used_consts map[string]bool // filled in by the checker, when pref.skip_unused = true;
used_globals map[string]bool // filled in by the checker, when pref.skip_unused = true;
used_features UsedFeatures // filled in by the checker, when pref.skip_unused = true;
used_veb_types []Type // veb context types, filled in by checker, when pref.skip_unused = true;
veb_res_idx_cache int // Cache of `veb.Result` type
veb_ctx_idx_cache int // Cache of `veb.Context` type
used_maps int // how many times maps were used, filled in by checker, when pref.skip_unused = true;
used_features &UsedFeatures = &UsedFeatures{} // filled in by the checker/markused, when pref.skip_unused = true;
veb_res_idx_cache int // Cache of `veb.Result` type
veb_ctx_idx_cache int // Cache of `veb.Context` type
panic_handler FnPanicHandler = default_table_panic_handler
panic_userdata voidptr = unsafe { nil } // can be used to pass arbitrary data to panic_handler;
panic_npanics int
Expand Down Expand Up @@ -94,10 +106,7 @@ pub fn (mut t Table) free() {
t.redefined_fns.free()
t.fn_generic_types.free()
t.cmod_prefix.free()
t.used_fns.free()
t.used_consts.free()
t.used_globals.free()
t.used_veb_types.free()
t.used_features.free()
}
}

Expand Down
2 changes: 1 addition & 1 deletion vlib/v/callgraph/callgraph.v
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ fn (mut m Mapper) visit(node &ast.Node) ! {
ast.FnDecl {
m.is_caller_used = true
if m.pref.skip_unused {
m.is_caller_used = m.table.used_fns[node.fkey()]
m.is_caller_used = m.table.used_features.used_fns[node.fkey()]
}
m.fn_decl = unsafe { &node }
m.caller_name = m.fn_name(node.name, node.receiver.typ, node.is_method)
Expand Down
2 changes: 1 addition & 1 deletion vlib/v/checker/comptime.v
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ fn (mut c Checker) verify_all_vweb_routes() {
if c.vweb_gen_types.len == 0 {
return
}
c.table.used_veb_types = c.vweb_gen_types
c.table.used_features.used_veb_types = c.vweb_gen_types
typ_vweb_result := c.table.find_type('vweb.Result')
old_file := c.file
for vgt in c.vweb_gen_types {
Expand Down
14 changes: 7 additions & 7 deletions vlib/v/gen/c/cgen.v
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ pub fn (mut g Gen) init() {
} else {
g.cheaders.writeln(c_headers)
}
if !g.pref.skip_unused || g.table.used_maps > 0 {
if !g.pref.skip_unused || g.table.used_features.used_maps > 0 {
g.cheaders.writeln(c_wyhash_headers)
}
}
Expand Down Expand Up @@ -936,11 +936,11 @@ pub fn (mut g Gen) init() {
// and this is being called in the main thread, so we can mutate the table
mut muttable := unsafe { &ast.Table(g.table) }
if g.use_segfault_handler {
muttable.used_fns['v_segmentation_fault_handler'] = true
muttable.used_features.used_fns['v_segmentation_fault_handler'] = true
}
muttable.used_fns['eprintln'] = true
muttable.used_fns['print_backtrace'] = true
muttable.used_fns['exit'] = true
muttable.used_features.used_fns['eprintln'] = true
muttable.used_features.used_fns['print_backtrace'] = true
muttable.used_features.used_fns['exit'] = true
}

pub fn (mut g Gen) finish() {
Expand Down Expand Up @@ -6009,7 +6009,7 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) {
}
for field in node.fields {
if g.pref.skip_unused {
if field.name !in g.table.used_consts {
if field.name !in g.table.used_features.used_consts {
$if trace_skip_unused_consts ? {
eprintln('>> skipping unused const name: ${field.name}')
}
Expand Down Expand Up @@ -6413,7 +6413,7 @@ fn (mut g Gen) global_decl(node ast.GlobalDecl) {
}
for field in node.fields {
if g.pref.skip_unused {
if field.name !in g.table.used_globals {
if field.name !in g.table.used_features.used_globals {
$if trace_skip_unused_globals ? {
eprintln('>> skipping unused global name: ${field.name}')
}
Expand Down
2 changes: 1 addition & 1 deletion vlib/v/gen/c/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn (mut g Gen) is_used_by_main(node ast.FnDecl) bool {
mut is_used_by_main := true
if g.pref.skip_unused {
fkey := node.fkey()
is_used_by_main = g.table.used_fns[fkey]
is_used_by_main = g.table.used_features.used_fns[fkey]
$if trace_skip_unused_fns ? {
println('> is_used_by_main: ${is_used_by_main} | node.name: ${node.name} | fkey: ${fkey} | node.is_method: ${node.is_method}')
}
Expand Down
22 changes: 11 additions & 11 deletions vlib/v/markused/markused.v
Original file line number Diff line number Diff line change
Expand Up @@ -339,14 +339,14 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a
if 'C.cJSON_Parse' in all_fns {
all_fn_root_names << 'tos5'
}
mut walker := Walker{
mut walker := Walker.new(
table: table
files: ast_files
all_fns: all_fns
all_consts: all_consts
all_globals: all_globals
pref: pref_
}
)
// println( all_fns.keys() )
walker.mark_markused_fns() // tagged with `@[markused]`
walker.mark_markused_consts() // tagged with `@[markused]`
Expand All @@ -357,7 +357,7 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a
if walker.n_asserts > 0 {
unsafe { walker.fn_decl(mut all_fns['__print_assert_failure']) }
}
if table.used_maps > 0 {
if table.used_features.used_maps > 0 {
for k, mut mfn in all_fns {
mut method_receiver_typename := ''
if mfn.is_method {
Expand Down Expand Up @@ -405,15 +405,15 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a
walker.mark_const_as_used(kcon)
}
}
table.used_fns = walker.used_fns.move()
table.used_consts = walker.used_consts.move()
table.used_globals = walker.used_globals.move()
table.used_features.used_fns = walker.used_fns.move()
table.used_features.used_consts = walker.used_consts.move()
table.used_features.used_globals = walker.used_globals.move()

$if trace_skip_unused ? {
eprintln('>> t.used_fns: ${table.used_fns.keys()}')
eprintln('>> t.used_consts: ${table.used_consts.keys()}')
eprintln('>> t.used_globals: ${table.used_globals.keys()}')
eprintln('>> walker.table.used_maps: ${walker.table.used_maps}')
eprintln('>> t.used_fns: ${table.used_features.used_fns.keys()}')
eprintln('>> t.used_consts: ${table.used_features.used_consts.keys()}')
eprintln('>> t.used_globals: ${table.used_features.used_globals.keys()}')
eprintln('>> walker.table.used_features.used_maps: ${walker.table.used_features.used_maps}')
}
}

Expand Down Expand Up @@ -460,7 +460,7 @@ fn handle_vweb(mut table ast.Table, mut all_fn_root_names []string, result_name
all_fn_root_names << filter_name
typ_vweb_context := table.find_type(context_name).set_nr_muls(1)
all_fn_root_names << '${int(typ_vweb_context)}.html'
for vgt in table.used_veb_types {
for vgt in table.used_features.used_veb_types {
sym_app := table.sym(vgt)
for m in sym_app.methods {
mut skip := true
Expand Down
58 changes: 43 additions & 15 deletions vlib/v/markused/walker.v
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import v.pref

pub struct Walker {
pub mut:
table &ast.Table = unsafe { nil }
table &ast.Table = unsafe { nil }
features &ast.UsedFeatures = unsafe { nil }
used_fns map[string]bool // used_fns['println'] == true
used_consts map[string]bool // used_consts['os.args'] == true
used_globals map[string]bool
Expand All @@ -23,6 +24,14 @@ mut:
all_globals map[string]ast.GlobalField
}

pub fn Walker.new(params Walker) &Walker {
mut new_walker := &Walker{
...params
}
new_walker.features = params.table.used_features
return new_walker
}

pub fn (mut w Walker) mark_fn_as_used(fkey string) {
$if trace_skip_unused_marked ? {
eprintln(' fn > |${fkey}|')
Expand Down Expand Up @@ -77,7 +86,7 @@ pub fn (mut w Walker) mark_root_fns(all_fn_root_names []string) {
for fn_name in all_fn_root_names {
if fn_name !in w.used_fns {
$if trace_skip_unused_roots ? {
println('>>>> ${fn_name} uses: ')
println('>>>> walking root func: ${fn_name} ...')
}
unsafe { w.fn_decl(mut w.all_fns[fn_name]) }
}
Expand All @@ -87,6 +96,9 @@ pub fn (mut w Walker) mark_root_fns(all_fn_root_names []string) {
pub fn (mut w Walker) mark_exported_fns() {
for _, mut func in w.all_fns {
if func.is_exported {
$if trace_skip_unused_exported_fns ? {
println('>>>> walking exported func: ${func.name} ...')
}
w.fn_decl(mut func)
}
}
Expand All @@ -95,6 +107,9 @@ pub fn (mut w Walker) mark_exported_fns() {
pub fn (mut w Walker) mark_markused_fns() {
for _, mut func in w.all_fns {
if func.is_markused {
$if trace_skip_unused_markused_fns ? {
println('>>>> walking markused func: ${func.name} ...')
}
w.fn_decl(mut func)
}
}
Expand All @@ -103,6 +118,9 @@ pub fn (mut w Walker) mark_markused_fns() {
pub fn (mut w Walker) mark_markused_consts() {
for ckey, mut constfield in w.all_consts {
if constfield.is_markused {
$if trace_skip_unused_markused_consts ? {
println('>>>> walking markused const: ${ckey}')
}
w.mark_const_as_used(ckey)
}
}
Expand All @@ -111,6 +129,9 @@ pub fn (mut w Walker) mark_markused_consts() {
pub fn (mut w Walker) mark_markused_globals() {
for gkey, mut globalfield in w.all_globals {
if globalfield.is_markused || globalfield.is_exported {
$if trace_skip_unused_markused_globals ? {
println('>>>> walking markused global: ${gkey}')
}
w.mark_global_as_used(gkey)
}
}
Expand Down Expand Up @@ -170,9 +191,10 @@ pub fn (mut w Walker) stmt(node_ ast.Stmt) {
w.expr(node.high)
w.stmts(node.stmts)
if node.kind == .map {
w.table.used_maps++
}
if node.kind == .struct {
w.features.used_maps++
} else if node.kind == .array {
w.features.used_arrays++
} else if node.kind == .struct {
if node.cond_type == 0 {
return
}
Expand Down Expand Up @@ -268,6 +290,7 @@ fn (mut w Walker) expr(node_ ast.Expr) {
w.expr(node.cap_expr)
w.expr(node.init_expr)
w.exprs(node.exprs)
w.features.used_arrays++
}
ast.Assoc {
w.exprs(node.exprs)
Expand Down Expand Up @@ -325,7 +348,9 @@ fn (mut w Walker) expr(node_ ast.Expr) {
}
sym := w.table.final_sym(node.left_type)
if sym.kind == .map {
w.table.used_maps++
w.features.used_maps++
} else if sym.kind == .array {
w.features.used_arrays++
}
}
ast.InfixExpr {
Expand All @@ -347,8 +372,12 @@ fn (mut w Walker) expr(node_ ast.Expr) {
return
}
right_sym := w.table.sym(node.right_type)
if node.op in [.not_in, .key_in] && right_sym.kind == .map {
w.table.used_maps++
if node.op in [.not_in, .key_in] {
if right_sym.kind == .map {
w.features.used_maps++
} else if right_sym.kind == .array {
w.features.used_arrays++
}
}
}
ast.IfGuardExpr {
Expand Down Expand Up @@ -387,7 +416,7 @@ fn (mut w Walker) expr(node_ ast.Expr) {
ast.MapInit {
w.exprs(node.keys)
w.exprs(node.vals)
w.table.used_maps++
w.features.used_maps++
}
ast.MatchExpr {
w.expr(node.cond)
Expand Down Expand Up @@ -503,9 +532,10 @@ pub fn (mut w Walker) a_struct_info(sname string, info ast.Struct) {
if ifield.typ != 0 {
fsym := w.table.sym(ifield.typ)
if fsym.kind == .map {
w.table.used_maps++
}
if fsym.kind == .struct {
w.features.used_maps++
} else if fsym.kind == .array {
w.features.used_arrays++
} else if fsym.kind == .struct {
w.a_struct_info(fsym.name, fsym.struct_info())
}
}
Expand All @@ -518,8 +548,6 @@ pub fn (mut w Walker) fn_decl(mut node ast.FnDecl) {
}
fkey := node.fkey()
if w.used_fns[fkey] {
// This function is already known to be called, meaning it has been processed already.
// Save CPU time and do nothing.
return
}
w.mark_fn_as_used(fkey)
Expand All @@ -533,7 +561,7 @@ pub fn (mut w Walker) call_expr(mut node ast.CallExpr) {
}
if node.language == .c {
if node.name in ['C.wyhash', 'C.wyhash64'] {
w.table.used_maps++
w.features.used_maps++
}
return
}
Expand Down

0 comments on commit 09f8b56

Please sign in to comment.