Mercurial > hg > truffle
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------------------------------------------- |