mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-15 10:23:28 +00:00
8267687: ModXNode::Ideal optimization is better than Parse::do_irem
Reviewed-by: neliasso, kvn
This commit is contained in:
parent
48dc72b74d
commit
4e6748c543
@ -502,8 +502,6 @@ class Parse : public GraphKit {
|
||||
void modd();
|
||||
void l2f();
|
||||
|
||||
void do_irem();
|
||||
|
||||
// implementation of _get* and _put* bytecodes
|
||||
void do_getstatic() { do_field_access(true, false); }
|
||||
void do_getfield () { do_field_access(true, true); }
|
||||
@ -544,7 +542,6 @@ class Parse : public GraphKit {
|
||||
Node* val, const Type* tval);
|
||||
void maybe_add_predicate_after_if(Block* path);
|
||||
IfNode* jump_if_fork_int(Node* a, Node* b, BoolTest::mask mask, float prob, float cnt);
|
||||
Node* jump_if_join(Node* iffalse, Node* iftrue);
|
||||
void jump_if_true_fork(IfNode *ifNode, int dest_bci_if_true, bool unc);
|
||||
void jump_if_false_fork(IfNode *ifNode, int dest_bci_if_false, bool unc);
|
||||
void jump_if_always_fork(int dest_bci_if_true, bool unc);
|
||||
|
||||
@ -218,17 +218,6 @@ IfNode* Parse::jump_if_fork_int(Node* a, Node* b, BoolTest::mask mask, float pro
|
||||
return iff;
|
||||
}
|
||||
|
||||
// return Region node
|
||||
Node* Parse::jump_if_join(Node* iffalse, Node* iftrue) {
|
||||
Node *region = new RegionNode(3); // 2 results
|
||||
record_for_igvn(region);
|
||||
region->init_req(1, iffalse);
|
||||
region->init_req(2, iftrue );
|
||||
_gvn.set_type(region, Type::CONTROL);
|
||||
region = _gvn.transform(region);
|
||||
set_control (region);
|
||||
return region;
|
||||
}
|
||||
|
||||
// sentinel value for the target bci to mark never taken branches
|
||||
// (according to profiling)
|
||||
@ -1158,50 +1147,6 @@ void Parse::l2f() {
|
||||
push(res);
|
||||
}
|
||||
|
||||
void Parse::do_irem() {
|
||||
// Must keep both values on the expression-stack during null-check
|
||||
zero_check_int(peek());
|
||||
// Compile-time detect of null-exception?
|
||||
if (stopped()) return;
|
||||
|
||||
Node* b = pop();
|
||||
Node* a = pop();
|
||||
|
||||
const Type *t = _gvn.type(b);
|
||||
if (t != Type::TOP) {
|
||||
const TypeInt *ti = t->is_int();
|
||||
if (ti->is_con()) {
|
||||
int divisor = ti->get_con();
|
||||
// check for positive power of 2
|
||||
if (divisor > 0 &&
|
||||
(divisor & ~(divisor-1)) == divisor) {
|
||||
// yes !
|
||||
Node *mask = _gvn.intcon((divisor - 1));
|
||||
// Sigh, must handle negative dividends
|
||||
Node *zero = _gvn.intcon(0);
|
||||
IfNode *ifff = jump_if_fork_int(a, zero, BoolTest::lt, PROB_FAIR, COUNT_UNKNOWN);
|
||||
Node *iff = _gvn.transform( new IfFalseNode(ifff) );
|
||||
Node *ift = _gvn.transform( new IfTrueNode (ifff) );
|
||||
Node *reg = jump_if_join(ift, iff);
|
||||
Node *phi = PhiNode::make(reg, NULL, TypeInt::INT);
|
||||
// Negative path; negate/and/negate
|
||||
Node *neg = _gvn.transform( new SubINode(zero, a) );
|
||||
Node *andn= _gvn.transform( new AndINode(neg, mask) );
|
||||
Node *negn= _gvn.transform( new SubINode(zero, andn) );
|
||||
phi->init_req(1, negn);
|
||||
// Fast positive case
|
||||
Node *andx = _gvn.transform( new AndINode(a, mask) );
|
||||
phi->init_req(2, andx);
|
||||
// Push the merge
|
||||
push( _gvn.transform(phi) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Default case
|
||||
push( _gvn.transform( new ModINode(control(),a,b) ) );
|
||||
}
|
||||
|
||||
// Handle jsr and jsr_w bytecode
|
||||
void Parse::do_jsr() {
|
||||
assert(bc() == Bytecodes::_jsr || bc() == Bytecodes::_jsr_w, "wrong bytecode");
|
||||
@ -2196,7 +2141,13 @@ void Parse::do_one_bytecode() {
|
||||
break;
|
||||
|
||||
case Bytecodes::_irem:
|
||||
do_irem();
|
||||
// Must keep both values on the expression-stack during null-check
|
||||
zero_check_int(peek());
|
||||
// Compile-time detect of null-exception?
|
||||
if (stopped()) return;
|
||||
b = pop();
|
||||
a = pop();
|
||||
push(_gvn.transform(new ModINode(control(), a, b)));
|
||||
break;
|
||||
case Bytecodes::_idiv:
|
||||
// Must keep both values on the expression-stack during null-check
|
||||
|
||||
137
test/micro/org/openjdk/bench/vm/compiler/ModPowerOf2.java
Normal file
137
test/micro/org/openjdk/bench/vm/compiler/ModPowerOf2.java
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Alibaba Group Holding 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.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Test for x % 2^n (n is constant)
|
||||
*/
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@State(Scope.Thread)
|
||||
public class ModPowerOf2 {
|
||||
@Benchmark
|
||||
public int testPositivePowerOf2() {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
sum += i % 1;
|
||||
sum += i % 2;
|
||||
sum += i % 4;
|
||||
sum += i % 8;
|
||||
sum += i % 16;
|
||||
sum += i % 32;
|
||||
sum += i % 64;
|
||||
sum += i % 128;
|
||||
sum += i % 256;
|
||||
sum += i % 512;
|
||||
sum += i % 1024;
|
||||
sum += i % 2048;
|
||||
sum += i % 4096;
|
||||
sum += i % 8192;
|
||||
sum += i % 16384;
|
||||
sum += i % 32768;
|
||||
sum += i % 65536;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public int testNegativePowerOf2() {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
sum += i % -1;
|
||||
sum += i % -2;
|
||||
sum += i % -4;
|
||||
sum += i % -8;
|
||||
sum += i % -16;
|
||||
sum += i % -32;
|
||||
sum += i % -64;
|
||||
sum += i % -128;
|
||||
sum += i % -256;
|
||||
sum += i % -512;
|
||||
sum += i % -1024;
|
||||
sum += i % -2048;
|
||||
sum += i % -4096;
|
||||
sum += i % -8192;
|
||||
sum += i % -16384;
|
||||
sum += i % -32768;
|
||||
sum += i % -65536;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public int testMixedPowerOf2() {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
sum += i % -1;
|
||||
sum += i % 1;
|
||||
sum += i % -2;
|
||||
sum += i % 2;
|
||||
sum += i % -4;
|
||||
sum += i % 4;
|
||||
sum += i % -8;
|
||||
sum += i % 8;
|
||||
sum += i % -16;
|
||||
sum += i % 16;
|
||||
sum += i % -32;
|
||||
sum += i % 32;
|
||||
sum += i % -64;
|
||||
sum += i % 64;
|
||||
sum += i % -128;
|
||||
sum += i % 128;
|
||||
sum += i % -256;
|
||||
sum += i % 256;
|
||||
sum += i % -512;
|
||||
sum += i % 512;
|
||||
sum += i % -1024;
|
||||
sum += i % 1024;
|
||||
sum += i % -2048;
|
||||
sum += i % 2048;
|
||||
sum += i % -4096;
|
||||
sum += i % 4096;
|
||||
sum += i % -8192;
|
||||
sum += i % 8192;
|
||||
sum += i % -16384;
|
||||
sum += i % 16384;
|
||||
sum += i % -32768;
|
||||
sum += i % 32768;
|
||||
sum += i % -65536;
|
||||
sum += i % 65536;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user