Mercurial > hg > truffle
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) { |