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

Unified Diff: src/data-flow.cc

Issue 876001: Initialize reaching definitions state for all flow graph nodes. (Closed)
Patch Set: Incorporated review comments. 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 0561677884a5790122e24a9fa173f30863849b02..434991c8dd34ece0251677f5bee159d32a5a74f2 100644
--- a/src/data-flow.cc
+++ b/src/data-flow.cc
@@ -133,14 +133,14 @@ void BranchNode::Traverse(bool mark,
ZoneList<Node*>* postorder) {
ASSERT(successor0_ != NULL && successor1_ != NULL);
preorder->Add(this);
- if (!successor0_->IsMarkedWith(mark)) {
- successor0_->MarkWith(mark);
- successor0_->Traverse(mark, preorder, postorder);
- }
if (!successor1_->IsMarkedWith(mark)) {
successor1_->MarkWith(mark);
successor1_->Traverse(mark, preorder, postorder);
}
+ if (!successor0_->IsMarkedWith(mark)) {
+ successor0_->MarkWith(mark);
+ successor0_->Traverse(mark, preorder, postorder);
+ }
postorder->Add(this);
}
@@ -358,7 +358,10 @@ void FlowGraphBuilder::VisitAssignment(Assignment* expr) {
ASSERT(var == NULL || prop == NULL);
if (var != NULL) {
Visit(expr->value());
- if (var->IsStackAllocated()) definitions_.Add(expr);
+ if (var->IsStackAllocated()) {
+ expr->set_num(definitions_.length());
+ definitions_.Add(expr);
+ }
} else if (prop != NULL) {
Visit(prop->obj());
@@ -434,6 +437,7 @@ void FlowGraphBuilder::VisitCountOperation(CountOperation* expr) {
Visit(expr->expression());
Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
if (var != NULL && var->IsStackAllocated()) {
+ expr->set_num(definitions_.length());
definitions_.Add(expr);
}
@@ -1483,7 +1487,10 @@ void AssignedVariablesAnalyzer::VisitDeclaration(Declaration* decl) {
// only used for printing in debug mode.
class TextInstructionPrinter: public AstVisitor {
public:
- TextInstructionPrinter() {}
+ TextInstructionPrinter() : number_(0) {}
+
+ int NextNumber() { return number_; }
+ void AssignNumber(AstNode* node) { node->set_num(number_++); }
private:
// AST node visit functions.
@@ -1491,6 +1498,8 @@ class TextInstructionPrinter: public AstVisitor {
AST_NODE_LIST(DECLARE_VISIT)
#undef DECLARE_VISIT
+ int number_;
+
DISALLOW_COPY_AND_ASSIGN(TextInstructionPrinter);
};
@@ -1611,8 +1620,7 @@ void TextInstructionPrinter::VisitSlot(Slot* expr) {
void TextInstructionPrinter::VisitVariableProxy(VariableProxy* expr) {
Variable* var = expr->AsVariable();
if (var != NULL) {
- SmartPointer<char> name = var->name()->ToCString();
- PrintF("%s", *name);
+ PrintF("%s", *var->name()->ToCString());
} else {
ASSERT(expr->AsProperty() != NULL);
VisitProperty(expr->AsProperty());
@@ -1651,9 +1659,8 @@ void TextInstructionPrinter::VisitAssignment(Assignment* expr) {
Property* prop = expr->target()->AsProperty();
if (var != NULL) {
- SmartPointer<char> name = var->name()->ToCString();
PrintF("%s %s @%d",
- *name,
+ *var->name()->ToCString(),
Token::String(expr->op()),
expr->value()->num());
} else if (prop != NULL) {
@@ -1675,6 +1682,10 @@ void TextInstructionPrinter::VisitAssignment(Assignment* expr) {
// Throw reference error.
Visit(expr->target());
}
+
+ if (expr->num() != AstNode::kNoNumber) {
+ PrintF(" ;; D%d", expr->num());
+ }
}
@@ -1717,8 +1728,7 @@ void TextInstructionPrinter::VisitCallNew(CallNew* expr) {
void TextInstructionPrinter::VisitCallRuntime(CallRuntime* expr) {
- SmartPointer<char> name = expr->name()->ToCString();
- PrintF("%s(", *name);
+ PrintF("%s(", *expr->name()->ToCString());
ZoneList<Expression*>* arguments = expr->arguments();
for (int i = 0, len = arguments->length(); i < len; i++) {
if (i != 0) PrintF(", ");
@@ -1739,6 +1749,10 @@ void TextInstructionPrinter::VisitCountOperation(CountOperation* expr) {
} else {
PrintF("@%d%s", expr->expression()->num(), Token::String(expr->op()));
}
+
+ if (expr->num() != AstNode::kNoNumber) {
+ PrintF(" ;; D%d", expr->num());
+ }
}
@@ -1770,31 +1784,66 @@ static int node_count = 0;
static int instruction_count = 0;
-void Node::AssignNumbers() {
+void Node::AssignNodeNumber() {
set_number(node_count++);
}
-void BlockNode::AssignNumbers() {
- set_number(node_count++);
- for (int i = 0, len = instructions_.length(); i < len; i++) {
- instructions_[i]->set_num(instruction_count++);
+void Node::PrintReachingDefinitions() {
+ 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");
}
}
void ExitNode::PrintText() {
+ PrintReachingDefinitions();
PrintF("L%d: Exit\n\n", number());
}
void BlockNode::PrintText() {
+ PrintReachingDefinitions();
// Print the instructions in the block.
PrintF("L%d: Block\n", number());
TextInstructionPrinter printer;
for (int i = 0, len = instructions_.length(); i < len; i++) {
- PrintF("%d ", instructions_[i]->num());
+ PrintF("%d ", printer.NextNumber());
printer.Visit(instructions_[i]);
+ printer.AssignNumber(instructions_[i]);
PrintF("\n");
}
PrintF("goto L%d\n\n", successor_->number());
@@ -1802,12 +1851,14 @@ void BlockNode::PrintText() {
void BranchNode::PrintText() {
+ PrintReachingDefinitions();
PrintF("L%d: Branch\n", number());
PrintF("goto (L%d, L%d)\n\n", successor0_->number(), successor1_->number());
}
void JoinNode::PrintText() {
+ PrintReachingDefinitions();
PrintF("L%d: Join(", number());
for (int i = 0, len = predecessors_.length(); i < len; i++) {
if (i != 0) PrintF(", ");
@@ -1824,7 +1875,7 @@ void FlowGraph::PrintText(ZoneList<Node*>* postorder) {
node_count = 0;
instruction_count = 0;
for (int i = postorder->length() - 1; i >= 0; i--) {
- postorder->at(i)->AssignNumbers();
+ postorder->at(i)->AssignNodeNumber();
}
// Print basic blocks in reverse postorder.
@@ -1837,4 +1888,95 @@ void FlowGraph::PrintText(ZoneList<Node*>* postorder) {
#endif // defined(DEBUG)
+int ReachingDefinitions::IndexFor(Variable* var, int variable_count) {
+ // Parameters are numbered left-to-right from the beginning of the bit
+ // set. Stack-allocated locals are allocated right-to-left from the end.
+ ASSERT(var != NULL && var->IsStackAllocated());
+ Slot* slot = var->slot();
+ if (slot->type() == Slot::PARAMETER) {
+ return slot->index();
+ } else {
+ return (variable_count - 1) - slot->index();
+ }
+}
+
+
+void Node::InitializeReachingDefinitions(int definition_count,
+ List<BitVector*>* variables) {
+ rd_.Initialize(definition_count);
+}
+
+
+void BlockNode::InitializeReachingDefinitions(int definition_count,
+ List<BitVector*>* variables) {
+ int instruction_count = instructions_.length();
+ int variable_count = variables->length();
+
+ rd_.Initialize(definition_count);
+
+ for (int i = 0; i < instruction_count; i++) {
+ Expression* expr = instructions_[i]->AsExpression();
+ if (expr == NULL) continue;
+ Variable* var = expr->AssignedVar();
+ if (var == NULL) continue;
+
+ // All definitions of this variable are killed.
+ BitVector* def_set =
+ variables->at(ReachingDefinitions::IndexFor(var, variable_count));
+ rd_.kill()->Union(*def_set);
+
+ // All previously generated definitions are not generated.
+ rd_.gen()->Subtract(*def_set);
+
+ // This one is generated.
+ rd_.gen()->Add(expr->num());
+ }
+}
+
+
+void ReachingDefinitions::Compute() {
+ if (definitions_->is_empty()) return;
+
+ int variable_count = variables_.length();
+ int definition_count = definitions_->length();
+ int block_count = postorder_->length();
+
+ // Step 1: For each variable, identify the set of all its definitions in
+ // the body.
+ for (int i = 0; i < definition_count; i++) {
+ Variable* var = definitions_->at(i)->AssignedVar();
+ variables_[IndexFor(var, variable_count)]->Add(i);
+ }
+
+ if (FLAG_print_graph_text) {
+ for (int i = 0; i < variable_count; i++) {
+ BitVector* def_set = variables_[i];
+ if (!def_set->IsEmpty()) {
+ // At least one definition.
+ bool first = true;
+ for (int j = 0; j < definition_count; j++) {
+ if (def_set->Contains(j)) {
+ if (first) {
+ Variable* var = definitions_->at(j)->AssignedVar();
+ ASSERT(var != NULL);
+ PrintF("Def[%s] = {%d", *var->name()->ToCString(), j);
+ first = false;
+ } else {
+ PrintF(", %d", j);
+ }
+ }
+ }
+ PrintF("}\n");
+ }
+ }
+ }
+
+ // Step 2: Compute KILL and GEN for each block node, initialize RD.
+ for (int i = block_count - 1; i >= 0; i--) {
+ postorder_->at(i)->InitializeReachingDefinitions(definition_count,
+ &variables_);
+ }
+}
+
+
} } // namespace v8::internal
« 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