+static ir_node *find_candidate(condeval_env_t *env, ir_node *jump,
+ ir_node *value)
+{
+ ir_node *block = get_nodes_block(jump);
+
+ if(irn_visited(value)) {
+ return NULL;
+ }
+ mark_irn_visited(value);
+
+ if (is_Const_or_Confirm(value)) {
+ tarval *tv = get_Const_or_Confirm_tarval(value);
+
+ if (tv != env->tv)
+ return NULL;
+
+ DB((
+ dbg, LEVEL_1,
+ "> Found condition evaluation candidate %+F->%+F\n",
+ env->true_block, block
+ ));
+
+ /* adjust true_block to point directly towards our jump */
+ add_pred(env->true_block, jump);
+
+ split_critical_edge(env->true_block, 0);
+
+ /* we need a bigger visited nr when going back */
+ env->visited_nr++;
+
+ return block;
+ }
+ if(is_Phi(value)) {
+ int i, arity;
+
+ /* the Phi has to be in the same Block as the Jmp */
+ if(get_nodes_block(value) != block)
+ return NULL;
+
+ arity = get_irn_arity(value);
+ for(i = 0; i < arity; ++i) {
+ ir_node *copy_block;
+ ir_node *phi_pred = get_Phi_pred(value, i);
+ ir_node *cfgpred = get_Block_cfgpred(block, i);
+
+ copy_block = find_candidate(env, cfgpred, phi_pred);
+ if(copy_block == NULL)
+ continue;
+
+ /* copy duplicated nodes in copy_block and fix SSA */
+ copy_and_fix(env, block, copy_block, i);
+
+ if(copy_block == get_nodes_block(cfgpred)) {
+ env->cnst_pred = block;
+ env->cnst_pos = i;
+ }
+
+ /* return now as we can't process more possibilities in 1 run */
+ return copy_block;
+ }
+ }
+ if(is_Proj(value)) {
+ ir_node *left;
+ ir_node *right;
+ int pnc;
+ ir_node *cmp = get_Proj_pred(value);
+ if(!is_Cmp(cmp))
+ return NULL;
+
+ left = get_Cmp_left(cmp);
+ right = get_Cmp_right(cmp);
+ pnc = get_Proj_proj(value);
+
+ /* we assume that the constant is on the right side, swap left/right
+ * if needed */
+ if(is_Const(left)) {
+ ir_node *t = left;
+ left = right;
+ right = t;
+
+ pnc = get_inversed_pnc(pnc);
+ }
+
+ if(!is_Const(right))
+ return 0;
+
+ if(get_nodes_block(left) != block) {
+ return 0;
+ }
+
+ /* negate condition when we're looking for the false block */
+ if(env->tv == tarval_b_false) {
+ pnc = get_negated_pnc(pnc, get_irn_mode(right));
+ }
+
+ /* (recursively) look if a pred of a Phi is a constant or a Confirm */
+ env->cmp = cmp;
+ env->pnc = pnc;
+ env->cnst = right;
+
+ return find_const_or_confirm(env, jump, left);
+ }
+
+ return NULL;
+}