src/share/vm/opto/castnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/share/vm/opto/castnode.cpp	Wed Sep 17 18:42:42 2014
--- new/src/share/vm/opto/castnode.cpp	Wed Sep 17 18:42:42 2014

*** 81,90 **** --- 81,179 ---- set_type(t); // Turn into ID function ccp->hash_insert(this); return this; } + Node *CastIINode::Identity(PhaseTransform *phase) { + if (_inexact) { + return this; + } + return ConstraintCastNode::Identity(phase); + } + + Node *CastIINode::Ideal(PhaseGVN *phase, bool can_reshape) { + Node* res = ConstraintCastNode::Ideal(phase, can_reshape); + // Try to improve the type of the CastII if we recognize a CmpI/If + // pattern. + if (res == NULL && _inexact) { + if (in(0) != NULL && (in(0)->is_IfFalse() || in(0)->is_IfTrue())) { + Node* proj = in(0); + if (proj->in(0)->in(1)->is_Bool()) { + Node* b = proj->in(0)->in(1); + if (b->in(1)->Opcode() == Op_CmpI) { + Node* cmp = b->in(1); + if (cmp->in(1) == in(1)) { + const TypeInt* in2_t = phase->type(cmp->in(2))->is_int(); + const Type* t = TypeInt::INT; + BoolTest test = b->as_Bool()->_test; + if (proj->is_IfFalse()) { + test = test.negate(); + } + BoolTest::mask m = test._test; + jlong lo_long = min_jint; + jlong hi_long = max_jint; + if (m == BoolTest::le || m == BoolTest::lt) { + hi_long = in2_t->_hi; + if (m == BoolTest::lt) { + hi_long -= 1; + } + } else if (m == BoolTest::ge || m == BoolTest::gt) { + lo_long = in2_t->_lo; + if (m == BoolTest::gt) { + lo_long += 1; + } + } else if (m == BoolTest::eq) { + lo_long = in2_t->_lo; + hi_long = in2_t->_hi; + } else if (m == BoolTest::ne) { + // can't do any better + } else { + ShouldNotReachHere(); + } + int lo_int = (int)lo_long; + int hi_int = (int)hi_long; + + if (lo_long != (jlong)lo_int) { + lo_int = min_jint; + } + if (hi_long != (jlong)hi_int) { + hi_int = max_jint; + } + + t = TypeInt::make(lo_int, hi_int, Type::WidenMax); + t = t->filter_speculative(_type); + if (_type != t || in2_t->is_con()) { + CastIINode* castii = new CastIINode(in(1), t, _required, !in2_t->is_con()); + castii->set_req(0, in(0)); + res = castii; + } + } + } + } + } + } + return res; + } + + Node *CastIINode::Ideal_DU_postCCP(PhaseCCP *ccp) { + if (_required) { + return NULL; + } + return ConstraintCastNode::Ideal_DU_postCCP(ccp); + } + + #ifndef PRODUCT + void CastIINode::dump_spec(outputStream *st) const { + TypeNode::dump_spec(st); + if (_inexact) { + st->print(" inexact"); + } + if (_required) { + st->print(" required"); + } + } + #endif //============================================================================= //------------------------------Ideal_DU_postCCP------------------------------- // If not converting int->oop, throw away cast after constant propagation

src/share/vm/opto/castnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File