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 void inline_math_mathExact(Node* math); |
206 template <typename OverflowOp> |
|
207 bool inline_math_overflow(Node* arg1, Node* arg2); |
|
208 void inline_math_mathExact(Node* math, Node* test); |
207 bool inline_math_addExactI(bool is_increment); |
209 bool inline_math_addExactI(bool is_increment); |
208 bool inline_math_addExactL(bool is_increment); |
210 bool inline_math_addExactL(bool is_increment); |
209 bool inline_math_multiplyExactI(); |
211 bool inline_math_multiplyExactI(); |
210 bool inline_math_multiplyExactL(); |
212 bool inline_math_multiplyExactL(); |
211 bool inline_math_negateExactI(); |
213 bool inline_math_negateExactI(); |
515 if (!UseCRC32Intrinsics) return NULL; |
517 if (!UseCRC32Intrinsics) return NULL; |
516 break; |
518 break; |
517 |
519 |
518 case vmIntrinsics::_incrementExactI: |
520 case vmIntrinsics::_incrementExactI: |
519 case vmIntrinsics::_addExactI: |
521 case vmIntrinsics::_addExactI: |
520 if (!Matcher::match_rule_supported(Op_AddExactI) || !UseMathExactIntrinsics) return NULL; |
522 if (!Matcher::match_rule_supported(Op_OverflowAddI) || !UseMathExactIntrinsics) return NULL; |
521 break; |
523 break; |
522 case vmIntrinsics::_incrementExactL: |
524 case vmIntrinsics::_incrementExactL: |
523 case vmIntrinsics::_addExactL: |
525 case vmIntrinsics::_addExactL: |
524 if (!Matcher::match_rule_supported(Op_AddExactL) || !UseMathExactIntrinsics) return NULL; |
526 if (!Matcher::match_rule_supported(Op_OverflowAddL) || !UseMathExactIntrinsics) return NULL; |
525 break; |
527 break; |
526 case vmIntrinsics::_decrementExactI: |
528 case vmIntrinsics::_decrementExactI: |
527 case vmIntrinsics::_subtractExactI: |
529 case vmIntrinsics::_subtractExactI: |
528 if (!Matcher::match_rule_supported(Op_SubExactI) || !UseMathExactIntrinsics) return NULL; |
530 if (!Matcher::match_rule_supported(Op_OverflowSubI) || !UseMathExactIntrinsics) return NULL; |
529 break; |
531 break; |
530 case vmIntrinsics::_decrementExactL: |
532 case vmIntrinsics::_decrementExactL: |
531 case vmIntrinsics::_subtractExactL: |
533 case vmIntrinsics::_subtractExactL: |
532 if (!Matcher::match_rule_supported(Op_SubExactL) || !UseMathExactIntrinsics) return NULL; |
534 if (!Matcher::match_rule_supported(Op_OverflowSubL) || !UseMathExactIntrinsics) return NULL; |
533 break; |
535 break; |
534 case vmIntrinsics::_negateExactI: |
536 case vmIntrinsics::_negateExactI: |
535 if (!Matcher::match_rule_supported(Op_NegExactI) || !UseMathExactIntrinsics) return NULL; |
537 if (!Matcher::match_rule_supported(Op_OverflowSubI) || !UseMathExactIntrinsics) return NULL; |
536 break; |
538 break; |
537 case vmIntrinsics::_negateExactL: |
539 case vmIntrinsics::_negateExactL: |
538 if (!Matcher::match_rule_supported(Op_NegExactL) || !UseMathExactIntrinsics) return NULL; |
540 if (!Matcher::match_rule_supported(Op_OverflowSubL) || !UseMathExactIntrinsics) return NULL; |
539 break; |
541 break; |
540 case vmIntrinsics::_multiplyExactI: |
542 case vmIntrinsics::_multiplyExactI: |
541 if (!Matcher::match_rule_supported(Op_MulExactI) || !UseMathExactIntrinsics) return NULL; |
543 if (!Matcher::match_rule_supported(Op_OverflowMulI) || !UseMathExactIntrinsics) return NULL; |
542 break; |
544 break; |
543 case vmIntrinsics::_multiplyExactL: |
545 case vmIntrinsics::_multiplyExactL: |
544 if (!Matcher::match_rule_supported(Op_MulExactL) || !UseMathExactIntrinsics) return NULL; |
546 if (!Matcher::match_rule_supported(Op_OverflowMulL) || !UseMathExactIntrinsics) return NULL; |
545 break; |
547 break; |
546 |
548 |
547 default: |
549 default: |
548 assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility"); |
550 assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility"); |
549 assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?"); |
551 assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?"); |
1968 bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) { |
1970 bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) { |
1969 set_result(generate_min_max(id, argument(0), argument(1))); |
1971 set_result(generate_min_max(id, argument(0), argument(1))); |
1970 return true; |
1972 return true; |
1971 } |
1973 } |
1972 |
1974 |
1973 void LibraryCallKit::inline_math_mathExact(Node* math) { |
1975 void LibraryCallKit::inline_math_mathExact(Node* math, Node *test) { |
1974 // If we didn't get the expected opcode it means we have optimized |
1976 Node* bol = _gvn.transform( new (C) BoolNode(test, BoolTest::overflow) ); |
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); |
1977 IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN); |
1986 Node* fast_path = _gvn.transform( new (C) IfFalseNode(check)); |
1978 Node* fast_path = _gvn.transform( new (C) IfFalseNode(check)); |
1987 Node* slow_path = _gvn.transform( new (C) IfTrueNode(check) ); |
1979 Node* slow_path = _gvn.transform( new (C) IfTrueNode(check) ); |
1988 |
1980 |
1989 { |
1981 { |
1997 uncommon_trap(Deoptimization::Reason_intrinsic, |
1989 uncommon_trap(Deoptimization::Reason_intrinsic, |
1998 Deoptimization::Action_none); |
1990 Deoptimization::Action_none); |
1999 } |
1991 } |
2000 |
1992 |
2001 set_control(fast_path); |
1993 set_control(fast_path); |
2002 set_result(result); |
1994 set_result(math); |
|
1995 } |
|
1996 |
|
1997 template <typename OverflowOp> |
|
1998 bool LibraryCallKit::inline_math_overflow(Node* arg1, Node* arg2) { |
|
1999 typedef typename OverflowOp::MathOp MathOp; |
|
2000 |
|
2001 MathOp* mathOp = new(C) MathOp(arg1, arg2); |
|
2002 Node* operation = _gvn.transform( mathOp ); |
|
2003 Node* ofcheck = _gvn.transform( new(C) OverflowOp(arg1, arg2) ); |
|
2004 inline_math_mathExact(operation, ofcheck); |
|
2005 return true; |
2003 } |
2006 } |
2004 |
2007 |
2005 bool LibraryCallKit::inline_math_addExactI(bool is_increment) { |
2008 bool LibraryCallKit::inline_math_addExactI(bool is_increment) { |
2006 Node* arg1 = argument(0); |
2009 return inline_math_overflow<OverflowAddINode>(argument(0), is_increment ? intcon(1) : argument(1)); |
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 } |
2010 } |
2019 |
2011 |
2020 bool LibraryCallKit::inline_math_addExactL(bool is_increment) { |
2012 bool LibraryCallKit::inline_math_addExactL(bool is_increment) { |
2021 Node* arg1 = argument(0); // type long |
2013 return inline_math_overflow<OverflowAddLNode>(argument(0), is_increment ? longcon(1) : argument(2)); |
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 } |
2014 } |
2036 |
2015 |
2037 bool LibraryCallKit::inline_math_subtractExactI(bool is_decrement) { |
2016 bool LibraryCallKit::inline_math_subtractExactI(bool is_decrement) { |
2038 Node* arg1 = argument(0); |
2017 return inline_math_overflow<OverflowSubINode>(argument(0), is_decrement ? intcon(1) : argument(1)); |
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 } |
2018 } |
2051 |
2019 |
2052 bool LibraryCallKit::inline_math_subtractExactL(bool is_decrement) { |
2020 bool LibraryCallKit::inline_math_subtractExactL(bool is_decrement) { |
2053 Node* arg1 = argument(0); // type long |
2021 return inline_math_overflow<OverflowSubLNode>(argument(0), is_decrement ? longcon(1) : argument(2)); |
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 } |
2022 } |
2068 |
2023 |
2069 bool LibraryCallKit::inline_math_negateExactI() { |
2024 bool LibraryCallKit::inline_math_negateExactI() { |
2070 Node* arg1 = argument(0); |
2025 return inline_math_overflow<OverflowSubINode>(intcon(0), argument(0)); |
2071 |
|
2072 Node* neg = _gvn.transform(new(C) NegExactINode(NULL, arg1)); |
|
2073 inline_math_mathExact(neg); |
|
2074 return true; |
|
2075 } |
2026 } |
2076 |
2027 |
2077 bool LibraryCallKit::inline_math_negateExactL() { |
2028 bool LibraryCallKit::inline_math_negateExactL() { |
2078 Node* arg1 = argument(0); |
2029 return inline_math_overflow<OverflowSubLNode>(longcon(0), 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 } |
2030 } |
2085 |
2031 |
2086 bool LibraryCallKit::inline_math_multiplyExactI() { |
2032 bool LibraryCallKit::inline_math_multiplyExactI() { |
2087 Node* arg1 = argument(0); |
2033 return inline_math_overflow<OverflowMulINode>(argument(0), argument(1)); |
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 } |
2034 } |
2094 |
2035 |
2095 bool LibraryCallKit::inline_math_multiplyExactL() { |
2036 bool LibraryCallKit::inline_math_multiplyExactL() { |
2096 Node* arg1 = argument(0); |
2037 return inline_math_overflow<OverflowMulLNode>(argument(0), argument(2)); |
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 } |
2038 } |
2105 |
2039 |
2106 Node* |
2040 Node* |
2107 LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) { |
2041 LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) { |
2108 // These are the candidate return value: |
2042 // These are the candidate return value: |