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 5902 : 8027754: Enable loop optimizations for loops with MathExact inside


 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_addExactI(bool is_increment);
 208   bool inline_math_addExactL(bool is_increment);
 209   bool inline_math_multiplyExactI();
 210   bool inline_math_multiplyExactL();
 211   bool inline_math_negateExactI();
 212   bool inline_math_negateExactL();
 213   bool inline_math_subtractExactI(bool is_decrement);
 214   bool inline_math_subtractExactL(bool is_decrement);
 215   bool inline_exp();
 216   bool inline_pow();
 217   void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
 218   bool inline_min_max(vmIntrinsics::ID id);
 219   Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
 220   // This returns Type::AnyPtr, RawPtr, or OopPtr.
 221   int classify_unsafe_addr(Node* &base, Node* &offset);
 222   Node* make_unsafe_address(Node* base, Node* offset);
 223   // Helper for inline_unsafe_access.
 224   // Generates the guards that check whether the result of
 225   // Unsafe.getObject should be recorded in an SATB log buffer.
 226   void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar);


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


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


2017   return true;
2018 }
2019 
2020 bool LibraryCallKit::inline_math_addExactL(bool is_increment) {
2021   Node* arg1 = argument(0); // type long
2022   // argument(1) == TOP
2023   Node* arg2 = NULL;
2024 
2025   if (is_increment) {
2026     arg2 = longcon(1);
2027   } else {
2028     arg2 = argument(2); // type long
2029     // argument(3) == TOP
2030   }
2031 
2032   Node* add = _gvn.transform(new(C) AddExactLNode(NULL, arg1, arg2));
2033   inline_math_mathExact(add);
2034   return true;
2035 }
2036 
2037 bool LibraryCallKit::inline_math_subtractExactI(bool is_decrement) {
2038   Node* arg1 = argument(0);
2039   Node* arg2 = NULL;
2040 
2041   if (is_decrement) {
2042     arg2 = intcon(1);
2043   } else {
2044     arg2 = argument(1);
2045   }
2046 
2047   Node* sub = _gvn.transform(new(C) SubExactINode(NULL, arg1, arg2));
2048   inline_math_mathExact(sub);
2049   return true;
2050 }
2051 
2052 bool LibraryCallKit::inline_math_subtractExactL(bool is_decrement) {
2053   Node* arg1 = argument(0); // type long
2054   // argument(1) == TOP
2055   Node* arg2 = NULL;
2056 
2057   if (is_decrement) {
2058     arg2 = longcon(1);
2059   } else {
2060     arg2 = argument(2); // type long
2061     // argument(3) == TOP
2062   }
2063 
2064   Node* sub = _gvn.transform(new(C) SubExactLNode(NULL, arg1, arg2));
2065   inline_math_mathExact(sub);
2066   return true;
2067 }
2068 
2069 bool LibraryCallKit::inline_math_negateExactI() {
2070   Node* arg1 = argument(0);
2071 
2072   Node* neg = _gvn.transform(new(C) NegExactINode(NULL, arg1));
2073   inline_math_mathExact(neg);
2074   return true;
2075 }
2076 
2077 bool LibraryCallKit::inline_math_negateExactL() {
2078   Node* arg1 = argument(0);
2079   // argument(1) == TOP
2080 
2081   Node* neg = _gvn.transform(new(C) NegExactLNode(NULL, arg1));
2082   inline_math_mathExact(neg);
2083   return true;
2084 }
2085 
2086 bool LibraryCallKit::inline_math_multiplyExactI() {
2087   Node* arg1 = argument(0);
2088   Node* arg2 = argument(1);
2089 
2090   Node* mul = _gvn.transform(new(C) MulExactINode(NULL, arg1, arg2));
2091   inline_math_mathExact(mul);
2092   return true;
2093 }
2094 
2095 bool LibraryCallKit::inline_math_multiplyExactL() {
2096   Node* arg1 = argument(0);
2097   // argument(1) == TOP
2098   Node* arg2 = argument(2);
2099   // argument(3) == TOP
2100 
2101   Node* mul = _gvn.transform(new(C) MulExactLNode(NULL, arg1, arg2));
2102   inline_math_mathExact(mul);
2103   return true;
2104 }
2105 
2106 Node*
2107 LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) {
2108   // These are the candidate return value:
2109   Node* xvalue = x0;
2110   Node* yvalue = y0;
2111 
2112   if (xvalue == yvalue) {
2113     return xvalue;
2114   }
2115 
2116   bool want_max = (id == vmIntrinsics::_max);
2117 
2118   const TypeInt* txvalue = _gvn.type(xvalue)->isa_int();
2119   const TypeInt* tyvalue = _gvn.type(yvalue)->isa_int();
2120   if (txvalue == NULL || tyvalue == NULL)  return top();
2121   // This is not really necessary, but it is consistent with a
2122   // hypothetical MaxINode::Value method:
2123   int widen = MAX2(txvalue->_widen, tyvalue->_widen);




 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   template <typename OverflowOp>
 207   bool inline_math_overflow(Node* arg1, Node* arg2);
 208   template <typename OverflowOp>
 209   bool inline_math_overflow(bool is_unary);
 210   void inline_math_mathExact(Node* math, Node* test);
 211   bool inline_math_addExactI(bool is_increment);
 212   bool inline_math_addExactL(bool is_increment);
 213   bool inline_math_multiplyExactI();
 214   bool inline_math_multiplyExactL();
 215   bool inline_math_negateExactI();
 216   bool inline_math_negateExactL();
 217   bool inline_math_subtractExactI(bool is_decrement);
 218   bool inline_math_subtractExactL(bool is_decrement);
 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);


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


1957   default:
1958     fatal_unexpected_iid(id);
1959     return false;
1960   }
1961 }
1962 
1963 static bool is_simple_name(Node* n) {
1964   return (n->req() == 1         // constant
1965           || (n->is_Type() && n->as_Type()->type()->singleton())
1966           || n->is_Proj()       // parameter or return value
1967           || n->is_Phi()        // local of some sort
1968           );
1969 }
1970 
1971 //----------------------------inline_min_max-----------------------------------
1972 bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) {
1973   set_result(generate_min_max(id, argument(0), argument(1)));
1974   return true;
1975 }
1976 
1977 void LibraryCallKit::inline_math_mathExact(Node* math, Node *test) {
1978   Node* bol = _gvn.transform( new (C) BoolNode(test, BoolTest::overflow) );










1979   IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
1980   Node* fast_path = _gvn.transform( new (C) IfFalseNode(check));
1981   Node* slow_path = _gvn.transform( new (C) IfTrueNode(check) );
1982 
1983   {
1984     PreserveJVMState pjvms(this);
1985     PreserveReexecuteState preexecs(this);
1986     jvms()->set_should_reexecute(true);
1987 
1988     set_control(slow_path);
1989     set_i_o(i_o());
1990 
1991     uncommon_trap(Deoptimization::Reason_intrinsic,
1992                   Deoptimization::Action_none);
1993   }
1994 
1995   set_control(fast_path);
1996   set_result(math);
1997 }
1998 
1999 template <typename OverflowOp>
2000 bool LibraryCallKit::inline_math_overflow(Node* arg1, Node* arg2) {
2001   typedef typename OverflowOp::MathOp MathOp;






2002 
2003   MathOp* mathOp = new(C) MathOp(arg1, arg2);
2004   Node* operation = _gvn.transform( mathOp );
2005   Node* ofcheck = _gvn.transform( new(C) OverflowOp(arg1, arg2) );
2006   inline_math_mathExact(operation, ofcheck);
2007   return true;
2008 }
2009 
2010 template <typename OverflowOp>
2011 bool LibraryCallKit::inline_math_overflow(bool is_unary) {
2012   Node* arg1 = argument(0);
2013   Node* arg2 = NULL;
2014 
2015   if (OverflowOp::IsLong) {
2016     arg2 = (is_unary ? longcon(1) : argument(2));
2017   } else {
2018     arg2 = (is_unary ? intcon(1) : argument(1));

2019   }
2020   return inline_math_overflow<OverflowOp>(arg1, arg2);



2021 }
2022 
2023 bool LibraryCallKit::inline_math_addExactI(bool is_increment) {
2024   return inline_math_overflow<OverflowAddINode>(is_increment);
2025 }
2026 
2027 bool LibraryCallKit::inline_math_addExactL(bool is_increment) {
2028   return inline_math_overflow<OverflowAddLNode>(is_increment);
2029 }


2030 
2031 bool LibraryCallKit::inline_math_subtractExactI(bool is_decrement) {
2032   return inline_math_overflow<OverflowSubINode>(is_decrement);

2033 }
2034 
2035 bool LibraryCallKit::inline_math_subtractExactL(bool is_decrement) {
2036   return inline_math_overflow<OverflowSubLNode>(is_decrement);













2037 }
2038 
2039 bool LibraryCallKit::inline_math_negateExactI() {
2040   return inline_math_overflow<OverflowSubINode>(intcon(0), argument(0));




2041 }
2042 
2043 bool LibraryCallKit::inline_math_negateExactL() {
2044   return inline_math_overflow<OverflowSubLNode>(longcon(0), argument(0));





2045 }
2046 
2047 bool LibraryCallKit::inline_math_multiplyExactI() {
2048   return inline_math_overflow<OverflowMulINode>(false);





2049 }
2050 
2051 bool LibraryCallKit::inline_math_multiplyExactL() {
2052   return inline_math_overflow<OverflowMulLNode>(false);







2053 }
2054 
2055 Node*
2056 LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) {
2057   // These are the candidate return value:
2058   Node* xvalue = x0;
2059   Node* yvalue = y0;
2060 
2061   if (xvalue == yvalue) {
2062     return xvalue;
2063   }
2064 
2065   bool want_max = (id == vmIntrinsics::_max);
2066 
2067   const TypeInt* txvalue = _gvn.type(xvalue)->isa_int();
2068   const TypeInt* tyvalue = _gvn.type(yvalue)->isa_int();
2069   if (txvalue == NULL || tyvalue == NULL)  return top();
2070   // This is not really necessary, but it is consistent with a
2071   // hypothetical MaxINode::Value method:
2072   int widen = MAX2(txvalue->_widen, tyvalue->_widen);


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