< prev index next >

src/share/vm/opto/library_call.cpp

Print this page




 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


< prev index next >