Skip to content

Commit cf5546b

Browse files
jaskarthchhagedorn
authored andcommittedOct 28, 2022
8291336: Add ideal rule to convert floating point multiply by 2 into addition
Reviewed-by: qamai, thartmann, chagedorn
1 parent 4b89fce commit cf5546b

File tree

4 files changed

+154
-0
lines changed

4 files changed

+154
-0
lines changed
 

‎src/hotspot/share/opto/mulnode.cpp

+28
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,20 @@ const Type *MulFNode::mul_ring(const Type *t0, const Type *t1) const {
423423
return TypeF::make( t0->getf() * t1->getf() );
424424
}
425425

426+
//------------------------------Ideal---------------------------------------
427+
// Check to see if we are multiplying by a constant 2 and convert to add, then try the regular MulNode::Ideal
428+
Node* MulFNode::Ideal(PhaseGVN* phase, bool can_reshape) {
429+
const TypeF *t2 = phase->type(in(2))->isa_float_constant();
430+
431+
// x * 2 -> x + x
432+
if (t2 != NULL && t2->getf() == 2) {
433+
Node* base = in(1);
434+
return new AddFNode(base, base);
435+
}
436+
437+
return MulNode::Ideal(phase, can_reshape);
438+
}
439+
426440
//=============================================================================
427441
//------------------------------mul_ring---------------------------------------
428442
// Compute the product type of two double ranges into this node.
@@ -432,6 +446,20 @@ const Type *MulDNode::mul_ring(const Type *t0, const Type *t1) const {
432446
return TypeD::make( t0->getd() * t1->getd() );
433447
}
434448

449+
//------------------------------Ideal---------------------------------------
450+
// Check to see if we are multiplying by a constant 2 and convert to add, then try the regular MulNode::Ideal
451+
Node* MulDNode::Ideal(PhaseGVN* phase, bool can_reshape) {
452+
const TypeD *t2 = phase->type(in(2))->isa_double_constant();
453+
454+
// x * 2 -> x + x
455+
if (t2 != NULL && t2->getd() == 2) {
456+
Node* base = in(1);
457+
return new AddDNode(base, base);
458+
}
459+
460+
return MulNode::Ideal(phase, can_reshape);
461+
}
462+
435463
//=============================================================================
436464
//------------------------------Value------------------------------------------
437465
const Type* MulHiLNode::Value(PhaseGVN* phase) const {

‎src/hotspot/share/opto/mulnode.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ class MulFNode : public MulNode {
130130
public:
131131
MulFNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {}
132132
virtual int Opcode() const;
133+
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
133134
virtual const Type *mul_ring( const Type *, const Type * ) const;
134135
const Type *mul_id() const { return TypeF::ONE; }
135136
const Type *add_id() const { return TypeF::ZERO; }
@@ -147,6 +148,7 @@ class MulDNode : public MulNode {
147148
public:
148149
MulDNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {}
149150
virtual int Opcode() const;
151+
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
150152
virtual const Type *mul_ring( const Type *, const Type * ) const;
151153
const Type *mul_id() const { return TypeD::ONE; }
152154
const Type *add_id() const { return TypeD::ZERO; }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
package compiler.c2.irTests;
25+
26+
import jdk.test.lib.Asserts;
27+
import compiler.lib.ir_framework.*;
28+
import java.util.Random;
29+
import jdk.test.lib.Utils;
30+
31+
/*
32+
* @test
33+
* @bug 8291336
34+
* @summary Test that transformation of multiply-by-2 is appropriately turned into additions.
35+
* @library /test/lib /
36+
* @requires vm.compiler2.enabled
37+
* @run driver compiler.c2.irTests.TestMulNodeIdealization
38+
*/
39+
public class TestMulNodeIdealization {
40+
private static final Random RANDOM = Utils.getRandomInstance();
41+
42+
public static void main(String[] args) {
43+
TestFramework.run();
44+
}
45+
46+
@Test
47+
@IR(failOn = {IRNode.MUL})
48+
// Checks x * 2 -> x + x
49+
public float testFloat(float x) {
50+
return x * 2;
51+
}
52+
53+
@Test
54+
@IR(failOn = {IRNode.MUL})
55+
// Checks x * 2 -> x + x
56+
public double testDouble(double x) {
57+
return x * 2;
58+
}
59+
60+
@Run(test = "testFloat")
61+
public void runTestFloat() {
62+
float value = RANDOM.nextFloat();
63+
float interpreterResult = value * 2;
64+
Asserts.assertEQ(testFloat(value), interpreterResult);
65+
}
66+
67+
@Run(test = "testDouble")
68+
public void runTestDouble() {
69+
double value = RANDOM.nextDouble();
70+
double interpreterResult = value * 2;
71+
Asserts.assertEQ(testDouble(value), interpreterResult);
72+
}
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
package org.openjdk.bench.vm.compiler;
24+
25+
import org.openjdk.jmh.annotations.*;
26+
import org.openjdk.jmh.infra.Blackhole;
27+
28+
import java.util.concurrent.TimeUnit;
29+
30+
@BenchmarkMode(Mode.AverageTime)
31+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
32+
@Measurement(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
33+
@Warmup(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
34+
@Fork(3)
35+
public class MulNodeIdealize {
36+
private static final int SIZE = 50;
37+
38+
@Benchmark
39+
public void testMul2Float(Blackhole blackhole) {
40+
for (float i = 0; i < SIZE; i++) {
41+
blackhole.consume(i * 2);
42+
}
43+
}
44+
45+
@Benchmark
46+
public void testMul2Double(Blackhole blackhole) {
47+
for (double i = 0; i < SIZE; i++) {
48+
blackhole.consume(i * 2);
49+
}
50+
}
51+
}

1 commit comments

Comments
 (1)

openjdk-notifier[bot] commented on Oct 28, 2022

@openjdk-notifier[bot]
Please sign in to comment.