Fri, 27 Sep 2013 08:39:19 +0200
8024924: Intrinsify java.lang.Math.addExact
Reviewed-by: kvn, twisti
1.1 --- a/src/cpu/sparc/vm/sparc.ad Thu Sep 26 12:07:53 2013 -0700 1.2 +++ b/src/cpu/sparc/vm/sparc.ad Fri Sep 27 08:39:19 2013 +0200 1.3 @@ -2018,6 +2018,15 @@ 1.4 return L7_REGP_mask(); 1.5 } 1.6 1.7 +const RegMask Matcher::mathExactI_result_proj_mask() { 1.8 + return G1_REGI_mask(); 1.9 +} 1.10 + 1.11 +const RegMask Matcher::mathExactI_flags_proj_mask() { 1.12 + return INT_FLAGS_mask(); 1.13 +} 1.14 + 1.15 + 1.16 %} 1.17 1.18 1.19 @@ -4245,12 +4254,16 @@ 1.20 greater_equal(0xB); 1.21 less_equal(0x2); 1.22 greater(0xA); 1.23 + overflow(0x7); 1.24 + no_overflow(0xF); 1.25 %} 1.26 %} 1.27 1.28 // Comparison Op, unsigned 1.29 operand cmpOpU() %{ 1.30 match(Bool); 1.31 + predicate(n->as_Bool()->_test._test != BoolTest::overflow && 1.32 + n->as_Bool()->_test._test != BoolTest::no_overflow); 1.33 1.34 format %{ "u" %} 1.35 interface(COND_INTER) %{ 1.36 @@ -4260,12 +4273,16 @@ 1.37 greater_equal(0xD); 1.38 less_equal(0x4); 1.39 greater(0xC); 1.40 + overflow(0x7); 1.41 + no_overflow(0xF); 1.42 %} 1.43 %} 1.44 1.45 // Comparison Op, pointer (same as unsigned) 1.46 operand cmpOpP() %{ 1.47 match(Bool); 1.48 + predicate(n->as_Bool()->_test._test != BoolTest::overflow && 1.49 + n->as_Bool()->_test._test != BoolTest::no_overflow); 1.50 1.51 format %{ "p" %} 1.52 interface(COND_INTER) %{ 1.53 @@ -4275,12 +4292,16 @@ 1.54 greater_equal(0xD); 1.55 less_equal(0x4); 1.56 greater(0xC); 1.57 + overflow(0x7); 1.58 + no_overflow(0xF); 1.59 %} 1.60 %} 1.61 1.62 // Comparison Op, branch-register encoding 1.63 operand cmpOp_reg() %{ 1.64 match(Bool); 1.65 + predicate(n->as_Bool()->_test._test != BoolTest::overflow && 1.66 + n->as_Bool()->_test._test != BoolTest::no_overflow); 1.67 1.68 format %{ "" %} 1.69 interface(COND_INTER) %{ 1.70 @@ -4290,12 +4311,16 @@ 1.71 greater_equal(0x7); 1.72 less_equal (0x2); 1.73 greater (0x6); 1.74 + overflow(0x7); // not supported 1.75 + no_overflow(0xF); // not supported 1.76 %} 1.77 %} 1.78 1.79 // Comparison Code, floating, unordered same as less 1.80 operand cmpOpF() %{ 1.81 match(Bool); 1.82 + predicate(n->as_Bool()->_test._test != BoolTest::overflow && 1.83 + n->as_Bool()->_test._test != BoolTest::no_overflow); 1.84 1.85 format %{ "fl" %} 1.86 interface(COND_INTER) %{ 1.87 @@ -4305,12 +4330,17 @@ 1.88 greater_equal(0xB); 1.89 less_equal(0xE); 1.90 greater(0x6); 1.91 + 1.92 + overflow(0x7); // not supported 1.93 + no_overflow(0xF); // not supported 1.94 %} 1.95 %} 1.96 1.97 // Used by long compare 1.98 operand cmpOp_commute() %{ 1.99 match(Bool); 1.100 + predicate(n->as_Bool()->_test._test != BoolTest::overflow && 1.101 + n->as_Bool()->_test._test != BoolTest::no_overflow); 1.102 1.103 format %{ "" %} 1.104 interface(COND_INTER) %{ 1.105 @@ -4320,6 +4350,8 @@ 1.106 greater_equal(0x2); 1.107 less_equal(0xB); 1.108 greater(0x3); 1.109 + overflow(0x7); 1.110 + no_overflow(0xF); 1.111 %} 1.112 %} 1.113
2.1 --- a/src/cpu/x86/vm/x86_32.ad Thu Sep 26 12:07:53 2013 -0700 2.2 +++ b/src/cpu/x86/vm/x86_32.ad Fri Sep 27 08:39:19 2013 +0200 2.3 @@ -1534,6 +1534,14 @@ 2.4 return EBP_REG_mask(); 2.5 } 2.6 2.7 +const RegMask Matcher::mathExactI_result_proj_mask() { 2.8 + return EAX_REG_mask(); 2.9 +} 2.10 + 2.11 +const RegMask Matcher::mathExactI_flags_proj_mask() { 2.12 + return INT_FLAGS_mask(); 2.13 +} 2.14 + 2.15 // Returns true if the high 32 bits of the value is known to be zero. 2.16 bool is_operand_hi32_zero(Node* n) { 2.17 int opc = n->Opcode(); 2.18 @@ -4922,6 +4930,8 @@ 2.19 greater_equal(0xD, "ge"); 2.20 less_equal(0xE, "le"); 2.21 greater(0xF, "g"); 2.22 + overflow(0x0, "o"); 2.23 + no_overflow(0x1, "no"); 2.24 %} 2.25 %} 2.26 2.27 @@ -4939,6 +4949,8 @@ 2.28 greater_equal(0x3, "nb"); 2.29 less_equal(0x6, "be"); 2.30 greater(0x7, "nbe"); 2.31 + overflow(0x0, "o"); 2.32 + no_overflow(0x1, "no"); 2.33 %} 2.34 %} 2.35 2.36 @@ -4957,6 +4969,8 @@ 2.37 greater_equal(0x3, "nb"); 2.38 less_equal(0x6, "be"); 2.39 greater(0x7, "nbe"); 2.40 + overflow(0x0, "o"); 2.41 + no_overflow(0x1, "no"); 2.42 %} 2.43 %} 2.44 2.45 @@ -4974,6 +4988,8 @@ 2.46 greater_equal(0x3, "nb"); 2.47 less_equal(0x6, "be"); 2.48 greater(0x7, "nbe"); 2.49 + overflow(0x0, "o"); 2.50 + no_overflow(0x1, "no"); 2.51 %} 2.52 %} 2.53 2.54 @@ -4981,6 +4997,8 @@ 2.55 operand cmpOp_fcmov() %{ 2.56 match(Bool); 2.57 2.58 + predicate(n->as_Bool()->_test._test != BoolTest::overflow && 2.59 + n->as_Bool()->_test._test != BoolTest::no_overflow); 2.60 format %{ "" %} 2.61 interface(COND_INTER) %{ 2.62 equal (0x0C8); 2.63 @@ -4989,6 +5007,8 @@ 2.64 greater_equal(0x1C0); 2.65 less_equal (0x0D0); 2.66 greater (0x1D0); 2.67 + overflow(0x0, "o"); // not really supported by the instruction 2.68 + no_overflow(0x1, "no"); // not really supported by the instruction 2.69 %} 2.70 %} 2.71 2.72 @@ -5004,6 +5024,8 @@ 2.73 greater_equal(0xE, "le"); 2.74 less_equal(0xD, "ge"); 2.75 greater(0xC, "l"); 2.76 + overflow(0x0, "o"); 2.77 + no_overflow(0x1, "no"); 2.78 %} 2.79 %} 2.80 2.81 @@ -7496,6 +7518,31 @@ 2.82 2.83 //----------Arithmetic Instructions-------------------------------------------- 2.84 //----------Addition Instructions---------------------------------------------- 2.85 + 2.86 +instruct addExactI_rReg(eAXRegI dst, rRegI src, eFlagsReg cr) 2.87 +%{ 2.88 + match(AddExactI dst src); 2.89 + effect(DEF cr); 2.90 + 2.91 + format %{ "ADD $dst, $src\t# addExact int" %} 2.92 + ins_encode %{ 2.93 + __ addl($dst$$Register, $src$$Register); 2.94 + %} 2.95 + ins_pipe(ialu_reg_reg); 2.96 +%} 2.97 + 2.98 +instruct addExactI_rReg_imm(eAXRegI dst, immI src, eFlagsReg cr) 2.99 +%{ 2.100 + match(AddExactI dst src); 2.101 + effect(DEF cr); 2.102 + 2.103 + format %{ "ADD $dst, $src\t# addExact int" %} 2.104 + ins_encode %{ 2.105 + __ addl($dst$$Register, $src$$constant); 2.106 + %} 2.107 + ins_pipe(ialu_reg_reg); 2.108 +%} 2.109 + 2.110 // Integer Addition Instructions 2.111 instruct addI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{ 2.112 match(Set dst (AddI dst src));
3.1 --- a/src/cpu/x86/vm/x86_64.ad Thu Sep 26 12:07:53 2013 -0700 3.2 +++ b/src/cpu/x86/vm/x86_64.ad Fri Sep 27 08:39:19 2013 +0200 3.3 @@ -1649,6 +1649,14 @@ 3.4 return PTR_RBP_REG_mask(); 3.5 } 3.6 3.7 +const RegMask Matcher::mathExactI_result_proj_mask() { 3.8 + return INT_RAX_REG_mask(); 3.9 +} 3.10 + 3.11 +const RegMask Matcher::mathExactI_flags_proj_mask() { 3.12 + return INT_FLAGS_mask(); 3.13 +} 3.14 + 3.15 %} 3.16 3.17 //----------ENCODING BLOCK----------------------------------------------------- 3.18 @@ -4133,6 +4141,8 @@ 3.19 greater_equal(0xD, "ge"); 3.20 less_equal(0xE, "le"); 3.21 greater(0xF, "g"); 3.22 + overflow(0x0, "o"); 3.23 + no_overflow(0x1, "no"); 3.24 %} 3.25 %} 3.26 3.27 @@ -4151,6 +4161,8 @@ 3.28 greater_equal(0x3, "nb"); 3.29 less_equal(0x6, "be"); 3.30 greater(0x7, "nbe"); 3.31 + overflow(0x0, "o"); 3.32 + no_overflow(0x1, "no"); 3.33 %} 3.34 %} 3.35 3.36 @@ -4170,6 +4182,8 @@ 3.37 greater_equal(0x3, "nb"); 3.38 less_equal(0x6, "be"); 3.39 greater(0x7, "nbe"); 3.40 + overflow(0x0, "o"); 3.41 + no_overflow(0x1, "no"); 3.42 %} 3.43 %} 3.44 3.45 @@ -4187,6 +4201,8 @@ 3.46 greater_equal(0x3, "nb"); 3.47 less_equal(0x6, "be"); 3.48 greater(0x7, "nbe"); 3.49 + overflow(0x0, "o"); 3.50 + no_overflow(0x1, "no"); 3.51 %} 3.52 %} 3.53 3.54 @@ -6922,6 +6938,30 @@ 3.55 //----------Arithmetic Instructions-------------------------------------------- 3.56 //----------Addition Instructions---------------------------------------------- 3.57 3.58 +instruct addExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr) 3.59 +%{ 3.60 + match(AddExactI dst src); 3.61 + effect(DEF cr); 3.62 + 3.63 + format %{ "addl $dst, $src\t# addExact int" %} 3.64 + ins_encode %{ 3.65 + __ addl($dst$$Register, $src$$Register); 3.66 + %} 3.67 + ins_pipe(ialu_reg_reg); 3.68 +%} 3.69 + 3.70 +instruct addExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr) 3.71 +%{ 3.72 + match(AddExactI dst src); 3.73 + effect(DEF cr); 3.74 + 3.75 + format %{ "addl $dst, $src\t# addExact int" %} 3.76 + ins_encode %{ 3.77 + __ addl($dst$$Register, $src$$constant); 3.78 + %} 3.79 + ins_pipe(ialu_reg_reg); 3.80 +%} 3.81 + 3.82 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 3.83 %{ 3.84 match(Set dst (AddI dst src));
4.1 --- a/src/share/vm/adlc/adlparse.cpp Thu Sep 26 12:07:53 2013 -0700 4.2 +++ b/src/share/vm/adlc/adlparse.cpp Fri Sep 27 08:39:19 2013 +0200 4.3 @@ -3395,12 +3395,16 @@ 4.4 char *greater_equal; 4.5 char *less_equal; 4.6 char *greater; 4.7 + char *overflow; 4.8 + char *no_overflow; 4.9 const char *equal_format = "eq"; 4.10 const char *not_equal_format = "ne"; 4.11 const char *less_format = "lt"; 4.12 const char *greater_equal_format = "ge"; 4.13 const char *less_equal_format = "le"; 4.14 const char *greater_format = "gt"; 4.15 + const char *overflow_format = "o"; 4.16 + const char *no_overflow_format = "no"; 4.17 4.18 if (_curchar != '%') { 4.19 parse_err(SYNERR, "Missing '%%{' for 'cond_interface' block.\n"); 4.20 @@ -3437,6 +3441,12 @@ 4.21 else if ( strcmp(field,"greater") == 0 ) { 4.22 greater = interface_field_parse(&greater_format); 4.23 } 4.24 + else if ( strcmp(field,"overflow") == 0 ) { 4.25 + overflow = interface_field_parse(&overflow_format); 4.26 + } 4.27 + else if ( strcmp(field,"no_overflow") == 0 ) { 4.28 + no_overflow = interface_field_parse(&no_overflow_format); 4.29 + } 4.30 else { 4.31 parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n"); 4.32 return NULL; 4.33 @@ -3455,7 +3465,9 @@ 4.34 less, less_format, 4.35 greater_equal, greater_equal_format, 4.36 less_equal, less_equal_format, 4.37 - greater, greater_format); 4.38 + greater, greater_format, 4.39 + overflow, overflow_format, 4.40 + no_overflow, no_overflow_format); 4.41 return inter; 4.42 } 4.43
5.1 --- a/src/share/vm/adlc/archDesc.cpp Thu Sep 26 12:07:53 2013 -0700 5.2 +++ b/src/share/vm/adlc/archDesc.cpp Fri Sep 27 08:39:19 2013 +0200 5.3 @@ -1192,6 +1192,8 @@ 5.4 || strcmp(idealName,"CmpF") == 0 5.5 || strcmp(idealName,"FastLock") == 0 5.6 || strcmp(idealName,"FastUnlock") == 0 5.7 + || strcmp(idealName,"AddExactI") == 0 5.8 + || strcmp(idealName,"FlagsProj") == 0 5.9 || strcmp(idealName,"Bool") == 0 5.10 || strcmp(idealName,"Binary") == 0 ) { 5.11 // Removed ConI from the must_clone list. CPUs that cannot use
6.1 --- a/src/share/vm/adlc/formssel.cpp Thu Sep 26 12:07:53 2013 -0700 6.2 +++ b/src/share/vm/adlc/formssel.cpp Fri Sep 27 08:39:19 2013 +0200 6.3 @@ -2757,14 +2757,18 @@ 6.4 const char* less, const char* less_format, 6.5 const char* greater_equal, const char* greater_equal_format, 6.6 const char* less_equal, const char* less_equal_format, 6.7 - const char* greater, const char* greater_format) 6.8 + const char* greater, const char* greater_format, 6.9 + const char* overflow, const char* overflow_format, 6.10 + const char* no_overflow, const char* no_overflow_format) 6.11 : Interface("COND_INTER"), 6.12 _equal(equal), _equal_format(equal_format), 6.13 _not_equal(not_equal), _not_equal_format(not_equal_format), 6.14 _less(less), _less_format(less_format), 6.15 _greater_equal(greater_equal), _greater_equal_format(greater_equal_format), 6.16 _less_equal(less_equal), _less_equal_format(less_equal_format), 6.17 - _greater(greater), _greater_format(greater_format) { 6.18 + _greater(greater), _greater_format(greater_format), 6.19 + _overflow(overflow), _overflow_format(overflow_format), 6.20 + _no_overflow(no_overflow), _no_overflow_format(no_overflow_format) { 6.21 } 6.22 CondInterface::~CondInterface() { 6.23 // not owner of any character arrays 6.24 @@ -2777,12 +2781,14 @@ 6.25 // Write info to output files 6.26 void CondInterface::output(FILE *fp) { 6.27 Interface::output(fp); 6.28 - if ( _equal != NULL ) fprintf(fp," equal == %s\n", _equal); 6.29 - if ( _not_equal != NULL ) fprintf(fp," not_equal == %s\n", _not_equal); 6.30 - if ( _less != NULL ) fprintf(fp," less == %s\n", _less); 6.31 - if ( _greater_equal != NULL ) fprintf(fp," greater_equal == %s\n", _greater_equal); 6.32 - if ( _less_equal != NULL ) fprintf(fp," less_equal == %s\n", _less_equal); 6.33 - if ( _greater != NULL ) fprintf(fp," greater == %s\n", _greater); 6.34 + if ( _equal != NULL ) fprintf(fp," equal == %s\n", _equal); 6.35 + if ( _not_equal != NULL ) fprintf(fp," not_equal == %s\n", _not_equal); 6.36 + if ( _less != NULL ) fprintf(fp," less == %s\n", _less); 6.37 + if ( _greater_equal != NULL ) fprintf(fp," greater_equal == %s\n", _greater_equal); 6.38 + if ( _less_equal != NULL ) fprintf(fp," less_equal == %s\n", _less_equal); 6.39 + if ( _greater != NULL ) fprintf(fp," greater == %s\n", _greater); 6.40 + if ( _overflow != NULL ) fprintf(fp," overflow == %s\n", _overflow); 6.41 + if ( _no_overflow != NULL ) fprintf(fp," no_overflow == %s\n", _no_overflow); 6.42 // fprintf(fp,"\n"); 6.43 } 6.44
7.1 --- a/src/share/vm/adlc/formssel.hpp Thu Sep 26 12:07:53 2013 -0700 7.2 +++ b/src/share/vm/adlc/formssel.hpp Fri Sep 27 08:39:19 2013 +0200 7.3 @@ -798,12 +798,16 @@ 7.4 const char *_greater_equal; 7.5 const char *_less_equal; 7.6 const char *_greater; 7.7 + const char *_overflow; 7.8 + const char *_no_overflow; 7.9 const char *_equal_format; 7.10 const char *_not_equal_format; 7.11 const char *_less_format; 7.12 const char *_greater_equal_format; 7.13 const char *_less_equal_format; 7.14 const char *_greater_format; 7.15 + const char *_overflow_format; 7.16 + const char *_no_overflow_format; 7.17 7.18 // Public Methods 7.19 CondInterface(const char* equal, const char* equal_format, 7.20 @@ -811,7 +815,9 @@ 7.21 const char* less, const char* less_format, 7.22 const char* greater_equal, const char* greater_equal_format, 7.23 const char* less_equal, const char* less_equal_format, 7.24 - const char* greater, const char* greater_format); 7.25 + const char* greater, const char* greater_format, 7.26 + const char* overflow, const char* overflow_format, 7.27 + const char* no_overflow, const char* no_overflow_format); 7.28 ~CondInterface(); 7.29 7.30 void dump();
8.1 --- a/src/share/vm/adlc/output_h.cpp Thu Sep 26 12:07:53 2013 -0700 8.2 +++ b/src/share/vm/adlc/output_h.cpp Fri Sep 27 08:39:19 2013 +0200 8.3 @@ -388,6 +388,8 @@ 8.4 fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format); 8.5 fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format); 8.6 fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format); 8.7 + fprintf(fp, " else if( _c%d == BoolTest::overflow ) st->print(\"%s\");\n",i,cond->_overflow_format); 8.8 + fprintf(fp, " else if( _c%d == BoolTest::no_overflow ) st->print(\"%s\");\n",i,cond->_no_overflow_format); 8.9 } 8.10 8.11 // Output code that dumps constant values, increment "i" if type is constant 8.12 @@ -1208,6 +1210,8 @@ 8.13 fprintf(fp," case BoolTest::ne : return not_equal();\n"); 8.14 fprintf(fp," case BoolTest::le : return less_equal();\n"); 8.15 fprintf(fp," case BoolTest::ge : return greater_equal();\n"); 8.16 + fprintf(fp," case BoolTest::overflow : return overflow();\n"); 8.17 + fprintf(fp," case BoolTest::no_overflow: return no_overflow();\n"); 8.18 fprintf(fp," default : ShouldNotReachHere(); return 0;\n"); 8.19 fprintf(fp," }\n"); 8.20 fprintf(fp," };\n"); 8.21 @@ -1373,6 +1377,14 @@ 8.22 if( greater != NULL ) { 8.23 define_oper_interface(fp, *oper, _globalNames, "greater", greater); 8.24 } 8.25 + const char *overflow = cInterface->_overflow; 8.26 + if( overflow != NULL ) { 8.27 + define_oper_interface(fp, *oper, _globalNames, "overflow", overflow); 8.28 + } 8.29 + const char *no_overflow = cInterface->_no_overflow; 8.30 + if( no_overflow != NULL ) { 8.31 + define_oper_interface(fp, *oper, _globalNames, "no_overflow", no_overflow); 8.32 + } 8.33 } // end Conditional Interface 8.34 // Check if it is a Constant Interface 8.35 else if (oper->_interface->is_ConstInterface() != NULL ) {
9.1 --- a/src/share/vm/classfile/vmSymbols.hpp Thu Sep 26 12:07:53 2013 -0700 9.2 +++ b/src/share/vm/classfile/vmSymbols.hpp Fri Sep 27 08:39:19 2013 +0200 9.3 @@ -631,6 +631,10 @@ 9.4 do_name(log_name,"log") do_name(log10_name,"log10") do_name(pow_name,"pow") \ 9.5 do_name(exp_name,"exp") do_name(min_name,"min") do_name(max_name,"max") \ 9.6 \ 9.7 + do_name(addExact_name,"addExact") \ 9.8 + do_name(subtractExact_name,"subtractExact") \ 9.9 + do_name(multiplyExact_name,"multiplyExact") \ 9.10 + \ 9.11 do_intrinsic(_dabs, java_lang_Math, abs_name, double_double_signature, F_S) \ 9.12 do_intrinsic(_dsin, java_lang_Math, sin_name, double_double_signature, F_S) \ 9.13 do_intrinsic(_dcos, java_lang_Math, cos_name, double_double_signature, F_S) \ 9.14 @@ -643,6 +647,7 @@ 9.15 do_intrinsic(_dexp, java_lang_Math, exp_name, double_double_signature, F_S) \ 9.16 do_intrinsic(_min, java_lang_Math, min_name, int2_int_signature, F_S) \ 9.17 do_intrinsic(_max, java_lang_Math, max_name, int2_int_signature, F_S) \ 9.18 + do_intrinsic(_addExact, java_lang_Math, addExact_name, int2_int_signature, F_S) \ 9.19 \ 9.20 do_intrinsic(_floatToRawIntBits, java_lang_Float, floatToRawIntBits_name, float_int_signature, F_S) \ 9.21 do_name( floatToRawIntBits_name, "floatToRawIntBits") \
10.1 --- a/src/share/vm/opto/c2_globals.hpp Thu Sep 26 12:07:53 2013 -0700 10.2 +++ b/src/share/vm/opto/c2_globals.hpp Fri Sep 27 08:39:19 2013 +0200 10.3 @@ -636,7 +636,9 @@ 10.4 \ 10.5 diagnostic(bool, OptimizeExpensiveOps, true, \ 10.6 "Find best control for expensive operations") \ 10.7 - 10.8 + \ 10.9 + product(bool, UseMathExactIntrinsics, true, \ 10.10 + "Enables intrinsification of various java.lang.Math funcitons") 10.11 10.12 C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG) 10.13
11.1 --- a/src/share/vm/opto/classes.cpp Thu Sep 26 12:07:53 2013 -0700 11.2 +++ b/src/share/vm/opto/classes.cpp Fri Sep 27 08:39:19 2013 +0200 11.3 @@ -32,6 +32,7 @@ 11.4 #include "opto/loopnode.hpp" 11.5 #include "opto/machnode.hpp" 11.6 #include "opto/memnode.hpp" 11.7 +#include "opto/mathexactnode.hpp" 11.8 #include "opto/mulnode.hpp" 11.9 #include "opto/multnode.hpp" 11.10 #include "opto/node.hpp"
12.1 --- a/src/share/vm/opto/classes.hpp Thu Sep 26 12:07:53 2013 -0700 12.2 +++ b/src/share/vm/opto/classes.hpp Fri Sep 27 08:39:19 2013 +0200 12.3 @@ -29,6 +29,7 @@ 12.4 macro(AbsF) 12.5 macro(AbsI) 12.6 macro(AddD) 12.7 +macro(AddExactI) 12.8 macro(AddF) 12.9 macro(AddI) 12.10 macro(AddL) 12.11 @@ -133,6 +134,7 @@ 12.12 macro(ExpD) 12.13 macro(FastLock) 12.14 macro(FastUnlock) 12.15 +macro(FlagsProj) 12.16 macro(Goto) 12.17 macro(Halt) 12.18 macro(If) 12.19 @@ -167,6 +169,7 @@ 12.20 macro(LoopLimit) 12.21 macro(Mach) 12.22 macro(MachProj) 12.23 +macro(MathExact) 12.24 macro(MaxI) 12.25 macro(MemBarAcquire) 12.26 macro(MemBarAcquireLock)
13.1 --- a/src/share/vm/opto/ifnode.cpp Thu Sep 26 12:07:53 2013 -0700 13.2 +++ b/src/share/vm/opto/ifnode.cpp Fri Sep 27 08:39:19 2013 +0200 13.3 @@ -76,6 +76,7 @@ 13.4 if( !i1->is_Bool() ) return NULL; 13.5 BoolNode *b = i1->as_Bool(); 13.6 Node *cmp = b->in(1); 13.7 + if( cmp->is_FlagsProj() ) return NULL; 13.8 if( !cmp->is_Cmp() ) return NULL; 13.9 i1 = cmp->in(1); 13.10 if( i1 == NULL || !i1->is_Phi() ) return NULL;
14.1 --- a/src/share/vm/opto/lcm.cpp Thu Sep 26 12:07:53 2013 -0700 14.2 +++ b/src/share/vm/opto/lcm.cpp Fri Sep 27 08:39:19 2013 +0200 14.3 @@ -472,6 +472,13 @@ 14.4 break; 14.5 } 14.6 14.7 + // For nodes that produce a FlagsProj, make the node adjacent to the 14.8 + // use of the FlagsProj 14.9 + if (use->is_FlagsProj() && get_block_for_node(use) == block) { 14.10 + found_machif = true; 14.11 + break; 14.12 + } 14.13 + 14.14 // More than this instruction pending for successor to be ready, 14.15 // don't choose this if other opportunities are ready 14.16 if (ready_cnt.at(use->_idx) > 1)
15.1 --- a/src/share/vm/opto/library_call.cpp Thu Sep 26 12:07:53 2013 -0700 15.2 +++ b/src/share/vm/opto/library_call.cpp Fri Sep 27 08:39:19 2013 +0200 15.3 @@ -32,6 +32,7 @@ 15.4 #include "opto/callGenerator.hpp" 15.5 #include "opto/cfgnode.hpp" 15.6 #include "opto/idealKit.hpp" 15.7 +#include "opto/mathexactnode.hpp" 15.8 #include "opto/mulnode.hpp" 15.9 #include "opto/parse.hpp" 15.10 #include "opto/runtime.hpp" 15.11 @@ -199,6 +200,8 @@ 15.12 bool inline_math_native(vmIntrinsics::ID id); 15.13 bool inline_trig(vmIntrinsics::ID id); 15.14 bool inline_math(vmIntrinsics::ID id); 15.15 + bool inline_math_mathExact(Node* math); 15.16 + bool inline_math_addExact(); 15.17 bool inline_exp(); 15.18 bool inline_pow(); 15.19 void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName); 15.20 @@ -498,6 +501,15 @@ 15.21 if (!UseCRC32Intrinsics) return NULL; 15.22 break; 15.23 15.24 + case vmIntrinsics::_addExact: 15.25 + if (!Matcher::match_rule_supported(Op_AddExactI)) { 15.26 + return NULL; 15.27 + } 15.28 + if (!UseMathExactIntrinsics) { 15.29 + return NULL; 15.30 + } 15.31 + break; 15.32 + 15.33 default: 15.34 assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility"); 15.35 assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?"); 15.36 @@ -668,6 +680,8 @@ 15.37 case vmIntrinsics::_min: 15.38 case vmIntrinsics::_max: return inline_min_max(intrinsic_id()); 15.39 15.40 + case vmIntrinsics::_addExact: return inline_math_addExact(); 15.41 + 15.42 case vmIntrinsics::_arraycopy: return inline_arraycopy(); 15.43 15.44 case vmIntrinsics::_compareTo: return inline_string_compareTo(); 15.45 @@ -1911,6 +1925,45 @@ 15.46 return true; 15.47 } 15.48 15.49 +bool LibraryCallKit::inline_math_mathExact(Node* math) { 15.50 + Node* result = _gvn.transform( new(C) ProjNode(math, MathExactNode::result_proj_node)); 15.51 + Node* flags = _gvn.transform( new(C) FlagsProjNode(math, MathExactNode::flags_proj_node)); 15.52 + 15.53 + Node* bol = _gvn.transform( new (C) BoolNode(flags, BoolTest::overflow) ); 15.54 + IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN); 15.55 + Node* fast_path = _gvn.transform( new (C) IfFalseNode(check)); 15.56 + Node* slow_path = _gvn.transform( new (C) IfTrueNode(check) ); 15.57 + 15.58 + { 15.59 + PreserveJVMState pjvms(this); 15.60 + PreserveReexecuteState preexecs(this); 15.61 + jvms()->set_should_reexecute(true); 15.62 + 15.63 + set_control(slow_path); 15.64 + set_i_o(i_o()); 15.65 + 15.66 + uncommon_trap(Deoptimization::Reason_intrinsic, 15.67 + Deoptimization::Action_none); 15.68 + } 15.69 + 15.70 + set_control(fast_path); 15.71 + set_result(result); 15.72 + return true; 15.73 +} 15.74 + 15.75 +bool LibraryCallKit::inline_math_addExact() { 15.76 + Node* arg1 = argument(0); 15.77 + Node* arg2 = argument(1); 15.78 + 15.79 + Node* add = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2) ); 15.80 + if (add->Opcode() == Op_AddExactI) { 15.81 + return inline_math_mathExact(add); 15.82 + } else { 15.83 + set_result(add); 15.84 + } 15.85 + return true; 15.86 +} 15.87 + 15.88 Node* 15.89 LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) { 15.90 // These are the candidate return value:
16.1 --- a/src/share/vm/opto/loopTransform.cpp Thu Sep 26 12:07:53 2013 -0700 16.2 +++ b/src/share/vm/opto/loopTransform.cpp Fri Sep 27 08:39:19 2013 +0200 16.3 @@ -776,6 +776,9 @@ 16.4 continue; // not RC 16.5 16.6 Node *cmp = bol->in(1); 16.7 + if (cmp->is_FlagsProj()) { 16.8 + continue; 16.9 + } 16.10 16.11 Node *rc_exp = cmp->in(1); 16.12 Node *limit = cmp->in(2);
17.1 --- a/src/share/vm/opto/loopopts.cpp Thu Sep 26 12:07:53 2013 -0700 17.2 +++ b/src/share/vm/opto/loopopts.cpp Fri Sep 27 08:39:19 2013 +0200 17.3 @@ -2355,7 +2355,8 @@ 17.4 opc == Op_Catch || 17.5 opc == Op_CatchProj || 17.6 opc == Op_Jump || 17.7 - opc == Op_JumpProj) { 17.8 + opc == Op_JumpProj || 17.9 + opc == Op_FlagsProj) { 17.10 #if !defined(PRODUCT) 17.11 if (TracePartialPeeling) { 17.12 tty->print_cr("\nExit control too complex: lp: %d", head->_idx);
18.1 --- a/src/share/vm/opto/matcher.cpp Thu Sep 26 12:07:53 2013 -0700 18.2 +++ b/src/share/vm/opto/matcher.cpp Fri Sep 27 08:39:19 2013 +0200 18.3 @@ -1964,6 +1964,7 @@ 18.4 case Op_Catch: 18.5 case Op_CatchProj: 18.6 case Op_CProj: 18.7 + case Op_FlagsProj: 18.8 case Op_JumpProj: 18.9 case Op_JProj: 18.10 case Op_NeverBranch:
19.1 --- a/src/share/vm/opto/matcher.hpp Thu Sep 26 12:07:53 2013 -0700 19.2 +++ b/src/share/vm/opto/matcher.hpp Fri Sep 27 08:39:19 2013 +0200 19.3 @@ -337,6 +337,9 @@ 19.4 // Register for MODL projection of divmodL 19.5 static RegMask modL_proj_mask(); 19.6 19.7 + static const RegMask mathExactI_result_proj_mask(); 19.8 + static const RegMask mathExactI_flags_proj_mask(); 19.9 + 19.10 // Use hardware DIV instruction when it is faster than 19.11 // a code which use multiply for division by constant. 19.12 static bool use_asm_for_ldiv_by_con( jlong divisor );
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/src/share/vm/opto/mathexactnode.cpp Fri Sep 27 08:39:19 2013 +0200 20.3 @@ -0,0 +1,143 @@ 20.4 +/* 20.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 20.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 20.7 + * 20.8 + * This code is free software; you can redistribute it and/or modify it 20.9 + * under the terms of the GNU General Public License version 2 only, as 20.10 + * published by the Free Software Foundation. 20.11 + * 20.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 20.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 20.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20.15 + * version 2 for more details (a copy is included in the LICENSE file that 20.16 + * accompanied this code). 20.17 + * 20.18 + * You should have received a copy of the GNU General Public License version 20.19 + * 2 along with this work; if not, write to the Free Software Foundation, 20.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20.21 + * 20.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20.23 + * or visit www.oracle.com if you need additional information or have any 20.24 + * questions. 20.25 + * 20.26 + */ 20.27 + 20.28 +#include "precompiled.hpp" 20.29 +#include "memory/allocation.inline.hpp" 20.30 +#include "opto/addnode.hpp" 20.31 +#include "opto/machnode.hpp" 20.32 +#include "opto/mathexactnode.hpp" 20.33 +#include "opto/matcher.hpp" 20.34 +#include "opto/subnode.hpp" 20.35 + 20.36 +MathExactNode::MathExactNode(Node* ctrl, Node* n1, Node* n2) : MultiNode(3) { 20.37 + init_req(0, ctrl); 20.38 + init_req(1, n1); 20.39 + init_req(2, n2); 20.40 +} 20.41 + 20.42 +Node* AddExactINode::match(const ProjNode* proj, const Matcher* m) { 20.43 + uint ideal_reg = proj->ideal_reg(); 20.44 + RegMask rm; 20.45 + if (proj->_con == result_proj_node) { 20.46 + rm = m->mathExactI_result_proj_mask(); 20.47 + } else { 20.48 + assert(proj->_con == flags_proj_node, "must be result or flags"); 20.49 + assert(ideal_reg == Op_RegFlags, "sanity"); 20.50 + rm = m->mathExactI_flags_proj_mask(); 20.51 + } 20.52 + return new (m->C) MachProjNode(this, proj->_con, rm, ideal_reg); 20.53 +} 20.54 + 20.55 +// If the MathExactNode won't overflow we have to replace the 20.56 +// FlagsProjNode and ProjNode that is generated by the MathExactNode 20.57 +Node* MathExactNode::no_overflow(PhaseGVN *phase, Node* new_result) { 20.58 + PhaseIterGVN *igvn = phase->is_IterGVN(); 20.59 + if (igvn) { 20.60 + ProjNode* result = result_node(); 20.61 + ProjNode* flags = flags_node(); 20.62 + 20.63 + if (result != NULL) { 20.64 + igvn->replace_node(result, new_result); 20.65 + } 20.66 + 20.67 + if (flags != NULL) { 20.68 + BoolNode* bolnode = (BoolNode *) flags->unique_out(); 20.69 + switch (bolnode->_test._test) { 20.70 + case BoolTest::overflow: 20.71 + // if the check is for overflow - never taken 20.72 + igvn->replace_node(bolnode, phase->intcon(0)); 20.73 + break; 20.74 + case BoolTest::no_overflow: 20.75 + // if the check is for no overflow - always taken 20.76 + igvn->replace_node(bolnode, phase->intcon(1)); 20.77 + break; 20.78 + default: 20.79 + fatal("Unexpected value of BoolTest"); 20.80 + break; 20.81 + } 20.82 + flags->del_req(0); 20.83 + } 20.84 + } 20.85 + return new_result; 20.86 +} 20.87 + 20.88 +Node *AddExactINode::Ideal(PhaseGVN *phase, bool can_reshape) { 20.89 + Node *arg1 = in(1); 20.90 + Node *arg2 = in(2); 20.91 + 20.92 + const Type* type1 = phase->type(arg1); 20.93 + const Type* type2 = phase->type(arg2); 20.94 + 20.95 + if (type1 != Type::TOP && type1->singleton() && 20.96 + type2 != Type::TOP && type2->singleton()) { 20.97 + jint val1 = arg1->get_int(); 20.98 + jint val2 = arg2->get_int(); 20.99 + jint result = val1 + val2; 20.100 + // Hacker's Delight 2-12 Overflow if both arguments have the opposite sign of the result 20.101 + if ( (((val1 ^ result) & (val2 ^ result)) >= 0)) { 20.102 + Node* con_result = ConINode::make(phase->C, result); 20.103 + return no_overflow(phase, con_result); 20.104 + } 20.105 + return NULL; 20.106 + } 20.107 + 20.108 + if (type1 == TypeInt::ZERO) { // (Add 0 x) == x 20.109 + Node* add_result = new (phase->C) AddINode(arg1, arg2); 20.110 + return no_overflow(phase, add_result); 20.111 + } 20.112 + 20.113 + if (type2 == TypeInt::ZERO) { // (Add x 0) == x 20.114 + Node* add_result = new (phase->C) AddINode(arg1, arg2); 20.115 + return no_overflow(phase, add_result); 20.116 + } 20.117 + 20.118 + if (type2->singleton()) { 20.119 + return NULL; // no change - keep constant on the right 20.120 + } 20.121 + 20.122 + if (type1->singleton()) { 20.123 + // Make it x + Constant - move constant to the right 20.124 + swap_edges(1, 2); 20.125 + return this; 20.126 + } 20.127 + 20.128 + if (arg2->is_Load()) { 20.129 + return NULL; // no change - keep load on the right 20.130 + } 20.131 + 20.132 + if (arg1->is_Load()) { 20.133 + // Make it x + Load - move load to the right 20.134 + swap_edges(1, 2); 20.135 + return this; 20.136 + } 20.137 + 20.138 + if (arg1->_idx > arg2->_idx) { 20.139 + // Sort the edges 20.140 + swap_edges(1, 2); 20.141 + return this; 20.142 + } 20.143 + 20.144 + return NULL; 20.145 +} 20.146 +
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/src/share/vm/opto/mathexactnode.hpp Fri Sep 27 08:39:19 2013 +0200 21.3 @@ -0,0 +1,81 @@ 21.4 +/* 21.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 21.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 21.7 + * 21.8 + * This code is free software; you can redistribute it and/or modify it 21.9 + * under the terms of the GNU General Public License version 2 only, as 21.10 + * published by the Free Software Foundation. 21.11 + * 21.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 21.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 21.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 21.15 + * version 2 for more details (a copy is included in the LICENSE file that 21.16 + * accompanied this code). 21.17 + * 21.18 + * You should have received a copy of the GNU General Public License version 21.19 + * 2 along with this work; if not, write to the Free Software Foundation, 21.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21.21 + * 21.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21.23 + * or visit www.oracle.com if you need additional information or have any 21.24 + * questions. 21.25 + * 21.26 + */ 21.27 + 21.28 +#ifndef SHARE_VM_OPTO_MATHEXACTNODE_HPP 21.29 +#define SHARE_VM_OPTO_MATHEXACTNODE_HPP 21.30 + 21.31 +#include "opto/multnode.hpp" 21.32 +#include "opto/node.hpp" 21.33 +#include "opto/type.hpp" 21.34 + 21.35 +class Node; 21.36 + 21.37 +class PhaseGVN; 21.38 +class PhaseTransform; 21.39 + 21.40 +class MathExactNode : public MultiNode { 21.41 +public: 21.42 + MathExactNode(Node* ctrl, Node* in1, Node* in2); 21.43 + enum { 21.44 + result_proj_node = 0, 21.45 + flags_proj_node = 1 21.46 + }; 21.47 + virtual int Opcode() const; 21.48 + virtual Node* Identity(PhaseTransform* phase) { return this; } 21.49 + virtual Node* Ideal(PhaseGVN* phase, bool can_reshape) { return NULL; } 21.50 + virtual const Type* Value(PhaseTransform* phase) const { return bottom_type(); } 21.51 + virtual uint hash() const { return Node::hash(); } 21.52 + virtual bool is_CFG() const { return false; } 21.53 + virtual uint ideal_reg() const { return NotAMachineReg; } 21.54 + 21.55 + ProjNode* result_node() { return proj_out(result_proj_node); } 21.56 + ProjNode* flags_node() { return proj_out(flags_proj_node); } 21.57 +protected: 21.58 + Node* no_overflow(PhaseGVN *phase, Node* new_result); 21.59 +}; 21.60 + 21.61 +class AddExactINode : public MathExactNode { 21.62 +public: 21.63 + AddExactINode(Node* ctrl, Node* in1, Node* in2) : MathExactNode(ctrl, in1, in2) {} 21.64 + virtual int Opcode() const; 21.65 + virtual const Type* bottom_type() const { return TypeTuple::INT_CC_PAIR; } 21.66 + virtual Node* match(const ProjNode* proj, const Matcher* m); 21.67 + virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 21.68 +}; 21.69 + 21.70 +class FlagsProjNode : public ProjNode { 21.71 +public: 21.72 + FlagsProjNode(Node* src, uint con) : ProjNode(src, con) { 21.73 + init_class_id(Class_FlagsProj); 21.74 + } 21.75 + 21.76 + virtual int Opcode() const; 21.77 + virtual bool is_CFG() const { return false; } 21.78 + virtual const Type* bottom_type() const { return TypeInt::CC; } 21.79 + virtual uint ideal_reg() const { return Op_RegFlags; } 21.80 +}; 21.81 + 21.82 + 21.83 +#endif 21.84 +
22.1 --- a/src/share/vm/opto/multnode.cpp Thu Sep 26 12:07:53 2013 -0700 22.2 +++ b/src/share/vm/opto/multnode.cpp Fri Sep 27 08:39:19 2013 +0200 22.3 @@ -25,6 +25,7 @@ 22.4 #include "precompiled.hpp" 22.5 #include "opto/callnode.hpp" 22.6 #include "opto/matcher.hpp" 22.7 +#include "opto/mathexactnode.hpp" 22.8 #include "opto/multnode.hpp" 22.9 #include "opto/opcodes.hpp" 22.10 #include "opto/phaseX.hpp" 22.11 @@ -46,15 +47,21 @@ 22.12 assert(Opcode() != Op_If || outcnt() == 2, "bad if #1"); 22.13 for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) { 22.14 Node *p = fast_out(i); 22.15 - if( !p->is_Proj() ) { 22.16 + if (p->is_Proj()) { 22.17 + ProjNode *proj = p->as_Proj(); 22.18 + if (proj->_con == which_proj) { 22.19 + assert(Opcode() != Op_If || proj->Opcode() == (which_proj?Op_IfTrue:Op_IfFalse), "bad if #2"); 22.20 + return proj; 22.21 + } 22.22 + } else if (p->is_FlagsProj()) { 22.23 + FlagsProjNode *proj = p->as_FlagsProj(); 22.24 + if (proj->_con == which_proj) { 22.25 + return proj; 22.26 + } 22.27 + } else { 22.28 assert(p == this && this->is_Start(), "else must be proj"); 22.29 continue; 22.30 } 22.31 - ProjNode *proj = p->as_Proj(); 22.32 - if( proj->_con == which_proj ) { 22.33 - assert(Opcode() != Op_If || proj->Opcode() == (which_proj?Op_IfTrue:Op_IfFalse), "bad if #2"); 22.34 - return proj; 22.35 - } 22.36 } 22.37 return NULL; 22.38 }
23.1 --- a/src/share/vm/opto/node.hpp Thu Sep 26 12:07:53 2013 -0700 23.2 +++ b/src/share/vm/opto/node.hpp Fri Sep 27 08:39:19 2013 +0200 23.3 @@ -69,6 +69,7 @@ 23.4 class EncodePKlassNode; 23.5 class FastLockNode; 23.6 class FastUnlockNode; 23.7 +class FlagsProjNode; 23.8 class IfNode; 23.9 class IfFalseNode; 23.10 class IfTrueNode; 23.11 @@ -623,6 +624,7 @@ 23.12 DEFINE_CLASS_ID(Cmp, Sub, 0) 23.13 DEFINE_CLASS_ID(FastLock, Cmp, 0) 23.14 DEFINE_CLASS_ID(FastUnlock, Cmp, 1) 23.15 + DEFINE_CLASS_ID(FlagsProj, Cmp, 2) 23.16 23.17 DEFINE_CLASS_ID(MergeMem, Node, 7) 23.18 DEFINE_CLASS_ID(Bool, Node, 8) 23.19 @@ -726,6 +728,7 @@ 23.20 DEFINE_CLASS_QUERY(EncodePKlass) 23.21 DEFINE_CLASS_QUERY(FastLock) 23.22 DEFINE_CLASS_QUERY(FastUnlock) 23.23 + DEFINE_CLASS_QUERY(FlagsProj) 23.24 DEFINE_CLASS_QUERY(If) 23.25 DEFINE_CLASS_QUERY(IfFalse) 23.26 DEFINE_CLASS_QUERY(IfTrue)
24.1 --- a/src/share/vm/opto/subnode.cpp Thu Sep 26 12:07:53 2013 -0700 24.2 +++ b/src/share/vm/opto/subnode.cpp Fri Sep 27 08:39:19 2013 +0200 24.3 @@ -1064,7 +1064,7 @@ 24.4 // Print special per-node info 24.5 #ifndef PRODUCT 24.6 void BoolTest::dump_on(outputStream *st) const { 24.7 - const char *msg[] = {"eq","gt","??","lt","ne","le","??","ge"}; 24.8 + const char *msg[] = {"eq","gt","of","lt","ne","le","nof","ge"}; 24.9 st->print(msg[_test]); 24.10 } 24.11 #endif 24.12 @@ -1126,7 +1126,7 @@ 24.13 Node *cmp = in(1); 24.14 if( !cmp->is_Sub() ) return NULL; 24.15 int cop = cmp->Opcode(); 24.16 - if( cop == Op_FastLock || cop == Op_FastUnlock ) return NULL; 24.17 + if( cop == Op_FastLock || cop == Op_FastUnlock || cop == Op_FlagsProj) return NULL; 24.18 Node *cmp1 = cmp->in(1); 24.19 Node *cmp2 = cmp->in(2); 24.20 if( !cmp1 ) return NULL;
25.1 --- a/src/share/vm/opto/subnode.hpp Thu Sep 26 12:07:53 2013 -0700 25.2 +++ b/src/share/vm/opto/subnode.hpp Fri Sep 27 08:39:19 2013 +0200 25.3 @@ -263,16 +263,16 @@ 25.4 // We pick the values as 3 bits; the low order 2 bits we compare against the 25.5 // condition codes, the high bit flips the sense of the result. 25.6 struct BoolTest VALUE_OBJ_CLASS_SPEC { 25.7 - enum mask { eq = 0, ne = 4, le = 5, ge = 7, lt = 3, gt = 1, illegal = 8 }; 25.8 + enum mask { eq = 0, ne = 4, le = 5, ge = 7, lt = 3, gt = 1, overflow = 2, no_overflow = 6, illegal = 8 }; 25.9 mask _test; 25.10 BoolTest( mask btm ) : _test(btm) {} 25.11 const Type *cc2logical( const Type *CC ) const; 25.12 // Commute the test. I use a small table lookup. The table is created as 25.13 // a simple char array where each element is the ASCII version of a 'mask' 25.14 // enum from above. 25.15 - mask commute( ) const { return mask("038147858"[_test]-'0'); } 25.16 + mask commute( ) const { return mask("032147658"[_test]-'0'); } 25.17 mask negate( ) const { return mask(_test^4); } 25.18 - bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le); } 25.19 + bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le || _test == BoolTest::overflow); } 25.20 #ifndef PRODUCT 25.21 void dump_on(outputStream *st) const; 25.22 #endif
26.1 --- a/src/share/vm/opto/type.cpp Thu Sep 26 12:07:53 2013 -0700 26.2 +++ b/src/share/vm/opto/type.cpp Fri Sep 27 08:39:19 2013 +0200 26.3 @@ -430,6 +430,11 @@ 26.4 longpair[1] = TypeLong::LONG; 26.5 TypeTuple::LONG_PAIR = TypeTuple::make(2, longpair); 26.6 26.7 + const Type **intccpair = TypeTuple::fields(2); 26.8 + intccpair[0] = TypeInt::INT; 26.9 + intccpair[1] = TypeInt::CC; 26.10 + TypeTuple::INT_CC_PAIR = TypeTuple::make(2, intccpair); 26.11 + 26.12 _const_basic_type[T_NARROWOOP] = TypeNarrowOop::BOTTOM; 26.13 _const_basic_type[T_NARROWKLASS] = Type::BOTTOM; 26.14 _const_basic_type[T_BOOLEAN] = TypeInt::BOOL; 26.15 @@ -1646,6 +1651,7 @@ 26.16 const TypeTuple *TypeTuple::START_I2C; 26.17 const TypeTuple *TypeTuple::INT_PAIR; 26.18 const TypeTuple *TypeTuple::LONG_PAIR; 26.19 +const TypeTuple *TypeTuple::INT_CC_PAIR; 26.20 26.21 26.22 //------------------------------make-------------------------------------------
27.1 --- a/src/share/vm/opto/type.hpp Thu Sep 26 12:07:53 2013 -0700 27.2 +++ b/src/share/vm/opto/type.hpp Fri Sep 27 08:39:19 2013 +0200 27.3 @@ -584,6 +584,7 @@ 27.4 static const TypeTuple *START_I2C; 27.5 static const TypeTuple *INT_PAIR; 27.6 static const TypeTuple *LONG_PAIR; 27.7 + static const TypeTuple *INT_CC_PAIR; 27.8 #ifndef PRODUCT 27.9 virtual void dump2( Dict &d, uint, outputStream *st ) const; // Specialized per-Type dumping 27.10 #endif
28.1 --- a/src/share/vm/runtime/vmStructs.cpp Thu Sep 26 12:07:53 2013 -0700 28.2 +++ b/src/share/vm/runtime/vmStructs.cpp Fri Sep 27 08:39:19 2013 +0200 28.3 @@ -176,6 +176,7 @@ 28.4 #include "opto/loopnode.hpp" 28.5 #include "opto/machnode.hpp" 28.6 #include "opto/matcher.hpp" 28.7 +#include "opto/mathexactnode.hpp" 28.8 #include "opto/mulnode.hpp" 28.9 #include "opto/phaseX.hpp" 28.10 #include "opto/parse.hpp" 28.11 @@ -1927,6 +1928,9 @@ 28.12 declare_c2_type(CmpF3Node, CmpFNode) \ 28.13 declare_c2_type(CmpDNode, CmpNode) \ 28.14 declare_c2_type(CmpD3Node, CmpDNode) \ 28.15 + declare_c2_type(MathExactNode, MultiNode) \ 28.16 + declare_c2_type(AddExactINode, MathExactNode) \ 28.17 + declare_c2_type(FlagsProjNode, ProjNode) \ 28.18 declare_c2_type(BoolNode, Node) \ 28.19 declare_c2_type(AbsNode, Node) \ 28.20 declare_c2_type(AbsINode, AbsNode) \
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/test/compiler/intrinsics/mathexact/CondTest.java Fri Sep 27 08:39:19 2013 +0200 29.3 @@ -0,0 +1,59 @@ 29.4 +/* 29.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 29.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 29.7 + * 29.8 + * This code is free software; you can redistribute it and/or modify it 29.9 + * under the terms of the GNU General Public License version 2 only, as 29.10 + * published by the Free Software Foundation. 29.11 + * 29.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 29.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 29.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 29.15 + * version 2 for more details (a copy is included in the LICENSE file that 29.16 + * accompanied this code). 29.17 + * 29.18 + * You should have received a copy of the GNU General Public License version 29.19 + * 2 along with this work; if not, write to the Free Software Foundation, 29.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 29.21 + * 29.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 29.23 + * or visit www.oracle.com if you need additional information or have any 29.24 + * questions. 29.25 + */ 29.26 + 29.27 +/* 29.28 + * @test 29.29 + * @bug 8024924 29.30 + * @summary Test non constant addExact 29.31 + * @compile CondTest.java Verify.java 29.32 + * @run main CondTest 29.33 + * 29.34 + */ 29.35 + 29.36 +import java.lang.ArithmeticException; 29.37 + 29.38 +public class CondTest { 29.39 + public static int result = 0; 29.40 + 29.41 + public static void main(String[] args) { 29.42 + for (int i = 0; i < 50000; ++i) { 29.43 + runTest(); 29.44 + } 29.45 + } 29.46 + 29.47 + public static void runTest() { 29.48 + int i = 7; 29.49 + while (java.lang.Math.addExact(i, result) < 89361) { 29.50 + if ((java.lang.Math.addExact(i, i) & 1) == 1) { 29.51 + i += 3; 29.52 + } else if ((i & 5) == 4) { 29.53 + i += 7; 29.54 + } else if ((i & 0xf) == 6) { 29.55 + i += 2; 29.56 + } else { 29.57 + i += 1; 29.58 + } 29.59 + result += 2; 29.60 + } 29.61 + } 29.62 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/test/compiler/intrinsics/mathexact/ConstantTest.java Fri Sep 27 08:39:19 2013 +0200 30.3 @@ -0,0 +1,47 @@ 30.4 +/* 30.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 30.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 30.7 + * 30.8 + * This code is free software; you can redistribute it and/or modify it 30.9 + * under the terms of the GNU General Public License version 2 only, as 30.10 + * published by the Free Software Foundation. 30.11 + * 30.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 30.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 30.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 30.15 + * version 2 for more details (a copy is included in the LICENSE file that 30.16 + * accompanied this code). 30.17 + * 30.18 + * You should have received a copy of the GNU General Public License version 30.19 + * 2 along with this work; if not, write to the Free Software Foundation, 30.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 30.21 + * 30.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 30.23 + * or visit www.oracle.com if you need additional information or have any 30.24 + * questions. 30.25 + */ 30.26 + 30.27 +/* 30.28 + * @test 30.29 + * @bug 8024924 30.30 + * @summary Test constant addExact 30.31 + * @compile ConstantTest.java Verify.java 30.32 + * @run main ConstantTest 30.33 + * 30.34 + */ 30.35 + 30.36 +import java.lang.ArithmeticException; 30.37 + 30.38 +public class ConstantTest { 30.39 + public static void main(String[] args) { 30.40 + for (int i = 0; i < 50000; ++i) { 30.41 + Verify.verify(5, 7); 30.42 + Verify.verify(Integer.MAX_VALUE, 1); 30.43 + Verify.verify(Integer.MIN_VALUE, -1); 30.44 + Verify.verify(Integer.MAX_VALUE, -1); 30.45 + Verify.verify(Integer.MIN_VALUE, 1); 30.46 + Verify.verify(Integer.MAX_VALUE / 2, Integer.MAX_VALUE / 2); 30.47 + Verify.verify(Integer.MAX_VALUE / 2, (Integer.MAX_VALUE / 2) + 3); 30.48 + } 30.49 + } 30.50 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/test/compiler/intrinsics/mathexact/LoadTest.java Fri Sep 27 08:39:19 2013 +0200 31.3 @@ -0,0 +1,55 @@ 31.4 +/* 31.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 31.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 31.7 + * 31.8 + * This code is free software; you can redistribute it and/or modify it 31.9 + * under the terms of the GNU General Public License version 2 only, as 31.10 + * published by the Free Software Foundation. 31.11 + * 31.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 31.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 31.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 31.15 + * version 2 for more details (a copy is included in the LICENSE file that 31.16 + * accompanied this code). 31.17 + * 31.18 + * You should have received a copy of the GNU General Public License version 31.19 + * 2 along with this work; if not, write to the Free Software Foundation, 31.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 31.21 + * 31.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 31.23 + * or visit www.oracle.com if you need additional information or have any 31.24 + * questions. 31.25 + */ 31.26 + 31.27 +/* 31.28 + * @test 31.29 + * @bug 8024924 31.30 + * @summary Test non constant addExact 31.31 + * @compile LoadTest.java Verify.java 31.32 + * @run main LoadTest 31.33 + * 31.34 + */ 31.35 + 31.36 +import java.lang.ArithmeticException; 31.37 + 31.38 +public class LoadTest { 31.39 + public static java.util.Random rnd = new java.util.Random(); 31.40 + public static int[] values = new int[256]; 31.41 + 31.42 + public static void main(String[] args) { 31.43 + for (int i = 0; i < values.length; ++i) { 31.44 + values[i] = rnd.nextInt(); 31.45 + } 31.46 + 31.47 + for (int i = 0; i < 50000; ++i) { 31.48 + Verify.verify(values[i & 255], values[i & 255] - i); 31.49 + Verify.verify(values[i & 255] + i, values[i & 255] - i); 31.50 + Verify.verify(values[i & 255], values[i & 255]); 31.51 + if ((i & 1) == 1 && i > 5) { 31.52 + Verify.verify(values[i & 255] + i, values[i & 255] - i); 31.53 + } else { 31.54 + Verify.verify(values[i & 255] - i, values[i & 255] + i); 31.55 + } 31.56 + } 31.57 + } 31.58 +}
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/test/compiler/intrinsics/mathexact/LoopDependentTest.java Fri Sep 27 08:39:19 2013 +0200 32.3 @@ -0,0 +1,48 @@ 32.4 +/* 32.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 32.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 32.7 + * 32.8 + * This code is free software; you can redistribute it and/or modify it 32.9 + * under the terms of the GNU General Public License version 2 only, as 32.10 + * published by the Free Software Foundation. 32.11 + * 32.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 32.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 32.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 32.15 + * version 2 for more details (a copy is included in the LICENSE file that 32.16 + * accompanied this code). 32.17 + * 32.18 + * You should have received a copy of the GNU General Public License version 32.19 + * 2 along with this work; if not, write to the Free Software Foundation, 32.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 32.21 + * 32.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 32.23 + * or visit www.oracle.com if you need additional information or have any 32.24 + * questions. 32.25 + */ 32.26 + 32.27 +/* 32.28 + * @test 32.29 + * @bug 8024924 32.30 + * @summary Test non constant addExact 32.31 + * @compile LoopDependentTest.java Verify.java 32.32 + * @run main LoopDependentTest 32.33 + * 32.34 + */ 32.35 + 32.36 +import java.lang.ArithmeticException; 32.37 + 32.38 +public class LoopDependentTest { 32.39 + public static java.util.Random rnd = new java.util.Random(); 32.40 + 32.41 + public static void main(String[] args) { 32.42 + int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt(); 32.43 + for (int i = 0; i < 50000; ++i) { 32.44 + Verify.verify(rnd1 + i, rnd2 + i); 32.45 + Verify.verify(rnd1 + i, rnd2 + (i & 0xff)); 32.46 + Verify.verify(rnd1 - i, rnd2 - (i & 0xff)); 32.47 + Verify.verify(rnd1 + i + 1, rnd2 + i + 2); 32.48 + Verify.verify(rnd1 + i * 2, rnd2 + i); 32.49 + } 32.50 + } 32.51 +}
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/test/compiler/intrinsics/mathexact/NonConstantTest.java Fri Sep 27 08:39:19 2013 +0200 33.3 @@ -0,0 +1,48 @@ 33.4 +/* 33.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 33.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 33.7 + * 33.8 + * This code is free software; you can redistribute it and/or modify it 33.9 + * under the terms of the GNU General Public License version 2 only, as 33.10 + * published by the Free Software Foundation. 33.11 + * 33.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 33.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 33.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 33.15 + * version 2 for more details (a copy is included in the LICENSE file that 33.16 + * accompanied this code). 33.17 + * 33.18 + * You should have received a copy of the GNU General Public License version 33.19 + * 2 along with this work; if not, write to the Free Software Foundation, 33.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 33.21 + * 33.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 33.23 + * or visit www.oracle.com if you need additional information or have any 33.24 + * questions. 33.25 + */ 33.26 + 33.27 +/* 33.28 + * @test 33.29 + * @bug 8024924 33.30 + * @summary Test non constant addExact 33.31 + * @compile NonConstantTest.java Verify.java 33.32 + * @run main NonConstantTest 33.33 + * 33.34 + */ 33.35 + 33.36 +import java.lang.ArithmeticException; 33.37 + 33.38 +public class NonConstantTest { 33.39 + public static java.util.Random rnd = new java.util.Random(); 33.40 + 33.41 + public static void main(String[] args) { 33.42 + for (int i = 0; i < 50000; ++i) { 33.43 + int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt(); 33.44 + Verify.verify(rnd1, rnd2); 33.45 + Verify.verify(rnd1, rnd2 + 1); 33.46 + Verify.verify(rnd1 + 1, rnd2); 33.47 + Verify.verify(rnd1 - 1, rnd2); 33.48 + Verify.verify(rnd1, rnd2 - 1); 33.49 + } 33.50 + } 33.51 +}
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/test/compiler/intrinsics/mathexact/Verify.java Fri Sep 27 08:39:19 2013 +0200 34.3 @@ -0,0 +1,68 @@ 34.4 +/* 34.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 34.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 34.7 + * 34.8 + * This code is free software; you can redistribute it and/or modify it 34.9 + * under the terms of the GNU General Public License version 2 only, as 34.10 + * published by the Free Software Foundation. 34.11 + * 34.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 34.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 34.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 34.15 + * version 2 for more details (a copy is included in the LICENSE file that 34.16 + * accompanied this code). 34.17 + * 34.18 + * You should have received a copy of the GNU General Public License version 34.19 + * 2 along with this work; if not, write to the Free Software Foundation, 34.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 34.21 + * 34.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 34.23 + * or visit www.oracle.com if you need additional information or have any 34.24 + * questions. 34.25 + */ 34.26 + 34.27 +public class Verify { 34.28 + public static String throwWord(boolean threw) { 34.29 + return (threw ? "threw" : "didn't throw"); 34.30 + } 34.31 + 34.32 + public static void verify(int a, int b) { 34.33 + boolean exception1 = false, exception2 = false; 34.34 + int result1 = 0, result2 = 0; 34.35 + try { 34.36 + result1 = testIntrinsic(a, b); 34.37 + } catch (ArithmeticException e) { 34.38 + exception1 = true; 34.39 + } 34.40 + try { 34.41 + result2 = testNonIntrinsic(a, b); 34.42 + } catch (ArithmeticException e) { 34.43 + exception2 = true; 34.44 + } 34.45 + 34.46 + if (exception1 != exception2) { 34.47 + throw new RuntimeException("Intrinsic version " + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b); 34.48 + } 34.49 + if (result1 != result2) { 34.50 + throw new RuntimeException("Intrinsic version returned: " + a + " while NonIntrinsic version returned: " + b); 34.51 + } 34.52 + } 34.53 + 34.54 + public static int testIntrinsic(int a, int b) { 34.55 + return java.lang.Math.addExact(a, b); 34.56 + } 34.57 + 34.58 + public static int testNonIntrinsic(int a, int b) { 34.59 + return safeAddExact(a, b); 34.60 + } 34.61 + 34.62 + // Copied java.lang.Math.addExact to avoid intrinsification 34.63 + public static int safeAddExact(int x, int y) { 34.64 + int r = x + y; 34.65 + // HD 2-12 Overflow iff both arguments have the opposite sign of the result 34.66 + if (((x ^ r) & (y ^ r)) < 0) { 34.67 + throw new ArithmeticException("integer overflow"); 34.68 + } 34.69 + return r; 34.70 + } 34.71 +}