-/**
- * Optimize Bounds(idx, idx, upper) into idx.
- */
-static ir_node *transform_node_Proj_Bound(ir_node *proj)
-{
- ir_node *oldn = proj;
- ir_node *bound = get_Proj_pred(proj);
- ir_node *idx = get_Bound_index(bound);
- ir_node *pred = skip_Proj(idx);
- int ret_tuple = 0;
-
- if (idx == get_Bound_lower(bound))
- ret_tuple = 1;
- else if (is_Bound(pred)) {
- /*
- * idx was Bounds checked previously, it is still valid if
- * lower <= pred_lower && pred_upper <= upper.
- */
- ir_node *lower = get_Bound_lower(bound);
- ir_node *upper = get_Bound_upper(bound);
- if (get_Bound_lower(pred) == lower &&
- get_Bound_upper(pred) == upper) {
- /*
- * One could expect that we simply return the previous
- * Bound here. However, this would be wrong, as we could
- * add an exception Proj to a new location then.
- * So, we must turn in into a tuple.
- */
- ret_tuple = 1;
- }
- }
- if (ret_tuple) {
- /* Turn Bound into a tuple (mem, jmp, bad, idx) */
- switch (get_Proj_proj(proj)) {
- case pn_Bound_M:
- DBG_OPT_EXC_REM(proj);
- proj = get_Bound_mem(bound);
- break;
- case pn_Bound_X_except:
- DBG_OPT_EXC_REM(proj);
- proj = new_r_Bad(get_irn_irg(proj), mode_X);
- break;
- case pn_Bound_res:
- proj = idx;
- DBG_OPT_ALGSIM0(oldn, proj, FS_OPT_NOP);
- break;
- case pn_Bound_X_regular:
- DBG_OPT_EXC_REM(proj);
- proj = new_r_Jmp(get_nodes_block(bound));
- break;
- default:
- break;
- }
- }
- return proj;
-}
-