# HG changeset patch # User vdeshpande # Date 1471980365 25200 # Node ID a7a6aada8883dbaec8ddc6c94434d797e899e4aa # Parent 5c4adc260369e7499dfedba902e6e7affad8ac66 8151988: Hotspot deoptimizes div/mod pair usage Summary: don't remove control edge of Mod node until DivMod node matching Reviewed-by: kvn diff -r 5c4adc260369 -r a7a6aada8883 hotspot/src/share/vm/opto/compile.cpp --- a/hotspot/src/share/vm/opto/compile.cpp Tue Aug 23 18:03:37 2016 +0000 +++ b/hotspot/src/share/vm/opto/compile.cpp Tue Aug 23 12:26:05 2016 -0700 @@ -3159,45 +3159,65 @@ break; #endif - case Op_ModI: + case Op_ModI: { + Node* di = NULL; if (UseDivMod) { // Check if a%b and a/b both exist - Node* d = n->find_similar(Op_DivI); - if (d) { + di = n->find_similar(Op_DivI); + if (di) { // Replace them with a fused divmod if supported if (Matcher::has_match_rule(Op_DivModI)) { DivModINode* divmod = DivModINode::make(n); - d->subsume_by(divmod->div_proj(), this); + di->subsume_by(divmod->div_proj(), this); n->subsume_by(divmod->mod_proj(), this); } else { // replace a%b with a-((a/b)*b) - Node* mult = new MulINode(d, d->in(2)); - Node* sub = new SubINode(d->in(1), mult); + Node* mult = new MulINode(di, di->in(2)); + Node* sub = new SubINode(di->in(1), mult); n->subsume_by(sub, this); } } } + if (di == NULL) { + // Remove useless control edge in case of not mod-zero. + const Type *t = n->in(2)->bottom_type(); + const TypeInt *ti = t->is_int(); + if (n->in(0) && (ti->_hi < 0 || ti->_lo > 0)) { + n->set_req(0, NULL); + } + } break; - - case Op_ModL: + } + + case Op_ModL: { + Node* dl = NULL; if (UseDivMod) { // Check if a%b and a/b both exist - Node* d = n->find_similar(Op_DivL); - if (d) { + dl = n->find_similar(Op_DivL); + if (dl) { // Replace them with a fused divmod if supported if (Matcher::has_match_rule(Op_DivModL)) { DivModLNode* divmod = DivModLNode::make(n); - d->subsume_by(divmod->div_proj(), this); + dl->subsume_by(divmod->div_proj(), this); n->subsume_by(divmod->mod_proj(), this); } else { // replace a%b with a-((a/b)*b) - Node* mult = new MulLNode(d, d->in(2)); - Node* sub = new SubLNode(d->in(1), mult); + Node* mult = new MulLNode(dl, dl->in(2)); + Node* sub = new SubLNode(dl->in(1), mult); n->subsume_by(sub, this); } } } + if (dl == NULL) { + // Remove useless control edge in case of not mod-zero. + const Type *t = n->in(2)->bottom_type(); + const TypeLong *tl = t->is_long(); + if (n->in(0) && (tl->_hi < 0 || tl->_lo > 0)) { + n->set_req(0, NULL); + } + } break; + } case Op_LoadVector: case Op_StoreVector: diff -r 5c4adc260369 -r a7a6aada8883 hotspot/src/share/vm/opto/divnode.cpp --- a/hotspot/src/share/vm/opto/divnode.cpp Tue Aug 23 18:03:37 2016 +0000 +++ b/hotspot/src/share/vm/opto/divnode.cpp Tue Aug 23 12:26:05 2016 -0700 @@ -853,13 +853,6 @@ if( t == Type::TOP ) return NULL; const TypeInt *ti = t->is_int(); - // Check for useless control input - // Check for excluding mod-zero case - if( in(0) && (ti->_hi < 0 || ti->_lo > 0) ) { - set_req(0, NULL); // Yank control input - return this; - } - // See if we are MOD'ing by 2^k or 2^k-1. if( !ti->is_con() ) return NULL; jint con = ti->get_con(); @@ -1024,13 +1017,6 @@ if( t == Type::TOP ) return NULL; const TypeLong *tl = t->is_long(); - // Check for useless control input - // Check for excluding mod-zero case - if( in(0) && (tl->_hi < 0 || tl->_lo > 0) ) { - set_req(0, NULL); // Yank control input - return this; - } - // See if we are MOD'ing by 2^k or 2^k-1. if( !tl->is_con() ) return NULL; jlong con = tl->get_con();