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 |