Mercurial > hg > truffle
comparison src/share/vm/opto/callnode.cpp @ 4115:1bd45abaa507
6890673: Eliminate allocations immediately after EA
Summary: Try to eliminate allocations and related locks immediately after escape analysis.
Reviewed-by: never
author | kvn |
---|---|
date | Wed, 16 Nov 2011 09:13:57 -0800 |
parents | f95d63e2154a |
children | e9a5e0a812c8 |
comparison
equal
deleted
inserted
replaced
4114:6729bbc1fcd6 | 4115:1bd45abaa507 |
---|---|
1069 _n_fields(n_fields) | 1069 _n_fields(n_fields) |
1070 { | 1070 { |
1071 init_class_id(Class_SafePointScalarObject); | 1071 init_class_id(Class_SafePointScalarObject); |
1072 } | 1072 } |
1073 | 1073 |
1074 bool SafePointScalarObjectNode::pinned() const { return true; } | 1074 // Do not allow value-numbering for SafePointScalarObject node. |
1075 bool SafePointScalarObjectNode::depends_only_on_test() const { return false; } | 1075 uint SafePointScalarObjectNode::hash() const { return NO_HASH; } |
1076 uint SafePointScalarObjectNode::cmp( const Node &n ) const { | |
1077 return (&n == this); // Always fail except on self | |
1078 } | |
1076 | 1079 |
1077 uint SafePointScalarObjectNode::ideal_reg() const { | 1080 uint SafePointScalarObjectNode::ideal_reg() const { |
1078 return 0; // No matching to machine instruction | 1081 return 0; // No matching to machine instruction |
1079 } | 1082 } |
1080 | 1083 |
1094 SafePointScalarObjectNode::clone(int jvms_adj, Dict* sosn_map) const { | 1097 SafePointScalarObjectNode::clone(int jvms_adj, Dict* sosn_map) const { |
1095 void* cached = (*sosn_map)[(void*)this]; | 1098 void* cached = (*sosn_map)[(void*)this]; |
1096 if (cached != NULL) { | 1099 if (cached != NULL) { |
1097 return (SafePointScalarObjectNode*)cached; | 1100 return (SafePointScalarObjectNode*)cached; |
1098 } | 1101 } |
1099 Compile* C = Compile::current(); | |
1100 SafePointScalarObjectNode* res = (SafePointScalarObjectNode*)Node::clone(); | 1102 SafePointScalarObjectNode* res = (SafePointScalarObjectNode*)Node::clone(); |
1101 res->_first_index += jvms_adj; | 1103 res->_first_index += jvms_adj; |
1102 sosn_map->Insert((void*)this, (void*)res); | 1104 sosn_map->Insert((void*)this, (void*)res); |
1103 return res; | 1105 return res; |
1104 } | 1106 } |
1140 //============================================================================= | 1142 //============================================================================= |
1141 uint AllocateArrayNode::size_of() const { return sizeof(*this); } | 1143 uint AllocateArrayNode::size_of() const { return sizeof(*this); } |
1142 | 1144 |
1143 Node* AllocateArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) { | 1145 Node* AllocateArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
1144 if (remove_dead_region(phase, can_reshape)) return this; | 1146 if (remove_dead_region(phase, can_reshape)) return this; |
1147 // Don't bother trying to transform a dead node | |
1148 if (in(0) && in(0)->is_top()) return NULL; | |
1145 | 1149 |
1146 const Type* type = phase->type(Ideal_length()); | 1150 const Type* type = phase->type(Ideal_length()); |
1147 if (type->isa_int() && type->is_int()->_hi < 0) { | 1151 if (type->isa_int() && type->is_int()->_hi < 0) { |
1148 if (can_reshape) { | 1152 if (can_reshape) { |
1149 PhaseIterGVN *igvn = phase->is_IterGVN(); | 1153 PhaseIterGVN *igvn = phase->is_IterGVN(); |
1520 //============================================================================= | 1524 //============================================================================= |
1521 Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) { | 1525 Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
1522 | 1526 |
1523 // perform any generic optimizations first (returns 'this' or NULL) | 1527 // perform any generic optimizations first (returns 'this' or NULL) |
1524 Node *result = SafePointNode::Ideal(phase, can_reshape); | 1528 Node *result = SafePointNode::Ideal(phase, can_reshape); |
1529 if (result != NULL) return result; | |
1530 // Don't bother trying to transform a dead node | |
1531 if (in(0) && in(0)->is_top()) return NULL; | |
1525 | 1532 |
1526 // Now see if we can optimize away this lock. We don't actually | 1533 // Now see if we can optimize away this lock. We don't actually |
1527 // remove the locking here, we simply set the _eliminate flag which | 1534 // remove the locking here, we simply set the _eliminate flag which |
1528 // prevents macro expansion from expanding the lock. Since we don't | 1535 // prevents macro expansion from expanding the lock. Since we don't |
1529 // modify the graph, the value returned from this function is the | 1536 // modify the graph, the value returned from this function is the |
1530 // one computed above. | 1537 // one computed above. |
1531 if (result == NULL && can_reshape && EliminateLocks && !is_eliminated()) { | 1538 if (can_reshape && EliminateLocks && (!is_eliminated() || is_coarsened())) { |
1532 // | 1539 // |
1533 // If we are locking an unescaped object, the lock/unlock is unnecessary | 1540 // If we are locking an unescaped object, the lock/unlock is unnecessary |
1534 // | 1541 // |
1535 ConnectionGraph *cgr = phase->C->congraph(); | 1542 ConnectionGraph *cgr = phase->C->congraph(); |
1536 PointsToNode::EscapeState es = PointsToNode::GlobalEscape; | 1543 PointsToNode::EscapeState es = PointsToNode::GlobalEscape; |
1537 if (cgr != NULL) | 1544 if (cgr != NULL) |
1538 es = cgr->escape_state(obj_node()); | 1545 es = cgr->escape_state(obj_node()); |
1539 if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) { | 1546 if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) { |
1540 // Mark it eliminated to update any counters | 1547 if (!is_eliminated()) { |
1541 this->set_eliminated(); | 1548 // Mark it eliminated to update any counters |
1549 this->set_eliminated(); | |
1550 } else { | |
1551 assert(is_coarsened(), "sanity"); | |
1552 // The lock could be marked eliminated by lock coarsening | |
1553 // code during first IGVN before EA. Clear coarsened flag | |
1554 // to eliminate all associated locks/unlocks. | |
1555 this->clear_coarsened(); | |
1556 } | |
1542 return result; | 1557 return result; |
1543 } | 1558 } |
1544 | 1559 |
1545 // | 1560 // |
1546 // Try lock coarsening | 1561 // Try lock coarsening |
1547 // | 1562 // |
1548 PhaseIterGVN* iter = phase->is_IterGVN(); | 1563 PhaseIterGVN* iter = phase->is_IterGVN(); |
1549 if (iter != NULL) { | 1564 if (iter != NULL && !is_eliminated()) { |
1550 | 1565 |
1551 GrowableArray<AbstractLockNode*> lock_ops; | 1566 GrowableArray<AbstractLockNode*> lock_ops; |
1552 | 1567 |
1553 Node *ctrl = next_control(in(0)); | 1568 Node *ctrl = next_control(in(0)); |
1554 | 1569 |
1600 | 1615 |
1601 // Mark it eliminated to update any counters | 1616 // Mark it eliminated to update any counters |
1602 lock->set_eliminated(); | 1617 lock->set_eliminated(); |
1603 lock->set_coarsened(); | 1618 lock->set_coarsened(); |
1604 } | 1619 } |
1605 } else if (result != NULL && ctrl->is_Region() && | 1620 } else if (ctrl->is_Region() && |
1606 iter->_worklist.member(ctrl)) { | 1621 iter->_worklist.member(ctrl)) { |
1607 // We weren't able to find any opportunities but the region this | 1622 // We weren't able to find any opportunities but the region this |
1608 // lock is control dependent on hasn't been processed yet so put | 1623 // lock is control dependent on hasn't been processed yet so put |
1609 // this lock back on the worklist so we can check again once any | 1624 // this lock back on the worklist so we can check again once any |
1610 // region simplification has occurred. | 1625 // region simplification has occurred. |
1621 | 1636 |
1622 //============================================================================= | 1637 //============================================================================= |
1623 Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) { | 1638 Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
1624 | 1639 |
1625 // perform any generic optimizations first (returns 'this' or NULL) | 1640 // perform any generic optimizations first (returns 'this' or NULL) |
1626 Node * result = SafePointNode::Ideal(phase, can_reshape); | 1641 Node *result = SafePointNode::Ideal(phase, can_reshape); |
1642 if (result != NULL) return result; | |
1643 // Don't bother trying to transform a dead node | |
1644 if (in(0) && in(0)->is_top()) return NULL; | |
1627 | 1645 |
1628 // Now see if we can optimize away this unlock. We don't actually | 1646 // Now see if we can optimize away this unlock. We don't actually |
1629 // remove the unlocking here, we simply set the _eliminate flag which | 1647 // remove the unlocking here, we simply set the _eliminate flag which |
1630 // prevents macro expansion from expanding the unlock. Since we don't | 1648 // prevents macro expansion from expanding the unlock. Since we don't |
1631 // modify the graph, the value returned from this function is the | 1649 // modify the graph, the value returned from this function is the |
1632 // one computed above. | 1650 // one computed above. |
1633 // Escape state is defined after Parse phase. | 1651 // Escape state is defined after Parse phase. |
1634 if (result == NULL && can_reshape && EliminateLocks && !is_eliminated()) { | 1652 if (can_reshape && EliminateLocks && (!is_eliminated() || is_coarsened())) { |
1635 // | 1653 // |
1636 // If we are unlocking an unescaped object, the lock/unlock is unnecessary. | 1654 // If we are unlocking an unescaped object, the lock/unlock is unnecessary. |
1637 // | 1655 // |
1638 ConnectionGraph *cgr = phase->C->congraph(); | 1656 ConnectionGraph *cgr = phase->C->congraph(); |
1639 PointsToNode::EscapeState es = PointsToNode::GlobalEscape; | 1657 PointsToNode::EscapeState es = PointsToNode::GlobalEscape; |
1640 if (cgr != NULL) | 1658 if (cgr != NULL) |
1641 es = cgr->escape_state(obj_node()); | 1659 es = cgr->escape_state(obj_node()); |
1642 if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) { | 1660 if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) { |
1643 // Mark it eliminated to update any counters | 1661 if (!is_eliminated()) { |
1644 this->set_eliminated(); | 1662 // Mark it eliminated to update any counters |
1663 this->set_eliminated(); | |
1664 } else { | |
1665 assert(is_coarsened(), "sanity"); | |
1666 // The lock could be marked eliminated by lock coarsening | |
1667 // code during first IGVN before EA. Clear coarsened flag | |
1668 // to eliminate all associated locks/unlocks. | |
1669 this->clear_coarsened(); | |
1670 } | |
1645 } | 1671 } |
1646 } | 1672 } |
1647 return result; | 1673 return result; |
1648 } | 1674 } |