Once linearized, a few essentials optimizations are done but the logic of the succession of these optimizations is open-coded at the end of linearize_fn(). Obviously, this logic have nothing to do with the linearization and moving it to a separate file will help to clarify this logic and change it when needed. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- Makefile | 1 + linearize.c | 64 ++------------------------------------------------- optimize.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ optimize.h | 9 ++++++++ 4 files changed, 88 insertions(+), 62 deletions(-) create mode 100644 optimize.c create mode 100644 optimize.h diff --git a/Makefile b/Makefile index dab38aacd..14cf02a93 100644 --- a/Makefile +++ b/Makefile @@ -47,6 +47,7 @@ LIB_OBJS += linearize.o LIB_OBJS += liveness.o LIB_OBJS += memops.o LIB_OBJS += opcode.o +LIB_OBJS += optimize.o LIB_OBJS += parse.o LIB_OBJS += pre-process.o LIB_OBJS += ptrlist.o diff --git a/linearize.c b/linearize.c index c2a129f5d..9315882c9 100644 --- a/linearize.c +++ b/linearize.c @@ -19,6 +19,7 @@ #include "parse.h" #include "expression.h" #include "linearize.h" +#include "optimize.h" #include "flow.h" #include "target.h" @@ -779,15 +780,6 @@ pseudo_t alloc_pseudo(struct instruction *def) return pseudo; } -static void clear_symbol_pseudos(struct entrypoint *ep) -{ - pseudo_t pseudo; - - FOR_EACH_PTR(ep->accesses, pseudo) { - pseudo->sym->pseudo = NULL; - } END_FOR_EACH_PTR(pseudo); -} - static pseudo_t symbol_pseudo(struct entrypoint *ep, struct symbol *sym) { pseudo_t pseudo; @@ -2218,59 +2210,7 @@ static struct entrypoint *linearize_fn(struct symbol *sym, struct symbol *base_t add_one_insn(ep, insn); } - if (fdump_ir & PASS_LINEARIZE) - show_entry(ep); - - /* - * Do trivial flow simplification - branches to - * branches, kill dead basicblocks etc - */ - kill_unreachable_bbs(ep); - - /* - * Turn symbols into pseudos - */ - if (fpasses & PASS_MEM2REG) - simplify_symbol_usage(ep); - if (fdump_ir & PASS_MEM2REG) - show_entry(ep); - - if (!(fpasses & PASS_OPTIM)) - return ep; -repeat: - /* - * Remove trivial instructions, and try to CSE - * the rest. - */ - do { - cleanup_and_cse(ep); - pack_basic_blocks(ep); - } while (repeat_phase & REPEAT_CSE); - - kill_unreachable_bbs(ep); - vrfy_flow(ep); - - /* Cleanup */ - clear_symbol_pseudos(ep); - - /* And track pseudo register usage */ - track_pseudo_liveness(ep); - - /* - * Some flow optimizations can only effectively - * be done when we've done liveness analysis. But - * if they trigger, we need to start all over - * again - */ - if (simplify_flow(ep)) { - clear_liveness(ep); - goto repeat; - } - - /* Finally, add deathnotes to pseudos now that we have them */ - if (dbg_dead) - track_pseudo_death(ep); - + optimize(ep); return ep; } diff --git a/optimize.c b/optimize.c new file mode 100644 index 000000000..8cf243517 --- /dev/null +++ b/optimize.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: MIT +// +// optimize.c - main optimization loop +// +// Copyright (C) 2004 Linus Torvalds +// Copyright (C) 2004 Christopher Li + +#include "optimize.h" +#include "linearize.h" +#include "flow.h" + + +static void clear_symbol_pseudos(struct entrypoint *ep) +{ + pseudo_t pseudo; + + FOR_EACH_PTR(ep->accesses, pseudo) { + pseudo->sym->pseudo = NULL; + } END_FOR_EACH_PTR(pseudo); +} + +void optimize(struct entrypoint *ep) +{ + if (fdump_ir & PASS_LINEARIZE) + show_entry(ep); + + /* + * Do trivial flow simplification - branches to + * branches, kill dead basicblocks etc + */ + kill_unreachable_bbs(ep); + + /* + * Turn symbols into pseudos + */ + if (fpasses & PASS_MEM2REG) + simplify_symbol_usage(ep); + if (fdump_ir & PASS_MEM2REG) + show_entry(ep); + + if (!(fpasses & PASS_OPTIM)) + return; +repeat: + /* + * Remove trivial instructions, and try to CSE + * the rest. + */ + do { + cleanup_and_cse(ep); + pack_basic_blocks(ep); + } while (repeat_phase & REPEAT_CSE); + + kill_unreachable_bbs(ep); + vrfy_flow(ep); + + /* Cleanup */ + clear_symbol_pseudos(ep); + + /* And track pseudo register usage */ + track_pseudo_liveness(ep); + + /* + * Some flow optimizations can only effectively + * be done when we've done liveness analysis. But + * if they trigger, we need to start all over + * again + */ + if (simplify_flow(ep)) { + clear_liveness(ep); + goto repeat; + } + + /* Finally, add deathnotes to pseudos now that we have them */ + if (dbg_dead) + track_pseudo_death(ep); +} diff --git a/optimize.h b/optimize.h new file mode 100644 index 000000000..31e2cf081 --- /dev/null +++ b/optimize.h @@ -0,0 +1,9 @@ +#ifndef OPTIMIZE_H +#define OPTIMIZE_H + +struct entrypoint; + +/* optimize.c */ +void optimize(struct entrypoint *ep); + +#endif -- 2.16.0 -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html