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