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

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

Issue 1155006: Include initial definitions in reaching definitions analysis. (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 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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