+ ir_node *a = get_DivMod_left(n);
+ ir_node *b = get_DivMod_right(n);
+ ir_mode *mode = get_irn_mode(a);
+ tarval *ta = value_of(a);
+ tarval *tb = value_of(b);
+
+ if (!(mode_is_int(mode) && mode_is_int(get_irn_mode(b))))
+ return n;
+
+ /* BEWARE: it is NOT possible to optimize a/a to 1, as this may cause a exception */
+
+ if (tb != tarval_bad) {
+ if (tb == get_mode_one(get_tarval_mode(tb))) {
+ b = new_Const (mode, get_mode_null(mode));
+ evaluated = 1;
+ } else if (ta != tarval_bad) {
+ tarval *resa, *resb;
+ resa = tarval_div (ta, tb);
+ if (resa == tarval_bad) return n; /* Causes exception!!! Model by replacing through
+ Jmp for X result!? */
+ resb = tarval_mod (ta, tb);
+ if (resb == tarval_bad) return n; /* Causes exception! */
+ a = new_Const (mode, resa);
+ b = new_Const (mode, resb);
+ evaluated = 1;
+ }
+ } else if (ta == get_mode_null(mode)) {
+ b = a;
+ evaluated = 1;
+ }
+ if (evaluated) { /* replace by tuple */
+ ir_node *mem = get_DivMod_mem(n);
+ turn_into_tuple(n, 4);
+ set_Tuple_pred(n, pn_DivMod_M, mem);
+ set_Tuple_pred(n, pn_DivMod_X_except, new_Bad()); /* no exception */
+ set_Tuple_pred(n, pn_DivMod_res_div, a);
+ set_Tuple_pred(n, pn_DivMod_res_mod, b);
+ assert(get_nodes_block(n));
+ }
+
+ return n;
+}
+
+static ir_node *transform_node_Cond(ir_node *n)
+{
+ /* Replace the Cond by a Jmp if it branches on a constant
+ condition. */
+ ir_node *jmp;
+ ir_node *a = get_Cond_selector(n);
+ tarval *ta = value_of(a);
+
+ if ((ta != tarval_bad) &&
+ (get_irn_mode(a) == mode_b) &&
+ (get_opt_unreachable_code())) {
+ /* It's a boolean Cond, branching on a boolean constant.
+ Replace it by a tuple (Bad, Jmp) or (Jmp, Bad) */
+ jmp = new_r_Jmp(current_ir_graph, get_nodes_block(n));
+ turn_into_tuple(n, 2);
+ if (ta == tarval_b_true) {
+ set_Tuple_pred(n, pn_Cond_false, new_Bad());
+ set_Tuple_pred(n, pn_Cond_true, jmp);
+ } else {
+ set_Tuple_pred(n, pn_Cond_false, jmp);
+ set_Tuple_pred(n, pn_Cond_true, new_Bad());
+ }
+ /* We might generate an endless loop, so keep it alive. */
+ add_End_keepalive(get_irg_end(current_ir_graph), get_nodes_block(n));
+ } else if ((ta != tarval_bad) &&
+ (get_irn_mode(a) == mode_Iu) &&
+ (get_Cond_kind(n) == dense) &&
+ (get_opt_unreachable_code())) {
+ /* I don't want to allow Tuples smaller than the biggest Proj.
+ Also this tuple might get really big...
+ I generate the Jmp here, and remember it in link. Link is used
+ when optimizing Proj. */
+ set_irn_link(n, new_r_Jmp(current_ir_graph, get_nodes_block(n)));
+ /* We might generate an endless loop, so keep it alive. */
+ add_End_keepalive(get_irg_end(current_ir_graph), get_nodes_block(n));
+ } else if ((get_irn_op(a) == op_Eor)
+ && (get_irn_mode(a) == mode_b)
+ && (classify_tarval(computed_value(get_Eor_right(a))) == TV_CLASSIFY_ONE)) {
+ /* The Eor is a negate. Generate a new Cond without the negate,
+ simulate the negate by exchanging the results. */
+ set_irn_link(n, new_r_Cond(current_ir_graph, get_nodes_block(n),
+ get_Eor_left(a)));
+ } else if ((get_irn_op(a) == op_Not)
+ && (get_irn_mode(a) == mode_b)) {
+ /* A Not before the Cond. Generate a new Cond without the Not,
+ simulate the Not by exchanging the results. */
+ set_irn_link(n, new_r_Cond(current_ir_graph, get_nodes_block(n),
+ get_Not_op(a)));
+ }
+ return n;
+}
+
+static ir_node *transform_node_Eor(ir_node *n)
+{
+ ir_node *a = get_Eor_left(n);
+ ir_node *b = get_Eor_right(n);
+
+ if ((get_irn_mode(n) == mode_b)
+ && (get_irn_op(a) == op_Proj)
+ && (get_irn_mode(a) == mode_b)
+ && (classify_tarval (computed_value (b)) == TV_CLASSIFY_ONE)
+ && (get_irn_op(get_Proj_pred(a)) == op_Cmp))
+ /* The Eor negates a Cmp. The Cmp has the negated result anyways! */
+ n = new_r_Proj(current_ir_graph, get_nodes_block(n), get_Proj_pred(a),
+ mode_b, get_negated_pnc(get_Proj_proj(a)));
+ else if ((get_irn_mode(n) == mode_b)
+ && (classify_tarval (computed_value (b)) == TV_CLASSIFY_ONE))
+ /* The Eor is a Not. Replace it by a Not. */
+ /* ????!!!Extend to bitfield 1111111. */
+ n = new_r_Not(current_ir_graph, get_nodes_block(n), a, mode_b);
+
+ return n;
+}
+
+/**
+ * Transfor a boolean Not.
+ */
+static ir_node *transform_node_Not(ir_node *n)
+{
+ ir_node *a = get_Not_op(n);
+
+ if ( (get_irn_mode(n) == mode_b)
+ && (get_irn_op(a) == op_Proj)
+ && (get_irn_mode(a) == mode_b)
+ && (get_irn_op(get_Proj_pred(a)) == op_Cmp))
+ /* We negate a Cmp. The Cmp has the negated result anyways! */
+ n = new_r_Proj(current_ir_graph, get_nodes_block(n), get_Proj_pred(a),
+ mode_b, get_negated_pnc(get_Proj_proj(a)));
+
+ return n;
+}
+
+/**
+ * Transform a Div/Mod/DivMod with a non-zero constant. Must be
+ * done here instead of equivalent node because in creates new
+ * nodes.
+ */
+static ir_node *transform_node_Proj(ir_node *proj)
+{
+ ir_node *n = get_Proj_pred(proj);
+ ir_node *b;
+ tarval *tb;