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

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

Issue 853004: Compute reaching definitions. (Closed)
Patch Set: Leave entry node off the worklist. 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 1884 matching lines...) Expand 10 before | Expand all | Expand 10 after
1895 Slot* slot = var->slot(); 1895 Slot* slot = var->slot();
1896 if (slot->type() == Slot::PARAMETER) { 1896 if (slot->type() == Slot::PARAMETER) {
1897 return slot->index(); 1897 return slot->index();
1898 } else { 1898 } else {
1899 return (variable_count - 1) - slot->index(); 1899 return (variable_count - 1) - slot->index();
1900 } 1900 }
1901 } 1901 }
1902 1902
1903 1903
1904 void Node::InitializeReachingDefinitions(int definition_count, 1904 void Node::InitializeReachingDefinitions(int definition_count,
1905 List<BitVector*>* variables) { 1905 List<BitVector*>* variables,
1906 WorkList<Node>* worklist,
1907 bool mark) {
1908 ASSERT(!IsMarkedWith(mark));
1906 rd_.Initialize(definition_count); 1909 rd_.Initialize(definition_count);
1910 MarkWith(mark);
1911 worklist->Insert(this);
1907 } 1912 }
1908 1913
1909 1914
1910 void BlockNode::InitializeReachingDefinitions(int definition_count, 1915 void BlockNode::InitializeReachingDefinitions(int definition_count,
1911 List<BitVector*>* variables) { 1916 List<BitVector*>* variables,
1917 WorkList<Node>* worklist,
1918 bool mark) {
1919 ASSERT(!IsMarkedWith(mark));
1912 int instruction_count = instructions_.length(); 1920 int instruction_count = instructions_.length();
1913 int variable_count = variables->length(); 1921 int variable_count = variables->length();
1914 1922
1915 rd_.Initialize(definition_count); 1923 rd_.Initialize(definition_count);
1916 1924
1917 for (int i = 0; i < instruction_count; i++) { 1925 for (int i = 0; i < instruction_count; i++) {
1918 Expression* expr = instructions_[i]->AsExpression(); 1926 Expression* expr = instructions_[i]->AsExpression();
1919 if (expr == NULL) continue; 1927 if (expr == NULL) continue;
1920 Variable* var = expr->AssignedVar(); 1928 Variable* var = expr->AssignedVar();
1921 if (var == NULL) continue; 1929 if (var == NULL) continue;
1922 1930
1923 // All definitions of this variable are killed. 1931 // All definitions of this variable are killed.
1924 BitVector* def_set = 1932 BitVector* def_set =
1925 variables->at(ReachingDefinitions::IndexFor(var, variable_count)); 1933 variables->at(ReachingDefinitions::IndexFor(var, variable_count));
1926 rd_.kill()->Union(*def_set); 1934 rd_.kill()->Union(*def_set);
1927 1935
1928 // All previously generated definitions are not generated. 1936 // All previously generated definitions are not generated.
1929 rd_.gen()->Subtract(*def_set); 1937 rd_.gen()->Subtract(*def_set);
1930 1938
1931 // This one is generated. 1939 // This one is generated.
1932 rd_.gen()->Add(expr->num()); 1940 rd_.gen()->Add(expr->num());
1933 } 1941 }
1942
1943 if (predecessor_ != NULL) {
1944 MarkWith(mark);
1945 worklist->Insert(this);
1946 }
1934 } 1947 }
1935 1948
1936 1949
1950 void ExitNode::ComputeRDOut(BitVector* result) {
1951 // Should not be the predecessor of any node.
1952 UNREACHABLE();
1953 }
1954
1955
1956 void BlockNode::ComputeRDOut(BitVector* result) {
1957 // All definitions reaching this block ...
1958 result->CopyFrom(*rd_.rd_in());
1959 // ... except those killed by the block ...
1960 result->Subtract(*rd_.kill());
1961 // ... but including those generated by the block.
1962 result->Union(*rd_.gen());
1963 }
1964
1965
1966 void BranchNode::ComputeRDOut(BitVector* result) {
1967 // Branch nodes don't kill or generate definitions.
1968 result->CopyFrom(*rd_.rd_in());
1969 }
1970
1971
1972 void JoinNode::ComputeRDOut(BitVector* result) {
1973 // Join nodes don't kill or generate definitions.
1974 result->CopyFrom(*rd_.rd_in());
1975 }
1976
1977
1978 void ExitNode::UpdateRDIn(WorkList<Node>* worklist, bool mark) {
1979 // The exit node has no successors so we can just update in place. New
1980 // RD_in is the union over all predecessors.
1981 int definition_count = rd_.rd_in()->length();
1982 rd_.rd_in()->Clear();
1983 for (int i = 0, len = predecessors_.length(); i < len; i++) {
1984 BitVector temp(definition_count);
1985 predecessors_[i]->ComputeRDOut(&temp);
1986 rd_.rd_in()->Union(temp);
1987 }
1988 }
1989
1990
1991 void BlockNode::UpdateRDIn(WorkList<Node>* worklist, bool mark) {
1992 // The entry block has no predecessor. Its RD_in does not change.
1993 if (predecessor_ == NULL) return;
1994
1995 BitVector new_rd_in(rd_.rd_in()->length());
1996 predecessor_->ComputeRDOut(&new_rd_in);
1997
1998 if (rd_.rd_in()->Equals(new_rd_in)) return;
1999
2000 // Update RD_in.
2001 rd_.rd_in()->CopyFrom(new_rd_in);
2002 // Add the successor to the worklist if not already present.
2003 if (!successor_->IsMarkedWith(mark)) {
2004 successor_->MarkWith(mark);
2005 worklist->Insert(successor_);
2006 }
2007 }
2008
2009
2010 void BranchNode::UpdateRDIn(WorkList<Node>* worklist, bool mark) {
2011 BitVector new_rd_in(rd_.rd_in()->length());
2012 predecessor_->ComputeRDOut(&new_rd_in);
2013
2014 if (rd_.rd_in()->Equals(new_rd_in)) return;
2015
2016 // Update RD_in.
2017 rd_.rd_in()->CopyFrom(new_rd_in);
2018 // Add the successors to the worklist if not already present.
2019 if (!successor0_->IsMarkedWith(mark)) {
2020 successor0_->MarkWith(mark);
2021 worklist->Insert(successor0_);
2022 }
2023 if (!successor1_->IsMarkedWith(mark)) {
2024 successor1_->MarkWith(mark);
2025 worklist->Insert(successor1_);
2026 }
2027 }
2028
2029
2030 void JoinNode::UpdateRDIn(WorkList<Node>* worklist, bool mark) {
2031 int definition_count = rd_.rd_in()->length();
2032 BitVector new_rd_in(definition_count);
2033
2034 // New RD_in is the union over all predecessors.
2035 for (int i = 0, len = predecessors_.length(); i < len; i++) {
2036 BitVector temp(definition_count);
2037 predecessors_[i]->ComputeRDOut(&temp);
2038 new_rd_in.Union(temp);
2039 }
2040
2041 if (rd_.rd_in()->Equals(new_rd_in)) return;
2042
2043 // Update RD_in.
2044 rd_.rd_in()->CopyFrom(new_rd_in);
2045 // Add the successor to the worklist if not already present.
2046 if (!successor_->IsMarkedWith(mark)) {
2047 successor_->MarkWith(mark);
2048 worklist->Insert(successor_);
2049 }
2050 }
2051
2052
1937 void ReachingDefinitions::Compute() { 2053 void ReachingDefinitions::Compute() {
1938 if (definitions_->is_empty()) return; 2054 if (definitions_->is_empty()) return;
1939 2055
1940 int variable_count = variables_.length(); 2056 int variable_count = variables_.length();
1941 int definition_count = definitions_->length(); 2057 int definition_count = definitions_->length();
1942 int block_count = postorder_->length(); 2058 int node_count = postorder_->length();
1943 2059
1944 // Step 1: For each variable, identify the set of all its definitions in 2060 // Step 1: For each variable, identify the set of all its definitions in
1945 // the body. 2061 // the body.
1946 for (int i = 0; i < definition_count; i++) { 2062 for (int i = 0; i < definition_count; i++) {
1947 Variable* var = definitions_->at(i)->AssignedVar(); 2063 Variable* var = definitions_->at(i)->AssignedVar();
1948 variables_[IndexFor(var, variable_count)]->Add(i); 2064 variables_[IndexFor(var, variable_count)]->Add(i);
1949 } 2065 }
1950 2066
1951 if (FLAG_print_graph_text) { 2067 if (FLAG_print_graph_text) {
1952 for (int i = 0; i < variable_count; i++) { 2068 for (int i = 0; i < variable_count; i++) {
(...skipping 11 matching lines...) Expand all
1964 } else { 2080 } else {
1965 PrintF(", %d", j); 2081 PrintF(", %d", j);
1966 } 2082 }
1967 } 2083 }
1968 } 2084 }
1969 PrintF("}\n"); 2085 PrintF("}\n");
1970 } 2086 }
1971 } 2087 }
1972 } 2088 }
1973 2089
1974 // Step 2: Compute KILL and GEN for each block node, initialize RD. 2090 // Step 2: Compute KILL and GEN for each block node, initialize RD_in for
1975 for (int i = block_count - 1; i >= 0; i--) { 2091 // all nodes, and mark and add all nodes to the worklist in reverse
2092 // postorder. All nodes should currently have the same mark.
2093 bool mark = postorder_->at(0)->IsMarkedWith(false); // Negation of current.
2094 WorkList<Node> worklist(node_count);
2095 for (int i = node_count - 1; i >= 0; i--) {
1976 postorder_->at(i)->InitializeReachingDefinitions(definition_count, 2096 postorder_->at(i)->InitializeReachingDefinitions(definition_count,
1977 &variables_); 2097 &variables_,
2098 &worklist,
2099 mark);
2100 }
2101
2102 // Step 3: Until the worklist is empty, remove an item compute and update
2103 // its rd_in based on its predecessor's rd_out. If rd_in has changed, add
2104 // all necessary successors to the worklist.
2105 while (!worklist.is_empty()) {
2106 Node* node = worklist.Remove();
2107 node->MarkWith(!mark);
2108 node->UpdateRDIn(&worklist, mark);
1978 } 2109 }
1979 } 2110 }
1980 2111
1981 2112
1982 } } // namespace v8::internal 2113 } } // 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