< prev index next >
src/share/vm/opto/loopTransform.cpp
Print this page
@@ -2658,11 +2658,11 @@
}
//=============================================================================
// Process all the loops in the loop tree and replace any fill
-// patterns with an intrisc version.
+// patterns with an intrinsic version.
bool PhaseIdealLoop::do_intrinsify_fill() {
bool changed = false;
for (LoopTreeIterator iter(_ltree_root); !iter.done(); iter.next()) {
IdealLoopTree* lpt = iter.current();
changed |= intrinsify_fill(lpt);
@@ -2756,12 +2756,13 @@
#endif
return false;
}
// Make sure the address expression can be handled. It should be
- // head->phi * elsize + con. head->phi might have a ConvI2L.
+ // head->phi * elsize + con. head->phi might have a ConvI2L(CastII()).
Node* elements[4];
+ Node* cast = NULL;
Node* conv = NULL;
bool found_index = false;
int count = store->in(MemNode::Address)->as_AddP()->unpack_offsets(elements, ARRAY_SIZE(elements));
for (int e = 0; e < count; e++) {
Node* n = elements[e];
@@ -2772,10 +2773,16 @@
#ifdef _LP64
if (value->Opcode() == Op_ConvI2L) {
conv = value;
value = value->in(1);
}
+ if (value->Opcode() == Op_CastII &&
+ value->as_CastII()->has_range_check()) {
+ // Skip range check dependent CastII nodes
+ cast = value;
+ value = value->in(1);
+ }
#endif
if (value != head->phi()) {
msg = "unhandled shift in address";
} else {
if (type2aelembytes(store->as_Mem()->memory_type(), true) != (1 << n->in(2)->get_int())) {
@@ -2784,13 +2791,20 @@
found_index = true;
shift = n;
}
}
} else if (n->Opcode() == Op_ConvI2L && conv == NULL) {
- if (n->in(1) == head->phi()) {
- found_index = true;
conv = n;
+ n = n->in(1);
+ if (n->Opcode() == Op_CastII &&
+ n->as_CastII()->has_range_check()) {
+ // Skip range check dependent CastII nodes
+ cast = n;
+ n = n->in(1);
+ }
+ if (n == head->phi()) {
+ found_index = true;
} else {
msg = "unhandled input to ConvI2L";
}
} else if (n == head->phi()) {
// no shift, check below for allowed cases
@@ -2845,10 +2859,11 @@
ok.set(loop_exit->in(1)->_idx);
// Address elements are ok
if (con) ok.set(con->_idx);
if (shift) ok.set(shift->_idx);
+ if (cast) ok.set(cast->_idx);
if (conv) ok.set(conv->_idx);
for (uint i = 0; msg == NULL && i < lpt->_body.size(); i++) {
Node* n = lpt->_body.at(i);
if (n->outcnt() == 0) continue; // Ignore dead
< prev index next >