mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-14 20:35:09 +00:00
8066312: Add new Node* Node::find_out(int opc) method
Added methods find_user_with() and has_user_with() for searching for a particular out type. Reviewed-by: kvn, jrose
This commit is contained in:
parent
9d6b3c1d71
commit
eb5be4c2fe
@ -2010,14 +2010,9 @@ bool ConnectionGraph::is_oop_field(Node* n, int offset, bool* unsafe) {
|
||||
bt = field->layout_type();
|
||||
} else {
|
||||
// Check for unsafe oop field access
|
||||
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
|
||||
int opcode = n->fast_out(i)->Opcode();
|
||||
if (opcode == Op_StoreP || opcode == Op_LoadP ||
|
||||
opcode == Op_StoreN || opcode == Op_LoadN) {
|
||||
bt = T_OBJECT;
|
||||
(*unsafe) = true;
|
||||
break;
|
||||
}
|
||||
if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN)) {
|
||||
bt = T_OBJECT;
|
||||
(*unsafe) = true;
|
||||
}
|
||||
}
|
||||
} else if (adr_type->isa_aryptr()) {
|
||||
@ -2031,13 +2026,8 @@ bool ConnectionGraph::is_oop_field(Node* n, int offset, bool* unsafe) {
|
||||
}
|
||||
} else if (adr_type->isa_rawptr() || adr_type->isa_klassptr()) {
|
||||
// Allocation initialization, ThreadLocal field access, unsafe access
|
||||
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
|
||||
int opcode = n->fast_out(i)->Opcode();
|
||||
if (opcode == Op_StoreP || opcode == Op_LoadP ||
|
||||
opcode == Op_StoreN || opcode == Op_LoadN) {
|
||||
bt = T_OBJECT;
|
||||
break;
|
||||
}
|
||||
if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN)) {
|
||||
bt = T_OBJECT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3092,13 +3082,7 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist)
|
||||
continue;
|
||||
} else if (n->Opcode() == Op_EncodeISOArray) {
|
||||
// get the memory projection
|
||||
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
|
||||
Node *use = n->fast_out(i);
|
||||
if (use->Opcode() == Op_SCMemProj) {
|
||||
n = use;
|
||||
break;
|
||||
}
|
||||
}
|
||||
n = n->find_out_with(Op_SCMemProj);
|
||||
assert(n->Opcode() == Op_SCMemProj, "memory projection required");
|
||||
} else {
|
||||
assert(n->is_Mem(), "memory node required.");
|
||||
@ -3122,13 +3106,7 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist)
|
||||
continue; // don't push users
|
||||
} else if (n->is_LoadStore()) {
|
||||
// get the memory projection
|
||||
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
|
||||
Node *use = n->fast_out(i);
|
||||
if (use->Opcode() == Op_SCMemProj) {
|
||||
n = use;
|
||||
break;
|
||||
}
|
||||
}
|
||||
n = n->find_out_with(Op_SCMemProj);
|
||||
assert(n->Opcode() == Op_SCMemProj, "memory projection required");
|
||||
}
|
||||
}
|
||||
|
||||
@ -535,12 +535,8 @@ bool PhaseChaitin::remove_node_if_not_used(Block* b, uint location, Node* n, uin
|
||||
// The method add_input_to_liveout() keeps such nodes alive (put them on liveout list)
|
||||
// when it sees SCMemProj node in a block. Unfortunately SCMemProj node could be placed
|
||||
// in block in such order that KILL MachProj nodes are processed first.
|
||||
uint cnt = def->outcnt();
|
||||
for (uint i = 0; i < cnt; i++) {
|
||||
Node* proj = def->raw_out(i);
|
||||
if (proj->Opcode() == Op_SCMemProj) {
|
||||
return false;
|
||||
}
|
||||
if (def->has_out_with(Op_SCMemProj)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
b->remove_node(location);
|
||||
|
||||
@ -258,14 +258,7 @@ void PhaseMacroExpand::eliminate_card_mark(Node* p2x) {
|
||||
// Search for CastP2X->Xor->URShift->Cmp path which
|
||||
// checks if the store done to a different from the value's region.
|
||||
// And replace Cmp with #0 (false) to collapse G1 post barrier.
|
||||
Node* xorx = NULL;
|
||||
for (DUIterator_Fast imax, i = p2x->fast_outs(imax); i < imax; i++) {
|
||||
Node* u = p2x->fast_out(i);
|
||||
if (u->Opcode() == Op_XorX) {
|
||||
xorx = u;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Node* xorx = p2x->find_out_with(Op_XorX);
|
||||
assert(xorx != NULL, "missing G1 post barrier");
|
||||
Node* shift = xorx->unique_out();
|
||||
Node* cmpx = shift->unique_out();
|
||||
|
||||
@ -2609,7 +2609,6 @@ bool StoreNode::value_never_loaded( PhaseTransform *phase) const {
|
||||
return false; // if not a distinct instance, there may be aliases of the address
|
||||
for (DUIterator_Fast imax, i = adr->fast_outs(imax); i < imax; i++) {
|
||||
Node *use = adr->fast_out(i);
|
||||
int opc = use->Opcode();
|
||||
if (use->is_Load() || use->is_LoadStore()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -881,6 +881,34 @@ Node* Node::uncast() const {
|
||||
return (Node*) this;
|
||||
}
|
||||
|
||||
// Find out of current node that matches opcode.
|
||||
Node* Node::find_out_with(int opcode) {
|
||||
for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
|
||||
Node* use = fast_out(i);
|
||||
if (use->Opcode() == opcode) {
|
||||
return use;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Return true if the current node has an out that matches opcode.
|
||||
bool Node::has_out_with(int opcode) {
|
||||
return (find_out_with(opcode) != NULL);
|
||||
}
|
||||
|
||||
// Return true if the current node has an out that matches any of the opcodes.
|
||||
bool Node::has_out_with(int opcode1, int opcode2, int opcode3, int opcode4) {
|
||||
for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
|
||||
int opcode = fast_out(i)->Opcode();
|
||||
if (opcode == opcode1 || opcode == opcode2 || opcode == opcode3 || opcode == opcode4) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------uncast_helper-------------------------------------
|
||||
Node* Node::uncast_helper(const Node* p) {
|
||||
#ifdef ASSERT
|
||||
|
||||
@ -436,6 +436,13 @@ protected:
|
||||
return (this->uncast() == n->uncast());
|
||||
}
|
||||
|
||||
// Find out of current node that matches opcode.
|
||||
Node* find_out_with(int opcode);
|
||||
// Return true if the current node has an out that matches opcode.
|
||||
bool has_out_with(int opcode);
|
||||
// Return true if the current node has an out that matches any of the opcodes.
|
||||
bool has_out_with(int opcode1, int opcode2, int opcode3, int opcode4);
|
||||
|
||||
private:
|
||||
static Node* uncast_helper(const Node* n);
|
||||
|
||||
@ -507,18 +514,25 @@ public:
|
||||
|
||||
//----------------- Other Node Properties
|
||||
|
||||
// Generate class id for some ideal nodes to avoid virtual query
|
||||
// methods is_<Node>().
|
||||
// Class id is the set of bits corresponded to the node class and all its
|
||||
// super classes so that queries for super classes are also valid.
|
||||
// Subclasses of the same super class have different assigned bit
|
||||
// (the third parameter in the macro DEFINE_CLASS_ID).
|
||||
// Classes with deeper hierarchy are declared first.
|
||||
// Classes with the same hierarchy depth are sorted by usage frequency.
|
||||
// Generate class IDs for (some) ideal nodes so that it is possible to determine
|
||||
// the type of a node using a non-virtual method call (the method is_<Node>() below).
|
||||
//
|
||||
// The query method masks the bits to cut off bits of subclasses
|
||||
// and then compare the result with the class id
|
||||
// (see the macro DEFINE_CLASS_QUERY below).
|
||||
// A class ID of an ideal node is a set of bits. In a class ID, a single bit determines
|
||||
// the type of the node the ID represents; another subset of an ID's bits are reserved
|
||||
// for the superclasses of the node represented by the ID.
|
||||
//
|
||||
// By design, if A is a supertype of B, A.is_B() returns true and B.is_A()
|
||||
// returns false. A.is_A() returns true.
|
||||
//
|
||||
// If two classes, A and B, have the same superclass, a different bit of A's class id
|
||||
// is reserved for A's type than for B's type. That bit is specified by the third
|
||||
// parameter in the macro DEFINE_CLASS_ID.
|
||||
//
|
||||
// By convention, classes with deeper hierarchy are declared first. Moreover,
|
||||
// classes with the same hierarchy depth are sorted by usage frequency.
|
||||
//
|
||||
// The query method masks the bits to cut off bits of subclasses and then compares
|
||||
// the result with the class id (see the macro DEFINE_CLASS_QUERY below).
|
||||
//
|
||||
// Class_MachCall=30, ClassMask_MachCall=31
|
||||
// 12 8 4 0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user