< prev index next >

src/hotspot/share/c1/c1_LinearScan.cpp

Print this page
@@ -1238,16 +1238,23 @@
          }
        }
        break;
      }
      case lir_cmove: {
+ #ifndef RISCV
        assert(op->as_Op2() != NULL, "lir_cmove must be LIR_Op2");
        LIR_Op2* cmove = (LIR_Op2*)op;
  
        LIR_Opr move_from = cmove->in_opr1();
        LIR_Opr move_to = cmove->result_opr();
+ #else
+       assert(op->as_Op4() != NULL, "lir_cmove must be LIR_Op4");
+       LIR_Op4* cmove = (LIR_Op4*)op;
  
+       LIR_Opr move_from = cmove->in_opr3();
+       LIR_Opr move_to   = cmove->in_opr4();
+ #endif
        if (move_to->is_register() && move_from->is_register()) {
          Interval* from = interval_at(reg_num(move_from));
          Interval* to = interval_at(reg_num(move_to));
          if (from != NULL && to != NULL) {
            to->set_register_hint(from);

@@ -6155,10 +6162,20 @@
          // no further optimization possible
          return;
        }
      }
  
+ #ifdef RISCV
+     // Some platforms, such as riscv64, s390 and aarch64, the branch instruction may contain register operands.
+     // If the move instruction would change the branch instruction's operand after the optimization, we can't apply it.
+     if (branch->as_Op2() != NULL) {
+       LIR_Op2* branch_op2 = (LIR_Op2*)branch;
+       if (op->result_opr()->has_common_register(branch_op2->in_opr1())) return;
+       if (op->result_opr()->has_common_register(branch_op2->in_opr2())) return;
+     }
+ #endif
+ 
      TRACE_LINEAR_SCAN(4, tty->print("----- found instruction that is equal in all %d successors: ", num_sux); op->print());
  
      // insert instruction at end of current block
      block->lir()->insert_before(insert_idx, op);
      insert_idx++;

@@ -6362,10 +6379,11 @@
              assert(prev_op->as_OpBranch() != NULL, "branch must be of type LIR_OpBranch");
              LIR_OpBranch* prev_branch = (LIR_OpBranch*)prev_op;
  
              if (prev_branch->stub() == NULL) {
  
+ #ifndef RISCV
                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;

@@ -6384,26 +6402,31 @@
                    assert(prev_branch->cond() == prev_cmp->condition(), "should be the same");
                  }
                }
                // Guarantee because it is dereferenced below.
                guarantee(prev_cmp != NULL, "should have found comp instruction for branch");
+ #endif
                if (prev_branch->block() == code->at(i + 1) && prev_branch->info() == NULL) {
  
                  TRACE_LINEAR_SCAN(3, tty->print_cr("Negating conditional branch and deleting unconditional branch at end of block B%d", block->block_id()));
  
                  // eliminate a conditional branch to the immediate successor
                  prev_branch->change_block(last_branch->block());
                  prev_branch->negate_cond();
+ #ifndef RISCV
                  prev_cmp->set_condition(prev_branch->cond());
+ #endif
                  instructions->trunc_to(instructions->length() - 1);
+ #ifndef RISCV
                  // 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);
                  }
+ #endif
                }
              }
            }
          }
        }

@@ -6705,11 +6728,13 @@
              ShouldNotReachHere();
            }
            break;
          }
  
+ #ifndef RISCV
          case lir_cmp:             inc_counter(counter_cmp); break;
+ #endif
  
          case lir_branch:
          case lir_cond_float_branch: {
            LIR_OpBranch* branch = op->as_OpBranch();
            if (branch->block() == NULL) {
< prev index next >