typedef struct merge_env {
bool changed; /**< Set if the graph was changed. */
bool phis_moved; /**< Set if Phi nodes were moved. */
- ir_node **switch_conds; /**< Helper list for all found Switch Conds. */
} merge_env;
static void set_Block_removable(ir_node *block, bool removable)
return get_Block_mark(block);
}
+static bool is_switch_Cond(ir_node *cond) {
+ ir_node *sel = get_Cond_selector(cond);
+ return get_irn_mode(sel) != mode_b;
+}
+
static void clear_link(ir_node *node, void *ctx)
{
(void) ctx;
*/
static void collect_nodes(ir_node *n, void *ctx)
{
- merge_env *env = (merge_env*)ctx;
+ ir_node ***switch_conds = (ir_node***)ctx;
if (is_Phi(n)) {
/* Collect Phi nodes to compact ins along with block's ins. */
ir_node *pred = get_Proj_pred(n);
set_irn_link(n, get_irn_link(pred));
set_irn_link(pred, n);
- } else if (is_Cond(n)) {
- ir_node *sel = get_Cond_selector(n);
- if (get_irn_mode(sel) != mode_b) {
- /* found a switch-Cond, collect */
- ARR_APP1(ir_node*, env->switch_conds, n);
- }
+ } else if (is_Cond(n) && is_switch_Cond(n)) {
+ /* found a switch-Cond, collect */
+ ARR_APP1(ir_node*, *switch_conds, n);
}
}
}
return false;
}
-static bool is_switch_Cond(ir_node *cond) {
- return get_irn_mode(get_Cond_selector(cond)) != mode_b;
-}
-
static bool get_phase_flag(ir_phase *block_info, ir_node *block, int offset) {
return ((int)phase_get_irn_data(block_info, block)) & (1<<offset);
}
/* The switch Cond optimization might expose unreachable code, so we loop */
for (;;) {
int length;
+ ir_node **switch_conds = NULL;
env.changed = false;
env.phis_moved = false;
* Finally it marks all blocks that do not contain useful
* computations, i.e., these blocks might be removed.
*/
- env.switch_conds = NEW_ARR_F(ir_node*, 0);
- irg_walk(end, clear_link, collect_nodes, &env);
+ switch_conds = NEW_ARR_F(ir_node*, 0);
+ irg_walk(end, clear_link, collect_nodes, &switch_conds);
/* handle all collected switch-Conds */
- length = ARR_LEN(env.switch_conds);
+ length = ARR_LEN(switch_conds);
for (i = 0; i < length; ++i) {
- ir_node *cond = env.switch_conds[i];
+ ir_node *cond = switch_conds[i];
env.changed |= handle_switch_cond(cond);
}
- DEL_ARR_F(env.switch_conds);
+ DEL_ARR_F(switch_conds);
if (!env.changed) break;