Mercurial > hg > graal-compiler
comparison src/share/vm/opto/library_call.cpp @ 17810:62c54fcc0a35
Merge
author | kvn |
---|---|
date | Tue, 25 Mar 2014 17:07:36 -0700 |
parents | 7c462558a08a 9ab9f254cfe2 |
children | 400709e275c1 |
comparison
equal
deleted
inserted
replaced
17809:a433eb716ce1 | 17810:62c54fcc0a35 |
---|---|
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: |
2664 } | 2598 } |
2665 break; | 2599 break; |
2666 case T_ADDRESS: | 2600 case T_ADDRESS: |
2667 // Cast to an int type. | 2601 // Cast to an int type. |
2668 p = _gvn.transform(new (C) CastP2XNode(NULL, p)); | 2602 p = _gvn.transform(new (C) CastP2XNode(NULL, p)); |
2669 p = ConvX2L(p); | 2603 p = ConvX2UL(p); |
2670 break; | 2604 break; |
2671 default: | 2605 default: |
2672 fatal(err_msg_res("unexpected type %d: %s", type, type2name(type))); | 2606 fatal(err_msg_res("unexpected type %d: %s", type, type2name(type))); |
2673 break; | 2607 break; |
2674 } | 2608 } |
3244 | 3178 |
3245 //------------------------inline_native_isInterrupted------------------ | 3179 //------------------------inline_native_isInterrupted------------------ |
3246 // private native boolean java.lang.Thread.isInterrupted(boolean ClearInterrupted); | 3180 // private native boolean java.lang.Thread.isInterrupted(boolean ClearInterrupted); |
3247 bool LibraryCallKit::inline_native_isInterrupted() { | 3181 bool LibraryCallKit::inline_native_isInterrupted() { |
3248 // Add a fast path to t.isInterrupted(clear_int): | 3182 // Add a fast path to t.isInterrupted(clear_int): |
3249 // (t == Thread.current() && (!TLS._osthread._interrupted || !clear_int)) | 3183 // (t == Thread.current() && |
3184 // (!TLS._osthread._interrupted || WINDOWS_ONLY(false) NOT_WINDOWS(!clear_int))) | |
3250 // ? TLS._osthread._interrupted : /*slow path:*/ t.isInterrupted(clear_int) | 3185 // ? TLS._osthread._interrupted : /*slow path:*/ t.isInterrupted(clear_int) |
3251 // So, in the common case that the interrupt bit is false, | 3186 // So, in the common case that the interrupt bit is false, |
3252 // we avoid making a call into the VM. Even if the interrupt bit | 3187 // we avoid making a call into the VM. Even if the interrupt bit |
3253 // is true, if the clear_int argument is false, we avoid the VM call. | 3188 // is true, if the clear_int argument is false, we avoid the VM call. |
3254 // However, if the receiver is not currentThread, we must call the VM, | 3189 // However, if the receiver is not currentThread, we must call the VM, |
3301 result_val->init_req(no_int_result_path, intcon(0)); | 3236 result_val->init_req(no_int_result_path, intcon(0)); |
3302 | 3237 |
3303 // drop through to next case | 3238 // drop through to next case |
3304 set_control( _gvn.transform(new (C) IfTrueNode(iff_bit))); | 3239 set_control( _gvn.transform(new (C) IfTrueNode(iff_bit))); |
3305 | 3240 |
3241 #ifndef TARGET_OS_FAMILY_windows | |
3306 // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path. | 3242 // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path. |
3307 Node* clr_arg = argument(1); | 3243 Node* clr_arg = argument(1); |
3308 Node* cmp_arg = _gvn.transform(new (C) CmpINode(clr_arg, intcon(0))); | 3244 Node* cmp_arg = _gvn.transform(new (C) CmpINode(clr_arg, intcon(0))); |
3309 Node* bol_arg = _gvn.transform(new (C) BoolNode(cmp_arg, BoolTest::ne)); | 3245 Node* bol_arg = _gvn.transform(new (C) BoolNode(cmp_arg, BoolTest::ne)); |
3310 IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN); | 3246 IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN); |
3314 result_rgn->init_req(no_clear_result_path, false_arg); | 3250 result_rgn->init_req(no_clear_result_path, false_arg); |
3315 result_val->init_req(no_clear_result_path, intcon(1)); | 3251 result_val->init_req(no_clear_result_path, intcon(1)); |
3316 | 3252 |
3317 // drop through to next case | 3253 // drop through to next case |
3318 set_control( _gvn.transform(new (C) IfTrueNode(iff_arg))); | 3254 set_control( _gvn.transform(new (C) IfTrueNode(iff_arg))); |
3255 #else | |
3256 // To return true on Windows you must read the _interrupted field | |
3257 // and check the the event state i.e. take the slow path. | |
3258 #endif // TARGET_OS_FAMILY_windows | |
3319 | 3259 |
3320 // (d) Otherwise, go to the slow path. | 3260 // (d) Otherwise, go to the slow path. |
3321 slow_region->add_req(control()); | 3261 slow_region->add_req(control()); |
3322 set_control( _gvn.transform(slow_region)); | 3262 set_control( _gvn.transform(slow_region)); |
3323 | 3263 |