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)
/** 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
/** 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"
#include "debug.h"
#include "error.h"
#include "irflag.h"
-#include "opt_manage.h"
/**
* Walker environment.
}
}
-/*
- * 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");
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)
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)
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);
}
}
- assure_irg_outs(irg);
-
irg_frame = get_irg_frame(irg);
for (j = get_irn_n_outs(irg_frame) - 1; j >= 0; --j) {
}
}
-
/* now computed */
add_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE);
}
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)
{
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)
#include "iredges_t.h"
#include "type_t.h"
#include "irmemory.h"
+#include "iroptimize.h"
+#include "irgopt.h"
#define INITIAL_IDX_IRN_MAP_SIZE 1024
{
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);
+}
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)
{
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);
#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
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
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);
}
void remove_tuples(ir_graph *irg)
{
irg_walk_graph(irg, exchange_tuple_projs, NULL, NULL);
+ add_irg_properties(irg, IR_GRAPH_PROPERTY_NO_TUPLES);
}
{
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);
}
#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 {
}
}
-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");
/* 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. */
#include "irdump.h"
#include "irverify.h"
#include "iredges.h"
-#include "opt_manage.h"
#include "array_t.h"
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;
}
}
}
/* 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;
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);
* 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);
}
}
- 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. */
#include "irouts.h"
#include "irgopt.h"
#include "irpass.h"
-#include "opt_manage.h"
static bool is_block_reachable(ir_node *block)
{
}
/* 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. */
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);
}
/**
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);
#include "irpass.h"
#include "tv_t.h"
#include "irtools.h"
-#include "opt_manage.h"
#include "irprintf.h"
#include "irdump.h"
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;
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 */
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)
{
#include "irpass_t.h"
#include "tv.h"
#include "vrp.h"
-#include "opt_manage.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg;)
}
}
-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. */
/* 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);
}
}
for (call = env->found_allocs; call; call = next) {
next = (ir_node*)get_irn_link(call);
}
+
+ confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_NONE);
}
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 */
#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
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);
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)
#include "config.h"
#include "opt_init.h"
+#include <stdbool.h>
#include "irnode_t.h"
#include "irgraph_t.h"
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.
/**
* 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;
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);
/* 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.
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);
}
}
finish:
- edges_deactivate_kind(irg, EDGE_KIND_NORMAL);
+ confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_ALL);
return res;
}
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);
}
/*
}
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);
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
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 */
+}
#include "array_t.h"
#include "irpass_t.h"
#include "be.h"
-#include "opt_manage.h"
#include "irdump.h"
#include "debug.h"
}
}
-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;
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)
#include "iroptimize.h"
#include <assert.h>
+#include <stdbool.h>
#include "array_t.h"
#include "debug.h"
#include "ircons.h"
#include "iropt_dbg.h"
#include "irpass.h"
#include "vrp.h"
-#include "opt_manage.h"
#undef AVOID_PHIB
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;
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;
}
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");
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. */
#include "set.h"
#include "be.h"
#include "debug.h"
-#include "opt_manage.h"
/** The debug handle. */
DEBUG_ONLY(static firm_dbg_module_t *dbg;)
/*
* 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");
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)
*/
#include <config.h>
#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);
}
#include "beutil.h"
#include "irpass.h"
#include "irdom.h"
-#include "opt_manage.h"
#include <math.h>
#include "irbackedge_t.h"
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 */
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);
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 */
/* 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);
- }
}
}
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)
* 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;
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. -- */
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);
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;
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;
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();
}
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
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);
if (env.n_mem_ops == 0) {
/* no memory ops */
- goto end;
+ goto no_changes;
}
/* create the backward links. */
/* 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);
+++ /dev/null
-#include "config.h"
-
-#include <assert.h>
-#include <stdbool.h>
-
-#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);
-}
+++ /dev/null
-/*
- * 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 <stdbool.h>
-
-#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
{
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));
*/
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);
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)
{
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);
*/
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. */
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 {
#include "irflag_t.h"
#include "irprintf.h"
#include "irpass.h"
-#include "opt_manage.h"
typedef struct parallelize_info
{
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)
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();
#endif
del_waitq(env.wq);
+
+ confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_CONTROL_FLOW);
} /* optimize_reassociation */
/* create a pass for the reassociation */
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;
}
}
}
- 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);
/* 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. */
}
}
- 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
/* 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. */
#include "xmalloc.h"
#include "debug.h"
#include "error.h"
-#include "opt_manage.h"
static unsigned get_vnum(const ir_node *node)
{
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);
*
* @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;
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);
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)
#include "irhooks.h"
#include "ircons_t.h"
#include "irpass.h"
-#include "opt_manage.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg;)
/*
* 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;
/* 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));
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)