changeset 60381:b639fff3fc5a

8240794: [BACKOUT] 8238384 CTW: C2 compilation fails with "assert(store != load->find_exact_control(load->in(0))) failed: dependence cycle found" Reviewed-by: thartmann
author roland
date Tue, 10 Mar 2020 10:45:01 +0100
parents 7e741a3fc650
children 7c057af653f9
files src/hotspot/share/opto/compile.cpp src/hotspot/share/opto/gcm.cpp src/hotspot/share/opto/loopnode.cpp src/hotspot/share/opto/macro.hpp src/hotspot/share/opto/macroArrayCopy.cpp src/hotspot/share/opto/type.hpp test/hotspot/jtreg/compiler/escapeAnalysis/TestCopyOfBrokenAntiDependency.java
diffstat 7 files changed, 20 insertions(+), 82 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/opto/compile.cpp	Mon Mar 09 22:41:11 2020 +0100
+++ b/src/hotspot/share/opto/compile.cpp	Tue Mar 10 10:45:01 2020 +0100
@@ -1905,9 +1905,8 @@
 bool Compile::can_alias(const TypePtr* adr_type, int alias_idx) {
   if (alias_idx == AliasIdxTop)         return false; // the empty category
   if (adr_type == NULL)                 return false; // NULL serves as TypePtr::TOP
-  // Known instance doesn't alias with bottom memory
-  if (alias_idx == AliasIdxBot)         return !adr_type->is_known_instance();                   // the universal category
-  if (adr_type->base() == Type::AnyPtr) return !C->get_adr_type(alias_idx)->is_known_instance(); // TypePtr::BOTTOM or its twins
+  if (alias_idx == AliasIdxBot)         return true;  // the universal category
+  if (adr_type->base() == Type::AnyPtr) return true;  // TypePtr::BOTTOM or its twins
 
   // the only remaining possible overlap is identity
   int adr_idx = get_alias_index(adr_type);
--- a/src/hotspot/share/opto/gcm.cpp	Mon Mar 09 22:41:11 2020 +0100
+++ b/src/hotspot/share/opto/gcm.cpp	Tue Mar 10 10:45:01 2020 +0100
@@ -707,6 +707,19 @@
         // instead of control + memory.
         if (mstore->ideal_Opcode() == Op_SafePoint)
           continue;
+
+        // Check if the store is a membar on which the load is control dependent.
+        // Inserting an anti-dependency between that membar and the load would
+        // create a cycle that causes local scheduling to fail.
+        if (mstore->isa_MachMemBar()) {
+          Node* dom = load->find_exact_control(load->in(0));
+          while (dom != NULL && dom != dom->in(0) && dom != mstore) {
+            dom = dom->in(0);
+          }
+          if (dom == mstore) {
+            continue;
+          }
+        }
       } else {
         // Some raw memory, such as the load of "top" at an allocation,
         // can be control dependent on the previous safepoint. See
--- a/src/hotspot/share/opto/loopnode.cpp	Mon Mar 09 22:41:11 2020 +0100
+++ b/src/hotspot/share/opto/loopnode.cpp	Tue Mar 10 10:45:01 2020 +0100
@@ -31,7 +31,6 @@
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "opto/addnode.hpp"
-#include "opto/arraycopynode.hpp"
 #include "opto/callnode.hpp"
 #include "opto/connode.hpp"
 #include "opto/convertnode.hpp"
@@ -4090,16 +4089,8 @@
           }
         } else {
           Node *sctrl = has_ctrl(s) ? get_ctrl(s) : s->in(0);
-          const TypePtr* adr_type = s->adr_type();
-          if (s->is_ArrayCopy()) {
-            // Copy to known instance needs destination type to test for aliasing
-            const TypePtr* dest_type = s->as_ArrayCopy()->_dest_type;
-            if (dest_type != TypeOopPtr::BOTTOM) {
-              adr_type = dest_type;
-            }
-          }
           assert(sctrl != NULL || !s->is_reachable_from_root(), "must have control");
-          if (sctrl != NULL && !sctrl->is_top() && C->can_alias(adr_type, load_alias_idx) && is_dominator(early, sctrl)) {
+          if (sctrl != NULL && !sctrl->is_top() && C->can_alias(s->adr_type(), load_alias_idx) && is_dominator(early, sctrl)) {
             LCA = dom_lca_for_get_late_ctrl(LCA, sctrl, n);
           }
         }
--- a/src/hotspot/share/opto/macro.hpp	Mon Mar 09 22:41:11 2020 +0100
+++ b/src/hotspot/share/opto/macro.hpp	Tue Mar 10 10:45:01 2020 +0100
@@ -119,7 +119,7 @@
   void expand_unlock_node(UnlockNode *unlock);
 
   // More helper methods modeled after GraphKit for array copy
-  void insert_mem_bar(Node** ctrl, Node** mem, int opcode, int alias_idx = Compile::AliasIdxBot, Node* precedent = NULL);
+  void insert_mem_bar(Node** ctrl, Node** mem, int opcode, Node* precedent = NULL);
   Node* array_element_address(Node* ary, Node* idx, BasicType elembt);
   Node* ConvI2L(Node* offset);
 
--- a/src/hotspot/share/opto/macroArrayCopy.cpp	Mon Mar 09 22:41:11 2020 +0100
+++ b/src/hotspot/share/opto/macroArrayCopy.cpp	Tue Mar 10 10:45:01 2020 +0100
@@ -33,8 +33,8 @@
 #include "utilities/align.hpp"
 #include "utilities/powerOfTwo.hpp"
 
-void PhaseMacroExpand::insert_mem_bar(Node** ctrl, Node** mem, int opcode, int alias_idx, Node* precedent) {
-  MemBarNode* mb = MemBarNode::make(C, opcode, alias_idx, precedent);
+void PhaseMacroExpand::insert_mem_bar(Node** ctrl, Node** mem, int opcode, Node* precedent) {
+  MemBarNode* mb = MemBarNode::make(C, opcode, Compile::AliasIdxBot, precedent);
   mb->init_req(TypeFunc::Control, *ctrl);
   mb->init_req(TypeFunc::Memory, *mem);
   transform_later(mb);
@@ -706,15 +706,7 @@
   // the membar also.
   //
   // Do not let reads from the cloned object float above the arraycopy.
-  if (ac->_dest_type != TypeOopPtr::BOTTOM && adr_type != ac->_dest_type) {
-    // Known instance: add memory of the destination type
-    MergeMemNode* mm = out_mem->clone()->as_MergeMem();
-    transform_later(mm);
-    uint dest_idx = C->get_alias_index(ac->_dest_type);
-    insert_mem_bar(ctrl, &out_mem, Op_MemBarCPUOrder, dest_idx);
-    mm->set_memory_at(dest_idx, out_mem);
-    out_mem = mm;
-  } else if (alloc != NULL && !alloc->initialization()->does_not_escape()) {
+  if (alloc != NULL && !alloc->initialization()->does_not_escape()) {
     // Do not let stores that initialize this object be reordered with
     // a subsequent store that would make this object accessible by
     // other threads.
--- a/src/hotspot/share/opto/type.hpp	Mon Mar 09 22:41:11 2020 +0100
+++ b/src/hotspot/share/opto/type.hpp	Tue Mar 10 10:45:01 2020 +0100
@@ -452,7 +452,6 @@
   const Type* maybe_remove_speculative(bool include_speculative) const;
 
   virtual bool maybe_null() const { return true; }
-  virtual bool is_known_instance() const { return false; }
 
 private:
   // support arrays
@@ -1398,10 +1397,6 @@
     return _ptrtype;
   }
 
-  bool is_known_instance() const {
-    return _ptrtype->is_known_instance();
-  }
-
 #ifndef PRODUCT
   virtual void dump2( Dict &d, uint depth, outputStream *st ) const;
 #endif
--- a/test/hotspot/jtreg/compiler/escapeAnalysis/TestCopyOfBrokenAntiDependency.java	Mon Mar 09 22:41:11 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2020, Red Hat, Inc. 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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @bug 8238384
- * @summary CTW: C2 compilation fails with "assert(store != load->find_exact_control(load->in(0))) failed: dependence cycle found"
- *
- * @run main/othervm -XX:-BackgroundCompilation TestCopyOfBrokenAntiDependency
- *
- */
-
-import java.util.Arrays;
-
-public class TestCopyOfBrokenAntiDependency {
-
-    public static void main(String[] args) {
-        for (int i = 0; i < 20_000; i++) {
-            test(100);
-        }
-    }
-
-    private static Object test(int length) {
-        Object[] src  = new Object[length]; // non escaping
-        final Object[] dst = Arrays.copyOf(src, 10); // can't be removed
-        final Object[] dst2 = Arrays.copyOf(dst, 100);
-        // load is control dependent on membar from previous copyOf
-        // but has memory edge to first copyOf.
-        final Object v = dst[0];
-        return v;
-    }
-}