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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/data-flow.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/data-flow.cc
diff --git a/src/data-flow.cc b/src/data-flow.cc
index 434991c8dd34ece0251677f5bee159d32a5a74f2..7cdc46f3ca143e1249b08b1341905efee6d54b15 100644
--- a/src/data-flow.cc
+++ b/src/data-flow.cc
@@ -1902,13 +1902,21 @@ int ReachingDefinitions::IndexFor(Variable* var, int variable_count) {
void Node::InitializeReachingDefinitions(int definition_count,
- List<BitVector*>* variables) {
+ List<BitVector*>* variables,
+ WorkList<Node>* worklist,
+ bool mark) {
+ ASSERT(!IsMarkedWith(mark));
rd_.Initialize(definition_count);
+ MarkWith(mark);
+ worklist->Insert(this);
}
void BlockNode::InitializeReachingDefinitions(int definition_count,
- List<BitVector*>* variables) {
+ List<BitVector*>* variables,
+ WorkList<Node>* worklist,
+ bool mark) {
+ ASSERT(!IsMarkedWith(mark));
int instruction_count = instructions_.length();
int variable_count = variables->length();
@@ -1931,6 +1939,114 @@ void BlockNode::InitializeReachingDefinitions(int definition_count,
// This one is generated.
rd_.gen()->Add(expr->num());
}
+
+ if (predecessor_ != NULL) {
+ MarkWith(mark);
+ worklist->Insert(this);
+ }
+}
+
+
+void ExitNode::ComputeRDOut(BitVector* result) {
+ // Should not be the predecessor of any node.
+ UNREACHABLE();
+}
+
+
+void BlockNode::ComputeRDOut(BitVector* result) {
+ // All definitions reaching this block ...
+ result->CopyFrom(*rd_.rd_in());
+ // ... except those killed by the block ...
+ result->Subtract(*rd_.kill());
+ // ... but including those generated by the block.
+ result->Union(*rd_.gen());
+}
+
+
+void BranchNode::ComputeRDOut(BitVector* result) {
+ // Branch nodes don't kill or generate definitions.
+ result->CopyFrom(*rd_.rd_in());
+}
+
+
+void JoinNode::ComputeRDOut(BitVector* result) {
+ // Join nodes don't kill or generate definitions.
+ result->CopyFrom(*rd_.rd_in());
+}
+
+
+void ExitNode::UpdateRDIn(WorkList<Node>* worklist, bool mark) {
+ // The exit node has no successors so we can just update in place. New
+ // RD_in is the union over all predecessors.
+ int definition_count = rd_.rd_in()->length();
+ rd_.rd_in()->Clear();
+ for (int i = 0, len = predecessors_.length(); i < len; i++) {
+ BitVector temp(definition_count);
+ predecessors_[i]->ComputeRDOut(&temp);
+ rd_.rd_in()->Union(temp);
+ }
+}
+
+
+void BlockNode::UpdateRDIn(WorkList<Node>* worklist, bool mark) {
+ // The entry block has no predecessor. Its RD_in does not change.
+ if (predecessor_ == NULL) return;
+
+ BitVector new_rd_in(rd_.rd_in()->length());
+ predecessor_->ComputeRDOut(&new_rd_in);
+
+ if (rd_.rd_in()->Equals(new_rd_in)) return;
+
+ // Update RD_in.
+ rd_.rd_in()->CopyFrom(new_rd_in);
+ // Add the successor to the worklist if not already present.
+ if (!successor_->IsMarkedWith(mark)) {
+ successor_->MarkWith(mark);
+ worklist->Insert(successor_);
+ }
+}
+
+
+void BranchNode::UpdateRDIn(WorkList<Node>* worklist, bool mark) {
+ BitVector new_rd_in(rd_.rd_in()->length());
+ predecessor_->ComputeRDOut(&new_rd_in);
+
+ if (rd_.rd_in()->Equals(new_rd_in)) return;
+
+ // Update RD_in.
+ rd_.rd_in()->CopyFrom(new_rd_in);
+ // Add the successors to the worklist if not already present.
+ if (!successor0_->IsMarkedWith(mark)) {
+ successor0_->MarkWith(mark);
+ worklist->Insert(successor0_);
+ }
+ if (!successor1_->IsMarkedWith(mark)) {
+ successor1_->MarkWith(mark);
+ worklist->Insert(successor1_);
+ }
+}
+
+
+void JoinNode::UpdateRDIn(WorkList<Node>* worklist, bool mark) {
+ int definition_count = rd_.rd_in()->length();
+ BitVector new_rd_in(definition_count);
+
+ // New RD_in is the union over all predecessors.
+ for (int i = 0, len = predecessors_.length(); i < len; i++) {
+ BitVector temp(definition_count);
+ predecessors_[i]->ComputeRDOut(&temp);
+ new_rd_in.Union(temp);
+ }
+
+ if (rd_.rd_in()->Equals(new_rd_in)) return;
+
+ // Update RD_in.
+ rd_.rd_in()->CopyFrom(new_rd_in);
+ // Add the successor to the worklist if not already present.
+ if (!successor_->IsMarkedWith(mark)) {
+ successor_->MarkWith(mark);
+ worklist->Insert(successor_);
+ }
}
@@ -1939,7 +2055,7 @@ void ReachingDefinitions::Compute() {
int variable_count = variables_.length();
int definition_count = definitions_->length();
- int block_count = postorder_->length();
+ int node_count = postorder_->length();
// Step 1: For each variable, identify the set of all its definitions in
// the body.
@@ -1971,10 +2087,25 @@ void ReachingDefinitions::Compute() {
}
}
- // Step 2: Compute KILL and GEN for each block node, initialize RD.
- for (int i = block_count - 1; i >= 0; i--) {
+ // Step 2: Compute KILL and GEN for each block node, initialize RD_in for
+ // all nodes, and mark and add all nodes to the worklist in reverse
+ // postorder. All nodes should currently have the same mark.
+ bool mark = postorder_->at(0)->IsMarkedWith(false); // Negation of current.
+ WorkList<Node> worklist(node_count);
+ for (int i = node_count - 1; i >= 0; i--) {
postorder_->at(i)->InitializeReachingDefinitions(definition_count,
- &variables_);
+ &variables_,
+ &worklist,
+ mark);
+ }
+
+ // Step 3: Until the worklist is empty, remove an item compute and update
+ // its rd_in based on its predecessor's rd_out. If rd_in has changed, add
+ // all necessary successors to the worklist.
+ while (!worklist.is_empty()) {
+ Node* node = worklist.Remove();
+ node->MarkWith(!mark);
+ node->UpdateRDIn(&worklist, mark);
}
}
« 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