void Canonicalizer::do_Op2(Op2* x) { if (x->x() == x->y()) { switch (x->op()) { case Bytecodes::_isub: set_constant(0); return; case Bytecodes::_lsub: set_constant(jlong_cast(0)); return; case Bytecodes::_iand: // fall through case Bytecodes::_land: // fall through case Bytecodes::_ior: // fall through case Bytecodes::_lor : set_canonical(x->x()); return; case Bytecodes::_ixor: set_constant(0); return; case Bytecodes::_lxor: set_constant(jlong_cast(0)); return; } } if (x->x()->type()->is_constant() && x->y()->type()->is_constant()) { // do constant folding for selected operations switch (x->type()->tag()) { case intTag: { jint a = x->x()->type()->as_IntConstant()->value(); jint b = x->y()->type()->as_IntConstant()->value(); switch (x->op()) { case Bytecodes::_iadd: set_constant(a + b); return; case Bytecodes::_isub: set_constant(a - b); return; case Bytecodes::_imul: set_constant(a * b); return; case Bytecodes::_idiv: if (b != 0) { if (a == min_jint && b == -1) { set_constant(min_jint); } else { set_constant(a / b); } return; } break; case Bytecodes::_irem: if (b != 0) { if (a == min_jint && b == -1) { set_constant(0); } else { set_constant(a % b); } return; } break; case Bytecodes::_iand: set_constant(a & b); return; case Bytecodes::_ior : set_constant(a | b); return; case Bytecodes::_ixor: set_constant(a ^ b); return; } } break; case longTag: { jlong a = x->x()->type()->as_LongConstant()->value(); jlong b = x->y()->type()->as_LongConstant()->value(); switch (x->op()) { case Bytecodes::_ladd: set_constant(a + b); return; case Bytecodes::_lsub: set_constant(a - b); return; case Bytecodes::_lmul: set_constant(a * b); return; case Bytecodes::_ldiv: if (b != 0) { set_constant(SharedRuntime::ldiv(b, a)); return; } break; case Bytecodes::_lrem: if (b != 0) { set_constant(SharedRuntime::lrem(b, a)); return; } break; case Bytecodes::_land: set_constant(a & b); return; case Bytecodes::_lor : set_constant(a | b); return; case Bytecodes::_lxor: set_constant(a ^ b); return; } } break; // other cases not implemented (must be extremely careful with floats & doubles!) } } // make sure constant is on the right side, if any move_const_to_right(x); if (x->y()->type()->is_constant()) { // do constant folding for selected operations switch (x->type()->tag()) { case intTag: if (x->y()->type()->as_IntConstant()->value() == 0) { switch (x->op()) { case Bytecodes::_iadd: set_canonical(x->x()); return; case Bytecodes::_isub: set_canonical(x->x()); return; case Bytecodes::_imul: set_constant(0); return; // Note: for div and rem, make sure that C semantics // corresponds to Java semantics! case Bytecodes::_iand: set_constant(0); return; case Bytecodes::_ior : set_canonical(x->x()); return; } } break; case longTag: if (x->y()->type()->as_LongConstant()->value() == (jlong)0) { switch (x->op()) { case Bytecodes::_ladd: set_canonical(x->x()); return; case Bytecodes::_lsub: set_canonical(x->x()); return; case Bytecodes::_lmul: set_constant((jlong)0); return; // Note: for div and rem, make sure that C semantics // corresponds to Java semantics! case Bytecodes::_land: set_constant((jlong)0); return; case Bytecodes::_lor : set_canonical(x->x()); return; } } break; } } }
void Canonicalizer::do_IfOp(IfOp* x) { // Caution: do not use do_Op2(x) here for now since // we map the condition to the op for now! move_const_to_right(x); }