From 7a483ab981d403222150c320242adaad13d60af9 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Fri, 15 Jun 2012 14:55:46 +0200 Subject: [PATCH] remove opt_manage, provide assure_irg_properties The opt_manage framework didn't really do much except assuring that some analysis info is computed before a pass starts. We can achieve this simpler by providing an assure_irg_properties function. This commit also fixes some places where analysis info was potentially not invalidated before. --- include/libfirm/irgraph.h | 58 +++++++++++++++--- include/libfirm/irprog.h | 6 -- ir/ana/irconsconfirm.c | 26 +++----- ir/ana/irmemory.c | 5 +- ir/ir/iredges.c | 2 + ir/ir/irgraph.c | 42 +++++++++++++ ir/ir/irprog.c | 10 ---- ir/ir/irprog_t.h | 16 ----- ir/ir/irtypes.h | 1 - ir/ir/rm_bads.c | 1 + ir/ir/rm_tuples.c | 1 + ir/ir/unreachable.c | 15 +++-- ir/opt/boolopt.c | 26 ++------ ir/opt/cfopt.c | 24 +++----- ir/opt/code_placement.c | 46 +++----------- ir/opt/combo.c | 21 +++---- ir/opt/convopt.c | 21 +++---- ir/opt/escape_ana.c | 7 ++- ir/opt/fp-vrp.c | 29 +++------ ir/opt/funccall.c | 38 +++++++----- ir/opt/gvn_pre.c | 19 +++--- ir/opt/ifconv.c | 24 ++++---- ir/opt/jumpthreading.c | 43 ++++++-------- ir/opt/ldstopt.c | 38 +++++------- ir/opt/local.c | 15 +---- ir/opt/loop.c | 44 ++++---------- ir/opt/opt_frame.c | 47 +++++++-------- ir/opt/opt_inline.c | 11 ++-- ir/opt/opt_ldst.c | 122 ++++---------------------------------- ir/opt/opt_manage.c | 74 ----------------------- ir/opt/opt_manage.h | 61 ------------------- ir/opt/opt_osr.c | 29 +++++---- ir/opt/parallelize_mem.c | 17 +----- ir/opt/reassoc.c | 15 ++--- ir/opt/return.c | 34 +++++++---- ir/opt/scalar_replace.c | 22 +++---- ir/opt/tailrec.c | 55 ++++++++--------- 37 files changed, 361 insertions(+), 704 deletions(-) delete mode 100644 ir/opt/opt_manage.c delete mode 100644 ir/opt/opt_manage.h diff --git a/include/libfirm/irgraph.h b/include/libfirm/irgraph.h index c5a73f12b..5fbe89c50 100644 --- a/include/libfirm/irgraph.h +++ b/include/libfirm/irgraph.h @@ -464,31 +464,58 @@ typedef enum ir_graph_properties_t { IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES = 1U << 0, /** graph contains no Bad nodes */ IR_GRAPH_PROPERTY_NO_BADS = 1U << 1, + /** No tuple nodes exist in the graph */ + IR_GRAPH_PROPERTY_NO_TUPLES = 1U << 2, /** * there exists no (obviously) unreachable code in the graph. * Unreachable in this context is code that you can't reach by following * execution flow from the start block. */ - IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE = 1U << 2, + IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE = 1U << 3, /** graph contains at most one return */ - IR_GRAPH_PROPERTY_ONE_RETURN = 1U << 3, + IR_GRAPH_PROPERTY_ONE_RETURN = 1U << 4, /** dominance information about the graph is valid */ - IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE = 1U << 4, + IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE = 1U << 5, /** postdominance information about the graph is valid */ - IR_GRAPH_PROPERTY_CONSISTENT_POSTDOMINANCE = 1U << 5, + IR_GRAPH_PROPERTY_CONSISTENT_POSTDOMINANCE = 1U << 6, /** * out edges (=iredges) are enable and there is no dead code that can be * reached by following them */ - IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES = 1U << 6, + IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES = 1U << 7, /** outs (irouts) are computed and up to date */ - IR_GRAPH_PROPERTY_CONSISTENT_OUTS = 1U << 7, + IR_GRAPH_PROPERTY_CONSISTENT_OUTS = 1U << 8, /** loopinfo is computed and up to date */ - IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO = 1U << 8, + IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO = 1U << 9, /** entity usage information is computed and up to date */ - IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE = 1U << 9, + IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE = 1U << 10, /** graph contains as many returns as possible */ - IR_GRAPH_PROPERTY_MANY_RETURNS = 1U << 10, + IR_GRAPH_PROPERTY_MANY_RETURNS = 1U << 11, + + /** + * List of all graph properties that are only affected byt control flow + * changes. + */ + IR_GRAPH_PROPERTIES_CONTROL_FLOW = + IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES + | IR_GRAPH_PROPERTY_ONE_RETURN + | IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE + | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO + | IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE + | IR_GRAPH_PROPERTY_CONSISTENT_POSTDOMINANCE, + + /** + * List of all graph properties. + */ + IR_GRAPH_PROPERTIES_ALL = + IR_GRAPH_PROPERTIES_CONTROL_FLOW + | IR_GRAPH_PROPERTY_NO_BADS + | IR_GRAPH_PROPERTY_NO_TUPLES + | IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES + | IR_GRAPH_PROPERTY_CONSISTENT_OUTS + | IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE + | IR_GRAPH_PROPERTY_MANY_RETURNS, + } ir_graph_properties_t; ENUM_BITSET(ir_graph_properties_t) @@ -520,6 +547,19 @@ FIRM_API unsigned get_irg_fp_model(const ir_graph *irg); /** Sets a floating point model for this graph. */ FIRM_API void set_irg_fp_model(ir_graph *irg, unsigned model); +/** + * Ensures that a graph fulfills all properties stated in @p state. + * Performs graph transformations if necessary. + */ +FIRM_API void assure_irg_properties(ir_graph *irg, ir_graph_properties_t props); + +/** + * Invalidates all graph properties/analysis data except the ones specified + * in @p props. + * This should be called after a transformation phase. + */ +FIRM_API void confirm_irg_properties(ir_graph *irg, ir_graph_properties_t props); + /** * Accesses custom graph data. * The data must have been registered with diff --git a/include/libfirm/irprog.h b/include/libfirm/irprog.h index 0e4906363..eba962c2f 100644 --- a/include/libfirm/irprog.h +++ b/include/libfirm/irprog.h @@ -285,12 +285,6 @@ FIRM_API size_t get_irp_n_asms(void); /** Returns the global asm include at position pos. */ FIRM_API ident *get_irp_asm(size_t pos); -/** Returns whether optimization dump vcg graphs */ -FIRM_API int get_irp_optimization_dumps(void); - -/** Enable vcg dumping of optimization */ -FIRM_API void enable_irp_optimization_dumps(void); - /** @} */ #include "end.h" diff --git a/ir/ana/irconsconfirm.c b/ir/ana/irconsconfirm.c index 5d9daa79a..783e4c305 100644 --- a/ir/ana/irconsconfirm.c +++ b/ir/ana/irconsconfirm.c @@ -42,7 +42,6 @@ #include "debug.h" #include "error.h" #include "irflag.h" -#include "opt_manage.h" /** * Walker environment. @@ -563,14 +562,16 @@ static void insert_Confirm(ir_node *node, void *data) } } -/* - * Construct Confirm nodes - */ -static ir_graph_properties_t do_construct_confirms(ir_graph *irg) +void construct_confirms(ir_graph *irg) { env_t env; FIRM_DBG_REGISTER(dbg, "firm.ana.confirm"); + assure_irg_properties(irg, + IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES + | IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE + | IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES); + assert(get_irg_pinned(irg) == op_pin_state_pinned && "Nodes must be placed to insert Confirms"); @@ -591,20 +592,8 @@ static ir_graph_properties_t do_construct_confirms(ir_graph *irg) DB((dbg, LEVEL_1, "# Const replacements: %u\n", env.num_consts)); DB((dbg, LEVEL_1, "# node equalities : %u\n", env.num_eq)); DB((dbg, LEVEL_1, "# non-null Confirms : %u\n", env.num_non_null)); - return 0; -} - -static optdesc_t opt_confirms = { - "confirms", - IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES - | IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE - | IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES, - do_construct_confirms -}; -void construct_confirms(ir_graph *irg) -{ - perform_irg_optimization(irg, &opt_confirms); + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_CONTROL_FLOW); } ir_graph_pass_t *construct_confirms_pass(const char *name) @@ -627,6 +616,7 @@ static void remove_confirm(ir_node *n, void *env) void remove_confirms(ir_graph *irg) { irg_walk_graph(irg, NULL, remove_confirm, NULL); + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_CONTROL_FLOW); } ir_graph_pass_t *remove_confirms_pass(const char *name) diff --git a/ir/ana/irmemory.c b/ir/ana/irmemory.c index dcc5daeb1..172d615ce 100644 --- a/ir/ana/irmemory.c +++ b/ir/ana/irmemory.c @@ -950,6 +950,8 @@ static void analyse_irg_entity_usage(ir_graph *irg) size_t i, n; int j, k, static_link_arg; + assure_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS); + /* set initial state to not_taken, as this is the "smallest" state */ for (i = 0, n = get_class_n_members(ft); i < n; ++i) { ir_entity *ent = get_class_member(ft, i); @@ -963,8 +965,6 @@ static void analyse_irg_entity_usage(ir_graph *irg) } } - assure_irg_outs(irg); - irg_frame = get_irg_frame(irg); for (j = get_irn_n_outs(irg_frame) - 1; j >= 0; --j) { @@ -1021,7 +1021,6 @@ static void analyse_irg_entity_usage(ir_graph *irg) } } - /* now computed */ add_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE); } diff --git a/ir/ir/iredges.c b/ir/ir/iredges.c index 1e6fe6ceb..c83d49755 100644 --- a/ir/ir/iredges.c +++ b/ir/ir/iredges.c @@ -631,6 +631,7 @@ void edges_deactivate_kind(ir_graph *irg, ir_edge_kind_t kind) ir_edgeset_destroy(&info->edges); info->allocated = 0; } + clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES); } int (edges_activated_kind)(const ir_graph *irg, ir_edge_kind_t kind) @@ -917,6 +918,7 @@ void assure_edges(ir_graph *irg) { assure_edges_kind(irg, EDGE_KIND_BLOCK); assure_edges_kind(irg, EDGE_KIND_NORMAL); + add_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES); } void assure_edges_kind(ir_graph *irg, ir_edge_kind_t kind) diff --git a/ir/ir/irgraph.c b/ir/ir/irgraph.c index fd7e9d5ae..aeea92b9c 100644 --- a/ir/ir/irgraph.c +++ b/ir/ir/irgraph.c @@ -46,6 +46,8 @@ #include "iredges_t.h" #include "type_t.h" #include "irmemory.h" +#include "iroptimize.h" +#include "irgopt.h" #define INITIAL_IDX_IRN_MAP_SIZE 1024 @@ -797,3 +799,43 @@ int (irg_has_properties)(const ir_graph *irg, ir_graph_properties_t props) { return irg_has_properties_(irg, props); } + +typedef void (*assure_property_func)(ir_graph *irg); + +void assure_irg_properties(ir_graph *irg, ir_graph_properties_t props) +{ + static struct { + ir_graph_properties_t property; + assure_property_func func; + } property_functions[] = { + { IR_GRAPH_PROPERTY_ONE_RETURN, normalize_one_return }, + { IR_GRAPH_PROPERTY_MANY_RETURNS, normalize_n_returns }, + { IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES, remove_critical_cf_edges }, + { IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE, remove_unreachable_code }, + { IR_GRAPH_PROPERTY_NO_BADS, remove_bads }, + { IR_GRAPH_PROPERTY_NO_TUPLES, remove_tuples }, + { IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE, assure_doms }, + { IR_GRAPH_PROPERTY_CONSISTENT_POSTDOMINANCE, assure_postdoms }, + { IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES, assure_edges }, + { IR_GRAPH_PROPERTY_CONSISTENT_OUTS, assure_irg_outs }, + { IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO, assure_loopinfo }, + { IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE, assure_irg_entity_usage_computed }, + }; + size_t i; + for (i = 0; i < ARRAY_SIZE(property_functions); ++i) { + ir_graph_properties_t missing = props & ~irg->properties; + if (missing & property_functions[i].property) + property_functions[i].func(irg); + } + assert((props & ~irg->properties) == IR_GRAPH_PROPERTIES_NONE); +} + +void confirm_irg_properties(ir_graph *irg, ir_graph_properties_t props) +{ + clear_irg_properties(irg, ~props); + if (! (props & IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES)) + edges_deactivate(irg); + if (! (props & IR_GRAPH_PROPERTY_CONSISTENT_OUTS) + && (irg->properties & IR_GRAPH_PROPERTY_CONSISTENT_OUTS)) + free_irg_outs(irg); +} diff --git a/ir/ir/irprog.c b/ir/ir/irprog.c index 8dd3767aa..13de01263 100644 --- a/ir/ir/irprog.c +++ b/ir/ir/irprog.c @@ -398,16 +398,6 @@ ident *get_irp_asm(size_t pos) return irp->global_asms[pos]; } -int (get_irp_optimization_dumps)(void) -{ - return get_irp_optimization_dumps_(); -} - -void (enable_irp_optimization_dumps)(void) -{ - enable_irp_optimization_dumps_(); -} - #ifndef NDEBUG void irp_reserve_resources(ir_prog *irp, irp_resources_t resources) { diff --git a/ir/ir/irprog_t.h b/ir/ir/irprog_t.h index 311eb5075..c17a5bad0 100644 --- a/ir/ir/irprog_t.h +++ b/ir/ir/irprog_t.h @@ -103,20 +103,6 @@ static inline ir_label_t get_irp_next_label_nr_(void) return ++irp->last_label_nr; } -/** Whether optimizations should dump irgs */ -static inline int get_irp_optimization_dumps_(void) -{ - assert(irp); - return irp->optimization_dumps; -} - -/** Set optimizations to dump irgs */ -static inline void enable_irp_optimization_dumps_(void) -{ - assert(irp); - irp->optimization_dumps = 1; -} - void set_irp_ip_outedges(ir_node ** ip_outedges); ir_node** get_irp_ip_outedges(void); @@ -143,7 +129,5 @@ void remove_irp_type(ir_type *typ); #define get_glob_type() get_glob_type_() #define get_tls_type() get_tls_type_() #define get_irp_next_label_nr() get_irp_next_label_nr_() -#define get_irp_optimization_dumps() get_irp_optimization_dumps_() -#define enable_irp_optimization_dumps() enable_irp_optimization_dumps_() #endif diff --git a/ir/ir/irtypes.h b/ir/ir/irtypes.h index 880b6d452..060ce3254 100644 --- a/ir/ir/irtypes.h +++ b/ir/ir/irtypes.h @@ -652,7 +652,6 @@ struct ir_prog { size_t max_irg_idx; /**< highest unused irg index */ long max_node_nr; /**< to generate unique numbers for nodes. */ unsigned dump_nr; /**< number of program info dumps */ - unsigned optimization_dumps :1; /**< dump irg on each optimization */ #ifndef NDEBUG irp_resources_t reserved_resources; /**< Bitset for tracking used global resources. */ #endif diff --git a/ir/ir/rm_bads.c b/ir/ir/rm_bads.c index 7a39fa887..ad5aadf33 100644 --- a/ir/ir/rm_bads.c +++ b/ir/ir/rm_bads.c @@ -146,4 +146,5 @@ void remove_bads(ir_graph *irg) clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS); clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE); } + add_irg_properties(irg, IR_GRAPH_PROPERTY_NO_BADS); } diff --git a/ir/ir/rm_tuples.c b/ir/ir/rm_tuples.c index adc6d8da1..dc9f06ec3 100644 --- a/ir/ir/rm_tuples.c +++ b/ir/ir/rm_tuples.c @@ -57,4 +57,5 @@ static void exchange_tuple_projs(ir_node *node, void *env) void remove_tuples(ir_graph *irg) { irg_walk_graph(irg, exchange_tuple_projs, NULL, NULL); + add_irg_properties(irg, IR_GRAPH_PROPERTY_NO_TUPLES); } diff --git a/ir/ir/unreachable.c b/ir/ir/unreachable.c index ce36b0ee7..a66a054db 100644 --- a/ir/ir/unreachable.c +++ b/ir/ir/unreachable.c @@ -117,17 +117,16 @@ void remove_unreachable_code(ir_graph *irg) { bool changed = false; - assure_doms(irg); + assure_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE); irg_walk_graph(irg, unreachable_to_bad, NULL, &changed); remove_unreachable_keeps(irg); - if (changed) { - edges_deactivate(irg); - clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS - | IR_GRAPH_PROPERTY_NO_BADS - | IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES - | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO); - } + confirm_irg_properties(irg, changed + ? IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES + | IR_GRAPH_PROPERTY_NO_TUPLES + | IR_GRAPH_PROPERTY_ONE_RETURN + | IR_GRAPH_PROPERTY_MANY_RETURNS + : IR_GRAPH_PROPERTIES_ALL); add_irg_properties(irg, IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE); } diff --git a/ir/opt/boolopt.c b/ir/opt/boolopt.c index b6e80c1f0..1ca652717 100644 --- a/ir/opt/boolopt.c +++ b/ir/opt/boolopt.c @@ -38,7 +38,6 @@ #include "tv.h" #include "irpass.h" #include "debug.h" -#include "opt_manage.h" /** Describes a pair of relative conditions lo < hi, lo rel_lo x, hi rel_hi x */ typedef struct cond_pair { @@ -716,10 +715,9 @@ restart: } } -static ir_graph_properties_t do_simplify_bool(ir_graph *const irg) +void opt_bool(ir_graph *const irg) { bool_opt_env_t env; - ir_graph_properties_t res = 0; /* register a debug mask */ FIRM_DBG_REGISTER(dbg, "firm.opt.bool"); @@ -729,30 +727,14 @@ static ir_graph_properties_t do_simplify_bool(ir_graph *const irg) /* optimize simple Andb and Orb cases */ irg_walk_graph(irg, NULL, bool_walk, &env); - ir_reserve_resources(irg, IR_RESOURCE_BLOCK_MARK | IR_RESOURCE_PHI_LIST); - /* now more complicated cases: find control flow And/Or and optimize. */ + ir_reserve_resources(irg, IR_RESOURCE_BLOCK_MARK | IR_RESOURCE_PHI_LIST); irg_walk_graph(irg, clear_block_infos, collect_phis, NULL); irg_block_walk_graph(irg, NULL, find_cf_and_or_walker, &env); - - if (! env.changed) { - res |= IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE; - } - ir_free_resources(irg, IR_RESOURCE_BLOCK_MARK | IR_RESOURCE_PHI_LIST); - return res; -} - -static optdesc_t opt_simplify_bool = { - "bool-simplification", - IR_GRAPH_PROPERTY_ONE_RETURN, /* works better with one return block only */ - do_simplify_bool, -}; - -void opt_bool(ir_graph *irg) -{ - perform_irg_optimization(irg, &opt_simplify_bool); + confirm_irg_properties(irg, + env.changed ? IR_GRAPH_PROPERTIES_NONE : IR_GRAPH_PROPERTIES_ALL); } /* Creates an ir_graph pass for opt_bool. */ diff --git a/ir/opt/cfopt.c b/ir/opt/cfopt.c index aa5e01d5f..f6817652b 100644 --- a/ir/opt/cfopt.c +++ b/ir/opt/cfopt.c @@ -46,7 +46,6 @@ #include "irdump.h" #include "irverify.h" #include "iredges.h" -#include "opt_manage.h" #include "array_t.h" @@ -809,12 +808,13 @@ static void cfgopt_ignoring_phis(ir_graph *irg) irg_block_walk_graph(irg, NULL, optimize_ifs, &env); if (env.changed) { - clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE); + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_NONE); /* clear block info, because it must be recomputed */ irg_block_walk_graph(irg, clear_block_info, NULL, &env.block_infos); /* Removing blocks and Conds might enable more optimizations */ continue; } else { + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_ALL); break; } } @@ -823,7 +823,7 @@ static void cfgopt_ignoring_phis(ir_graph *irg) } /* Optimizations of the control flow that also require changes of Phi nodes. */ -static ir_graph_properties_t do_cfopt(ir_graph *irg) +void optimize_cf(ir_graph *irg) { int i, j, n; ir_node **in = NULL; @@ -840,7 +840,7 @@ static ir_graph_properties_t do_cfopt(ir_graph *irg) assert(get_irg_pinned(irg) != op_pin_state_floats && "Control flow optimization need a pinned graph"); - edges_deactivate(irg); + assure_irg_properties(irg, IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE); /* First the "simple" optimizations, which do not touch Phis */ cfgopt_ignoring_phis(irg); @@ -866,7 +866,7 @@ static ir_graph_properties_t do_cfopt(ir_graph *irg) * It walks only over block nodes and adapts these and the Phi nodes in * these blocks, which it finds in a linked list computed before. */ - assure_doms(irg); + assure_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE); irg_block_walk_graph(irg, optimize_blocks, merge_blocks, &env); new_end = optimize_in_place(end); @@ -915,18 +915,8 @@ static ir_graph_properties_t do_cfopt(ir_graph *irg) } } - return 0; -} - -static optdesc_t opt_cf = { - "control-flow", - IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE, - do_cfopt, -}; - -void optimize_cf(ir_graph *irg) -{ - perform_irg_optimization(irg, &opt_cf); + confirm_irg_properties(irg, + env.changed ? IR_GRAPH_PROPERTIES_NONE : IR_GRAPH_PROPERTIES_ALL); } /* Creates an ir_graph pass for optimize_cf. */ diff --git a/ir/opt/code_placement.c b/ir/opt/code_placement.c index 9c048d15f..c074dd060 100644 --- a/ir/opt/code_placement.c +++ b/ir/opt/code_placement.c @@ -38,7 +38,6 @@ #include "irouts.h" #include "irgopt.h" #include "irpass.h" -#include "opt_manage.h" static bool is_block_reachable(ir_node *block) { @@ -396,12 +395,18 @@ static void place_late(ir_graph *irg, waitq *worklist) } /* Code Placement. */ -static ir_graph_properties_t do_codeplacement(ir_graph *irg) +void place_code(ir_graph *irg) { waitq *worklist; /* Handle graph state */ assert(get_irg_phase_state(irg) != phase_building); + assure_irg_properties(irg, + IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES | + IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE | + IR_GRAPH_PROPERTY_CONSISTENT_OUTS | + IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE | + IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO); /* Place all floating nodes as early as possible. This guarantees a legal code placement. */ @@ -419,22 +424,7 @@ static ir_graph_properties_t do_codeplacement(ir_graph *irg) place_late(irg, worklist); del_waitq(worklist); - return 0; -} - -static optdesc_t opt_codeplacement = { - "code-placement", - IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES | - IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE | - IR_GRAPH_PROPERTY_CONSISTENT_OUTS | - IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE | - IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO, - do_codeplacement, -}; - -void place_code(ir_graph *irg) -{ - perform_irg_optimization(irg, &opt_codeplacement); + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_NONE); } /** @@ -448,26 +438,6 @@ static void place_code_wrapper(ir_graph *irg) set_opt_global_cse(0); } -#if 0 -static ir_graph_properties_t do_gcse(ir_graph *irg) -{ - set_opt_global_cse(1); - optimize_graph_df(irg); - do_codeplacement(irg); - set_opt_global_cse(0); - return 0; -} - -static optdesc_t opt_gcse = { - "gcse", - IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES | - IR_GRAPH_PROPERTY_CONSISTENT_OUTS | - IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE | - IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO, - do_gcse, -}; -#endif - ir_graph_pass_t *place_code_pass(const char *name) { return def_graph_pass(name ? name : "place", place_code_wrapper); diff --git a/ir/opt/combo.c b/ir/opt/combo.c index f8e05d8f2..3e834b2f5 100644 --- a/ir/opt/combo.c +++ b/ir/opt/combo.c @@ -83,7 +83,6 @@ #include "irpass.h" #include "tv_t.h" #include "irtools.h" -#include "opt_manage.h" #include "irprintf.h" #include "irdump.h" @@ -3512,7 +3511,7 @@ static void add_memory_keeps(ir_node **kept_memory, size_t len) ir_nodeset_destroy(&set); } /* add_memory_keeps */ -static ir_graph_properties_t do_combo(ir_graph *irg) +void combo(ir_graph *irg) { environment_t env; ir_node *initial_bl; @@ -3520,6 +3519,11 @@ static ir_graph_properties_t do_combo(ir_graph *irg) ir_graph *rem = current_ir_graph; size_t len; + assure_irg_properties(irg, + IR_GRAPH_PROPERTY_NO_BADS + | IR_GRAPH_PROPERTY_CONSISTENT_OUTS + | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO); + current_ir_graph = irg; /* register a debug mask */ @@ -3622,20 +3626,9 @@ static ir_graph_properties_t do_combo(ir_graph *irg) set_value_of_func(NULL); current_ir_graph = rem; - return 0; // cannot guarantee anything + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_NONE); } /* combo */ -static optdesc_t opt_combo = { - "combo", - IR_GRAPH_PROPERTY_NO_BADS | IR_GRAPH_PROPERTY_CONSISTENT_OUTS | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO, - do_combo, -}; - -void combo(ir_graph *irg) -{ - perform_irg_optimization(irg, &opt_combo); -} - /* Creates an ir_graph pass for combo. */ ir_graph_pass_t *combo_pass(const char *name) { diff --git a/ir/opt/convopt.c b/ir/opt/convopt.c index 27518bb7f..ee9b382de 100644 --- a/ir/opt/convopt.c +++ b/ir/opt/convopt.c @@ -53,7 +53,6 @@ #include "irpass_t.h" #include "tv.h" #include "vrp.h" -#include "opt_manage.h" DEBUG_ONLY(static firm_dbg_module_t *dbg;) @@ -303,31 +302,25 @@ static void conv_opt_walker(ir_node *node, void *data) } } -static ir_graph_properties_t do_deconv(ir_graph *irg) +void conv_opt(ir_graph *irg) { + bool global_changed = false; bool changed; FIRM_DBG_REGISTER(dbg, "firm.opt.conv"); + assure_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES); + DB((dbg, LEVEL_1, "===> Performing conversion optimization on %+F\n", irg)); do { changed = false; irg_walk_graph(irg, NULL, conv_opt_walker, &changed); local_optimize_graph(irg); + global_changed |= changed; } while (changed); - return 0; -} - -static optdesc_t opt_deconv = { - "deconv", - IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES, - do_deconv, -}; - -void conv_opt(ir_graph *irg) -{ - perform_irg_optimization(irg, &opt_deconv); + confirm_irg_properties(irg, + global_changed ? IR_GRAPH_PROPERTIES_NONE : IR_GRAPH_PROPERTIES_ALL); } /* Creates an ir_graph pass for conv_opt. */ diff --git a/ir/opt/escape_ana.c b/ir/opt/escape_ana.c index 5c9094349..cba1a581e 100644 --- a/ir/opt/escape_ana.c +++ b/ir/opt/escape_ana.c @@ -450,8 +450,7 @@ static void transform_allocs(ir_graph *irg, walk_env_t *env) /* if allocs were removed somehow */ if (env->nr_removed && env->nr_deads) { - /* exception control flow might have been changed */ - clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE); + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_NONE); } } @@ -484,6 +483,8 @@ static void transform_alloc_calls(ir_graph *irg, walk_env_t *env) for (call = env->found_allocs; call; call = next) { next = (ir_node*)get_irn_link(call); } + + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_NONE); } @@ -551,7 +552,7 @@ void escape_analysis(int run_scalar_replace, check_alloc_entity_func callback) for (i = 0, n = get_irp_n_irgs(); i < n; ++i) { ir_graph *irg = get_irp_irg(i); - assure_irg_outs(irg); + assure_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS); if (callback) { /* search for Calls */ diff --git a/ir/opt/fp-vrp.c b/ir/opt/fp-vrp.c index 70e82e6d5..cf2595b8c 100644 --- a/ir/opt/fp-vrp.c +++ b/ir/opt/fp-vrp.c @@ -43,7 +43,6 @@ #include "tv.h" #include "irpass.h" #include "irmemory.h" -#include "opt_manage.h" /* TODO: * - Implement cleared/set bit calculation for Add, Sub, Minus, Mul, Div, Mod, Shl, Shr, Shrs, Rotl @@ -837,14 +836,19 @@ static void build_phi_lists(ir_node *irn, void *env) add_Block_phi(get_nodes_block(irn), irn); } -static ir_graph_properties_t do_fixpoint_vrp(ir_graph* const irg) +void fixpoint_vrp(ir_graph* const irg) { environment_t env; - ir_graph_properties_t res = 0; FIRM_DBG_REGISTER(dbg, "firm.opt.fp-vrp"); DB((dbg, LEVEL_1, "===> Performing constant propagation on %+F\n", irg)); + assure_irg_properties(irg, + IR_GRAPH_PROPERTY_NO_BADS + | IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE + | IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE + | IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES); + obstack_init(&obst); ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_PHI_LIST); @@ -879,26 +883,11 @@ static ir_graph_properties_t do_fixpoint_vrp(ir_graph* const irg) env.modified = 0; irg_walk_graph(irg, NULL, apply_result, &env); - if (! env.modified) { - res |= IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE | IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE; - } - ir_free_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_PHI_LIST); obstack_free(&obst, NULL); - - return res; -} - -static optdesc_t opt_fpvrp = { - "fp-vrp", - IR_GRAPH_PROPERTY_NO_BADS | IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE | IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE | IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES, - do_fixpoint_vrp, -}; - -void fixpoint_vrp(ir_graph* const irg) -{ - perform_irg_optimization(irg, &opt_fpvrp); + confirm_irg_properties(irg, + env.modified ? IR_GRAPH_PROPERTIES_NONE : IR_GRAPH_PROPERTIES_ALL); } ir_graph_pass_t *fixpoint_vrp_irg_pass(const char *name) diff --git a/ir/opt/funccall.c b/ir/opt/funccall.c index 214260b98..5f19c590d 100644 --- a/ir/opt/funccall.c +++ b/ir/opt/funccall.c @@ -25,6 +25,7 @@ #include "config.h" #include "opt_init.h" +#include #include "irnode_t.h" #include "irgraph_t.h" @@ -637,8 +638,13 @@ static void handle_const_Calls(env_t *ctx) if (ctx->float_const_call_list != NULL) fix_const_call_lists(irg, ctx); ir_free_resources(irg, IR_RESOURCE_IRN_LINK); + + confirm_irg_properties(irg, + IR_GRAPH_PROPERTIES_CONTROL_FLOW + | IR_GRAPH_PROPERTY_ONE_RETURN + | IR_GRAPH_PROPERTY_MANY_RETURNS); } -} /* handle_const_Calls */ +} /** * Handle calls to nothrow functions. @@ -697,7 +703,7 @@ static mtp_additional_properties update_property(mtp_additional_properties orig_ /** * Check if a node is stored. */ -static int is_stored(const ir_node *n) +static bool is_stored(const ir_node *n) { const ir_edge_t *edge; const ir_node *ptr; @@ -713,14 +719,14 @@ static int is_stored(const ir_node *n) break; case iro_Store: if (get_Store_value(succ) == n) - return 1; + return true; /* ok if its only the address input */ break; case iro_Sel: case iro_Cast: case iro_Confirm: if (is_stored(succ)) - return 1; + return true; break; case iro_Call: ptr = get_Call_ptr(succ); @@ -734,22 +740,22 @@ static int is_stored(const ir_node *n) /* n is the i'th param of the call */ if (get_method_param_access(ent, i) & ptr_access_store) { /* n is store in ent */ - return 1; + return true; } } } } else { /* unknown call address */ - return 1; + return true; } break; default: /* bad, potential alias */ - return 1; + return true; } } - return 0; -} /* is_stored */ + return false; +} /** * Check that the return value of an irg is not stored anywhere. @@ -761,7 +767,8 @@ static mtp_additional_properties check_stored_result(ir_graph *irg) ir_node *end_blk = get_irg_end_block(irg); int i; mtp_additional_properties res = ~mtp_no_property; - assure_edges_kind(irg, EDGE_KIND_NORMAL); + + assure_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES); for (i = get_Block_n_cfgpreds(end_blk) - 1; i >= 0; --i) { ir_node *pred = get_Block_cfgpred(end_blk, i); @@ -780,7 +787,7 @@ static mtp_additional_properties check_stored_result(ir_graph *irg) } } finish: - edges_deactivate_kind(irg, EDGE_KIND_NORMAL); + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_ALL); return res; } @@ -980,11 +987,13 @@ static mtp_additional_properties check_nothrow_or_malloc(ir_graph *irg, int top) static void check_for_possible_endless_loops(ir_graph *irg) { ir_loop *root_loop; - assure_loopinfo(irg); + assure_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO); root_loop = get_irg_loop(irg); if (root_loop->flags & loop_outer_loop) add_irg_additional_properties(irg, mtp_property_has_loop); + + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_ALL); } /* @@ -1047,9 +1056,10 @@ void optimize_funccalls(void) } handle_const_Calls(&ctx); - DB((dbg, LEVEL_1, "Detected %zu const graphs, %zu pure graphs.\n", num_const, num_pure)); + DB((dbg, LEVEL_1, "Detected %zu const graphs, %zu pure graphs.\n", + num_const, num_pure)); DB((dbg, LEVEL_1, "Optimizes %u(SymConst) + %u(Sel) calls to const functions.\n", - ctx.n_calls_SymConst, ctx.n_calls_Sel)); + ctx.n_calls_SymConst, ctx.n_calls_Sel)); xfree(busy_set); xfree(ready_set); diff --git a/ir/opt/gvn_pre.c b/ir/opt/gvn_pre.c index a028d338d..fa7f3b246 100644 --- a/ir/opt/gvn_pre.c +++ b/ir/opt/gvn_pre.c @@ -1148,19 +1148,17 @@ void do_gvn_pre(ir_graph *irg) unsigned antic_iter; unsigned insert_iter; + assure_irg_properties(irg, + IR_GRAPH_PROPERTY_CONSISTENT_OUTS + | IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES + | IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE + | IR_GRAPH_PROPERTY_CONSISTENT_POSTDOMINANCE); + /* register a debug mask */ FIRM_DBG_REGISTER(dbg, "firm.opt.gvn_pre"); /* edges will crash if enabled due to our allocate on other obstack trick */ edges_deactivate(irg); - /* algorithm preconditions */ - remove_critical_cf_edges(irg); - /* we get all nodes of a block by following outs */ - assure_irg_outs(irg); - /* we need dominator for Antic_out calculation */ - compute_doms(irg); - compute_postdoms(irg); - save_optimization_state(&state); /* CSE pass @@ -1245,10 +1243,11 @@ void do_gvn_pre(ir_graph *irg) set_irg_pinned(irg, op_pin_state_pinned); restore_optimization_state(&state); -} /* do_gvn_pre */ + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_NONE); +} /* Creates an ir_graph pass for do_gvn_pre. */ ir_graph_pass_t *do_gvn_pre_pass(const char *name) { return def_graph_pass(name ? name : "gvn_pre", do_gvn_pre); -} /* do_gvn_pre_pass */ +} diff --git a/ir/opt/ifconv.c b/ir/opt/ifconv.c index 3b35074ec..1bc7f13c9 100644 --- a/ir/opt/ifconv.c +++ b/ir/opt/ifconv.c @@ -39,7 +39,6 @@ #include "array_t.h" #include "irpass_t.h" #include "be.h" -#include "opt_manage.h" #include "irdump.h" #include "debug.h" @@ -464,11 +463,17 @@ static void collect_phis(ir_node *node, void *env) } } -static ir_graph_properties_t do_ifconv(ir_graph *irg) +void opt_if_conv(ir_graph *irg) { walker_env env; const backend_params *be_params = be_get_backend_param(); + assure_irg_properties(irg, + IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES + | IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE + | IR_GRAPH_PROPERTY_NO_BADS + | IR_GRAPH_PROPERTY_ONE_RETURN); + /* get the parameters */ env.allow_ifconv = be_params->allow_ifconv; env.changed = false; @@ -493,18 +498,9 @@ static ir_graph_properties_t do_ifconv(ir_graph *irg) free_cdep(irg); - return IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES | IR_GRAPH_PROPERTY_ONE_RETURN; -} - -static optdesc_t opt_ifconv = { - "if-conversion", - IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES | IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE | IR_GRAPH_PROPERTY_NO_BADS | IR_GRAPH_PROPERTY_ONE_RETURN, - do_ifconv, -}; - -void opt_if_conv(ir_graph *irg) -{ - perform_irg_optimization(irg, &opt_ifconv); + confirm_irg_properties(irg, + IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES + | IR_GRAPH_PROPERTY_ONE_RETURN); } ir_graph_pass_t *opt_if_conv_pass(const char *name) diff --git a/ir/opt/jumpthreading.c b/ir/opt/jumpthreading.c index 6253b6d59..eeca132b4 100644 --- a/ir/opt/jumpthreading.c +++ b/ir/opt/jumpthreading.c @@ -28,6 +28,7 @@ #include "iroptimize.h" #include +#include #include "array_t.h" #include "debug.h" #include "ircons.h" @@ -45,7 +46,6 @@ #include "iropt_dbg.h" #include "irpass.h" #include "vrp.h" -#include "opt_manage.h" #undef AVOID_PHIB @@ -633,7 +633,7 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump, static void thread_jumps(ir_node* block, void* data) { jumpthreading_env_t env; - int *changed = (int*)data; + bool *changed = (bool*)data; ir_node *selector; ir_node *projx; ir_node *cond; @@ -703,14 +703,14 @@ static void thread_jumps(ir_node* block, void* data) ir_graph *irg = get_irn_irg(block); ir_node *bad = new_r_Bad(irg, mode_X); exchange(projx, bad); - *changed = 1; + *changed = true; return; } else if (selector_evaluated == 1) { dbg_info *dbgi = get_irn_dbg_info(selector); ir_node *jmp = new_rd_Jmp(dbgi, get_nodes_block(projx)); DBG_OPT_JUMPTHREADING(projx, jmp); exchange(projx, jmp); - *changed = 1; + *changed = true; return; } @@ -747,13 +747,18 @@ static void thread_jumps(ir_node* block, void* data) set_Block_cfgpred(env.cnst_pred, cnst_pos, badX); /* the graph is changed now */ - *changed = 1; + *changed = true; } -static ir_graph_properties_t do_jumpthread(ir_graph* irg) +void opt_jumpthreading(ir_graph* irg) { - int changed, rerun; - ir_graph_properties_t res = 0; + bool changed; + bool rerun; + + assure_irg_properties(irg, + IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE + | IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES + | IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES); FIRM_DBG_REGISTER(dbg, "firm.opt.jumpthreading"); @@ -761,31 +766,17 @@ static ir_graph_properties_t do_jumpthread(ir_graph* irg) ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_IRN_VISITED); - changed = 0; + changed = false; do { - rerun = 0; + rerun = false; irg_block_walk_graph(irg, thread_jumps, NULL, &rerun); changed |= rerun; } while (rerun); ir_free_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_IRN_VISITED); - if (!changed) { - res |= IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE | IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE; - } - - return res; -} - -static optdesc_t opt_jumpthread = { - "jumpthreading", - IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE | IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES | IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES, - do_jumpthread, -}; - -void opt_jumpthreading(ir_graph* irg) -{ - perform_irg_optimization(irg, &opt_jumpthread); + confirm_irg_properties(irg, + changed ? IR_GRAPH_PROPERTIES_NONE : IR_GRAPH_PROPERTIES_ALL); } /* Creates an ir_graph pass for opt_jumpthreading. */ diff --git a/ir/opt/ldstopt.c b/ir/opt/ldstopt.c index 5f389dbd3..64df7f7ef 100644 --- a/ir/opt/ldstopt.c +++ b/ir/opt/ldstopt.c @@ -49,7 +49,6 @@ #include "set.h" #include "be.h" #include "debug.h" -#include "opt_manage.h" /** The debug handle. */ DEBUG_ONLY(static firm_dbg_module_t *dbg;) @@ -2081,10 +2080,16 @@ static int optimize_loops(ir_graph *irg) /* * do the load store optimization */ -static ir_graph_properties_t do_loadstore_opt(ir_graph *irg) +void optimize_load_store(ir_graph *irg) { walk_env_t env; - ir_graph_properties_t res = 0; + + assure_irg_properties(irg, + IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE + | IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES + | IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES + | IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE + | IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE); FIRM_DBG_REGISTER(dbg, "firm.opt.ldstopt"); @@ -2110,27 +2115,12 @@ static ir_graph_properties_t do_loadstore_opt(ir_graph *irg) obstack_free(&env.obst, NULL); - /* Handle graph state */ - if (env.changes) { - edges_deactivate(irg); - } - - if (!(env.changes & CF_CHANGED)) { - res |= IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE | IR_GRAPH_PROPERTY_NO_BADS; - } - - return res; -} - -static optdesc_t opt_loadstore = { - "load-store", - IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE | IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES | IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES | IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE | IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE, - do_loadstore_opt, -}; - -void optimize_load_store(ir_graph *irg) -{ - perform_irg_optimization(irg, &opt_loadstore); + confirm_irg_properties(irg, + env.changes + ? env.changes & CF_CHANGED + ? IR_GRAPH_PROPERTIES_NONE + : IR_GRAPH_PROPERTIES_CONTROL_FLOW + : IR_GRAPH_PROPERTIES_ALL); } ir_graph_pass_t *optimize_load_store_pass(const char *name) diff --git a/ir/opt/local.c b/ir/opt/local.c index cd679e724..3abb165fb 100644 --- a/ir/opt/local.c +++ b/ir/opt/local.c @@ -23,21 +23,8 @@ */ #include #include "irgopt.h" -#include "opt_manage.h" - -static ir_graph_properties_t do_optimize_graph_df(ir_graph *irg) -{ - optimize_graph_df(irg); - return 0; -} - -static optdesc_t opt_local = { - "localopts", - 0, // TODO optimize_graph_df handles preconditions itself - do_optimize_graph_df, -}; void local_opts(ir_graph *irg) { - perform_irg_optimization(irg, &opt_local); + optimize_graph_df(irg); } diff --git a/ir/opt/loop.c b/ir/opt/loop.c index 9578fc925..56a511699 100644 --- a/ir/opt/loop.c +++ b/ir/opt/loop.c @@ -44,7 +44,6 @@ #include "beutil.h" #include "irpass.h" #include "irdom.h" -#include "opt_manage.h" #include #include "irbackedge_t.h" @@ -2680,6 +2679,11 @@ void loop_optimization(ir_graph *irg) size_t i; size_t n_elements; + assure_irg_properties(irg, + IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES + | IR_GRAPH_PROPERTY_CONSISTENT_OUTS + | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO); + set_loop_params(); /* Reset stats for this procedure */ @@ -2726,56 +2730,28 @@ void loop_optimization(ir_graph *irg) DEL_ARR_F(loops); ir_free_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_PHI_LIST); + + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_NONE); } -static ir_graph_properties_t perform_loop_unrolling(ir_graph *irg) +void do_loop_unrolling(ir_graph *irg) { loop_op = loop_op_unrolling; loop_optimization(irg); - return 0; } -static ir_graph_properties_t perform_loop_inversion(ir_graph *irg) +void do_loop_inversion(ir_graph *irg) { loop_op = loop_op_inversion; loop_optimization(irg); - return 0; } -static ir_graph_properties_t perform_loop_peeling(ir_graph *irg) +void do_loop_peeling(ir_graph *irg) { loop_op = loop_op_peeling; loop_optimization(irg); - return 0; } -static optdesc_t opt_unroll_loops = { - "unroll-loops", - IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES | IR_GRAPH_PROPERTY_CONSISTENT_OUTS | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO, - perform_loop_unrolling, -}; - -static optdesc_t opt_invert_loops = { - "invert-loops", - IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES | IR_GRAPH_PROPERTY_CONSISTENT_OUTS | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO, - perform_loop_inversion, -}; - -static optdesc_t opt_peel_loops = { - "peel-loops", - IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES | IR_GRAPH_PROPERTY_CONSISTENT_OUTS | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO, - perform_loop_peeling, -}; - -void do_loop_unrolling(ir_graph *irg) -{ perform_irg_optimization(irg, &opt_unroll_loops); } - -void do_loop_inversion(ir_graph *irg) -{ perform_irg_optimization(irg, &opt_invert_loops); } - -void do_loop_peeling(ir_graph *irg) -{ perform_irg_optimization(irg, &opt_peel_loops); } - ir_graph_pass_t *loop_inversion_pass(const char *name) { return def_graph_pass(name ? name : "loop_inversion", do_loop_inversion); diff --git a/ir/opt/opt_frame.c b/ir/opt/opt_frame.c index c28abd8f1..4e7cbda8c 100644 --- a/ir/opt/opt_frame.c +++ b/ir/opt/opt_frame.c @@ -44,10 +44,13 @@ void opt_frame_irg(ir_graph *irg) ir_entity *ent, *list; ir_node *frame, *sel; size_t i, n = get_class_n_members(frame_tp); + int o; if (n <= 0) return; + assure_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS); + irp_reserve_resources(irp, IRP_RESOURCE_ENTITY_LINK); /* clear all entity links */ @@ -59,32 +62,14 @@ void opt_frame_irg(ir_graph *irg) /* look for uses */ frame = get_irg_frame(irg); - if (edges_activated(irg)) { /* use inplace edges */ - const ir_edge_t *edge; - - /* mark all used entities */ - foreach_out_edge(frame, edge) { - sel = get_edge_src_irn(edge); - if (is_Sel(sel)) { - ent = get_Sel_entity(sel); + /* mark all used entities */ + for (o = get_irn_n_outs(frame) - 1; o >= 0; --o) { + sel = get_irn_out(frame, o); + if (is_Sel(sel)) { + ent = get_Sel_entity(sel); + /* only entities on the frame */ + if (get_entity_owner(ent) == frame_tp) set_entity_link(ent, ent); - } - } - } else { - int i; - - /* use traditionally out edges */ - assure_irg_outs(irg); - - /* mark all used entities */ - for (i = get_irn_n_outs(frame) - 1; i >= 0; --i) { - sel = get_irn_out(frame, i); - if (is_Sel(sel)) { - ent = get_Sel_entity(sel); - /* only entities on the frame */ - if (get_entity_owner(ent) == frame_tp) - set_entity_link(ent, ent); - } } } @@ -109,6 +94,18 @@ void opt_frame_irg(ir_graph *irg) set_type_state(frame_tp, layout_undefined); } irp_free_resources(irp, IRP_RESOURCE_ENTITY_LINK); + + /* we changed the type, this affects none of the currently known graph + * properties, but I don't use ALL because I don't know if someone adds + * type-based properties at some point */ + confirm_irg_properties(irg, + IR_GRAPH_PROPERTIES_CONTROL_FLOW + | IR_GRAPH_PROPERTY_NO_BADS + | IR_GRAPH_PROPERTY_NO_TUPLES + | IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES + | IR_GRAPH_PROPERTY_CONSISTENT_OUTS + | IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE + | IR_GRAPH_PROPERTY_MANY_RETURNS); } ir_graph_pass_t *opt_frame_irg_pass(const char *name) diff --git a/ir/opt/opt_inline.c b/ir/opt/opt_inline.c index 87a8abb68..c23694c6b 100644 --- a/ir/opt/opt_inline.c +++ b/ir/opt/opt_inline.c @@ -961,7 +961,7 @@ static void append_call_list(inline_irg_env *dst, inline_irg_env *src, int loop_ * size are inlined. */ void inline_leaf_functions(unsigned maxsize, unsigned leafsize, - unsigned size, int ignore_runtime) + unsigned size, int ignore_runtime) { inline_irg_env *env; ir_graph *irg; @@ -994,9 +994,11 @@ void inline_leaf_functions(unsigned maxsize, unsigned leafsize, assert(get_irg_phase_state(irg) != phase_building); free_callee_info(irg); - assure_loopinfo(irg); + assure_irg_properties(irg, + IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO); wenv.x = (inline_irg_env*)get_irg_link(irg); irg_walk_graph(irg, NULL, collect_calls2, &wenv); + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_ALL); } /* -- and now inline. -- */ @@ -1121,7 +1123,8 @@ void inline_leaf_functions(unsigned maxsize, unsigned leafsize, callee_env = alloc_inline_irg_env(); set_irg_link(copy, callee_env); - assure_loopinfo(copy); + assure_irg_properties(copy, + IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO); wenv.x = callee_env; wenv.ignore_callers = 1; irg_walk_graph(copy, NULL, collect_calls2, &wenv); @@ -1659,7 +1662,7 @@ static void inline_into(ir_graph *irg, unsigned maxsize, callee_env = alloc_inline_irg_env(); set_irg_link(copy, callee_env); - assure_loopinfo(copy); + assure_irg_properties(copy, IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO); memset(&wenv, 0, sizeof(wenv)); wenv.x = callee_env; wenv.ignore_callers = 1; diff --git a/ir/opt/opt_ldst.c b/ir/opt/opt_ldst.c index 33fa793ba..24891e5b9 100644 --- a/ir/opt/opt_ldst.c +++ b/ir/opt/opt_ldst.c @@ -2060,103 +2060,6 @@ static void insert_Loads_upwards(void) DB((dbg, LEVEL_2, "Finished Load inserting after %d iterations\n", i)); } /* insert_Loads_upwards */ -/** - * Kill unreachable control flow. - * - * @param irg the graph to operate on - */ -static void kill_unreachable_blocks(ir_graph *irg) -{ - block_t *bl; - ir_node **ins; - int changed = 0; - - NEW_ARR_A(ir_node *, ins, env.max_cfg_preds); - - for (bl = env.forward; bl != NULL; bl = bl->forward_next) { - ir_node *block = bl->block; - int i, j, k, n; - - assert(get_Block_mark(block)); - - n = get_Block_n_cfgpreds(block); - - for (i = j = 0; i < n; ++i) { - ir_node *pred = get_Block_cfgpred(block, i); - ir_node *pred_bl; - - if (is_Bad(pred)) - continue; - - pred_bl = get_nodes_block(skip_Proj(pred)); - if (! get_Block_mark(pred_bl)) - continue; - - ins[j++] = pred; - } - if (j != n) { - ir_node *phi, *next; - - /* some unreachable blocks detected */ - changed = 1; - - DB((dbg, LEVEL_1, "Killing dead block predecessors on %+F\n", block)); - - set_irn_in(block, j, ins); - - /* shorten all Phi nodes */ - for (phi = get_Block_phis(block); phi != NULL; phi = next) { - next = get_Phi_next(phi); - - for (i = k = 0; i < n; ++i) { - ir_node *pred = get_Block_cfgpred_block(block, i); - - if (is_Bad(pred)) - continue; - - if (! get_Block_mark(pred)) - continue; - - ins[k++] = get_Phi_pred(phi, i); - } - if (k == 1) - exchange(phi, ins[0]); - else - set_irn_in(phi, k, ins); - } - } - - } - - if (changed) { - /* kick keep alives */ - ir_node *end = get_irg_end(irg); - int i, j, n = get_End_n_keepalives(end); - - NEW_ARR_A(ir_node *, ins, n); - - for (i = j = 0; i < n; ++i) { - ir_node *ka = get_End_keepalive(end, i); - ir_node *ka_bl; - - if (is_Bad(ka)) - continue; - if (is_Block(ka)) - ka_bl = ka; - else - ka_bl = get_nodes_block(skip_Proj(ka)); - if (get_Block_mark(ka_bl)) - ins[j++] = ka; - } - if (j != n) - set_End_keepalives(end, j, ins); - - free_irg_outs(irg); - - /* this transformation do NOT invalidate the dominance */ - } -} /* kill_unreachable_blocks */ - void opt_ldst(ir_graph *irg) { block_t *bl; @@ -2165,11 +2068,14 @@ void opt_ldst(ir_graph *irg) DB((dbg, LEVEL_1, "\nDoing Load/Store optimization on %+F\n", irg)); - /* we need landing pads */ - remove_critical_cf_edges(irg); + assure_irg_properties(irg, + IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES /* we need landing pads */ + | IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE + | IR_GRAPH_PROPERTY_CONSISTENT_OUTS + | IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE + | IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE); if (get_opt_alias_analysis()) { - assure_irg_entity_usage_computed(irg); assure_irp_globals_entity_usage_computed(); } @@ -2188,8 +2094,6 @@ void opt_ldst(ir_graph *irg) env.id_2_address = NEW_ARR_F(ir_node *, 0); #endif - assure_irg_outs(irg); - ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_BLOCK_MARK); /* first step: allocate block entries. Note that some blocks might be @@ -2212,11 +2116,6 @@ void opt_ldst(ir_graph *irg) set_Block_mark(env.end_bl, 1); } - /* KILL unreachable blocks: these disturb the data flow analysis */ - kill_unreachable_blocks(irg); - - assure_doms(irg); - /* second step: find and sort all memory ops */ walk_memory_irg(irg, collect_memops, NULL, NULL); @@ -2227,7 +2126,7 @@ void opt_ldst(ir_graph *irg) if (env.n_mem_ops == 0) { /* no memory ops */ - goto end; + goto no_changes; } /* create the backward links. */ @@ -2283,10 +2182,11 @@ void opt_ldst(ir_graph *irg) /* not only invalidate but free them. We might allocate new out arrays on our obstack which will be deleted yet. */ - free_irg_outs(irg); - clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE); + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_CONTROL_FLOW); + } else { +no_changes: + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_ALL); } -end: ir_free_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_BLOCK_MARK); ir_nodehashmap_destroy(&env.adr_map); diff --git a/ir/opt/opt_manage.c b/ir/opt/opt_manage.c deleted file mode 100644 index 5b5905c9a..000000000 --- a/ir/opt/opt_manage.c +++ /dev/null @@ -1,74 +0,0 @@ -#include "config.h" - -#include -#include - -#include "irgraph_t.h" -#include "irprog_t.h" -#include "irnode.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" - -static void nop(ir_graph *irg) { - (void)irg; -} - -void perform_irg_optimization(ir_graph *irg, optdesc_t *opt) -{ - ir_graph_properties_t new_irg_state; - ir_graph_properties_t required = opt->requirements; - const bool dump = get_irp_optimization_dumps(); - - /* It does not make sense to require both: */ - assert (!((required & IR_GRAPH_PROPERTY_ONE_RETURN) && (required & IR_GRAPH_PROPERTY_MANY_RETURNS))); - - /* assure that all requirements for the optimization are fulfilled */ -#define PREPARE(property,func) if (property & (required ^ irg->properties)) {func(irg); add_irg_properties(irg,property);} - PREPARE(IR_GRAPH_PROPERTY_ONE_RETURN, normalize_one_return) - PREPARE(IR_GRAPH_PROPERTY_MANY_RETURNS, normalize_n_returns) - PREPARE(IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES, remove_critical_cf_edges) - PREPARE(IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE, remove_unreachable_code) - PREPARE(IR_GRAPH_PROPERTY_NO_BADS, remove_bads) - PREPARE(IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE, assure_doms) - PREPARE(IR_GRAPH_PROPERTY_CONSISTENT_POSTDOMINANCE, assure_postdoms) - PREPARE(IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES, assure_edges) - PREPARE(IR_GRAPH_PROPERTY_CONSISTENT_OUTS, assure_irg_outs) - PREPARE(IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO, assure_loopinfo) - PREPARE(IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE, assure_irg_entity_usage_computed) - - /* now all the requirements for the optimization are fulfilled */ - if (dump) - dump_ir_graph(irg, opt->name); - - new_irg_state = opt->optimization(irg); - - if (dump) - 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(property,func) if (!(property & new_irg_state)) {clear_irg_properties(irg,property); func(irg);} - INVALIDATE(IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES, nop) - INVALIDATE(IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE, nop) - INVALIDATE(IR_GRAPH_PROPERTY_NO_BADS, nop) - INVALIDATE(IR_GRAPH_PROPERTY_ONE_RETURN, nop) - INVALIDATE(IR_GRAPH_PROPERTY_MANY_RETURNS, nop) - INVALIDATE(IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE, nop) - INVALIDATE(IR_GRAPH_PROPERTY_CONSISTENT_POSTDOMINANCE, nop) - INVALIDATE(IR_GRAPH_PROPERTY_CONSISTENT_OUTS, nop) - INVALIDATE(IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES, edges_deactivate) - INVALIDATE(IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO, nop) - INVALIDATE(IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE, nop) - - remove_End_Bads_and_doublets(get_irg_end(irg)); - - irg_verify(irg, VERIFY_ENFORCE_SSA); -} diff --git a/ir/opt/opt_manage.h b/ir/opt/opt_manage.h deleted file mode 100644 index b11f050e3..000000000 --- a/ir/opt/opt_manage.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2011 Karlsruhe Institute of Technology. All right reserved. - * - * This file is part of libFirm. - * - * This file may be distributed and/or modified under the terms of the - * GNU General Public License version 2 as published by the Free Software - * Foundation and appearing in the file LICENSE.GPL included in the - * packaging of this file. - * - * Licensees holding valid libFirm Professional Edition licenses may use - * this file in accordance with the libFirm Commercial License. - * Agreement provided with the Software. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ - -/** - * @file - * @brief Optimization wrapper for specifying requirements - * @author Andreas Zwinkau - */ -#ifndef FIRM_OPT_MANAGE_H -#define FIRM_OPT_MANAGE_H - -#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 properties for this optimization - */ - ir_graph_properties_t requirements; - - /** - * The optimization function itself - * - * @returns zero by default; set some flags, if you guarantee some properties - **/ - ir_graph_properties_t (*const optimization)(ir_graph *irg); -} optdesc_t; - -/** Apply an optimization to an ir graph. - * Assures preconditions, invalidates afterwards, and runs the verifier. - * Might also dump the irg. - */ -void perform_irg_optimization(ir_graph *irg, optdesc_t *opt); - -#endif diff --git a/ir/opt/opt_osr.c b/ir/opt/opt_osr.c index 89d5f81fd..2165b5967 100644 --- a/ir/opt/opt_osr.c +++ b/ir/opt/opt_osr.c @@ -1300,6 +1300,11 @@ void remove_phi_cycles(ir_graph *irg) { iv_env env; + assure_irg_properties(irg, + IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE + | IR_GRAPH_PROPERTY_CONSISTENT_OUTS + | IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES); + FIRM_DBG_REGISTER(dbg, "firm.opt.remove_phi"); DB((dbg, LEVEL_1, "Doing Phi cycle removement for %+F\n", irg)); @@ -1323,9 +1328,6 @@ void remove_phi_cycles(ir_graph *irg) */ irg_walk_graph(irg, NULL, clear_and_fix, NULL); - /* we need outs for calculating the post order */ - assure_irg_outs(irg); - /* calculate the post order number for blocks. */ irg_out_block_walk(get_irg_start_block(irg), NULL, assign_po, &env); @@ -1335,12 +1337,15 @@ void remove_phi_cycles(ir_graph *irg) ir_free_resources(irg, IR_RESOURCE_IRN_LINK); if (env.replaced) { - DB((dbg, LEVEL_1, "remove_phi_cycles: %u Cycles removed\n\n", env.replaced)); + DB((dbg, LEVEL_1, "remove_phi_cycles: %u Cycles removed\n\n", + env.replaced)); } DEL_ARR_F(env.stack); obstack_free(&env.obst, NULL); -} /* remove_phi_cycles */ + + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_CONTROL_FLOW); +} ir_graph_pass_t *remove_phi_cycles_pass(const char *name) { @@ -1422,6 +1427,11 @@ void opt_osr(ir_graph *irg, unsigned flags) FIRM_DBG_REGISTER(dbg, "firm.opt.osr"); + assure_irg_properties(irg, + IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE + | IR_GRAPH_PROPERTY_CONSISTENT_OUTS + | IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES); + DB((dbg, LEVEL_1, "Doing Operator Strength Reduction for %+F\n", irg)); obstack_init(&env.obst); @@ -1443,13 +1453,6 @@ void opt_osr(ir_graph *irg, unsigned flags) */ irg_walk_graph(irg, NULL, clear_and_fix, NULL); - /* we need dominance */ - assure_doms(irg); - - assure_edges(irg); - - /* calculate the post order number for blocks by walking the out edges. */ - assure_irg_outs(irg); irg_block_edges_walk(get_irg_start_block(irg), NULL, assign_po, &env); /* calculate the SCC's and drive OSR. */ @@ -1473,7 +1476,7 @@ void opt_osr(ir_graph *irg, unsigned flags) DEL_ARR_F(env.stack); obstack_free(&env.obst, NULL); - edges_deactivate(irg); + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_NONE); } typedef struct pass_t { diff --git a/ir/opt/parallelize_mem.c b/ir/opt/parallelize_mem.c index 2b370b2f9..3936cf326 100644 --- a/ir/opt/parallelize_mem.c +++ b/ir/opt/parallelize_mem.c @@ -41,7 +41,6 @@ #include "irflag_t.h" #include "irprintf.h" #include "irpass.h" -#include "opt_manage.h" typedef struct parallelize_info { @@ -238,22 +237,10 @@ static void walker(ir_node *proj, void *env) ir_nodeset_destroy(&pi.user_mem); } -static ir_graph_properties_t do_parallelize_mem(ir_graph *irg) -{ - irg_walk_graph(irg, NULL, walker, NULL); - - return 0; -} - -static optdesc_t opt_parallel_mem = { - "parallel-mem", - 0, - do_parallelize_mem, -}; - void opt_parallelize_mem(ir_graph *irg) { - perform_irg_optimization(irg, &opt_parallel_mem); + irg_walk_graph(irg, NULL, walker, NULL); + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_CONTROL_FLOW); } ir_graph_pass_t *opt_parallelize_mem_pass(const char *name) diff --git a/ir/opt/reassoc.c b/ir/opt/reassoc.c index f70d19c3b..276db38ad 100644 --- a/ir/opt/reassoc.c +++ b/ir/opt/reassoc.c @@ -929,20 +929,15 @@ void optimize_reassociation(ir_graph *irg) assert(get_irg_pinned(irg) != op_pin_state_floats && "Reassociation needs pinned graph to work properly"); - /* we use dominance to detect dead blocks */ - assure_doms(irg); + assure_irg_properties(irg, + IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE + | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO); #ifdef NEW_REASSOC - assure_irg_outs(irg); + assire_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS); obstack_init(&commutative_args); #endif - /* - * Calculate loop info, so we could identify loop-invariant - * code and treat it like a constant. - */ - assure_loopinfo(irg); - env.changes = 0; env.irg = irg; env.wq = new_waitq(); @@ -964,6 +959,8 @@ void optimize_reassociation(ir_graph *irg) #endif del_waitq(env.wq); + + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_CONTROL_FLOW); } /* optimize_reassociation */ /* create a pass for the reassociation */ diff --git a/ir/opt/return.c b/ir/opt/return.c index 900a5c420..572ba2b78 100644 --- a/ir/opt/return.c +++ b/ir/opt/return.c @@ -74,6 +74,8 @@ void normalize_one_return(ir_graph *irg) if (n <= 0) { /* The end block has no predecessors, we have an endless loop. In that case, no returns exists. */ + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_ALL); + add_irg_properties(irg, IR_GRAPH_PROPERTY_ONE_RETURN); return; } @@ -99,8 +101,11 @@ void normalize_one_return(ir_graph *irg) } } - if (n_rets <= 1) + if (n_rets <= 1) { + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_ALL); + add_irg_properties(irg, IR_GRAPH_PROPERTY_ONE_RETURN); return; + } in = ALLOCAN(ir_node*, MAX(n_rets, n_ret_vals)); retvals = ALLOCAN(ir_node*, n_rets * n_ret_vals); @@ -141,9 +146,14 @@ void normalize_one_return(ir_graph *irg) /* invalidate analysis information: * a new Block was added, so dominator, outs and loop are inconsistent, - * trouts and callee-state should be still valid - */ - clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE); + * trouts and callee-state should be still valid */ + confirm_irg_properties(irg, + IR_GRAPH_PROPERTY_NO_BADS + | IR_GRAPH_PROPERTY_NO_TUPLES + | IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES + | IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE + | IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE); + add_irg_properties(irg, IR_GRAPH_PROPERTY_ONE_RETURN); } /* Create a graph pass. */ @@ -263,8 +273,11 @@ void normalize_n_returns(ir_graph *irg) } } - if (n_rets == 0) + if (n_rets == 0) { + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_ALL); + add_irg_properties(irg, IR_GRAPH_PROPERTY_MANY_RETURNS); return; + } /* * Now move the Returns upwards. We move always one block up (and create n @@ -359,12 +372,11 @@ void normalize_n_returns(ir_graph *irg) /* Invalidate analysis information: * Blocks become dead and new Returns were deleted, so dominator, outs and * loop are inconsistent, trouts and callee-state should be still valid */ - clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE - | IR_GRAPH_PROPERTY_CONSISTENT_POSTDOMINANCE - | IR_GRAPH_PROPERTY_ONE_RETURN - | IR_GRAPH_PROPERTY_CONSISTENT_OUTS - | IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE - | IR_GRAPH_PROPERTY_NO_BADS); + confirm_irg_properties(irg, + IR_GRAPH_PROPERTY_NO_TUPLES + | IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES + | IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE); + add_irg_properties(irg, IR_GRAPH_PROPERTY_MANY_RETURNS); } /* Create a graph pass. */ diff --git a/ir/opt/scalar_replace.c b/ir/opt/scalar_replace.c index d8bbce675..c061a2b8b 100644 --- a/ir/opt/scalar_replace.c +++ b/ir/opt/scalar_replace.c @@ -46,7 +46,6 @@ #include "xmalloc.h" #include "debug.h" #include "error.h" -#include "opt_manage.h" static unsigned get_vnum(const ir_node *node) { @@ -367,7 +366,7 @@ static int find_possible_replacements(ir_graph *irg) ir_node *args; int j; - assure_irg_outs(inner_irg); + assure_irg_properties(inner_irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS); args = get_irg_args(inner_irg); for (j = get_irn_n_outs(args) - 1; j >= 0; --j) { ir_node *arg = get_irn_out(args, j); @@ -677,7 +676,7 @@ static void do_scalar_replacements(ir_graph *irg, pset *sels, unsigned nvals, * * @param irg The current ir graph. */ -static ir_graph_properties_t do_scalar_replacement(ir_graph *irg) +void scalar_replacement_opt(ir_graph *irg) { unsigned nvals; int i; @@ -688,6 +687,10 @@ static ir_graph_properties_t do_scalar_replacement(ir_graph *irg) pset *sels; ir_type *ent_type, *frame_tp; + assure_irg_properties(irg, + IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE + | IR_GRAPH_PROPERTY_CONSISTENT_OUTS); + /* we use the link field to store the VNUM */ ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK); irp_reserve_resources(irp, IRP_RESOURCE_ENTITY_LINK); @@ -764,18 +767,7 @@ static ir_graph_properties_t do_scalar_replacement(ir_graph *irg) ir_free_resources(irg, IR_RESOURCE_IRN_LINK); irp_free_resources(irp, IRP_RESOURCE_ENTITY_LINK); - return 0; -} - -static optdesc_t opt_scalar_rep = { - "scalar-replace", - IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE | IR_GRAPH_PROPERTY_CONSISTENT_OUTS, - do_scalar_replacement, -}; - -void scalar_replacement_opt(ir_graph *irg) -{ - perform_irg_optimization(irg, &opt_scalar_rep); + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_NONE); } ir_graph_pass_t *scalar_replacement_opt_pass(const char *name) diff --git a/ir/opt/tailrec.c b/ir/opt/tailrec.c index 4fb672699..d25ea6d93 100644 --- a/ir/opt/tailrec.c +++ b/ir/opt/tailrec.c @@ -45,7 +45,6 @@ #include "irhooks.h" #include "ircons_t.h" #include "irpass.h" -#include "opt_manage.h" DEBUG_ONLY(static firm_dbg_module_t *dbg;) @@ -559,20 +558,27 @@ static tail_rec_variants find_variant(ir_node *irn, ir_node *call) /* * convert simple tail-calls into loops */ -static ir_graph_properties_t do_tailrec(ir_graph *irg) +void opt_tail_rec_irg(ir_graph *irg) { - tr_env env; - ir_node *end_block; - int i, n_ress, n_tail_calls = 0; - ir_node *rets = NULL; - ir_type *mtd_type, *call_type; - ir_entity *ent; - ir_graph *rem; + tr_env env; + ir_node *end_block; + int i, n_ress, n_tail_calls = 0; + ir_node *rets = NULL; + ir_type *mtd_type, *call_type; + ir_entity *ent; + ir_graph *rem; + + assure_irg_properties(irg, + IR_GRAPH_PROPERTY_MANY_RETURNS + | IR_GRAPH_PROPERTY_NO_BADS + | IR_GRAPH_PROPERTY_CONSISTENT_OUTS); FIRM_DBG_REGISTER(dbg, "firm.opt.tailrec"); - if (! check_lifetime_of_locals(irg)) - return 0; + if (! check_lifetime_of_locals(irg)) { + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_ALL); + return; + } rem = current_ir_graph; current_ir_graph = irg; @@ -651,10 +657,11 @@ static ir_graph_properties_t do_tailrec(ir_graph *irg) /* cannot be transformed */ break; } - if (var == TR_DIRECT) - var = env.variants[j]; - else if (env.variants[j] == TR_DIRECT) + if (var == TR_DIRECT) { + var = env.variants[j]; + } else if (env.variants[j] == TR_DIRECT) { env.variants[j] = var; + } if (env.variants[j] != var) { /* not compatible */ DB((dbg, LEVEL_3, " tail recursion fails for %d return value of %+F\n", j, ret)); @@ -684,26 +691,12 @@ static ir_graph_properties_t do_tailrec(ir_graph *irg) env.n_tail_calls = n_tail_calls; env.rets = rets; do_opt_tail_rec(irg, &env); + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_NONE); + } else { + confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_ALL); } ir_free_resources(irg, IR_RESOURCE_IRN_LINK); current_ir_graph = rem; - return 0; -} - - -/* - * This tail recursion optimization works best - * if the Returns are normalized. - */ -static optdesc_t opt_tailrec = { - "tail-recursion", - IR_GRAPH_PROPERTY_MANY_RETURNS | IR_GRAPH_PROPERTY_NO_BADS | IR_GRAPH_PROPERTY_CONSISTENT_OUTS, - do_tailrec, -}; - -void opt_tail_rec_irg(ir_graph *irg) -{ - perform_irg_optimization(irg, &opt_tailrec); } ir_graph_pass_t *opt_tail_rec_irg_pass(const char *name) -- 2.20.1