src/share/vm/opto/library_call.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/opto

src/share/vm/opto/library_call.cpp

Print this page
rev 5462 : 8026844: Various Math functions needs intrinsification
Reviewed-by: duke


 186                                      bool is_virtual = false, bool is_static = false);
 187   CallJavaNode* generate_method_call_static(vmIntrinsics::ID method_id) {
 188     return generate_method_call(method_id, false, true);
 189   }
 190   CallJavaNode* generate_method_call_virtual(vmIntrinsics::ID method_id) {
 191     return generate_method_call(method_id, true, false);
 192   }
 193   Node * load_field_from_object(Node * fromObj, const char * fieldName, const char * fieldTypeString, bool is_exact, bool is_static);
 194 
 195   Node* make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2);
 196   Node* make_string_method_node(int opcode, Node* str1, Node* str2);
 197   bool inline_string_compareTo();
 198   bool inline_string_indexOf();
 199   Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i);
 200   bool inline_string_equals();
 201   Node* round_double_node(Node* n);
 202   bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
 203   bool inline_math_native(vmIntrinsics::ID id);
 204   bool inline_trig(vmIntrinsics::ID id);
 205   bool inline_math(vmIntrinsics::ID id);
 206   bool inline_math_mathExact(Node* math);
 207   bool inline_math_addExact();











 208   bool inline_exp();
 209   bool inline_pow();
 210   void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
 211   bool inline_min_max(vmIntrinsics::ID id);
 212   Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
 213   // This returns Type::AnyPtr, RawPtr, or OopPtr.
 214   int classify_unsafe_addr(Node* &base, Node* &offset);
 215   Node* make_unsafe_address(Node* base, Node* offset);
 216   // Helper for inline_unsafe_access.
 217   // Generates the guards that check whether the result of
 218   // Unsafe.getObject should be recorded in an SATB log buffer.
 219   void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar);
 220   bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile);
 221   bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static);
 222   static bool klass_needs_init_guard(Node* kls);
 223   bool inline_unsafe_allocate();
 224   bool inline_unsafe_copyMemory();
 225   bool inline_native_currentThread();
 226 #ifdef TRACE_HAVE_INTRINSICS
 227   bool inline_native_classID();


 490 #endif
 491 
 492   case vmIntrinsics::_aescrypt_encryptBlock:
 493   case vmIntrinsics::_aescrypt_decryptBlock:
 494     if (!UseAESIntrinsics) return NULL;
 495     break;
 496 
 497   case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
 498   case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
 499     if (!UseAESIntrinsics) return NULL;
 500     // these two require the predicated logic
 501     is_predicted = true;
 502     break;
 503 
 504   case vmIntrinsics::_updateCRC32:
 505   case vmIntrinsics::_updateBytesCRC32:
 506   case vmIntrinsics::_updateByteBufferCRC32:
 507     if (!UseCRC32Intrinsics) return NULL;
 508     break;
 509 

 510   case vmIntrinsics::_addExact:
 511     if (!Matcher::match_rule_supported(Op_AddExactI)) {
 512       return NULL;
 513     }
 514     if (!UseMathExactIntrinsics) {
 515       return NULL;
 516     }



















 517     break;
 518 
 519  default:
 520     assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility");
 521     assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?");
 522     break;
 523   }
 524 
 525   // -XX:-InlineClassNatives disables natives from the Class class.
 526   // The flag applies to all reflective calls, notably Array.newArray
 527   // (visible to Java programmers as Array.newInstance).
 528   if (m->holder()->name() == ciSymbol::java_lang_Class() ||
 529       m->holder()->name() == ciSymbol::java_lang_reflect_Array()) {
 530     if (!InlineClassNatives)  return NULL;
 531   }
 532 
 533   // -XX:-InlineThreadNatives disables natives from the Thread class.
 534   if (m->holder()->name() == ciSymbol::java_lang_Thread()) {
 535     if (!InlineThreadNatives)  return NULL;
 536   }


 670   switch (intrinsic_id()) {
 671   case vmIntrinsics::_hashCode:                 return inline_native_hashcode(intrinsic()->is_virtual(), !is_static);
 672   case vmIntrinsics::_identityHashCode:         return inline_native_hashcode(/*!virtual*/ false,         is_static);
 673   case vmIntrinsics::_getClass:                 return inline_native_getClass();
 674 
 675   case vmIntrinsics::_dsin:
 676   case vmIntrinsics::_dcos:
 677   case vmIntrinsics::_dtan:
 678   case vmIntrinsics::_dabs:
 679   case vmIntrinsics::_datan2:
 680   case vmIntrinsics::_dsqrt:
 681   case vmIntrinsics::_dexp:
 682   case vmIntrinsics::_dlog:
 683   case vmIntrinsics::_dlog10:
 684   case vmIntrinsics::_dpow:                     return inline_math_native(intrinsic_id());
 685 
 686   case vmIntrinsics::_min:
 687   case vmIntrinsics::_max:                      return inline_min_max(intrinsic_id());
 688 
 689   case vmIntrinsics::_addExact:                 return inline_math_addExact();











 690 
 691   case vmIntrinsics::_arraycopy:                return inline_arraycopy();
 692 
 693   case vmIntrinsics::_compareTo:                return inline_string_compareTo();
 694   case vmIntrinsics::_indexOf:                  return inline_string_indexOf();
 695   case vmIntrinsics::_equals:                   return inline_string_equals();
 696 
 697   case vmIntrinsics::_getObject:                return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT,  !is_volatile);
 698   case vmIntrinsics::_getBoolean:               return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, !is_volatile);
 699   case vmIntrinsics::_getByte:                  return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE,    !is_volatile);
 700   case vmIntrinsics::_getShort:                 return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT,   !is_volatile);
 701   case vmIntrinsics::_getChar:                  return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR,    !is_volatile);
 702   case vmIntrinsics::_getInt:                   return inline_unsafe_access(!is_native_ptr, !is_store, T_INT,     !is_volatile);
 703   case vmIntrinsics::_getLong:                  return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG,    !is_volatile);
 704   case vmIntrinsics::_getFloat:                 return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT,   !is_volatile);
 705   case vmIntrinsics::_getDouble:                return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE,  !is_volatile);
 706 
 707   case vmIntrinsics::_putObject:                return inline_unsafe_access(!is_native_ptr,  is_store, T_OBJECT,  !is_volatile);
 708   case vmIntrinsics::_putBoolean:               return inline_unsafe_access(!is_native_ptr,  is_store, T_BOOLEAN, !is_volatile);
 709   case vmIntrinsics::_putByte:                  return inline_unsafe_access(!is_native_ptr,  is_store, T_BYTE,    !is_volatile);


1914   default:
1915     fatal_unexpected_iid(id);
1916     return false;
1917   }
1918 }
1919 
1920 static bool is_simple_name(Node* n) {
1921   return (n->req() == 1         // constant
1922           || (n->is_Type() && n->as_Type()->type()->singleton())
1923           || n->is_Proj()       // parameter or return value
1924           || n->is_Phi()        // local of some sort
1925           );
1926 }
1927 
1928 //----------------------------inline_min_max-----------------------------------
1929 bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) {
1930   set_result(generate_min_max(id, argument(0), argument(1)));
1931   return true;
1932 }
1933 
1934 bool LibraryCallKit::inline_math_mathExact(Node* math) {







1935   Node* result = _gvn.transform( new(C) ProjNode(math, MathExactNode::result_proj_node));
1936   Node* flags = _gvn.transform( new(C) FlagsProjNode(math, MathExactNode::flags_proj_node));
1937 
1938   Node* bol = _gvn.transform( new (C) BoolNode(flags, BoolTest::overflow) );
1939   IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
1940   Node* fast_path = _gvn.transform( new (C) IfFalseNode(check));
1941   Node* slow_path = _gvn.transform( new (C) IfTrueNode(check) );
1942 
1943   {
1944     PreserveJVMState pjvms(this);
1945     PreserveReexecuteState preexecs(this);
1946     jvms()->set_should_reexecute(true);
1947 
1948     set_control(slow_path);
1949     set_i_o(i_o());
1950 
1951     uncommon_trap(Deoptimization::Reason_intrinsic,
1952                   Deoptimization::Action_none);
1953   }
1954 
1955   set_control(fast_path);
1956   set_result(result);
1957   return true;
1958 }
1959 
1960 bool LibraryCallKit::inline_math_addExact() {
1961   Node* arg1 = argument(0);
1962   Node* arg2 = argument(1);
1963 
1964   Node* add = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2) );
1965   if (add->Opcode() == Op_AddExactI) {
1966     return inline_math_mathExact(add);
1967   } else {
1968     set_result(add);
1969   }






































































































1970   return true;
1971 }
1972 
1973 Node*
1974 LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) {
1975   // These are the candidate return value:
1976   Node* xvalue = x0;
1977   Node* yvalue = y0;
1978 
1979   if (xvalue == yvalue) {
1980     return xvalue;
1981   }
1982 
1983   bool want_max = (id == vmIntrinsics::_max);
1984 
1985   const TypeInt* txvalue = _gvn.type(xvalue)->isa_int();
1986   const TypeInt* tyvalue = _gvn.type(yvalue)->isa_int();
1987   if (txvalue == NULL || tyvalue == NULL)  return top();
1988   // This is not really necessary, but it is consistent with a
1989   // hypothetical MaxINode::Value method:




 186                                      bool is_virtual = false, bool is_static = false);
 187   CallJavaNode* generate_method_call_static(vmIntrinsics::ID method_id) {
 188     return generate_method_call(method_id, false, true);
 189   }
 190   CallJavaNode* generate_method_call_virtual(vmIntrinsics::ID method_id) {
 191     return generate_method_call(method_id, true, false);
 192   }
 193   Node * load_field_from_object(Node * fromObj, const char * fieldName, const char * fieldTypeString, bool is_exact, bool is_static);
 194 
 195   Node* make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2);
 196   Node* make_string_method_node(int opcode, Node* str1, Node* str2);
 197   bool inline_string_compareTo();
 198   bool inline_string_indexOf();
 199   Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i);
 200   bool inline_string_equals();
 201   Node* round_double_node(Node* n);
 202   bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
 203   bool inline_math_native(vmIntrinsics::ID id);
 204   bool inline_trig(vmIntrinsics::ID id);
 205   bool inline_math(vmIntrinsics::ID id);
 206   void inline_math_mathExact(Node* math);
 207   bool inline_math_addExact();
 208   bool inline_math_addExactL();
 209   bool inline_math_decrementExact();
 210   bool inline_math_decrementExactL();
 211   bool inline_math_incrementExact();
 212   bool inline_math_incrementExactL();
 213   bool inline_math_multiplyExact();
 214   bool inline_math_multiplyExactL();
 215   bool inline_math_negateExact();
 216   bool inline_math_negateExactL();
 217   bool inline_math_subtractExact();
 218   bool inline_math_subtractExactL();
 219   bool inline_exp();
 220   bool inline_pow();
 221   void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
 222   bool inline_min_max(vmIntrinsics::ID id);
 223   Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
 224   // This returns Type::AnyPtr, RawPtr, or OopPtr.
 225   int classify_unsafe_addr(Node* &base, Node* &offset);
 226   Node* make_unsafe_address(Node* base, Node* offset);
 227   // Helper for inline_unsafe_access.
 228   // Generates the guards that check whether the result of
 229   // Unsafe.getObject should be recorded in an SATB log buffer.
 230   void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar);
 231   bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile);
 232   bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static);
 233   static bool klass_needs_init_guard(Node* kls);
 234   bool inline_unsafe_allocate();
 235   bool inline_unsafe_copyMemory();
 236   bool inline_native_currentThread();
 237 #ifdef TRACE_HAVE_INTRINSICS
 238   bool inline_native_classID();


 501 #endif
 502 
 503   case vmIntrinsics::_aescrypt_encryptBlock:
 504   case vmIntrinsics::_aescrypt_decryptBlock:
 505     if (!UseAESIntrinsics) return NULL;
 506     break;
 507 
 508   case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
 509   case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
 510     if (!UseAESIntrinsics) return NULL;
 511     // these two require the predicated logic
 512     is_predicted = true;
 513     break;
 514 
 515   case vmIntrinsics::_updateCRC32:
 516   case vmIntrinsics::_updateBytesCRC32:
 517   case vmIntrinsics::_updateByteBufferCRC32:
 518     if (!UseCRC32Intrinsics) return NULL;
 519     break;
 520 
 521   case vmIntrinsics::_incrementExact:
 522   case vmIntrinsics::_addExact:
 523     if (!Matcher::match_rule_supported(Op_AddExactI) || !UseMathExactIntrinsics) return NULL;
 524     break;
 525   case vmIntrinsics::_incrementExactL:
 526   case vmIntrinsics::_addExactL:
 527     if (!Matcher::match_rule_supported(Op_AddExactL) || !UseMathExactIntrinsics) return NULL;
 528     break;
 529   case vmIntrinsics::_decrementExact:
 530   case vmIntrinsics::_subtractExact:
 531     if (!Matcher::match_rule_supported(Op_SubExactI) || !UseMathExactIntrinsics) return NULL;
 532     break;
 533   case vmIntrinsics::_decrementExactL:
 534   case vmIntrinsics::_subtractExactL:
 535     if (!Matcher::match_rule_supported(Op_SubExactL) || !UseMathExactIntrinsics) return NULL;
 536     break;
 537   case vmIntrinsics::_negateExact:
 538     if (!Matcher::match_rule_supported(Op_NegExactI) || !UseMathExactIntrinsics) return NULL;
 539     break;
 540   case vmIntrinsics::_negateExactL:
 541     if (!Matcher::match_rule_supported(Op_NegExactL) || !UseMathExactIntrinsics) return NULL;
 542     break;
 543   case vmIntrinsics::_multiplyExact:
 544     if (!Matcher::match_rule_supported(Op_MulExactI) || !UseMathExactIntrinsics) return NULL;
 545     break;
 546   case vmIntrinsics::_multiplyExactL:
 547     if (!Matcher::match_rule_supported(Op_MulExactL) || !UseMathExactIntrinsics) return NULL;
 548     break;
 549 
 550  default:
 551     assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility");
 552     assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?");
 553     break;
 554   }
 555 
 556   // -XX:-InlineClassNatives disables natives from the Class class.
 557   // The flag applies to all reflective calls, notably Array.newArray
 558   // (visible to Java programmers as Array.newInstance).
 559   if (m->holder()->name() == ciSymbol::java_lang_Class() ||
 560       m->holder()->name() == ciSymbol::java_lang_reflect_Array()) {
 561     if (!InlineClassNatives)  return NULL;
 562   }
 563 
 564   // -XX:-InlineThreadNatives disables natives from the Thread class.
 565   if (m->holder()->name() == ciSymbol::java_lang_Thread()) {
 566     if (!InlineThreadNatives)  return NULL;
 567   }


 701   switch (intrinsic_id()) {
 702   case vmIntrinsics::_hashCode:                 return inline_native_hashcode(intrinsic()->is_virtual(), !is_static);
 703   case vmIntrinsics::_identityHashCode:         return inline_native_hashcode(/*!virtual*/ false,         is_static);
 704   case vmIntrinsics::_getClass:                 return inline_native_getClass();
 705 
 706   case vmIntrinsics::_dsin:
 707   case vmIntrinsics::_dcos:
 708   case vmIntrinsics::_dtan:
 709   case vmIntrinsics::_dabs:
 710   case vmIntrinsics::_datan2:
 711   case vmIntrinsics::_dsqrt:
 712   case vmIntrinsics::_dexp:
 713   case vmIntrinsics::_dlog:
 714   case vmIntrinsics::_dlog10:
 715   case vmIntrinsics::_dpow:                     return inline_math_native(intrinsic_id());
 716 
 717   case vmIntrinsics::_min:
 718   case vmIntrinsics::_max:                      return inline_min_max(intrinsic_id());
 719 
 720   case vmIntrinsics::_addExact:                 return inline_math_addExact();
 721   case vmIntrinsics::_addExactL:                return inline_math_addExactL();
 722   case vmIntrinsics::_decrementExact:           return inline_math_decrementExact();
 723   case vmIntrinsics::_decrementExactL:          return inline_math_decrementExactL();
 724   case vmIntrinsics::_incrementExact:           return inline_math_incrementExact();
 725   case vmIntrinsics::_incrementExactL:          return inline_math_incrementExactL();
 726   case vmIntrinsics::_multiplyExact:            return inline_math_multiplyExact();
 727   case vmIntrinsics::_multiplyExactL:           return inline_math_multiplyExactL();
 728   case vmIntrinsics::_negateExact:              return inline_math_negateExact();
 729   case vmIntrinsics::_negateExactL:             return inline_math_negateExactL();
 730   case vmIntrinsics::_subtractExact:            return inline_math_subtractExact();
 731   case vmIntrinsics::_subtractExactL:           return inline_math_subtractExactL();
 732 
 733   case vmIntrinsics::_arraycopy:                return inline_arraycopy();
 734 
 735   case vmIntrinsics::_compareTo:                return inline_string_compareTo();
 736   case vmIntrinsics::_indexOf:                  return inline_string_indexOf();
 737   case vmIntrinsics::_equals:                   return inline_string_equals();
 738 
 739   case vmIntrinsics::_getObject:                return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT,  !is_volatile);
 740   case vmIntrinsics::_getBoolean:               return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, !is_volatile);
 741   case vmIntrinsics::_getByte:                  return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE,    !is_volatile);
 742   case vmIntrinsics::_getShort:                 return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT,   !is_volatile);
 743   case vmIntrinsics::_getChar:                  return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR,    !is_volatile);
 744   case vmIntrinsics::_getInt:                   return inline_unsafe_access(!is_native_ptr, !is_store, T_INT,     !is_volatile);
 745   case vmIntrinsics::_getLong:                  return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG,    !is_volatile);
 746   case vmIntrinsics::_getFloat:                 return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT,   !is_volatile);
 747   case vmIntrinsics::_getDouble:                return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE,  !is_volatile);
 748 
 749   case vmIntrinsics::_putObject:                return inline_unsafe_access(!is_native_ptr,  is_store, T_OBJECT,  !is_volatile);
 750   case vmIntrinsics::_putBoolean:               return inline_unsafe_access(!is_native_ptr,  is_store, T_BOOLEAN, !is_volatile);
 751   case vmIntrinsics::_putByte:                  return inline_unsafe_access(!is_native_ptr,  is_store, T_BYTE,    !is_volatile);


1956   default:
1957     fatal_unexpected_iid(id);
1958     return false;
1959   }
1960 }
1961 
1962 static bool is_simple_name(Node* n) {
1963   return (n->req() == 1         // constant
1964           || (n->is_Type() && n->as_Type()->type()->singleton())
1965           || n->is_Proj()       // parameter or return value
1966           || n->is_Phi()        // local of some sort
1967           );
1968 }
1969 
1970 //----------------------------inline_min_max-----------------------------------
1971 bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) {
1972   set_result(generate_min_max(id, argument(0), argument(1)));
1973   return true;
1974 }
1975 
1976 void LibraryCallKit::inline_math_mathExact(Node* math) {
1977   // If we didn't get the expected opcode it means we have optimized
1978   // the node to something else and don't need the exception edge.
1979   if (MathExactNode::is_MathExactOpcode(math->Opcode()) == false) {
1980     set_result(math);
1981     return;
1982   }
1983 
1984   Node* result = _gvn.transform( new(C) ProjNode(math, MathExactNode::result_proj_node));
1985   Node* flags = _gvn.transform( new(C) FlagsProjNode(math, MathExactNode::flags_proj_node));
1986 
1987   Node* bol = _gvn.transform( new (C) BoolNode(flags, BoolTest::overflow) );
1988   IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
1989   Node* fast_path = _gvn.transform( new (C) IfFalseNode(check));
1990   Node* slow_path = _gvn.transform( new (C) IfTrueNode(check) );
1991 
1992   {
1993     PreserveJVMState pjvms(this);
1994     PreserveReexecuteState preexecs(this);
1995     jvms()->set_should_reexecute(true);
1996 
1997     set_control(slow_path);
1998     set_i_o(i_o());
1999 
2000     uncommon_trap(Deoptimization::Reason_intrinsic,
2001                   Deoptimization::Action_none);
2002   }
2003 
2004   set_control(fast_path);
2005   set_result(result);

2006 }
2007 
2008 bool LibraryCallKit::inline_math_addExact() {
2009   Node* arg1 = argument(0);
2010   Node* arg2 = argument(1);
2011 
2012   Node* add = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2) );
2013   inline_math_mathExact(add);
2014   return true;
2015 }
2016 
2017 bool LibraryCallKit::inline_math_addExactL() {
2018   Node* arg1 = argument(0); // type long
2019   // argument(1) == TOP
2020   Node* arg2 = argument(2); // type long
2021   // argument(4) == TOP
2022 
2023   Node* add = _gvn.transform( new(C) AddExactLNode(NULL, arg1, arg2) );
2024   inline_math_mathExact(add);
2025   return true;
2026 }
2027 
2028 bool LibraryCallKit::inline_math_subtractExactL() {
2029   Node* arg1 = argument(0); // type long
2030   // argument(1) == TOP
2031   Node* arg2 = argument(2); // type long
2032   // argument(4) == TOP
2033 
2034   Node* sub = _gvn.transform( new(C) SubExactLNode(NULL, arg1, arg2) );
2035   inline_math_mathExact(sub);
2036   return true;
2037 }
2038 
2039 bool LibraryCallKit::inline_math_subtractExact() {
2040   Node* arg1 = argument(0);
2041   Node* arg2 = argument(1);
2042 
2043   Node* sub = _gvn.transform( new(C) SubExactINode(NULL, arg1, arg2) );
2044   inline_math_mathExact(sub);
2045   return true;
2046 }
2047 
2048 bool LibraryCallKit::inline_math_negateExact() {
2049   Node* arg1 = argument(0);
2050 
2051   Node* neg = _gvn.transform( new(C) NegExactINode(NULL, arg1));
2052   inline_math_mathExact(neg);
2053   return true;
2054 }
2055 
2056 bool LibraryCallKit::inline_math_negateExactL() {
2057   Node* arg1 = argument(0);
2058   // argument(1) == TOP
2059 
2060   Node* neg = _gvn.transform( new(C) NegExactLNode(NULL, arg1));
2061   inline_math_mathExact(neg);
2062   return true;
2063 }
2064 
2065 bool LibraryCallKit::inline_math_multiplyExact() {
2066   Node* arg1 = argument(0);
2067   Node* arg2 = argument(1);
2068 
2069   Node* mul = _gvn.transform( new(C) MulExactINode(NULL, arg1, arg2) );
2070   inline_math_mathExact(mul);
2071   return true;
2072 }
2073 
2074 bool LibraryCallKit::inline_math_multiplyExactL() {
2075   Node* arg1 = argument(0);
2076   // argument(1) == TOP
2077   Node* arg2 = argument(2);
2078   // argument(3) == TOP
2079 
2080   Node* mul = _gvn.transform( new(C) MulExactLNode(NULL, arg1, arg2) );
2081   inline_math_mathExact(mul);
2082   return true;
2083 }
2084 
2085 bool LibraryCallKit::inline_math_incrementExact() {
2086   Node* arg1 = argument(0);
2087   Node* arg2 = intcon(1);
2088 
2089   Node* inc = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2));
2090   inline_math_mathExact(inc);
2091   return true;
2092 }
2093 
2094 bool LibraryCallKit::inline_math_incrementExactL() {
2095   Node* arg1 = argument(0);
2096   // argument(1) == TOP
2097   Node* arg2 = longcon(1);
2098 
2099   Node* inc = _gvn.transform( new(C) AddExactLNode(NULL, arg1, arg2));
2100   inline_math_mathExact(inc);
2101   return true;
2102 }
2103 
2104 bool LibraryCallKit::inline_math_decrementExact() {
2105   Node* arg1 = argument(0);
2106   Node* arg2 = intcon(1);
2107 
2108   Node* dec = _gvn.transform( new(C) SubExactINode(NULL, arg1, arg2));
2109   inline_math_mathExact(dec);
2110   return true;
2111 }
2112 
2113 bool LibraryCallKit::inline_math_decrementExactL() {
2114   Node* arg1 = argument(0);
2115   // argument(1) == TOP
2116   Node* arg2 = longcon(1);
2117 
2118   Node* dec = _gvn.transform( new(C) SubExactLNode(NULL, arg1, arg2));
2119   inline_math_mathExact(dec);
2120   return true;
2121 }
2122 
2123 Node*
2124 LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) {
2125   // These are the candidate return value:
2126   Node* xvalue = x0;
2127   Node* yvalue = y0;
2128 
2129   if (xvalue == yvalue) {
2130     return xvalue;
2131   }
2132 
2133   bool want_max = (id == vmIntrinsics::_max);
2134 
2135   const TypeInt* txvalue = _gvn.type(xvalue)->isa_int();
2136   const TypeInt* tyvalue = _gvn.type(yvalue)->isa_int();
2137   if (txvalue == NULL || tyvalue == NULL)  return top();
2138   // This is not really necessary, but it is consistent with a
2139   // hypothetical MaxINode::Value method:


src/share/vm/opto/library_call.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File