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 |