@@ -1633,6 +1633,65 @@ bool LibraryCallKit::runtime_math(const TypeFunc* call_type, address funcAddr, c
1633
1633
return true ;
1634
1634
}
1635
1635
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
+
1636
1695
// ------------------------------inline_math_native-----------------------------
1637
1696
bool LibraryCallKit::inline_math_native (vmIntrinsics::ID id) {
1638
1697
#define FN_PTR (f ) CAST_FROM_FN_PTR(address, f)
@@ -1673,21 +1732,9 @@ bool LibraryCallKit::inline_math_native(vmIntrinsics::ID id) {
1673
1732
return StubRoutines::dexp () != NULL ?
1674
1733
runtime_math (OptoRuntime::Math_D_D_Type (), StubRoutines::dexp (), " dexp" ) :
1675
1734
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
- }
1689
1735
#undef FN_PTR
1690
1736
1737
+ case vmIntrinsics::_dpow: return inline_math_pow ();
1691
1738
case vmIntrinsics::_dcopySign: return inline_double_math (id);
1692
1739
case vmIntrinsics::_fcopySign: return inline_math (id);
1693
1740
case vmIntrinsics::_dsignum: return inline_double_math (id);
0 commit comments