From 57c0820b6e1c9cb03811e58c62c6b4220633eca3 Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Wed, 7 Sep 2011 14:59:03 +0200 Subject: [PATCH] introduce opt_manage framework This is a basic implementation of http://libfirm.org/PhaseManagement Introduces remove_unreachable_blocks as an extra API function, which does a subset of optimize_graph_df. --- include/libfirm/irgraph.h | 13 ++++++ ir/ir/unreachable.c | 2 + ir/opt/opt_manage.c | 97 +++++++++++++++++++++++++++++++++++++++ ir/opt/opt_manage.h | 28 +++++++++++ 4 files changed, 140 insertions(+) create mode 100644 ir/opt/opt_manage.c create mode 100644 ir/opt/opt_manage.h diff --git a/include/libfirm/irgraph.h b/include/libfirm/irgraph.h index 03a916ef9..39375edb9 100644 --- a/include/libfirm/irgraph.h +++ b/include/libfirm/irgraph.h @@ -514,6 +514,19 @@ typedef enum { * Set IMPLICIT_BITFIELD_MASKING, if the lowering phase must insert masking operations. */ IR_GRAPH_STATE_IMPLICIT_BITFIELD_MASKING = 1U << 5, + + IR_GRAPH_STATE_NO_CRITICAL_EDGES = 1U << 6, + IR_GRAPH_STATE_NO_BAD_BLOCKS = 1U << 7, // TODO must be inverse of IR_GRAPH_STATE_BAD_BLOCK + IR_GRAPH_STATE_NO_UNREACHABLE_BLOCKS = 1U << 8, + IR_GRAPH_STATE_ONE_RETURN = 1U << 9, + IR_GRAPH_STATE_CONSISTENT_DOMINANCE = 1U << 10, + IR_GRAPH_STATE_CONSISTENT_POSTDOMINANCE = 1U << 11, + IR_GRAPH_STATE_CONSISTENT_OUT_EDGES = 1U << 12, + IR_GRAPH_STATE_CONSISTENT_OUTS = 1U << 13, + IR_GRAPH_STATE_CONSISTENT_LOOPINFO = 1U << 14, + IR_GRAPH_STATE_CONSISTENT_ENTITY_USAGE = 1U << 15, + IR_GRAPH_STATE_VALID_EXTENDED_BLOCKS = 1U << 16, + IR_GRAPH_STATE_BROKEN_FOR_VERIFIER = 1U << 17, } ir_graph_state_t; ENUM_BITSET(ir_graph_state_t) diff --git a/ir/ir/unreachable.c b/ir/ir/unreachable.c index 780ac54d6..15692ec23 100644 --- a/ir/ir/unreachable.c +++ b/ir/ir/unreachable.c @@ -66,5 +66,7 @@ void remove_unreachable_blocks(ir_graph *irg) if (changed) { edges_deactivate(irg); set_irg_outs_inconsistent(irg); + clear_irg_state(irg, IR_GRAPH_STATE_NO_BAD_BLOCKS); } + set_irg_state(irg, IR_GRAPH_STATE_NO_UNREACHABLE_BLOCKS); } diff --git a/ir/opt/opt_manage.c b/ir/opt/opt_manage.c new file mode 100644 index 000000000..8e256c8ab --- /dev/null +++ b/ir/opt/opt_manage.c @@ -0,0 +1,97 @@ +#include "config.h" + +#include +#include + +#include "irgraph_t.h" + +#include "iroptimize.h" +#include "irgopt.h" +#include "irdom.h" +#include "iredges.h" +#include "irouts.h" +#include "irverify.h" +#include "irdump.h" +#include "opt_manage.h" + +// TODO some API to enable dumping +static const bool dump_opts = false; + +static void deactivate_entity_usage(ir_graph *irg) +{ + set_irg_entity_usage_state(irg, ir_entity_usage_not_computed); +} + +static void nop(ir_graph *irg) { + (void)irg; +} + +void perform_irg_optimization(ir_graph *irg, optdesc_t *opt) +{ + ir_graph_state_t new_irg_state; + ir_graph_state_t required = opt->requirements; + const bool dump = get_irp_optimization_dumps(); + + /* no bad block requires no unreachable code */ + if (required & IR_GRAPH_STATE_NO_BAD_BLOCKS) + required |= IR_GRAPH_STATE_NO_UNREACHABLE_BLOCKS; + + /** Some workarounds because information is currently duplicated */ + // FIXME should not be necessary! + if (dom_inconsistent == get_irg_dom_state(irg)) + clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_DOMINANCE); + if (outs_inconsistent == get_irg_outs_state(irg)) + clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_OUTS); + if (loopinfo_inconsistent == get_irg_loopinfo_state(irg)) + clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_LOOPINFO); + if (is_irg_state(irg, IR_GRAPH_STATE_BAD_BLOCK)) + clear_irg_state(irg, IR_GRAPH_STATE_NO_BAD_BLOCKS); + if (ir_entity_usage_not_computed == get_irg_entity_usage_state(irg)) + clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_ENTITY_USAGE); + clear_irg_state(irg, IR_GRAPH_STATE_NO_UNREACHABLE_BLOCKS); // FIXME seems to incorrect sometimes + + /* assure that all requirements for the optimization are fulfilled */ +#define PREPARE(st,func) if (st & (required ^ irg->state)) {func(irg); set_irg_state(irg,st);} + PREPARE(IR_GRAPH_STATE_ONE_RETURN, normalize_one_return) + PREPARE(IR_GRAPH_STATE_NO_CRITICAL_EDGES, remove_critical_cf_edges) + PREPARE(IR_GRAPH_STATE_NO_UNREACHABLE_BLOCKS, remove_unreachable_blocks) + PREPARE(IR_GRAPH_STATE_NO_BAD_BLOCKS, remove_bads) + PREPARE(IR_GRAPH_STATE_CONSISTENT_DOMINANCE, assure_doms) + PREPARE(IR_GRAPH_STATE_CONSISTENT_POSTDOMINANCE, assure_postdoms) + PREPARE(IR_GRAPH_STATE_CONSISTENT_OUT_EDGES, edges_assure) + PREPARE(IR_GRAPH_STATE_CONSISTENT_OUTS, assure_irg_outs) + PREPARE(IR_GRAPH_STATE_CONSISTENT_LOOPINFO, assure_cf_loop) + PREPARE(IR_GRAPH_STATE_CONSISTENT_ENTITY_USAGE, assure_irg_entity_usage_computed) + PREPARE(IR_GRAPH_STATE_VALID_EXTENDED_BLOCKS, compute_extbb) + + /* now all the requirements for the optimization are fulfilled */ + if (dump_opts) + dump_ir_graph(irg, opt->name); + + new_irg_state = opt->optimization(irg); + + if (dump_opts) + dump_ir_graph(irg, opt->name); + + /* unless the optimization returned that some state is retained, + * we disable the corresponding irg state. + * Since we currently duplicate information, sometimes another func must be called too. + */ +#define INVALIDATE(state,func) if (!(state & new_irg_state)) {clear_irg_state(irg,state); func(irg);} + INVALIDATE(IR_GRAPH_STATE_NO_CRITICAL_EDGES, nop) + INVALIDATE(IR_GRAPH_STATE_NO_UNREACHABLE_BLOCKS, nop) + INVALIDATE(IR_GRAPH_STATE_NO_BAD_BLOCKS, nop) + INVALIDATE(IR_GRAPH_STATE_ONE_RETURN, nop) + INVALIDATE(IR_GRAPH_STATE_CONSISTENT_DOMINANCE, set_irg_doms_inconsistent) + INVALIDATE(IR_GRAPH_STATE_CONSISTENT_POSTDOMINANCE, set_irg_postdoms_inconsistent) + INVALIDATE(IR_GRAPH_STATE_CONSISTENT_OUTS, set_irg_outs_inconsistent) + INVALIDATE(IR_GRAPH_STATE_CONSISTENT_OUT_EDGES, edges_deactivate) + INVALIDATE(IR_GRAPH_STATE_CONSISTENT_LOOPINFO, set_irg_loopinfo_inconsistent) + INVALIDATE(IR_GRAPH_STATE_CONSISTENT_ENTITY_USAGE, deactivate_entity_usage) + INVALIDATE(IR_GRAPH_STATE_VALID_EXTENDED_BLOCKS, set_irg_extblk_inconsistent) + + if (!(new_irg_state & IR_GRAPH_STATE_BROKEN_FOR_VERIFIER)) { + irg_verify(irg, VERIFY_ENFORCE_SSA); + } + +} diff --git a/ir/opt/opt_manage.h b/ir/opt/opt_manage.h new file mode 100644 index 000000000..21e18647a --- /dev/null +++ b/ir/opt/opt_manage.h @@ -0,0 +1,28 @@ +#include "config.h" + +#include + +#include "irgraph_t.h" + +typedef struct optdesc_t { + /** + * The short name of the optimization + * + * Should not contain spaces, since it is used for the dumper filenames. + */ + const char * const name; + + /** + * required irg_state for this optimization + */ + ir_graph_state_t requirements; + + /** + * The optimization function itself + * + * @returns zero by default; set some flags, if you guarantee some irg_state properties + **/ + ir_graph_state_t (*const optimization)(ir_graph *irg); +} optdesc_t; + +void perform_irg_optimization(ir_graph *irg, optdesc_t *opt); -- 2.20.1