Commit 8a98cf06 authored by Andreas Zwinkau's avatar Andreas Zwinkau
Browse files

convert opts to use the opt_manage framework

Converted: ifconv, boolopt, combo, fpvrp, ldst, code placement,
jumpthreading, deconv, parallelize mem, loop, scalar replacement,
cfopt.
parent 57c0820b
......@@ -39,6 +39,7 @@
#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,16 +717,14 @@ restart:
}
}
void opt_bool(ir_graph *const irg)
static ir_graph_state_t do_simplify_bool(ir_graph *const irg)
{
bool_opt_env_t env;
ir_graph_state_t res = 0;
/* register a debug mask */
FIRM_DBG_REGISTER(dbg, "firm.opt.bool");
/* works better with one return block only */
normalize_one_return(irg);
env.changed = 0;
/* optimize simple Andb and Orb cases */
......@@ -737,12 +736,24 @@ void opt_bool(ir_graph *const irg)
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) {
set_irg_doms_inconsistent(irg);
set_irg_extblk_inconsistent(irg);
if (! env.changed) {
res |= IR_GRAPH_STATE_CONSISTENT_DOMINANCE;
}
ir_free_resources(irg, IR_RESOURCE_BLOCK_MARK | IR_RESOURCE_PHI_LIST);
return res;
}
optdesc_t opt_simplify_bool = {
"bool-simplification",
IR_GRAPH_STATE_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);
}
/* Creates an ir_graph pass for opt_bool. */
......
......@@ -47,6 +47,7 @@
#include "irdump.h"
#include "irverify.h"
#include "iredges.h"
#include "opt_manage.h"
#include "array_t.h"
......@@ -851,7 +852,7 @@ static void cfgopt_ignoring_phis(ir_graph *irg)
}
/* Optimizations of the control flow that also require changes of Phi nodes. */
void optimize_cf(ir_graph *irg)
static ir_graph_state_t do_cfopt(ir_graph *irg)
{
int i, j, n;
ir_node **in = NULL;
......@@ -966,12 +967,17 @@ void optimize_cf(ir_graph *irg)
}
}
if (env.changed) {
/* Handle graph state if was changed. */
set_irg_doms_inconsistent(irg);
set_irg_extblk_inconsistent(irg);
set_irg_entity_usage_state(irg, ir_entity_usage_not_computed);
}
return 0;
}
optdesc_t opt_cf = {
"control-flow",
0,
do_cfopt,
};
void optimize_cf(ir_graph *irg) {
perform_irg_optimization(irg, &opt_cf);
}
/* Creates an ir_graph pass for optimize_cf. */
......
......@@ -39,6 +39,7 @@
#include "irouts.h"
#include "irgopt.h"
#include "irpass.h"
#include "opt_manage.h"
static bool is_block_reachable(ir_node *block)
{
......@@ -396,17 +397,12 @@ static void place_late(ir_graph *irg, waitq *worklist)
}
/* Code Placement. */
void place_code(ir_graph *irg)
static ir_graph_state_t do_codeplacement(ir_graph *irg)
{
waitq *worklist;
remove_critical_cf_edges(irg);
/* Handle graph state */
assert(get_irg_phase_state(irg) != phase_building);
assure_irg_outs(irg);
assure_doms(irg);
assure_cf_loop(irg);
/* Place all floating nodes as early as possible. This guarantees
a legal code placement. */
......@@ -424,6 +420,21 @@ void place_code(ir_graph *irg)
place_late(irg, worklist);
del_waitq(worklist);
return 0;
}
optdesc_t opt_codeplacement = {
"code-placement",
IR_GRAPH_STATE_NO_CRITICAL_EDGES |
IR_GRAPH_STATE_CONSISTENT_OUTS |
IR_GRAPH_STATE_CONSISTENT_DOMINANCE |
IR_GRAPH_STATE_CONSISTENT_LOOPINFO,
do_codeplacement,
};
void place_code(ir_graph *irg)
{
perform_irg_optimization(irg, &opt_codeplacement);
}
/**
......@@ -437,6 +448,24 @@ static void place_code_wrapper(ir_graph *irg)
set_opt_global_cse(0);
}
static ir_graph_state_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;
}
optdesc_t opt_gcse = {
"gcse",
IR_GRAPH_STATE_NO_CRITICAL_EDGES |
IR_GRAPH_STATE_CONSISTENT_OUTS |
IR_GRAPH_STATE_CONSISTENT_DOMINANCE |
IR_GRAPH_STATE_CONSISTENT_LOOPINFO,
do_gcse,
};
ir_graph_pass_t *place_code_pass(const char *name)
{
return def_graph_pass(name ? name : "place", place_code_wrapper);
......
......@@ -84,6 +84,7 @@
#include "irpass.h"
#include "tv_t.h"
#include "irtools.h"
#include "opt_manage.h"
#include "irprintf.h"
#include "irdump.h"
......@@ -3491,7 +3492,7 @@ static void add_memory_keeps(ir_node **kept_memory, size_t len)
ir_nodeset_destroy(&set);
} /* add_memory_keeps */
void combo(ir_graph *irg)
static ir_graph_state_t do_combo(ir_graph *irg)
{
environment_t env;
ir_node *initial_bl;
......@@ -3524,9 +3525,6 @@ void combo(ir_graph *irg)
env.commutative = 1;
env.opt_unknown = 1;
assure_irg_outs(irg);
assure_cf_loop(irg);
/* we have our own value_of function */
set_value_of_func(get_node_tarval);
......@@ -3591,13 +3589,6 @@ void combo(ir_graph *irg)
DB((dbg, LEVEL_1, "Unoptimized Control Flow left"));
}
if (env.modified) {
/* control flow might changed */
set_irg_extblk_inconsistent(irg);
set_irg_doms_inconsistent(irg);
set_irg_entity_usage_state(irg, ir_entity_usage_not_computed);
}
ir_free_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_PHI_LIST);
/* remove the partition hook */
......@@ -3610,8 +3601,21 @@ void combo(ir_graph *irg)
/* restore value_of() default behavior */
set_value_of_func(NULL);
current_ir_graph = rem;
return 0; // cannot guarantee anything
} /* combo */
optdesc_t opt_combo = {
"combo",
IR_GRAPH_STATE_NO_BAD_BLOCKS | IR_GRAPH_STATE_CONSISTENT_OUTS | IR_GRAPH_STATE_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)
{
......
......@@ -54,6 +54,7 @@
#include "irpass_t.h"
#include "tv.h"
#include "vrp.h"
#include "opt_manage.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg);
......@@ -312,7 +313,7 @@ static void conv_opt_walker(ir_node *node, void *data)
}
}
int conv_opt(ir_graph *irg)
static ir_graph_state_t do_deconv(ir_graph *irg)
{
bool changed;
bool invalidate = false;
......@@ -320,7 +321,6 @@ int conv_opt(ir_graph *irg)
DB((dbg, LEVEL_1, "===> Performing conversion optimization on %+F\n", irg));
edges_assure(irg);
do {
changed = false;
irg_walk_graph(irg, NULL, conv_opt_walker, &changed);
......@@ -328,7 +328,19 @@ int conv_opt(ir_graph *irg)
invalidate |= changed;
} while (changed);
return invalidate;
return 0;
}
optdesc_t opt_deconv = {
"deconv",
IR_GRAPH_STATE_CONSISTENT_OUT_EDGES,
do_deconv,
};
int conv_opt(ir_graph *irg)
{
perform_irg_optimization(irg, &opt_deconv);
return 1;
}
/* Creates an ir_graph pass for conv_opt. */
......
......@@ -44,6 +44,7 @@
#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
......@@ -812,22 +813,16 @@ static void build_phi_lists(ir_node *irn, void *env)
add_Block_phi(get_nodes_block(irn), irn);
}
void fixpoint_vrp(ir_graph* const irg)
static ir_graph_state_t do_fixpoint_vrp(ir_graph* const irg)
{
environment_t env;
ir_graph_state_t res = 0;
FIRM_DBG_REGISTER(dbg, "firm.opt.fp-vrp");
DB((dbg, LEVEL_1, "===> Performing constant propagation on %+F\n", irg));
obstack_init(&obst);
/* HACK: to avoid finding dead code */
edges_deactivate(irg);
edges_activate(irg);
edges_assure(irg);
assure_doms(irg);
ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_PHI_LIST);
{
......@@ -860,16 +855,26 @@ void fixpoint_vrp(ir_graph* const irg)
env.modified = 0;
irg_walk_graph(irg, NULL, apply_result, &env);
if (env.modified) {
/* control flow might changed */
set_irg_extblk_inconsistent(irg);
set_irg_doms_inconsistent(irg);
set_irg_entity_usage_state(irg, ir_entity_usage_not_computed);
if (! env.modified) {
res |= IR_GRAPH_STATE_CONSISTENT_DOMINANCE | IR_GRAPH_STATE_CONSISTENT_ENTITY_USAGE;
}
ir_free_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_PHI_LIST);
obstack_free(&obst, NULL);
return res;
}
optdesc_t opt_fpvrp = {
"fp-vrp",
IR_GRAPH_STATE_NO_BAD_BLOCKS | IR_GRAPH_STATE_NO_UNREACHABLE_BLOCKS | IR_GRAPH_STATE_CONSISTENT_DOMINANCE | IR_GRAPH_STATE_CONSISTENT_OUT_EDGES,
do_fixpoint_vrp,
};
void fixpoint_vrp(ir_graph* const irg)
{
perform_irg_optimization(irg, &opt_fpvrp);
}
ir_graph_pass_t *fixpoint_vrp_irg_pass(const char *name)
......
......@@ -40,6 +40,7 @@
#include "array_t.h"
#include "irpass_t.h"
#include "be.h"
#include "opt_manage.h"
#include "irdump.h"
#include "debug.h"
......@@ -464,7 +465,7 @@ static void collect_phis(ir_node *node, void *env)
}
}
void opt_if_conv(ir_graph *irg)
static ir_graph_state_t do_ifconv(ir_graph *irg)
{
walker_env env;
const backend_params *be_params = be_get_backend_param();
......@@ -477,11 +478,6 @@ void opt_if_conv(ir_graph *irg)
DB((dbg, LEVEL_1, "Running if-conversion on %+F\n", irg));
env.changed |= remove_bads(irg);
normalize_one_return(irg);
remove_critical_cf_edges(irg);
compute_cdep(irg);
ir_reserve_resources(irg, IR_RESOURCE_BLOCK_MARK | IR_RESOURCE_PHI_LIST);
......@@ -494,13 +490,22 @@ void opt_if_conv(ir_graph *irg)
if (env.changed) {
local_optimize_graph(irg);
/* graph has changed, invalidate analysis info */
set_irg_extblk_inconsistent(irg);
set_irg_doms_inconsistent(irg);
}
free_cdep(irg);
return IR_GRAPH_STATE_NO_CRITICAL_EDGES | IR_GRAPH_STATE_ONE_RETURN;
}
optdesc_t opt_ifconv = {
"if-conversion",
IR_GRAPH_STATE_NO_CRITICAL_EDGES | IR_GRAPH_STATE_NO_UNREACHABLE_BLOCKS | IR_GRAPH_STATE_NO_BAD_BLOCKS | IR_GRAPH_STATE_ONE_RETURN,
do_ifconv,
};
void opt_if_conv(ir_graph *irg)
{
perform_irg_optimization(irg, &opt_ifconv);
}
ir_graph_pass_t *opt_if_conv_pass(const char *name)
......
......@@ -46,6 +46,7 @@
#include "iropt_dbg.h"
#include "irpass.h"
#include "vrp.h"
#include "opt_manage.h"
#undef AVOID_PHIB
......@@ -753,21 +754,15 @@ static void thread_jumps(ir_node* block, void* data)
*changed = 1;
}
void opt_jumpthreading(ir_graph* irg)
static ir_graph_state_t do_jumpthread(ir_graph* irg)
{
int changed, rerun;
ir_graph_state_t res = 0;
FIRM_DBG_REGISTER(dbg, "firm.opt.jumpthreading");
DB((dbg, LEVEL_1, "===> Performing jumpthreading on %+F\n", irg));
remove_critical_cf_edges(irg);
/* ugly: jump threading might get confused by garbage nodes
* of mode_X in copy_and_fix_node(), so remove all garbage edges. */
edges_deactivate(irg);
edges_assure(irg);
ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_IRN_VISITED);
changed = 0;
......@@ -779,12 +774,22 @@ void opt_jumpthreading(ir_graph* irg)
ir_free_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_IRN_VISITED);
if (changed) {
/* control flow changed, some blocks may become dead */
set_irg_doms_inconsistent(irg);
set_irg_extblk_inconsistent(irg);
set_irg_entity_usage_state(irg, ir_entity_usage_not_computed);
if (!changed) {
res |= IR_GRAPH_STATE_CONSISTENT_DOMINANCE | IR_GRAPH_STATE_CONSISTENT_ENTITY_USAGE;
}
return res;
}
optdesc_t opt_jumpthread = {
"jumpthreading",
IR_GRAPH_STATE_NO_UNREACHABLE_BLOCKS | IR_GRAPH_STATE_CONSISTENT_OUT_EDGES | IR_GRAPH_STATE_NO_CRITICAL_EDGES,
do_jumpthread,
};
void opt_jumpthreading(ir_graph* irg)
{
perform_irg_optimization(irg, &opt_jumpthread);
}
/* Creates an ir_graph pass for opt_jumpthreading. */
......
......@@ -50,6 +50,7 @@
#include "set.h"
#include "be.h"
#include "debug.h"
#include "opt_manage.h"
/** The debug handle. */
DEBUG_ONLY(static firm_dbg_module_t *dbg;)
......@@ -2260,9 +2261,10 @@ static int optimize_loops(ir_graph *irg)
/*
* do the load store optimization
*/
int optimize_load_store(ir_graph *irg)
static ir_graph_state_t do_loadstore_opt(ir_graph *irg)
{
walk_env_t env;
ir_graph_state_t res = 0;
FIRM_DBG_REGISTER(dbg, "firm.opt.ldstopt");
......@@ -2270,16 +2272,7 @@ int optimize_load_store(ir_graph *irg)
assert(get_irg_pinned(irg) != op_pin_state_floats &&
"LoadStore optimization needs pinned graph");
/* we need landing pads */
remove_critical_cf_edges(irg);
edges_assure(irg);
/* for Phi optimization post-dominators are needed ... */
assure_postdoms(irg);
if (get_opt_alias_analysis()) {
assure_irg_entity_usage_computed(irg);
assure_irp_globals_entity_usage_computed();
}
......@@ -2304,12 +2297,26 @@ int optimize_load_store(ir_graph *irg)
}
if (env.changes & CF_CHANGED) {
/* is this really needed: Yes, control flow changed, block might
have Bad() predecessors. */
/* control flow changed, block might have Bad() predecessors. */
set_irg_doms_inconsistent(irg);
} else {
res |= IR_GRAPH_STATE_CONSISTENT_DOMINANCE | IR_GRAPH_STATE_NO_BAD_BLOCKS;
}
return env.changes != 0;
} /* optimize_load_store */
return res;
}
optdesc_t opt_loadstore = {
"load-store",
IR_GRAPH_STATE_NO_UNREACHABLE_BLOCKS | IR_GRAPH_STATE_CONSISTENT_OUT_EDGES | IR_GRAPH_STATE_NO_CRITICAL_EDGES | IR_GRAPH_STATE_CONSISTENT_DOMINANCE | IR_GRAPH_STATE_CONSISTENT_ENTITY_USAGE,
do_loadstore_opt,
};
int optimize_load_store(ir_graph *irg)
{
perform_irg_optimization(irg, &opt_loadstore);
return 1;
}
ir_graph_pass_t *optimize_load_store_pass(const char *name)
{
......
......@@ -45,6 +45,7 @@
#include "beutil.h"
#include "irpass.h"
#include "irdom.h"
#include "opt_manage.h"
#include <math.h>
#include "irbackedge_t.h"
......@@ -2679,10 +2680,6 @@ void loop_optimization(ir_graph *irg)
/* Preconditions */
set_current_ir_graph(irg);
edges_assure(irg);
assure_irg_outs(irg);
assure_cf_loop(irg);
ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_PHI_LIST);
collect_phiprojs(irg);
......@@ -2720,24 +2717,54 @@ void loop_optimization(ir_graph *irg)
ir_free_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_PHI_LIST);
}
void do_loop_unrolling(ir_graph *irg)
static ir_graph_state_t perform_loop_unrolling(ir_graph *irg)
{
loop_op = loop_op_unrolling;
loop_optimization(irg);
return 0;
}
void do_loop_inversion(ir_graph *irg)
static ir_graph_state_t perform_loop_inversion(ir_graph *irg)
{
loop_op = loop_op_inversion;
loop_optimization(irg);
return 0;
}
void do_loop_peeling(ir_graph *irg)
static ir_graph_state_t perform_loop_peeling(ir_graph *irg)
{
loop_op = loop_op_peeling;
loop_optimization(irg);
return 0;
}
optdesc_t opt_unroll_loops = {
"unroll-loops",
IR_GRAPH_STATE_CONSISTENT_OUT_EDGES | IR_GRAPH_STATE_CONSISTENT_OUTS | IR_GRAPH_STATE_CONSISTENT_LOOPINFO,
perform_loop_unrolling,
};
optdesc_t opt_invert_loops = {
"invert-loops",
IR_GRAPH_STATE_CONSISTENT_OUT_EDGES | IR_GRAPH_STATE_CONSISTENT_OUTS | IR_GRAPH_STATE_CONSISTENT_LOOPINFO,
perform_loop_inversion,
};
optdesc_t opt_peel_loops = {
"peel-loops",
IR_GRAPH_STATE_CONSISTENT_OUT_EDGES | IR_GRAPH_STATE_CONSISTENT_OUTS | IR_GRAPH_STATE_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);
......
......@@ -48,7 +48,6 @@ void perform_irg_optimization(ir_graph *irg, optdesc_t *opt)
clear_irg_state(irg, IR_GRAPH_STATE_NO_BAD_BLOCKS);
if (ir_entity_usage_not_computed == get_irg_entity_usage_state(irg))
clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_ENTITY_USAGE);
clear_irg_state(irg, IR_GRAPH_STATE_NO_UNREACHABLE_BLOCKS); // FIXME seems to incorrect sometimes
/* assure that all requirements for the optimization are fulfilled */
#define PREPARE(st,func) if (st & (required ^ irg->state)) {func(irg); set_irg_state(irg,st);}
......
......@@ -42,6 +42,7 @@
#include "irflag_t.h"
#include "irprintf.h"
#include "irpass.h"
#include "opt_manage.h"
typedef struct parallelize_info
{
......@@ -238,14 +239,22 @@ static void walker(ir_node *proj, void *env)
ir_nodeset_destroy(&pi.user_mem);
}
void opt_parallelize_mem(ir_graph *irg)
static ir_graph_state_t do_parallelize_mem(ir_graph *irg)
{
//assure_irg_entity_usage_computed(irg);
//assure_irp_globals_entity_usage_computed();
irg_walk_graph(irg, NULL, walker, NULL);
//optimize_graph_df(irg);
//irg_walk_graph(irg, NormaliseSync, NULL, NULL);
return 0;
}
optdesc_t opt_parallel_mem = {
"parallel-mem",
0,
do_parallelize_mem,
};
void opt_parallelize_mem(ir_graph *irg)
{