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

Unified Diff: src/data-flow.cc

Issue 1530003: Rework flow graph construction. (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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/data-flow.h ('k') | src/flow-graph.h » ('j') | src/flow-graph.h » ('J')
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 1bc77c033822fdc396f2f623e92a7dc17f83bc82..66e97d8bca15be53caa61b32d288f81cc924f4e2 100644
--- a/src/data-flow.cc
+++ b/src/data-flow.cc
@@ -28,7 +28,6 @@
#include "v8.h"
#include "data-flow.h"
-#include "flow-graph.h"
#include "scopes.h"
namespace v8 {
@@ -621,21 +620,34 @@ void AssignedVariablesAnalyzer::VisitCatchExtensionObject(
void AssignedVariablesAnalyzer::VisitAssignment(Assignment* expr) {
ASSERT(av_.IsEmpty());
- if (expr->target()->AsProperty() != NULL) {
- // Visit receiver and key of property store and rhs.
- Visit(expr->target()->AsProperty()->obj());
- ProcessExpression(expr->target()->AsProperty()->key());
- ProcessExpression(expr->value());
+ // There are three kinds of assignments: variable assignments, property
+ // assignments, and reference errors (invalid left-hand sides).
+ Variable* var = expr->target()->AsVariableProxy()->AsVariable();
+ Property* prop = expr->target()->AsProperty();
+ ASSERT(var == NULL || prop == NULL);
+
+ if (var != NULL) {
+ MarkIfTrivial(expr->value());
+ Visit(expr->value());
+ if (expr->is_compound()) {
+ // Left-hand side occurs also as an rvalue.
+ MarkIfTrivial(expr->target());
+ ProcessExpression(expr->target());
+ }
+ RecordAssignedVar(var);
+
+ } else if (prop != NULL) {
+ MarkIfTrivial(expr->value());
+ Visit(expr->value());
+ if (!prop->key()->IsPropertyName()) {
+ MarkIfTrivial(prop->key());
+ ProcessExpression(prop->key());
+ }
+ MarkIfTrivial(prop->obj());
+ ProcessExpression(prop->obj());
- // If we have a variable as a receiver in a property store, check if
- // we can mark it as trivial.
- MarkIfTrivial(expr->target()->AsProperty()->obj());
} else {
Visit(expr->target());
- ProcessExpression(expr->value());
-
- Variable* var = expr->target()->AsVariableProxy()->AsVariable();
- if (var != NULL) RecordAssignedVar(var);
}
}
@@ -648,12 +660,12 @@ void AssignedVariablesAnalyzer::VisitThrow(Throw* expr) {
void AssignedVariablesAnalyzer::VisitProperty(Property* expr) {
ASSERT(av_.IsEmpty());
- Visit(expr->obj());
- ProcessExpression(expr->key());
-
- // In case we have a variable as a receiver, check if we can mark
- // it as trivial.
+ if (!expr->key()->IsPropertyName()) {
+ MarkIfTrivial(expr->key());
+ Visit(expr->key());
+ }
MarkIfTrivial(expr->obj());
+ ProcessExpression(expr->key());
fschneider 2010/03/29 13:49:59 That should be ProcessExpression(expr->obj());
Kevin Millikin (Chromium) 2010/03/29 14:22:53 Thank you.
}
@@ -713,25 +725,19 @@ void AssignedVariablesAnalyzer::VisitCountOperation(CountOperation* expr) {
void AssignedVariablesAnalyzer::VisitBinaryOperation(BinaryOperation* expr) {
ASSERT(av_.IsEmpty());
- Visit(expr->left());
-
- ProcessExpression(expr->right());
-
- // In case we have a variable on the left side, check if we can mark
- // it as trivial.
+ MarkIfTrivial(expr->right());
+ Visit(expr->right());
MarkIfTrivial(expr->left());
+ ProcessExpression(expr->left());
}
void AssignedVariablesAnalyzer::VisitCompareOperation(CompareOperation* expr) {
ASSERT(av_.IsEmpty());
- Visit(expr->left());
-
- ProcessExpression(expr->right());
-
- // In case we have a variable on the left side, check if we can mark
- // it as trivial.
+ MarkIfTrivial(expr->right());
+ Visit(expr->right());
MarkIfTrivial(expr->left());
+ ProcessExpression(expr->left());
}
@@ -746,802 +752,4 @@ void AssignedVariablesAnalyzer::VisitDeclaration(Declaration* decl) {
}
-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,
- 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,
- WorkList<Node>* worklist,
- bool mark) {
- ASSERT(!IsMarkedWith(mark));
- int instruction_count = instructions_.length();
- int variable_count = variables->length();
-
- rd_.Initialize(definition_count);
- // The RD_in set for the entry node has a definition for each parameter
- // and local.
- if (predecessor_ == NULL) {
- for (int i = 0; i < variable_count; i++) rd_.rd_in()->Add(i);
- }
-
- for (int i = 0; i < instruction_count; i++) {
- Expression* expr = instructions_[i]->AsExpression();
- if (expr == NULL) continue;
- Variable* var = expr->AssignedVariable();
- if (var == NULL || !var->IsStackAllocated()) 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());
- }
-
- // Add all blocks except the entry node to the worklist.
- 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 = *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 = *rd_.rd_in();
-}
-
-
-void JoinNode::ComputeRDOut(BitVector* result) {
- // Join nodes don't kill or generate definitions.
- *result = *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();
-
- BitVector temp(definition_count);
- for (int i = 0, len = predecessors_.length(); i < len; i++) {
- // Because ComputeRDOut always overwrites temp and its value is
- // always read out before calling ComputeRDOut again, we do not
- // have to clear it on each iteration of the loop.
- 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() = 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() = 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.
- BitVector temp(definition_count);
- for (int i = 0, len = predecessors_.length(); i < len; i++) {
- predecessors_[i]->ComputeRDOut(&temp);
- new_rd_in.Union(temp);
- }
-
- if (rd_.rd_in()->Equals(new_rd_in)) return;
-
- // Update 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->AssignedVariable();
- 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() {
- // The definitions in the body plus an implicit definition for each
- // variable at function entry.
- int definition_count = body_definitions_->length() + variable_count_;
- int node_count = postorder_->length();
-
- // Step 1: For each stack-allocated variable, identify the set of all its
- // definitions.
- List<BitVector*> variables;
- for (int i = 0; i < variable_count_; i++) {
- // Add the initial definition for each variable.
- BitVector* initial = new BitVector(definition_count);
- initial->Add(i);
- variables.Add(initial);
- }
- for (int i = 0, len = body_definitions_->length(); i < len; i++) {
- // Account for each definition in the body as a definition of the
- // defined variable.
- Variable* var = body_definitions_->at(i)->AssignedVariable();
- variables[IndexFor(var, variable_count_)]->Add(i + variable_count_);
- }
-
- // 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,
- &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);
- }
-
- // 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);
- }
-}
-
-
-bool TypeAnalyzer::IsPrimitiveDef(int def_num) {
- if (def_num < param_count_) return false;
- if (def_num < variable_count_) return true;
- return body_definitions_->at(def_num - variable_count_)->IsPrimitive();
-}
-
-
-void TypeAnalyzer::Compute() {
- bool changed;
- int count = 0;
-
- do {
- changed = false;
-
- if (FLAG_print_graph_text) {
- PrintF("TypeAnalyzer::Compute - iteration %d\n", count++);
- }
-
- for (int i = postorder_->length() - 1; i >= 0; --i) {
- Node* node = postorder_->at(i);
- if (node->IsBlockNode()) {
- BlockNode* block = BlockNode::cast(node);
- for (int j = 0; j < block->instructions()->length(); j++) {
- Expression* expr = block->instructions()->at(j)->AsExpression();
- if (expr != NULL) {
- // For variable uses: Compute new type from reaching definitions.
- VariableProxy* proxy = expr->AsVariableProxy();
- if (proxy != NULL && proxy->reaching_definitions() != NULL) {
- BitVector* rd = proxy->reaching_definitions();
- bool prim_type = true;
- // TODO(fsc): A sparse set representation of reaching
- // definitions would speed up iterating here.
- for (int k = 0; k < rd->length(); k++) {
- if (rd->Contains(k) && !IsPrimitiveDef(k)) {
- prim_type = false;
- break;
- }
- }
- // Reset changed flag if new type information was computed.
- if (prim_type != proxy->IsPrimitive()) {
- changed = true;
- proxy->SetIsPrimitive(prim_type);
- }
- }
- }
- }
- }
- }
- } while (changed);
-}
-
-
-void Node::MarkCriticalInstructions(
- List<AstNode*>* stack,
- ZoneList<Expression*>* body_definitions,
- int variable_count) {
-}
-
-
-void BlockNode::MarkCriticalInstructions(
- List<AstNode*>* stack,
- ZoneList<Expression*>* body_definitions,
- int variable_count) {
- for (int i = instructions_.length() - 1; i >= 0; i--) {
- // Only expressions can appear in the flow graph for now.
- Expression* expr = instructions_[i]->AsExpression();
- if (expr != NULL && !expr->is_live() &&
- (expr->is_loop_condition() || expr->IsCritical())) {
- expr->mark_as_live();
- expr->ProcessNonLiveChildren(stack, body_definitions, variable_count);
- }
- }
-}
-
-
-void MarkLiveCode(ZoneList<Node*>* nodes,
- ZoneList<Expression*>* body_definitions,
- int variable_count) {
- List<AstNode*> stack(20);
-
- // Mark the critical AST nodes as live; mark their dependencies and
- // add them to the marking stack.
- for (int i = nodes->length() - 1; i >= 0; i--) {
- nodes->at(i)->MarkCriticalInstructions(&stack, body_definitions,
- variable_count);
- }
-
- // Continue marking dependencies until no more.
- while (!stack.is_empty()) {
- // Only expressions can appear in the flow graph for now.
- Expression* expr = stack.RemoveLast()->AsExpression();
- if (expr != NULL) {
- expr->ProcessNonLiveChildren(&stack, body_definitions, variable_count);
- }
- }
-}
-
-
-#ifdef DEBUG
-
-// Print a textual representation of an instruction in a flow graph. Using
-// the AstVisitor is overkill because there is no recursion here. It is
-// only used for printing in debug mode.
-class TextInstructionPrinter: public AstVisitor {
- public:
- TextInstructionPrinter() : number_(0) {}
-
- int NextNumber() { return number_; }
- void AssignNumber(AstNode* node) { node->set_num(number_++); }
-
- private:
- // AST node visit functions.
-#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
- AST_NODE_LIST(DECLARE_VISIT)
-#undef DECLARE_VISIT
-
- int number_;
-
- DISALLOW_COPY_AND_ASSIGN(TextInstructionPrinter);
-};
-
-
-void TextInstructionPrinter::VisitDeclaration(Declaration* decl) {
- UNREACHABLE();
-}
-
-
-void TextInstructionPrinter::VisitBlock(Block* stmt) {
- PrintF("Block");
-}
-
-
-void TextInstructionPrinter::VisitExpressionStatement(
- ExpressionStatement* stmt) {
- PrintF("ExpressionStatement");
-}
-
-
-void TextInstructionPrinter::VisitEmptyStatement(EmptyStatement* stmt) {
- PrintF("EmptyStatement");
-}
-
-
-void TextInstructionPrinter::VisitIfStatement(IfStatement* stmt) {
- PrintF("IfStatement");
-}
-
-
-void TextInstructionPrinter::VisitContinueStatement(ContinueStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void TextInstructionPrinter::VisitBreakStatement(BreakStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void TextInstructionPrinter::VisitReturnStatement(ReturnStatement* stmt) {
- PrintF("return @%d", stmt->expression()->num());
-}
-
-
-void TextInstructionPrinter::VisitWithEnterStatement(WithEnterStatement* stmt) {
- PrintF("WithEnterStatement");
-}
-
-
-void TextInstructionPrinter::VisitWithExitStatement(WithExitStatement* stmt) {
- PrintF("WithExitStatement");
-}
-
-
-void TextInstructionPrinter::VisitSwitchStatement(SwitchStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void TextInstructionPrinter::VisitDoWhileStatement(DoWhileStatement* stmt) {
- PrintF("DoWhileStatement");
-}
-
-
-void TextInstructionPrinter::VisitWhileStatement(WhileStatement* stmt) {
- PrintF("WhileStatement");
-}
-
-
-void TextInstructionPrinter::VisitForStatement(ForStatement* stmt) {
- PrintF("ForStatement");
-}
-
-
-void TextInstructionPrinter::VisitForInStatement(ForInStatement* stmt) {
- PrintF("ForInStatement");
-}
-
-
-void TextInstructionPrinter::VisitTryCatchStatement(TryCatchStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void TextInstructionPrinter::VisitTryFinallyStatement(
- TryFinallyStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void TextInstructionPrinter::VisitDebuggerStatement(DebuggerStatement* stmt) {
- PrintF("DebuggerStatement");
-}
-
-
-void TextInstructionPrinter::VisitFunctionLiteral(FunctionLiteral* expr) {
- PrintF("FunctionLiteral");
-}
-
-
-void TextInstructionPrinter::VisitSharedFunctionInfoLiteral(
- SharedFunctionInfoLiteral* expr) {
- PrintF("SharedFunctionInfoLiteral");
-}
-
-
-void TextInstructionPrinter::VisitConditional(Conditional* expr) {
- PrintF("Conditional");
-}
-
-
-void TextInstructionPrinter::VisitSlot(Slot* expr) {
- UNREACHABLE();
-}
-
-
-void TextInstructionPrinter::VisitVariableProxy(VariableProxy* expr) {
- 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());
- }
-}
-
-
-void TextInstructionPrinter::VisitLiteral(Literal* expr) {
- expr->handle()->ShortPrint();
-}
-
-
-void TextInstructionPrinter::VisitRegExpLiteral(RegExpLiteral* expr) {
- PrintF("RegExpLiteral");
-}
-
-
-void TextInstructionPrinter::VisitObjectLiteral(ObjectLiteral* expr) {
- PrintF("ObjectLiteral");
-}
-
-
-void TextInstructionPrinter::VisitArrayLiteral(ArrayLiteral* expr) {
- PrintF("ArrayLiteral");
-}
-
-
-void TextInstructionPrinter::VisitCatchExtensionObject(
- CatchExtensionObject* expr) {
- PrintF("CatchExtensionObject");
-}
-
-
-void TextInstructionPrinter::VisitAssignment(Assignment* expr) {
- 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", *var->name()->ToCString());
- } else if (prop != NULL) {
- 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 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 {
- 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());
- }
-}
-
-
-void TextInstructionPrinter::VisitThrow(Throw* expr) {
- PrintF("throw @%d", expr->exception()->num());
-}
-
-
-void TextInstructionPrinter::VisitProperty(Property* expr) {
- if (expr->key()->IsPropertyName()) {
- PrintF("@%d.", expr->obj()->num());
- ASSERT(expr->key()->AsLiteral() != NULL);
- expr->key()->AsLiteral()->handle()->Print();
- } else {
- PrintF("@%d[@%d]", expr->obj()->num(), expr->key()->num());
- }
-}
-
-
-void TextInstructionPrinter::VisitCall(Call* expr) {
- PrintF("@%d(", expr->expression()->num());
- ZoneList<Expression*>* arguments = expr->arguments();
- for (int i = 0, len = arguments->length(); i < len; i++) {
- if (i != 0) PrintF(", ");
- PrintF("@%d", arguments->at(i)->num());
- }
- PrintF(")");
-}
-
-
-void TextInstructionPrinter::VisitCallNew(CallNew* expr) {
- PrintF("new @%d(", expr->expression()->num());
- ZoneList<Expression*>* arguments = expr->arguments();
- for (int i = 0, len = arguments->length(); i < len; i++) {
- if (i != 0) PrintF(", ");
- PrintF("@%d", arguments->at(i)->num());
- }
- PrintF(")");
-}
-
-
-void TextInstructionPrinter::VisitCallRuntime(CallRuntime* expr) {
- PrintF("%s(", *expr->name()->ToCString());
- ZoneList<Expression*>* arguments = expr->arguments();
- for (int i = 0, len = arguments->length(); i < len; i++) {
- if (i != 0) PrintF(", ");
- PrintF("@%d", arguments->at(i)->num());
- }
- PrintF(")");
-}
-
-
-void TextInstructionPrinter::VisitUnaryOperation(UnaryOperation* expr) {
- PrintF("%s(@%d)", Token::String(expr->op()), expr->expression()->num());
-}
-
-
-void TextInstructionPrinter::VisitCountOperation(CountOperation* expr) {
- if (expr->is_prefix()) {
- PrintF("%s@%d", Token::String(expr->op()), expr->expression()->num());
- } else {
- PrintF("@%d%s", expr->expression()->num(), Token::String(expr->op()));
- }
-
- if (expr->num() != AstNode::kNoNumber) {
- PrintF(" ;; D%d", expr->num());
- }
-}
-
-
-void TextInstructionPrinter::VisitBinaryOperation(BinaryOperation* expr) {
- ASSERT(expr->op() != Token::COMMA);
- ASSERT(expr->op() != Token::OR);
- ASSERT(expr->op() != Token::AND);
- PrintF("@%d %s @%d",
- expr->left()->num(),
- Token::String(expr->op()),
- expr->right()->num());
-}
-
-
-void TextInstructionPrinter::VisitCompareOperation(CompareOperation* expr) {
- PrintF("@%d %s @%d",
- expr->left()->num(),
- Token::String(expr->op()),
- expr->right()->num());
-}
-
-
-void TextInstructionPrinter::VisitThisFunction(ThisFunction* expr) {
- PrintF("ThisFunction");
-}
-
-
-static int node_count = 0;
-static int instruction_count = 0;
-
-
-void Node::AssignNodeNumber() {
- set_number(node_count++);
-}
-
-
-void Node::PrintReachingDefinitions() {
- if (rd_.rd_in() != NULL) {
- ASSERT(rd_.kill() != NULL && rd_.gen() != NULL);
-
- 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");
- }
-}
-
-
-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++) {
- AstNode* instr = instructions_[i];
- // Print a star next to dead instructions.
- if (instr->AsExpression() != NULL && instr->AsExpression()->is_live()) {
- PrintF(" ");
- } else {
- PrintF("* ");
- }
- PrintF("%d ", printer.NextNumber());
- printer.Visit(instr);
- printer.AssignNumber(instr);
- PrintF("\n");
- }
- PrintF("goto L%d\n\n", successor_->number());
-}
-
-
-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(", ");
- PrintF("L%d", predecessors_[i]->number());
- }
- PrintF(")\ngoto L%d\n\n", successor_->number());
-}
-
-
-void FlowGraph::PrintText(FunctionLiteral* fun, ZoneList<Node*>* postorder) {
- PrintF("\n========\n");
- PrintF("name = %s\n", *fun->name()->ToCString());
-
- // Number nodes and instructions in reverse postorder.
- node_count = 0;
- instruction_count = 0;
- for (int i = postorder->length() - 1; i >= 0; i--) {
- postorder->at(i)->AssignNodeNumber();
- }
-
- // Print basic blocks in reverse postorder.
- for (int i = postorder->length() - 1; i >= 0; i--) {
- postorder->at(i)->PrintText();
- }
-}
-
-#endif // DEBUG
-
-
} } // namespace v8::internal
« no previous file with comments | « src/data-flow.h ('k') | src/flow-graph.h » ('j') | src/flow-graph.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698