comparison src/share/vm/opto/node.cpp @ 40:7c1f32ae4a20

6670459: Fix Node::dump() performance Summary: dump full ideal graph takes forever. Reviewed-by: never, rasbold
author kvn
date Thu, 06 Mar 2008 20:58:16 -0800
parents 953939ef62ab
children 99269dbf4ba8
comparison
equal deleted inserted replaced
39:76256d272075 40:7c1f32ae4a20
1460 } 1460 }
1461 tty->print("]] "); 1461 tty->print("]] ");
1462 } 1462 }
1463 1463
1464 //------------------------------dump_nodes------------------------------------- 1464 //------------------------------dump_nodes-------------------------------------
1465
1466 // Helper class for dump_nodes. Wraps an old and new VectorSet.
1467 class OldNewVectorSet : public StackObj {
1468 Arena* _node_arena;
1469 VectorSet _old_vset, _new_vset;
1470 VectorSet* select(Node* n) {
1471 return _node_arena->contains(n) ? &_new_vset : &_old_vset;
1472 }
1473 public:
1474 OldNewVectorSet(Arena* node_arena, ResourceArea* area) :
1475 _node_arena(node_arena),
1476 _old_vset(area), _new_vset(area) {}
1477
1478 void set(Node* n) { select(n)->set(n->_idx); }
1479 bool test_set(Node* n) { return select(n)->test_set(n->_idx) != 0; }
1480 bool test(Node* n) { return select(n)->test(n->_idx) != 0; }
1481 void del(Node* n) { (*select(n)) >>= n->_idx; }
1482 };
1483
1484
1485 static void dump_nodes(const Node* start, int d, bool only_ctrl) { 1465 static void dump_nodes(const Node* start, int d, bool only_ctrl) {
1486 Node* s = (Node*)start; // remove const 1466 Node* s = (Node*)start; // remove const
1487 if (NotANode(s)) return; 1467 if (NotANode(s)) return;
1488 1468
1489 uint depth = (uint)ABS(d); 1469 uint depth = (uint)ABS(d);
1490 int direction = d; 1470 int direction = d;
1491 Compile* C = Compile::current(); 1471 Compile* C = Compile::current();
1492 ResourceArea *area = Thread::current()->resource_area(); 1472 GrowableArray <Node *> nstack(C->unique());
1493 Node_Stack stack(area, MIN2(depth, C->unique() >> 1)); 1473
1494 OldNewVectorSet dumped(C->node_arena(), area); 1474 nstack.append(s);
1495 OldNewVectorSet on_stack(C->node_arena(), area); 1475 int begin = 0;
1496 1476 int end = 0;
1497 on_stack.set(s); 1477 for(uint i = 0; i < depth; i++) {
1498 stack.push(s, 0); 1478 end = nstack.length();
1499 if (direction < 0) { 1479 for(int j = begin; j < end; j++) {
1500 dumped.set(s); 1480 Node* tp = nstack.at(j);
1501 s->dump(); 1481 uint limit = direction > 0 ? tp->len() : tp->outcnt();
1502 } 1482 for(uint k = 0; k < limit; k++) {
1503 1483 Node* n = direction > 0 ? tp->in(k) : tp->raw_out(k);
1504 // Do a depth first walk over edges 1484
1505 while (stack.is_nonempty()) { 1485 if (NotANode(n)) continue;
1506 Node* tp = stack.node(); 1486 // do not recurse through top or the root (would reach unrelated stuff)
1507 uint idx = stack.index(); 1487 if (n->is_Root() || n->is_top()) continue;
1508 uint limit; 1488 if (only_ctrl && !n->is_CFG()) continue;
1509 // Limit depth 1489
1510 if (stack.size() < depth) { 1490 bool on_stack = nstack.contains(n);
1511 limit = direction > 0 ? tp->len() : tp->outcnt(); 1491 if (!on_stack) {
1512 } else { 1492 nstack.append(n);
1513 limit = 0; // reached depth limit.
1514 }
1515 if (idx >= limit) {
1516 // no more arcs to visit
1517 if (direction > 0 && !dumped.test_set(tp)) tp->dump();
1518 on_stack.del(tp);
1519 stack.pop();
1520 } else {
1521 // process the "idx"th arc
1522 stack.set_index(idx + 1);
1523 Node* n = direction > 0 ? tp->in(idx) : tp->raw_out(idx);
1524
1525 if (NotANode(n)) continue;
1526 // do not recurse through top or the root (would reach unrelated stuff)
1527 if (n->is_Root() || n->is_top()) continue;
1528 if (only_ctrl && !n->is_CFG()) continue;
1529
1530 if (!on_stack.test(n)) { // forward arc
1531 if (direction < 0 && !dumped.test_set(n)) n->dump();
1532 stack.push(n, 0);
1533 on_stack.set(n);
1534 } else { // back or cross arc
1535 // print loop if there are no phis or regions in the mix
1536 bool found_loop_breaker = false;
1537 int k;
1538 for (k = stack.size() - 1; k >= 0; k--) {
1539 Node* m = stack.node_at(k);
1540 if (m->is_Phi() || m->is_Region() || m->is_Root() || m->is_Start()) {
1541 found_loop_breaker = true;
1542 break;
1543 }
1544 if (m == n) // Found loop head
1545 break;
1546 }
1547 assert(k >= 0, "n must be on stack");
1548
1549 if (!found_loop_breaker) {
1550 tty->print("# %s LOOP FOUND:", only_ctrl ? "CONTROL" : "DATA");
1551 for (int i = stack.size() - 1; i >= k; i--) {
1552 Node* m = stack.node_at(i);
1553 bool mnew = C->node_arena()->contains(m);
1554 tty->print(" %s%d:%s", (mnew? "": "o"), m->_idx, m->Name());
1555 if (i != 0) tty->print(direction > 0? " <-": " ->");
1556 }
1557 tty->cr();
1558 } 1493 }
1559 } 1494 }
1495 }
1496 begin = end;
1497 }
1498 end = nstack.length();
1499 if (direction > 0) {
1500 for(int j = end-1; j >= 0; j--) {
1501 nstack.at(j)->dump();
1502 }
1503 } else {
1504 for(int j = 0; j < end; j++) {
1505 nstack.at(j)->dump();
1560 } 1506 }
1561 } 1507 }
1562 } 1508 }
1563 1509
1564 //------------------------------dump------------------------------------------- 1510 //------------------------------dump-------------------------------------------