mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-08 17:38:38 +00:00
8256858: C2: Devirtualize PhaseIterGVN-specific methods
Reviewed-by: kvn, thartmann
This commit is contained in:
parent
7b3d0958c0
commit
f55ae9595e
@ -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);
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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.
|
||||
@ -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 {
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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.
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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(); )
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -335,9 +335,6 @@ public:
|
||||
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; };
|
||||
|
||||
@ -369,18 +366,18 @@ public:
|
||||
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) {
|
||||
@ -391,8 +388,8 @@ public:
|
||||
|
||||
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
|
||||
@ -463,15 +460,13 @@ protected:
|
||||
// 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,
|
||||
@ -527,10 +522,6 @@ public:
|
||||
_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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user