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 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 void FlowGraphBuilder::VisitAssignment(Assignment* expr) { | 369 void FlowGraphBuilder::VisitAssignment(Assignment* expr) { |
| 370 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 370 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
| 371 Property* prop = expr->target()->AsProperty(); | 371 Property* prop = expr->target()->AsProperty(); |
| 372 // 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 |
| 373 // not both. | 373 // not both. |
| 374 ASSERT(var == NULL || prop == NULL); | 374 ASSERT(var == NULL || prop == NULL); |
| 375 if (var != NULL) { | 375 if (var != NULL) { |
| 376 if (expr->is_compound()) Visit(expr->target()); | 376 if (expr->is_compound()) Visit(expr->target()); |
| 377 Visit(expr->value()); | 377 Visit(expr->value()); |
| 378 if (var->IsStackAllocated()) { | 378 if (var->IsStackAllocated()) { |
| 379 expr->set_num(definitions_.length()); | 379 // The first definition in the body is numbered n, where n is the |
| 380 definitions_.Add(expr); | 380 // number of parameters and stack-allocated locals. |
| 381 expr->set_num(body_definitions_.length() + variable_count_); | |
| 382 body_definitions_.Add(expr); | |
| 381 } | 383 } |
| 382 | 384 |
| 383 } else if (prop != NULL) { | 385 } else if (prop != NULL) { |
| 384 Visit(prop->obj()); | 386 Visit(prop->obj()); |
| 385 if (!prop->key()->IsPropertyName()) Visit(prop->key()); | 387 if (!prop->key()->IsPropertyName()) Visit(prop->key()); |
| 386 Visit(expr->value()); | 388 Visit(expr->value()); |
| 387 } | 389 } |
| 388 | 390 |
| 389 if (HasStackOverflow()) return; | 391 if (HasStackOverflow()) return; |
| 390 graph_.AppendInstruction(expr); | 392 graph_.AppendInstruction(expr); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 447 default: | 449 default: |
| 448 UNREACHABLE(); | 450 UNREACHABLE(); |
| 449 } | 451 } |
| 450 } | 452 } |
| 451 | 453 |
| 452 | 454 |
| 453 void FlowGraphBuilder::VisitCountOperation(CountOperation* expr) { | 455 void FlowGraphBuilder::VisitCountOperation(CountOperation* expr) { |
| 454 Visit(expr->expression()); | 456 Visit(expr->expression()); |
| 455 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); | 457 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); |
| 456 if (var != NULL && var->IsStackAllocated()) { | 458 if (var != NULL && var->IsStackAllocated()) { |
| 457 expr->set_num(definitions_.length()); | 459 // The first definition in the body is numbered n, where n is the number |
| 458 definitions_.Add(expr); | 460 // of parameters and stack-allocated locals. |
| 461 expr->set_num(body_definitions_.length() + variable_count_); | |
| 462 body_definitions_.Add(expr); | |
| 459 } | 463 } |
| 460 | 464 |
| 461 if (HasStackOverflow()) return; | 465 if (HasStackOverflow()) return; |
| 462 graph_.AppendInstruction(expr); | 466 graph_.AppendInstruction(expr); |
| 463 } | 467 } |
| 464 | 468 |
| 465 | 469 |
| 466 void FlowGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { | 470 void FlowGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { |
| 467 switch (expr->op()) { | 471 switch (expr->op()) { |
| 468 case Token::COMMA: | 472 case Token::COMMA: |
| (...skipping 1188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1657 | 1661 |
| 1658 void BlockNode::InitializeReachingDefinitions(int definition_count, | 1662 void BlockNode::InitializeReachingDefinitions(int definition_count, |
| 1659 List<BitVector*>* variables, | 1663 List<BitVector*>* variables, |
| 1660 WorkList<Node>* worklist, | 1664 WorkList<Node>* worklist, |
| 1661 bool mark) { | 1665 bool mark) { |
| 1662 ASSERT(!IsMarkedWith(mark)); | 1666 ASSERT(!IsMarkedWith(mark)); |
| 1663 int instruction_count = instructions_.length(); | 1667 int instruction_count = instructions_.length(); |
| 1664 int variable_count = variables->length(); | 1668 int variable_count = variables->length(); |
| 1665 | 1669 |
| 1666 rd_.Initialize(definition_count); | 1670 rd_.Initialize(definition_count); |
| 1671 // The RD_in set for the entry node has a definition for each parameter | |
| 1672 // and local. | |
| 1673 if (predecessor_ == NULL) { | |
| 1674 for (int i = 0; i < variable_count; i++) rd_.rd_in()->Add(i); | |
| 1675 } | |
| 1667 | 1676 |
| 1668 for (int i = 0; i < instruction_count; i++) { | 1677 for (int i = 0; i < instruction_count; i++) { |
| 1669 Expression* expr = instructions_[i]->AsExpression(); | 1678 Expression* expr = instructions_[i]->AsExpression(); |
| 1670 if (expr == NULL) continue; | 1679 if (expr == NULL) continue; |
| 1671 Variable* var = expr->AssignedVar(); | 1680 Variable* var = expr->AssignedVar(); |
| 1672 if (var == NULL || !var->IsStackAllocated()) continue; | 1681 if (var == NULL || !var->IsStackAllocated()) continue; |
| 1673 | 1682 |
| 1674 // All definitions of this variable are killed. | 1683 // All definitions of this variable are killed. |
| 1675 BitVector* def_set = | 1684 BitVector* def_set = |
| 1676 variables->at(ReachingDefinitions::IndexFor(var, variable_count)); | 1685 variables->at(ReachingDefinitions::IndexFor(var, variable_count)); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1852 BitVector* def_set = | 1861 BitVector* def_set = |
| 1853 variables->at(ReachingDefinitions::IndexFor(var, variable_count)); | 1862 variables->at(ReachingDefinitions::IndexFor(var, variable_count)); |
| 1854 rd.Subtract(*def_set); | 1863 rd.Subtract(*def_set); |
| 1855 // This definition is generated. | 1864 // This definition is generated. |
| 1856 rd.Add(expr->num()); | 1865 rd.Add(expr->num()); |
| 1857 } | 1866 } |
| 1858 } | 1867 } |
| 1859 | 1868 |
| 1860 | 1869 |
| 1861 void ReachingDefinitions::Compute() { | 1870 void ReachingDefinitions::Compute() { |
| 1862 ASSERT(!definitions_->is_empty()); | 1871 // The definitions in the body plus an implicit definition for each |
| 1863 | 1872 // variable at function entry. |
| 1864 int variable_count = variables_.length(); | 1873 int definition_count = body_definitions_->length() + variable_count_; |
| 1865 int definition_count = definitions_->length(); | |
| 1866 int node_count = postorder_->length(); | 1874 int node_count = postorder_->length(); |
| 1867 | 1875 |
| 1868 // Step 1: For each variable, identify the set of all its definitions in | 1876 // Step 1: For each (stack-allocated) variable, identify the set of all |
|
fschneider
2010/03/22 13:49:29
We don't handle any other variables? Maybe change
Kevin Millikin (Chromium)
2010/03/22 14:06:40
Done.
| |
| 1869 // the body. | 1877 // its definitions. |
| 1870 for (int i = 0; i < definition_count; i++) { | 1878 List<BitVector*> variables; |
| 1871 Variable* var = definitions_->at(i)->AssignedVar(); | 1879 for (int i = 0; i < variable_count_; i++) { |
| 1872 variables_[IndexFor(var, variable_count)]->Add(i); | 1880 // Add the initial definition for each variable. |
| 1881 BitVector* initial = new BitVector(definition_count); | |
| 1882 initial->Add(i); | |
| 1883 variables.Add(initial); | |
| 1873 } | 1884 } |
| 1874 | 1885 for (int i = 0, len = body_definitions_->length(); i < len; i++) { |
| 1875 if (FLAG_print_graph_text) { | 1886 // Account for each definition in the body as a definition of the |
| 1876 for (int i = 0; i < variable_count; i++) { | 1887 // defined variable. |
| 1877 BitVector* def_set = variables_[i]; | 1888 Variable* var = body_definitions_->at(i)->AssignedVar(); |
| 1878 if (!def_set->IsEmpty()) { | 1889 variables[IndexFor(var, variable_count_)]->Add(i + variable_count_); |
|
fschneider
2010/03/22 13:49:29
variables->at(IndexFor(var, variable_count_))
for
Kevin Millikin (Chromium)
2010/03/22 14:06:40
It would be variables.at(...). I'll leave it with
| |
| 1879 // At least one definition. | |
| 1880 bool first = true; | |
| 1881 for (int j = 0; j < definition_count; j++) { | |
| 1882 if (def_set->Contains(j)) { | |
| 1883 if (first) { | |
| 1884 Variable* var = definitions_->at(j)->AssignedVar(); | |
| 1885 ASSERT(var != NULL); | |
| 1886 PrintF("Def[%s] = {%d", *var->name()->ToCString(), j); | |
| 1887 first = false; | |
| 1888 } else { | |
| 1889 PrintF(",%d", j); | |
| 1890 } | |
| 1891 } | |
| 1892 } | |
| 1893 PrintF("}\n"); | |
| 1894 } | |
| 1895 } | |
| 1896 } | 1890 } |
| 1897 | 1891 |
| 1898 // Step 2: Compute KILL and GEN for each block node, initialize RD_in for | 1892 // Step 2: Compute KILL and GEN for each block node, initialize RD_in for |
| 1899 // all nodes, and mark and add all nodes to the worklist in reverse | 1893 // all nodes, and mark and add all nodes to the worklist in reverse |
| 1900 // postorder. All nodes should currently have the same mark. | 1894 // postorder. All nodes should currently have the same mark. |
| 1901 bool mark = postorder_->at(0)->IsMarkedWith(false); // Negation of current. | 1895 bool mark = postorder_->at(0)->IsMarkedWith(false); // Negation of current. |
| 1902 WorkList<Node> worklist(node_count); | 1896 WorkList<Node> worklist(node_count); |
| 1903 for (int i = node_count - 1; i >= 0; i--) { | 1897 for (int i = node_count - 1; i >= 0; i--) { |
| 1904 postorder_->at(i)->InitializeReachingDefinitions(definition_count, | 1898 postorder_->at(i)->InitializeReachingDefinitions(definition_count, |
| 1905 &variables_, | 1899 &variables, |
| 1906 &worklist, | 1900 &worklist, |
| 1907 mark); | 1901 mark); |
| 1908 } | 1902 } |
| 1909 | 1903 |
| 1910 // Step 3: Until the worklist is empty, remove an item compute and update | 1904 // Step 3: Until the worklist is empty, remove an item compute and update |
| 1911 // its rd_in based on its predecessor's rd_out. If rd_in has changed, add | 1905 // its rd_in based on its predecessor's rd_out. If rd_in has changed, add |
| 1912 // all necessary successors to the worklist. | 1906 // all necessary successors to the worklist. |
| 1913 while (!worklist.is_empty()) { | 1907 while (!worklist.is_empty()) { |
| 1914 Node* node = worklist.Remove(); | 1908 Node* node = worklist.Remove(); |
| 1915 node->MarkWith(!mark); | 1909 node->MarkWith(!mark); |
| 1916 node->UpdateRDIn(&worklist, mark); | 1910 node->UpdateRDIn(&worklist, mark); |
| 1917 } | 1911 } |
| 1918 | 1912 |
| 1919 // Step 4: Based on RD_in for block nodes, propagate reaching definitions | 1913 // Step 4: Based on RD_in for block nodes, propagate reaching definitions |
| 1920 // to all variable uses in the block. | 1914 // to all variable uses in the block. |
| 1921 for (int i = 0; i < node_count; i++) { | 1915 for (int i = 0; i < node_count; i++) { |
| 1922 postorder_->at(i)->PropagateReachingDefinitions(&variables_); | 1916 postorder_->at(i)->PropagateReachingDefinitions(&variables); |
| 1923 } | 1917 } |
| 1924 } | 1918 } |
| 1925 | 1919 |
| 1926 | 1920 |
| 1927 } } // namespace v8::internal | 1921 } } // namespace v8::internal |
| OLD | NEW |