hotspot/src/share/vm/opto/library_call.cpp
changeset 35146 9ebfec283f56
parent 35110 f19bcdf40799
child 35154 a9b3c1984a01
equal deleted inserted replaced
35145:a4ffa2fa7f4d 35146:9ebfec283f56
   228   bool inline_math_multiplyExactL();
   228   bool inline_math_multiplyExactL();
   229   bool inline_math_negateExactI();
   229   bool inline_math_negateExactI();
   230   bool inline_math_negateExactL();
   230   bool inline_math_negateExactL();
   231   bool inline_math_subtractExactI(bool is_decrement);
   231   bool inline_math_subtractExactI(bool is_decrement);
   232   bool inline_math_subtractExactL(bool is_decrement);
   232   bool inline_math_subtractExactL(bool is_decrement);
   233   bool inline_pow();
       
   234   Node* finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
       
   235   bool inline_min_max(vmIntrinsics::ID id);
   233   bool inline_min_max(vmIntrinsics::ID id);
   236   bool inline_notify(vmIntrinsics::ID id);
   234   bool inline_notify(vmIntrinsics::ID id);
   237   Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
   235   Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
   238   // This returns Type::AnyPtr, RawPtr, or OopPtr.
   236   // This returns Type::AnyPtr, RawPtr, or OopPtr.
   239   int classify_unsafe_addr(Node* &base, Node* &offset);
   237   int classify_unsafe_addr(Node* &base, Node* &offset);
  1716   }
  1714   }
  1717   set_result(n);
  1715   set_result(n);
  1718   return true;
  1716   return true;
  1719 }
  1717 }
  1720 
  1718 
  1721 Node* LibraryCallKit::finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName) {
       
  1722   //-------------------
       
  1723   //result=(result.isNaN())? funcAddr():result;
       
  1724   // Check: If isNaN() by checking result!=result? then either trap
       
  1725   // or go to runtime
       
  1726   Node* cmpisnan = _gvn.transform(new CmpDNode(result, result));
       
  1727   // Build the boolean node
       
  1728   Node* bolisnum = _gvn.transform(new BoolNode(cmpisnan, BoolTest::eq));
       
  1729 
       
  1730   if (!too_many_traps(Deoptimization::Reason_intrinsic)) {
       
  1731     { BuildCutout unless(this, bolisnum, PROB_STATIC_FREQUENT);
       
  1732       // The pow or exp intrinsic returned a NaN, which requires a call
       
  1733       // to the runtime.  Recompile with the runtime call.
       
  1734       uncommon_trap(Deoptimization::Reason_intrinsic,
       
  1735                     Deoptimization::Action_make_not_entrant);
       
  1736     }
       
  1737     return result;
       
  1738   } else {
       
  1739     // If this inlining ever returned NaN in the past, we compile a call
       
  1740     // to the runtime to properly handle corner cases
       
  1741 
       
  1742     IfNode* iff = create_and_xform_if(control(), bolisnum, PROB_STATIC_FREQUENT, COUNT_UNKNOWN);
       
  1743     Node* if_slow = _gvn.transform(new IfFalseNode(iff));
       
  1744     Node* if_fast = _gvn.transform(new IfTrueNode(iff));
       
  1745 
       
  1746     if (!if_slow->is_top()) {
       
  1747       RegionNode* result_region = new RegionNode(3);
       
  1748       PhiNode*    result_val = new PhiNode(result_region, Type::DOUBLE);
       
  1749 
       
  1750       result_region->init_req(1, if_fast);
       
  1751       result_val->init_req(1, result);
       
  1752 
       
  1753       set_control(if_slow);
       
  1754 
       
  1755       const TypePtr* no_memory_effects = NULL;
       
  1756       Node* rt = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName,
       
  1757                                    no_memory_effects,
       
  1758                                    x, top(), y, y ? top() : NULL);
       
  1759       Node* value = _gvn.transform(new ProjNode(rt, TypeFunc::Parms+0));
       
  1760 #ifdef ASSERT
       
  1761       Node* value_top = _gvn.transform(new ProjNode(rt, TypeFunc::Parms+1));
       
  1762       assert(value_top == top(), "second value must be top");
       
  1763 #endif
       
  1764 
       
  1765       result_region->init_req(2, control());
       
  1766       result_val->init_req(2, value);
       
  1767       set_control(_gvn.transform(result_region));
       
  1768       return _gvn.transform(result_val);
       
  1769     } else {
       
  1770       return result;
       
  1771     }
       
  1772   }
       
  1773 }
       
  1774 
       
  1775 //------------------------------inline_pow-------------------------------------
       
  1776 // Inline power instructions, if possible.
       
  1777 bool LibraryCallKit::inline_pow() {
       
  1778   // Pseudocode for pow
       
  1779   // if (y == 2) {
       
  1780   //   return x * x;
       
  1781   // } else {
       
  1782   //   if (x <= 0.0) {
       
  1783   //     long longy = (long)y;
       
  1784   //     if ((double)longy == y) { // if y is long
       
  1785   //       if (y + 1 == y) longy = 0; // huge number: even
       
  1786   //       result = ((1&longy) == 0)?-DPow(abs(x), y):DPow(abs(x), y);
       
  1787   //     } else {
       
  1788   //       result = NaN;
       
  1789   //     }
       
  1790   //   } else {
       
  1791   //     result = DPow(x,y);
       
  1792   //   }
       
  1793   //   if (result != result)?  {
       
  1794   //     result = uncommon_trap() or runtime_call();
       
  1795   //   }
       
  1796   //   return result;
       
  1797   // }
       
  1798 
       
  1799   Node* x = round_double_node(argument(0));
       
  1800   Node* y = round_double_node(argument(2));
       
  1801 
       
  1802   Node* result = NULL;
       
  1803 
       
  1804   Node*   const_two_node = makecon(TypeD::make(2.0));
       
  1805   Node*   cmp_node       = _gvn.transform(new CmpDNode(y, const_two_node));
       
  1806   Node*   bool_node      = _gvn.transform(new BoolNode(cmp_node, BoolTest::eq));
       
  1807   IfNode* if_node        = create_and_xform_if(control(), bool_node, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN);
       
  1808   Node*   if_true        = _gvn.transform(new IfTrueNode(if_node));
       
  1809   Node*   if_false       = _gvn.transform(new IfFalseNode(if_node));
       
  1810 
       
  1811   RegionNode* region_node = new RegionNode(3);
       
  1812   region_node->init_req(1, if_true);
       
  1813 
       
  1814   Node* phi_node = new PhiNode(region_node, Type::DOUBLE);
       
  1815   // special case for x^y where y == 2, we can convert it to x * x
       
  1816   phi_node->init_req(1, _gvn.transform(new MulDNode(x, x)));
       
  1817 
       
  1818   // set control to if_false since we will now process the false branch
       
  1819   set_control(if_false);
       
  1820 
       
  1821   if (!too_many_traps(Deoptimization::Reason_intrinsic)) {
       
  1822     // Short form: skip the fancy tests and just check for NaN result.
       
  1823     result = _gvn.transform(new PowDNode(C, control(), x, y));
       
  1824   } else {
       
  1825     // If this inlining ever returned NaN in the past, include all
       
  1826     // checks + call to the runtime.
       
  1827 
       
  1828     // Set the merge point for If node with condition of (x <= 0.0)
       
  1829     // There are four possible paths to region node and phi node
       
  1830     RegionNode *r = new RegionNode(4);
       
  1831     Node *phi = new PhiNode(r, Type::DOUBLE);
       
  1832 
       
  1833     // Build the first if node: if (x <= 0.0)
       
  1834     // Node for 0 constant
       
  1835     Node *zeronode = makecon(TypeD::ZERO);
       
  1836     // Check x:0
       
  1837     Node *cmp = _gvn.transform(new CmpDNode(x, zeronode));
       
  1838     // Check: If (x<=0) then go complex path
       
  1839     Node *bol1 = _gvn.transform(new BoolNode( cmp, BoolTest::le ));
       
  1840     // Branch either way
       
  1841     IfNode *if1 = create_and_xform_if(control(),bol1, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN);
       
  1842     // Fast path taken; set region slot 3
       
  1843     Node *fast_taken = _gvn.transform(new IfFalseNode(if1));
       
  1844     r->init_req(3,fast_taken); // Capture fast-control
       
  1845 
       
  1846     // Fast path not-taken, i.e. slow path
       
  1847     Node *complex_path = _gvn.transform(new IfTrueNode(if1));
       
  1848 
       
  1849     // Set fast path result
       
  1850     Node *fast_result = _gvn.transform(new PowDNode(C, control(), x, y));
       
  1851     phi->init_req(3, fast_result);
       
  1852 
       
  1853     // Complex path
       
  1854     // Build the second if node (if y is long)
       
  1855     // Node for (long)y
       
  1856     Node *longy = _gvn.transform(new ConvD2LNode(y));
       
  1857     // Node for (double)((long) y)
       
  1858     Node *doublelongy= _gvn.transform(new ConvL2DNode(longy));
       
  1859     // Check (double)((long) y) : y
       
  1860     Node *cmplongy= _gvn.transform(new CmpDNode(doublelongy, y));
       
  1861     // Check if (y isn't long) then go to slow path
       
  1862 
       
  1863     Node *bol2 = _gvn.transform(new BoolNode( cmplongy, BoolTest::ne ));
       
  1864     // Branch either way
       
  1865     IfNode *if2 = create_and_xform_if(complex_path,bol2, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN);
       
  1866     Node* ylong_path = _gvn.transform(new IfFalseNode(if2));
       
  1867 
       
  1868     Node *slow_path = _gvn.transform(new IfTrueNode(if2));
       
  1869 
       
  1870     // Calculate DPow(abs(x), y)*(1 & (long)y)
       
  1871     // Node for constant 1
       
  1872     Node *conone = longcon(1);
       
  1873     // 1& (long)y
       
  1874     Node *signnode= _gvn.transform(new AndLNode(conone, longy));
       
  1875 
       
  1876     // A huge number is always even. Detect a huge number by checking
       
  1877     // if y + 1 == y and set integer to be tested for parity to 0.
       
  1878     // Required for corner case:
       
  1879     // (long)9.223372036854776E18 = max_jlong
       
  1880     // (double)(long)9.223372036854776E18 = 9.223372036854776E18
       
  1881     // max_jlong is odd but 9.223372036854776E18 is even
       
  1882     Node* yplus1 = _gvn.transform(new AddDNode(y, makecon(TypeD::make(1))));
       
  1883     Node *cmpyplus1= _gvn.transform(new CmpDNode(yplus1, y));
       
  1884     Node *bolyplus1 = _gvn.transform(new BoolNode( cmpyplus1, BoolTest::eq ));
       
  1885     Node* correctedsign = NULL;
       
  1886     if (ConditionalMoveLimit != 0) {
       
  1887       correctedsign = _gvn.transform(CMoveNode::make(NULL, bolyplus1, signnode, longcon(0), TypeLong::LONG));
       
  1888     } else {
       
  1889       IfNode *ifyplus1 = create_and_xform_if(ylong_path,bolyplus1, PROB_FAIR, COUNT_UNKNOWN);
       
  1890       RegionNode *r = new RegionNode(3);
       
  1891       Node *phi = new PhiNode(r, TypeLong::LONG);
       
  1892       r->init_req(1, _gvn.transform(new IfFalseNode(ifyplus1)));
       
  1893       r->init_req(2, _gvn.transform(new IfTrueNode(ifyplus1)));
       
  1894       phi->init_req(1, signnode);
       
  1895       phi->init_req(2, longcon(0));
       
  1896       correctedsign = _gvn.transform(phi);
       
  1897       ylong_path = _gvn.transform(r);
       
  1898       record_for_igvn(r);
       
  1899     }
       
  1900 
       
  1901     // zero node
       
  1902     Node *conzero = longcon(0);
       
  1903     // Check (1&(long)y)==0?
       
  1904     Node *cmpeq1 = _gvn.transform(new CmpLNode(correctedsign, conzero));
       
  1905     // Check if (1&(long)y)!=0?, if so the result is negative
       
  1906     Node *bol3 = _gvn.transform(new BoolNode( cmpeq1, BoolTest::ne ));
       
  1907     // abs(x)
       
  1908     Node *absx=_gvn.transform(new AbsDNode(x));
       
  1909     // abs(x)^y
       
  1910     Node *absxpowy = _gvn.transform(new PowDNode(C, control(), absx, y));
       
  1911     // -abs(x)^y
       
  1912     Node *negabsxpowy = _gvn.transform(new NegDNode (absxpowy));
       
  1913     // (1&(long)y)==1?-DPow(abs(x), y):DPow(abs(x), y)
       
  1914     Node *signresult = NULL;
       
  1915     if (ConditionalMoveLimit != 0) {
       
  1916       signresult = _gvn.transform(CMoveNode::make(NULL, bol3, absxpowy, negabsxpowy, Type::DOUBLE));
       
  1917     } else {
       
  1918       IfNode *ifyeven = create_and_xform_if(ylong_path,bol3, PROB_FAIR, COUNT_UNKNOWN);
       
  1919       RegionNode *r = new RegionNode(3);
       
  1920       Node *phi = new PhiNode(r, Type::DOUBLE);
       
  1921       r->init_req(1, _gvn.transform(new IfFalseNode(ifyeven)));
       
  1922       r->init_req(2, _gvn.transform(new IfTrueNode(ifyeven)));
       
  1923       phi->init_req(1, absxpowy);
       
  1924       phi->init_req(2, negabsxpowy);
       
  1925       signresult = _gvn.transform(phi);
       
  1926       ylong_path = _gvn.transform(r);
       
  1927       record_for_igvn(r);
       
  1928     }
       
  1929     // Set complex path fast result
       
  1930     r->init_req(2, ylong_path);
       
  1931     phi->init_req(2, signresult);
       
  1932 
       
  1933     static const jlong nan_bits = CONST64(0x7ff8000000000000);
       
  1934     Node *slow_result = makecon(TypeD::make(*(double*)&nan_bits)); // return NaN
       
  1935     r->init_req(1,slow_path);
       
  1936     phi->init_req(1,slow_result);
       
  1937 
       
  1938     // Post merge
       
  1939     set_control(_gvn.transform(r));
       
  1940     record_for_igvn(r);
       
  1941     result = _gvn.transform(phi);
       
  1942   }
       
  1943 
       
  1944   result = finish_pow_exp(result, x, y, OptoRuntime::Math_DD_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dpow), "POW");
       
  1945 
       
  1946   // control from finish_pow_exp is now input to the region node
       
  1947   region_node->set_req(2, control());
       
  1948   // the result from finish_pow_exp is now input to the phi node
       
  1949   phi_node->init_req(2, result);
       
  1950   set_control(_gvn.transform(region_node));
       
  1951   record_for_igvn(region_node);
       
  1952   set_result(_gvn.transform(phi_node));
       
  1953 
       
  1954   C->set_has_split_ifs(true); // Has chance for split-if optimization
       
  1955   return true;
       
  1956 }
       
  1957 
       
  1958 //------------------------------runtime_math-----------------------------
  1719 //------------------------------runtime_math-----------------------------
  1959 bool LibraryCallKit::runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName) {
  1720 bool LibraryCallKit::runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName) {
  1960   assert(call_type == OptoRuntime::Math_DD_D_Type() || call_type == OptoRuntime::Math_D_D_Type(),
  1721   assert(call_type == OptoRuntime::Math_DD_D_Type() || call_type == OptoRuntime::Math_D_D_Type(),
  1961          "must be (DD)D or (D)D type");
  1722          "must be (DD)D or (D)D type");
  1962 
  1723 
  2003 
  1764 
  2004   case vmIntrinsics::_dexp:
  1765   case vmIntrinsics::_dexp:
  2005     return StubRoutines::dexp() != NULL ?
  1766     return StubRoutines::dexp() != NULL ?
  2006       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dexp(),  "dexp") :
  1767       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dexp(),  "dexp") :
  2007       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dexp),  "EXP");
  1768       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dexp),  "EXP");
  2008   case vmIntrinsics::_dpow:   return Matcher::has_match_rule(Op_PowD)   ? inline_pow()    :
  1769   case vmIntrinsics::_dpow:
  2009     runtime_math(OptoRuntime::Math_DD_D_Type(), FN_PTR(SharedRuntime::dpow),  "POW");
  1770     return StubRoutines::dpow() != NULL ?
       
  1771       runtime_math(OptoRuntime::Math_DD_D_Type(), StubRoutines::dpow(), "dpow") :
       
  1772       runtime_math(OptoRuntime::Math_DD_D_Type(), FN_PTR(SharedRuntime::dpow),  "POW");
  2010 #undef FN_PTR
  1773 #undef FN_PTR
  2011 
  1774 
  2012    // These intrinsics are not yet correctly implemented
  1775    // These intrinsics are not yet correctly implemented
  2013   case vmIntrinsics::_datan2:
  1776   case vmIntrinsics::_datan2:
  2014     return false;
  1777     return false;