Skip to content
This repository has been archived by the owner on Aug 27, 2022. It is now read-only.

Commit

Permalink
8247307: C2: Loop array fill stub routines are not called
Browse files Browse the repository at this point in the history
Ignore safepoint polling use of CountedLoopNode when matching loop array fill pattern.

Reviewed-by: kvn, thartmann
  • Loading branch information
Pengfei Li committed Jun 28, 2020
1 parent bdab5a0 commit ac4f14c
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 5 deletions.
6 changes: 6 additions & 0 deletions src/hotspot/cpu/x86/vm_version_x86.cpp
Expand Up @@ -1507,6 +1507,12 @@ void VM_Version::get_processor_features() {
// Modern processors allow misaligned memory operations for vectors.
AlignVector = !UseUnalignedLoadStores;
}
if (FLAG_IS_DEFAULT(OptimizeFill)) {
// 8247307: On x86, the auto-vectorized loop array fill code shows
// better performance than the array fill stubs. We should reenable
// this after the x86 stubs get improved.
OptimizeFill = false;
}
#endif // COMPILER2

if (FLAG_IS_DEFAULT(AllocatePrefetchInstr)) {
Expand Down
21 changes: 16 additions & 5 deletions src/hotspot/share/opto/loopTransform.cpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2020, 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
Expand Down Expand Up @@ -3642,10 +3642,21 @@ bool PhaseIdealLoop::match_fill_loop(IdealLoopTree* lpt, Node*& store, Node*& st
for (SimpleDUIterator iter(n); iter.has_next(); iter.next()) {
Node* use = iter.get();
if (!lpt->_body.contains(use)) {
msg = "node is used outside loop";
// lpt->_body.dump();
msg_node = n;
break;
if (n->is_CountedLoop() && n->as_CountedLoop()->is_strip_mined()) {
// In strip-mined counted loops, the CountedLoopNode may be
// used by the address polling node of the outer safepoint.
// Skip this use because it's safe.
#ifdef ASSERT
Node* sfpt = n->as_CountedLoop()->outer_safepoint();
Node* polladr = sfpt->in(TypeFunc::Parms+0);
assert(use == polladr, "the use should be a safepoint polling");
#endif
continue;
} else {
msg = "node is used outside loop";
msg_node = n;
break;
}
}
}
}
Expand Down
98 changes: 98 additions & 0 deletions test/micro/org/openjdk/bench/vm/compiler/ArrayFill.java
@@ -0,0 +1,98 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, Arm Limited. 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.
*/

package org.openjdk.bench.vm.compiler;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;

import java.util.concurrent.TimeUnit;
import java.util.Arrays;

@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class ArrayFill {
@Param("65536") private int size;

private byte[] ba;
private short[] sa;
private int[] ia;

@Setup
public void setup() {
ba = new byte[size];
sa = new short[size];
ia = new int[size];
}

@Benchmark
public void fillByteArray() {
for (int i = 0; i < size; i++) {
ba[i] = (byte) 123;
}
}

@Benchmark
public void fillShortArray() {
for (int i = 0; i < size; i++) {
sa[i] = (short) 12345;
}
}

@Benchmark
public void fillIntArray() {
for (int i = 0; i < size; i++) {
ia[i] = 1234567890;
}
}

@Benchmark
public void zeroByteArray() {
for (int i = 0; i < size; i++) {
ba[i] = 0;
}
}

@Benchmark
public void zeroShortArray() {
for (int i = 0; i < size; i++) {
sa[i] = 0;
}
}

@Benchmark
public void zeroIntArray() {
for (int i = 0; i < size; i++) {
ia[i] = 0;
}
}
}

0 comments on commit ac4f14c

Please sign in to comment.