Skip to content

Commit f93d6bf

Browse files
committed
kconfig: use hash table to reuse expressions
Currently, every expression in Kconfig files produces a new abstract syntax tree (AST), even if it is identical to a previously encountered one. Consider the following code: config FOO bool "FOO" depends on (A || B) && C config BAR bool "BAR" depends on (A || B) && C config BAZ bool "BAZ" depends on A || B The "depends on" lines are similar, but currently a separate AST is allocated for each one. The current data structure looks like this: FOO->dep ==> AND BAR->dep ==> AND BAZ->dep ==> OR / \ / \ / \ OR C OR C A B / \ / \ A B A B This is redundant; FOO->dep and BAR->dep have identical ASTs but different memory instances. We can optimize this; FOO->dep and BAR->dep can share the same AST, and BAZ->dep can reference its sub tree. The optimized data structure looks like this: FOO->dep, BAR->dep ==> AND / \ BAZ->dep ==> OR C / \ A B This commit introduces a hash table to keep track of allocated expressions. If an identical expression is found, it is reused. This does not necessarily result in memory savings, as menu_finalize() transforms expressions without freeing up stale ones. This will be addressed later. One optimization that can be easily implemented is caching the expression's value. Once FOO's dependency, (A || B) && C, is calculated, it can be cached, eliminating the need to recalculate it for BAR. This commit also reverts commit e983b7b ("kconfig/menu.c: fix multiple references to expressions in menu_add_prop()"). Signed-off-by: Masahiro Yamada <[email protected]>
1 parent 440f67c commit f93d6bf

File tree

5 files changed

+170
-277
lines changed

5 files changed

+170
-277
lines changed

scripts/include/hash.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,17 @@ static inline unsigned int hash_str(const char *s)
1212
return hash;
1313
}
1414

15+
/* simplified version of functions from include/linux/hash.h */
16+
#define GOLDEN_RATIO_32 0x61C88647
17+
18+
static inline unsigned int hash_32(unsigned int val)
19+
{
20+
return 0x61C88647 * val;
21+
}
22+
23+
static inline unsigned int hash_ptr(const void *ptr)
24+
{
25+
return hash_32((unsigned int)(unsigned long)ptr);
26+
}
27+
1528
#endif /* HASH_H */

0 commit comments

Comments
 (0)