Revision: 4143
Author: [email protected]
Date: Tue Mar 16 03:54:02 2010
Log: Propagate reaching definitions to the instuctions of a block.

After computing RD_in for all flow graph nodes, push the reaching
definitions through the basic blocks to annotate all variable
references in the AST.

Review URL: http://codereview.chromium.org/889003
http://code.google.com/p/v8/source/detail?r=4143

Modified:
 /branches/bleeding_edge/src/ast.cc
 /branches/bleeding_edge/src/ast.h
 /branches/bleeding_edge/src/data-flow.cc
 /branches/bleeding_edge/src/data-flow.h

=======================================
--- /branches/bleeding_edge/src/ast.cc  Fri Mar 12 05:10:42 2010
+++ /branches/bleeding_edge/src/ast.cc  Tue Mar 16 03:54:02 2010
@@ -78,14 +78,16 @@
     var_(NULL),
     is_this_(is_this),
     inside_with_(inside_with),
-    is_trivial_(false) {
+    is_trivial_(false),
+    reaching_definitions_(NULL) {
   // names must be canonicalized for fast equality checks
   ASSERT(name->IsSymbol());
 }


 VariableProxy::VariableProxy(bool is_this)
-  : is_this_(is_this) {
+  : is_this_(is_this),
+    reaching_definitions_(NULL) {
 }


=======================================
--- /branches/bleeding_edge/src/ast.h   Mon Mar 15 07:03:36 2010
+++ /branches/bleeding_edge/src/ast.h   Tue Mar 16 03:54:02 2010
@@ -103,6 +103,7 @@
 class TargetCollector;
 class MaterializedLiteral;
 class DefinitionInfo;
+class BitVector;

 #define DEF_FORWARD_DECLARATION(type) class type;
 AST_NODE_LIST(DEF_FORWARD_DECLARATION)
@@ -1040,6 +1041,9 @@
   bool inside_with() const  { return inside_with_; }
   bool is_trivial() { return is_trivial_; }
   void set_is_trivial(bool b) { is_trivial_ = b; }
+
+  BitVector* reaching_definitions() { return reaching_definitions_; }
+ void set_reaching_definitions(BitVector* rd) { reaching_definitions_ = rd; }

   // Bind this proxy to the variable var.
   void BindTo(Variable* var);
@@ -1050,6 +1054,7 @@
   bool is_this_;
   bool inside_with_;
   bool is_trivial_;
+  BitVector* reaching_definitions_;

   VariableProxy(Handle<String> name, bool is_this, bool inside_with);
   explicit VariableProxy(bool is_this);
=======================================
--- /branches/bleeding_edge/src/data-flow.cc    Fri Mar 12 07:01:05 2010
+++ /branches/bleeding_edge/src/data-flow.cc    Tue Mar 16 03:54:02 2010
@@ -34,6 +34,22 @@
 namespace internal {


+#ifdef DEBUG
+void BitVector::Print() {
+  bool first = true;
+  PrintF("{");
+  for (int i = 0; i < length(); i++) {
+    if (Contains(i)) {
+      if (!first) PrintF(",");
+      first = false;
+      PrintF("%d");
+    }
+  }
+  PrintF("}");
+}
+#endif
+
+
 void FlowGraph::AppendInstruction(AstNode* instruction) {
   // Add a (non-null) AstNode to the end of the graph fragment.
   ASSERT(instruction != NULL);
@@ -357,6 +373,7 @@
   // not both.
   ASSERT(var == NULL || prop == NULL);
   if (var != NULL) {
+    if (expr->is_compound()) Visit(expr->target());
     Visit(expr->value());
     if (var->IsStackAllocated()) {
       expr->set_num(definitions_.length());
@@ -1333,7 +1350,7 @@
     result.Union(av_);
     av_.Clear();
   }
-  av_.CopyFrom(result);
+  av_ = result;
 }


@@ -1345,7 +1362,7 @@
     result.Union(av_);
     av_.Clear();
   }
-  av_.CopyFrom(result);
+  av_ = result;
 }


@@ -1405,7 +1422,7 @@
     Visit(expr->arguments()->at(i));
     result.Union(av_);
   }
-  av_.CopyFrom(result);
+  av_ = result;
 }


@@ -1418,7 +1435,7 @@
     Visit(expr->arguments()->at(i));
     result.Union(av_);
   }
-  av_.CopyFrom(result);
+  av_ = result;
 }


@@ -1430,7 +1447,7 @@
     Visit(expr->arguments()->at(i));
     result.Union(av_);
   }
-  av_.CopyFrom(result);
+  av_ = result;
 }


@@ -1626,6 +1643,9 @@
   Variable* var = expr->AsVariable();
   if (var != NULL) {
     PrintF("%s", *var->name()->ToCString());
+    if (var->IsStackAllocated() && expr->reaching_definitions() != NULL) {
+      expr->reaching_definitions()->Print();
+    }
   } else {
     ASSERT(expr->AsProperty() != NULL);
     VisitProperty(expr->AsProperty());
@@ -1663,30 +1683,50 @@
   Variable* var = expr->target()->AsVariableProxy()->AsVariable();
   Property* prop = expr->target()->AsProperty();

+  if (var == NULL && prop == NULL) {
+    // Throw reference error.
+    Visit(expr->target());
+    return;
+  }
+
+  // Print the left-hand side.
   if (var != NULL) {
-    PrintF("%s %s @%d",
-           *var->name()->ToCString(),
-           Token::String(expr->op()),
-           expr->value()->num());
+    PrintF("%s", *var->name()->ToCString());
   } else if (prop != NULL) {
+    PrintF("@%d", prop->obj()->num());
     if (prop->key()->IsPropertyName()) {
-      PrintF("@%d.", prop->obj()->num());
+      PrintF(".");
       ASSERT(prop->key()->AsLiteral() != NULL);
       prop->key()->AsLiteral()->handle()->Print();
-      PrintF(" %s @%d",
-             Token::String(expr->op()),
-             expr->value()->num());
     } else {
-      PrintF("@%...@%d] %s @%d",
-             prop->obj()->num(),
-             prop->key()->num(),
-             Token::String(expr->op()),
-             expr->value()->num());
-    }
+      PrintF("[...@%d]", prop->key()->num());
+    }
+  }
+
+  // Print the operation.
+  if (expr->is_compound()) {
+    PrintF(" = ");
+    // Print the left-hand side again when compound.
+    if (var != NULL) {
+      PrintF("@%d", expr->target()->num());
+    } else {
+      PrintF("@%d", prop->obj()->num());
+      if (prop->key()->IsPropertyName()) {
+        PrintF(".");
+        ASSERT(prop->key()->AsLiteral() != NULL);
+        prop->key()->AsLiteral()->handle()->Print();
+      } else {
+        PrintF("[...@%d]", prop->key()->num());
+      }
+    }
+    // Print the corresponding binary operator.
+    PrintF(" %s ", Token::String(expr->binary_op()));
   } else {
-    // Throw reference error.
-    Visit(expr->target());
-  }
+    PrintF(" %s ", Token::String(expr->op()));
+  }
+
+  // Print the right-hand side.
+  PrintF("@%d", expr->value()->num());

   if (expr->num() != AstNode::kNoNumber) {
     PrintF(" ;; D%d", expr->num());
@@ -1798,38 +1838,17 @@
   if (rd_.rd_in() != NULL) {
     ASSERT(rd_.kill() != NULL && rd_.gen() != NULL);

-    PrintF("RD_in = {");
-    bool first = true;
-    for (int i = 0; i < rd_.rd_in()->length(); i++) {
-      if (rd_.rd_in()->Contains(i)) {
-        if (!first) PrintF(",");
-        PrintF("%d");
-        first = false;
-      }
-    }
-    PrintF("}\n");
-
-    PrintF("RD_kill = {");
-    first = true;
-    for (int i = 0; i < rd_.kill()->length(); i++) {
-      if (rd_.kill()->Contains(i)) {
-        if (!first) PrintF(",");
-        PrintF("%d");
-        first = false;
-      }
-    }
-    PrintF("}\n");
-
-    PrintF("RD_gen = {");
-    first = true;
-    for (int i = 0; i < rd_.gen()->length(); i++) {
-      if (rd_.gen()->Contains(i)) {
-        if (!first) PrintF(",");
-        PrintF("%d");
-        first = false;
-      }
-    }
-    PrintF("}\n");
+    PrintF("RD_in = ");
+    rd_.rd_in()->Print();
+    PrintF("\n");
+
+    PrintF("RD_kill = ");
+    rd_.kill()->Print();
+    PrintF("\n");
+
+    PrintF("RD_gen = ");
+    rd_.gen()->Print();
+    PrintF("\n");
   }
 }

@@ -1961,7 +1980,7 @@

 void BlockNode::ComputeRDOut(BitVector* result) {
   // All definitions reaching this block ...
-  result->CopyFrom(*rd_.rd_in());
+  *result = *rd_.rd_in();
   // ... except those killed by the block ...
   result->Subtract(*rd_.kill());
   // ... but including those generated by the block.
@@ -1971,13 +1990,13 @@

 void BranchNode::ComputeRDOut(BitVector* result) {
   // Branch nodes don't kill or generate definitions.
-  result->CopyFrom(*rd_.rd_in());
+  *result = *rd_.rd_in();
 }


 void JoinNode::ComputeRDOut(BitVector* result) {
   // Join nodes don't kill or generate definitions.
-  result->CopyFrom(*rd_.rd_in());
+  *result = *rd_.rd_in();
 }


@@ -2008,7 +2027,7 @@
   if (rd_.rd_in()->Equals(new_rd_in)) return;

   // Update RD_in.
-  rd_.rd_in()->CopyFrom(new_rd_in);
+  *rd_.rd_in() = new_rd_in;
   // Add the successor to the worklist if not already present.
   if (!successor_->IsMarkedWith(mark)) {
     successor_->MarkWith(mark);
@@ -2024,7 +2043,7 @@
   if (rd_.rd_in()->Equals(new_rd_in)) return;

   // Update RD_in.
-  rd_.rd_in()->CopyFrom(new_rd_in);
+  *rd_.rd_in() = new_rd_in;
   // Add the successors to the worklist if not already present.
   if (!successor0_->IsMarkedWith(mark)) {
     successor0_->MarkWith(mark);
@@ -2051,13 +2070,73 @@
   if (rd_.rd_in()->Equals(new_rd_in)) return;

   // Update RD_in.
-  rd_.rd_in()->CopyFrom(new_rd_in);
+  *rd_.rd_in() = new_rd_in;
   // Add the successor to the worklist if not already present.
   if (!successor_->IsMarkedWith(mark)) {
     successor_->MarkWith(mark);
     worklist->Insert(successor_);
   }
 }
+
+
+void Node::PropagateReachingDefinitions(List<BitVector*>* variables) {
+  // Nothing to do.
+}
+
+
+void BlockNode::PropagateReachingDefinitions(List<BitVector*>* variables) {
+  // Propagate RD_in from the start of the block to all the variable
+  // references.
+  int variable_count = variables->length();
+  BitVector rd = *rd_.rd_in();
+  for (int i = 0, len = instructions_.length(); i < len; i++) {
+    Expression* expr = instructions_[i]->AsExpression();
+    if (expr == NULL) continue;
+
+    // Look for a variable reference to record its reaching definitions.
+    VariableProxy* proxy = expr->AsVariableProxy();
+    if (proxy == NULL) {
+      // Not a VariableProxy?  Maybe it's a count operation.
+      CountOperation* count_operation = expr->AsCountOperation();
+      if (count_operation != NULL) {
+        proxy = count_operation->expression()->AsVariableProxy();
+      }
+    }
+    if (proxy == NULL) {
+      // OK, Maybe it's a compound assignment.
+      Assignment* assignment = expr->AsAssignment();
+      if (assignment != NULL && assignment->is_compound()) {
+        proxy = assignment->target()->AsVariableProxy();
+      }
+    }
+
+    if (proxy != NULL &&
+        proxy->var()->IsStackAllocated() &&
+        !proxy->var()->is_this()) {
+      // All definitions for this variable.
+      BitVector* definitions =
+          variables->at(ReachingDefinitions::IndexFor(proxy->var(),
+                                                      variable_count));
+      BitVector* reaching_definitions = new BitVector(*definitions);
+      // Intersected with all definitions (of any variable) reaching this
+      // instruction.
+      reaching_definitions->Intersect(rd);
+      proxy->set_reaching_definitions(reaching_definitions);
+    }
+
+    // It may instead (or also) be a definition.  If so update the running
+    // value of reaching definitions for the block.
+    Variable* var = expr->AssignedVar();
+    if (var == NULL || !var->IsStackAllocated()) continue;
+
+    // All definitions of this variable are killed.
+    BitVector* def_set =
+        variables->at(ReachingDefinitions::IndexFor(var, variable_count));
+    rd.Subtract(*def_set);
+    // This definition is generated.
+    rd.Add(expr->num());
+  }
+}


 void ReachingDefinitions::Compute() {
@@ -2088,7 +2167,7 @@
               PrintF("Def[%s] = {%d", *var->name()->ToCString(), j);
               first = false;
             } else {
-              PrintF(", %d", j);
+              PrintF(",%d", j);
             }
           }
         }
@@ -2117,6 +2196,12 @@
     node->MarkWith(!mark);
     node->UpdateRDIn(&worklist, mark);
   }
+
+  // Step 4: Based on RD_in for block nodes, propagate reaching definitions
+  // to all variable uses in the block.
+  for (int i = 0; i < node_count; i++) {
+    postorder_->at(i)->PropagateReachingDefinitions(&variables_);
+  }
 }


=======================================
--- /branches/bleeding_edge/src/data-flow.h     Fri Mar 12 02:39:31 2010
+++ /branches/bleeding_edge/src/data-flow.h     Tue Mar 16 03:54:02 2010
@@ -128,6 +128,10 @@
   }

   int length() const { return length_; }
+
+#ifdef DEBUG
+  void Print();
+#endif

  private:
   int length_;
@@ -235,6 +239,7 @@
                                              bool mark);
   virtual void ComputeRDOut(BitVector* result) = 0;
   virtual void UpdateRDIn(WorkList<Node>* worklist, bool mark) = 0;
+  virtual void PropagateReachingDefinitions(List<BitVector*>* variables);

 #ifdef DEBUG
   void AssignNodeNumber();
@@ -324,6 +329,7 @@
                                      bool mark);
   void ComputeRDOut(BitVector* result);
   void UpdateRDIn(WorkList<Node>* worklist, bool mark);
+  void PropagateReachingDefinitions(List<BitVector*>* variables);

 #ifdef DEBUG
   void PrintText();

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to