changeset 26479:f1d4ef86b205

8142314: Bug in C1 ControlFlowOptimizer::delete_unnecessary_jumps with bytecode profiling Reviewed-by: kvn Contributed-by: gunter.haug@sap.com
author simonis
date Tue, 10 Nov 2015 11:01:28 +0100
parents 1d42c245cc87
children 37544bee88a2 d86252b62778
files src/share/vm/c1/c1_LIR.cpp src/share/vm/c1/c1_LinearScan.cpp
diffstat 2 files changed, 18 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/c1/c1_LIR.cpp	Wed Nov 11 01:27:36 2015 +0300
+++ b/src/share/vm/c1/c1_LIR.cpp	Tue Nov 10 11:01:28 2015 +0100
@@ -2004,7 +2004,7 @@
 
 // LIR_Op2
 void LIR_Op2::print_instr(outputStream* out) const {
-  if (code() == lir_cmove) {
+  if (code() == lir_cmove || code() == lir_cmp) {
     print_condition(out, condition());         out->print(" ");
   }
   in_opr1()->print(out);    out->print(" ");
--- a/src/share/vm/c1/c1_LinearScan.cpp	Wed Nov 11 01:27:36 2015 +0300
+++ b/src/share/vm/c1/c1_LinearScan.cpp	Tue Nov 10 11:01:28 2015 +0100
@@ -6233,9 +6233,19 @@
             if (prev_branch->stub() == NULL) {
 
               LIR_Op2* prev_cmp = NULL;
+              // There might be a cmove inserted for profiling which depends on the same
+              // compare. If we change the condition of the respective compare, we have
+              // to take care of this cmove as well.
+              LIR_Op2* prev_cmove = NULL;
 
               for(int j = instructions->length() - 3; j >= 0 && prev_cmp == NULL; j--) {
                 prev_op = instructions->at(j);
+                // check for the cmove
+                if (prev_op->code() == lir_cmove) {
+                  assert(prev_op->as_Op2() != NULL, "cmove must be of type LIR_Op2");
+                  prev_cmove = (LIR_Op2*)prev_op;
+                  assert(prev_branch->cond() == prev_cmove->condition(), "should be the same");
+                }
                 if (prev_op->code() == lir_cmp) {
                   assert(prev_op->as_Op2() != NULL, "branch must be of type LIR_Op2");
                   prev_cmp = (LIR_Op2*)prev_op;
@@ -6252,6 +6262,13 @@
                 prev_branch->negate_cond();
                 prev_cmp->set_condition(prev_branch->cond());
                 instructions->truncate(instructions->length() - 1);
+                // if we do change the condition, we have to change the cmove as well
+                if (prev_cmove != NULL) {
+                  prev_cmove->set_condition(prev_branch->cond());
+                  LIR_Opr t = prev_cmove->in_opr1();
+                  prev_cmove->set_in_opr1(prev_cmove->in_opr2());
+                  prev_cmove->set_in_opr2(t);
+                }
               }
             }
           }