src/share/vm/c1/c1_Canonicalizer.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/share/vm/c1/c1_Canonicalizer.cpp	Fri Sep 19 19:56:31 2014
--- new/src/share/vm/c1/c1_Canonicalizer.cpp	Fri Sep 19 19:56:31 2014

*** 325,335 **** --- 325,335 ---- } } if (t2->is_constant()) { switch (t2->tag()) { case intTag : if (t2->as_IntConstant()->value() == 0) set_canonical(x->x()); return; ! case longTag : if (t2->as_IntConstant()->value() == 0) set_canonical(x->x()); return; ! case longTag : if (t2->as_LongConstant()->value() == (jlong)0) set_canonical(x->x()); return; default : ShouldNotReachHere(); } } }
*** 806,837 **** --- 806,850 ---- void Canonicalizer::do_OsrEntry (OsrEntry* x) {} void Canonicalizer::do_ExceptionObject(ExceptionObject* x) {} static bool match_index_and_scale(Instruction* instr, Instruction** index, ! int* log2_scale, Instruction** instr_to_unpin) { *instr_to_unpin = NULL; // Skip conversion ops ! int* log2_scale) { + // Skip conversion ops. This works only on 32bit because of the implicit l2i that the + // unsafe performs. + #ifndef _LP64 Convert* convert = instr->as_Convert(); ! if (convert != NULL && convert->op() == Bytecodes::_i2l) { + assert(convert->value()->type() == intType, "invalid input type"); instr = convert->value(); } + #endif ShiftOp* shift = instr->as_ShiftOp(); if (shift != NULL) { ! if (shift->is_pinned()) { ! *instr_to_unpin = shift; ! if (shift->op() == Bytecodes::_lshl) { ! assert(shift->x()->type() == longType, "invalid input type"); + } else { + #ifndef _LP64 + if (shift->op() == Bytecodes::_ishl) { + assert(shift->x()->type() == intType, "invalid input type"); + } else { + return false; + } + #else + return false; + #endif } + + // Constant shift value? Constant* con = shift->y()->as_Constant(); if (con == NULL) return false; // Well-known type and value? IntConstant* val = con->type()->as_IntConstant(); ! if (val == NULL) return false; if (shift->x()->type() != intType) return false; ! assert(val != NULL, "Should be an int constant"); + *index = shift->x(); int tmp_scale = val->value(); if (tmp_scale >= 0 && tmp_scale < 4) { *log2_scale = tmp_scale; return true;
*** 840,909 **** --- 853,941 ---- } } ArithmeticOp* arith = instr->as_ArithmeticOp(); if (arith != NULL) { if (arith->is_pinned()) { *instr_to_unpin = arith; } // Check for integer multiply if (arith->op() == Bytecodes::_imul) { // See if either arg is a known constant Constant* con = arith->x()->as_Constant(); if (con != NULL) { *index = arith->y(); } else { con = arith->y()->as_Constant(); if (con == NULL) return false; *index = arith->x(); } ! if ((*index)->type() != intType) return false; // Well-known type and value? ! long const_value; + // Check for integer multiply + if (arith->op() == Bytecodes::_lmul) { + assert((*index)->type() == longType, "invalid input type"); + LongConstant* val = con->type()->as_LongConstant(); + assert(val != NULL, "expecting a long constant"); + const_value = val->value(); + } else { + #ifndef _LP64 + if (arith->op() == Bytecodes::_imul) { + assert((*index)->type() == intType, "invalid input type"); IntConstant* val = con->type()->as_IntConstant(); ! if (val == NULL) return false; switch (val->value()) { ! assert(val != NULL, "expecting an int constant"); + const_value = val->value(); + } else { + return false; + } + #else + return false; + #endif + } + switch (const_value) { case 1: *log2_scale = 0; return true; case 2: *log2_scale = 1; return true; case 4: *log2_scale = 2; return true; case 8: *log2_scale = 3; return true; default: return false; } } } // Unknown instruction sequence; don't touch it return false; } static bool match(UnsafeRawOp* x, Instruction** base, Instruction** index, int* log2_scale) { Instruction* instr_to_unpin = NULL; ArithmeticOp* root = x->base()->as_ArithmeticOp(); if (root == NULL) return false; // Limit ourselves to addition for now if (root->op() != Bytecodes::_ladd) return false; + + bool match_found = false; // Try to find shift or scale op - if (match_index_and_scale(root->y(), index, log2_scale, &instr_to_unpin)) { *base = root->x(); } else if (match_index_and_scale(root->x(), index, log2_scale, &instr_to_unpin)) { + match_found = true; + } else if (match_index_and_scale(root->x(), index, log2_scale)) { *base = root->y(); } else if (root->y()->as_Convert() != NULL) { + match_found = true; + } else if (NOT_LP64(root->y()->as_Convert() != NULL) LP64_ONLY(false)) { + // Skipping i2l works only on 32bit because of the implicit l2i that the unsafe performs. + // 64bit needs a real sign-extending conversion. Convert* convert = root->y()->as_Convert(); - if (convert->op() == Bytecodes::_i2l && convert->value()->type() == intType) { + assert(convert->value()->type() == intType, "should be an int"); // pick base and index, setting scale at 1 *base = root->x(); *index = convert->value(); *log2_scale = 0; } else { return false; + match_found = true; } } else { // doesn't match any expected sequences return false; + } + // The default solution + if (!match_found) { + *base = root->x(); + *index = root->y(); + *log2_scale = 0; } // If the value is pinned then it will be always be computed so // there's no profit to reshaping the expression. return !root->is_pinned();

src/share/vm/c1/c1_Canonicalizer.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File