Commit 55a7a1f4 authored by Andreas Zwinkau's avatar Andreas Zwinkau
Browse files

tailrec requires many Returns

Extend opt_manage framework with MANY_RETURNS condition.

Since normalize_n_returns might introduce unreachable code,
the order should be handled in the framework instead of the
optimization.

Fix opt/gap test.
parent 979c74be
......@@ -462,6 +462,8 @@ typedef enum {
IR_GRAPH_STATE_CONSISTENT_ENTITY_USAGE = 1U << 14,
/** extended basic blocks have been formed and are up to date */
IR_GRAPH_STATE_VALID_EXTENDED_BLOCKS = 1U << 15,
/** graph contains as many returns as possible */
IR_GRAPH_STATE_MANY_RETURNS = 1U << 16,
} ir_graph_state_t;
ENUM_BITSET(ir_graph_state_t)
......
......@@ -25,9 +25,13 @@ void perform_irg_optimization(ir_graph *irg, optdesc_t *opt)
ir_graph_state_t required = opt->requirements;
const bool dump = get_irp_optimization_dumps();
/* It does not make sense to require both: */
assert (!((required & IR_GRAPH_STATE_ONE_RETURN) && (required & IR_GRAPH_STATE_MANY_RETURNS)));
/* assure that all requirements for the optimization are fulfilled */
#define PREPARE(st,func) if (st & (required ^ irg->state)) {func(irg); set_irg_state(irg,st);}
PREPARE(IR_GRAPH_STATE_ONE_RETURN, normalize_one_return)
PREPARE(IR_GRAPH_STATE_MANY_RETURNS, normalize_n_returns)
PREPARE(IR_GRAPH_STATE_NO_CRITICAL_EDGES, remove_critical_cf_edges)
PREPARE(IR_GRAPH_STATE_NO_UNREACHABLE_CODE, remove_unreachable_code)
PREPARE(IR_GRAPH_STATE_NO_BADS, remove_bads)
......@@ -57,6 +61,7 @@ void perform_irg_optimization(ir_graph *irg, optdesc_t *opt)
INVALIDATE(IR_GRAPH_STATE_NO_UNREACHABLE_CODE, nop)
INVALIDATE(IR_GRAPH_STATE_NO_BADS, nop)
INVALIDATE(IR_GRAPH_STATE_ONE_RETURN, nop)
INVALIDATE(IR_GRAPH_STATE_MANY_RETURNS, nop)
INVALIDATE(IR_GRAPH_STATE_CONSISTENT_DOMINANCE, nop)
INVALIDATE(IR_GRAPH_STATE_CONSISTENT_POSTDOMINANCE, nop)
INVALIDATE(IR_GRAPH_STATE_CONSISTENT_OUTS, nop)
......
......@@ -594,12 +594,6 @@ static ir_graph_state_t do_tailrec(ir_graph *irg)
env.variants[i] = TR_DIRECT;
}
/*
* This tail recursion optimization works best
* if the Returns are normalized.
*/
normalize_n_returns(irg);
ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
end_block = get_irg_end_block(irg);
......@@ -661,7 +655,7 @@ static ir_graph_state_t do_tailrec(ir_graph *irg)
break;
}
if (var == TR_DIRECT)
var = env.variants[j];
var = env.variants[j];
else if (env.variants[j] == TR_DIRECT)
env.variants[j] = var;
if (env.variants[j] != var) {
......@@ -699,9 +693,14 @@ static ir_graph_state_t do_tailrec(ir_graph *irg)
return 0;
}
/*
* This tail recursion optimization works best
* if the Returns are normalized.
*/
static optdesc_t opt_tailrec = {
"tail-recursion",
IR_GRAPH_STATE_NO_BADS | IR_GRAPH_STATE_CONSISTENT_OUTS,
IR_GRAPH_STATE_MANY_RETURNS | IR_GRAPH_STATE_NO_BADS | IR_GRAPH_STATE_CONSISTENT_OUTS,
do_tailrec,
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment