Chromium Code Reviews| 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 16 matching lines...) Expand all Loading... | |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "data-flow.h" | 30 #include "data-flow.h" |
| 31 #include "scopes.h" | 31 #include "scopes.h" |
| 32 | 32 |
| 33 namespace v8 { | 33 namespace v8 { |
| 34 namespace internal { | 34 namespace internal { |
| 35 | 35 |
| 36 | 36 |
| 37 #ifdef DEBUG | |
| 38 void BitVector::Print() { | |
| 39 bool first = true; | |
| 40 PrintF("{"); | |
| 41 for (int i = 0; i < length(); i++) { | |
| 42 if (Contains(i)) { | |
| 43 if (!first) PrintF(","); | |
| 44 first = false; | |
| 45 PrintF("%d"); | |
| 46 } | |
| 47 } | |
| 48 PrintF("}"); | |
| 49 } | |
| 50 #endif | |
| 51 | |
| 52 | |
| 37 void FlowGraph::AppendInstruction(AstNode* instruction) { | 53 void FlowGraph::AppendInstruction(AstNode* instruction) { |
| 38 // Add a (non-null) AstNode to the end of the graph fragment. | 54 // Add a (non-null) AstNode to the end of the graph fragment. |
| 39 ASSERT(instruction != NULL); | 55 ASSERT(instruction != NULL); |
| 40 if (exit()->IsExitNode()) return; | 56 if (exit()->IsExitNode()) return; |
| 41 if (!exit()->IsBlockNode()) AppendNode(new BlockNode()); | 57 if (!exit()->IsBlockNode()) AppendNode(new BlockNode()); |
| 42 BlockNode::cast(exit())->AddInstruction(instruction); | 58 BlockNode::cast(exit())->AddInstruction(instruction); |
| 43 } | 59 } |
| 44 | 60 |
| 45 | 61 |
| 46 void FlowGraph::AppendNode(Node* node) { | 62 void FlowGraph::AppendNode(Node* node) { |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 350 } | 366 } |
| 351 | 367 |
| 352 | 368 |
| 353 void FlowGraphBuilder::VisitAssignment(Assignment* expr) { | 369 void FlowGraphBuilder::VisitAssignment(Assignment* expr) { |
| 354 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 370 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
| 355 Property* prop = expr->target()->AsProperty(); | 371 Property* prop = expr->target()->AsProperty(); |
| 356 // Left-hand side can be a variable or property (or reference error) but | 372 // Left-hand side can be a variable or property (or reference error) but |
| 357 // not both. | 373 // not both. |
| 358 ASSERT(var == NULL || prop == NULL); | 374 ASSERT(var == NULL || prop == NULL); |
| 359 if (var != NULL) { | 375 if (var != NULL) { |
| 376 if (expr->is_compound()) Visit(expr->target()); | |
| 360 Visit(expr->value()); | 377 Visit(expr->value()); |
| 361 if (var->IsStackAllocated()) { | 378 if (var->IsStackAllocated()) { |
| 362 expr->set_num(definitions_.length()); | 379 expr->set_num(definitions_.length()); |
| 363 definitions_.Add(expr); | 380 definitions_.Add(expr); |
| 364 } | 381 } |
| 365 | 382 |
| 366 } else if (prop != NULL) { | 383 } else if (prop != NULL) { |
| 367 Visit(prop->obj()); | 384 Visit(prop->obj()); |
| 368 if (!prop->key()->IsPropertyName()) Visit(prop->key()); | 385 if (!prop->key()->IsPropertyName()) Visit(prop->key()); |
| 369 Visit(expr->value()); | 386 Visit(expr->value()); |
| (...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1326 | 1343 |
| 1327 | 1344 |
| 1328 void AssignedVariablesAnalyzer::VisitObjectLiteral(ObjectLiteral* expr) { | 1345 void AssignedVariablesAnalyzer::VisitObjectLiteral(ObjectLiteral* expr) { |
| 1329 ASSERT(av_.IsEmpty()); | 1346 ASSERT(av_.IsEmpty()); |
| 1330 BitVector result(av_.length()); | 1347 BitVector result(av_.length()); |
| 1331 for (int i = 0; i < expr->properties()->length(); i++) { | 1348 for (int i = 0; i < expr->properties()->length(); i++) { |
| 1332 Visit(expr->properties()->at(i)->value()); | 1349 Visit(expr->properties()->at(i)->value()); |
| 1333 result.Union(av_); | 1350 result.Union(av_); |
| 1334 av_.Clear(); | 1351 av_.Clear(); |
| 1335 } | 1352 } |
| 1336 av_.CopyFrom(result); | 1353 av_ = result; |
| 1337 } | 1354 } |
| 1338 | 1355 |
| 1339 | 1356 |
| 1340 void AssignedVariablesAnalyzer::VisitArrayLiteral(ArrayLiteral* expr) { | 1357 void AssignedVariablesAnalyzer::VisitArrayLiteral(ArrayLiteral* expr) { |
| 1341 ASSERT(av_.IsEmpty()); | 1358 ASSERT(av_.IsEmpty()); |
| 1342 BitVector result(av_.length()); | 1359 BitVector result(av_.length()); |
| 1343 for (int i = 0; i < expr->values()->length(); i++) { | 1360 for (int i = 0; i < expr->values()->length(); i++) { |
| 1344 Visit(expr->values()->at(i)); | 1361 Visit(expr->values()->at(i)); |
| 1345 result.Union(av_); | 1362 result.Union(av_); |
| 1346 av_.Clear(); | 1363 av_.Clear(); |
| 1347 } | 1364 } |
| 1348 av_.CopyFrom(result); | 1365 av_ = result; |
| 1349 } | 1366 } |
| 1350 | 1367 |
| 1351 | 1368 |
| 1352 void AssignedVariablesAnalyzer::VisitCatchExtensionObject( | 1369 void AssignedVariablesAnalyzer::VisitCatchExtensionObject( |
| 1353 CatchExtensionObject* expr) { | 1370 CatchExtensionObject* expr) { |
| 1354 ASSERT(av_.IsEmpty()); | 1371 ASSERT(av_.IsEmpty()); |
| 1355 Visit(expr->key()); | 1372 Visit(expr->key()); |
| 1356 ProcessExpression(expr->value()); | 1373 ProcessExpression(expr->value()); |
| 1357 } | 1374 } |
| 1358 | 1375 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1398 | 1415 |
| 1399 void AssignedVariablesAnalyzer::VisitCall(Call* expr) { | 1416 void AssignedVariablesAnalyzer::VisitCall(Call* expr) { |
| 1400 ASSERT(av_.IsEmpty()); | 1417 ASSERT(av_.IsEmpty()); |
| 1401 Visit(expr->expression()); | 1418 Visit(expr->expression()); |
| 1402 BitVector result(av_); | 1419 BitVector result(av_); |
| 1403 for (int i = 0; i < expr->arguments()->length(); i++) { | 1420 for (int i = 0; i < expr->arguments()->length(); i++) { |
| 1404 av_.Clear(); | 1421 av_.Clear(); |
| 1405 Visit(expr->arguments()->at(i)); | 1422 Visit(expr->arguments()->at(i)); |
| 1406 result.Union(av_); | 1423 result.Union(av_); |
| 1407 } | 1424 } |
| 1408 av_.CopyFrom(result); | 1425 av_ = result; |
| 1409 } | 1426 } |
| 1410 | 1427 |
| 1411 | 1428 |
| 1412 void AssignedVariablesAnalyzer::VisitCallNew(CallNew* expr) { | 1429 void AssignedVariablesAnalyzer::VisitCallNew(CallNew* expr) { |
| 1413 ASSERT(av_.IsEmpty()); | 1430 ASSERT(av_.IsEmpty()); |
| 1414 Visit(expr->expression()); | 1431 Visit(expr->expression()); |
| 1415 BitVector result(av_); | 1432 BitVector result(av_); |
| 1416 for (int i = 0; i < expr->arguments()->length(); i++) { | 1433 for (int i = 0; i < expr->arguments()->length(); i++) { |
| 1417 av_.Clear(); | 1434 av_.Clear(); |
| 1418 Visit(expr->arguments()->at(i)); | 1435 Visit(expr->arguments()->at(i)); |
| 1419 result.Union(av_); | 1436 result.Union(av_); |
| 1420 } | 1437 } |
| 1421 av_.CopyFrom(result); | 1438 av_ = result; |
| 1422 } | 1439 } |
| 1423 | 1440 |
| 1424 | 1441 |
| 1425 void AssignedVariablesAnalyzer::VisitCallRuntime(CallRuntime* expr) { | 1442 void AssignedVariablesAnalyzer::VisitCallRuntime(CallRuntime* expr) { |
| 1426 ASSERT(av_.IsEmpty()); | 1443 ASSERT(av_.IsEmpty()); |
| 1427 BitVector result(av_); | 1444 BitVector result(av_); |
| 1428 for (int i = 0; i < expr->arguments()->length(); i++) { | 1445 for (int i = 0; i < expr->arguments()->length(); i++) { |
| 1429 av_.Clear(); | 1446 av_.Clear(); |
| 1430 Visit(expr->arguments()->at(i)); | 1447 Visit(expr->arguments()->at(i)); |
| 1431 result.Union(av_); | 1448 result.Union(av_); |
| 1432 } | 1449 } |
| 1433 av_.CopyFrom(result); | 1450 av_ = result; |
| 1434 } | 1451 } |
| 1435 | 1452 |
| 1436 | 1453 |
| 1437 void AssignedVariablesAnalyzer::VisitUnaryOperation(UnaryOperation* expr) { | 1454 void AssignedVariablesAnalyzer::VisitUnaryOperation(UnaryOperation* expr) { |
| 1438 ASSERT(av_.IsEmpty()); | 1455 ASSERT(av_.IsEmpty()); |
| 1439 Visit(expr->expression()); | 1456 Visit(expr->expression()); |
| 1440 } | 1457 } |
| 1441 | 1458 |
| 1442 | 1459 |
| 1443 void AssignedVariablesAnalyzer::VisitCountOperation(CountOperation* expr) { | 1460 void AssignedVariablesAnalyzer::VisitCountOperation(CountOperation* expr) { |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1619 | 1636 |
| 1620 void TextInstructionPrinter::VisitSlot(Slot* expr) { | 1637 void TextInstructionPrinter::VisitSlot(Slot* expr) { |
| 1621 UNREACHABLE(); | 1638 UNREACHABLE(); |
| 1622 } | 1639 } |
| 1623 | 1640 |
| 1624 | 1641 |
| 1625 void TextInstructionPrinter::VisitVariableProxy(VariableProxy* expr) { | 1642 void TextInstructionPrinter::VisitVariableProxy(VariableProxy* expr) { |
| 1626 Variable* var = expr->AsVariable(); | 1643 Variable* var = expr->AsVariable(); |
| 1627 if (var != NULL) { | 1644 if (var != NULL) { |
| 1628 PrintF("%s", *var->name()->ToCString()); | 1645 PrintF("%s", *var->name()->ToCString()); |
| 1646 if (var->IsStackAllocated() && expr->reaching_definitions() != NULL) { | |
| 1647 expr->reaching_definitions()->Print(); | |
| 1648 } | |
| 1629 } else { | 1649 } else { |
| 1630 ASSERT(expr->AsProperty() != NULL); | 1650 ASSERT(expr->AsProperty() != NULL); |
| 1631 VisitProperty(expr->AsProperty()); | 1651 VisitProperty(expr->AsProperty()); |
| 1632 } | 1652 } |
| 1633 } | 1653 } |
| 1634 | 1654 |
| 1635 | 1655 |
| 1636 void TextInstructionPrinter::VisitLiteral(Literal* expr) { | 1656 void TextInstructionPrinter::VisitLiteral(Literal* expr) { |
| 1637 expr->handle()->ShortPrint(); | 1657 expr->handle()->ShortPrint(); |
| 1638 } | 1658 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1656 void TextInstructionPrinter::VisitCatchExtensionObject( | 1676 void TextInstructionPrinter::VisitCatchExtensionObject( |
| 1657 CatchExtensionObject* expr) { | 1677 CatchExtensionObject* expr) { |
| 1658 PrintF("CatchExtensionObject"); | 1678 PrintF("CatchExtensionObject"); |
| 1659 } | 1679 } |
| 1660 | 1680 |
| 1661 | 1681 |
| 1662 void TextInstructionPrinter::VisitAssignment(Assignment* expr) { | 1682 void TextInstructionPrinter::VisitAssignment(Assignment* expr) { |
| 1663 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 1683 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
| 1664 Property* prop = expr->target()->AsProperty(); | 1684 Property* prop = expr->target()->AsProperty(); |
| 1665 | 1685 |
| 1686 if (var == NULL && prop == NULL) { | |
| 1687 // Throw reference error. | |
| 1688 Visit(expr->target()); | |
| 1689 return; | |
| 1690 } | |
| 1691 | |
| 1692 // Print the left-hand side. | |
| 1666 if (var != NULL) { | 1693 if (var != NULL) { |
| 1667 PrintF("%s %s @%d", | 1694 PrintF("%s", *var->name()->ToCString()); |
| 1668 *var->name()->ToCString(), | |
| 1669 Token::String(expr->op()), | |
| 1670 expr->value()->num()); | |
| 1671 } else if (prop != NULL) { | 1695 } else if (prop != NULL) { |
| 1696 PrintF("@%d", prop->obj()->num()); | |
| 1672 if (prop->key()->IsPropertyName()) { | 1697 if (prop->key()->IsPropertyName()) { |
| 1673 PrintF("@%d.", prop->obj()->num()); | 1698 PrintF("."); |
| 1674 ASSERT(prop->key()->AsLiteral() != NULL); | 1699 ASSERT(prop->key()->AsLiteral() != NULL); |
| 1675 prop->key()->AsLiteral()->handle()->Print(); | 1700 prop->key()->AsLiteral()->handle()->Print(); |
| 1676 PrintF(" %s @%d", | |
| 1677 Token::String(expr->op()), | |
| 1678 expr->value()->num()); | |
| 1679 } else { | 1701 } else { |
| 1680 PrintF("@%d[@%d] %s @%d", | 1702 PrintF("[@%d]", prop->key()->num()); |
| 1681 prop->obj()->num(), | |
| 1682 prop->key()->num(), | |
| 1683 Token::String(expr->op()), | |
| 1684 expr->value()->num()); | |
| 1685 } | 1703 } |
| 1704 } | |
| 1705 | |
| 1706 // Print the operation. | |
| 1707 if (expr->is_compound()) { | |
| 1708 PrintF(" = "); | |
| 1709 // Print the left-hand side again when compound. | |
| 1710 if (var != NULL) { | |
| 1711 PrintF("@%d", expr->target()->num()); | |
| 1712 } else { | |
| 1713 PrintF("@%d", prop->obj()->num()); | |
| 1714 if (prop->key()->IsPropertyName()) { | |
| 1715 PrintF("."); | |
| 1716 ASSERT(prop->key()->AsLiteral() != NULL); | |
| 1717 prop->key()->AsLiteral()->handle()->Print(); | |
| 1718 } else { | |
| 1719 PrintF("[@%d]", prop->key()->num()); | |
| 1720 } | |
| 1721 } | |
| 1722 // Print the corresponding binary operator. | |
| 1723 PrintF(" %s ", Token::String(expr->binary_op())); | |
| 1686 } else { | 1724 } else { |
| 1687 // Throw reference error. | 1725 PrintF(" %s ", Token::String(expr->op())); |
| 1688 Visit(expr->target()); | |
| 1689 } | 1726 } |
| 1690 | 1727 |
| 1728 // Print the right-hand side. | |
| 1729 PrintF("@%d", expr->value()->num()); | |
| 1730 | |
| 1691 if (expr->num() != AstNode::kNoNumber) { | 1731 if (expr->num() != AstNode::kNoNumber) { |
| 1692 PrintF(" ;; D%d", expr->num()); | 1732 PrintF(" ;; D%d", expr->num()); |
| 1693 } | 1733 } |
| 1694 } | 1734 } |
| 1695 | 1735 |
| 1696 | 1736 |
| 1697 void TextInstructionPrinter::VisitThrow(Throw* expr) { | 1737 void TextInstructionPrinter::VisitThrow(Throw* expr) { |
| 1698 PrintF("throw @%d", expr->exception()->num()); | 1738 PrintF("throw @%d", expr->exception()->num()); |
| 1699 } | 1739 } |
| 1700 | 1740 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1791 | 1831 |
| 1792 void Node::AssignNodeNumber() { | 1832 void Node::AssignNodeNumber() { |
| 1793 set_number(node_count++); | 1833 set_number(node_count++); |
| 1794 } | 1834 } |
| 1795 | 1835 |
| 1796 | 1836 |
| 1797 void Node::PrintReachingDefinitions() { | 1837 void Node::PrintReachingDefinitions() { |
| 1798 if (rd_.rd_in() != NULL) { | 1838 if (rd_.rd_in() != NULL) { |
| 1799 ASSERT(rd_.kill() != NULL && rd_.gen() != NULL); | 1839 ASSERT(rd_.kill() != NULL && rd_.gen() != NULL); |
| 1800 | 1840 |
| 1801 PrintF("RD_in = {"); | 1841 PrintF("RD_in = "); |
| 1802 bool first = true; | 1842 rd_.rd_in()->Print(); |
| 1803 for (int i = 0; i < rd_.rd_in()->length(); i++) { | 1843 PrintF("\n"); |
| 1804 if (rd_.rd_in()->Contains(i)) { | |
| 1805 if (!first) PrintF(","); | |
| 1806 PrintF("%d"); | |
| 1807 first = false; | |
| 1808 } | |
| 1809 } | |
| 1810 PrintF("}\n"); | |
| 1811 | 1844 |
| 1812 PrintF("RD_kill = {"); | 1845 PrintF("RD_kill = "); |
| 1813 first = true; | 1846 rd_.kill()->Print(); |
| 1814 for (int i = 0; i < rd_.kill()->length(); i++) { | 1847 PrintF("\n"); |
| 1815 if (rd_.kill()->Contains(i)) { | |
| 1816 if (!first) PrintF(","); | |
| 1817 PrintF("%d"); | |
| 1818 first = false; | |
| 1819 } | |
| 1820 } | |
| 1821 PrintF("}\n"); | |
| 1822 | 1848 |
| 1823 PrintF("RD_gen = {"); | 1849 PrintF("RD_gen = "); |
| 1824 first = true; | 1850 rd_.gen()->Print(); |
| 1825 for (int i = 0; i < rd_.gen()->length(); i++) { | 1851 PrintF("\n"); |
| 1826 if (rd_.gen()->Contains(i)) { | |
| 1827 if (!first) PrintF(","); | |
| 1828 PrintF("%d"); | |
| 1829 first = false; | |
| 1830 } | |
| 1831 } | |
| 1832 PrintF("}\n"); | |
| 1833 } | 1852 } |
| 1834 } | 1853 } |
| 1835 | 1854 |
| 1836 | 1855 |
| 1837 void ExitNode::PrintText() { | 1856 void ExitNode::PrintText() { |
| 1838 PrintReachingDefinitions(); | 1857 PrintReachingDefinitions(); |
| 1839 PrintF("L%d: Exit\n\n", number()); | 1858 PrintF("L%d: Exit\n\n", number()); |
| 1840 } | 1859 } |
| 1841 | 1860 |
| 1842 | 1861 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1954 | 1973 |
| 1955 | 1974 |
| 1956 void ExitNode::ComputeRDOut(BitVector* result) { | 1975 void ExitNode::ComputeRDOut(BitVector* result) { |
| 1957 // Should not be the predecessor of any node. | 1976 // Should not be the predecessor of any node. |
| 1958 UNREACHABLE(); | 1977 UNREACHABLE(); |
| 1959 } | 1978 } |
| 1960 | 1979 |
| 1961 | 1980 |
| 1962 void BlockNode::ComputeRDOut(BitVector* result) { | 1981 void BlockNode::ComputeRDOut(BitVector* result) { |
| 1963 // All definitions reaching this block ... | 1982 // All definitions reaching this block ... |
| 1964 result->CopyFrom(*rd_.rd_in()); | 1983 *result = *rd_.rd_in(); |
| 1965 // ... except those killed by the block ... | 1984 // ... except those killed by the block ... |
| 1966 result->Subtract(*rd_.kill()); | 1985 result->Subtract(*rd_.kill()); |
| 1967 // ... but including those generated by the block. | 1986 // ... but including those generated by the block. |
| 1968 result->Union(*rd_.gen()); | 1987 result->Union(*rd_.gen()); |
| 1969 } | 1988 } |
| 1970 | 1989 |
| 1971 | 1990 |
| 1972 void BranchNode::ComputeRDOut(BitVector* result) { | 1991 void BranchNode::ComputeRDOut(BitVector* result) { |
| 1973 // Branch nodes don't kill or generate definitions. | 1992 // Branch nodes don't kill or generate definitions. |
| 1974 result->CopyFrom(*rd_.rd_in()); | 1993 *result = *rd_.rd_in(); |
| 1975 } | 1994 } |
| 1976 | 1995 |
| 1977 | 1996 |
| 1978 void JoinNode::ComputeRDOut(BitVector* result) { | 1997 void JoinNode::ComputeRDOut(BitVector* result) { |
| 1979 // Join nodes don't kill or generate definitions. | 1998 // Join nodes don't kill or generate definitions. |
| 1980 result->CopyFrom(*rd_.rd_in()); | 1999 *result = *rd_.rd_in(); |
| 1981 } | 2000 } |
| 1982 | 2001 |
| 1983 | 2002 |
| 1984 void ExitNode::UpdateRDIn(WorkList<Node>* worklist, bool mark) { | 2003 void ExitNode::UpdateRDIn(WorkList<Node>* worklist, bool mark) { |
| 1985 // The exit node has no successors so we can just update in place. New | 2004 // The exit node has no successors so we can just update in place. New |
| 1986 // RD_in is the union over all predecessors. | 2005 // RD_in is the union over all predecessors. |
| 1987 int definition_count = rd_.rd_in()->length(); | 2006 int definition_count = rd_.rd_in()->length(); |
| 1988 rd_.rd_in()->Clear(); | 2007 rd_.rd_in()->Clear(); |
| 1989 | 2008 |
| 1990 BitVector temp(definition_count); | 2009 BitVector temp(definition_count); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 2001 void BlockNode::UpdateRDIn(WorkList<Node>* worklist, bool mark) { | 2020 void BlockNode::UpdateRDIn(WorkList<Node>* worklist, bool mark) { |
| 2002 // The entry block has no predecessor. Its RD_in does not change. | 2021 // The entry block has no predecessor. Its RD_in does not change. |
| 2003 if (predecessor_ == NULL) return; | 2022 if (predecessor_ == NULL) return; |
| 2004 | 2023 |
| 2005 BitVector new_rd_in(rd_.rd_in()->length()); | 2024 BitVector new_rd_in(rd_.rd_in()->length()); |
| 2006 predecessor_->ComputeRDOut(&new_rd_in); | 2025 predecessor_->ComputeRDOut(&new_rd_in); |
| 2007 | 2026 |
| 2008 if (rd_.rd_in()->Equals(new_rd_in)) return; | 2027 if (rd_.rd_in()->Equals(new_rd_in)) return; |
| 2009 | 2028 |
| 2010 // Update RD_in. | 2029 // Update RD_in. |
| 2011 rd_.rd_in()->CopyFrom(new_rd_in); | 2030 *rd_.rd_in() = new_rd_in; |
| 2012 // Add the successor to the worklist if not already present. | 2031 // Add the successor to the worklist if not already present. |
| 2013 if (!successor_->IsMarkedWith(mark)) { | 2032 if (!successor_->IsMarkedWith(mark)) { |
| 2014 successor_->MarkWith(mark); | 2033 successor_->MarkWith(mark); |
| 2015 worklist->Insert(successor_); | 2034 worklist->Insert(successor_); |
| 2016 } | 2035 } |
| 2017 } | 2036 } |
| 2018 | 2037 |
| 2019 | 2038 |
| 2020 void BranchNode::UpdateRDIn(WorkList<Node>* worklist, bool mark) { | 2039 void BranchNode::UpdateRDIn(WorkList<Node>* worklist, bool mark) { |
| 2021 BitVector new_rd_in(rd_.rd_in()->length()); | 2040 BitVector new_rd_in(rd_.rd_in()->length()); |
| 2022 predecessor_->ComputeRDOut(&new_rd_in); | 2041 predecessor_->ComputeRDOut(&new_rd_in); |
| 2023 | 2042 |
| 2024 if (rd_.rd_in()->Equals(new_rd_in)) return; | 2043 if (rd_.rd_in()->Equals(new_rd_in)) return; |
| 2025 | 2044 |
| 2026 // Update RD_in. | 2045 // Update RD_in. |
| 2027 rd_.rd_in()->CopyFrom(new_rd_in); | 2046 *rd_.rd_in() = new_rd_in; |
| 2028 // Add the successors to the worklist if not already present. | 2047 // Add the successors to the worklist if not already present. |
| 2029 if (!successor0_->IsMarkedWith(mark)) { | 2048 if (!successor0_->IsMarkedWith(mark)) { |
| 2030 successor0_->MarkWith(mark); | 2049 successor0_->MarkWith(mark); |
| 2031 worklist->Insert(successor0_); | 2050 worklist->Insert(successor0_); |
| 2032 } | 2051 } |
| 2033 if (!successor1_->IsMarkedWith(mark)) { | 2052 if (!successor1_->IsMarkedWith(mark)) { |
| 2034 successor1_->MarkWith(mark); | 2053 successor1_->MarkWith(mark); |
| 2035 worklist->Insert(successor1_); | 2054 worklist->Insert(successor1_); |
| 2036 } | 2055 } |
| 2037 } | 2056 } |
| 2038 | 2057 |
| 2039 | 2058 |
| 2040 void JoinNode::UpdateRDIn(WorkList<Node>* worklist, bool mark) { | 2059 void JoinNode::UpdateRDIn(WorkList<Node>* worklist, bool mark) { |
| 2041 int definition_count = rd_.rd_in()->length(); | 2060 int definition_count = rd_.rd_in()->length(); |
| 2042 BitVector new_rd_in(definition_count); | 2061 BitVector new_rd_in(definition_count); |
| 2043 | 2062 |
| 2044 // New RD_in is the union over all predecessors. | 2063 // New RD_in is the union over all predecessors. |
| 2045 BitVector temp(definition_count); | 2064 BitVector temp(definition_count); |
| 2046 for (int i = 0, len = predecessors_.length(); i < len; i++) { | 2065 for (int i = 0, len = predecessors_.length(); i < len; i++) { |
| 2047 predecessors_[i]->ComputeRDOut(&temp); | 2066 predecessors_[i]->ComputeRDOut(&temp); |
| 2048 new_rd_in.Union(temp); | 2067 new_rd_in.Union(temp); |
| 2049 } | 2068 } |
| 2050 | 2069 |
| 2051 if (rd_.rd_in()->Equals(new_rd_in)) return; | 2070 if (rd_.rd_in()->Equals(new_rd_in)) return; |
| 2052 | 2071 |
| 2053 // Update RD_in. | 2072 // Update RD_in. |
| 2054 rd_.rd_in()->CopyFrom(new_rd_in); | 2073 *rd_.rd_in() = new_rd_in; |
| 2055 // Add the successor to the worklist if not already present. | 2074 // Add the successor to the worklist if not already present. |
| 2056 if (!successor_->IsMarkedWith(mark)) { | 2075 if (!successor_->IsMarkedWith(mark)) { |
| 2057 successor_->MarkWith(mark); | 2076 successor_->MarkWith(mark); |
| 2058 worklist->Insert(successor_); | 2077 worklist->Insert(successor_); |
| 2059 } | 2078 } |
| 2060 } | 2079 } |
| 2061 | 2080 |
| 2062 | 2081 |
| 2082 void Node::PropagateReachingDefinitions(List<BitVector*>* variables) { | |
| 2083 // Nothing to do. | |
| 2084 } | |
| 2085 | |
| 2086 | |
| 2087 void BlockNode::PropagateReachingDefinitions(List<BitVector*>* variables) { | |
| 2088 // Propagate RD_in from the start of the block to all the variable | |
| 2089 // references. | |
| 2090 int variable_count = variables->length(); | |
| 2091 BitVector rd = *rd_.rd_in(); | |
| 2092 for (int i = 0, len = instructions_.length(); i < len; i++) { | |
| 2093 Expression* expr = instructions_[i]->AsExpression(); | |
| 2094 if (expr == NULL) continue; | |
| 2095 | |
| 2096 // Look for a variable reference to record its reaching definitions. | |
| 2097 VariableProxy* proxy = expr->AsVariableProxy(); | |
| 2098 if (proxy == NULL) { | |
| 2099 // Not a VariableProxy? Maybe it's a count operation. | |
| 2100 CountOperation* count_operation = expr->AsCountOperation(); | |
| 2101 if (count_operation != NULL) { | |
| 2102 proxy = count_operation->expression()->AsVariableProxy(); | |
| 2103 } | |
| 2104 } | |
| 2105 if (proxy == NULL) { | |
| 2106 // OK, Maybe it's a compound assignment. | |
| 2107 Assignment* assignment = expr->AsAssignment(); | |
| 2108 if (assignment != NULL && assignment->is_compound()) { | |
| 2109 proxy = assignment->target()->AsVariableProxy(); | |
| 2110 } | |
| 2111 } | |
| 2112 | |
| 2113 if (proxy != NULL && proxy->var()->IsStackAllocated()) { | |
| 2114 // All definitions for this variable. | |
| 2115 BitVector* definitions = | |
| 2116 variables->at(ReachingDefinitions::IndexFor(proxy->var(), | |
| 2117 variable_count)); | |
| 2118 BitVector* reaching_definitions = new BitVector(*definitions); | |
| 2119 // Intersected with all definitions (of any variable) reaching this | |
| 2120 // instruction. | |
| 2121 reaching_definitions->Intersect(rd); | |
| 2122 proxy->set_reaching_definitions(reaching_definitions); | |
| 2123 continue; | |
| 2124 } | |
| 2125 | |
| 2126 Assignment* assignment = expr->AsAssignment(); | |
| 2127 if (assignment != NULL) { | |
| 2128 } | |
|
fschneider
2010/03/15 10:11:15
Misplaced brackets?
| |
| 2129 | |
| 2130 // For an assignment, update the running value of reaching definitions | |
| 2131 // for the block. | |
| 2132 Variable* var = expr->AssignedVar(); | |
| 2133 if (var == NULL || !var->IsStackAllocated()) continue; | |
| 2134 | |
| 2135 // All definitions of this variable are killed. | |
| 2136 BitVector* def_set = | |
| 2137 variables->at(ReachingDefinitions::IndexFor(var, variable_count)); | |
| 2138 rd.Subtract(*def_set); | |
| 2139 // This definition is generated. | |
| 2140 rd.Add(expr->num()); | |
| 2141 } | |
| 2142 } | |
| 2143 | |
| 2144 | |
| 2063 void ReachingDefinitions::Compute() { | 2145 void ReachingDefinitions::Compute() { |
| 2064 if (definitions_->is_empty()) return; | 2146 if (definitions_->is_empty()) return; |
| 2065 | 2147 |
| 2066 int variable_count = variables_.length(); | 2148 int variable_count = variables_.length(); |
| 2067 int definition_count = definitions_->length(); | 2149 int definition_count = definitions_->length(); |
| 2068 int node_count = postorder_->length(); | 2150 int node_count = postorder_->length(); |
| 2069 | 2151 |
| 2070 // Step 1: For each variable, identify the set of all its definitions in | 2152 // Step 1: For each variable, identify the set of all its definitions in |
| 2071 // the body. | 2153 // the body. |
| 2072 for (int i = 0; i < definition_count; i++) { | 2154 for (int i = 0; i < definition_count; i++) { |
| 2073 Variable* var = definitions_->at(i)->AssignedVar(); | 2155 Variable* var = definitions_->at(i)->AssignedVar(); |
| 2074 variables_[IndexFor(var, variable_count)]->Add(i); | 2156 variables_[IndexFor(var, variable_count)]->Add(i); |
| 2075 } | 2157 } |
| 2076 | 2158 |
| 2077 if (FLAG_print_graph_text) { | 2159 if (FLAG_print_graph_text) { |
| 2078 for (int i = 0; i < variable_count; i++) { | 2160 for (int i = 0; i < variable_count; i++) { |
| 2079 BitVector* def_set = variables_[i]; | 2161 BitVector* def_set = variables_[i]; |
| 2080 if (!def_set->IsEmpty()) { | 2162 if (!def_set->IsEmpty()) { |
| 2081 // At least one definition. | 2163 // At least one definition. |
| 2082 bool first = true; | 2164 bool first = true; |
| 2083 for (int j = 0; j < definition_count; j++) { | 2165 for (int j = 0; j < definition_count; j++) { |
| 2084 if (def_set->Contains(j)) { | 2166 if (def_set->Contains(j)) { |
| 2085 if (first) { | 2167 if (first) { |
| 2086 Variable* var = definitions_->at(j)->AssignedVar(); | 2168 Variable* var = definitions_->at(j)->AssignedVar(); |
| 2087 ASSERT(var != NULL); | 2169 ASSERT(var != NULL); |
| 2088 PrintF("Def[%s] = {%d", *var->name()->ToCString(), j); | 2170 PrintF("Def[%s] = {%d", *var->name()->ToCString(), j); |
| 2089 first = false; | 2171 first = false; |
| 2090 } else { | 2172 } else { |
| 2091 PrintF(", %d", j); | 2173 PrintF(",%d", j); |
| 2092 } | 2174 } |
| 2093 } | 2175 } |
| 2094 } | 2176 } |
| 2095 PrintF("}\n"); | 2177 PrintF("}\n"); |
| 2096 } | 2178 } |
| 2097 } | 2179 } |
| 2098 } | 2180 } |
| 2099 | 2181 |
| 2100 // Step 2: Compute KILL and GEN for each block node, initialize RD_in for | 2182 // Step 2: Compute KILL and GEN for each block node, initialize RD_in for |
| 2101 // all nodes, and mark and add all nodes to the worklist in reverse | 2183 // all nodes, and mark and add all nodes to the worklist in reverse |
| 2102 // postorder. All nodes should currently have the same mark. | 2184 // postorder. All nodes should currently have the same mark. |
| 2103 bool mark = postorder_->at(0)->IsMarkedWith(false); // Negation of current. | 2185 bool mark = postorder_->at(0)->IsMarkedWith(false); // Negation of current. |
| 2104 WorkList<Node> worklist(node_count); | 2186 WorkList<Node> worklist(node_count); |
| 2105 for (int i = node_count - 1; i >= 0; i--) { | 2187 for (int i = node_count - 1; i >= 0; i--) { |
| 2106 postorder_->at(i)->InitializeReachingDefinitions(definition_count, | 2188 postorder_->at(i)->InitializeReachingDefinitions(definition_count, |
| 2107 &variables_, | 2189 &variables_, |
| 2108 &worklist, | 2190 &worklist, |
| 2109 mark); | 2191 mark); |
| 2110 } | 2192 } |
| 2111 | 2193 |
| 2112 // Step 3: Until the worklist is empty, remove an item compute and update | 2194 // Step 3: Until the worklist is empty, remove an item compute and update |
| 2113 // its rd_in based on its predecessor's rd_out. If rd_in has changed, add | 2195 // its rd_in based on its predecessor's rd_out. If rd_in has changed, add |
| 2114 // all necessary successors to the worklist. | 2196 // all necessary successors to the worklist. |
| 2115 while (!worklist.is_empty()) { | 2197 while (!worklist.is_empty()) { |
| 2116 Node* node = worklist.Remove(); | 2198 Node* node = worklist.Remove(); |
| 2117 node->MarkWith(!mark); | 2199 node->MarkWith(!mark); |
| 2118 node->UpdateRDIn(&worklist, mark); | 2200 node->UpdateRDIn(&worklist, mark); |
| 2119 } | 2201 } |
| 2202 | |
| 2203 // Step 4: Based on RD_in for block nodes, propagate reaching definitions | |
| 2204 // to all variable uses in the block. | |
| 2205 for (int i = 0; i < node_count; i++) { | |
| 2206 postorder_->at(i)->PropagateReachingDefinitions(&variables_); | |
| 2207 } | |
| 2120 } | 2208 } |
| 2121 | 2209 |
| 2122 | 2210 |
| 2123 } } // namespace v8::internal | 2211 } } // namespace v8::internal |
| OLD | NEW |