Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
5fef85db
D
dragonwell8_hotspot
项目概览
openanolis
/
dragonwell8_hotspot
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_hotspot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
5fef85db
编写于
9月 27, 2013
作者:
R
rbackman
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8024924: Intrinsify java.lang.Math.addExact
Reviewed-by: kvn, twisti
上级
f526d9e6
变更
34
隐藏空白更改
内联
并排
Showing
34 changed file
with
830 addition
and
23 deletion
+830
-23
src/cpu/sparc/vm/sparc.ad
src/cpu/sparc/vm/sparc.ad
+32
-0
src/cpu/x86/vm/x86_32.ad
src/cpu/x86/vm/x86_32.ad
+47
-0
src/cpu/x86/vm/x86_64.ad
src/cpu/x86/vm/x86_64.ad
+40
-0
src/share/vm/adlc/adlparse.cpp
src/share/vm/adlc/adlparse.cpp
+13
-1
src/share/vm/adlc/archDesc.cpp
src/share/vm/adlc/archDesc.cpp
+2
-0
src/share/vm/adlc/formssel.cpp
src/share/vm/adlc/formssel.cpp
+14
-8
src/share/vm/adlc/formssel.hpp
src/share/vm/adlc/formssel.hpp
+7
-1
src/share/vm/adlc/output_h.cpp
src/share/vm/adlc/output_h.cpp
+12
-0
src/share/vm/classfile/vmSymbols.hpp
src/share/vm/classfile/vmSymbols.hpp
+5
-0
src/share/vm/opto/c2_globals.hpp
src/share/vm/opto/c2_globals.hpp
+3
-1
src/share/vm/opto/classes.cpp
src/share/vm/opto/classes.cpp
+1
-0
src/share/vm/opto/classes.hpp
src/share/vm/opto/classes.hpp
+3
-0
src/share/vm/opto/ifnode.cpp
src/share/vm/opto/ifnode.cpp
+1
-0
src/share/vm/opto/lcm.cpp
src/share/vm/opto/lcm.cpp
+7
-0
src/share/vm/opto/library_call.cpp
src/share/vm/opto/library_call.cpp
+53
-0
src/share/vm/opto/loopTransform.cpp
src/share/vm/opto/loopTransform.cpp
+3
-0
src/share/vm/opto/loopopts.cpp
src/share/vm/opto/loopopts.cpp
+2
-1
src/share/vm/opto/matcher.cpp
src/share/vm/opto/matcher.cpp
+1
-0
src/share/vm/opto/matcher.hpp
src/share/vm/opto/matcher.hpp
+3
-0
src/share/vm/opto/mathexactnode.cpp
src/share/vm/opto/mathexactnode.cpp
+143
-0
src/share/vm/opto/mathexactnode.hpp
src/share/vm/opto/mathexactnode.hpp
+81
-0
src/share/vm/opto/multnode.cpp
src/share/vm/opto/multnode.cpp
+13
-6
src/share/vm/opto/node.hpp
src/share/vm/opto/node.hpp
+3
-0
src/share/vm/opto/subnode.cpp
src/share/vm/opto/subnode.cpp
+2
-2
src/share/vm/opto/subnode.hpp
src/share/vm/opto/subnode.hpp
+3
-3
src/share/vm/opto/type.cpp
src/share/vm/opto/type.cpp
+6
-0
src/share/vm/opto/type.hpp
src/share/vm/opto/type.hpp
+1
-0
src/share/vm/runtime/vmStructs.cpp
src/share/vm/runtime/vmStructs.cpp
+4
-0
test/compiler/intrinsics/mathexact/CondTest.java
test/compiler/intrinsics/mathexact/CondTest.java
+59
-0
test/compiler/intrinsics/mathexact/ConstantTest.java
test/compiler/intrinsics/mathexact/ConstantTest.java
+47
-0
test/compiler/intrinsics/mathexact/LoadTest.java
test/compiler/intrinsics/mathexact/LoadTest.java
+55
-0
test/compiler/intrinsics/mathexact/LoopDependentTest.java
test/compiler/intrinsics/mathexact/LoopDependentTest.java
+48
-0
test/compiler/intrinsics/mathexact/NonConstantTest.java
test/compiler/intrinsics/mathexact/NonConstantTest.java
+48
-0
test/compiler/intrinsics/mathexact/Verify.java
test/compiler/intrinsics/mathexact/Verify.java
+68
-0
未找到文件。
src/cpu/sparc/vm/sparc.ad
浏览文件 @
5fef85db
...
@@ -2018,6 +2018,15 @@ const RegMask Matcher::method_handle_invoke_SP_save_mask() {
...
@@ -2018,6 +2018,15 @@ const RegMask Matcher::method_handle_invoke_SP_save_mask() {
return L7_REGP_mask();
return L7_REGP_mask();
}
}
const RegMask Matcher::mathExactI_result_proj_mask() {
return G1_REGI_mask();
}
const RegMask Matcher::mathExactI_flags_proj_mask() {
return INT_FLAGS_mask();
}
%}
%}
...
@@ -4245,12 +4254,16 @@ operand cmpOp() %{
...
@@ -4245,12 +4254,16 @@ operand cmpOp() %{
greater_equal(0xB);
greater_equal(0xB);
less_equal(0x2);
less_equal(0x2);
greater(0xA);
greater(0xA);
overflow(0x7);
no_overflow(0xF);
%}
%}
%}
%}
// Comparison Op, unsigned
// Comparison Op, unsigned
operand cmpOpU() %{
operand cmpOpU() %{
match(Bool);
match(Bool);
predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
n->as_Bool()->_test._test != BoolTest::no_overflow);
format %{ "u" %}
format %{ "u" %}
interface(COND_INTER) %{
interface(COND_INTER) %{
...
@@ -4260,12 +4273,16 @@ operand cmpOpU() %{
...
@@ -4260,12 +4273,16 @@ operand cmpOpU() %{
greater_equal(0xD);
greater_equal(0xD);
less_equal(0x4);
less_equal(0x4);
greater(0xC);
greater(0xC);
overflow(0x7);
no_overflow(0xF);
%}
%}
%}
%}
// Comparison Op, pointer (same as unsigned)
// Comparison Op, pointer (same as unsigned)
operand cmpOpP() %{
operand cmpOpP() %{
match(Bool);
match(Bool);
predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
n->as_Bool()->_test._test != BoolTest::no_overflow);
format %{ "p" %}
format %{ "p" %}
interface(COND_INTER) %{
interface(COND_INTER) %{
...
@@ -4275,12 +4292,16 @@ operand cmpOpP() %{
...
@@ -4275,12 +4292,16 @@ operand cmpOpP() %{
greater_equal(0xD);
greater_equal(0xD);
less_equal(0x4);
less_equal(0x4);
greater(0xC);
greater(0xC);
overflow(0x7);
no_overflow(0xF);
%}
%}
%}
%}
// Comparison Op, branch-register encoding
// Comparison Op, branch-register encoding
operand cmpOp_reg() %{
operand cmpOp_reg() %{
match(Bool);
match(Bool);
predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
n->as_Bool()->_test._test != BoolTest::no_overflow);
format %{ "" %}
format %{ "" %}
interface(COND_INTER) %{
interface(COND_INTER) %{
...
@@ -4290,12 +4311,16 @@ operand cmpOp_reg() %{
...
@@ -4290,12 +4311,16 @@ operand cmpOp_reg() %{
greater_equal(0x7);
greater_equal(0x7);
less_equal (0x2);
less_equal (0x2);
greater (0x6);
greater (0x6);
overflow(0x7); // not supported
no_overflow(0xF); // not supported
%}
%}
%}
%}
// Comparison Code, floating, unordered same as less
// Comparison Code, floating, unordered same as less
operand cmpOpF() %{
operand cmpOpF() %{
match(Bool);
match(Bool);
predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
n->as_Bool()->_test._test != BoolTest::no_overflow);
format %{ "fl" %}
format %{ "fl" %}
interface(COND_INTER) %{
interface(COND_INTER) %{
...
@@ -4305,12 +4330,17 @@ operand cmpOpF() %{
...
@@ -4305,12 +4330,17 @@ operand cmpOpF() %{
greater_equal(0xB);
greater_equal(0xB);
less_equal(0xE);
less_equal(0xE);
greater(0x6);
greater(0x6);
overflow(0x7); // not supported
no_overflow(0xF); // not supported
%}
%}
%}
%}
// Used by long compare
// Used by long compare
operand cmpOp_commute() %{
operand cmpOp_commute() %{
match(Bool);
match(Bool);
predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
n->as_Bool()->_test._test != BoolTest::no_overflow);
format %{ "" %}
format %{ "" %}
interface(COND_INTER) %{
interface(COND_INTER) %{
...
@@ -4320,6 +4350,8 @@ operand cmpOp_commute() %{
...
@@ -4320,6 +4350,8 @@ operand cmpOp_commute() %{
greater_equal(0x2);
greater_equal(0x2);
less_equal(0xB);
less_equal(0xB);
greater(0x3);
greater(0x3);
overflow(0x7);
no_overflow(0xF);
%}
%}
%}
%}
...
...
src/cpu/x86/vm/x86_32.ad
浏览文件 @
5fef85db
...
@@ -1534,6 +1534,14 @@ const RegMask Matcher::method_handle_invoke_SP_save_mask() {
...
@@ -1534,6 +1534,14 @@ const RegMask Matcher::method_handle_invoke_SP_save_mask() {
return EBP_REG_mask();
return EBP_REG_mask();
}
}
const RegMask Matcher::mathExactI_result_proj_mask() {
return EAX_REG_mask();
}
const RegMask Matcher::mathExactI_flags_proj_mask() {
return INT_FLAGS_mask();
}
// Returns true if the high 32 bits of the value is known to be zero.
// Returns true if the high 32 bits of the value is known to be zero.
bool is_operand_hi32_zero(Node* n) {
bool is_operand_hi32_zero(Node* n) {
int opc = n->Opcode();
int opc = n->Opcode();
...
@@ -4922,6 +4930,8 @@ operand cmpOp() %{
...
@@ -4922,6 +4930,8 @@ operand cmpOp() %{
greater_equal(0xD, "ge");
greater_equal(0xD, "ge");
less_equal(0xE, "le");
less_equal(0xE, "le");
greater(0xF, "g");
greater(0xF, "g");
overflow(0x0, "o");
no_overflow(0x1, "no");
%}
%}
%}
%}
...
@@ -4939,6 +4949,8 @@ operand cmpOpU() %{
...
@@ -4939,6 +4949,8 @@ operand cmpOpU() %{
greater_equal(0x3, "nb");
greater_equal(0x3, "nb");
less_equal(0x6, "be");
less_equal(0x6, "be");
greater(0x7, "nbe");
greater(0x7, "nbe");
overflow(0x0, "o");
no_overflow(0x1, "no");
%}
%}
%}
%}
...
@@ -4957,6 +4969,8 @@ operand cmpOpUCF() %{
...
@@ -4957,6 +4969,8 @@ operand cmpOpUCF() %{
greater_equal(0x3, "nb");
greater_equal(0x3, "nb");
less_equal(0x6, "be");
less_equal(0x6, "be");
greater(0x7, "nbe");
greater(0x7, "nbe");
overflow(0x0, "o");
no_overflow(0x1, "no");
%}
%}
%}
%}
...
@@ -4974,6 +4988,8 @@ operand cmpOpUCF2() %{
...
@@ -4974,6 +4988,8 @@ operand cmpOpUCF2() %{
greater_equal(0x3, "nb");
greater_equal(0x3, "nb");
less_equal(0x6, "be");
less_equal(0x6, "be");
greater(0x7, "nbe");
greater(0x7, "nbe");
overflow(0x0, "o");
no_overflow(0x1, "no");
%}
%}
%}
%}
...
@@ -4981,6 +4997,8 @@ operand cmpOpUCF2() %{
...
@@ -4981,6 +4997,8 @@ operand cmpOpUCF2() %{
operand cmpOp_fcmov() %{
operand cmpOp_fcmov() %{
match(Bool);
match(Bool);
predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
n->as_Bool()->_test._test != BoolTest::no_overflow);
format %{ "" %}
format %{ "" %}
interface(COND_INTER) %{
interface(COND_INTER) %{
equal (0x0C8);
equal (0x0C8);
...
@@ -4989,6 +5007,8 @@ operand cmpOp_fcmov() %{
...
@@ -4989,6 +5007,8 @@ operand cmpOp_fcmov() %{
greater_equal(0x1C0);
greater_equal(0x1C0);
less_equal (0x0D0);
less_equal (0x0D0);
greater (0x1D0);
greater (0x1D0);
overflow(0x0, "o"); // not really supported by the instruction
no_overflow(0x1, "no"); // not really supported by the instruction
%}
%}
%}
%}
...
@@ -5004,6 +5024,8 @@ operand cmpOp_commute() %{
...
@@ -5004,6 +5024,8 @@ operand cmpOp_commute() %{
greater_equal(0xE, "le");
greater_equal(0xE, "le");
less_equal(0xD, "ge");
less_equal(0xD, "ge");
greater(0xC, "l");
greater(0xC, "l");
overflow(0x0, "o");
no_overflow(0x1, "no");
%}
%}
%}
%}
...
@@ -7496,6 +7518,31 @@ instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{
...
@@ -7496,6 +7518,31 @@ instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{
//----------Arithmetic Instructions--------------------------------------------
//----------Arithmetic Instructions--------------------------------------------
//----------Addition Instructions----------------------------------------------
//----------Addition Instructions----------------------------------------------
instruct addExactI_rReg(eAXRegI dst, rRegI src, eFlagsReg cr)
%{
match(AddExactI dst src);
effect(DEF cr);
format %{ "ADD $dst, $src\t# addExact int" %}
ins_encode %{
__ addl($dst$$Register, $src$$Register);
%}
ins_pipe(ialu_reg_reg);
%}
instruct addExactI_rReg_imm(eAXRegI dst, immI src, eFlagsReg cr)
%{
match(AddExactI dst src);
effect(DEF cr);
format %{ "ADD $dst, $src\t# addExact int" %}
ins_encode %{
__ addl($dst$$Register, $src$$constant);
%}
ins_pipe(ialu_reg_reg);
%}
// Integer Addition Instructions
// Integer Addition Instructions
instruct addI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
instruct addI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
match(Set dst (AddI dst src));
match(Set dst (AddI dst src));
...
...
src/cpu/x86/vm/x86_64.ad
浏览文件 @
5fef85db
...
@@ -1649,6 +1649,14 @@ const RegMask Matcher::method_handle_invoke_SP_save_mask() {
...
@@ -1649,6 +1649,14 @@ const RegMask Matcher::method_handle_invoke_SP_save_mask() {
return PTR_RBP_REG_mask();
return PTR_RBP_REG_mask();
}
}
const RegMask Matcher::mathExactI_result_proj_mask() {
return INT_RAX_REG_mask();
}
const RegMask Matcher::mathExactI_flags_proj_mask() {
return INT_FLAGS_mask();
}
%}
%}
//----------ENCODING BLOCK-----------------------------------------------------
//----------ENCODING BLOCK-----------------------------------------------------
...
@@ -4133,6 +4141,8 @@ operand cmpOp()
...
@@ -4133,6 +4141,8 @@ operand cmpOp()
greater_equal(0xD, "ge");
greater_equal(0xD, "ge");
less_equal(0xE, "le");
less_equal(0xE, "le");
greater(0xF, "g");
greater(0xF, "g");
overflow(0x0, "o");
no_overflow(0x1, "no");
%}
%}
%}
%}
...
@@ -4151,6 +4161,8 @@ operand cmpOpU()
...
@@ -4151,6 +4161,8 @@ operand cmpOpU()
greater_equal(0x3, "nb");
greater_equal(0x3, "nb");
less_equal(0x6, "be");
less_equal(0x6, "be");
greater(0x7, "nbe");
greater(0x7, "nbe");
overflow(0x0, "o");
no_overflow(0x1, "no");
%}
%}
%}
%}
...
@@ -4170,6 +4182,8 @@ operand cmpOpUCF() %{
...
@@ -4170,6 +4182,8 @@ operand cmpOpUCF() %{
greater_equal(0x3, "nb");
greater_equal(0x3, "nb");
less_equal(0x6, "be");
less_equal(0x6, "be");
greater(0x7, "nbe");
greater(0x7, "nbe");
overflow(0x0, "o");
no_overflow(0x1, "no");
%}
%}
%}
%}
...
@@ -4187,6 +4201,8 @@ operand cmpOpUCF2() %{
...
@@ -4187,6 +4201,8 @@ operand cmpOpUCF2() %{
greater_equal(0x3, "nb");
greater_equal(0x3, "nb");
less_equal(0x6, "be");
less_equal(0x6, "be");
greater(0x7, "nbe");
greater(0x7, "nbe");
overflow(0x0, "o");
no_overflow(0x1, "no");
%}
%}
%}
%}
...
@@ -6922,6 +6938,30 @@ instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
...
@@ -6922,6 +6938,30 @@ instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
//----------Arithmetic Instructions--------------------------------------------
//----------Arithmetic Instructions--------------------------------------------
//----------Addition Instructions----------------------------------------------
//----------Addition Instructions----------------------------------------------
instruct addExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr)
%{
match(AddExactI dst src);
effect(DEF cr);
format %{ "addl $dst, $src\t# addExact int" %}
ins_encode %{
__ addl($dst$$Register, $src$$Register);
%}
ins_pipe(ialu_reg_reg);
%}
instruct addExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr)
%{
match(AddExactI dst src);
effect(DEF cr);
format %{ "addl $dst, $src\t# addExact int" %}
ins_encode %{
__ addl($dst$$Register, $src$$constant);
%}
ins_pipe(ialu_reg_reg);
%}
instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
%{
%{
match(Set dst (AddI dst src));
match(Set dst (AddI dst src));
...
...
src/share/vm/adlc/adlparse.cpp
浏览文件 @
5fef85db
...
@@ -3395,12 +3395,16 @@ Interface *ADLParser::cond_interface_parse(void) {
...
@@ -3395,12 +3395,16 @@ Interface *ADLParser::cond_interface_parse(void) {
char
*
greater_equal
;
char
*
greater_equal
;
char
*
less_equal
;
char
*
less_equal
;
char
*
greater
;
char
*
greater
;
char
*
overflow
;
char
*
no_overflow
;
const
char
*
equal_format
=
"eq"
;
const
char
*
equal_format
=
"eq"
;
const
char
*
not_equal_format
=
"ne"
;
const
char
*
not_equal_format
=
"ne"
;
const
char
*
less_format
=
"lt"
;
const
char
*
less_format
=
"lt"
;
const
char
*
greater_equal_format
=
"ge"
;
const
char
*
greater_equal_format
=
"ge"
;
const
char
*
less_equal_format
=
"le"
;
const
char
*
less_equal_format
=
"le"
;
const
char
*
greater_format
=
"gt"
;
const
char
*
greater_format
=
"gt"
;
const
char
*
overflow_format
=
"o"
;
const
char
*
no_overflow_format
=
"no"
;
if
(
_curchar
!=
'%'
)
{
if
(
_curchar
!=
'%'
)
{
parse_err
(
SYNERR
,
"Missing '%%{' for 'cond_interface' block.
\n
"
);
parse_err
(
SYNERR
,
"Missing '%%{' for 'cond_interface' block.
\n
"
);
...
@@ -3437,6 +3441,12 @@ Interface *ADLParser::cond_interface_parse(void) {
...
@@ -3437,6 +3441,12 @@ Interface *ADLParser::cond_interface_parse(void) {
else
if
(
strcmp
(
field
,
"greater"
)
==
0
)
{
else
if
(
strcmp
(
field
,
"greater"
)
==
0
)
{
greater
=
interface_field_parse
(
&
greater_format
);
greater
=
interface_field_parse
(
&
greater_format
);
}
}
else
if
(
strcmp
(
field
,
"overflow"
)
==
0
)
{
overflow
=
interface_field_parse
(
&
overflow_format
);
}
else
if
(
strcmp
(
field
,
"no_overflow"
)
==
0
)
{
no_overflow
=
interface_field_parse
(
&
no_overflow_format
);
}
else
{
else
{
parse_err
(
SYNERR
,
"Expected keyword, base|index|scale|disp, or '%%}' ending interface.
\n
"
);
parse_err
(
SYNERR
,
"Expected keyword, base|index|scale|disp, or '%%}' ending interface.
\n
"
);
return
NULL
;
return
NULL
;
...
@@ -3455,7 +3465,9 @@ Interface *ADLParser::cond_interface_parse(void) {
...
@@ -3455,7 +3465,9 @@ Interface *ADLParser::cond_interface_parse(void) {
less
,
less_format
,
less
,
less_format
,
greater_equal
,
greater_equal_format
,
greater_equal
,
greater_equal_format
,
less_equal
,
less_equal_format
,
less_equal
,
less_equal_format
,
greater
,
greater_format
);
greater
,
greater_format
,
overflow
,
overflow_format
,
no_overflow
,
no_overflow_format
);
return
inter
;
return
inter
;
}
}
...
...
src/share/vm/adlc/archDesc.cpp
浏览文件 @
5fef85db
...
@@ -1192,6 +1192,8 @@ void ArchDesc::buildMustCloneMap(FILE *fp_hpp, FILE *fp_cpp) {
...
@@ -1192,6 +1192,8 @@ void ArchDesc::buildMustCloneMap(FILE *fp_hpp, FILE *fp_cpp) {
||
strcmp
(
idealName
,
"CmpF"
)
==
0
||
strcmp
(
idealName
,
"CmpF"
)
==
0
||
strcmp
(
idealName
,
"FastLock"
)
==
0
||
strcmp
(
idealName
,
"FastLock"
)
==
0
||
strcmp
(
idealName
,
"FastUnlock"
)
==
0
||
strcmp
(
idealName
,
"FastUnlock"
)
==
0
||
strcmp
(
idealName
,
"AddExactI"
)
==
0
||
strcmp
(
idealName
,
"FlagsProj"
)
==
0
||
strcmp
(
idealName
,
"Bool"
)
==
0
||
strcmp
(
idealName
,
"Bool"
)
==
0
||
strcmp
(
idealName
,
"Binary"
)
==
0
)
{
||
strcmp
(
idealName
,
"Binary"
)
==
0
)
{
// Removed ConI from the must_clone list. CPUs that cannot use
// Removed ConI from the must_clone list. CPUs that cannot use
...
...
src/share/vm/adlc/formssel.cpp
浏览文件 @
5fef85db
...
@@ -2757,14 +2757,18 @@ CondInterface::CondInterface(const char* equal, const char* equal_format
...
@@ -2757,14 +2757,18 @@ CondInterface::CondInterface(const char* equal, const char* equal_format
const
char
*
less
,
const
char
*
less_format
,
const
char
*
less
,
const
char
*
less_format
,
const
char
*
greater_equal
,
const
char
*
greater_equal_format
,
const
char
*
greater_equal
,
const
char
*
greater_equal_format
,
const
char
*
less_equal
,
const
char
*
less_equal_format
,
const
char
*
less_equal
,
const
char
*
less_equal_format
,
const
char
*
greater
,
const
char
*
greater_format
)
const
char
*
greater
,
const
char
*
greater_format
,
const
char
*
overflow
,
const
char
*
overflow_format
,
const
char
*
no_overflow
,
const
char
*
no_overflow_format
)
:
Interface
(
"COND_INTER"
),
:
Interface
(
"COND_INTER"
),
_equal
(
equal
),
_equal_format
(
equal_format
),
_equal
(
equal
),
_equal_format
(
equal_format
),
_not_equal
(
not_equal
),
_not_equal_format
(
not_equal_format
),
_not_equal
(
not_equal
),
_not_equal_format
(
not_equal_format
),
_less
(
less
),
_less_format
(
less_format
),
_less
(
less
),
_less_format
(
less_format
),
_greater_equal
(
greater_equal
),
_greater_equal_format
(
greater_equal_format
),
_greater_equal
(
greater_equal
),
_greater_equal_format
(
greater_equal_format
),
_less_equal
(
less_equal
),
_less_equal_format
(
less_equal_format
),
_less_equal
(
less_equal
),
_less_equal_format
(
less_equal_format
),
_greater
(
greater
),
_greater_format
(
greater_format
)
{
_greater
(
greater
),
_greater_format
(
greater_format
),
_overflow
(
overflow
),
_overflow_format
(
overflow_format
),
_no_overflow
(
no_overflow
),
_no_overflow_format
(
no_overflow_format
)
{
}
}
CondInterface
::~
CondInterface
()
{
CondInterface
::~
CondInterface
()
{
// not owner of any character arrays
// not owner of any character arrays
...
@@ -2777,12 +2781,14 @@ void CondInterface::dump() {
...
@@ -2777,12 +2781,14 @@ void CondInterface::dump() {
// Write info to output files
// Write info to output files
void
CondInterface
::
output
(
FILE
*
fp
)
{
void
CondInterface
::
output
(
FILE
*
fp
)
{
Interface
::
output
(
fp
);
Interface
::
output
(
fp
);
if
(
_equal
!=
NULL
)
fprintf
(
fp
,
" equal == %s
\n
"
,
_equal
);
if
(
_equal
!=
NULL
)
fprintf
(
fp
,
" equal == %s
\n
"
,
_equal
);
if
(
_not_equal
!=
NULL
)
fprintf
(
fp
,
" not_equal == %s
\n
"
,
_not_equal
);
if
(
_not_equal
!=
NULL
)
fprintf
(
fp
,
" not_equal == %s
\n
"
,
_not_equal
);
if
(
_less
!=
NULL
)
fprintf
(
fp
,
" less == %s
\n
"
,
_less
);
if
(
_less
!=
NULL
)
fprintf
(
fp
,
" less == %s
\n
"
,
_less
);
if
(
_greater_equal
!=
NULL
)
fprintf
(
fp
,
" greater_equal == %s
\n
"
,
_greater_equal
);
if
(
_greater_equal
!=
NULL
)
fprintf
(
fp
,
" greater_equal == %s
\n
"
,
_greater_equal
);
if
(
_less_equal
!=
NULL
)
fprintf
(
fp
,
" less_equal == %s
\n
"
,
_less_equal
);
if
(
_less_equal
!=
NULL
)
fprintf
(
fp
,
" less_equal == %s
\n
"
,
_less_equal
);
if
(
_greater
!=
NULL
)
fprintf
(
fp
,
" greater == %s
\n
"
,
_greater
);
if
(
_greater
!=
NULL
)
fprintf
(
fp
,
" greater == %s
\n
"
,
_greater
);
if
(
_overflow
!=
NULL
)
fprintf
(
fp
,
" overflow == %s
\n
"
,
_overflow
);
if
(
_no_overflow
!=
NULL
)
fprintf
(
fp
,
" no_overflow == %s
\n
"
,
_no_overflow
);
// fprintf(fp,"\n");
// fprintf(fp,"\n");
}
}
...
...
src/share/vm/adlc/formssel.hpp
浏览文件 @
5fef85db
...
@@ -798,12 +798,16 @@ public:
...
@@ -798,12 +798,16 @@ public:
const
char
*
_greater_equal
;
const
char
*
_greater_equal
;
const
char
*
_less_equal
;
const
char
*
_less_equal
;
const
char
*
_greater
;
const
char
*
_greater
;
const
char
*
_overflow
;
const
char
*
_no_overflow
;
const
char
*
_equal_format
;
const
char
*
_equal_format
;
const
char
*
_not_equal_format
;
const
char
*
_not_equal_format
;
const
char
*
_less_format
;
const
char
*
_less_format
;
const
char
*
_greater_equal_format
;
const
char
*
_greater_equal_format
;
const
char
*
_less_equal_format
;
const
char
*
_less_equal_format
;
const
char
*
_greater_format
;
const
char
*
_greater_format
;
const
char
*
_overflow_format
;
const
char
*
_no_overflow_format
;
// Public Methods
// Public Methods
CondInterface
(
const
char
*
equal
,
const
char
*
equal_format
,
CondInterface
(
const
char
*
equal
,
const
char
*
equal_format
,
...
@@ -811,7 +815,9 @@ public:
...
@@ -811,7 +815,9 @@ public:
const
char
*
less
,
const
char
*
less_format
,
const
char
*
less
,
const
char
*
less_format
,
const
char
*
greater_equal
,
const
char
*
greater_equal_format
,
const
char
*
greater_equal
,
const
char
*
greater_equal_format
,
const
char
*
less_equal
,
const
char
*
less_equal_format
,
const
char
*
less_equal
,
const
char
*
less_equal_format
,
const
char
*
greater
,
const
char
*
greater_format
);
const
char
*
greater
,
const
char
*
greater_format
,
const
char
*
overflow
,
const
char
*
overflow_format
,
const
char
*
no_overflow
,
const
char
*
no_overflow_format
);
~
CondInterface
();
~
CondInterface
();
void
dump
();
void
dump
();
...
...
src/share/vm/adlc/output_h.cpp
浏览文件 @
5fef85db
...
@@ -388,6 +388,8 @@ static void defineCCodeDump(OperandForm* oper, FILE *fp, int i) {
...
@@ -388,6 +388,8 @@ static void defineCCodeDump(OperandForm* oper, FILE *fp, int i) {
fprintf
(
fp
,
" else if( _c%d == BoolTest::ge ) st->print(
\"
%s
\"
);
\n
"
,
i
,
cond
->
_greater_equal_format
);
fprintf
(
fp
,
" else if( _c%d == BoolTest::ge ) st->print(
\"
%s
\"
);
\n
"
,
i
,
cond
->
_greater_equal_format
);
fprintf
(
fp
,
" else if( _c%d == BoolTest::lt ) st->print(
\"
%s
\"
);
\n
"
,
i
,
cond
->
_less_format
);
fprintf
(
fp
,
" else if( _c%d == BoolTest::lt ) st->print(
\"
%s
\"
);
\n
"
,
i
,
cond
->
_less_format
);
fprintf
(
fp
,
" else if( _c%d == BoolTest::gt ) st->print(
\"
%s
\"
);
\n
"
,
i
,
cond
->
_greater_format
);
fprintf
(
fp
,
" else if( _c%d == BoolTest::gt ) st->print(
\"
%s
\"
);
\n
"
,
i
,
cond
->
_greater_format
);
fprintf
(
fp
,
" else if( _c%d == BoolTest::overflow ) st->print(
\"
%s
\"
);
\n
"
,
i
,
cond
->
_overflow_format
);
fprintf
(
fp
,
" else if( _c%d == BoolTest::no_overflow ) st->print(
\"
%s
\"
);
\n
"
,
i
,
cond
->
_no_overflow_format
);
}
}
// Output code that dumps constant values, increment "i" if type is constant
// Output code that dumps constant values, increment "i" if type is constant
...
@@ -1208,6 +1210,8 @@ void ArchDesc::declareClasses(FILE *fp) {
...
@@ -1208,6 +1210,8 @@ void ArchDesc::declareClasses(FILE *fp) {
fprintf
(
fp
,
" case BoolTest::ne : return not_equal();
\n
"
);
fprintf
(
fp
,
" case BoolTest::ne : return not_equal();
\n
"
);
fprintf
(
fp
,
" case BoolTest::le : return less_equal();
\n
"
);
fprintf
(
fp
,
" case BoolTest::le : return less_equal();
\n
"
);
fprintf
(
fp
,
" case BoolTest::ge : return greater_equal();
\n
"
);
fprintf
(
fp
,
" case BoolTest::ge : return greater_equal();
\n
"
);
fprintf
(
fp
,
" case BoolTest::overflow : return overflow();
\n
"
);
fprintf
(
fp
,
" case BoolTest::no_overflow: return no_overflow();
\n
"
);
fprintf
(
fp
,
" default : ShouldNotReachHere(); return 0;
\n
"
);
fprintf
(
fp
,
" default : ShouldNotReachHere(); return 0;
\n
"
);
fprintf
(
fp
,
" }
\n
"
);
fprintf
(
fp
,
" }
\n
"
);
fprintf
(
fp
,
" };
\n
"
);
fprintf
(
fp
,
" };
\n
"
);
...
@@ -1373,6 +1377,14 @@ void ArchDesc::declareClasses(FILE *fp) {
...
@@ -1373,6 +1377,14 @@ void ArchDesc::declareClasses(FILE *fp) {
if
(
greater
!=
NULL
)
{
if
(
greater
!=
NULL
)
{
define_oper_interface
(
fp
,
*
oper
,
_globalNames
,
"greater"
,
greater
);
define_oper_interface
(
fp
,
*
oper
,
_globalNames
,
"greater"
,
greater
);
}
}
const
char
*
overflow
=
cInterface
->
_overflow
;
if
(
overflow
!=
NULL
)
{
define_oper_interface
(
fp
,
*
oper
,
_globalNames
,
"overflow"
,
overflow
);
}
const
char
*
no_overflow
=
cInterface
->
_no_overflow
;
if
(
no_overflow
!=
NULL
)
{
define_oper_interface
(
fp
,
*
oper
,
_globalNames
,
"no_overflow"
,
no_overflow
);
}
}
// end Conditional Interface
}
// end Conditional Interface
// Check if it is a Constant Interface
// Check if it is a Constant Interface
else
if
(
oper
->
_interface
->
is_ConstInterface
()
!=
NULL
)
{
else
if
(
oper
->
_interface
->
is_ConstInterface
()
!=
NULL
)
{
...
...
src/share/vm/classfile/vmSymbols.hpp
浏览文件 @
5fef85db
...
@@ -631,6 +631,10 @@
...
@@ -631,6 +631,10 @@
do_name(log_name,"log") do_name(log10_name,"log10") do_name(pow_name,"pow") \
do_name(log_name,"log") do_name(log10_name,"log10") do_name(pow_name,"pow") \
do_name(exp_name,"exp") do_name(min_name,"min") do_name(max_name,"max") \
do_name(exp_name,"exp") do_name(min_name,"min") do_name(max_name,"max") \
\
\
do_name(addExact_name,"addExact") \
do_name(subtractExact_name,"subtractExact") \
do_name(multiplyExact_name,"multiplyExact") \
\
do_intrinsic(_dabs, java_lang_Math, abs_name, double_double_signature, F_S) \
do_intrinsic(_dabs, java_lang_Math, abs_name, double_double_signature, F_S) \
do_intrinsic(_dsin, java_lang_Math, sin_name, double_double_signature, F_S) \
do_intrinsic(_dsin, java_lang_Math, sin_name, double_double_signature, F_S) \
do_intrinsic(_dcos, java_lang_Math, cos_name, double_double_signature, F_S) \
do_intrinsic(_dcos, java_lang_Math, cos_name, double_double_signature, F_S) \
...
@@ -643,6 +647,7 @@
...
@@ -643,6 +647,7 @@
do_intrinsic(_dexp, java_lang_Math, exp_name, double_double_signature, F_S) \
do_intrinsic(_dexp, java_lang_Math, exp_name, double_double_signature, F_S) \
do_intrinsic(_min, java_lang_Math, min_name, int2_int_signature, F_S) \
do_intrinsic(_min, java_lang_Math, min_name, int2_int_signature, F_S) \
do_intrinsic(_max, java_lang_Math, max_name, int2_int_signature, F_S) \
do_intrinsic(_max, java_lang_Math, max_name, int2_int_signature, F_S) \
do_intrinsic(_addExact, java_lang_Math, addExact_name, int2_int_signature, F_S) \
\
\
do_intrinsic(_floatToRawIntBits, java_lang_Float, floatToRawIntBits_name, float_int_signature, F_S) \
do_intrinsic(_floatToRawIntBits, java_lang_Float, floatToRawIntBits_name, float_int_signature, F_S) \
do_name( floatToRawIntBits_name, "floatToRawIntBits") \
do_name( floatToRawIntBits_name, "floatToRawIntBits") \
...
...
src/share/vm/opto/c2_globals.hpp
浏览文件 @
5fef85db
...
@@ -636,7 +636,9 @@
...
@@ -636,7 +636,9 @@
\
\
diagnostic(bool, OptimizeExpensiveOps, true, \
diagnostic(bool, OptimizeExpensiveOps, true, \
"Find best control for expensive operations") \
"Find best control for expensive operations") \
\
product(bool, UseMathExactIntrinsics, true, \
"Enables intrinsification of various java.lang.Math funcitons")
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
)
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
)
...
...
src/share/vm/opto/classes.cpp
浏览文件 @
5fef85db
...
@@ -32,6 +32,7 @@
...
@@ -32,6 +32,7 @@
#include "opto/loopnode.hpp"
#include "opto/loopnode.hpp"
#include "opto/machnode.hpp"
#include "opto/machnode.hpp"
#include "opto/memnode.hpp"
#include "opto/memnode.hpp"
#include "opto/mathexactnode.hpp"
#include "opto/mulnode.hpp"
#include "opto/mulnode.hpp"
#include "opto/multnode.hpp"
#include "opto/multnode.hpp"
#include "opto/node.hpp"
#include "opto/node.hpp"
...
...
src/share/vm/opto/classes.hpp
浏览文件 @
5fef85db
...
@@ -29,6 +29,7 @@ macro(AbsD)
...
@@ -29,6 +29,7 @@ macro(AbsD)
macro
(
AbsF
)
macro
(
AbsF
)
macro
(
AbsI
)
macro
(
AbsI
)
macro
(
AddD
)
macro
(
AddD
)
macro
(
AddExactI
)
macro
(
AddF
)
macro
(
AddF
)
macro
(
AddI
)
macro
(
AddI
)
macro
(
AddL
)
macro
(
AddL
)
...
@@ -133,6 +134,7 @@ macro(EncodePKlass)
...
@@ -133,6 +134,7 @@ macro(EncodePKlass)
macro
(
ExpD
)
macro
(
ExpD
)
macro
(
FastLock
)
macro
(
FastLock
)
macro
(
FastUnlock
)
macro
(
FastUnlock
)
macro
(
FlagsProj
)
macro
(
Goto
)
macro
(
Goto
)
macro
(
Halt
)
macro
(
Halt
)
macro
(
If
)
macro
(
If
)
...
@@ -167,6 +169,7 @@ macro(Loop)
...
@@ -167,6 +169,7 @@ macro(Loop)
macro
(
LoopLimit
)
macro
(
LoopLimit
)
macro
(
Mach
)
macro
(
Mach
)
macro
(
MachProj
)
macro
(
MachProj
)
macro
(
MathExact
)
macro
(
MaxI
)
macro
(
MaxI
)
macro
(
MemBarAcquire
)
macro
(
MemBarAcquire
)
macro
(
MemBarAcquireLock
)
macro
(
MemBarAcquireLock
)
...
...
src/share/vm/opto/ifnode.cpp
浏览文件 @
5fef85db
...
@@ -76,6 +76,7 @@ static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) {
...
@@ -76,6 +76,7 @@ static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) {
if
(
!
i1
->
is_Bool
()
)
return
NULL
;
if
(
!
i1
->
is_Bool
()
)
return
NULL
;
BoolNode
*
b
=
i1
->
as_Bool
();
BoolNode
*
b
=
i1
->
as_Bool
();
Node
*
cmp
=
b
->
in
(
1
);
Node
*
cmp
=
b
->
in
(
1
);
if
(
cmp
->
is_FlagsProj
()
)
return
NULL
;
if
(
!
cmp
->
is_Cmp
()
)
return
NULL
;
if
(
!
cmp
->
is_Cmp
()
)
return
NULL
;
i1
=
cmp
->
in
(
1
);
i1
=
cmp
->
in
(
1
);
if
(
i1
==
NULL
||
!
i1
->
is_Phi
()
)
return
NULL
;
if
(
i1
==
NULL
||
!
i1
->
is_Phi
()
)
return
NULL
;
...
...
src/share/vm/opto/lcm.cpp
浏览文件 @
5fef85db
...
@@ -472,6 +472,13 @@ Node* PhaseCFG::select(Block* block, Node_List &worklist, GrowableArray<int> &re
...
@@ -472,6 +472,13 @@ Node* PhaseCFG::select(Block* block, Node_List &worklist, GrowableArray<int> &re
break
;
break
;
}
}
// For nodes that produce a FlagsProj, make the node adjacent to the
// use of the FlagsProj
if
(
use
->
is_FlagsProj
()
&&
get_block_for_node
(
use
)
==
block
)
{
found_machif
=
true
;
break
;
}
// More than this instruction pending for successor to be ready,
// More than this instruction pending for successor to be ready,
// don't choose this if other opportunities are ready
// don't choose this if other opportunities are ready
if
(
ready_cnt
.
at
(
use
->
_idx
)
>
1
)
if
(
ready_cnt
.
at
(
use
->
_idx
)
>
1
)
...
...
src/share/vm/opto/library_call.cpp
浏览文件 @
5fef85db
...
@@ -32,6 +32,7 @@
...
@@ -32,6 +32,7 @@
#include "opto/callGenerator.hpp"
#include "opto/callGenerator.hpp"
#include "opto/cfgnode.hpp"
#include "opto/cfgnode.hpp"
#include "opto/idealKit.hpp"
#include "opto/idealKit.hpp"
#include "opto/mathexactnode.hpp"
#include "opto/mulnode.hpp"
#include "opto/mulnode.hpp"
#include "opto/parse.hpp"
#include "opto/parse.hpp"
#include "opto/runtime.hpp"
#include "opto/runtime.hpp"
...
@@ -199,6 +200,8 @@ class LibraryCallKit : public GraphKit {
...
@@ -199,6 +200,8 @@ class LibraryCallKit : public GraphKit {
bool
inline_math_native
(
vmIntrinsics
::
ID
id
);
bool
inline_math_native
(
vmIntrinsics
::
ID
id
);
bool
inline_trig
(
vmIntrinsics
::
ID
id
);
bool
inline_trig
(
vmIntrinsics
::
ID
id
);
bool
inline_math
(
vmIntrinsics
::
ID
id
);
bool
inline_math
(
vmIntrinsics
::
ID
id
);
bool
inline_math_mathExact
(
Node
*
math
);
bool
inline_math_addExact
();
bool
inline_exp
();
bool
inline_exp
();
bool
inline_pow
();
bool
inline_pow
();
void
finish_pow_exp
(
Node
*
result
,
Node
*
x
,
Node
*
y
,
const
TypeFunc
*
call_type
,
address
funcAddr
,
const
char
*
funcName
);
void
finish_pow_exp
(
Node
*
result
,
Node
*
x
,
Node
*
y
,
const
TypeFunc
*
call_type
,
address
funcAddr
,
const
char
*
funcName
);
...
@@ -498,6 +501,15 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
...
@@ -498,6 +501,15 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
if
(
!
UseCRC32Intrinsics
)
return
NULL
;
if
(
!
UseCRC32Intrinsics
)
return
NULL
;
break
;
break
;
case
vmIntrinsics
::
_addExact
:
if
(
!
Matcher
::
match_rule_supported
(
Op_AddExactI
))
{
return
NULL
;
}
if
(
!
UseMathExactIntrinsics
)
{
return
NULL
;
}
break
;
default:
default:
assert
(
id
<=
vmIntrinsics
::
LAST_COMPILER_INLINE
,
"caller responsibility"
);
assert
(
id
<=
vmIntrinsics
::
LAST_COMPILER_INLINE
,
"caller responsibility"
);
assert
(
id
!=
vmIntrinsics
::
_Object_init
&&
id
!=
vmIntrinsics
::
_invoke
,
"enum out of order?"
);
assert
(
id
!=
vmIntrinsics
::
_Object_init
&&
id
!=
vmIntrinsics
::
_invoke
,
"enum out of order?"
);
...
@@ -668,6 +680,8 @@ bool LibraryCallKit::try_to_inline() {
...
@@ -668,6 +680,8 @@ bool LibraryCallKit::try_to_inline() {
case
vmIntrinsics
::
_min
:
case
vmIntrinsics
::
_min
:
case
vmIntrinsics
::
_max
:
return
inline_min_max
(
intrinsic_id
());
case
vmIntrinsics
::
_max
:
return
inline_min_max
(
intrinsic_id
());
case
vmIntrinsics
::
_addExact
:
return
inline_math_addExact
();
case
vmIntrinsics
::
_arraycopy
:
return
inline_arraycopy
();
case
vmIntrinsics
::
_arraycopy
:
return
inline_arraycopy
();
case
vmIntrinsics
::
_compareTo
:
return
inline_string_compareTo
();
case
vmIntrinsics
::
_compareTo
:
return
inline_string_compareTo
();
...
@@ -1911,6 +1925,45 @@ bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) {
...
@@ -1911,6 +1925,45 @@ bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) {
return
true
;
return
true
;
}
}
bool
LibraryCallKit
::
inline_math_mathExact
(
Node
*
math
)
{
Node
*
result
=
_gvn
.
transform
(
new
(
C
)
ProjNode
(
math
,
MathExactNode
::
result_proj_node
));
Node
*
flags
=
_gvn
.
transform
(
new
(
C
)
FlagsProjNode
(
math
,
MathExactNode
::
flags_proj_node
));
Node
*
bol
=
_gvn
.
transform
(
new
(
C
)
BoolNode
(
flags
,
BoolTest
::
overflow
)
);
IfNode
*
check
=
create_and_map_if
(
control
(),
bol
,
PROB_UNLIKELY_MAG
(
3
),
COUNT_UNKNOWN
);
Node
*
fast_path
=
_gvn
.
transform
(
new
(
C
)
IfFalseNode
(
check
));
Node
*
slow_path
=
_gvn
.
transform
(
new
(
C
)
IfTrueNode
(
check
)
);
{
PreserveJVMState
pjvms
(
this
);
PreserveReexecuteState
preexecs
(
this
);
jvms
()
->
set_should_reexecute
(
true
);
set_control
(
slow_path
);
set_i_o
(
i_o
());
uncommon_trap
(
Deoptimization
::
Reason_intrinsic
,
Deoptimization
::
Action_none
);
}
set_control
(
fast_path
);
set_result
(
result
);
return
true
;
}
bool
LibraryCallKit
::
inline_math_addExact
()
{
Node
*
arg1
=
argument
(
0
);
Node
*
arg2
=
argument
(
1
);
Node
*
add
=
_gvn
.
transform
(
new
(
C
)
AddExactINode
(
NULL
,
arg1
,
arg2
)
);
if
(
add
->
Opcode
()
==
Op_AddExactI
)
{
return
inline_math_mathExact
(
add
);
}
else
{
set_result
(
add
);
}
return
true
;
}
Node
*
Node
*
LibraryCallKit
::
generate_min_max
(
vmIntrinsics
::
ID
id
,
Node
*
x0
,
Node
*
y0
)
{
LibraryCallKit
::
generate_min_max
(
vmIntrinsics
::
ID
id
,
Node
*
x0
,
Node
*
y0
)
{
// These are the candidate return value:
// These are the candidate return value:
...
...
src/share/vm/opto/loopTransform.cpp
浏览文件 @
5fef85db
...
@@ -776,6 +776,9 @@ bool IdealLoopTree::policy_range_check( PhaseIdealLoop *phase ) const {
...
@@ -776,6 +776,9 @@ bool IdealLoopTree::policy_range_check( PhaseIdealLoop *phase ) const {
continue
;
// not RC
continue
;
// not RC
Node
*
cmp
=
bol
->
in
(
1
);
Node
*
cmp
=
bol
->
in
(
1
);
if
(
cmp
->
is_FlagsProj
())
{
continue
;
}
Node
*
rc_exp
=
cmp
->
in
(
1
);
Node
*
rc_exp
=
cmp
->
in
(
1
);
Node
*
limit
=
cmp
->
in
(
2
);
Node
*
limit
=
cmp
->
in
(
2
);
...
...
src/share/vm/opto/loopopts.cpp
浏览文件 @
5fef85db
...
@@ -2355,7 +2355,8 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
...
@@ -2355,7 +2355,8 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
opc
==
Op_Catch
||
opc
==
Op_Catch
||
opc
==
Op_CatchProj
||
opc
==
Op_CatchProj
||
opc
==
Op_Jump
||
opc
==
Op_Jump
||
opc
==
Op_JumpProj
)
{
opc
==
Op_JumpProj
||
opc
==
Op_FlagsProj
)
{
#if !defined(PRODUCT)
#if !defined(PRODUCT)
if
(
TracePartialPeeling
)
{
if
(
TracePartialPeeling
)
{
tty
->
print_cr
(
"
\n
Exit control too complex: lp: %d"
,
head
->
_idx
);
tty
->
print_cr
(
"
\n
Exit control too complex: lp: %d"
,
head
->
_idx
);
...
...
src/share/vm/opto/matcher.cpp
浏览文件 @
5fef85db
...
@@ -1964,6 +1964,7 @@ void Matcher::find_shared( Node *n ) {
...
@@ -1964,6 +1964,7 @@ void Matcher::find_shared( Node *n ) {
case
Op_Catch
:
case
Op_Catch
:
case
Op_CatchProj
:
case
Op_CatchProj
:
case
Op_CProj
:
case
Op_CProj
:
case
Op_FlagsProj
:
case
Op_JumpProj
:
case
Op_JumpProj
:
case
Op_JProj
:
case
Op_JProj
:
case
Op_NeverBranch
:
case
Op_NeverBranch
:
...
...
src/share/vm/opto/matcher.hpp
浏览文件 @
5fef85db
...
@@ -337,6 +337,9 @@ public:
...
@@ -337,6 +337,9 @@ public:
// Register for MODL projection of divmodL
// Register for MODL projection of divmodL
static
RegMask
modL_proj_mask
();
static
RegMask
modL_proj_mask
();
static
const
RegMask
mathExactI_result_proj_mask
();
static
const
RegMask
mathExactI_flags_proj_mask
();
// Use hardware DIV instruction when it is faster than
// Use hardware DIV instruction when it is faster than
// a code which use multiply for division by constant.
// a code which use multiply for division by constant.
static
bool
use_asm_for_ldiv_by_con
(
jlong
divisor
);
static
bool
use_asm_for_ldiv_by_con
(
jlong
divisor
);
...
...
src/share/vm/opto/mathexactnode.cpp
0 → 100644
浏览文件 @
5fef85db
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "memory/allocation.inline.hpp"
#include "opto/addnode.hpp"
#include "opto/machnode.hpp"
#include "opto/mathexactnode.hpp"
#include "opto/matcher.hpp"
#include "opto/subnode.hpp"
MathExactNode
::
MathExactNode
(
Node
*
ctrl
,
Node
*
n1
,
Node
*
n2
)
:
MultiNode
(
3
)
{
init_req
(
0
,
ctrl
);
init_req
(
1
,
n1
);
init_req
(
2
,
n2
);
}
Node
*
AddExactINode
::
match
(
const
ProjNode
*
proj
,
const
Matcher
*
m
)
{
uint
ideal_reg
=
proj
->
ideal_reg
();
RegMask
rm
;
if
(
proj
->
_con
==
result_proj_node
)
{
rm
=
m
->
mathExactI_result_proj_mask
();
}
else
{
assert
(
proj
->
_con
==
flags_proj_node
,
"must be result or flags"
);
assert
(
ideal_reg
==
Op_RegFlags
,
"sanity"
);
rm
=
m
->
mathExactI_flags_proj_mask
();
}
return
new
(
m
->
C
)
MachProjNode
(
this
,
proj
->
_con
,
rm
,
ideal_reg
);
}
// If the MathExactNode won't overflow we have to replace the
// FlagsProjNode and ProjNode that is generated by the MathExactNode
Node
*
MathExactNode
::
no_overflow
(
PhaseGVN
*
phase
,
Node
*
new_result
)
{
PhaseIterGVN
*
igvn
=
phase
->
is_IterGVN
();
if
(
igvn
)
{
ProjNode
*
result
=
result_node
();
ProjNode
*
flags
=
flags_node
();
if
(
result
!=
NULL
)
{
igvn
->
replace_node
(
result
,
new_result
);
}
if
(
flags
!=
NULL
)
{
BoolNode
*
bolnode
=
(
BoolNode
*
)
flags
->
unique_out
();
switch
(
bolnode
->
_test
.
_test
)
{
case
BoolTest
::
overflow
:
// if the check is for overflow - never taken
igvn
->
replace_node
(
bolnode
,
phase
->
intcon
(
0
));
break
;
case
BoolTest
::
no_overflow
:
// if the check is for no overflow - always taken
igvn
->
replace_node
(
bolnode
,
phase
->
intcon
(
1
));
break
;
default:
fatal
(
"Unexpected value of BoolTest"
);
break
;
}
flags
->
del_req
(
0
);
}
}
return
new_result
;
}
Node
*
AddExactINode
::
Ideal
(
PhaseGVN
*
phase
,
bool
can_reshape
)
{
Node
*
arg1
=
in
(
1
);
Node
*
arg2
=
in
(
2
);
const
Type
*
type1
=
phase
->
type
(
arg1
);
const
Type
*
type2
=
phase
->
type
(
arg2
);
if
(
type1
!=
Type
::
TOP
&&
type1
->
singleton
()
&&
type2
!=
Type
::
TOP
&&
type2
->
singleton
())
{
jint
val1
=
arg1
->
get_int
();
jint
val2
=
arg2
->
get_int
();
jint
result
=
val1
+
val2
;
// Hacker's Delight 2-12 Overflow if both arguments have the opposite sign of the result
if
(
(((
val1
^
result
)
&
(
val2
^
result
))
>=
0
))
{
Node
*
con_result
=
ConINode
::
make
(
phase
->
C
,
result
);
return
no_overflow
(
phase
,
con_result
);
}
return
NULL
;
}
if
(
type1
==
TypeInt
::
ZERO
)
{
// (Add 0 x) == x
Node
*
add_result
=
new
(
phase
->
C
)
AddINode
(
arg1
,
arg2
);
return
no_overflow
(
phase
,
add_result
);
}
if
(
type2
==
TypeInt
::
ZERO
)
{
// (Add x 0) == x
Node
*
add_result
=
new
(
phase
->
C
)
AddINode
(
arg1
,
arg2
);
return
no_overflow
(
phase
,
add_result
);
}
if
(
type2
->
singleton
())
{
return
NULL
;
// no change - keep constant on the right
}
if
(
type1
->
singleton
())
{
// Make it x + Constant - move constant to the right
swap_edges
(
1
,
2
);
return
this
;
}
if
(
arg2
->
is_Load
())
{
return
NULL
;
// no change - keep load on the right
}
if
(
arg1
->
is_Load
())
{
// Make it x + Load - move load to the right
swap_edges
(
1
,
2
);
return
this
;
}
if
(
arg1
->
_idx
>
arg2
->
_idx
)
{
// Sort the edges
swap_edges
(
1
,
2
);
return
this
;
}
return
NULL
;
}
src/share/vm/opto/mathexactnode.hpp
0 → 100644
浏览文件 @
5fef85db
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_OPTO_MATHEXACTNODE_HPP
#define SHARE_VM_OPTO_MATHEXACTNODE_HPP
#include "opto/multnode.hpp"
#include "opto/node.hpp"
#include "opto/type.hpp"
class
Node
;
class
PhaseGVN
;
class
PhaseTransform
;
class
MathExactNode
:
public
MultiNode
{
public:
MathExactNode
(
Node
*
ctrl
,
Node
*
in1
,
Node
*
in2
);
enum
{
result_proj_node
=
0
,
flags_proj_node
=
1
};
virtual
int
Opcode
()
const
;
virtual
Node
*
Identity
(
PhaseTransform
*
phase
)
{
return
this
;
}
virtual
Node
*
Ideal
(
PhaseGVN
*
phase
,
bool
can_reshape
)
{
return
NULL
;
}
virtual
const
Type
*
Value
(
PhaseTransform
*
phase
)
const
{
return
bottom_type
();
}
virtual
uint
hash
()
const
{
return
Node
::
hash
();
}
virtual
bool
is_CFG
()
const
{
return
false
;
}
virtual
uint
ideal_reg
()
const
{
return
NotAMachineReg
;
}
ProjNode
*
result_node
()
{
return
proj_out
(
result_proj_node
);
}
ProjNode
*
flags_node
()
{
return
proj_out
(
flags_proj_node
);
}
protected:
Node
*
no_overflow
(
PhaseGVN
*
phase
,
Node
*
new_result
);
};
class
AddExactINode
:
public
MathExactNode
{
public:
AddExactINode
(
Node
*
ctrl
,
Node
*
in1
,
Node
*
in2
)
:
MathExactNode
(
ctrl
,
in1
,
in2
)
{}
virtual
int
Opcode
()
const
;
virtual
const
Type
*
bottom_type
()
const
{
return
TypeTuple
::
INT_CC_PAIR
;
}
virtual
Node
*
match
(
const
ProjNode
*
proj
,
const
Matcher
*
m
);
virtual
Node
*
Ideal
(
PhaseGVN
*
phase
,
bool
can_reshape
);
};
class
FlagsProjNode
:
public
ProjNode
{
public:
FlagsProjNode
(
Node
*
src
,
uint
con
)
:
ProjNode
(
src
,
con
)
{
init_class_id
(
Class_FlagsProj
);
}
virtual
int
Opcode
()
const
;
virtual
bool
is_CFG
()
const
{
return
false
;
}
virtual
const
Type
*
bottom_type
()
const
{
return
TypeInt
::
CC
;
}
virtual
uint
ideal_reg
()
const
{
return
Op_RegFlags
;
}
};
#endif
src/share/vm/opto/multnode.cpp
浏览文件 @
5fef85db
...
@@ -25,6 +25,7 @@
...
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "precompiled.hpp"
#include "opto/callnode.hpp"
#include "opto/callnode.hpp"
#include "opto/matcher.hpp"
#include "opto/matcher.hpp"
#include "opto/mathexactnode.hpp"
#include "opto/multnode.hpp"
#include "opto/multnode.hpp"
#include "opto/opcodes.hpp"
#include "opto/opcodes.hpp"
#include "opto/phaseX.hpp"
#include "opto/phaseX.hpp"
...
@@ -46,15 +47,21 @@ ProjNode* MultiNode::proj_out(uint which_proj) const {
...
@@ -46,15 +47,21 @@ ProjNode* MultiNode::proj_out(uint which_proj) const {
assert
(
Opcode
()
!=
Op_If
||
outcnt
()
==
2
,
"bad if #1"
);
assert
(
Opcode
()
!=
Op_If
||
outcnt
()
==
2
,
"bad if #1"
);
for
(
DUIterator_Fast
imax
,
i
=
fast_outs
(
imax
);
i
<
imax
;
i
++
)
{
for
(
DUIterator_Fast
imax
,
i
=
fast_outs
(
imax
);
i
<
imax
;
i
++
)
{
Node
*
p
=
fast_out
(
i
);
Node
*
p
=
fast_out
(
i
);
if
(
!
p
->
is_Proj
()
)
{
if
(
p
->
is_Proj
())
{
ProjNode
*
proj
=
p
->
as_Proj
();
if
(
proj
->
_con
==
which_proj
)
{
assert
(
Opcode
()
!=
Op_If
||
proj
->
Opcode
()
==
(
which_proj
?
Op_IfTrue
:
Op_IfFalse
),
"bad if #2"
);
return
proj
;
}
}
else
if
(
p
->
is_FlagsProj
())
{
FlagsProjNode
*
proj
=
p
->
as_FlagsProj
();
if
(
proj
->
_con
==
which_proj
)
{
return
proj
;
}
}
else
{
assert
(
p
==
this
&&
this
->
is_Start
(),
"else must be proj"
);
assert
(
p
==
this
&&
this
->
is_Start
(),
"else must be proj"
);
continue
;
continue
;
}
}
ProjNode
*
proj
=
p
->
as_Proj
();
if
(
proj
->
_con
==
which_proj
)
{
assert
(
Opcode
()
!=
Op_If
||
proj
->
Opcode
()
==
(
which_proj
?
Op_IfTrue
:
Op_IfFalse
),
"bad if #2"
);
return
proj
;
}
}
}
return
NULL
;
return
NULL
;
}
}
...
...
src/share/vm/opto/node.hpp
浏览文件 @
5fef85db
...
@@ -69,6 +69,7 @@ class EncodePNode;
...
@@ -69,6 +69,7 @@ class EncodePNode;
class
EncodePKlassNode
;
class
EncodePKlassNode
;
class
FastLockNode
;
class
FastLockNode
;
class
FastUnlockNode
;
class
FastUnlockNode
;
class
FlagsProjNode
;
class
IfNode
;
class
IfNode
;
class
IfFalseNode
;
class
IfFalseNode
;
class
IfTrueNode
;
class
IfTrueNode
;
...
@@ -623,6 +624,7 @@ public:
...
@@ -623,6 +624,7 @@ public:
DEFINE_CLASS_ID
(
Cmp
,
Sub
,
0
)
DEFINE_CLASS_ID
(
Cmp
,
Sub
,
0
)
DEFINE_CLASS_ID
(
FastLock
,
Cmp
,
0
)
DEFINE_CLASS_ID
(
FastLock
,
Cmp
,
0
)
DEFINE_CLASS_ID
(
FastUnlock
,
Cmp
,
1
)
DEFINE_CLASS_ID
(
FastUnlock
,
Cmp
,
1
)
DEFINE_CLASS_ID
(
FlagsProj
,
Cmp
,
2
)
DEFINE_CLASS_ID
(
MergeMem
,
Node
,
7
)
DEFINE_CLASS_ID
(
MergeMem
,
Node
,
7
)
DEFINE_CLASS_ID
(
Bool
,
Node
,
8
)
DEFINE_CLASS_ID
(
Bool
,
Node
,
8
)
...
@@ -726,6 +728,7 @@ public:
...
@@ -726,6 +728,7 @@ public:
DEFINE_CLASS_QUERY
(
EncodePKlass
)
DEFINE_CLASS_QUERY
(
EncodePKlass
)
DEFINE_CLASS_QUERY
(
FastLock
)
DEFINE_CLASS_QUERY
(
FastLock
)
DEFINE_CLASS_QUERY
(
FastUnlock
)
DEFINE_CLASS_QUERY
(
FastUnlock
)
DEFINE_CLASS_QUERY
(
FlagsProj
)
DEFINE_CLASS_QUERY
(
If
)
DEFINE_CLASS_QUERY
(
If
)
DEFINE_CLASS_QUERY
(
IfFalse
)
DEFINE_CLASS_QUERY
(
IfFalse
)
DEFINE_CLASS_QUERY
(
IfTrue
)
DEFINE_CLASS_QUERY
(
IfTrue
)
...
...
src/share/vm/opto/subnode.cpp
浏览文件 @
5fef85db
...
@@ -1064,7 +1064,7 @@ const Type *BoolTest::cc2logical( const Type *CC ) const {
...
@@ -1064,7 +1064,7 @@ const Type *BoolTest::cc2logical( const Type *CC ) const {
// Print special per-node info
// Print special per-node info
#ifndef PRODUCT
#ifndef PRODUCT
void
BoolTest
::
dump_on
(
outputStream
*
st
)
const
{
void
BoolTest
::
dump_on
(
outputStream
*
st
)
const
{
const
char
*
msg
[]
=
{
"eq"
,
"gt"
,
"
??"
,
"lt"
,
"ne"
,
"le"
,
"??
"
,
"ge"
};
const
char
*
msg
[]
=
{
"eq"
,
"gt"
,
"
of"
,
"lt"
,
"ne"
,
"le"
,
"nof
"
,
"ge"
};
st
->
print
(
msg
[
_test
]);
st
->
print
(
msg
[
_test
]);
}
}
#endif
#endif
...
@@ -1126,7 +1126,7 @@ Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) {
...
@@ -1126,7 +1126,7 @@ Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node
*
cmp
=
in
(
1
);
Node
*
cmp
=
in
(
1
);
if
(
!
cmp
->
is_Sub
()
)
return
NULL
;
if
(
!
cmp
->
is_Sub
()
)
return
NULL
;
int
cop
=
cmp
->
Opcode
();
int
cop
=
cmp
->
Opcode
();
if
(
cop
==
Op_FastLock
||
cop
==
Op_FastUnlock
)
return
NULL
;
if
(
cop
==
Op_FastLock
||
cop
==
Op_FastUnlock
||
cop
==
Op_FlagsProj
)
return
NULL
;
Node
*
cmp1
=
cmp
->
in
(
1
);
Node
*
cmp1
=
cmp
->
in
(
1
);
Node
*
cmp2
=
cmp
->
in
(
2
);
Node
*
cmp2
=
cmp
->
in
(
2
);
if
(
!
cmp1
)
return
NULL
;
if
(
!
cmp1
)
return
NULL
;
...
...
src/share/vm/opto/subnode.hpp
浏览文件 @
5fef85db
...
@@ -263,16 +263,16 @@ public:
...
@@ -263,16 +263,16 @@ public:
// We pick the values as 3 bits; the low order 2 bits we compare against the
// We pick the values as 3 bits; the low order 2 bits we compare against the
// condition codes, the high bit flips the sense of the result.
// condition codes, the high bit flips the sense of the result.
struct
BoolTest
VALUE_OBJ_CLASS_SPEC
{
struct
BoolTest
VALUE_OBJ_CLASS_SPEC
{
enum
mask
{
eq
=
0
,
ne
=
4
,
le
=
5
,
ge
=
7
,
lt
=
3
,
gt
=
1
,
illegal
=
8
};
enum
mask
{
eq
=
0
,
ne
=
4
,
le
=
5
,
ge
=
7
,
lt
=
3
,
gt
=
1
,
overflow
=
2
,
no_overflow
=
6
,
illegal
=
8
};
mask
_test
;
mask
_test
;
BoolTest
(
mask
btm
)
:
_test
(
btm
)
{}
BoolTest
(
mask
btm
)
:
_test
(
btm
)
{}
const
Type
*
cc2logical
(
const
Type
*
CC
)
const
;
const
Type
*
cc2logical
(
const
Type
*
CC
)
const
;
// Commute the test. I use a small table lookup. The table is created as
// Commute the test. I use a small table lookup. The table is created as
// a simple char array where each element is the ASCII version of a 'mask'
// a simple char array where each element is the ASCII version of a 'mask'
// enum from above.
// enum from above.
mask
commute
(
)
const
{
return
mask
(
"03
81478
58"
[
_test
]
-
'0'
);
}
mask
commute
(
)
const
{
return
mask
(
"03
21476
58"
[
_test
]
-
'0'
);
}
mask
negate
(
)
const
{
return
mask
(
_test
^
4
);
}
mask
negate
(
)
const
{
return
mask
(
_test
^
4
);
}
bool
is_canonical
(
)
const
{
return
(
_test
==
BoolTest
::
ne
||
_test
==
BoolTest
::
lt
||
_test
==
BoolTest
::
le
);
}
bool
is_canonical
(
)
const
{
return
(
_test
==
BoolTest
::
ne
||
_test
==
BoolTest
::
lt
||
_test
==
BoolTest
::
le
||
_test
==
BoolTest
::
overflow
);
}
#ifndef PRODUCT
#ifndef PRODUCT
void
dump_on
(
outputStream
*
st
)
const
;
void
dump_on
(
outputStream
*
st
)
const
;
#endif
#endif
...
...
src/share/vm/opto/type.cpp
浏览文件 @
5fef85db
...
@@ -430,6 +430,11 @@ void Type::Initialize_shared(Compile* current) {
...
@@ -430,6 +430,11 @@ void Type::Initialize_shared(Compile* current) {
longpair
[
1
]
=
TypeLong
::
LONG
;
longpair
[
1
]
=
TypeLong
::
LONG
;
TypeTuple
::
LONG_PAIR
=
TypeTuple
::
make
(
2
,
longpair
);
TypeTuple
::
LONG_PAIR
=
TypeTuple
::
make
(
2
,
longpair
);
const
Type
**
intccpair
=
TypeTuple
::
fields
(
2
);
intccpair
[
0
]
=
TypeInt
::
INT
;
intccpair
[
1
]
=
TypeInt
::
CC
;
TypeTuple
::
INT_CC_PAIR
=
TypeTuple
::
make
(
2
,
intccpair
);
_const_basic_type
[
T_NARROWOOP
]
=
TypeNarrowOop
::
BOTTOM
;
_const_basic_type
[
T_NARROWOOP
]
=
TypeNarrowOop
::
BOTTOM
;
_const_basic_type
[
T_NARROWKLASS
]
=
Type
::
BOTTOM
;
_const_basic_type
[
T_NARROWKLASS
]
=
Type
::
BOTTOM
;
_const_basic_type
[
T_BOOLEAN
]
=
TypeInt
::
BOOL
;
_const_basic_type
[
T_BOOLEAN
]
=
TypeInt
::
BOOL
;
...
@@ -1646,6 +1651,7 @@ const TypeTuple *TypeTuple::STORECONDITIONAL;
...
@@ -1646,6 +1651,7 @@ const TypeTuple *TypeTuple::STORECONDITIONAL;
const
TypeTuple
*
TypeTuple
::
START_I2C
;
const
TypeTuple
*
TypeTuple
::
START_I2C
;
const
TypeTuple
*
TypeTuple
::
INT_PAIR
;
const
TypeTuple
*
TypeTuple
::
INT_PAIR
;
const
TypeTuple
*
TypeTuple
::
LONG_PAIR
;
const
TypeTuple
*
TypeTuple
::
LONG_PAIR
;
const
TypeTuple
*
TypeTuple
::
INT_CC_PAIR
;
//------------------------------make-------------------------------------------
//------------------------------make-------------------------------------------
...
...
src/share/vm/opto/type.hpp
浏览文件 @
5fef85db
...
@@ -584,6 +584,7 @@ public:
...
@@ -584,6 +584,7 @@ public:
static
const
TypeTuple
*
START_I2C
;
static
const
TypeTuple
*
START_I2C
;
static
const
TypeTuple
*
INT_PAIR
;
static
const
TypeTuple
*
INT_PAIR
;
static
const
TypeTuple
*
LONG_PAIR
;
static
const
TypeTuple
*
LONG_PAIR
;
static
const
TypeTuple
*
INT_CC_PAIR
;
#ifndef PRODUCT
#ifndef PRODUCT
virtual
void
dump2
(
Dict
&
d
,
uint
,
outputStream
*
st
)
const
;
// Specialized per-Type dumping
virtual
void
dump2
(
Dict
&
d
,
uint
,
outputStream
*
st
)
const
;
// Specialized per-Type dumping
#endif
#endif
...
...
src/share/vm/runtime/vmStructs.cpp
浏览文件 @
5fef85db
...
@@ -176,6 +176,7 @@
...
@@ -176,6 +176,7 @@
#include "opto/loopnode.hpp"
#include "opto/loopnode.hpp"
#include "opto/machnode.hpp"
#include "opto/machnode.hpp"
#include "opto/matcher.hpp"
#include "opto/matcher.hpp"
#include "opto/mathexactnode.hpp"
#include "opto/mulnode.hpp"
#include "opto/mulnode.hpp"
#include "opto/phaseX.hpp"
#include "opto/phaseX.hpp"
#include "opto/parse.hpp"
#include "opto/parse.hpp"
...
@@ -1927,6 +1928,9 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
...
@@ -1927,6 +1928,9 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
declare_c2_type(CmpF3Node, CmpFNode) \
declare_c2_type(CmpF3Node, CmpFNode) \
declare_c2_type(CmpDNode, CmpNode) \
declare_c2_type(CmpDNode, CmpNode) \
declare_c2_type(CmpD3Node, CmpDNode) \
declare_c2_type(CmpD3Node, CmpDNode) \
declare_c2_type(MathExactNode, MultiNode) \
declare_c2_type(AddExactINode, MathExactNode) \
declare_c2_type(FlagsProjNode, ProjNode) \
declare_c2_type(BoolNode, Node) \
declare_c2_type(BoolNode, Node) \
declare_c2_type(AbsNode, Node) \
declare_c2_type(AbsNode, Node) \
declare_c2_type(AbsINode, AbsNode) \
declare_c2_type(AbsINode, AbsNode) \
...
...
test/compiler/intrinsics/mathexact/CondTest.java
0 → 100644
浏览文件 @
5fef85db
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8024924
* @summary Test non constant addExact
* @compile CondTest.java Verify.java
* @run main CondTest
*
*/
import
java.lang.ArithmeticException
;
public
class
CondTest
{
public
static
int
result
=
0
;
public
static
void
main
(
String
[]
args
)
{
for
(
int
i
=
0
;
i
<
50000
;
++
i
)
{
runTest
();
}
}
public
static
void
runTest
()
{
int
i
=
7
;
while
(
java
.
lang
.
Math
.
addExact
(
i
,
result
)
<
89361
)
{
if
((
java
.
lang
.
Math
.
addExact
(
i
,
i
)
&
1
)
==
1
)
{
i
+=
3
;
}
else
if
((
i
&
5
)
==
4
)
{
i
+=
7
;
}
else
if
((
i
&
0xf
)
==
6
)
{
i
+=
2
;
}
else
{
i
+=
1
;
}
result
+=
2
;
}
}
}
test/compiler/intrinsics/mathexact/ConstantTest.java
0 → 100644
浏览文件 @
5fef85db
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8024924
* @summary Test constant addExact
* @compile ConstantTest.java Verify.java
* @run main ConstantTest
*
*/
import
java.lang.ArithmeticException
;
public
class
ConstantTest
{
public
static
void
main
(
String
[]
args
)
{
for
(
int
i
=
0
;
i
<
50000
;
++
i
)
{
Verify
.
verify
(
5
,
7
);
Verify
.
verify
(
Integer
.
MAX_VALUE
,
1
);
Verify
.
verify
(
Integer
.
MIN_VALUE
,
-
1
);
Verify
.
verify
(
Integer
.
MAX_VALUE
,
-
1
);
Verify
.
verify
(
Integer
.
MIN_VALUE
,
1
);
Verify
.
verify
(
Integer
.
MAX_VALUE
/
2
,
Integer
.
MAX_VALUE
/
2
);
Verify
.
verify
(
Integer
.
MAX_VALUE
/
2
,
(
Integer
.
MAX_VALUE
/
2
)
+
3
);
}
}
}
test/compiler/intrinsics/mathexact/LoadTest.java
0 → 100644
浏览文件 @
5fef85db
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8024924
* @summary Test non constant addExact
* @compile LoadTest.java Verify.java
* @run main LoadTest
*
*/
import
java.lang.ArithmeticException
;
public
class
LoadTest
{
public
static
java
.
util
.
Random
rnd
=
new
java
.
util
.
Random
();
public
static
int
[]
values
=
new
int
[
256
];
public
static
void
main
(
String
[]
args
)
{
for
(
int
i
=
0
;
i
<
values
.
length
;
++
i
)
{
values
[
i
]
=
rnd
.
nextInt
();
}
for
(
int
i
=
0
;
i
<
50000
;
++
i
)
{
Verify
.
verify
(
values
[
i
&
255
],
values
[
i
&
255
]
-
i
);
Verify
.
verify
(
values
[
i
&
255
]
+
i
,
values
[
i
&
255
]
-
i
);
Verify
.
verify
(
values
[
i
&
255
],
values
[
i
&
255
]);
if
((
i
&
1
)
==
1
&&
i
>
5
)
{
Verify
.
verify
(
values
[
i
&
255
]
+
i
,
values
[
i
&
255
]
-
i
);
}
else
{
Verify
.
verify
(
values
[
i
&
255
]
-
i
,
values
[
i
&
255
]
+
i
);
}
}
}
}
test/compiler/intrinsics/mathexact/LoopDependentTest.java
0 → 100644
浏览文件 @
5fef85db
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8024924
* @summary Test non constant addExact
* @compile LoopDependentTest.java Verify.java
* @run main LoopDependentTest
*
*/
import
java.lang.ArithmeticException
;
public
class
LoopDependentTest
{
public
static
java
.
util
.
Random
rnd
=
new
java
.
util
.
Random
();
public
static
void
main
(
String
[]
args
)
{
int
rnd1
=
rnd
.
nextInt
(),
rnd2
=
rnd
.
nextInt
();
for
(
int
i
=
0
;
i
<
50000
;
++
i
)
{
Verify
.
verify
(
rnd1
+
i
,
rnd2
+
i
);
Verify
.
verify
(
rnd1
+
i
,
rnd2
+
(
i
&
0xff
));
Verify
.
verify
(
rnd1
-
i
,
rnd2
-
(
i
&
0xff
));
Verify
.
verify
(
rnd1
+
i
+
1
,
rnd2
+
i
+
2
);
Verify
.
verify
(
rnd1
+
i
*
2
,
rnd2
+
i
);
}
}
}
test/compiler/intrinsics/mathexact/NonConstantTest.java
0 → 100644
浏览文件 @
5fef85db
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8024924
* @summary Test non constant addExact
* @compile NonConstantTest.java Verify.java
* @run main NonConstantTest
*
*/
import
java.lang.ArithmeticException
;
public
class
NonConstantTest
{
public
static
java
.
util
.
Random
rnd
=
new
java
.
util
.
Random
();
public
static
void
main
(
String
[]
args
)
{
for
(
int
i
=
0
;
i
<
50000
;
++
i
)
{
int
rnd1
=
rnd
.
nextInt
(),
rnd2
=
rnd
.
nextInt
();
Verify
.
verify
(
rnd1
,
rnd2
);
Verify
.
verify
(
rnd1
,
rnd2
+
1
);
Verify
.
verify
(
rnd1
+
1
,
rnd2
);
Verify
.
verify
(
rnd1
-
1
,
rnd2
);
Verify
.
verify
(
rnd1
,
rnd2
-
1
);
}
}
}
test/compiler/intrinsics/mathexact/Verify.java
0 → 100644
浏览文件 @
5fef85db
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
public
class
Verify
{
public
static
String
throwWord
(
boolean
threw
)
{
return
(
threw
?
"threw"
:
"didn't throw"
);
}
public
static
void
verify
(
int
a
,
int
b
)
{
boolean
exception1
=
false
,
exception2
=
false
;
int
result1
=
0
,
result2
=
0
;
try
{
result1
=
testIntrinsic
(
a
,
b
);
}
catch
(
ArithmeticException
e
)
{
exception1
=
true
;
}
try
{
result2
=
testNonIntrinsic
(
a
,
b
);
}
catch
(
ArithmeticException
e
)
{
exception2
=
true
;
}
if
(
exception1
!=
exception2
)
{
throw
new
RuntimeException
(
"Intrinsic version "
+
throwWord
(
exception1
)
+
" exception, NonIntrinsic version "
+
throwWord
(
exception2
)
+
" for: "
+
a
+
" + "
+
b
);
}
if
(
result1
!=
result2
)
{
throw
new
RuntimeException
(
"Intrinsic version returned: "
+
a
+
" while NonIntrinsic version returned: "
+
b
);
}
}
public
static
int
testIntrinsic
(
int
a
,
int
b
)
{
return
java
.
lang
.
Math
.
addExact
(
a
,
b
);
}
public
static
int
testNonIntrinsic
(
int
a
,
int
b
)
{
return
safeAddExact
(
a
,
b
);
}
// Copied java.lang.Math.addExact to avoid intrinsification
public
static
int
safeAddExact
(
int
x
,
int
y
)
{
int
r
=
x
+
y
;
// HD 2-12 Overflow iff both arguments have the opposite sign of the result
if
(((
x
^
r
)
&
(
y
^
r
))
<
0
)
{
throw
new
ArithmeticException
(
"integer overflow"
);
}
return
r
;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录