< prev index next >
src/share/vm/opto/phaseX.cpp
Print this page
*** 1,7 ****
/*
! * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 1414,1423 ****
--- 1414,1444 ----
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
_worklist.push(n->fast_out(i)); // Push on worklist
}
}
+ // Return counted loop Phi if as a counted loop exit condition, cmp
+ // compares the the induction variable with n
+ static PhiNode* countedloop_phi_from_cmp(CmpINode* cmp, Node* n) {
+ for (DUIterator_Fast imax, i = cmp->fast_outs(imax); i < imax; i++) {
+ Node* bol = cmp->fast_out(i);
+ for (DUIterator_Fast i2max, i2 = bol->fast_outs(i2max); i2 < i2max; i2++) {
+ Node* iff = bol->fast_out(i2);
+ if (iff->is_CountedLoopEnd()) {
+ CountedLoopEndNode* cle = iff->as_CountedLoopEnd();
+ if (cle->limit() == n) {
+ PhiNode* phi = cle->phi();
+ if (phi != NULL) {
+ return phi;
+ }
+ }
+ }
+ }
+ }
+ return NULL;
+ }
+
void PhaseIterGVN::add_users_to_worklist( Node *n ) {
add_users_to_worklist0(n);
// Move users of node to worklist
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
*** 1443,1464 ****
add_users_to_worklist(use); // Put Bool on worklist
if (use->outcnt() > 0) {
Node* bol = use->raw_out(0);
if (bol->outcnt() > 0) {
Node* iff = bol->raw_out(0);
! if (use_op == Op_CmpI &&
! iff->is_CountedLoopEnd()) {
! CountedLoopEndNode* cle = iff->as_CountedLoopEnd();
! if (cle->limit() == n && cle->phi() != NULL) {
! // If an opaque node feeds into the limit condition of a
! // CountedLoop, we need to process the Phi node for the
! // induction variable when the opaque node is removed:
! // the range of values taken by the Phi is now known and
! // so its type is also known.
! _worklist.push(cle->phi());
! }
! } else if (iff->outcnt() == 2) {
// Look for the 'is_x2logic' pattern: "x ? : 0 : 1" and put the
// phi merging either 0 or 1 onto the worklist
Node* ifproj0 = iff->raw_out(0);
Node* ifproj1 = iff->raw_out(1);
if (ifproj0->outcnt() > 0 && ifproj1->outcnt() > 0) {
--- 1464,1474 ----
add_users_to_worklist(use); // Put Bool on worklist
if (use->outcnt() > 0) {
Node* bol = use->raw_out(0);
if (bol->outcnt() > 0) {
Node* iff = bol->raw_out(0);
! if (iff->outcnt() == 2) {
// Look for the 'is_x2logic' pattern: "x ? : 0 : 1" and put the
// phi merging either 0 or 1 onto the worklist
Node* ifproj0 = iff->raw_out(0);
Node* ifproj1 = iff->raw_out(1);
if (ifproj0->outcnt() > 0 && ifproj1->outcnt() > 0) {
*** 1469,1478 ****
--- 1479,1497 ----
}
}
}
}
if (use_op == Op_CmpI) {
+ Node* phi = countedloop_phi_from_cmp((CmpINode*)use, n);
+ if (phi != NULL) {
+ // If an opaque node feeds into the limit condition of a
+ // CountedLoop, we need to process the Phi node for the
+ // induction variable when the opaque node is removed:
+ // the range of values taken by the Phi is now known and
+ // so its type is also known.
+ _worklist.push(phi);
+ }
Node* in1 = use->in(1);
for (uint i = 0; i < in1->outcnt(); i++) {
if (in1->raw_out(i)->Opcode() == Op_CastII) {
Node* castii = in1->raw_out(i);
if (castii->in(0) != NULL && castii->in(0)->in(0) != NULL && castii->in(0)->in(0)->is_If()) {
*** 1657,1666 ****
--- 1676,1694 ----
worklist.push(p); // Propagate change to user
}
}
}
}
+ // If n is used in a counted loop exit condition then the type
+ // of the counted loop's Phi depends on the type of n. See
+ // PhiNode::Value().
+ if (m_op == Op_CmpI) {
+ PhiNode* phi = countedloop_phi_from_cmp((CmpINode*)m, n);
+ if (phi != NULL) {
+ worklist.push(phi);
+ }
+ }
}
}
}
}
< prev index next >