src/share/vm/opto/phaseX.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/opto

src/share/vm/opto/phaseX.cpp

Print this page
rev 8016 : 8069191: moving predicate out of loops may cause array accesses to bypass null check
Summary: Remove CastPP nodes only during final graph reshape
Reviewed-by:


1588           for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) {
1589             Node* p = m->fast_out(i2);  // Propagate changes to uses
1590             if (p->is_Proj() && p->as_Proj()->_con == TypeFunc::Control && p->outcnt() == 1)
1591               worklist.push(p->unique_out());
1592           }
1593         }
1594         if( m->bottom_type() != type(m) ) // If not already bottomed out
1595           worklist.push(m);     // Propagate change to user
1596       }
1597     }
1598   }
1599 }
1600 
1601 //------------------------------do_transform-----------------------------------
1602 // Top level driver for the recursive transformer
1603 void PhaseCCP::do_transform() {
1604   // Correct leaves of new-space Nodes; they point to old-space.
1605   C->set_root( transform(C->root())->as_Root() );
1606   assert( C->top(),  "missing TOP node" );
1607   assert( C->root(), "missing root" );
1608 
1609   // Eagerly remove castPP nodes here. CastPP nodes might not be
1610   // removed in the subsequent IGVN phase if a node that changes
1611   // in(1) of a castPP is processed prior to the castPP node.
1612   for (uint i = 0; i < _worklist.size(); i++) {
1613     Node* n = _worklist.at(i);
1614 
1615     if (n->is_ConstraintCast()) {
1616       Node* nn = n->Identity(this);
1617       if (nn != n) {
1618         replace_node(n, nn);
1619         --i;
1620       }
1621     }
1622   }
1623 }
1624 
1625 //------------------------------transform--------------------------------------
1626 // Given a Node in old-space, clone him into new-space.
1627 // Convert any of his old-space children into new-space children.
1628 Node *PhaseCCP::transform( Node *n ) {
1629   Node *new_node = _nodes[n->_idx]; // Check for transformed node
1630   if( new_node != NULL )
1631     return new_node;                // Been there, done that, return old answer
1632   new_node = transform_once(n);     // Check for constant
1633   _nodes.map( n->_idx, new_node );  // Flag as having been cloned
1634 
1635   // Allocate stack of size _nodes.Size()/2 to avoid frequent realloc
1636   GrowableArray <Node *> trstack(C->unique() >> 1);
1637 
1638   trstack.push(new_node);           // Process children of cloned node
1639   while ( trstack.is_nonempty() ) {
1640     Node *clone = trstack.pop();
1641     uint cnt = clone->req();
1642     for( uint i = 0; i < cnt; i++ ) {          // For all inputs do


1683           Node* m = n->out(i);
1684           if( m->is_Phi() ) {
1685             assert(type(m) == Type::TOP, "Unreachable region should not have live phis.");
1686             replace_node(m, nn);
1687             --i; // deleted this phi; rescan starting with next position
1688           }
1689         }
1690       }
1691       replace_node(n,nn);       // Update DefUse edges for new constant
1692     }
1693     return nn;
1694   }
1695 
1696   // If x is a TypeNode, capture any more-precise type permanently into Node
1697   if (t != n->bottom_type()) {
1698     hash_delete(n);             // changing bottom type may force a rehash
1699     n->raise_bottom_type(t);
1700     _worklist.push(n);          // n re-enters the hash table via the worklist
1701   }
1702 
1703   // Idealize graph using DU info.  Must clone() into new-space.
1704   // DU info is generally used to show profitability, progress or safety
1705   // (but generally not needed for correctness).
1706   Node *nn = n->Ideal_DU_postCCP(this);
1707 
1708   // TEMPORARY fix to ensure that 2nd GVN pass eliminates NULL checks
1709   switch( n->Opcode() ) {
1710   case Op_FastLock:      // Revisit FastLocks for lock coarsening
1711   case Op_If:
1712   case Op_CountedLoopEnd:
1713   case Op_Region:
1714   case Op_Loop:
1715   case Op_CountedLoop:
1716   case Op_Conv2B:
1717   case Op_Opaque1:
1718   case Op_Opaque2:
1719     _worklist.push(n);
1720     break;
1721   default:
1722     break;
1723   }
1724   if( nn ) {
1725     _worklist.push(n);
1726     // Put users of 'n' onto worklist for second igvn transform
1727     add_users_to_worklist(n);
1728     return nn;
1729   }
1730 
1731   return  n;
1732 }
1733 
1734 //---------------------------------saturate------------------------------------
1735 const Type* PhaseCCP::saturate(const Type* new_type, const Type* old_type,
1736                                const Type* limit_type) const {
1737   const Type* wide_type = new_type->widen(old_type, limit_type);
1738   if (wide_type != new_type) {          // did we widen?
1739     // If so, we may have widened beyond the limit type.  Clip it back down.
1740     new_type = wide_type->filter(limit_type);
1741   }
1742   return new_type;
1743 }
1744 
1745 //------------------------------print_statistics-------------------------------
1746 #ifndef PRODUCT
1747 void PhaseCCP::print_statistics() {
1748   tty->print_cr("CCP: %d  constants found: %d", _total_invokes, _total_constants);




1588           for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) {
1589             Node* p = m->fast_out(i2);  // Propagate changes to uses
1590             if (p->is_Proj() && p->as_Proj()->_con == TypeFunc::Control && p->outcnt() == 1)
1591               worklist.push(p->unique_out());
1592           }
1593         }
1594         if( m->bottom_type() != type(m) ) // If not already bottomed out
1595           worklist.push(m);     // Propagate change to user
1596       }
1597     }
1598   }
1599 }
1600 
1601 //------------------------------do_transform-----------------------------------
1602 // Top level driver for the recursive transformer
1603 void PhaseCCP::do_transform() {
1604   // Correct leaves of new-space Nodes; they point to old-space.
1605   C->set_root( transform(C->root())->as_Root() );
1606   assert( C->top(),  "missing TOP node" );
1607   assert( C->root(), "missing root" );















1608 }
1609 
1610 //------------------------------transform--------------------------------------
1611 // Given a Node in old-space, clone him into new-space.
1612 // Convert any of his old-space children into new-space children.
1613 Node *PhaseCCP::transform( Node *n ) {
1614   Node *new_node = _nodes[n->_idx]; // Check for transformed node
1615   if( new_node != NULL )
1616     return new_node;                // Been there, done that, return old answer
1617   new_node = transform_once(n);     // Check for constant
1618   _nodes.map( n->_idx, new_node );  // Flag as having been cloned
1619 
1620   // Allocate stack of size _nodes.Size()/2 to avoid frequent realloc
1621   GrowableArray <Node *> trstack(C->unique() >> 1);
1622 
1623   trstack.push(new_node);           // Process children of cloned node
1624   while ( trstack.is_nonempty() ) {
1625     Node *clone = trstack.pop();
1626     uint cnt = clone->req();
1627     for( uint i = 0; i < cnt; i++ ) {          // For all inputs do


1668           Node* m = n->out(i);
1669           if( m->is_Phi() ) {
1670             assert(type(m) == Type::TOP, "Unreachable region should not have live phis.");
1671             replace_node(m, nn);
1672             --i; // deleted this phi; rescan starting with next position
1673           }
1674         }
1675       }
1676       replace_node(n,nn);       // Update DefUse edges for new constant
1677     }
1678     return nn;
1679   }
1680 
1681   // If x is a TypeNode, capture any more-precise type permanently into Node
1682   if (t != n->bottom_type()) {
1683     hash_delete(n);             // changing bottom type may force a rehash
1684     n->raise_bottom_type(t);
1685     _worklist.push(n);          // n re-enters the hash table via the worklist
1686   }
1687 





1688   // TEMPORARY fix to ensure that 2nd GVN pass eliminates NULL checks
1689   switch( n->Opcode() ) {
1690   case Op_FastLock:      // Revisit FastLocks for lock coarsening
1691   case Op_If:
1692   case Op_CountedLoopEnd:
1693   case Op_Region:
1694   case Op_Loop:
1695   case Op_CountedLoop:
1696   case Op_Conv2B:
1697   case Op_Opaque1:
1698   case Op_Opaque2:
1699     _worklist.push(n);
1700     break;
1701   default:
1702     break;






1703   }
1704 
1705   return  n;
1706 }
1707 
1708 //---------------------------------saturate------------------------------------
1709 const Type* PhaseCCP::saturate(const Type* new_type, const Type* old_type,
1710                                const Type* limit_type) const {
1711   const Type* wide_type = new_type->widen(old_type, limit_type);
1712   if (wide_type != new_type) {          // did we widen?
1713     // If so, we may have widened beyond the limit type.  Clip it back down.
1714     new_type = wide_type->filter(limit_type);
1715   }
1716   return new_type;
1717 }
1718 
1719 //------------------------------print_statistics-------------------------------
1720 #ifndef PRODUCT
1721 void PhaseCCP::print_statistics() {
1722   tty->print_cr("CCP: %d  constants found: %d", _total_invokes, _total_constants);


src/share/vm/opto/phaseX.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File