[PATCH] kconfig: Fix Kconfig performance bug
authorDavid Gibson <david@gibson.dropbear.id.au>
Wed, 9 Nov 2005 05:34:46 +0000 (21:34 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 9 Nov 2005 15:55:53 +0000 (07:55 -0800)
When doing its recursive dependency check, scripts/kconfig/conf uses the flag
SYMBOL_CHECK_DONE to avoid rechecking a symbol it has already checked.
However, that flag is only set at the top level, so if a symbol is first
encountered as a dependency of another symbol it will be rechecked every time
it is encountered until it's encountered at the top level.

This patch adjusts the flag setting so that each symbol will only be checked
once, regardless of whether it is first encountered at the top level, or while
recursing down from another symbol.  On complex configurations, this vastly
speeds up scripts/kconfig/conf.  The config in the powerpc merge tree is
particularly bad: this patch reduces the time for 'scripts/kconfig/conf -o
arch/powerpc/Kconfig' by a factor of 40 on a G5.  That's even including the
time to print the config, so the speedup in the actual checking is more likely
2 or 3 orders of magnitude.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
scripts/kconfig/expr.h
scripts/kconfig/symbol.c
scripts/kconfig/zconf.tab.c_shipped
scripts/kconfig/zconf.y

index 7d39ff43e6e1facd64d6267cd443919b3d1c7381..1b36ef18c48d2ea04ac65d6cd9733b334b5ec621 100644 (file)
@@ -93,7 +93,6 @@ struct symbol {
 #define SYMBOL_NEW             0x0800
 #define SYMBOL_AUTO            0x1000
 #define SYMBOL_CHECKED         0x2000
-#define SYMBOL_CHECK_DONE      0x4000
 #define SYMBOL_WARNED          0x8000
 
 #define SYMBOL_MAXLENGTH       256
index affa52f5c651365d77b0866df06d81dd89a15619..10d96c4188dddc6fbbed52e2aaabddc43d3417ee 100644 (file)
@@ -731,12 +731,12 @@ struct symbol *sym_check_deps(struct symbol *sym)
        struct symbol *sym2;
        struct property *prop;
 
-       if (sym->flags & SYMBOL_CHECK_DONE)
-               return NULL;
        if (sym->flags & SYMBOL_CHECK) {
                printf("Warning! Found recursive dependency: %s", sym->name);
                return sym;
        }
+       if (sym->flags & SYMBOL_CHECKED)
+               return NULL;
 
        sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
        sym2 = sym_check_expr_deps(sym->rev_dep.expr);
@@ -756,8 +756,13 @@ struct symbol *sym_check_deps(struct symbol *sym)
                        goto out;
        }
 out:
-       if (sym2)
+       if (sym2) {
                printf(" %s", sym->name);
+               if (sym2 == sym) {
+                       printf("\n");
+                       sym2 = NULL;
+               }
+       }
        sym->flags &= ~SYMBOL_CHECK;
        return sym2;
 }
index ff4fcc09720ecbd5303ab4c13a37efdde3eb0c98..da12f7b33be3d7e87e0cda794294a27e98c1bc9d 100644 (file)
@@ -1933,10 +1933,7 @@ void conf_parse(const char *name)
                exit(1);
        menu_finalize(&rootmenu);
        for_all_symbols(i, sym) {
-                if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
-                        printf("\n");
-               else
-                       sym->flags |= SYMBOL_CHECK_DONE;
+               sym_check_deps(sym);
         }
 
        sym_change_count = 1;
index e1a0f455d4a8decb163ff3196a0725b738279bb1..1e214e9c1d31313d4ad9bf713931a5e15d4eed9c 100644 (file)
@@ -495,10 +495,7 @@ void conf_parse(const char *name)
                exit(1);
        menu_finalize(&rootmenu);
        for_all_symbols(i, sym) {
-                if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
-                        printf("\n");
-               else
-                       sym->flags |= SYMBOL_CHECK_DONE;
+               sym_check_deps(sym);
         }
 
        sym_change_count = 1;