diff --git a/src/share/vm/opto/loopnode.hpp b/src/share/vm/opto/loopnode.hpp index 63934ea36c54905050fd6d2929f4d265a9cf27ed..d97bf07ca7fa1904f4cd5154cb08fe0303f4a7c0 100644 --- a/src/share/vm/opto/loopnode.hpp +++ b/src/share/vm/opto/loopnode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -257,19 +257,29 @@ public: Node *incr() const { Node *tmp = cmp_node(); return (tmp && tmp->req()==3) ? tmp->in(1) : NULL; } Node *limit() const { Node *tmp = cmp_node(); return (tmp && tmp->req()==3) ? tmp->in(2) : NULL; } Node *stride() const { Node *tmp = incr (); return (tmp && tmp->req()==3) ? tmp->in(2) : NULL; } - Node *phi() const { Node *tmp = incr (); return (tmp && tmp->req()==3) ? tmp->in(1) : NULL; } Node *init_trip() const { Node *tmp = phi (); return (tmp && tmp->req()==3) ? tmp->in(1) : NULL; } int stride_con() const; bool stride_is_con() const { Node *tmp = stride (); return (tmp != NULL && tmp->is_Con()); } BoolTest::mask test_trip() const { return in(TestValue)->as_Bool()->_test._test; } + PhiNode *phi() const { + Node *tmp = incr(); + if (tmp && tmp->req() == 3) { + Node* phi = tmp->in(1); + if (phi->is_Phi()) { + return phi->as_Phi(); + } + } + return NULL; + } CountedLoopNode *loopnode() const { // The CountedLoopNode that goes with this CountedLoopEndNode may // have been optimized out by the IGVN so be cautious with the // pattern matching on the graph - if (phi() == NULL) { + PhiNode* iv_phi = phi(); + if (iv_phi == NULL) { return NULL; } - Node *ln = phi()->in(0); + Node *ln = iv_phi->in(0); if (ln->is_CountedLoop() && ln->as_CountedLoop()->loopexit() == this) { return (CountedLoopNode*)ln; } diff --git a/src/share/vm/opto/phaseX.cpp b/src/share/vm/opto/phaseX.cpp index 1782cb9cb7b136301858dcf04d09d7967f0cbd27..2117c888334d651d5473a7fae59f9b1cd2a3f622 100644 --- a/src/share/vm/opto/phaseX.cpp +++ b/src/share/vm/opto/phaseX.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -1416,6 +1416,27 @@ void PhaseIterGVN::add_users_to_worklist0( Node *n ) { } } +// 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); @@ -1445,18 +1466,7 @@ void PhaseIterGVN::add_users_to_worklist( Node *n ) { 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) { + 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); @@ -1471,6 +1481,15 @@ void PhaseIterGVN::add_users_to_worklist( Node *n ) { } } 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) { @@ -1659,6 +1678,15 @@ void PhaseCCP::analyze() { } } } + // 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); + } + } } } } diff --git a/src/share/vm/opto/phaseX.hpp b/src/share/vm/opto/phaseX.hpp index ef55c0ec7b322a0e8898c90e7e42f9f0c676bf27..a2a2a538b99fda0172f55e40d4526f938693fb53 100644 --- a/src/share/vm/opto/phaseX.hpp +++ b/src/share/vm/opto/phaseX.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -417,7 +417,7 @@ public: // Phase for iteratively performing local, pessimistic GVN-style optimizations. // and ideal transformations on the graph. class PhaseIterGVN : public PhaseGVN { - private: +private: bool _delay_transform; // When true simply register the node when calling transform // instead of actually optimizing it