Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(485)

Side by Side Diff: src/data-flow.cc

Issue 889003: Propagate reaching definitions to the instuctions of a block. (Closed)
Patch Set: Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/data-flow.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/data-flow.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698