Commit dee663d4 authored by Matthias Braun's avatar Matthias Braun
Browse files

lower small switches to ifs

parent c3bca446
......@@ -160,14 +160,15 @@ FIRM_API void lower_CopyB(ir_graph *irg, unsigned max_size,
* They will either remain the same or be converted into if-cascades.
*
* @param irg The ir graph to be lowered.
* @param small_switch If switch has <= cases then change it to an if-cascade.
* @param spare_size Allowed spare size for table switches in machine words.
* (Default in edgfe: 128)
* @param allow_out_of_bounds backend can handle out-of-bounds values
* (values bigger than minimum and maximum proj
* number)
*/
FIRM_API void lower_switch(ir_graph *irg, unsigned spare_size,
int allow_out_of_bounds);
FIRM_API void lower_switch(ir_graph *irg, unsigned small_switch,
unsigned spare_size, int allow_out_of_bounds);
/**
* Replaces SymConsts by a real constant if possible.
......
......@@ -549,7 +549,7 @@ static void arm_lower_for_target(void)
for (i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
lower_switch(irg, 256, true);
lower_switch(irg, 4, 256, true);
}
}
......
......@@ -2046,7 +2046,7 @@ static void ia32_lower_for_target(void)
/* lower for mode_b stuff */
ir_lower_mode_b(irg, &lower_mode_b_config);
/* break up switches with wide ranges */
lower_switch(irg, 256, true);
lower_switch(irg, 4, 256, true);
}
}
......
......@@ -563,7 +563,7 @@ static void sparc_lower_for_target(void)
for (i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
ir_lower_mode_b(irg, &lower_mode_b_config);
lower_switch(irg, 256, false);
lower_switch(irg, 4, 256, false);
}
}
......
......@@ -44,6 +44,7 @@
typedef struct walk_env_t {
unsigned spare_size; /**< the allowed spare size for table switches */
unsigned small_switch;
bool allow_out_of_bounds;
bool changed; /**< indicates whether a change was performed */
ir_nodeset_t processed;
......@@ -311,6 +312,7 @@ static void find_cond_nodes(ir_node *block, void *ctx)
dbg_info *dbgi;
cond_env_t cond_env;
unsigned long spare;
bool lower_switch = false;
/* because we split critical blocks only blocks with 1 predecessors may
* contain Proj->Cond nodes */
......@@ -349,7 +351,10 @@ static void find_cond_nodes(ir_node *block, void *ctx)
spare = (unsigned long) cond_env.switch_max
- (unsigned long) cond_env.switch_min
- (unsigned long) cond_env.num_cases + 1;
if (spare < env->spare_size) {
lower_switch |= spare >= env->spare_size;
lower_switch |= cond_env.num_cases <= env->small_switch;
if (!lower_switch) {
/* we won't decompose the switch. But we might have to add
* out-of-bounds checking */
if (!env->allow_out_of_bounds) {
......@@ -405,11 +410,13 @@ static void find_cond_nodes(ir_node *block, void *ctx)
DEL_ARR_F(cond_env.defusers);
}
void lower_switch(ir_graph *irg, unsigned spare_size, int allow_out_of_bounds)
void lower_switch(ir_graph *irg, unsigned small_switch, unsigned spare_size,
int allow_out_of_bounds)
{
walk_env_t env;
env.changed = false;
env.spare_size = spare_size;
env.small_switch = small_switch;
env.allow_out_of_bounds = allow_out_of_bounds;
ir_nodeset_init(&env.processed);
......
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