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 |