# HG changeset patch # User zmajo # Date 1421656360 -3600 # Node ID a665e19ca007f78ad92a4d9a221e57498471dda5 # Parent 01e4ca94fb0de1b3f455498ff1676759c263552a 8066312: Add new Node* Node::find_out(int opc) method. Summary: Added methods find_user_with() and has_user_with() for searching for a particular out type. Reviewed-by: kvn, jrose diff -r 01e4ca94fb0d -r a665e19ca007 hotspot/src/share/vm/opto/escape.cpp --- a/hotspot/src/share/vm/opto/escape.cpp Thu Jan 15 11:30:13 2015 +0100 +++ b/hotspot/src/share/vm/opto/escape.cpp Mon Jan 19 09:32:40 2015 +0100 @@ -2010,14 +2010,9 @@ 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 @@ } } 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 @@ 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 @@ 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"); } } diff -r 01e4ca94fb0d -r a665e19ca007 hotspot/src/share/vm/opto/ifg.cpp --- a/hotspot/src/share/vm/opto/ifg.cpp Thu Jan 15 11:30:13 2015 +0100 +++ b/hotspot/src/share/vm/opto/ifg.cpp Mon Jan 19 09:32:40 2015 +0100 @@ -535,12 +535,8 @@ // 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); diff -r 01e4ca94fb0d -r a665e19ca007 hotspot/src/share/vm/opto/macro.cpp --- a/hotspot/src/share/vm/opto/macro.cpp Thu Jan 15 11:30:13 2015 +0100 +++ b/hotspot/src/share/vm/opto/macro.cpp Mon Jan 19 09:32:40 2015 +0100 @@ -258,14 +258,7 @@ // 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(); diff -r 01e4ca94fb0d -r a665e19ca007 hotspot/src/share/vm/opto/memnode.cpp --- a/hotspot/src/share/vm/opto/memnode.cpp Thu Jan 15 11:30:13 2015 +0100 +++ b/hotspot/src/share/vm/opto/memnode.cpp Mon Jan 19 09:32:40 2015 +0100 @@ -2609,7 +2609,6 @@ 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; } diff -r 01e4ca94fb0d -r a665e19ca007 hotspot/src/share/vm/opto/node.cpp --- a/hotspot/src/share/vm/opto/node.cpp Thu Jan 15 11:30:13 2015 +0100 +++ b/hotspot/src/share/vm/opto/node.cpp Mon Jan 19 09:32:40 2015 +0100 @@ -881,6 +881,34 @@ 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 diff -r 01e4ca94fb0d -r a665e19ca007 hotspot/src/share/vm/opto/node.hpp --- a/hotspot/src/share/vm/opto/node.hpp Thu Jan 15 11:30:13 2015 +0100 +++ b/hotspot/src/share/vm/opto/node.hpp Mon Jan 19 09:32:40 2015 +0100 @@ -436,6 +436,13 @@ 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 @@ //----------------- Other Node Properties - // Generate class id for some ideal nodes to avoid virtual query - // methods is_(). - // 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_() 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. // - // 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). + // 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