6670459: Fix Node::dump() performance
Dump full ideal graph takes forever. Reviewed-by: never, rasbold
This commit is contained in:
parent
277c3322f6
commit
37b9a97e08
@ -1462,26 +1462,6 @@ void Node::dump_out() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------dump_nodes-------------------------------------
|
//------------------------------dump_nodes-------------------------------------
|
||||||
|
|
||||||
// Helper class for dump_nodes. Wraps an old and new VectorSet.
|
|
||||||
class OldNewVectorSet : public StackObj {
|
|
||||||
Arena* _node_arena;
|
|
||||||
VectorSet _old_vset, _new_vset;
|
|
||||||
VectorSet* select(Node* n) {
|
|
||||||
return _node_arena->contains(n) ? &_new_vset : &_old_vset;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
OldNewVectorSet(Arena* node_arena, ResourceArea* area) :
|
|
||||||
_node_arena(node_arena),
|
|
||||||
_old_vset(area), _new_vset(area) {}
|
|
||||||
|
|
||||||
void set(Node* n) { select(n)->set(n->_idx); }
|
|
||||||
bool test_set(Node* n) { return select(n)->test_set(n->_idx) != 0; }
|
|
||||||
bool test(Node* n) { return select(n)->test(n->_idx) != 0; }
|
|
||||||
void del(Node* n) { (*select(n)) >>= n->_idx; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static void dump_nodes(const Node* start, int d, bool only_ctrl) {
|
static void dump_nodes(const Node* start, int d, bool only_ctrl) {
|
||||||
Node* s = (Node*)start; // remove const
|
Node* s = (Node*)start; // remove const
|
||||||
if (NotANode(s)) return;
|
if (NotANode(s)) return;
|
||||||
@ -1489,75 +1469,41 @@ static void dump_nodes(const Node* start, int d, bool only_ctrl) {
|
|||||||
uint depth = (uint)ABS(d);
|
uint depth = (uint)ABS(d);
|
||||||
int direction = d;
|
int direction = d;
|
||||||
Compile* C = Compile::current();
|
Compile* C = Compile::current();
|
||||||
ResourceArea *area = Thread::current()->resource_area();
|
GrowableArray <Node *> nstack(C->unique());
|
||||||
Node_Stack stack(area, MIN2(depth, C->unique() >> 1));
|
|
||||||
OldNewVectorSet dumped(C->node_arena(), area);
|
|
||||||
OldNewVectorSet on_stack(C->node_arena(), area);
|
|
||||||
|
|
||||||
on_stack.set(s);
|
nstack.append(s);
|
||||||
stack.push(s, 0);
|
int begin = 0;
|
||||||
if (direction < 0) {
|
int end = 0;
|
||||||
dumped.set(s);
|
for(uint i = 0; i < depth; i++) {
|
||||||
s->dump();
|
end = nstack.length();
|
||||||
}
|
for(int j = begin; j < end; j++) {
|
||||||
|
Node* tp = nstack.at(j);
|
||||||
|
uint limit = direction > 0 ? tp->len() : tp->outcnt();
|
||||||
|
for(uint k = 0; k < limit; k++) {
|
||||||
|
Node* n = direction > 0 ? tp->in(k) : tp->raw_out(k);
|
||||||
|
|
||||||
// Do a depth first walk over edges
|
if (NotANode(n)) continue;
|
||||||
while (stack.is_nonempty()) {
|
// do not recurse through top or the root (would reach unrelated stuff)
|
||||||
Node* tp = stack.node();
|
if (n->is_Root() || n->is_top()) continue;
|
||||||
uint idx = stack.index();
|
if (only_ctrl && !n->is_CFG()) continue;
|
||||||
uint limit;
|
|
||||||
// Limit depth
|
|
||||||
if (stack.size() < depth) {
|
|
||||||
limit = direction > 0 ? tp->len() : tp->outcnt();
|
|
||||||
} else {
|
|
||||||
limit = 0; // reached depth limit.
|
|
||||||
}
|
|
||||||
if (idx >= limit) {
|
|
||||||
// no more arcs to visit
|
|
||||||
if (direction > 0 && !dumped.test_set(tp)) tp->dump();
|
|
||||||
on_stack.del(tp);
|
|
||||||
stack.pop();
|
|
||||||
} else {
|
|
||||||
// process the "idx"th arc
|
|
||||||
stack.set_index(idx + 1);
|
|
||||||
Node* n = direction > 0 ? tp->in(idx) : tp->raw_out(idx);
|
|
||||||
|
|
||||||
if (NotANode(n)) continue;
|
bool on_stack = nstack.contains(n);
|
||||||
// do not recurse through top or the root (would reach unrelated stuff)
|
if (!on_stack) {
|
||||||
if (n->is_Root() || n->is_top()) continue;
|
nstack.append(n);
|
||||||
if (only_ctrl && !n->is_CFG()) continue;
|
|
||||||
|
|
||||||
if (!on_stack.test(n)) { // forward arc
|
|
||||||
if (direction < 0 && !dumped.test_set(n)) n->dump();
|
|
||||||
stack.push(n, 0);
|
|
||||||
on_stack.set(n);
|
|
||||||
} else { // back or cross arc
|
|
||||||
// print loop if there are no phis or regions in the mix
|
|
||||||
bool found_loop_breaker = false;
|
|
||||||
int k;
|
|
||||||
for (k = stack.size() - 1; k >= 0; k--) {
|
|
||||||
Node* m = stack.node_at(k);
|
|
||||||
if (m->is_Phi() || m->is_Region() || m->is_Root() || m->is_Start()) {
|
|
||||||
found_loop_breaker = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (m == n) // Found loop head
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
assert(k >= 0, "n must be on stack");
|
|
||||||
|
|
||||||
if (!found_loop_breaker) {
|
|
||||||
tty->print("# %s LOOP FOUND:", only_ctrl ? "CONTROL" : "DATA");
|
|
||||||
for (int i = stack.size() - 1; i >= k; i--) {
|
|
||||||
Node* m = stack.node_at(i);
|
|
||||||
bool mnew = C->node_arena()->contains(m);
|
|
||||||
tty->print(" %s%d:%s", (mnew? "": "o"), m->_idx, m->Name());
|
|
||||||
if (i != 0) tty->print(direction > 0? " <-": " ->");
|
|
||||||
}
|
|
||||||
tty->cr();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
begin = end;
|
||||||
|
}
|
||||||
|
end = nstack.length();
|
||||||
|
if (direction > 0) {
|
||||||
|
for(int j = end-1; j >= 0; j--) {
|
||||||
|
nstack.at(j)->dump();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(int j = 0; j < end; j++) {
|
||||||
|
nstack.at(j)->dump();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1384,7 +1384,7 @@ public:
|
|||||||
_inode_top->indx = i;
|
_inode_top->indx = i;
|
||||||
}
|
}
|
||||||
uint size_max() const { return (uint)pointer_delta(_inode_max, _inodes, sizeof(INode)); } // Max size
|
uint size_max() const { return (uint)pointer_delta(_inode_max, _inodes, sizeof(INode)); } // Max size
|
||||||
uint size() const { return (uint)pointer_delta(_inode_top, _inodes, sizeof(INode)) + 1; } // Current size
|
uint size() const { return (uint)pointer_delta((_inode_top+1), _inodes, sizeof(INode)); } // Current size
|
||||||
bool is_nonempty() const { return (_inode_top >= _inodes); }
|
bool is_nonempty() const { return (_inode_top >= _inodes); }
|
||||||
bool is_empty() const { return (_inode_top < _inodes); }
|
bool is_empty() const { return (_inode_top < _inodes); }
|
||||||
void clear() { _inode_top = _inodes - 1; } // retain storage
|
void clear() { _inode_top = _inodes - 1; } // retain storage
|
||||||
|
Loading…
Reference in New Issue
Block a user