Skip to content

Commit ed477da

Browse files
committed
8264945: Optimize the code-gen for Math.pow(x, 0.5)
Reviewed-by: neliasso, kvn
1 parent 7146104 commit ed477da

File tree

2 files changed

+62
-14
lines changed

2 files changed

+62
-14
lines changed

src/hotspot/share/opto/library_call.cpp

+60-13
Original file line numberDiff line numberDiff line change
@@ -1633,6 +1633,65 @@ bool LibraryCallKit::runtime_math(const TypeFunc* call_type, address funcAddr, c
16331633
return true;
16341634
}
16351635

1636+
//------------------------------inline_math_pow-----------------------------
1637+
bool LibraryCallKit::inline_math_pow() {
1638+
Node* exp = round_double_node(argument(2));
1639+
const TypeD* d = _gvn.type(exp)->isa_double_constant();
1640+
if (d != NULL) {
1641+
if (d->getd() == 2.0) {
1642+
// Special case: pow(x, 2.0) => x * x
1643+
Node* base = round_double_node(argument(0));
1644+
set_result(_gvn.transform(new MulDNode(base, base)));
1645+
return true;
1646+
}
1647+
#if defined(X86) && defined(_LP64)
1648+
else if (d->getd() == 0.5 && Matcher::match_rule_supported(Op_SqrtD)) {
1649+
// Special case: pow(x, 0.5) => sqrt(x)
1650+
Node* base = round_double_node(argument(0));
1651+
Node* zero = _gvn.zerocon(T_DOUBLE);
1652+
1653+
RegionNode* region = new RegionNode(3);
1654+
Node* phi = new PhiNode(region, Type::DOUBLE);
1655+
1656+
Node* cmp = _gvn.transform(new CmpDNode(base, zero));
1657+
Node* test = _gvn.transform(new BoolNode(cmp, BoolTest::lt));
1658+
1659+
Node* if_pow = generate_slow_guard(test, NULL);
1660+
Node* value_sqrt = _gvn.transform(new SqrtDNode(C, control(), base));
1661+
phi->init_req(1, value_sqrt);
1662+
region->init_req(1, control());
1663+
1664+
if (if_pow != NULL) {
1665+
set_control(if_pow);
1666+
address target = StubRoutines::dpow() != NULL ? StubRoutines::dpow() :
1667+
CAST_FROM_FN_PTR(address, SharedRuntime::dpow);
1668+
const TypePtr* no_memory_effects = NULL;
1669+
Node* trig = make_runtime_call(RC_LEAF, OptoRuntime::Math_DD_D_Type(), target, "POW",
1670+
no_memory_effects, base, top(), exp, top());
1671+
Node* value_pow = _gvn.transform(new ProjNode(trig, TypeFunc::Parms+0));
1672+
#ifdef ASSERT
1673+
Node* value_top = _gvn.transform(new ProjNode(trig, TypeFunc::Parms+1));
1674+
assert(value_top == top(), "second value must be top");
1675+
#endif
1676+
phi->init_req(2, value_pow);
1677+
region->init_req(2, _gvn.transform(new ProjNode(trig, TypeFunc::Control)));
1678+
}
1679+
1680+
C->set_has_split_ifs(true); // Has chance for split-if optimization
1681+
set_control(_gvn.transform(region));
1682+
record_for_igvn(region);
1683+
set_result(_gvn.transform(phi));
1684+
1685+
return true;
1686+
}
1687+
#endif // defined(X86) && defined(_LP64)
1688+
}
1689+
1690+
return StubRoutines::dpow() != NULL ?
1691+
runtime_math(OptoRuntime::Math_DD_D_Type(), StubRoutines::dpow(), "dpow") :
1692+
runtime_math(OptoRuntime::Math_DD_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dpow), "POW");
1693+
}
1694+
16361695
//------------------------------inline_math_native-----------------------------
16371696
bool LibraryCallKit::inline_math_native(vmIntrinsics::ID id) {
16381697
#define FN_PTR(f) CAST_FROM_FN_PTR(address, f)
@@ -1673,21 +1732,9 @@ bool LibraryCallKit::inline_math_native(vmIntrinsics::ID id) {
16731732
return StubRoutines::dexp() != NULL ?
16741733
runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dexp(), "dexp") :
16751734
runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dexp), "EXP");
1676-
case vmIntrinsics::_dpow: {
1677-
Node* exp = round_double_node(argument(2));
1678-
const TypeD* d = _gvn.type(exp)->isa_double_constant();
1679-
if (d != NULL && d->getd() == 2.0) {
1680-
// Special case: pow(x, 2.0) => x * x
1681-
Node* base = round_double_node(argument(0));
1682-
set_result(_gvn.transform(new MulDNode(base, base)));
1683-
return true;
1684-
}
1685-
return StubRoutines::dpow() != NULL ?
1686-
runtime_math(OptoRuntime::Math_DD_D_Type(), StubRoutines::dpow(), "dpow") :
1687-
runtime_math(OptoRuntime::Math_DD_D_Type(), FN_PTR(SharedRuntime::dpow), "POW");
1688-
}
16891735
#undef FN_PTR
16901736

1737+
case vmIntrinsics::_dpow: return inline_math_pow();
16911738
case vmIntrinsics::_dcopySign: return inline_double_math(id);
16921739
case vmIntrinsics::_fcopySign: return inline_math(id);
16931740
case vmIntrinsics::_dsignum: return inline_double_math(id);

src/hotspot/share/opto/library_call.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -201,6 +201,7 @@ class LibraryCallKit : public GraphKit {
201201
bool inline_math_native(vmIntrinsics::ID id);
202202
bool inline_math(vmIntrinsics::ID id);
203203
bool inline_double_math(vmIntrinsics::ID id);
204+
bool inline_math_pow();
204205
template <typename OverflowOp>
205206
bool inline_math_overflow(Node* arg1, Node* arg2);
206207
void inline_math_mathExact(Node* math, Node* test);

0 commit comments

Comments
 (0)