mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-14 20:35:09 +00:00
8213381: Hook to allow GC to inject Node::Ideal() calls
Reviewed-by: kvn, eosterlund, roland
This commit is contained in:
parent
f7fc720c9c
commit
9ba72c0c2c
@ -245,6 +245,9 @@ public:
|
||||
Node*& fast_oop_ctrl, Node*& fast_oop_rawmem,
|
||||
intx prefetch_lines) const;
|
||||
|
||||
virtual Node* ideal_node(PhaseGVN* phase, Node* n, bool can_reshape) const { return NULL; }
|
||||
virtual Node* identity_node(PhaseGVN* phase, Node* n) const { return n; }
|
||||
|
||||
// These are general helper methods used by C2
|
||||
enum ArrayCopyPhase {
|
||||
Parsing,
|
||||
|
||||
@ -1750,7 +1750,7 @@ void IdealLoopTree::split_fall_in( PhaseIdealLoop *phase, int fall_in_cnt ) {
|
||||
// disappear it. In JavaGrande I have a case where this useless
|
||||
// Phi is the loop limit and prevents recognizing a CountedLoop
|
||||
// which in turn prevents removing an empty loop.
|
||||
Node *id_old_phi = old_phi->Identity( &igvn );
|
||||
Node *id_old_phi = igvn.apply_identity(old_phi);
|
||||
if( id_old_phi != old_phi ) { // Found a simple identity?
|
||||
// Note that I cannot call 'replace_node' here, because
|
||||
// that will yank the edge from old_phi to the Region and
|
||||
|
||||
@ -129,7 +129,7 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
|
||||
// otherwise it will be not updated during igvn->transform since
|
||||
// igvn->type(x) is set to x->Value() already.
|
||||
x->raise_bottom_type(t);
|
||||
Node *y = x->Identity(&_igvn);
|
||||
Node *y = _igvn.apply_identity(x);
|
||||
if (y != x) {
|
||||
wins++;
|
||||
x = y;
|
||||
|
||||
@ -1404,7 +1404,7 @@ Node *LoadNode::split_through_phi(PhaseGVN *phase) {
|
||||
|
||||
// Do nothing here if Identity will find a value
|
||||
// (to avoid infinite chain of value phis generation).
|
||||
if (!phase->eqv(this, this->Identity(phase)))
|
||||
if (!phase->eqv(this, phase->apply_identity(this)))
|
||||
return NULL;
|
||||
|
||||
// Select Region to split through.
|
||||
@ -1494,7 +1494,7 @@ Node *LoadNode::split_through_phi(PhaseGVN *phase) {
|
||||
// otherwise it will be not updated during igvn->transform since
|
||||
// igvn->type(x) is set to x->Value() already.
|
||||
x->raise_bottom_type(t);
|
||||
Node *y = x->Identity(igvn);
|
||||
Node *y = igvn->apply_identity(x);
|
||||
if (y != x) {
|
||||
x = y;
|
||||
} else {
|
||||
|
||||
@ -769,6 +769,22 @@ ConNode* PhaseTransform::zerocon(BasicType bt) {
|
||||
|
||||
|
||||
//=============================================================================
|
||||
Node* PhaseGVN::apply_ideal(Node* k, bool can_reshape) {
|
||||
Node* i = BarrierSet::barrier_set()->barrier_set_c2()->ideal_node(this, k, can_reshape);
|
||||
if (i == NULL) {
|
||||
i = k->Ideal(this, can_reshape);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
Node* PhaseGVN::apply_identity(Node* k) {
|
||||
Node* i = BarrierSet::barrier_set()->barrier_set_c2()->identity_node(this, k);
|
||||
if (i == k) {
|
||||
i = k->Identity(this);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
//------------------------------transform--------------------------------------
|
||||
// Return a node which computes the same function as this node, but in a
|
||||
// faster or cheaper fashion.
|
||||
@ -786,7 +802,7 @@ Node *PhaseGVN::transform_no_reclaim( Node *n ) {
|
||||
Node *k = n;
|
||||
NOT_PRODUCT( uint loop_count = 0; )
|
||||
while( 1 ) {
|
||||
Node *i = k->Ideal(this, /*can_reshape=*/false);
|
||||
Node *i = apply_ideal(k, /*can_reshape=*/false);
|
||||
if( !i ) break;
|
||||
assert( i->_idx >= k->_idx, "Idealize should return new nodes, use Identity to return old nodes" );
|
||||
k = i;
|
||||
@ -823,7 +839,7 @@ Node *PhaseGVN::transform_no_reclaim( Node *n ) {
|
||||
}
|
||||
|
||||
// Now check for Identities
|
||||
Node *i = k->Identity(this); // Look for a nearby replacement
|
||||
Node *i = apply_identity(k); // Look for a nearby replacement
|
||||
if( i != k ) { // Found? Return replacement!
|
||||
NOT_PRODUCT( set_progress(); )
|
||||
return i;
|
||||
@ -1213,7 +1229,7 @@ Node *PhaseIterGVN::transform_old(Node* n) {
|
||||
DEBUG_ONLY(dead_loop_check(k);)
|
||||
DEBUG_ONLY(bool is_new = (k->outcnt() == 0);)
|
||||
C->remove_modified_node(k);
|
||||
Node* i = k->Ideal(this, /*can_reshape=*/true);
|
||||
Node* i = apply_ideal(k, /*can_reshape=*/true);
|
||||
assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes");
|
||||
#ifndef PRODUCT
|
||||
verify_step(k);
|
||||
@ -1255,7 +1271,7 @@ Node *PhaseIterGVN::transform_old(Node* n) {
|
||||
// Try idealizing again
|
||||
DEBUG_ONLY(is_new = (k->outcnt() == 0);)
|
||||
C->remove_modified_node(k);
|
||||
i = k->Ideal(this, /*can_reshape=*/true);
|
||||
i = apply_ideal(k, /*can_reshape=*/true);
|
||||
assert(i != k || is_new || (i->outcnt() > 0), "don't return dead nodes");
|
||||
#ifndef PRODUCT
|
||||
verify_step(k);
|
||||
@ -1297,7 +1313,7 @@ Node *PhaseIterGVN::transform_old(Node* n) {
|
||||
}
|
||||
|
||||
// Now check for Identities
|
||||
i = k->Identity(this); // Look for a nearby replacement
|
||||
i = apply_identity(k); // Look for a nearby replacement
|
||||
if (i != k) { // Found? Return replacement!
|
||||
NOT_PRODUCT(set_progress();)
|
||||
add_users_to_worklist(k);
|
||||
|
||||
@ -425,6 +425,12 @@ public:
|
||||
|
||||
bool is_dominator(Node *d, Node *n) { return is_dominator_helper(d, n, true); }
|
||||
|
||||
// Helper to call Node::Ideal() and BarrierSetC2::ideal_node().
|
||||
Node* apply_ideal(Node* i, bool can_reshape);
|
||||
|
||||
// Helper to call Node::Identity() and BarrierSetC2::identity_node().
|
||||
Node* apply_identity(Node* n);
|
||||
|
||||
// Check for a simple dead loop when a data node references itself.
|
||||
DEBUG_ONLY(void dead_loop_check(Node *n);)
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user