comparison src/share/vm/opto/library_call.cpp @ 6205:d50605d9417e

7177917: Failed test java/lang/Math/PowTests.java Summary: When c2 intrinsifies pow/exp, it should never inline the java implementations. Reviewed-by: kvn
author roland
date Mon, 02 Jul 2012 09:58:06 +0200
parents eeb819cf36e5
children 1d7922586cf6
comparison
equal deleted inserted replaced
6195:bcffa4c5eef6 6205:d50605d9417e
158 bool inline_math_native(vmIntrinsics::ID id); 158 bool inline_math_native(vmIntrinsics::ID id);
159 bool inline_trig(vmIntrinsics::ID id); 159 bool inline_trig(vmIntrinsics::ID id);
160 bool inline_trans(vmIntrinsics::ID id); 160 bool inline_trans(vmIntrinsics::ID id);
161 bool inline_abs(vmIntrinsics::ID id); 161 bool inline_abs(vmIntrinsics::ID id);
162 bool inline_sqrt(vmIntrinsics::ID id); 162 bool inline_sqrt(vmIntrinsics::ID id);
163 void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
163 bool inline_pow(vmIntrinsics::ID id); 164 bool inline_pow(vmIntrinsics::ID id);
164 bool inline_exp(vmIntrinsics::ID id); 165 bool inline_exp(vmIntrinsics::ID id);
165 bool inline_min_max(vmIntrinsics::ID id); 166 bool inline_min_max(vmIntrinsics::ID id);
166 Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y); 167 Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
167 // This returns Type::AnyPtr, RawPtr, or OopPtr. 168 // This returns Type::AnyPtr, RawPtr, or OopPtr.
1533 _sp += arg_size(); // restore stack pointer 1534 _sp += arg_size(); // restore stack pointer
1534 push_pair(_gvn.transform(new (C, 2) AbsDNode(pop_math_arg()))); 1535 push_pair(_gvn.transform(new (C, 2) AbsDNode(pop_math_arg())));
1535 return true; 1536 return true;
1536 } 1537 }
1537 1538
1539 void LibraryCallKit::finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName) {
1540 //-------------------
1541 //result=(result.isNaN())? funcAddr():result;
1542 // Check: If isNaN() by checking result!=result? then either trap
1543 // or go to runtime
1544 Node* cmpisnan = _gvn.transform(new (C, 3) CmpDNode(result,result));
1545 // Build the boolean node
1546 Node* bolisnum = _gvn.transform( new (C, 2) BoolNode(cmpisnan, BoolTest::eq) );
1547
1548 if (!too_many_traps(Deoptimization::Reason_intrinsic)) {
1549 {
1550 BuildCutout unless(this, bolisnum, PROB_STATIC_FREQUENT);
1551 // End the current control-flow path
1552 push_pair(x);
1553 if (y != NULL) {
1554 push_pair(y);
1555 }
1556 // The pow or exp intrinsic returned a NaN, which requires a call
1557 // to the runtime. Recompile with the runtime call.
1558 uncommon_trap(Deoptimization::Reason_intrinsic,
1559 Deoptimization::Action_make_not_entrant);
1560 }
1561 push_pair(result);
1562 } else {
1563 // If this inlining ever returned NaN in the past, we compile a call
1564 // to the runtime to properly handle corner cases
1565
1566 IfNode* iff = create_and_xform_if(control(), bolisnum, PROB_STATIC_FREQUENT, COUNT_UNKNOWN);
1567 Node* if_slow = _gvn.transform( new (C, 1) IfFalseNode(iff) );
1568 Node* if_fast = _gvn.transform( new (C, 1) IfTrueNode(iff) );
1569
1570 if (!if_slow->is_top()) {
1571 RegionNode* result_region = new(C, 3) RegionNode(3);
1572 PhiNode* result_val = new (C, 3) PhiNode(result_region, Type::DOUBLE);
1573
1574 result_region->init_req(1, if_fast);
1575 result_val->init_req(1, result);
1576
1577 set_control(if_slow);
1578
1579 const TypePtr* no_memory_effects = NULL;
1580 Node* rt = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName,
1581 no_memory_effects,
1582 x, top(), y, y ? top() : NULL);
1583 Node* value = _gvn.transform(new (C, 1) ProjNode(rt, TypeFunc::Parms+0));
1584 #ifdef ASSERT
1585 Node* value_top = _gvn.transform(new (C, 1) ProjNode(rt, TypeFunc::Parms+1));
1586 assert(value_top == top(), "second value must be top");
1587 #endif
1588
1589 result_region->init_req(2, control());
1590 result_val->init_req(2, value);
1591 push_result(result_region, result_val);
1592 } else {
1593 push_pair(result);
1594 }
1595 }
1596 }
1597
1538 //------------------------------inline_exp------------------------------------- 1598 //------------------------------inline_exp-------------------------------------
1539 // Inline exp instructions, if possible. The Intel hardware only misses 1599 // Inline exp instructions, if possible. The Intel hardware only misses
1540 // really odd corner cases (+/- Infinity). Just uncommon-trap them. 1600 // really odd corner cases (+/- Infinity). Just uncommon-trap them.
1541 bool LibraryCallKit::inline_exp(vmIntrinsics::ID id) { 1601 bool LibraryCallKit::inline_exp(vmIntrinsics::ID id) {
1542 assert(id == vmIntrinsics::_dexp, "Not exp"); 1602 assert(id == vmIntrinsics::_dexp, "Not exp");
1543 1603
1544 // If this inlining ever returned NaN in the past, we do not intrinsify it
1545 // every again. NaN results requires StrictMath.exp handling.
1546 if (too_many_traps(Deoptimization::Reason_intrinsic)) return false;
1547
1548 _sp += arg_size(); // restore stack pointer 1604 _sp += arg_size(); // restore stack pointer
1549 Node *x = pop_math_arg(); 1605 Node *x = pop_math_arg();
1550 Node *result = _gvn.transform(new (C, 2) ExpDNode(0,x)); 1606 Node *result = _gvn.transform(new (C, 2) ExpDNode(0,x));
1551 1607
1552 //------------------- 1608 finish_pow_exp(result, x, NULL, OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dexp), "EXP");
1553 //result=(result.isNaN())? StrictMath::exp():result;
1554 // Check: If isNaN() by checking result!=result? then go to Strict Math
1555 Node* cmpisnan = _gvn.transform(new (C, 3) CmpDNode(result,result));
1556 // Build the boolean node
1557 Node* bolisnum = _gvn.transform( new (C, 2) BoolNode(cmpisnan, BoolTest::eq) );
1558
1559 { BuildCutout unless(this, bolisnum, PROB_STATIC_FREQUENT);
1560 // End the current control-flow path
1561 push_pair(x);
1562 // Math.exp intrinsic returned a NaN, which requires StrictMath.exp
1563 // to handle. Recompile without intrinsifying Math.exp
1564 uncommon_trap(Deoptimization::Reason_intrinsic,
1565 Deoptimization::Action_make_not_entrant);
1566 }
1567 1609
1568 C->set_has_split_ifs(true); // Has chance for split-if optimization 1610 C->set_has_split_ifs(true); // Has chance for split-if optimization
1569
1570 push_pair(result);
1571 1611
1572 return true; 1612 return true;
1573 } 1613 }
1574 1614
1575 //------------------------------inline_pow------------------------------------- 1615 //------------------------------inline_pow-------------------------------------
1576 // Inline power instructions, if possible. 1616 // Inline power instructions, if possible.
1577 bool LibraryCallKit::inline_pow(vmIntrinsics::ID id) { 1617 bool LibraryCallKit::inline_pow(vmIntrinsics::ID id) {
1578 assert(id == vmIntrinsics::_dpow, "Not pow"); 1618 assert(id == vmIntrinsics::_dpow, "Not pow");
1579 1619
1580 // If this inlining ever returned NaN in the past, we do not intrinsify it
1581 // every again. NaN results requires StrictMath.pow handling.
1582 if (too_many_traps(Deoptimization::Reason_intrinsic)) return false;
1583
1584 // Do not intrinsify on older platforms which lack cmove.
1585 if (ConditionalMoveLimit == 0) return false;
1586
1587 // Pseudocode for pow 1620 // Pseudocode for pow
1588 // if (x <= 0.0) { 1621 // if (x <= 0.0) {
1589 // if ((double)((int)y)==y) { // if y is int 1622 // long longy = (long)y;
1590 // result = ((1&(int)y)==0)?-DPow(abs(x), y):DPow(abs(x), y) 1623 // if ((double)longy == y) { // if y is long
1624 // if (y + 1 == y) longy = 0; // huge number: even
1625 // result = ((1&longy) == 0)?-DPow(abs(x), y):DPow(abs(x), y);
1591 // } else { 1626 // } else {
1592 // result = NaN; 1627 // result = NaN;
1593 // } 1628 // }
1594 // } else { 1629 // } else {
1595 // result = DPow(x,y); 1630 // result = DPow(x,y);
1596 // } 1631 // }
1597 // if (result != result)? { 1632 // if (result != result)? {
1598 // uncommon_trap(); 1633 // result = uncommon_trap() or runtime_call();
1599 // } 1634 // }
1600 // return result; 1635 // return result;
1601 1636
1602 _sp += arg_size(); // restore stack pointer 1637 _sp += arg_size(); // restore stack pointer
1603 Node* y = pop_math_arg(); 1638 Node* y = pop_math_arg();
1604 Node* x = pop_math_arg(); 1639 Node* x = pop_math_arg();
1605 1640
1606 Node *fast_result = _gvn.transform( new (C, 3) PowDNode(0, x, y) ); 1641 Node* result = NULL;
1607 1642
1608 // Short form: if not top-level (i.e., Math.pow but inlining Math.pow 1643 if (!too_many_traps(Deoptimization::Reason_intrinsic)) {
1609 // inside of something) then skip the fancy tests and just check for 1644 // Short form: skip the fancy tests and just check for NaN result.
1610 // NaN result. 1645 result = _gvn.transform( new (C, 3) PowDNode(0, x, y) );
1611 Node *result = NULL;
1612 if( jvms()->depth() >= 1 ) {
1613 result = fast_result;
1614 } else { 1646 } else {
1647 // If this inlining ever returned NaN in the past, include all
1648 // checks + call to the runtime.
1615 1649
1616 // Set the merge point for If node with condition of (x <= 0.0) 1650 // Set the merge point for If node with condition of (x <= 0.0)
1617 // There are four possible paths to region node and phi node 1651 // There are four possible paths to region node and phi node
1618 RegionNode *r = new (C, 4) RegionNode(4); 1652 RegionNode *r = new (C, 4) RegionNode(4);
1619 Node *phi = new (C, 4) PhiNode(r, Type::DOUBLE); 1653 Node *phi = new (C, 4) PhiNode(r, Type::DOUBLE);
1625 Node *cmp = _gvn.transform(new (C, 3) CmpDNode(x, zeronode)); 1659 Node *cmp = _gvn.transform(new (C, 3) CmpDNode(x, zeronode));
1626 // Check: If (x<=0) then go complex path 1660 // Check: If (x<=0) then go complex path
1627 Node *bol1 = _gvn.transform( new (C, 2) BoolNode( cmp, BoolTest::le ) ); 1661 Node *bol1 = _gvn.transform( new (C, 2) BoolNode( cmp, BoolTest::le ) );
1628 // Branch either way 1662 // Branch either way
1629 IfNode *if1 = create_and_xform_if(control(),bol1, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN); 1663 IfNode *if1 = create_and_xform_if(control(),bol1, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN);
1630 Node *opt_test = _gvn.transform(if1);
1631 //assert( opt_test->is_If(), "Expect an IfNode");
1632 IfNode *opt_if1 = (IfNode*)opt_test;
1633 // Fast path taken; set region slot 3 1664 // Fast path taken; set region slot 3
1634 Node *fast_taken = _gvn.transform( new (C, 1) IfFalseNode(opt_if1) ); 1665 Node *fast_taken = _gvn.transform( new (C, 1) IfFalseNode(if1) );
1635 r->init_req(3,fast_taken); // Capture fast-control 1666 r->init_req(3,fast_taken); // Capture fast-control
1636 1667
1637 // Fast path not-taken, i.e. slow path 1668 // Fast path not-taken, i.e. slow path
1638 Node *complex_path = _gvn.transform( new (C, 1) IfTrueNode(opt_if1) ); 1669 Node *complex_path = _gvn.transform( new (C, 1) IfTrueNode(if1) );
1639 1670
1640 // Set fast path result 1671 // Set fast path result
1641 Node *fast_result = _gvn.transform( new (C, 3) PowDNode(0, y, x) ); 1672 Node *fast_result = _gvn.transform( new (C, 3) PowDNode(0, x, y) );
1642 phi->init_req(3, fast_result); 1673 phi->init_req(3, fast_result);
1643 1674
1644 // Complex path 1675 // Complex path
1645 // Build the second if node (if y is int) 1676 // Build the second if node (if y is long)
1646 // Node for (int)y 1677 // Node for (long)y
1647 Node *inty = _gvn.transform( new (C, 2) ConvD2INode(y)); 1678 Node *longy = _gvn.transform( new (C, 2) ConvD2LNode(y));
1648 // Node for (double)((int) y) 1679 // Node for (double)((long) y)
1649 Node *doubleinty= _gvn.transform( new (C, 2) ConvI2DNode(inty)); 1680 Node *doublelongy= _gvn.transform( new (C, 2) ConvL2DNode(longy));
1650 // Check (double)((int) y) : y 1681 // Check (double)((long) y) : y
1651 Node *cmpinty= _gvn.transform(new (C, 3) CmpDNode(doubleinty, y)); 1682 Node *cmplongy= _gvn.transform(new (C, 3) CmpDNode(doublelongy, y));
1652 // Check if (y isn't int) then go to slow path 1683 // Check if (y isn't long) then go to slow path
1653 1684
1654 Node *bol2 = _gvn.transform( new (C, 2) BoolNode( cmpinty, BoolTest::ne ) ); 1685 Node *bol2 = _gvn.transform( new (C, 2) BoolNode( cmplongy, BoolTest::ne ) );
1655 // Branch either way 1686 // Branch either way
1656 IfNode *if2 = create_and_xform_if(complex_path,bol2, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN); 1687 IfNode *if2 = create_and_xform_if(complex_path,bol2, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN);
1657 Node *slow_path = opt_iff(r,if2); // Set region path 2 1688 Node* ylong_path = _gvn.transform( new (C, 1) IfFalseNode(if2));
1658 1689
1659 // Calculate DPow(abs(x), y)*(1 & (int)y) 1690 Node *slow_path = _gvn.transform( new (C, 1) IfTrueNode(if2) );
1691
1692 // Calculate DPow(abs(x), y)*(1 & (long)y)
1660 // Node for constant 1 1693 // Node for constant 1
1661 Node *conone = intcon(1); 1694 Node *conone = longcon(1);
1662 // 1& (int)y 1695 // 1& (long)y
1663 Node *signnode= _gvn.transform( new (C, 3) AndINode(conone, inty) ); 1696 Node *signnode= _gvn.transform( new (C, 3) AndLNode(conone, longy) );
1697
1698 // A huge number is always even. Detect a huge number by checking
1699 // if y + 1 == y and set integer to be tested for parity to 0.
1700 // Required for corner case:
1701 // (long)9.223372036854776E18 = max_jlong
1702 // (double)(long)9.223372036854776E18 = 9.223372036854776E18
1703 // max_jlong is odd but 9.223372036854776E18 is even
1704 Node* yplus1 = _gvn.transform( new (C, 3) AddDNode(y, makecon(TypeD::make(1))));
1705 Node *cmpyplus1= _gvn.transform(new (C, 3) CmpDNode(yplus1, y));
1706 Node *bolyplus1 = _gvn.transform( new (C, 2) BoolNode( cmpyplus1, BoolTest::eq ) );
1707 Node* correctedsign = NULL;
1708 if (ConditionalMoveLimit != 0) {
1709 correctedsign = _gvn.transform( CMoveNode::make(C, NULL, bolyplus1, signnode, longcon(0), TypeLong::LONG));
1710 } else {
1711 IfNode *ifyplus1 = create_and_xform_if(ylong_path,bolyplus1, PROB_FAIR, COUNT_UNKNOWN);
1712 RegionNode *r = new (C, 3) RegionNode(3);
1713 Node *phi = new (C, 3) PhiNode(r, TypeLong::LONG);
1714 r->init_req(1, _gvn.transform( new (C, 1) IfFalseNode(ifyplus1)));
1715 r->init_req(2, _gvn.transform( new (C, 1) IfTrueNode(ifyplus1)));
1716 phi->init_req(1, signnode);
1717 phi->init_req(2, longcon(0));
1718 correctedsign = _gvn.transform(phi);
1719 ylong_path = _gvn.transform(r);
1720 record_for_igvn(r);
1721 }
1722
1664 // zero node 1723 // zero node
1665 Node *conzero = intcon(0); 1724 Node *conzero = longcon(0);
1666 // Check (1&(int)y)==0? 1725 // Check (1&(long)y)==0?
1667 Node *cmpeq1 = _gvn.transform(new (C, 3) CmpINode(signnode, conzero)); 1726 Node *cmpeq1 = _gvn.transform(new (C, 3) CmpLNode(correctedsign, conzero));
1668 // Check if (1&(int)y)!=0?, if so the result is negative 1727 // Check if (1&(long)y)!=0?, if so the result is negative
1669 Node *bol3 = _gvn.transform( new (C, 2) BoolNode( cmpeq1, BoolTest::ne ) ); 1728 Node *bol3 = _gvn.transform( new (C, 2) BoolNode( cmpeq1, BoolTest::ne ) );
1670 // abs(x) 1729 // abs(x)
1671 Node *absx=_gvn.transform( new (C, 2) AbsDNode(x)); 1730 Node *absx=_gvn.transform( new (C, 2) AbsDNode(x));
1672 // abs(x)^y 1731 // abs(x)^y
1673 Node *absxpowy = _gvn.transform( new (C, 3) PowDNode(0, y, absx) ); 1732 Node *absxpowy = _gvn.transform( new (C, 3) PowDNode(0, absx, y) );
1674 // -abs(x)^y 1733 // -abs(x)^y
1675 Node *negabsxpowy = _gvn.transform(new (C, 2) NegDNode (absxpowy)); 1734 Node *negabsxpowy = _gvn.transform(new (C, 2) NegDNode (absxpowy));
1676 // (1&(int)y)==1?-DPow(abs(x), y):DPow(abs(x), y) 1735 // (1&(long)y)==1?-DPow(abs(x), y):DPow(abs(x), y)
1677 Node *signresult = _gvn.transform( CMoveNode::make(C, NULL, bol3, absxpowy, negabsxpowy, Type::DOUBLE)); 1736 Node *signresult = NULL;
1737 if (ConditionalMoveLimit != 0) {
1738 signresult = _gvn.transform( CMoveNode::make(C, NULL, bol3, absxpowy, negabsxpowy, Type::DOUBLE));
1739 } else {
1740 IfNode *ifyeven = create_and_xform_if(ylong_path,bol3, PROB_FAIR, COUNT_UNKNOWN);
1741 RegionNode *r = new (C, 3) RegionNode(3);
1742 Node *phi = new (C, 3) PhiNode(r, Type::DOUBLE);
1743 r->init_req(1, _gvn.transform( new (C, 1) IfFalseNode(ifyeven)));
1744 r->init_req(2, _gvn.transform( new (C, 1) IfTrueNode(ifyeven)));
1745 phi->init_req(1, absxpowy);
1746 phi->init_req(2, negabsxpowy);
1747 signresult = _gvn.transform(phi);
1748 ylong_path = _gvn.transform(r);
1749 record_for_igvn(r);
1750 }
1678 // Set complex path fast result 1751 // Set complex path fast result
1752 r->init_req(2, ylong_path);
1679 phi->init_req(2, signresult); 1753 phi->init_req(2, signresult);
1680 1754
1681 static const jlong nan_bits = CONST64(0x7ff8000000000000); 1755 static const jlong nan_bits = CONST64(0x7ff8000000000000);
1682 Node *slow_result = makecon(TypeD::make(*(double*)&nan_bits)); // return NaN 1756 Node *slow_result = makecon(TypeD::make(*(double*)&nan_bits)); // return NaN
1683 r->init_req(1,slow_path); 1757 r->init_req(1,slow_path);
1687 set_control(_gvn.transform(r)); 1761 set_control(_gvn.transform(r));
1688 record_for_igvn(r); 1762 record_for_igvn(r);
1689 result=_gvn.transform(phi); 1763 result=_gvn.transform(phi);
1690 } 1764 }
1691 1765
1692 //------------------- 1766 finish_pow_exp(result, x, y, OptoRuntime::Math_DD_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dpow), "POW");
1693 //result=(result.isNaN())? uncommon_trap():result;
1694 // Check: If isNaN() by checking result!=result? then go to Strict Math
1695 Node* cmpisnan = _gvn.transform(new (C, 3) CmpDNode(result,result));
1696 // Build the boolean node
1697 Node* bolisnum = _gvn.transform( new (C, 2) BoolNode(cmpisnan, BoolTest::eq) );
1698
1699 { BuildCutout unless(this, bolisnum, PROB_STATIC_FREQUENT);
1700 // End the current control-flow path
1701 push_pair(x);
1702 push_pair(y);
1703 // Math.pow intrinsic returned a NaN, which requires StrictMath.pow
1704 // to handle. Recompile without intrinsifying Math.pow.
1705 uncommon_trap(Deoptimization::Reason_intrinsic,
1706 Deoptimization::Action_make_not_entrant);
1707 }
1708 1767
1709 C->set_has_split_ifs(true); // Has chance for split-if optimization 1768 C->set_has_split_ifs(true); // Has chance for split-if optimization
1710
1711 push_pair(result);
1712 1769
1713 return true; 1770 return true;
1714 } 1771 }
1715 1772
1716 //------------------------------inline_trans------------------------------------- 1773 //------------------------------inline_trans-------------------------------------