Merge

Fri, 24 Jul 2020 13:37:11 +0100

author
andrew
date
Fri, 24 Jul 2020 13:37:11 +0100
changeset 9958
147bfde2dfd4
parent 9956
d961c6fee216
parent 9957
d2ec2776ad0c
child 9959
ccdd791d3a6f

Merge

     1.1 --- a/src/share/vm/opto/callnode.cpp	Fri Jul 24 13:16:58 2020 +0100
     1.2 +++ b/src/share/vm/opto/callnode.cpp	Fri Jul 24 13:37:11 2020 +0100
     1.3 @@ -1180,6 +1180,14 @@
     1.4    return (TypeFunc::Parms == idx);
     1.5  }
     1.6  
     1.7 +void SafePointNode::disconnect_from_root(PhaseIterGVN *igvn) {
     1.8 +  assert(Opcode() == Op_SafePoint, "only value for safepoint in loops");
     1.9 +  int nb = igvn->C->root()->find_prec_edge(this);
    1.10 +  if (nb != -1) {
    1.11 +    igvn->C->root()->rm_prec(nb);
    1.12 +  }
    1.13 +}
    1.14 +
    1.15  //==============  SafePointScalarObjectNode  ==============
    1.16  
    1.17  SafePointScalarObjectNode::SafePointScalarObjectNode(const TypeOopPtr* tp,
     2.1 --- a/src/share/vm/opto/callnode.hpp	Fri Jul 24 13:16:58 2020 +0100
     2.2 +++ b/src/share/vm/opto/callnode.hpp	Fri Jul 24 13:37:11 2020 +0100
     2.3 @@ -459,6 +459,8 @@
     2.4      return !_replaced_nodes.is_empty();
     2.5    }
     2.6  
     2.7 +  void disconnect_from_root(PhaseIterGVN *igvn);
     2.8 +
     2.9    // Standard Node stuff
    2.10    virtual int            Opcode() const;
    2.11    virtual bool           pinned() const { return true; }
     3.1 --- a/src/share/vm/opto/compile.cpp	Fri Jul 24 13:16:58 2020 +0100
     3.2 +++ b/src/share/vm/opto/compile.cpp	Fri Jul 24 13:37:11 2020 +0100
     3.3 @@ -2075,6 +2075,23 @@
     3.4  }
     3.5  
     3.6  
     3.7 +// Remove edges from "root" to each SafePoint at a backward branch.
     3.8 +// They were inserted during parsing (see add_safepoint()) to make
     3.9 +// infinite loops without calls or exceptions visible to root, i.e.,
    3.10 +// useful.
    3.11 +void Compile::remove_root_to_sfpts_edges() {
    3.12 +  Node *r = root();
    3.13 +  if (r != NULL) {
    3.14 +    for (uint i = r->req(); i < r->len(); ++i) {
    3.15 +      Node *n = r->in(i);
    3.16 +      if (n != NULL && n->is_SafePoint()) {
    3.17 +        r->rm_prec(i);
    3.18 +        --i;
    3.19 +      }
    3.20 +    }
    3.21 +  }
    3.22 +}
    3.23 +
    3.24  //------------------------------Optimize---------------------------------------
    3.25  // Given a graph, optimize it.
    3.26  void Compile::Optimize() {
    3.27 @@ -2130,6 +2147,10 @@
    3.28      if (failing())  return;
    3.29    }
    3.30  
    3.31 +  // Now that all inlining is over, cut edge from root to loop
    3.32 +  // safepoints
    3.33 +  remove_root_to_sfpts_edges();
    3.34 +
    3.35    // Remove the speculative part of types and clean up the graph from
    3.36    // the extra CastPP nodes whose only purpose is to carry them. Do
    3.37    // that early so that optimizations are not disrupted by the extra
    3.38 @@ -3012,8 +3033,10 @@
    3.39              break;
    3.40            }
    3.41          }
    3.42 -        assert(proj != NULL, "must be found");
    3.43 -        p->subsume_by(proj, this);
    3.44 +        assert(proj != NULL || p->_con == TypeFunc::I_O, "io may be dropped at an infinite loop");
    3.45 +        if (proj != NULL) {
    3.46 +          p->subsume_by(proj, this);
    3.47 +        }
    3.48        }
    3.49      }
    3.50      break;
     4.1 --- a/src/share/vm/opto/compile.hpp	Fri Jul 24 13:16:58 2020 +0100
     4.2 +++ b/src/share/vm/opto/compile.hpp	Fri Jul 24 13:37:11 2020 +0100
     4.3 @@ -959,6 +959,7 @@
     4.4    void inline_incrementally(PhaseIterGVN& igvn);
     4.5    void inline_string_calls(bool parse_time);
     4.6    void inline_boxing_calls(PhaseIterGVN& igvn);
     4.7 +  void remove_root_to_sfpts_edges();
     4.8  
     4.9    // Matching, CFG layout, allocation, code generation
    4.10    PhaseCFG*         cfg()                       { return _cfg; }
     5.1 --- a/src/share/vm/opto/node.cpp	Fri Jul 24 13:16:58 2020 +0100
     5.2 +++ b/src/share/vm/opto/node.cpp	Fri Jul 24 13:37:11 2020 +0100
     5.3 @@ -1329,6 +1329,9 @@
     5.4  
     5.5    while (nstack.size() > 0) {
     5.6      dead = nstack.pop();
     5.7 +    if (dead->Opcode() == Op_SafePoint) {
     5.8 +      dead->as_SafePoint()->disconnect_from_root(igvn);
     5.9 +    }
    5.10      if (dead->outcnt() > 0) {
    5.11        // Keep dead node on stack until all uses are processed.
    5.12        nstack.push(dead);
     6.1 --- a/src/share/vm/opto/phaseX.cpp	Fri Jul 24 13:16:58 2020 +0100
     6.2 +++ b/src/share/vm/opto/phaseX.cpp	Fri Jul 24 13:37:11 2020 +0100
     6.3 @@ -419,20 +419,6 @@
     6.4  
     6.5    // Disconnect 'useless' nodes that are adjacent to useful nodes
     6.6    C->remove_useless_nodes(_useful);
     6.7 -
     6.8 -  // Remove edges from "root" to each SafePoint at a backward branch.
     6.9 -  // They were inserted during parsing (see add_safepoint()) to make infinite
    6.10 -  // loops without calls or exceptions visible to root, i.e., useful.
    6.11 -  Node *root = C->root();
    6.12 -  if( root != NULL ) {
    6.13 -    for( uint i = root->req(); i < root->len(); ++i ) {
    6.14 -      Node *n = root->in(i);
    6.15 -      if( n != NULL && n->is_SafePoint() ) {
    6.16 -        root->rm_prec(i);
    6.17 -        --i;
    6.18 -      }
    6.19 -    }
    6.20 -  }
    6.21  }
    6.22  
    6.23  //=============================================================================
    6.24 @@ -1258,6 +1244,9 @@
    6.25  
    6.26    while (_stack.is_nonempty()) {
    6.27      dead = _stack.node();
    6.28 +    if (dead->Opcode() == Op_SafePoint) {
    6.29 +      dead->as_SafePoint()->disconnect_from_root(this);
    6.30 +    }
    6.31      uint progress_state = _stack.index();
    6.32      assert(dead != C->root(), "killing root, eh?");
    6.33      assert(!dead->is_top(), "add check for top when pushing");
    6.34 @@ -1352,6 +1341,9 @@
    6.35  //------------------------------subsume_node-----------------------------------
    6.36  // Remove users from node 'old' and add them to node 'nn'.
    6.37  void PhaseIterGVN::subsume_node( Node *old, Node *nn ) {
    6.38 +  if (old->Opcode() == Op_SafePoint) {
    6.39 +    old->as_SafePoint()->disconnect_from_root(this);
    6.40 +  }
    6.41    assert( old != hash_find(old), "should already been removed" );
    6.42    assert( old != C->top(), "cannot subsume top node");
    6.43    // Copy debug or profile information to the new version:
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/test/compiler/inlining/StringConcatInfiniteLoop.java	Fri Jul 24 13:37:11 2020 +0100
     7.3 @@ -0,0 +1,54 @@
     7.4 +/*
     7.5 + * Copyright (c) 2018, Red Hat, Inc. All rights reserved.
     7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.7 + *
     7.8 + * This code is free software; you can redistribute it and/or modify it
     7.9 + * under the terms of the GNU General Public License version 2 only, as
    7.10 + * published by the Free Software Foundation.
    7.11 + *
    7.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    7.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    7.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    7.15 + * version 2 for more details (a copy is included in the LICENSE file that
    7.16 + * accompanied this code).
    7.17 + *
    7.18 + * You should have received a copy of the GNU General Public License version
    7.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    7.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    7.21 + *
    7.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    7.23 + * or visit www.oracle.com if you need additional information or have any
    7.24 + * questions.
    7.25 + */
    7.26 +
    7.27 +/*
    7.28 + * @test 8214862
    7.29 + * @summary Multiple passes of PhaseRemoveUseless causes infinite loop to be optimized out
    7.30 + *
    7.31 + * @run main/othervm -XX:-TieredCompilation -Xcomp -XX:CompileOnly=StringConcatInfiniteLoop::test -XX:CompileCommand=dontinline,*StringBuilder::* StringConcatInfiniteLoop
    7.32 + *
    7.33 + */
    7.34 +
    7.35 +public class StringConcatInfiniteLoop {
    7.36 +    public static void main(String[] args) {
    7.37 +        StringBuilder sb = new StringBuilder();
    7.38 +        test(sb, "foo", "bar", true);
    7.39 +    }
    7.40 +
    7.41 +    private static void test(Object v, String s1, String s2, boolean flag) {
    7.42 +        if (flag) {
    7.43 +            return;
    7.44 +        }
    7.45 +        int i = 0;
    7.46 +        for (; i < 10; i++);
    7.47 +        if (i == 10) {
    7.48 +            v = null;
    7.49 +        }
    7.50 +        StringBuilder sb = new StringBuilder(s1);
    7.51 +        sb.append(s2);
    7.52 +        while (v == null);
    7.53 +    }
    7.54 +
    7.55 +    private static class A {
    7.56 +    }
    7.57 +}

mercurial