summaryrefslogtreecommitdiff
path: root/scripts/kconfig/expr.h
diff options
context:
space:
mode:
authorMasahiro Yamada <masahiroy@kernel.org>2024-09-08 21:43:20 +0900
committerMasahiro Yamada <masahiroy@kernel.org>2024-09-20 09:21:52 +0900
commitf93d6bfbd2f74d79041c153a59df5336f6e9a14a (patch)
tree7661981cefb2b35765a7ade7d22b9b742cb050a2 /scripts/kconfig/expr.h
parent440f67ccdcd31ca33d8d0439b16e4b6d4d7aba17 (diff)
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 e983b7b17ad1 ("kconfig/menu.c: fix multiple references to expressions in menu_add_prop()"). Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Diffstat (limited to 'scripts/kconfig/expr.h')
-rw-r--r--scripts/kconfig/expr.h16
1 files changed, 12 insertions, 4 deletions
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 4ab7422ddbd8..a398b2b2dbe0 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -29,11 +29,21 @@ enum expr_type {
};
union expr_data {
- struct expr *expr;
- struct symbol *sym;
+ struct expr * const expr;
+ struct symbol * const sym;
+ void *_initdata;
};
+/**
+ * struct expr - expression
+ *
+ * @node: link node for the hash table
+ * @type: expressoin type
+ * @left: left node
+ * @right: right node
+ */
struct expr {
+ struct hlist_node node;
enum expr_type type;
union expr_data left, right;
};
@@ -275,8 +285,6 @@ struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e
struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2);
struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
struct expr *expr_alloc_or(struct expr *e1, struct expr *e2);
-struct expr *expr_copy(const struct expr *org);
-void expr_free(struct expr *e);
void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
bool expr_eq(struct expr *e1, struct expr *e2);
tristate expr_calc_value(struct expr *e);