diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2010-04-14 10:34:17 -0700 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2010-04-14 10:34:27 -0700 |
commit | 41ef1717e096a9e1761efa0df97c395f59c51f16 (patch) | |
tree | 7e854284ef8ce5189a63074857a408b6eea5a9cb /deps/v8/src/data-flow.cc | |
parent | 760bba55186eba039ca00e532f7813d2aea450a2 (diff) | |
download | node-new-41ef1717e096a9e1761efa0df97c395f59c51f16.tar.gz |
Upgrade V8 to 2.2.3.1
Diffstat (limited to 'deps/v8/src/data-flow.cc')
-rw-r--r-- | deps/v8/src/data-flow.cc | 864 |
1 files changed, 36 insertions, 828 deletions
diff --git a/deps/v8/src/data-flow.cc b/deps/v8/src/data-flow.cc index 1bc77c0338..4e7620acf7 100644 --- a/deps/v8/src/data-flow.cc +++ b/deps/v8/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->obj()); } @@ -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 |