< 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 >