< prev index next >
src/share/vm/opto/cfgnode.cpp
Print this page
*** 70,88 ****
//------------------------------merge_region-----------------------------------
// If a Region flows into a Region, merge into one big happy merge. This is
// hard to do if there is stuff that has to happen
static Node *merge_region(RegionNode *region, PhaseGVN *phase) {
! if( region->Opcode() != Op_Region ) // Do not do to LoopNodes
return NULL;
Node *progress = NULL; // Progress flag
PhaseIterGVN *igvn = phase->is_IterGVN();
uint rreq = region->req();
for( uint i = 1; i < rreq; i++ ) {
Node *r = region->in(i);
! if( r && r->Opcode() == Op_Region && // Found a region?
r->in(0) == r && // Not already collapsed?
r != region && // Avoid stupid situations
r->outcnt() == 2 ) { // Self user and 'region' user only?
assert(!r->as_Region()->has_phi(), "no phi users");
if( !progress ) { // No progress
--- 70,88 ----
//------------------------------merge_region-----------------------------------
// If a Region flows into a Region, merge into one big happy merge. This is
// hard to do if there is stuff that has to happen
static Node *merge_region(RegionNode *region, PhaseGVN *phase) {
! if( region->Opcode() != Opcodes::Op_Region ) // Do not do to LoopNodes
return NULL;
Node *progress = NULL; // Progress flag
PhaseIterGVN *igvn = phase->is_IterGVN();
uint rreq = region->req();
for( uint i = 1; i < rreq; i++ ) {
Node *r = region->in(i);
! if( r && r->Opcode() == Opcodes::Op_Region && // Found a region?
r->in(0) == r && // Not already collapsed?
r != region && // Avoid stupid situations
r->outcnt() == 2 ) { // Self user and 'region' user only?
assert(!r->as_Region()->has_phi(), "no phi users");
if( !progress ) { // No progress
*** 169,187 ****
val_idx = 0;
uint phi_max = phi->req();
if( phi_max == 4 ) {
for( uint j = 1; j < phi_max; ++j ) {
Node *n = phi->in(j);
! int opcode = n->Opcode();
switch( opcode ) {
! case Op_ConI:
{
if( min == NULL ) {
! min = n->Opcode() == Op_ConI ? (ConNode*)n : NULL;
min_idx = j;
} else {
! max = n->Opcode() == Op_ConI ? (ConNode*)n : NULL;
max_idx = j;
if( min->get_int() > max->get_int() ) {
// Swap min and max
ConNode *temp;
uint temp_idx;
--- 169,187 ----
val_idx = 0;
uint phi_max = phi->req();
if( phi_max == 4 ) {
for( uint j = 1; j < phi_max; ++j ) {
Node *n = phi->in(j);
! Opcodes opcode = n->Opcode();
switch( opcode ) {
! case Opcodes::Op_ConI:
{
if( min == NULL ) {
! min = n->Opcode() == Opcodes::Op_ConI ? (ConNode*)n : NULL;
min_idx = j;
} else {
! max = n->Opcode() == Opcodes::Op_ConI ? (ConNode*)n : NULL;
max_idx = j;
if( min->get_int() > max->get_int() ) {
// Swap min and max
ConNode *temp;
uint temp_idx;
*** 256,275 ****
convf2i = NULL;
// Check for the RShiftNode
Node *rshift = phi->in(idx);
assert( rshift, "Previous checks ensure phi input is present");
! if( rshift->Opcode() != Op_RShiftI ) { return false; }
// Check for the LShiftNode
Node *lshift = rshift->in(1);
assert( lshift, "Previous checks ensure phi input is present");
! if( lshift->Opcode() != Op_LShiftI ) { return false; }
// Check for the ConvF2INode
Node *conv = lshift->in(1);
! if( conv->Opcode() != Op_ConvF2I ) { return false; }
// Check that shift amounts are only to get sign bits set after F2I
jint max_cutoff = max->get_int();
jint min_cutoff = min->get_int();
jint left_shift = lshift->in(2)->get_int();
--- 256,275 ----
convf2i = NULL;
// Check for the RShiftNode
Node *rshift = phi->in(idx);
assert( rshift, "Previous checks ensure phi input is present");
! if( rshift->Opcode() != Opcodes::Op_RShiftI ) { return false; }
// Check for the LShiftNode
Node *lshift = rshift->in(1);
assert( lshift, "Previous checks ensure phi input is present");
! if( lshift->Opcode() != Opcodes::Op_LShiftI ) { return false; }
// Check for the ConvF2INode
Node *conv = lshift->in(1);
! if( conv->Opcode() != Opcodes::Op_ConvF2I ) { return false; }
// Check that shift amounts are only to get sign bits set after F2I
jint max_cutoff = max->get_int();
jint min_cutoff = min->get_int();
jint left_shift = lshift->in(2)->get_int();
*** 296,310 ****
if ( !i1->is_Bool() ) { return false; }
BoolNode *bool1 = i1->as_Bool();
if( less_than && bool1->_test._test != BoolTest::le ) { return false; }
else if( !less_than && bool1->_test._test != BoolTest::lt ) { return false; }
const Node *cmpF = bool1->in(1);
! if( cmpF->Opcode() != Op_CmpF ) { return false; }
// Test that the float value being compared against
// is equivalent to the int value used as a limit
Node *nodef = cmpF->in(2);
! if( nodef->Opcode() != Op_ConF ) { return false; }
jfloat conf = nodef->getf();
jint coni = limit->get_int();
if( ((int)conf) != coni ) { return false; }
input = cmpF->in(1);
return true;
--- 296,310 ----
if ( !i1->is_Bool() ) { return false; }
BoolNode *bool1 = i1->as_Bool();
if( less_than && bool1->_test._test != BoolTest::le ) { return false; }
else if( !less_than && bool1->_test._test != BoolTest::lt ) { return false; }
const Node *cmpF = bool1->in(1);
! if( cmpF->Opcode() != Opcodes::Op_CmpF ) { return false; }
// Test that the float value being compared against
// is equivalent to the int value used as a limit
Node *nodef = cmpF->in(2);
! if( nodef->Opcode() != Opcodes::Op_ConF ) { return false; }
jfloat conf = nodef->getf();
jint coni = limit->get_int();
if( ((int)conf) != coni ) { return false; }
input = cmpF->in(1);
return true;
*** 1103,1117 ****
if( !b->is_Bool() ) return 0;
const Node *cmp = b->in(1);
if( !cmp->is_Cmp() ) return 0;
// Check for branching opposite expected
! if( ifp2->Opcode() == Op_IfTrue ) {
! assert( ifp1->Opcode() == Op_IfFalse, "" );
return 2;
} else {
! assert( ifp1->Opcode() == Op_IfTrue, "" );
return 1;
}
}
//----------------------------check_cmove_id-----------------------------------
--- 1103,1117 ----
if( !b->is_Bool() ) return 0;
const Node *cmp = b->in(1);
if( !cmp->is_Cmp() ) return 0;
// Check for branching opposite expected
! if( ifp2->Opcode() == Opcodes::Op_IfTrue ) {
! assert( ifp1->Opcode() == Opcodes::Op_IfFalse, "" );
return 2;
} else {
! assert( ifp1->Opcode() == Opcodes::Op_IfTrue, "" );
return 1;
}
}
//----------------------------check_cmove_id-----------------------------------
*** 1319,1337 ****
if (region->in(1)->outcnt() != 1) return NULL;
if (region->in(2)->outcnt() != 1) return NULL;
// Check for "(P < Q)" of type signed int
if (b->_test._test != BoolTest::lt) return NULL;
! if (cmp->Opcode() != Op_CmpI) return NULL;
Node *p = cmp->in(1);
Node *q = cmp->in(2);
Node *n1 = phi->in( true_path);
Node *n2 = phi->in(3-true_path);
! int op = n1->Opcode();
! if( op != Op_AddI // Need zero as additive identity
/*&&op != Op_SubI &&
op != Op_AddP &&
op != Op_XorI &&
op != Op_OrI*/ )
return NULL;
--- 1319,1337 ----
if (region->in(1)->outcnt() != 1) return NULL;
if (region->in(2)->outcnt() != 1) return NULL;
// Check for "(P < Q)" of type signed int
if (b->_test._test != BoolTest::lt) return NULL;
! if (cmp->Opcode() != Opcodes::Op_CmpI) return NULL;
Node *p = cmp->in(1);
Node *q = cmp->in(2);
Node *n1 = phi->in( true_path);
Node *n2 = phi->in(3-true_path);
! Opcodes op = n1->Opcode();
! if( op != Opcodes::Op_AddI // Need zero as additive identity
/*&&op != Op_SubI &&
op != Op_AddP &&
op != Op_XorI &&
op != Op_OrI*/ )
return NULL;
*** 1380,1391 ****
// Test is next
Node *cmp = bol->in(1);
const Type *tzero = NULL;
switch( cmp->Opcode() ) {
! case Op_CmpF: tzero = TypeF::ZERO; break; // Float ABS
! case Op_CmpD: tzero = TypeD::ZERO; break; // Double ABS
default: return NULL;
}
// Find zero input of compare; the other input is being abs'd
Node *x = NULL;
--- 1380,1391 ----
// Test is next
Node *cmp = bol->in(1);
const Type *tzero = NULL;
switch( cmp->Opcode() ) {
! case Opcodes::Op_CmpF: tzero = TypeF::ZERO; break; // Float ABS
! case Opcodes::Op_CmpD: tzero = TypeD::ZERO; break; // Double ABS
default: return NULL;
}
// Find zero input of compare; the other input is being abs'd
Node *x = NULL;
*** 1407,1425 ****
// Check other phi input for subtract node
Node *sub = phi_root->in(3 - phi_x_idx);
// Allow only Sub(0,X) and fail out for all others; Neg is not OK
if( tzero == TypeF::ZERO ) {
! if( sub->Opcode() != Op_SubF ||
sub->in(2) != x ||
phase->type(sub->in(1)) != tzero ) return NULL;
x = new AbsFNode(x);
if (flip) {
x = new SubFNode(sub->in(1), phase->transform(x));
}
} else {
! if( sub->Opcode() != Op_SubD ||
sub->in(2) != x ||
phase->type(sub->in(1)) != tzero ) return NULL;
x = new AbsDNode(x);
if (flip) {
x = new SubDNode(sub->in(1), phase->transform(x));
--- 1407,1425 ----
// Check other phi input for subtract node
Node *sub = phi_root->in(3 - phi_x_idx);
// Allow only Sub(0,X) and fail out for all others; Neg is not OK
if( tzero == TypeF::ZERO ) {
! if( sub->Opcode() != Opcodes::Op_SubF ||
sub->in(2) != x ||
phase->type(sub->in(1)) != tzero ) return NULL;
x = new AbsFNode(x);
if (flip) {
x = new SubFNode(sub->in(1), phase->transform(x));
}
} else {
! if( sub->Opcode() != Opcodes::Op_SubD ||
sub->in(2) != x ||
phase->type(sub->in(1)) != tzero ) return NULL;
x = new AbsDNode(x);
if (flip) {
x = new SubDNode(sub->in(1), phase->transform(x));
*** 1466,1476 ****
uint i;
for( i = 1; i < phi->req()-1; i++ ) {
Node *n = phi->in(i);
if( !n ) return NULL;
if( phase->type(n) == Type::TOP ) return NULL;
! if( n->Opcode() == Op_ConP || n->Opcode() == Op_ConN || n->Opcode() == Op_ConNKlass )
break;
}
if( i >= phi->req() ) // Only split for constants
return NULL;
--- 1466,1476 ----
uint i;
for( i = 1; i < phi->req()-1; i++ ) {
Node *n = phi->in(i);
if( !n ) return NULL;
if( phase->type(n) == Type::TOP ) return NULL;
! if( n->Opcode() == Opcodes::Op_ConP || n->Opcode() == Opcodes::Op_ConN || n->Opcode() == Opcodes::Op_ConNKlass )
break;
}
if( i >= phi->req() ) // Only split for constants
return NULL;
*** 1706,1726 ****
// Add a cast node between the phi to be removed and its unique input.
// Wait until after parsing for the type information to propagate from the casts.
assert(can_reshape, "Invalid during parsing");
const Type* phi_type = bottom_type();
assert(phi_type->isa_int() || phi_type->isa_ptr(), "bad phi type");
! int opcode;
// Determine the type of cast to be added.
if (phi_type->isa_int()) {
! opcode = Op_CastII;
} else {
const Type* uin_type = phase->type(uin);
if ((phi_type->join(TypePtr::NOTNULL) == uin_type->join(TypePtr::NOTNULL)) ||
(!phi_type->isa_oopptr() && !uin_type->isa_oopptr())) {
! opcode = Op_CastPP;
} else {
! opcode = Op_CheckCastPP;
}
}
// Add a cast to carry the control dependency of the Phi that is
// going away
Node* cast = ConstraintCastNode::make_cast(opcode, r, uin, phi_type, true);
--- 1706,1726 ----
// Add a cast node between the phi to be removed and its unique input.
// Wait until after parsing for the type information to propagate from the casts.
assert(can_reshape, "Invalid during parsing");
const Type* phi_type = bottom_type();
assert(phi_type->isa_int() || phi_type->isa_ptr(), "bad phi type");
! Opcodes opcode;
// Determine the type of cast to be added.
if (phi_type->isa_int()) {
! opcode = Opcodes::Op_CastII;
} else {
const Type* uin_type = phase->type(uin);
if ((phi_type->join(TypePtr::NOTNULL) == uin_type->join(TypePtr::NOTNULL)) ||
(!phi_type->isa_oopptr() && !uin_type->isa_oopptr())) {
! opcode = Opcodes::Op_CastPP;
} else {
! opcode = Opcodes::Op_CheckCastPP;
}
}
// Add a cast to carry the control dependency of the Phi that is
// going away
Node* cast = ConstraintCastNode::make_cast(opcode, r, uin, phi_type, true);
*** 1795,1805 ****
// This optimization only modifies phi - don't need to check for dead loop.
assert(opt == NULL || phase->eqv(opt, this), "do not elide phi");
if (opt != NULL) return opt;
}
! if (in(1) != NULL && in(1)->Opcode() == Op_AddP && can_reshape) {
// Try to undo Phi of AddP:
// (Phi (AddP base base y) (AddP base2 base2 y))
// becomes:
// newbase := (Phi base base2)
// (AddP newbase newbase y)
--- 1795,1805 ----
// This optimization only modifies phi - don't need to check for dead loop.
assert(opt == NULL || phase->eqv(opt, this), "do not elide phi");
if (opt != NULL) return opt;
}
! if (in(1) != NULL && in(1)->Opcode() == Opcodes::Op_AddP && can_reshape) {
// Try to undo Phi of AddP:
// (Phi (AddP base base y) (AddP base2 base2 y))
// becomes:
// newbase := (Phi base base2)
// (AddP newbase newbase y)
*** 1814,1824 ****
// make sure that all the inputs are similar to the first one,
// i.e. AddP with base == address and same offset as first AddP
bool doit = true;
for (uint i = 2; i < req(); i++) {
if (in(i) == NULL ||
! in(i)->Opcode() != Op_AddP ||
in(i)->in(AddPNode::Base) != in(i)->in(AddPNode::Address) ||
in(i)->in(AddPNode::Offset) != y) {
doit = false;
break;
}
--- 1814,1824 ----
// make sure that all the inputs are similar to the first one,
// i.e. AddP with base == address and same offset as first AddP
bool doit = true;
for (uint i = 2; i < req(); i++) {
if (in(i) == NULL ||
! in(i)->Opcode() != Opcodes::Op_AddP ||
in(i)->in(AddPNode::Base) != in(i)->in(AddPNode::Address) ||
in(i)->in(AddPNode::Offset) != y) {
doit = false;
break;
}
*** 2070,2083 ****
const RegMask &PhiNode::in_RegMask(uint i) const {
return i ? out_RegMask() : RegMask::Empty;
}
const RegMask &PhiNode::out_RegMask() const {
! uint ideal_reg = _type->ideal_reg();
! assert( ideal_reg != Node::NotAMachineReg, "invalid type at Phi" );
! if( ideal_reg == 0 ) return RegMask::Empty;
! return *(Compile::current()->matcher()->idealreg2spillmask[ideal_reg]);
}
#ifndef PRODUCT
void PhiNode::related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
// For a PhiNode, the set of related nodes includes all inputs till level 2,
--- 2070,2083 ----
const RegMask &PhiNode::in_RegMask(uint i) const {
return i ? out_RegMask() : RegMask::Empty;
}
const RegMask &PhiNode::out_RegMask() const {
! Opcodes ideal_reg = _type->ideal_reg();
! assert( ideal_reg != Opcodes::NotAMachineReg, "invalid type at Phi" );
! if( ideal_reg == Opcodes::Op_Node ) return RegMask::Empty;
! return *(Compile::current()->matcher()->idealreg2spillmask[static_cast<uint>(ideal_reg)]);
}
#ifndef PRODUCT
void PhiNode::related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
// For a PhiNode, the set of related nodes includes all inputs till level 2,
< prev index next >