comparison src/share/vm/opto/library_call.cpp @ 12972:59e8ad757e19

8026844: Various Math functions needs intrinsification Reviewed-by: kvn, twisti
author rbackman
date Fri, 18 Oct 2013 10:41:56 +0200
parents b2ee5dc63353
children a57a165b8296
comparison
equal deleted inserted replaced
12971:3a04e444da6d 12972:59e8ad757e19
201 Node* round_double_node(Node* n); 201 Node* round_double_node(Node* n);
202 bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName); 202 bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
203 bool inline_math_native(vmIntrinsics::ID id); 203 bool inline_math_native(vmIntrinsics::ID id);
204 bool inline_trig(vmIntrinsics::ID id); 204 bool inline_trig(vmIntrinsics::ID id);
205 bool inline_math(vmIntrinsics::ID id); 205 bool inline_math(vmIntrinsics::ID id);
206 bool inline_math_mathExact(Node* math); 206 void inline_math_mathExact(Node* math);
207 bool inline_math_addExact(); 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);
208 bool inline_exp(); 215 bool inline_exp();
209 bool inline_pow(); 216 bool inline_pow();
210 void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName); 217 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); 218 bool inline_min_max(vmIntrinsics::ID id);
212 Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y); 219 Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
505 case vmIntrinsics::_updateBytesCRC32: 512 case vmIntrinsics::_updateBytesCRC32:
506 case vmIntrinsics::_updateByteBufferCRC32: 513 case vmIntrinsics::_updateByteBufferCRC32:
507 if (!UseCRC32Intrinsics) return NULL; 514 if (!UseCRC32Intrinsics) return NULL;
508 break; 515 break;
509 516
510 case vmIntrinsics::_addExact: 517 case vmIntrinsics::_incrementExactI:
511 if (!Matcher::match_rule_supported(Op_AddExactI)) { 518 case vmIntrinsics::_addExactI:
512 return NULL; 519 if (!Matcher::match_rule_supported(Op_AddExactI) || !UseMathExactIntrinsics) return NULL;
513 } 520 break;
514 if (!UseMathExactIntrinsics) { 521 case vmIntrinsics::_incrementExactL:
515 return NULL; 522 case vmIntrinsics::_addExactL:
516 } 523 if (!Matcher::match_rule_supported(Op_AddExactL) || !UseMathExactIntrinsics) return NULL;
524 break;
525 case vmIntrinsics::_decrementExactI:
526 case vmIntrinsics::_subtractExactI:
527 if (!Matcher::match_rule_supported(Op_SubExactI) || !UseMathExactIntrinsics) return NULL;
528 break;
529 case vmIntrinsics::_decrementExactL:
530 case vmIntrinsics::_subtractExactL:
531 if (!Matcher::match_rule_supported(Op_SubExactL) || !UseMathExactIntrinsics) return NULL;
532 break;
533 case vmIntrinsics::_negateExactI:
534 if (!Matcher::match_rule_supported(Op_NegExactI) || !UseMathExactIntrinsics) return NULL;
535 break;
536 case vmIntrinsics::_negateExactL:
537 if (!Matcher::match_rule_supported(Op_NegExactL) || !UseMathExactIntrinsics) return NULL;
538 break;
539 case vmIntrinsics::_multiplyExactI:
540 if (!Matcher::match_rule_supported(Op_MulExactI) || !UseMathExactIntrinsics) return NULL;
541 break;
542 case vmIntrinsics::_multiplyExactL:
543 if (!Matcher::match_rule_supported(Op_MulExactL) || !UseMathExactIntrinsics) return NULL;
517 break; 544 break;
518 545
519 default: 546 default:
520 assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility"); 547 assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility");
521 assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?"); 548 assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?");
684 case vmIntrinsics::_dpow: return inline_math_native(intrinsic_id()); 711 case vmIntrinsics::_dpow: return inline_math_native(intrinsic_id());
685 712
686 case vmIntrinsics::_min: 713 case vmIntrinsics::_min:
687 case vmIntrinsics::_max: return inline_min_max(intrinsic_id()); 714 case vmIntrinsics::_max: return inline_min_max(intrinsic_id());
688 715
689 case vmIntrinsics::_addExact: return inline_math_addExact(); 716 case vmIntrinsics::_addExactI: return inline_math_addExactI(false /* add */);
717 case vmIntrinsics::_addExactL: return inline_math_addExactL(false /* add */);
718 case vmIntrinsics::_decrementExactI: return inline_math_subtractExactI(true /* decrement */);
719 case vmIntrinsics::_decrementExactL: return inline_math_subtractExactL(true /* decrement */);
720 case vmIntrinsics::_incrementExactI: return inline_math_addExactI(true /* increment */);
721 case vmIntrinsics::_incrementExactL: return inline_math_addExactL(true /* increment */);
722 case vmIntrinsics::_multiplyExactI: return inline_math_multiplyExactI();
723 case vmIntrinsics::_multiplyExactL: return inline_math_multiplyExactL();
724 case vmIntrinsics::_negateExactI: return inline_math_negateExactI();
725 case vmIntrinsics::_negateExactL: return inline_math_negateExactL();
726 case vmIntrinsics::_subtractExactI: return inline_math_subtractExactI(false /* subtract */);
727 case vmIntrinsics::_subtractExactL: return inline_math_subtractExactL(false /* subtract */);
690 728
691 case vmIntrinsics::_arraycopy: return inline_arraycopy(); 729 case vmIntrinsics::_arraycopy: return inline_arraycopy();
692 730
693 case vmIntrinsics::_compareTo: return inline_string_compareTo(); 731 case vmIntrinsics::_compareTo: return inline_string_compareTo();
694 case vmIntrinsics::_indexOf: return inline_string_indexOf(); 732 case vmIntrinsics::_indexOf: return inline_string_indexOf();
1929 bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) { 1967 bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) {
1930 set_result(generate_min_max(id, argument(0), argument(1))); 1968 set_result(generate_min_max(id, argument(0), argument(1)));
1931 return true; 1969 return true;
1932 } 1970 }
1933 1971
1934 bool LibraryCallKit::inline_math_mathExact(Node* math) { 1972 void LibraryCallKit::inline_math_mathExact(Node* math) {
1973 // If we didn't get the expected opcode it means we have optimized
1974 // the node to something else and don't need the exception edge.
1975 if (!math->is_MathExact()) {
1976 set_result(math);
1977 return;
1978 }
1979
1935 Node* result = _gvn.transform( new(C) ProjNode(math, MathExactNode::result_proj_node)); 1980 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)); 1981 Node* flags = _gvn.transform( new(C) FlagsProjNode(math, MathExactNode::flags_proj_node));
1937 1982
1938 Node* bol = _gvn.transform( new (C) BoolNode(flags, BoolTest::overflow) ); 1983 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); 1984 IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
1952 Deoptimization::Action_none); 1997 Deoptimization::Action_none);
1953 } 1998 }
1954 1999
1955 set_control(fast_path); 2000 set_control(fast_path);
1956 set_result(result); 2001 set_result(result);
2002 }
2003
2004 bool LibraryCallKit::inline_math_addExactI(bool is_increment) {
2005 Node* arg1 = argument(0);
2006 Node* arg2 = NULL;
2007
2008 if (is_increment) {
2009 arg2 = intcon(1);
2010 } else {
2011 arg2 = argument(1);
2012 }
2013
2014 Node* add = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2) );
2015 inline_math_mathExact(add);
1957 return true; 2016 return true;
1958 } 2017 }
1959 2018
1960 bool LibraryCallKit::inline_math_addExact() { 2019 bool LibraryCallKit::inline_math_addExactL(bool is_increment) {
2020 Node* arg1 = argument(0); // type long
2021 // argument(1) == TOP
2022 Node* arg2 = NULL;
2023
2024 if (is_increment) {
2025 arg2 = longcon(1);
2026 } else {
2027 arg2 = argument(2); // type long
2028 // argument(3) == TOP
2029 }
2030
2031 Node* add = _gvn.transform(new(C) AddExactLNode(NULL, arg1, arg2));
2032 inline_math_mathExact(add);
2033 return true;
2034 }
2035
2036 bool LibraryCallKit::inline_math_subtractExactI(bool is_decrement) {
2037 Node* arg1 = argument(0);
2038 Node* arg2 = NULL;
2039
2040 if (is_decrement) {
2041 arg2 = intcon(1);
2042 } else {
2043 arg2 = argument(1);
2044 }
2045
2046 Node* sub = _gvn.transform(new(C) SubExactINode(NULL, arg1, arg2));
2047 inline_math_mathExact(sub);
2048 return true;
2049 }
2050
2051 bool LibraryCallKit::inline_math_subtractExactL(bool is_decrement) {
2052 Node* arg1 = argument(0); // type long
2053 // argument(1) == TOP
2054 Node* arg2 = NULL;
2055
2056 if (is_decrement) {
2057 arg2 = longcon(1);
2058 } else {
2059 Node* arg2 = argument(2); // type long
2060 // argument(3) == TOP
2061 }
2062
2063 Node* sub = _gvn.transform(new(C) SubExactLNode(NULL, arg1, arg2));
2064 inline_math_mathExact(sub);
2065 return true;
2066 }
2067
2068 bool LibraryCallKit::inline_math_negateExactI() {
2069 Node* arg1 = argument(0);
2070
2071 Node* neg = _gvn.transform(new(C) NegExactINode(NULL, arg1));
2072 inline_math_mathExact(neg);
2073 return true;
2074 }
2075
2076 bool LibraryCallKit::inline_math_negateExactL() {
2077 Node* arg1 = argument(0);
2078 // argument(1) == TOP
2079
2080 Node* neg = _gvn.transform(new(C) NegExactLNode(NULL, arg1));
2081 inline_math_mathExact(neg);
2082 return true;
2083 }
2084
2085 bool LibraryCallKit::inline_math_multiplyExactI() {
1961 Node* arg1 = argument(0); 2086 Node* arg1 = argument(0);
1962 Node* arg2 = argument(1); 2087 Node* arg2 = argument(1);
1963 2088
1964 Node* add = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2) ); 2089 Node* mul = _gvn.transform(new(C) MulExactINode(NULL, arg1, arg2));
1965 if (add->Opcode() == Op_AddExactI) { 2090 inline_math_mathExact(mul);
1966 return inline_math_mathExact(add); 2091 return true;
1967 } else { 2092 }
1968 set_result(add); 2093
1969 } 2094 bool LibraryCallKit::inline_math_multiplyExactL() {
2095 Node* arg1 = argument(0);
2096 // argument(1) == TOP
2097 Node* arg2 = argument(2);
2098 // argument(3) == TOP
2099
2100 Node* mul = _gvn.transform(new(C) MulExactLNode(NULL, arg1, arg2));
2101 inline_math_mathExact(mul);
1970 return true; 2102 return true;
1971 } 2103 }
1972 2104
1973 Node* 2105 Node*
1974 LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) { 2106 LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) {