< prev index next >
src/hotspot/share/opto/loopopts.cpp
Print this page
@@ -44,11 +44,11 @@
#include "utilities/macros.hpp"
//=============================================================================
//------------------------------split_thru_phi---------------------------------
// Split Node 'n' through merge point if there is enough win.
-Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
+Node* PhaseIdealLoop::split_thru_phi(Node* n, Node* region, int policy) {
if (n->Opcode() == Op_ConvI2L && n->bottom_type() != TypeLong::LONG) {
// ConvI2L may have type information on it which is unsafe to push up
// so disable this for now
return NULL;
}
@@ -59,45 +59,72 @@
if (n->Opcode() == Op_CastII && n->as_CastII()->has_range_check() &&
region->is_CountedLoop() && n->in(1) == region->as_CountedLoop()->phi()) {
return NULL;
}
+ // Bail out if 'n' is a Div or Mod node whose zero check was removed earlier (i.e. control is NULL) and its divisor is a phi node d_phi whose
+ // inputs could be zero (include zero in their type range). This can only happen if d_phi is an induction variable of a trip-counted (integer)
+ // loop. d_phi could have a more precise type range that does not necessarily include all values of its inputs. Since each of these inputs will
+ // be a divisor of the newly cloned nodes of 'n', we need to bail out of one of these divisors could be zero (zero in its type range).
+ if ((n->Opcode() == Op_DivI || n->Opcode() == Op_ModI) && n->in(0) == NULL
+ && region->is_CountedLoop() && n->in(2) == region->as_CountedLoop()->phi()) {
+ Node* phi = region->as_CountedLoop()->phi();
+ for (uint i = 1; i < phi->req(); i++) {
+ if (_igvn.type(phi->in(i))->filter_speculative(TypeInt::ZERO) != Type::TOP) {
+ // Zero could be a possible value but we already removed the zero check. Bail out to avoid a possible division by zero at a later point.
+ return NULL;
+ }
+ }
+ }
+
+#ifdef ASSERT
+ // A phi only has a more precise type than its inputs if it is an induction variable of a trip-counted integer loop. Verify that this is the
+ // case and we are not about to split a Mod or Div node without zero check that could end up with a new divisor that can be zero.
+ // A split of a division by a floating point zero, on the other hand, is not a problem since the result would just be INFINITY as floating point
+ // representation and does not result in an exception.
+ if ((n->Opcode() == Op_DivI || n->Opcode() == Op_ModI)) {
+ check_divide_by_zero(n, TypeInt::ZERO);
+ } else if ((n->Opcode() == Op_DivL || n->Opcode() == Op_ModL)) {
+ check_divide_by_zero(n, TypeLong::ZERO);
+ }
+#endif
+
int wins = 0;
assert(!n->is_CFG(), "");
assert(region->is_Region(), "");
const Type* type = n->bottom_type();
- const TypeOopPtr *t_oop = _igvn.type(n)->isa_oopptr();
- Node *phi;
+ const TypeOopPtr* t_oop = _igvn.type(n)->isa_oopptr();
+ Node* phi;
if (t_oop != NULL && t_oop->is_known_instance_field()) {
int iid = t_oop->instance_id();
int index = C->get_alias_index(t_oop);
int offset = t_oop->offset();
phi = new PhiNode(region, type, NULL, iid, index, offset);
} else {
phi = PhiNode::make_blank(region, n);
}
uint old_unique = C->unique();
for (uint i = 1; i < region->req(); i++) {
- Node *x;
+ Node* x;
Node* the_clone = NULL;
if (region->in(i) == C->top()) {
x = C->top(); // Dead path? Use a dead data op
} else {
x = n->clone(); // Else clone up the data op
the_clone = x; // Remember for possible deletion.
// Alter data node to use pre-phi inputs
if (n->in(0) == region)
x->set_req( 0, region->in(i) );
for (uint j = 1; j < n->req(); j++) {
- Node *in = n->in(j);
+ Node* in = n->in(j);
if (in->is_Phi() && in->in(0) == region)
- x->set_req( j, in->in(i) ); // Use pre-Phi input for the clone
+ x->set_req(j, in->in(i)); // Use pre-Phi input for the clone
}
}
// Check for a 'win' on some paths
- const Type *t = x->Value(&_igvn);
+ const Type* t = x->Value(&_igvn);
bool singleton = t->singleton();
// A TOP singleton indicates that there are no possible values incoming
// along a particular edge. In most cases, this is OK, and the Phi will
@@ -208,10 +235,26 @@
}
return phi;
}
+#ifdef ASSERT
+void PhaseIdealLoop::check_divide_by_zero(const Node* n, const Type* zero) const {
+ if (n->in(0) == NULL && n->in(2)->is_Phi()) {
+ Node* phi = n->in(2);
+ for (uint i = 1; i < phi->req(); i++) {
+ if (_igvn.type(phi->in(i))->filter_speculative(zero) != Type::TOP) {
+ // Zero could be a possible value
+ n->dump(2);
+ phi->dump(2);
+ assert(false, "should not happen that pre-phi type includes zero as possible value but zero check was already removed");
+ }
+ }
+ }
+}
+#endif
+
//------------------------------dominated_by------------------------------------
// Replace the dominated test with an obvious true or false. Place it on the
// IGVN worklist for later cleanup. Move control-dependent data Nodes on the
// live path up to the dominating control.
void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff, bool flip, bool exclude_loop_predicate ) {
< prev index next >