Skip to content

Commit

Permalink
8256858: C2: Devirtualize PhaseIterGVN-specific methods
Browse files Browse the repository at this point in the history
Reviewed-by: kvn, thartmann
  • Loading branch information
cl4es committed Nov 24, 2020
1 parent 7b3d095 commit f55ae95
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 44 deletions.
4 changes: 2 additions & 2 deletions src/hotspot/share/opto/addnode.cpp
Expand Up @@ -191,7 +191,7 @@ Node *AddNode::Ideal(PhaseGVN *phase, bool can_reshape) {
set_req(1, addx);
set_req(2, a22);
progress = this;
PhaseIterGVN *igvn = phase->is_IterGVN();
PhaseIterGVN* igvn = phase->is_IterGVN();
if (add2->outcnt() == 0 && igvn) {
// add disconnected.
igvn->_worklist.push(add2);
Expand Down Expand Up @@ -627,7 +627,7 @@ Node *AddPNode::Ideal(PhaseGVN *phase, bool can_reshape) {
if( t22->singleton() && (t22 != Type::TOP) ) { // Right input is an add of a constant?
set_req(Address, phase->transform(new AddPNode(in(Base),in(Address),add->in(1))));
set_req(Offset, add->in(2));
PhaseIterGVN *igvn = phase->is_IterGVN();
PhaseIterGVN* igvn = phase->is_IterGVN();
if (add->outcnt() == 0 && igvn) {
// add disconnected.
igvn->_worklist.push((Node*)add);
Expand Down
21 changes: 13 additions & 8 deletions src/hotspot/share/opto/memnode.cpp
Expand Up @@ -307,7 +307,7 @@ Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) {
(cmp != NULL && igvn->_worklist.member(cmp)) ) {
// This control path may be dead.
// Delay this memory node transformation until the control is processed.
phase->is_IterGVN()->_worklist.push(this);
igvn->_worklist.push(this);
return NodeSentinel; // caller will return NULL
}
}
Expand All @@ -319,7 +319,7 @@ Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) {
if (can_reshape && igvn != NULL && igvn->_worklist.member(mem)) {
// This memory slice may be dead.
// Delay this mem node transformation until the memory is processed.
phase->is_IterGVN()->_worklist.push(this);
igvn->_worklist.push(this);
return NodeSentinel; // caller will return NULL
}

Expand Down Expand Up @@ -350,7 +350,7 @@ Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) {
(igvn->_worklist.size() > 0 && t_adr != adr_type())) ) {
// The address's base and type may change when the address is processed.
// Delay this mem node transformation until the address is processed.
phase->is_IterGVN()->_worklist.push(this);
igvn->_worklist.push(this);
return NodeSentinel; // caller will return NULL
}

Expand Down Expand Up @@ -1721,7 +1721,7 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) {
PhaseIterGVN *igvn = phase->is_IterGVN();
if (igvn != NULL && igvn->_worklist.member(opt_mem)) {
// Delay this transformation until memory Phi is processed.
phase->is_IterGVN()->_worklist.push(this);
igvn->_worklist.push(this);
return NULL;
}
// Split instance field load through Phi.
Expand Down Expand Up @@ -2632,7 +2632,9 @@ Node *StoreNode::Ideal(PhaseGVN *phase, bool can_reshape) {
if (st->in(MemNode::Address)->eqv_uncast(address) &&
st->as_Store()->memory_size() <= this->memory_size()) {
Node* use = st->raw_out(0);
phase->igvn_rehash_node_delayed(use);
if (phase->is_IterGVN()) {
phase->is_IterGVN()->rehash_node_delayed(use);
}
if (can_reshape) {
use->set_req_X(MemNode::Memory, st->in(MemNode::Memory), phase->is_IterGVN());
} else {
Expand Down Expand Up @@ -2746,14 +2748,14 @@ Node* StoreNode::Identity(PhaseGVN* phase) {
}
}

if (result != this && phase->is_IterGVN() != NULL) {
PhaseIterGVN* igvn = phase->is_IterGVN();
if (result != this && igvn != NULL) {
MemBarNode* trailing = trailing_membar();
if (trailing != NULL) {
#ifdef ASSERT
const TypeOopPtr* t_oop = phase->type(in(Address))->isa_oopptr();
assert(t_oop == NULL || t_oop->is_known_instance_field(), "only for non escaping objects");
#endif
PhaseIterGVN* igvn = phase->is_IterGVN();
trailing->remove(igvn);
}
}
Expand Down Expand Up @@ -3951,7 +3953,10 @@ Node* InitializeNode::capture_store(StoreNode* st, intptr_t start,
// if it redundantly stored the same value (or zero to fresh memory).

// In any case, wire it in:
phase->igvn_rehash_node_delayed(this);
PhaseIterGVN* igvn = phase->is_IterGVN();
if (igvn) {
igvn->rehash_node_delayed(this);
}
set_req(i, new_st);

// The caller may now kill the old guy.
Expand Down
5 changes: 4 additions & 1 deletion src/hotspot/share/opto/mulnode.cpp
Expand Up @@ -654,7 +654,10 @@ static int maskShiftAmount(PhaseGVN *phase, Node *shiftNode, int nBits) {

if (shift != maskedShift) {
shiftNode->set_req(2, phase->intcon(maskedShift)); // Replace shift count with masked value.
phase->igvn_rehash_node_delayed(shiftNode);
PhaseIterGVN* igvn = phase->is_IterGVN();
if (igvn) {
igvn->rehash_node_delayed(shiftNode);
}
}

return maskedShift;
Expand Down
25 changes: 14 additions & 11 deletions src/hotspot/share/opto/phaseX.cpp
Expand Up @@ -690,14 +690,15 @@ void PhaseTransform::dump_nodes_and_types_recur( const Node *n, uint depth, bool
//=============================================================================
//------------------------------PhaseValues------------------------------------
// Set minimum table size to "255"
PhaseValues::PhaseValues( Arena *arena, uint est_max_size ) : PhaseTransform(arena, GVN), _table(arena, est_max_size) {
PhaseValues::PhaseValues( Arena *arena, uint est_max_size )
: PhaseTransform(arena, GVN), _table(arena, est_max_size), _iterGVN(false) {
NOT_PRODUCT( clear_new_values(); )
}

//------------------------------PhaseValues------------------------------------
// Set minimum table size to "255"
PhaseValues::PhaseValues( PhaseValues *ptv ) : PhaseTransform( ptv, GVN ),
_table(&ptv->_table) {
PhaseValues::PhaseValues(PhaseValues* ptv)
: PhaseTransform(ptv, GVN), _table(&ptv->_table), _iterGVN(false) {
NOT_PRODUCT( clear_new_values(); )
}

Expand Down Expand Up @@ -932,24 +933,26 @@ void PhaseGVN::dead_loop_check( Node *n ) {
//=============================================================================
//------------------------------PhaseIterGVN-----------------------------------
// Initialize with previous PhaseIterGVN info; used by PhaseCCP
PhaseIterGVN::PhaseIterGVN( PhaseIterGVN *igvn ) : PhaseGVN(igvn),
_delay_transform(igvn->_delay_transform),
_stack( igvn->_stack ),
_worklist( igvn->_worklist )
PhaseIterGVN::PhaseIterGVN(PhaseIterGVN* igvn) : PhaseGVN(igvn),
_delay_transform(igvn->_delay_transform),
_stack(igvn->_stack ),
_worklist(igvn->_worklist)
{
_iterGVN = true;
}

//------------------------------PhaseIterGVN-----------------------------------
// Initialize with previous PhaseGVN info from Parser
PhaseIterGVN::PhaseIterGVN( PhaseGVN *gvn ) : PhaseGVN(gvn),
_delay_transform(false),
PhaseIterGVN::PhaseIterGVN(PhaseGVN* gvn) : PhaseGVN(gvn),
_delay_transform(false),
// TODO: Before incremental inlining it was allocated only once and it was fine. Now that
// the constructor is used in incremental inlining, this consumes too much memory:
// _stack(C->live_nodes() >> 1),
// So, as a band-aid, we replace this by:
_stack(C->comp_arena(), 32),
_worklist(*C->for_igvn())
_stack(C->comp_arena(), 32),
_worklist(*C->for_igvn())
{
_iterGVN = true;
uint max;

// Dead nodes in the hash table inherited from GVN were not treated as
Expand Down
35 changes: 13 additions & 22 deletions src/hotspot/share/opto/phaseX.hpp
Expand Up @@ -335,9 +335,6 @@ class PhaseTransform : public Phase {
const Type* limit_type) const
{ ShouldNotCallThis(); return NULL; }

// Delayed node rehash if this is an IGVN phase
virtual void igvn_rehash_node_delayed(Node* n) {}

// true if CFG node d dominates CFG node n
virtual bool is_dominator(Node *d, Node *n) { fatal("unimplemented for this pass"); return false; };

Expand Down Expand Up @@ -369,18 +366,18 @@ class PhaseTransform : public Phase {
class PhaseValues : public PhaseTransform {
protected:
NodeHash _table; // Hash table for value-numbering

bool _iterGVN;
public:
PhaseValues( Arena *arena, uint est_max_size );
PhaseValues( PhaseValues *pt );
NOT_PRODUCT( ~PhaseValues(); )
virtual PhaseIterGVN *is_IterGVN() { return 0; }
PhaseValues(Arena* arena, uint est_max_size);
PhaseValues(PhaseValues* pt);
NOT_PRODUCT(~PhaseValues();)
PhaseIterGVN* is_IterGVN() { return (_iterGVN) ? (PhaseIterGVN*)this : NULL; }

// Some Ideal and other transforms delete --> modify --> insert values
bool hash_delete(Node *n) { return _table.hash_delete(n); }
void hash_insert(Node *n) { _table.hash_insert(n); }
Node *hash_find_insert(Node *n){ return _table.hash_find_insert(n); }
Node *hash_find(const Node *n) { return _table.hash_find(n); }
bool hash_delete(Node* n) { return _table.hash_delete(n); }
void hash_insert(Node* n) { _table.hash_insert(n); }
Node* hash_find_insert(Node* n){ return _table.hash_find_insert(n); }
Node* hash_find(const Node* n) { return _table.hash_find(n); }

// Used after parsing to eliminate values that are no longer in program
void remove_useless_nodes(VectorSet &useful) {
Expand All @@ -391,8 +388,8 @@ class PhaseValues : public PhaseTransform {

virtual ConNode* uncached_makecon(const Type* t); // override from PhaseTransform

virtual const Type* saturate(const Type* new_type, const Type* old_type,
const Type* limit_type) const
const Type* saturate(const Type* new_type, const Type* old_type,
const Type* limit_type) const
{ return new_type; }

#ifndef PRODUCT
Expand Down Expand Up @@ -463,15 +460,13 @@ class PhaseIterGVN : public PhaseGVN {
// improvement, such that it would take many (>>10) steps to reach 2**32.

public:
PhaseIterGVN( PhaseIterGVN *igvn ); // Used by CCP constructor
PhaseIterGVN( PhaseGVN *gvn ); // Used after Parser
PhaseIterGVN(PhaseIterGVN* igvn); // Used by CCP constructor
PhaseIterGVN(PhaseGVN* gvn); // Used after Parser

// Idealize new Node 'n' with respect to its inputs and its value
virtual Node *transform( Node *a_node );
virtual void record_for_igvn(Node *n) { }

virtual PhaseIterGVN *is_IterGVN() { return this; }

Unique_Node_List _worklist; // Iterative worklist

// Given def-use info and an initial worklist, apply Node::Ideal,
Expand Down Expand Up @@ -527,10 +522,6 @@ class PhaseIterGVN : public PhaseGVN {
_worklist.push(n);
}

void igvn_rehash_node_delayed(Node* n) {
rehash_node_delayed(n);
}

// Replace ith edge of "n" with "in"
void replace_input_of(Node* n, int i, Node* in) {
rehash_node_delayed(n);
Expand Down

0 comments on commit f55ae95

Please sign in to comment.