< 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 >