6671250: In Parse::do_if() old Cmp node 'c' should be replaced with new one after BoolNode transformation
authorkvn
Wed, 05 Mar 2008 11:33:31 -0800
changeset 210 6da234892f4a
parent 209 2a924148a40a
child 211 e2b60448c234
6671250: In Parse::do_if() old Cmp node 'c' should be replaced with new one after BoolNode transformation Summary: In Parse::do_if() 'c' (CmpNode) node may be changed during BoolNode transformation so 'c' may became dead but the node is referenced later in the code. Reviewed-by: never
hotspot/src/share/vm/opto/parse2.cpp
--- a/hotspot/src/share/vm/opto/parse2.cpp	Fri Feb 29 19:57:41 2008 -0800
+++ b/hotspot/src/share/vm/opto/parse2.cpp	Wed Mar 05 11:33:31 2008 -0800
@@ -1022,10 +1022,27 @@
   Node* tst = _gvn.transform(tst0);
   BoolTest::mask taken_btest   = BoolTest::illegal;
   BoolTest::mask untaken_btest = BoolTest::illegal;
-  if (btest == BoolTest::ne) {
-    // For now, these are the only cases of btest that matter.  (More later.)
-    taken_btest   = taken_if_true ?        btest : BoolTest::eq;
-    untaken_btest = taken_if_true ? BoolTest::eq :        btest;
+
+  if (tst->is_Bool()) {
+    // Refresh c from the transformed bool node, since it may be
+    // simpler than the original c.  Also re-canonicalize btest.
+    // This wins when (Bool ne (Conv2B p) 0) => (Bool ne (CmpP p NULL)).
+    // That can arise from statements like: if (x instanceof C) ...
+    if (tst != tst0) {
+      // Canonicalize one more time since transform can change it.
+      btest = tst->as_Bool()->_test._test;
+      if (!BoolTest(btest).is_canonical()) {
+        // Reverse edges one more time...
+        tst   = _gvn.transform( tst->as_Bool()->negate(&_gvn) );
+        btest = tst->as_Bool()->_test._test;
+        assert(BoolTest(btest).is_canonical(), "sanity");
+        taken_if_true = !taken_if_true;
+      }
+      c = tst->in(1);
+    }
+    BoolTest::mask neg_btest = BoolTest(btest).negate();
+    taken_btest   = taken_if_true ?     btest : neg_btest;
+    untaken_btest = taken_if_true ? neg_btest :     btest;
   }
 
   // Generate real control flow