204 bool inline_string_compareTo();
205 bool inline_string_indexOf();
206 Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i);
207 bool inline_string_equals();
208 Node* round_double_node(Node* n);
209 bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
210 bool inline_math_native(vmIntrinsics::ID id);
211 bool inline_trig(vmIntrinsics::ID id);
212 bool inline_math(vmIntrinsics::ID id);
213 template <typename OverflowOp>
214 bool inline_math_overflow(Node* arg1, Node* arg2);
215 void inline_math_mathExact(Node* math, Node* test);
216 bool inline_math_addExactI(bool is_increment);
217 bool inline_math_addExactL(bool is_increment);
218 bool inline_math_multiplyExactI();
219 bool inline_math_multiplyExactL();
220 bool inline_math_negateExactI();
221 bool inline_math_negateExactL();
222 bool inline_math_subtractExactI(bool is_decrement);
223 bool inline_math_subtractExactL(bool is_decrement);
224 bool inline_exp();
225 bool inline_pow();
226 Node* finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
227 bool inline_min_max(vmIntrinsics::ID id);
228 Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
229 // This returns Type::AnyPtr, RawPtr, or OopPtr.
230 int classify_unsafe_addr(Node* &base, Node* &offset);
231 Node* make_unsafe_address(Node* base, Node* offset);
232 // Helper for inline_unsafe_access.
233 // Generates the guards that check whether the result of
234 // Unsafe.getObject should be recorded in an SATB log buffer.
235 void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar);
236 bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile);
237 static bool klass_needs_init_guard(Node* kls);
238 bool inline_unsafe_allocate();
239 bool inline_unsafe_copyMemory();
240 bool inline_native_currentThread();
241 #ifdef TRACE_HAVE_INTRINSICS
242 bool inline_native_classID();
243 bool inline_native_threadID();
244 #endif
1793 const TypePtr* no_memory_effects = NULL;
1794 Node* rt = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName,
1795 no_memory_effects,
1796 x, top(), y, y ? top() : NULL);
1797 Node* value = _gvn.transform(new ProjNode(rt, TypeFunc::Parms+0));
1798 #ifdef ASSERT
1799 Node* value_top = _gvn.transform(new ProjNode(rt, TypeFunc::Parms+1));
1800 assert(value_top == top(), "second value must be top");
1801 #endif
1802
1803 result_region->init_req(2, control());
1804 result_val->init_req(2, value);
1805 set_control(_gvn.transform(result_region));
1806 return _gvn.transform(result_val);
1807 } else {
1808 return result;
1809 }
1810 }
1811 }
1812
1813 //------------------------------inline_exp-------------------------------------
1814 // Inline exp instructions, if possible. The Intel hardware only misses
1815 // really odd corner cases (+/- Infinity). Just uncommon-trap them.
1816 bool LibraryCallKit::inline_exp() {
1817 Node* arg = round_double_node(argument(0));
1818 Node* n = _gvn.transform(new ExpDNode(C, control(), arg));
1819
1820 n = finish_pow_exp(n, arg, NULL, OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dexp), "EXP");
1821 set_result(n);
1822
1823 C->set_has_split_ifs(true); // Has chance for split-if optimization
1824 return true;
1825 }
1826
1827 //------------------------------inline_pow-------------------------------------
1828 // Inline power instructions, if possible.
1829 bool LibraryCallKit::inline_pow() {
1830 // Pseudocode for pow
1831 // if (y == 2) {
1832 // return x * x;
1833 // } else {
1834 // if (x <= 0.0) {
1835 // long longy = (long)y;
1836 // if ((double)longy == y) { // if y is long
1837 // if (y + 1 == y) longy = 0; // huge number: even
1838 // result = ((1&longy) == 0)?-DPow(abs(x), y):DPow(abs(x), y);
1839 // } else {
1840 // result = NaN;
1841 // }
1842 // } else {
1843 // result = DPow(x,y);
1844 // }
1845 // if (result != result)? {
1846 // result = uncommon_trap() or runtime_call();
2034 bool LibraryCallKit::inline_math_native(vmIntrinsics::ID id) {
2035 #define FN_PTR(f) CAST_FROM_FN_PTR(address, f)
2036 switch (id) {
2037 // These intrinsics are not properly supported on all hardware
2038 case vmIntrinsics::_dcos: return Matcher::has_match_rule(Op_CosD) ? inline_trig(id) :
2039 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dcos), "COS");
2040 case vmIntrinsics::_dsin: return Matcher::has_match_rule(Op_SinD) ? inline_trig(id) :
2041 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dsin), "SIN");
2042 case vmIntrinsics::_dtan: return Matcher::has_match_rule(Op_TanD) ? inline_trig(id) :
2043 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dtan), "TAN");
2044
2045 case vmIntrinsics::_dlog: return Matcher::has_match_rule(Op_LogD) ? inline_math(id) :
2046 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog), "LOG");
2047 case vmIntrinsics::_dlog10: return Matcher::has_match_rule(Op_Log10D) ? inline_math(id) :
2048 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog10), "LOG10");
2049
2050 // These intrinsics are supported on all hardware
2051 case vmIntrinsics::_dsqrt: return Matcher::match_rule_supported(Op_SqrtD) ? inline_math(id) : false;
2052 case vmIntrinsics::_dabs: return Matcher::has_match_rule(Op_AbsD) ? inline_math(id) : false;
2053
2054 case vmIntrinsics::_dexp: return Matcher::has_match_rule(Op_ExpD) ? inline_exp() :
2055 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dexp), "EXP");
2056 case vmIntrinsics::_dpow: return Matcher::has_match_rule(Op_PowD) ? inline_pow() :
2057 runtime_math(OptoRuntime::Math_DD_D_Type(), FN_PTR(SharedRuntime::dpow), "POW");
2058 #undef FN_PTR
2059
2060 // These intrinsics are not yet correctly implemented
2061 case vmIntrinsics::_datan2:
2062 return false;
2063
2064 default:
2065 fatal_unexpected_iid(id);
2066 return false;
2067 }
2068 }
2069
2070 static bool is_simple_name(Node* n) {
2071 return (n->req() == 1 // constant
2072 || (n->is_Type() && n->as_Type()->type()->singleton())
2073 || n->is_Proj() // parameter or return value
2074 || n->is_Phi() // local of some sort
|
204 bool inline_string_compareTo();
205 bool inline_string_indexOf();
206 Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i);
207 bool inline_string_equals();
208 Node* round_double_node(Node* n);
209 bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
210 bool inline_math_native(vmIntrinsics::ID id);
211 bool inline_trig(vmIntrinsics::ID id);
212 bool inline_math(vmIntrinsics::ID id);
213 template <typename OverflowOp>
214 bool inline_math_overflow(Node* arg1, Node* arg2);
215 void inline_math_mathExact(Node* math, Node* test);
216 bool inline_math_addExactI(bool is_increment);
217 bool inline_math_addExactL(bool is_increment);
218 bool inline_math_multiplyExactI();
219 bool inline_math_multiplyExactL();
220 bool inline_math_negateExactI();
221 bool inline_math_negateExactL();
222 bool inline_math_subtractExactI(bool is_decrement);
223 bool inline_math_subtractExactL(bool is_decrement);
224 bool inline_pow();
225 Node* finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
226 bool inline_min_max(vmIntrinsics::ID id);
227 Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
228 // This returns Type::AnyPtr, RawPtr, or OopPtr.
229 int classify_unsafe_addr(Node* &base, Node* &offset);
230 Node* make_unsafe_address(Node* base, Node* offset);
231 // Helper for inline_unsafe_access.
232 // Generates the guards that check whether the result of
233 // Unsafe.getObject should be recorded in an SATB log buffer.
234 void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar);
235 bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile);
236 static bool klass_needs_init_guard(Node* kls);
237 bool inline_unsafe_allocate();
238 bool inline_unsafe_copyMemory();
239 bool inline_native_currentThread();
240 #ifdef TRACE_HAVE_INTRINSICS
241 bool inline_native_classID();
242 bool inline_native_threadID();
243 #endif
1792 const TypePtr* no_memory_effects = NULL;
1793 Node* rt = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName,
1794 no_memory_effects,
1795 x, top(), y, y ? top() : NULL);
1796 Node* value = _gvn.transform(new ProjNode(rt, TypeFunc::Parms+0));
1797 #ifdef ASSERT
1798 Node* value_top = _gvn.transform(new ProjNode(rt, TypeFunc::Parms+1));
1799 assert(value_top == top(), "second value must be top");
1800 #endif
1801
1802 result_region->init_req(2, control());
1803 result_val->init_req(2, value);
1804 set_control(_gvn.transform(result_region));
1805 return _gvn.transform(result_val);
1806 } else {
1807 return result;
1808 }
1809 }
1810 }
1811
1812 //------------------------------inline_pow-------------------------------------
1813 // Inline power instructions, if possible.
1814 bool LibraryCallKit::inline_pow() {
1815 // Pseudocode for pow
1816 // if (y == 2) {
1817 // return x * x;
1818 // } else {
1819 // if (x <= 0.0) {
1820 // long longy = (long)y;
1821 // if ((double)longy == y) { // if y is long
1822 // if (y + 1 == y) longy = 0; // huge number: even
1823 // result = ((1&longy) == 0)?-DPow(abs(x), y):DPow(abs(x), y);
1824 // } else {
1825 // result = NaN;
1826 // }
1827 // } else {
1828 // result = DPow(x,y);
1829 // }
1830 // if (result != result)? {
1831 // result = uncommon_trap() or runtime_call();
2019 bool LibraryCallKit::inline_math_native(vmIntrinsics::ID id) {
2020 #define FN_PTR(f) CAST_FROM_FN_PTR(address, f)
2021 switch (id) {
2022 // These intrinsics are not properly supported on all hardware
2023 case vmIntrinsics::_dcos: return Matcher::has_match_rule(Op_CosD) ? inline_trig(id) :
2024 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dcos), "COS");
2025 case vmIntrinsics::_dsin: return Matcher::has_match_rule(Op_SinD) ? inline_trig(id) :
2026 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dsin), "SIN");
2027 case vmIntrinsics::_dtan: return Matcher::has_match_rule(Op_TanD) ? inline_trig(id) :
2028 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dtan), "TAN");
2029
2030 case vmIntrinsics::_dlog: return Matcher::has_match_rule(Op_LogD) ? inline_math(id) :
2031 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog), "LOG");
2032 case vmIntrinsics::_dlog10: return Matcher::has_match_rule(Op_Log10D) ? inline_math(id) :
2033 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog10), "LOG10");
2034
2035 // These intrinsics are supported on all hardware
2036 case vmIntrinsics::_dsqrt: return Matcher::match_rule_supported(Op_SqrtD) ? inline_math(id) : false;
2037 case vmIntrinsics::_dabs: return Matcher::has_match_rule(Op_AbsD) ? inline_math(id) : false;
2038
2039 case vmIntrinsics::_dexp:
2040 return VM_Version::supports_sse2() ? runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dexp(), "dexp") :
2041 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dexp), "EXP");
2042 case vmIntrinsics::_dpow: return Matcher::has_match_rule(Op_PowD) ? inline_pow() :
2043 runtime_math(OptoRuntime::Math_DD_D_Type(), FN_PTR(SharedRuntime::dpow), "POW");
2044 #undef FN_PTR
2045
2046 // These intrinsics are not yet correctly implemented
2047 case vmIntrinsics::_datan2:
2048 return false;
2049
2050 default:
2051 fatal_unexpected_iid(id);
2052 return false;
2053 }
2054 }
2055
2056 static bool is_simple_name(Node* n) {
2057 return (n->req() == 1 // constant
2058 || (n->is_Type() && n->as_Type()->type()->singleton())
2059 || n->is_Proj() // parameter or return value
2060 || n->is_Phi() // local of some sort
|