aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorkvn <none@none>2008-03-06 20:58:16 -0800
committerkvn <none@none>2008-03-06 20:58:16 -0800
commit002a5e177d5e10ac07cee191cda4a9b2f72a2bf6 (patch)
tree48f47da9630165d3938b6f8e6875a95d80b8424b /src
parent91b01fefb353477287adba351ba024ac764e7484 (diff)
6670459: Fix Node::dump() performance
Summary: dump full ideal graph takes forever. Reviewed-by: never, rasbold
Diffstat (limited to 'src')
-rw-r--r--src/share/vm/opto/node.cpp118
-rw-r--r--src/share/vm/opto/node.hpp2
2 files changed, 33 insertions, 87 deletions
diff --git a/src/share/vm/opto/node.cpp b/src/share/vm/opto/node.cpp
index 14e112e21..f361ef8b8 100644
--- a/src/share/vm/opto/node.cpp
+++ b/src/share/vm/opto/node.cpp
@@ -1462,26 +1462,6 @@ void Node::dump_out() const {
}
//------------------------------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) {
Node* s = (Node*)start; // remove const
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);
int direction = d;
Compile* C = Compile::current();
- ResourceArea *area = Thread::current()->resource_area();
- 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);
- stack.push(s, 0);
- if (direction < 0) {
- dumped.set(s);
- s->dump();
- }
-
- // Do a depth first walk over edges
- while (stack.is_nonempty()) {
- Node* tp = stack.node();
- uint idx = stack.index();
- 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;
- // do not recurse through top or the root (would reach unrelated stuff)
- if (n->is_Root() || n->is_top()) continue;
- 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();
+ GrowableArray <Node *> nstack(C->unique());
+
+ nstack.append(s);
+ int begin = 0;
+ int end = 0;
+ for(uint i = 0; i < depth; i++) {
+ 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);
+
+ if (NotANode(n)) continue;
+ // do not recurse through top or the root (would reach unrelated stuff)
+ if (n->is_Root() || n->is_top()) continue;
+ if (only_ctrl && !n->is_CFG()) continue;
+
+ bool on_stack = nstack.contains(n);
+ if (!on_stack) {
+ nstack.append(n);
}
}
}
+ 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();
+ }
}
}
diff --git a/src/share/vm/opto/node.hpp b/src/share/vm/opto/node.hpp
index 8066da703..881de4d21 100644
--- a/src/share/vm/opto/node.hpp
+++ b/src/share/vm/opto/node.hpp
@@ -1384,7 +1384,7 @@ public:
_inode_top->indx = i;
}
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_empty() const { return (_inode_top < _inodes); }
void clear() { _inode_top = _inodes - 1; } // retain storage