OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 } | 126 } |
127 postorder->Add(this); | 127 postorder->Add(this); |
128 } | 128 } |
129 | 129 |
130 | 130 |
131 void BranchNode::Traverse(bool mark, | 131 void BranchNode::Traverse(bool mark, |
132 ZoneList<Node*>* preorder, | 132 ZoneList<Node*>* preorder, |
133 ZoneList<Node*>* postorder) { | 133 ZoneList<Node*>* postorder) { |
134 ASSERT(successor0_ != NULL && successor1_ != NULL); | 134 ASSERT(successor0_ != NULL && successor1_ != NULL); |
135 preorder->Add(this); | 135 preorder->Add(this); |
| 136 if (!successor1_->IsMarkedWith(mark)) { |
| 137 successor1_->MarkWith(mark); |
| 138 successor1_->Traverse(mark, preorder, postorder); |
| 139 } |
136 if (!successor0_->IsMarkedWith(mark)) { | 140 if (!successor0_->IsMarkedWith(mark)) { |
137 successor0_->MarkWith(mark); | 141 successor0_->MarkWith(mark); |
138 successor0_->Traverse(mark, preorder, postorder); | 142 successor0_->Traverse(mark, preorder, postorder); |
139 } | 143 } |
140 if (!successor1_->IsMarkedWith(mark)) { | |
141 successor1_->MarkWith(mark); | |
142 successor1_->Traverse(mark, preorder, postorder); | |
143 } | |
144 postorder->Add(this); | 144 postorder->Add(this); |
145 } | 145 } |
146 | 146 |
147 | 147 |
148 void JoinNode::Traverse(bool mark, | 148 void JoinNode::Traverse(bool mark, |
149 ZoneList<Node*>* preorder, | 149 ZoneList<Node*>* preorder, |
150 ZoneList<Node*>* postorder) { | 150 ZoneList<Node*>* postorder) { |
151 ASSERT(successor_ != NULL); | 151 ASSERT(successor_ != NULL); |
152 preorder->Add(this); | 152 preorder->Add(this); |
153 if (!successor_->IsMarkedWith(mark)) { | 153 if (!successor_->IsMarkedWith(mark)) { |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 | 351 |
352 | 352 |
353 void FlowGraphBuilder::VisitAssignment(Assignment* expr) { | 353 void FlowGraphBuilder::VisitAssignment(Assignment* expr) { |
354 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 354 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
355 Property* prop = expr->target()->AsProperty(); | 355 Property* prop = expr->target()->AsProperty(); |
356 // Left-hand side can be a variable or property (or reference error) but | 356 // Left-hand side can be a variable or property (or reference error) but |
357 // not both. | 357 // not both. |
358 ASSERT(var == NULL || prop == NULL); | 358 ASSERT(var == NULL || prop == NULL); |
359 if (var != NULL) { | 359 if (var != NULL) { |
360 Visit(expr->value()); | 360 Visit(expr->value()); |
361 if (var->IsStackAllocated()) definitions_.Add(expr); | 361 if (var->IsStackAllocated()) { |
| 362 expr->set_num(definitions_.length()); |
| 363 definitions_.Add(expr); |
| 364 } |
362 | 365 |
363 } else if (prop != NULL) { | 366 } else if (prop != NULL) { |
364 Visit(prop->obj()); | 367 Visit(prop->obj()); |
365 if (!prop->key()->IsPropertyName()) Visit(prop->key()); | 368 if (!prop->key()->IsPropertyName()) Visit(prop->key()); |
366 Visit(expr->value()); | 369 Visit(expr->value()); |
367 } | 370 } |
368 | 371 |
369 if (HasStackOverflow()) return; | 372 if (HasStackOverflow()) return; |
370 graph_.AppendInstruction(expr); | 373 graph_.AppendInstruction(expr); |
371 } | 374 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 default: | 430 default: |
428 UNREACHABLE(); | 431 UNREACHABLE(); |
429 } | 432 } |
430 } | 433 } |
431 | 434 |
432 | 435 |
433 void FlowGraphBuilder::VisitCountOperation(CountOperation* expr) { | 436 void FlowGraphBuilder::VisitCountOperation(CountOperation* expr) { |
434 Visit(expr->expression()); | 437 Visit(expr->expression()); |
435 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); | 438 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); |
436 if (var != NULL && var->IsStackAllocated()) { | 439 if (var != NULL && var->IsStackAllocated()) { |
| 440 expr->set_num(definitions_.length()); |
437 definitions_.Add(expr); | 441 definitions_.Add(expr); |
438 } | 442 } |
439 | 443 |
440 if (HasStackOverflow()) return; | 444 if (HasStackOverflow()) return; |
441 graph_.AppendInstruction(expr); | 445 graph_.AppendInstruction(expr); |
442 } | 446 } |
443 | 447 |
444 | 448 |
445 void FlowGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { | 449 void FlowGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { |
446 switch (expr->op()) { | 450 switch (expr->op()) { |
(...skipping 1029 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1476 } | 1480 } |
1477 | 1481 |
1478 | 1482 |
1479 #ifdef DEBUG | 1483 #ifdef DEBUG |
1480 | 1484 |
1481 // Print a textual representation of an instruction in a flow graph. Using | 1485 // Print a textual representation of an instruction in a flow graph. Using |
1482 // the AstVisitor is overkill because there is no recursion here. It is | 1486 // the AstVisitor is overkill because there is no recursion here. It is |
1483 // only used for printing in debug mode. | 1487 // only used for printing in debug mode. |
1484 class TextInstructionPrinter: public AstVisitor { | 1488 class TextInstructionPrinter: public AstVisitor { |
1485 public: | 1489 public: |
1486 TextInstructionPrinter() {} | 1490 TextInstructionPrinter() : number_(0) {} |
| 1491 |
| 1492 int NextNumber() { return number_; } |
| 1493 void AssignNumber(AstNode* node) { node->set_num(number_++); } |
1487 | 1494 |
1488 private: | 1495 private: |
1489 // AST node visit functions. | 1496 // AST node visit functions. |
1490 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); | 1497 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); |
1491 AST_NODE_LIST(DECLARE_VISIT) | 1498 AST_NODE_LIST(DECLARE_VISIT) |
1492 #undef DECLARE_VISIT | 1499 #undef DECLARE_VISIT |
1493 | 1500 |
| 1501 int number_; |
| 1502 |
1494 DISALLOW_COPY_AND_ASSIGN(TextInstructionPrinter); | 1503 DISALLOW_COPY_AND_ASSIGN(TextInstructionPrinter); |
1495 }; | 1504 }; |
1496 | 1505 |
1497 | 1506 |
1498 void TextInstructionPrinter::VisitDeclaration(Declaration* decl) { | 1507 void TextInstructionPrinter::VisitDeclaration(Declaration* decl) { |
1499 UNREACHABLE(); | 1508 UNREACHABLE(); |
1500 } | 1509 } |
1501 | 1510 |
1502 | 1511 |
1503 void TextInstructionPrinter::VisitBlock(Block* stmt) { | 1512 void TextInstructionPrinter::VisitBlock(Block* stmt) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1604 | 1613 |
1605 | 1614 |
1606 void TextInstructionPrinter::VisitSlot(Slot* expr) { | 1615 void TextInstructionPrinter::VisitSlot(Slot* expr) { |
1607 UNREACHABLE(); | 1616 UNREACHABLE(); |
1608 } | 1617 } |
1609 | 1618 |
1610 | 1619 |
1611 void TextInstructionPrinter::VisitVariableProxy(VariableProxy* expr) { | 1620 void TextInstructionPrinter::VisitVariableProxy(VariableProxy* expr) { |
1612 Variable* var = expr->AsVariable(); | 1621 Variable* var = expr->AsVariable(); |
1613 if (var != NULL) { | 1622 if (var != NULL) { |
1614 SmartPointer<char> name = var->name()->ToCString(); | 1623 PrintF("%s", *var->name()->ToCString()); |
1615 PrintF("%s", *name); | |
1616 } else { | 1624 } else { |
1617 ASSERT(expr->AsProperty() != NULL); | 1625 ASSERT(expr->AsProperty() != NULL); |
1618 VisitProperty(expr->AsProperty()); | 1626 VisitProperty(expr->AsProperty()); |
1619 } | 1627 } |
1620 } | 1628 } |
1621 | 1629 |
1622 | 1630 |
1623 void TextInstructionPrinter::VisitLiteral(Literal* expr) { | 1631 void TextInstructionPrinter::VisitLiteral(Literal* expr) { |
1624 expr->handle()->ShortPrint(); | 1632 expr->handle()->ShortPrint(); |
1625 } | 1633 } |
(...skipping 18 matching lines...) Expand all Loading... |
1644 CatchExtensionObject* expr) { | 1652 CatchExtensionObject* expr) { |
1645 PrintF("CatchExtensionObject"); | 1653 PrintF("CatchExtensionObject"); |
1646 } | 1654 } |
1647 | 1655 |
1648 | 1656 |
1649 void TextInstructionPrinter::VisitAssignment(Assignment* expr) { | 1657 void TextInstructionPrinter::VisitAssignment(Assignment* expr) { |
1650 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 1658 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
1651 Property* prop = expr->target()->AsProperty(); | 1659 Property* prop = expr->target()->AsProperty(); |
1652 | 1660 |
1653 if (var != NULL) { | 1661 if (var != NULL) { |
1654 SmartPointer<char> name = var->name()->ToCString(); | |
1655 PrintF("%s %s @%d", | 1662 PrintF("%s %s @%d", |
1656 *name, | 1663 *var->name()->ToCString(), |
1657 Token::String(expr->op()), | 1664 Token::String(expr->op()), |
1658 expr->value()->num()); | 1665 expr->value()->num()); |
1659 } else if (prop != NULL) { | 1666 } else if (prop != NULL) { |
1660 if (prop->key()->IsPropertyName()) { | 1667 if (prop->key()->IsPropertyName()) { |
1661 PrintF("@%d.", prop->obj()->num()); | 1668 PrintF("@%d.", prop->obj()->num()); |
1662 ASSERT(prop->key()->AsLiteral() != NULL); | 1669 ASSERT(prop->key()->AsLiteral() != NULL); |
1663 prop->key()->AsLiteral()->handle()->Print(); | 1670 prop->key()->AsLiteral()->handle()->Print(); |
1664 PrintF(" %s @%d", | 1671 PrintF(" %s @%d", |
1665 Token::String(expr->op()), | 1672 Token::String(expr->op()), |
1666 expr->value()->num()); | 1673 expr->value()->num()); |
1667 } else { | 1674 } else { |
1668 PrintF("@%d[@%d] %s @%d", | 1675 PrintF("@%d[@%d] %s @%d", |
1669 prop->obj()->num(), | 1676 prop->obj()->num(), |
1670 prop->key()->num(), | 1677 prop->key()->num(), |
1671 Token::String(expr->op()), | 1678 Token::String(expr->op()), |
1672 expr->value()->num()); | 1679 expr->value()->num()); |
1673 } | 1680 } |
1674 } else { | 1681 } else { |
1675 // Throw reference error. | 1682 // Throw reference error. |
1676 Visit(expr->target()); | 1683 Visit(expr->target()); |
1677 } | 1684 } |
| 1685 |
| 1686 if (expr->num() != AstNode::kNoNumber) { |
| 1687 PrintF(" ;; D%d", expr->num()); |
| 1688 } |
1678 } | 1689 } |
1679 | 1690 |
1680 | 1691 |
1681 void TextInstructionPrinter::VisitThrow(Throw* expr) { | 1692 void TextInstructionPrinter::VisitThrow(Throw* expr) { |
1682 PrintF("throw @%d", expr->exception()->num()); | 1693 PrintF("throw @%d", expr->exception()->num()); |
1683 } | 1694 } |
1684 | 1695 |
1685 | 1696 |
1686 void TextInstructionPrinter::VisitProperty(Property* expr) { | 1697 void TextInstructionPrinter::VisitProperty(Property* expr) { |
1687 if (expr->key()->IsPropertyName()) { | 1698 if (expr->key()->IsPropertyName()) { |
(...skipping 22 matching lines...) Expand all Loading... |
1710 ZoneList<Expression*>* arguments = expr->arguments(); | 1721 ZoneList<Expression*>* arguments = expr->arguments(); |
1711 for (int i = 0, len = arguments->length(); i < len; i++) { | 1722 for (int i = 0, len = arguments->length(); i < len; i++) { |
1712 if (i != 0) PrintF(", "); | 1723 if (i != 0) PrintF(", "); |
1713 PrintF("@%d", arguments->at(i)->num()); | 1724 PrintF("@%d", arguments->at(i)->num()); |
1714 } | 1725 } |
1715 PrintF(")"); | 1726 PrintF(")"); |
1716 } | 1727 } |
1717 | 1728 |
1718 | 1729 |
1719 void TextInstructionPrinter::VisitCallRuntime(CallRuntime* expr) { | 1730 void TextInstructionPrinter::VisitCallRuntime(CallRuntime* expr) { |
1720 SmartPointer<char> name = expr->name()->ToCString(); | 1731 PrintF("%s(", *expr->name()->ToCString()); |
1721 PrintF("%s(", *name); | |
1722 ZoneList<Expression*>* arguments = expr->arguments(); | 1732 ZoneList<Expression*>* arguments = expr->arguments(); |
1723 for (int i = 0, len = arguments->length(); i < len; i++) { | 1733 for (int i = 0, len = arguments->length(); i < len; i++) { |
1724 if (i != 0) PrintF(", "); | 1734 if (i != 0) PrintF(", "); |
1725 PrintF("@%d", arguments->at(i)->num()); | 1735 PrintF("@%d", arguments->at(i)->num()); |
1726 } | 1736 } |
1727 PrintF(")"); | 1737 PrintF(")"); |
1728 } | 1738 } |
1729 | 1739 |
1730 | 1740 |
1731 void TextInstructionPrinter::VisitUnaryOperation(UnaryOperation* expr) { | 1741 void TextInstructionPrinter::VisitUnaryOperation(UnaryOperation* expr) { |
1732 PrintF("%s(@%d)", Token::String(expr->op()), expr->expression()->num()); | 1742 PrintF("%s(@%d)", Token::String(expr->op()), expr->expression()->num()); |
1733 } | 1743 } |
1734 | 1744 |
1735 | 1745 |
1736 void TextInstructionPrinter::VisitCountOperation(CountOperation* expr) { | 1746 void TextInstructionPrinter::VisitCountOperation(CountOperation* expr) { |
1737 if (expr->is_prefix()) { | 1747 if (expr->is_prefix()) { |
1738 PrintF("%s@%d", Token::String(expr->op()), expr->expression()->num()); | 1748 PrintF("%s@%d", Token::String(expr->op()), expr->expression()->num()); |
1739 } else { | 1749 } else { |
1740 PrintF("@%d%s", expr->expression()->num(), Token::String(expr->op())); | 1750 PrintF("@%d%s", expr->expression()->num(), Token::String(expr->op())); |
1741 } | 1751 } |
| 1752 |
| 1753 if (expr->num() != AstNode::kNoNumber) { |
| 1754 PrintF(" ;; D%d", expr->num()); |
| 1755 } |
1742 } | 1756 } |
1743 | 1757 |
1744 | 1758 |
1745 void TextInstructionPrinter::VisitBinaryOperation(BinaryOperation* expr) { | 1759 void TextInstructionPrinter::VisitBinaryOperation(BinaryOperation* expr) { |
1746 ASSERT(expr->op() != Token::COMMA); | 1760 ASSERT(expr->op() != Token::COMMA); |
1747 ASSERT(expr->op() != Token::OR); | 1761 ASSERT(expr->op() != Token::OR); |
1748 ASSERT(expr->op() != Token::AND); | 1762 ASSERT(expr->op() != Token::AND); |
1749 PrintF("@%d %s @%d", | 1763 PrintF("@%d %s @%d", |
1750 expr->left()->num(), | 1764 expr->left()->num(), |
1751 Token::String(expr->op()), | 1765 Token::String(expr->op()), |
(...skipping 11 matching lines...) Expand all Loading... |
1763 | 1777 |
1764 void TextInstructionPrinter::VisitThisFunction(ThisFunction* expr) { | 1778 void TextInstructionPrinter::VisitThisFunction(ThisFunction* expr) { |
1765 PrintF("ThisFunction"); | 1779 PrintF("ThisFunction"); |
1766 } | 1780 } |
1767 | 1781 |
1768 | 1782 |
1769 static int node_count = 0; | 1783 static int node_count = 0; |
1770 static int instruction_count = 0; | 1784 static int instruction_count = 0; |
1771 | 1785 |
1772 | 1786 |
1773 void Node::AssignNumbers() { | 1787 void Node::AssignNodeNumber() { |
1774 set_number(node_count++); | 1788 set_number(node_count++); |
1775 } | 1789 } |
1776 | 1790 |
1777 | 1791 |
1778 void BlockNode::AssignNumbers() { | 1792 void Node::PrintReachingDefinitions() { |
1779 set_number(node_count++); | 1793 if (rd_.rd_in() != NULL) { |
1780 for (int i = 0, len = instructions_.length(); i < len; i++) { | 1794 ASSERT(rd_.kill() != NULL && rd_.gen() != NULL); |
1781 instructions_[i]->set_num(instruction_count++); | 1795 |
| 1796 PrintF("RD_in = {"); |
| 1797 bool first = true; |
| 1798 for (int i = 0; i < rd_.rd_in()->length(); i++) { |
| 1799 if (rd_.rd_in()->Contains(i)) { |
| 1800 if (!first) PrintF(","); |
| 1801 PrintF("%d"); |
| 1802 first = false; |
| 1803 } |
| 1804 } |
| 1805 PrintF("}\n"); |
| 1806 |
| 1807 PrintF("RD_kill = {"); |
| 1808 first = true; |
| 1809 for (int i = 0; i < rd_.kill()->length(); i++) { |
| 1810 if (rd_.kill()->Contains(i)) { |
| 1811 if (!first) PrintF(","); |
| 1812 PrintF("%d"); |
| 1813 first = false; |
| 1814 } |
| 1815 } |
| 1816 PrintF("}\n"); |
| 1817 |
| 1818 PrintF("RD_gen = {"); |
| 1819 first = true; |
| 1820 for (int i = 0; i < rd_.gen()->length(); i++) { |
| 1821 if (rd_.gen()->Contains(i)) { |
| 1822 if (!first) PrintF(","); |
| 1823 PrintF("%d"); |
| 1824 first = false; |
| 1825 } |
| 1826 } |
| 1827 PrintF("}\n"); |
1782 } | 1828 } |
1783 } | 1829 } |
1784 | 1830 |
1785 | 1831 |
1786 void ExitNode::PrintText() { | 1832 void ExitNode::PrintText() { |
| 1833 PrintReachingDefinitions(); |
1787 PrintF("L%d: Exit\n\n", number()); | 1834 PrintF("L%d: Exit\n\n", number()); |
1788 } | 1835 } |
1789 | 1836 |
1790 | 1837 |
1791 void BlockNode::PrintText() { | 1838 void BlockNode::PrintText() { |
| 1839 PrintReachingDefinitions(); |
1792 // Print the instructions in the block. | 1840 // Print the instructions in the block. |
1793 PrintF("L%d: Block\n", number()); | 1841 PrintF("L%d: Block\n", number()); |
1794 TextInstructionPrinter printer; | 1842 TextInstructionPrinter printer; |
1795 for (int i = 0, len = instructions_.length(); i < len; i++) { | 1843 for (int i = 0, len = instructions_.length(); i < len; i++) { |
1796 PrintF("%d ", instructions_[i]->num()); | 1844 PrintF("%d ", printer.NextNumber()); |
1797 printer.Visit(instructions_[i]); | 1845 printer.Visit(instructions_[i]); |
| 1846 printer.AssignNumber(instructions_[i]); |
1798 PrintF("\n"); | 1847 PrintF("\n"); |
1799 } | 1848 } |
1800 PrintF("goto L%d\n\n", successor_->number()); | 1849 PrintF("goto L%d\n\n", successor_->number()); |
1801 } | 1850 } |
1802 | 1851 |
1803 | 1852 |
1804 void BranchNode::PrintText() { | 1853 void BranchNode::PrintText() { |
| 1854 PrintReachingDefinitions(); |
1805 PrintF("L%d: Branch\n", number()); | 1855 PrintF("L%d: Branch\n", number()); |
1806 PrintF("goto (L%d, L%d)\n\n", successor0_->number(), successor1_->number()); | 1856 PrintF("goto (L%d, L%d)\n\n", successor0_->number(), successor1_->number()); |
1807 } | 1857 } |
1808 | 1858 |
1809 | 1859 |
1810 void JoinNode::PrintText() { | 1860 void JoinNode::PrintText() { |
| 1861 PrintReachingDefinitions(); |
1811 PrintF("L%d: Join(", number()); | 1862 PrintF("L%d: Join(", number()); |
1812 for (int i = 0, len = predecessors_.length(); i < len; i++) { | 1863 for (int i = 0, len = predecessors_.length(); i < len; i++) { |
1813 if (i != 0) PrintF(", "); | 1864 if (i != 0) PrintF(", "); |
1814 PrintF("L%d", predecessors_[i]->number()); | 1865 PrintF("L%d", predecessors_[i]->number()); |
1815 } | 1866 } |
1816 PrintF(")\ngoto L%d\n\n", successor_->number()); | 1867 PrintF(")\ngoto L%d\n\n", successor_->number()); |
1817 } | 1868 } |
1818 | 1869 |
1819 | 1870 |
1820 void FlowGraph::PrintText(ZoneList<Node*>* postorder) { | 1871 void FlowGraph::PrintText(ZoneList<Node*>* postorder) { |
1821 PrintF("\n========\n"); | 1872 PrintF("\n========\n"); |
1822 | 1873 |
1823 // Number nodes and instructions in reverse postorder. | 1874 // Number nodes and instructions in reverse postorder. |
1824 node_count = 0; | 1875 node_count = 0; |
1825 instruction_count = 0; | 1876 instruction_count = 0; |
1826 for (int i = postorder->length() - 1; i >= 0; i--) { | 1877 for (int i = postorder->length() - 1; i >= 0; i--) { |
1827 postorder->at(i)->AssignNumbers(); | 1878 postorder->at(i)->AssignNodeNumber(); |
1828 } | 1879 } |
1829 | 1880 |
1830 // Print basic blocks in reverse postorder. | 1881 // Print basic blocks in reverse postorder. |
1831 for (int i = postorder->length() - 1; i >= 0; i--) { | 1882 for (int i = postorder->length() - 1; i >= 0; i--) { |
1832 postorder->at(i)->PrintText(); | 1883 postorder->at(i)->PrintText(); |
1833 } | 1884 } |
1834 } | 1885 } |
1835 | 1886 |
1836 | 1887 |
1837 #endif // defined(DEBUG) | 1888 #endif // defined(DEBUG) |
1838 | 1889 |
1839 | 1890 |
| 1891 int ReachingDefinitions::IndexFor(Variable* var, int variable_count) { |
| 1892 // Parameters are numbered left-to-right from the beginning of the bit |
| 1893 // set. Stack-allocated locals are allocated right-to-left from the end. |
| 1894 ASSERT(var != NULL && var->IsStackAllocated()); |
| 1895 Slot* slot = var->slot(); |
| 1896 if (slot->type() == Slot::PARAMETER) { |
| 1897 return slot->index(); |
| 1898 } else { |
| 1899 return (variable_count - 1) - slot->index(); |
| 1900 } |
| 1901 } |
| 1902 |
| 1903 |
| 1904 void Node::InitializeReachingDefinitions(int definition_count, |
| 1905 List<BitVector*>* variables) { |
| 1906 rd_.Initialize(definition_count); |
| 1907 } |
| 1908 |
| 1909 |
| 1910 void BlockNode::InitializeReachingDefinitions(int definition_count, |
| 1911 List<BitVector*>* variables) { |
| 1912 int instruction_count = instructions_.length(); |
| 1913 int variable_count = variables->length(); |
| 1914 |
| 1915 rd_.Initialize(definition_count); |
| 1916 |
| 1917 for (int i = 0; i < instruction_count; i++) { |
| 1918 Expression* expr = instructions_[i]->AsExpression(); |
| 1919 if (expr == NULL) continue; |
| 1920 Variable* var = expr->AssignedVar(); |
| 1921 if (var == NULL) continue; |
| 1922 |
| 1923 // All definitions of this variable are killed. |
| 1924 BitVector* def_set = |
| 1925 variables->at(ReachingDefinitions::IndexFor(var, variable_count)); |
| 1926 rd_.kill()->Union(*def_set); |
| 1927 |
| 1928 // All previously generated definitions are not generated. |
| 1929 rd_.gen()->Subtract(*def_set); |
| 1930 |
| 1931 // This one is generated. |
| 1932 rd_.gen()->Add(expr->num()); |
| 1933 } |
| 1934 } |
| 1935 |
| 1936 |
| 1937 void ReachingDefinitions::Compute() { |
| 1938 if (definitions_->is_empty()) return; |
| 1939 |
| 1940 int variable_count = variables_.length(); |
| 1941 int definition_count = definitions_->length(); |
| 1942 int block_count = postorder_->length(); |
| 1943 |
| 1944 // Step 1: For each variable, identify the set of all its definitions in |
| 1945 // the body. |
| 1946 for (int i = 0; i < definition_count; i++) { |
| 1947 Variable* var = definitions_->at(i)->AssignedVar(); |
| 1948 variables_[IndexFor(var, variable_count)]->Add(i); |
| 1949 } |
| 1950 |
| 1951 if (FLAG_print_graph_text) { |
| 1952 for (int i = 0; i < variable_count; i++) { |
| 1953 BitVector* def_set = variables_[i]; |
| 1954 if (!def_set->IsEmpty()) { |
| 1955 // At least one definition. |
| 1956 bool first = true; |
| 1957 for (int j = 0; j < definition_count; j++) { |
| 1958 if (def_set->Contains(j)) { |
| 1959 if (first) { |
| 1960 Variable* var = definitions_->at(j)->AssignedVar(); |
| 1961 ASSERT(var != NULL); |
| 1962 PrintF("Def[%s] = {%d", *var->name()->ToCString(), j); |
| 1963 first = false; |
| 1964 } else { |
| 1965 PrintF(", %d", j); |
| 1966 } |
| 1967 } |
| 1968 } |
| 1969 PrintF("}\n"); |
| 1970 } |
| 1971 } |
| 1972 } |
| 1973 |
| 1974 // Step 2: Compute KILL and GEN for each block node, initialize RD. |
| 1975 for (int i = block_count - 1; i >= 0; i--) { |
| 1976 postorder_->at(i)->InitializeReachingDefinitions(definition_count, |
| 1977 &variables_); |
| 1978 } |
| 1979 } |
| 1980 |
| 1981 |
1840 } } // namespace v8::internal | 1982 } } // namespace v8::internal |
OLD | NEW |