Last active
April 8, 2018 02:10
-
-
Save rednaxelafx/8964030 to your computer and use it in GitHub Desktop.
A quick-n-dirty patch to implement JDK-8003585: strength reduce or eliminate range checks for power-of-two sized arrays
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -r 9d39e8a8ff61 src/share/vm/opto/subnode.cpp | |
--- a/src/share/vm/opto/subnode.cpp Fri Dec 27 07:51:07 2013 -0800 | |
+++ b/src/share/vm/opto/subnode.cpp Wed Feb 12 14:59:00 2014 -0800 | |
@@ -1206,6 +1206,40 @@ | |
Node *ncmp = phase->transform( new (phase->C) CmpINode(cmp1->in(2),cmp2)); | |
return new (phase->C) BoolNode( ncmp, _test.commute() ); | |
} | |
+ | |
+ // Change ((x & m) <= m) into (m >= 0) | |
+ // Integer expressions which perform bitwise and can be proven to | |
+ // be less than or equal to either operand, as long as the compared | |
+ // operand is non-negative. | |
+ if ( cop == Op_CmpI && | |
+ _test._test == BoolTest::le && | |
+ cmp1->Opcode() == Op_AndI && | |
+ cmp1->in(2) == cmp2) { | |
+ Node* ncmp = phase->transform( new (phase->C) CmpINode(cmp2, phase->intcon(0))); | |
+ return new (phase->C) BoolNode(ncmp, BoolTest::ge); | |
+ } | |
+ | |
+ // Change ((x & m) u<= m) to always true | |
+ if ( cop == Op_CmpU && | |
+ _test._test == BoolTest::le && | |
+ cmp1->Opcode() == Op_AndI && | |
+ cmp1->in(2) == cmp2) { | |
+ return phase->intcon(1); | |
+ } | |
+ | |
+ // Change ((x & m - 1) < m) or ((x & m - 1) u< m) into (m > 0) | |
+ // This is the off-by-one variant of the two patterns above | |
+ if ((cop == Op_CmpU || cop == Op_CmpI) && | |
+ _test._test == BoolTest::lt && | |
+ cmp1->Opcode() == Op_AndI && | |
+ (cmp1->in(2)->Opcode() == Op_AddI && cmp1->in(2)->in(2)->find_int_con(0) == -1 || | |
+ cmp1->in(2)->Opcode() == Op_SubI && cmp1->in(2)->in(2)->find_int_con(0) == 1) && | |
+ cmp1->in(2)->in(1) == cmp2) { | |
+ Node* ncmp = phase->transform( new (phase->C) CmpINode(cmp2, phase->intcon(0))); | |
+ return cmp2->Opcode() == Op_LoadRange | |
+ ? new (phase->C) BoolNode(ncmp, BoolTest::ne) // arraylength known to be non-negative | |
+ : new (phase->C) BoolNode(ncmp, BoolTest::gt); | |
+ } | |
// The transformation below is not valid for either signed or unsigned | |
// comparisons due to wraparound concerns at MAX_VALUE and MIN_VALUE. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment