1710 for (EdgeIterator j(jobj); j.has_next(); j.next()) {
1711 if (j.get()->is_Arraycopy()) {
1712 continue;
1713 }
1714
1715 // Non-escaping object node should point only to field nodes.
1716 FieldNode* field = j.get()->as_Field();
1717 int offset = field->as_Field()->offset();
1718
1719 // 4. An object is not scalar replaceable if it has a field with unknown
1720 // offset (array's element is accessed in loop).
1721 if (offset == Type::OffsetBot) {
1722 jobj->set_scalar_replaceable(false);
1723 return;
1724 }
1725 // 5. Currently an object is not scalar replaceable if a LoadStore node
1726 // access its field since the field value is unknown after it.
1727 //
1728 Node* n = field->ideal_node();
1729 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
1730 if (n->fast_out(i)->is_LoadStore()) {
1731 jobj->set_scalar_replaceable(false);
1732 return;
1733 }
1734 }
1735
1736 // 6. Or the address may point to more then one object. This may produce
1737 // the false positive result (set not scalar replaceable)
1738 // since the flow-insensitive escape analysis can't separate
1739 // the case when stores overwrite the field's value from the case
1740 // when stores happened on different control branches.
1741 //
1742 // Note: it will disable scalar replacement in some cases:
1743 //
1744 // Point p[] = new Point[1];
1745 // p[0] = new Point(); // Will be not scalar replaced
1746 //
1747 // but it will save us from incorrect optimizations in next cases:
1748 //
1749 // Point p[] = new Point[1];
1750 // if ( x ) p[0] = new Point(); // Will be not scalar replaced
|
1710 for (EdgeIterator j(jobj); j.has_next(); j.next()) {
1711 if (j.get()->is_Arraycopy()) {
1712 continue;
1713 }
1714
1715 // Non-escaping object node should point only to field nodes.
1716 FieldNode* field = j.get()->as_Field();
1717 int offset = field->as_Field()->offset();
1718
1719 // 4. An object is not scalar replaceable if it has a field with unknown
1720 // offset (array's element is accessed in loop).
1721 if (offset == Type::OffsetBot) {
1722 jobj->set_scalar_replaceable(false);
1723 return;
1724 }
1725 // 5. Currently an object is not scalar replaceable if a LoadStore node
1726 // access its field since the field value is unknown after it.
1727 //
1728 Node* n = field->ideal_node();
1729 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
1730 Node* u = n->fast_out(i);
1731 if (u->is_LoadStore() || (u->is_Mem() && u->as_Mem()->is_mismatched_access())) {
1732 jobj->set_scalar_replaceable(false);
1733 return;
1734 }
1735 }
1736
1737 // 6. Or the address may point to more then one object. This may produce
1738 // the false positive result (set not scalar replaceable)
1739 // since the flow-insensitive escape analysis can't separate
1740 // the case when stores overwrite the field's value from the case
1741 // when stores happened on different control branches.
1742 //
1743 // Note: it will disable scalar replacement in some cases:
1744 //
1745 // Point p[] = new Point[1];
1746 // p[0] = new Point(); // Will be not scalar replaced
1747 //
1748 // but it will save us from incorrect optimizations in next cases:
1749 //
1750 // Point p[] = new Point[1];
1751 // if ( x ) p[0] = new Point(); // Will be not scalar replaced
|