| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 join_block->SetJoinId(join_id); | 496 join_block->SetJoinId(join_id); |
| 497 return join_block; | 497 return join_block; |
| 498 } | 498 } |
| 499 } | 499 } |
| 500 | 500 |
| 501 | 501 |
| 502 HBasicBlock* HGraphBuilder::JoinContinue(IterationStatement* statement, | 502 HBasicBlock* HGraphBuilder::JoinContinue(IterationStatement* statement, |
| 503 HBasicBlock* exit_block, | 503 HBasicBlock* exit_block, |
| 504 HBasicBlock* continue_block) { | 504 HBasicBlock* continue_block) { |
| 505 if (continue_block != NULL) { | 505 if (continue_block != NULL) { |
| 506 if (exit_block != NULL) exit_block->Goto(continue_block); |
| 506 continue_block->SetJoinId(statement->ContinueId()); | 507 continue_block->SetJoinId(statement->ContinueId()); |
| 508 return continue_block; |
| 507 } | 509 } |
| 508 return CreateJoin(exit_block, continue_block, statement->ContinueId()); | 510 return exit_block; |
| 509 } | 511 } |
| 510 | 512 |
| 511 | 513 |
| 512 HBasicBlock* HGraphBuilder::CreateEndless(IterationStatement* statement, | 514 HBasicBlock* HGraphBuilder::CreateLoop(IterationStatement* statement, |
| 513 HBasicBlock* body_entry, | 515 HBasicBlock* loop_entry, |
| 514 HBasicBlock* body_exit, | 516 HBasicBlock* body_exit, |
| 515 HBasicBlock* break_block) { | 517 HBasicBlock* loop_successor, |
| 516 if (body_exit != NULL) body_exit->Goto(body_entry, true); | 518 HBasicBlock* break_block) { |
| 517 if (break_block != NULL) break_block->SetJoinId(statement->ExitId()); | 519 if (body_exit != NULL) body_exit->Goto(loop_entry, true); |
| 518 body_entry->PostProcessLoopHeader(statement); | 520 loop_entry->PostProcessLoopHeader(statement); |
| 519 return break_block; | 521 if (break_block != NULL) { |
| 522 if (loop_successor != NULL) loop_successor->Goto(break_block); |
| 523 break_block->SetJoinId(statement->ExitId()); |
| 524 return break_block; |
| 525 } |
| 526 return loop_successor; |
| 520 } | 527 } |
| 521 | 528 |
| 522 | 529 |
| 523 HBasicBlock* HGraphBuilder::CreateDoWhile(IterationStatement* statement, | |
| 524 HBasicBlock* body_entry, | |
| 525 HBasicBlock* go_back, | |
| 526 HBasicBlock* exit_block, | |
| 527 HBasicBlock* break_block) { | |
| 528 if (go_back != NULL) go_back->Goto(body_entry, true); | |
| 529 if (break_block != NULL) break_block->SetJoinId(statement->ExitId()); | |
| 530 HBasicBlock* new_exit = | |
| 531 CreateJoin(exit_block, break_block, statement->ExitId()); | |
| 532 body_entry->PostProcessLoopHeader(statement); | |
| 533 return new_exit; | |
| 534 } | |
| 535 | |
| 536 | |
| 537 HBasicBlock* HGraphBuilder::CreateWhile(IterationStatement* statement, | |
| 538 HBasicBlock* loop_entry, | |
| 539 HBasicBlock* cond_false, | |
| 540 HBasicBlock* body_exit, | |
| 541 HBasicBlock* break_block) { | |
| 542 if (break_block != NULL) break_block->SetJoinId(statement->ExitId()); | |
| 543 HBasicBlock* new_exit = | |
| 544 CreateJoin(cond_false, break_block, statement->ExitId()); | |
| 545 if (body_exit != NULL) body_exit->Goto(loop_entry, true); | |
| 546 loop_entry->PostProcessLoopHeader(statement); | |
| 547 return new_exit; | |
| 548 } | |
| 549 | |
| 550 | |
| 551 void HBasicBlock::FinishExit(HControlInstruction* instruction) { | 530 void HBasicBlock::FinishExit(HControlInstruction* instruction) { |
| 552 Finish(instruction); | 531 Finish(instruction); |
| 553 ClearEnvironment(); | 532 ClearEnvironment(); |
| 554 } | 533 } |
| 555 | 534 |
| 556 | 535 |
| 557 HGraph::HGraph(CompilationInfo* info) | 536 HGraph::HGraph(CompilationInfo* info) |
| 558 : HSubgraph(this), | 537 : HSubgraph(this), |
| 559 next_block_id_(0), | 538 next_block_id_(0), |
| 560 info_(info), | 539 info_(info), |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 | 593 |
| 615 | 594 |
| 616 HBasicBlock* HGraph::CreateBasicBlock() { | 595 HBasicBlock* HGraph::CreateBasicBlock() { |
| 617 HBasicBlock* result = new HBasicBlock(this); | 596 HBasicBlock* result = new HBasicBlock(this); |
| 618 blocks_.Add(result); | 597 blocks_.Add(result); |
| 619 return result; | 598 return result; |
| 620 } | 599 } |
| 621 | 600 |
| 622 | 601 |
| 623 void HGraph::Canonicalize() { | 602 void HGraph::Canonicalize() { |
| 603 if (!FLAG_use_canonicalizing) return; |
| 624 HPhase phase("Canonicalize", this); | 604 HPhase phase("Canonicalize", this); |
| 625 if (FLAG_use_canonicalizing) { | 605 for (int i = 0; i < blocks()->length(); ++i) { |
| 626 for (int i = 0; i < blocks()->length(); ++i) { | 606 HInstruction* instr = blocks()->at(i)->first(); |
| 627 HBasicBlock* b = blocks()->at(i); | 607 while (instr != NULL) { |
| 628 for (HInstruction* insn = b->first(); insn != NULL; insn = insn->next()) { | 608 HValue* value = instr->Canonicalize(); |
| 629 HValue* value = insn->Canonicalize(); | 609 if (value != instr) instr->ReplaceAndDelete(value); |
| 630 if (value != insn) { | 610 instr = instr->next(); |
| 631 if (value != NULL) { | |
| 632 insn->ReplaceAndDelete(value); | |
| 633 } else { | |
| 634 insn->Delete(); | |
| 635 } | |
| 636 } | |
| 637 } | |
| 638 } | 611 } |
| 639 } | 612 } |
| 640 } | 613 } |
| 641 | 614 |
| 642 | 615 |
| 643 void HGraph::OrderBlocks() { | 616 void HGraph::OrderBlocks() { |
| 644 HPhase phase("Block ordering"); | 617 HPhase phase("Block ordering"); |
| 645 BitVector visited(blocks_.length()); | 618 BitVector visited(blocks_.length()); |
| 646 | 619 |
| 647 ZoneList<HBasicBlock*> reverse_result(8); | 620 ZoneList<HBasicBlock*> reverse_result(8); |
| (...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1383 TraceGVN("Instruction %d kills\n", instr->id()); | 1356 TraceGVN("Instruction %d kills\n", instr->id()); |
| 1384 } else if (instr->CheckFlag(HValue::kUseGVN)) { | 1357 } else if (instr->CheckFlag(HValue::kUseGVN)) { |
| 1385 HValue* other = map->Lookup(instr); | 1358 HValue* other = map->Lookup(instr); |
| 1386 if (other != NULL) { | 1359 if (other != NULL) { |
| 1387 ASSERT(instr->Equals(other) && other->Equals(instr)); | 1360 ASSERT(instr->Equals(other) && other->Equals(instr)); |
| 1388 TraceGVN("Replacing value %d (%s) with value %d (%s)\n", | 1361 TraceGVN("Replacing value %d (%s) with value %d (%s)\n", |
| 1389 instr->id(), | 1362 instr->id(), |
| 1390 instr->Mnemonic(), | 1363 instr->Mnemonic(), |
| 1391 other->id(), | 1364 other->id(), |
| 1392 other->Mnemonic()); | 1365 other->Mnemonic()); |
| 1393 instr->ReplaceValue(other); | 1366 instr->ReplaceAndDelete(other); |
| 1394 instr->Delete(); | |
| 1395 } else { | 1367 } else { |
| 1396 map->Add(instr); | 1368 map->Add(instr); |
| 1397 } | 1369 } |
| 1398 } | 1370 } |
| 1399 instr = next; | 1371 instr = next; |
| 1400 } | 1372 } |
| 1401 | 1373 |
| 1402 // Recursively continue analysis for all immediately dominated blocks. | 1374 // Recursively continue analysis for all immediately dominated blocks. |
| 1403 int length = block->dominated_blocks()->length(); | 1375 int length = block->dominated_blocks()->length(); |
| 1404 for (int i = 0; i < length; ++i) { | 1376 for (int i = 0; i < length; ++i) { |
| (...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2089 | 2061 |
| 2090 | 2062 |
| 2091 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) { | 2063 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) { |
| 2092 for (int i = 0; i < exprs->length(); ++i) { | 2064 for (int i = 0; i < exprs->length(); ++i) { |
| 2093 VISIT_FOR_VALUE(exprs->at(i)); | 2065 VISIT_FOR_VALUE(exprs->at(i)); |
| 2094 } | 2066 } |
| 2095 } | 2067 } |
| 2096 | 2068 |
| 2097 | 2069 |
| 2098 HGraph* HGraphBuilder::CreateGraph(CompilationInfo* info) { | 2070 HGraph* HGraphBuilder::CreateGraph(CompilationInfo* info) { |
| 2099 ASSERT(current_subgraph_ == NULL); | 2071 ASSERT(subgraph() == NULL); |
| 2100 graph_ = new HGraph(info); | 2072 graph_ = new HGraph(info); |
| 2101 | 2073 |
| 2102 { | 2074 { |
| 2103 HPhase phase("Block building"); | 2075 HPhase phase("Block building"); |
| 2104 graph_->Initialize(CreateBasicBlock(graph_->start_environment())); | 2076 graph()->Initialize(CreateBasicBlock(graph()->start_environment())); |
| 2105 current_subgraph_ = graph_; | 2077 current_subgraph_ = graph(); |
| 2106 | 2078 |
| 2107 Scope* scope = info->scope(); | 2079 Scope* scope = info->scope(); |
| 2080 if (scope->HasIllegalRedeclaration()) { |
| 2081 Bailout("function with illegal redeclaration"); |
| 2082 return NULL; |
| 2083 } |
| 2108 SetupScope(scope); | 2084 SetupScope(scope); |
| 2109 VisitDeclarations(scope->declarations()); | 2085 VisitDeclarations(scope->declarations()); |
| 2110 | |
| 2111 AddInstruction(new HStackCheck()); | 2086 AddInstruction(new HStackCheck()); |
| 2112 | 2087 |
| 2113 ZoneList<Statement*>* stmts = info->function()->body(); | 2088 // Add an edge to the body entry. This is warty: the graph's start |
| 2114 HSubgraph* body = CreateGotoSubgraph(environment()); | 2089 // environment will be used by the Lithium translation as the initial |
| 2115 current_block()->Goto(body->entry_block()); | 2090 // environment on graph entry, but it has now been mutated by the |
| 2116 AddToSubgraph(body, stmts); | 2091 // Hydrogen translation of the instructions in the start block. This |
| 2092 // environment uses values which have not been defined yet. These |
| 2093 // Hydrogen instructions will then be replayed by the Lithium |
| 2094 // translation, so they cannot have an environment effect. The edge to |
| 2095 // the body's entry block (along with some special logic for the start |
| 2096 // block in HInstruction::InsertAfter) seals the start block from |
| 2097 // getting unwanted instructions inserted. |
| 2098 // |
| 2099 // TODO(kmillikin): Fix this. Stop mutating the initial environment. |
| 2100 // Make the Hydrogen instructions in the initial block into Hydrogen |
| 2101 // values (but not instructions), present in the initial environment and |
| 2102 // not replayed by the Lithium translation. |
| 2103 HEnvironment* initial_env = environment()->CopyWithoutHistory(); |
| 2104 HBasicBlock* body_entry = CreateBasicBlock(initial_env); |
| 2105 current_block()->Goto(body_entry); |
| 2106 body_entry->SetJoinId(info->function()->id()); |
| 2107 set_current_block(body_entry); |
| 2108 VisitStatements(info->function()->body()); |
| 2117 if (HasStackOverflow()) return NULL; | 2109 if (HasStackOverflow()) return NULL; |
| 2118 body->entry_block()->SetJoinId(info->function()->id()); | |
| 2119 set_current_block(body->exit_block()); | |
| 2120 | 2110 |
| 2121 if (graph()->exit_block() != NULL) { | 2111 if (current_block() != NULL) { |
| 2122 HReturn* instr = new HReturn(graph()->GetConstantUndefined()); | 2112 HReturn* instr = new HReturn(graph()->GetConstantUndefined()); |
| 2123 graph()->exit_block()->FinishExit(instr); | 2113 current_block()->FinishExit(instr); |
| 2124 graph()->set_exit_block(NULL); | 2114 set_current_block(NULL); |
| 2125 } | 2115 } |
| 2126 } | 2116 } |
| 2127 | 2117 |
| 2128 graph_->OrderBlocks(); | 2118 graph()->OrderBlocks(); |
| 2129 graph_->AssignDominators(); | 2119 graph()->AssignDominators(); |
| 2130 graph_->EliminateRedundantPhis(); | 2120 graph()->EliminateRedundantPhis(); |
| 2131 if (!graph_->CollectPhis()) { | 2121 if (!graph()->CollectPhis()) { |
| 2132 Bailout("Phi-use of arguments object"); | 2122 Bailout("Phi-use of arguments object"); |
| 2133 return NULL; | 2123 return NULL; |
| 2134 } | 2124 } |
| 2135 | 2125 |
| 2136 HInferRepresentation rep(graph_); | 2126 HInferRepresentation rep(graph()); |
| 2137 rep.Analyze(); | 2127 rep.Analyze(); |
| 2138 | 2128 |
| 2139 if (FLAG_use_range) { | 2129 if (FLAG_use_range) { |
| 2140 HRangeAnalysis rangeAnalysis(graph_); | 2130 HRangeAnalysis rangeAnalysis(graph()); |
| 2141 rangeAnalysis.Analyze(); | 2131 rangeAnalysis.Analyze(); |
| 2142 } | 2132 } |
| 2143 | 2133 |
| 2144 graph_->InitializeInferredTypes(); | 2134 graph()->InitializeInferredTypes(); |
| 2145 graph_->Canonicalize(); | 2135 graph()->Canonicalize(); |
| 2146 graph_->InsertRepresentationChanges(); | 2136 graph()->InsertRepresentationChanges(); |
| 2147 graph_->ComputeMinusZeroChecks(); | 2137 graph()->ComputeMinusZeroChecks(); |
| 2148 | 2138 |
| 2149 // Eliminate redundant stack checks on backwards branches. | 2139 // Eliminate redundant stack checks on backwards branches. |
| 2150 HStackCheckEliminator sce(graph_); | 2140 HStackCheckEliminator sce(graph()); |
| 2151 sce.Process(); | 2141 sce.Process(); |
| 2152 | 2142 |
| 2153 // Perform common subexpression elimination and loop-invariant code motion. | 2143 // Perform common subexpression elimination and loop-invariant code motion. |
| 2154 if (FLAG_use_gvn) { | 2144 if (FLAG_use_gvn) { |
| 2155 HPhase phase("Global value numbering", graph_); | 2145 HPhase phase("Global value numbering", graph()); |
| 2156 HGlobalValueNumberer gvn(graph_); | 2146 HGlobalValueNumberer gvn(graph()); |
| 2157 gvn.Analyze(); | 2147 gvn.Analyze(); |
| 2158 } | 2148 } |
| 2159 | 2149 |
| 2160 return graph_; | 2150 return graph(); |
| 2161 } | 2151 } |
| 2162 | 2152 |
| 2163 | 2153 |
| 2164 void HGraphBuilder::AddToSubgraph(HSubgraph* graph, Statement* stmt) { | 2154 void HGraphBuilder::AddToSubgraph(HSubgraph* graph, Statement* stmt) { |
| 2165 SubgraphScope scope(this, graph); | 2155 SubgraphScope scope(this, graph); |
| 2166 Visit(stmt); | 2156 Visit(stmt); |
| 2167 } | 2157 } |
| 2168 | 2158 |
| 2169 | 2159 |
| 2170 void HGraphBuilder::AddToSubgraph(HSubgraph* graph, Expression* expr) { | 2160 void HGraphBuilder::AddToSubgraph(HSubgraph* graph, Expression* expr) { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2278 FunctionLiteral* function) { | 2268 FunctionLiteral* function) { |
| 2279 HConstant* undefined = graph()->GetConstantUndefined(); | 2269 HConstant* undefined = graph()->GetConstantUndefined(); |
| 2280 HEnvironment* inner = | 2270 HEnvironment* inner = |
| 2281 outer->CopyForInlining(target, function, true, undefined); | 2271 outer->CopyForInlining(target, function, true, undefined); |
| 2282 HSubgraph* subgraph = new HSubgraph(graph()); | 2272 HSubgraph* subgraph = new HSubgraph(graph()); |
| 2283 subgraph->Initialize(CreateBasicBlock(inner)); | 2273 subgraph->Initialize(CreateBasicBlock(inner)); |
| 2284 return subgraph; | 2274 return subgraph; |
| 2285 } | 2275 } |
| 2286 | 2276 |
| 2287 | 2277 |
| 2288 HSubgraph* HGraphBuilder::CreateGotoSubgraph(HEnvironment* env) { | |
| 2289 HSubgraph* subgraph = new HSubgraph(graph()); | |
| 2290 HEnvironment* new_env = env->CopyWithoutHistory(); | |
| 2291 subgraph->Initialize(CreateBasicBlock(new_env)); | |
| 2292 return subgraph; | |
| 2293 } | |
| 2294 | |
| 2295 | |
| 2296 HSubgraph* HGraphBuilder::CreateEmptySubgraph() { | 2278 HSubgraph* HGraphBuilder::CreateEmptySubgraph() { |
| 2297 HSubgraph* subgraph = new HSubgraph(graph()); | 2279 HSubgraph* subgraph = new HSubgraph(graph()); |
| 2298 subgraph->Initialize(graph()->CreateBasicBlock()); | 2280 subgraph->Initialize(graph()->CreateBasicBlock()); |
| 2299 return subgraph; | 2281 return subgraph; |
| 2300 } | 2282 } |
| 2301 | 2283 |
| 2302 | 2284 |
| 2303 HSubgraph* HGraphBuilder::CreateBranchSubgraph(HEnvironment* env) { | 2285 HSubgraph* HGraphBuilder::CreateBranchSubgraph(HEnvironment* env) { |
| 2304 HSubgraph* subgraph = new HSubgraph(graph()); | 2286 HSubgraph* subgraph = new HSubgraph(graph()); |
| 2305 HEnvironment* new_env = env->Copy(); | 2287 HEnvironment* new_env = env->Copy(); |
| 2306 subgraph->Initialize(CreateBasicBlock(new_env)); | 2288 subgraph->Initialize(CreateBasicBlock(new_env)); |
| 2307 return subgraph; | 2289 return subgraph; |
| 2308 } | 2290 } |
| 2309 | 2291 |
| 2310 | 2292 |
| 2311 HBasicBlock* HGraphBuilder::CreateLoopHeader() { | 2293 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { |
| 2312 HBasicBlock* header = graph()->CreateBasicBlock(); | 2294 HBasicBlock* header = graph()->CreateBasicBlock(); |
| 2313 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); | 2295 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); |
| 2314 header->SetInitialEnvironment(entry_env); | 2296 header->SetInitialEnvironment(entry_env); |
| 2315 header->AttachLoopInformation(); | 2297 header->AttachLoopInformation(); |
| 2316 return header; | 2298 return header; |
| 2317 } | 2299 } |
| 2318 | 2300 |
| 2319 | 2301 |
| 2320 void HGraphBuilder::VisitBlock(Block* stmt) { | 2302 void HGraphBuilder::VisitBlock(Block* stmt) { |
| 2321 if (stmt->labels() != NULL) { | 2303 BreakAndContinueInfo break_info(stmt); |
| 2322 HSubgraph* block_graph = CreateGotoSubgraph(environment()); | 2304 { BreakAndContinueScope push(&break_info, this); |
| 2323 current_block()->Goto(block_graph->entry_block()); | |
| 2324 block_graph->entry_block()->SetJoinId(stmt->EntryId()); | |
| 2325 BreakAndContinueInfo break_info(stmt); | |
| 2326 { BreakAndContinueScope push(&break_info, this); | |
| 2327 ADD_TO_SUBGRAPH(block_graph, stmt->statements()); | |
| 2328 } | |
| 2329 HBasicBlock* break_block = break_info.break_block(); | |
| 2330 if (break_block != NULL) break_block->SetJoinId(stmt->EntryId()); | |
| 2331 set_current_block(CreateJoin(block_graph->exit_block(), | |
| 2332 break_block, | |
| 2333 stmt->ExitId())); | |
| 2334 } else { | |
| 2335 VisitStatements(stmt->statements()); | 2305 VisitStatements(stmt->statements()); |
| 2306 CHECK_BAILOUT; |
| 2307 } |
| 2308 HBasicBlock* break_block = break_info.break_block(); |
| 2309 if (break_block != NULL) { |
| 2310 if (current_block() != NULL) current_block()->Goto(break_block); |
| 2311 break_block->SetJoinId(stmt->ExitId()); |
| 2312 set_current_block(break_block); |
| 2336 } | 2313 } |
| 2337 } | 2314 } |
| 2338 | 2315 |
| 2339 | 2316 |
| 2340 void HGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) { | 2317 void HGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) { |
| 2341 VisitForEffect(stmt->expression()); | 2318 VisitForEffect(stmt->expression()); |
| 2342 } | 2319 } |
| 2343 | 2320 |
| 2344 | 2321 |
| 2345 void HGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) { | 2322 void HGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) { |
| 2346 } | 2323 } |
| 2347 | 2324 |
| 2348 | 2325 |
| 2349 void HGraphBuilder::VisitIfStatement(IfStatement* stmt) { | 2326 void HGraphBuilder::VisitIfStatement(IfStatement* stmt) { |
| 2350 if (stmt->condition()->ToBooleanIsTrue()) { | 2327 if (stmt->condition()->ToBooleanIsTrue()) { |
| 2351 AddSimulate(stmt->ThenId()); | 2328 AddSimulate(stmt->ThenId()); |
| 2352 Visit(stmt->then_statement()); | 2329 Visit(stmt->then_statement()); |
| 2353 } else if (stmt->condition()->ToBooleanIsFalse()) { | 2330 } else if (stmt->condition()->ToBooleanIsFalse()) { |
| 2354 AddSimulate(stmt->ElseId()); | 2331 AddSimulate(stmt->ElseId()); |
| 2355 Visit(stmt->else_statement()); | 2332 Visit(stmt->else_statement()); |
| 2356 } else { | 2333 } else { |
| 2357 HSubgraph* then_graph = CreateEmptySubgraph(); | 2334 HBasicBlock* cond_true = graph()->CreateBasicBlock(); |
| 2358 HSubgraph* else_graph = CreateEmptySubgraph(); | 2335 HBasicBlock* cond_false = graph()->CreateBasicBlock(); |
| 2359 VISIT_FOR_CONTROL(stmt->condition(), | 2336 VISIT_FOR_CONTROL(stmt->condition(), cond_true, cond_false); |
| 2360 then_graph->entry_block(), | 2337 cond_true->SetJoinId(stmt->ThenId()); |
| 2361 else_graph->entry_block()); | 2338 cond_false->SetJoinId(stmt->ElseId()); |
| 2362 | 2339 |
| 2363 then_graph->entry_block()->SetJoinId(stmt->ThenId()); | 2340 set_current_block(cond_true); |
| 2364 ADD_TO_SUBGRAPH(then_graph, stmt->then_statement()); | 2341 Visit(stmt->then_statement()); |
| 2342 CHECK_BAILOUT; |
| 2343 HBasicBlock* other = current_block(); |
| 2365 | 2344 |
| 2366 else_graph->entry_block()->SetJoinId(stmt->ElseId()); | 2345 set_current_block(cond_false); |
| 2367 ADD_TO_SUBGRAPH(else_graph, stmt->else_statement()); | 2346 Visit(stmt->else_statement()); |
| 2347 CHECK_BAILOUT; |
| 2368 | 2348 |
| 2369 set_current_block(CreateJoin(then_graph->exit_block(), | 2349 HBasicBlock* join = CreateJoin(other, current_block(), stmt->id()); |
| 2370 else_graph->exit_block(), | 2350 set_current_block(join); |
| 2371 stmt->id())); | |
| 2372 } | 2351 } |
| 2373 } | 2352 } |
| 2374 | 2353 |
| 2375 | 2354 |
| 2376 HBasicBlock* HGraphBuilder::BreakAndContinueScope::Get( | 2355 HBasicBlock* HGraphBuilder::BreakAndContinueScope::Get( |
| 2377 BreakableStatement* stmt, | 2356 BreakableStatement* stmt, |
| 2378 BreakType type) { | 2357 BreakType type) { |
| 2379 BreakAndContinueScope* current = this; | 2358 BreakAndContinueScope* current = this; |
| 2380 while (current != NULL && current->info()->target() != stmt) { | 2359 while (current != NULL && current->info()->target() != stmt) { |
| 2381 current = current->next(); | 2360 current = current->next(); |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2663 AddInstruction(new HOsrEntry(osr_entry_id)); | 2642 AddInstruction(new HOsrEntry(osr_entry_id)); |
| 2664 current_block()->Goto(loop_predecessor); | 2643 current_block()->Goto(loop_predecessor); |
| 2665 loop_predecessor->SetJoinId(statement->EntryId()); | 2644 loop_predecessor->SetJoinId(statement->EntryId()); |
| 2666 set_current_block(loop_predecessor); | 2645 set_current_block(loop_predecessor); |
| 2667 } | 2646 } |
| 2668 | 2647 |
| 2669 | 2648 |
| 2670 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 2649 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
| 2671 ASSERT(current_block() != NULL); | 2650 ASSERT(current_block() != NULL); |
| 2672 PreProcessOsrEntry(stmt); | 2651 PreProcessOsrEntry(stmt); |
| 2673 HBasicBlock* loop_entry = CreateLoopHeader(); | 2652 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
| 2674 current_block()->Goto(loop_entry, false); | 2653 current_block()->Goto(loop_entry, false); |
| 2675 set_current_block(loop_entry); | 2654 set_current_block(loop_entry); |
| 2676 | 2655 |
| 2677 BreakAndContinueInfo break_info(stmt); | 2656 BreakAndContinueInfo break_info(stmt); |
| 2678 { BreakAndContinueScope push(&break_info, this); | 2657 { BreakAndContinueScope push(&break_info, this); |
| 2679 Visit(stmt->body()); | 2658 Visit(stmt->body()); |
| 2680 CHECK_BAILOUT; | 2659 CHECK_BAILOUT; |
| 2681 } | 2660 } |
| 2682 HBasicBlock* body_exit = | 2661 HBasicBlock* body_exit = |
| 2683 JoinContinue(stmt, current_block(), break_info.continue_block()); | 2662 JoinContinue(stmt, current_block(), break_info.continue_block()); |
| 2684 HBasicBlock* loop_exit = NULL; | 2663 HBasicBlock* loop_successor = NULL; |
| 2685 if (body_exit == NULL || stmt->cond()->ToBooleanIsTrue()) { | 2664 if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) { |
| 2686 loop_exit = CreateEndless(stmt, | |
| 2687 loop_entry, | |
| 2688 body_exit, | |
| 2689 break_info.break_block()); | |
| 2690 } else { | |
| 2691 set_current_block(body_exit); | 2665 set_current_block(body_exit); |
| 2692 HBasicBlock* cond_true = graph()->CreateBasicBlock(); | 2666 // The block for a true condition, the actual predecessor block of the |
| 2693 HBasicBlock* cond_false = graph()->CreateBasicBlock(); | 2667 // back edge. |
| 2694 VISIT_FOR_CONTROL(stmt->cond(), cond_true, cond_false); | 2668 body_exit = graph()->CreateBasicBlock(); |
| 2695 cond_true->SetJoinId(stmt->BackEdgeId()); | 2669 loop_successor = graph()->CreateBasicBlock(); |
| 2696 cond_false->SetJoinId(stmt->ExitId()); | 2670 VISIT_FOR_CONTROL(stmt->cond(), body_exit, loop_successor); |
| 2697 loop_exit = CreateDoWhile(stmt, | 2671 body_exit->SetJoinId(stmt->BackEdgeId()); |
| 2698 loop_entry, | 2672 loop_successor->SetJoinId(stmt->ExitId()); |
| 2699 cond_true, | |
| 2700 cond_false, | |
| 2701 break_info.break_block()); | |
| 2702 } | 2673 } |
| 2674 HBasicBlock* loop_exit = CreateLoop(stmt, |
| 2675 loop_entry, |
| 2676 body_exit, |
| 2677 loop_successor, |
| 2678 break_info.break_block()); |
| 2703 set_current_block(loop_exit); | 2679 set_current_block(loop_exit); |
| 2704 } | 2680 } |
| 2705 | 2681 |
| 2706 | 2682 |
| 2707 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { | 2683 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { |
| 2708 ASSERT(current_block() != NULL); | 2684 ASSERT(current_block() != NULL); |
| 2709 PreProcessOsrEntry(stmt); | 2685 PreProcessOsrEntry(stmt); |
| 2710 HBasicBlock* loop_entry = CreateLoopHeader(); | 2686 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
| 2711 current_block()->Goto(loop_entry, false); | 2687 current_block()->Goto(loop_entry, false); |
| 2712 set_current_block(loop_entry); | 2688 set_current_block(loop_entry); |
| 2713 | 2689 |
| 2714 // If the condition is constant true, do not generate a branch. | 2690 // If the condition is constant true, do not generate a branch. |
| 2715 HBasicBlock* cond_false = NULL; | 2691 HBasicBlock* loop_successor = NULL; |
| 2716 if (!stmt->cond()->ToBooleanIsTrue()) { | 2692 if (!stmt->cond()->ToBooleanIsTrue()) { |
| 2717 HBasicBlock* cond_true = graph()->CreateBasicBlock(); | 2693 HBasicBlock* body_entry = graph()->CreateBasicBlock(); |
| 2718 cond_false = graph()->CreateBasicBlock(); | 2694 loop_successor = graph()->CreateBasicBlock(); |
| 2719 VISIT_FOR_CONTROL(stmt->cond(), cond_true, cond_false); | 2695 VISIT_FOR_CONTROL(stmt->cond(), body_entry, loop_successor); |
| 2720 cond_true->SetJoinId(stmt->BodyId()); | 2696 body_entry->SetJoinId(stmt->BodyId()); |
| 2721 cond_false->SetJoinId(stmt->ExitId()); | 2697 loop_successor->SetJoinId(stmt->ExitId()); |
| 2722 set_current_block(cond_true); | 2698 set_current_block(body_entry); |
| 2723 } | 2699 } |
| 2724 | 2700 |
| 2725 BreakAndContinueInfo break_info(stmt); | 2701 BreakAndContinueInfo break_info(stmt); |
| 2726 { BreakAndContinueScope push(&break_info, this); | 2702 { BreakAndContinueScope push(&break_info, this); |
| 2727 Visit(stmt->body()); | 2703 Visit(stmt->body()); |
| 2728 CHECK_BAILOUT; | 2704 CHECK_BAILOUT; |
| 2729 } | 2705 } |
| 2730 HBasicBlock* body_exit = | 2706 HBasicBlock* body_exit = |
| 2731 JoinContinue(stmt, current_block(), break_info.continue_block()); | 2707 JoinContinue(stmt, current_block(), break_info.continue_block()); |
| 2732 HBasicBlock* loop_exit = NULL; | 2708 HBasicBlock* loop_exit = CreateLoop(stmt, |
| 2733 if (stmt->cond()->ToBooleanIsTrue()) { | 2709 loop_entry, |
| 2734 // TODO(fschneider): Implement peeling for endless loops as well. | 2710 body_exit, |
| 2735 loop_exit = CreateEndless(stmt, | 2711 loop_successor, |
| 2736 loop_entry, | 2712 break_info.break_block()); |
| 2737 body_exit, | |
| 2738 break_info.break_block()); | |
| 2739 } else { | |
| 2740 loop_exit = CreateWhile(stmt, | |
| 2741 loop_entry, | |
| 2742 cond_false, | |
| 2743 body_exit, | |
| 2744 break_info.break_block()); | |
| 2745 } | |
| 2746 set_current_block(loop_exit); | 2713 set_current_block(loop_exit); |
| 2747 } | 2714 } |
| 2748 | 2715 |
| 2749 | 2716 |
| 2750 void HGraphBuilder::VisitForStatement(ForStatement* stmt) { | 2717 void HGraphBuilder::VisitForStatement(ForStatement* stmt) { |
| 2751 // Only visit the init statement in the peeled part of the loop. | 2718 if (stmt->init() != NULL) { |
| 2752 if (stmt->init() != NULL && peeled_statement_ != stmt) { | |
| 2753 Visit(stmt->init()); | 2719 Visit(stmt->init()); |
| 2754 CHECK_BAILOUT; | 2720 CHECK_BAILOUT; |
| 2755 } | 2721 } |
| 2756 ASSERT(current_block() != NULL); | 2722 ASSERT(current_block() != NULL); |
| 2757 PreProcessOsrEntry(stmt); | 2723 PreProcessOsrEntry(stmt); |
| 2758 HBasicBlock* loop_entry = CreateLoopHeader(); | 2724 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
| 2759 current_block()->Goto(loop_entry, false); | 2725 current_block()->Goto(loop_entry, false); |
| 2760 set_current_block(loop_entry); | 2726 set_current_block(loop_entry); |
| 2761 | 2727 |
| 2762 HBasicBlock* cond_false = NULL; | 2728 HBasicBlock* loop_successor = NULL; |
| 2763 if (stmt->cond() != NULL) { | 2729 if (stmt->cond() != NULL) { |
| 2764 HBasicBlock* cond_true = graph()->CreateBasicBlock(); | 2730 HBasicBlock* body_entry = graph()->CreateBasicBlock(); |
| 2765 cond_false = graph()->CreateBasicBlock(); | 2731 loop_successor = graph()->CreateBasicBlock(); |
| 2766 VISIT_FOR_CONTROL(stmt->cond(), cond_true, cond_false); | 2732 VISIT_FOR_CONTROL(stmt->cond(), body_entry, loop_successor); |
| 2767 cond_true->SetJoinId(stmt->BodyId()); | 2733 body_entry->SetJoinId(stmt->BodyId()); |
| 2768 cond_false->SetJoinId(stmt->ExitId()); | 2734 loop_successor->SetJoinId(stmt->ExitId()); |
| 2769 set_current_block(cond_true); | 2735 set_current_block(body_entry); |
| 2770 } | 2736 } |
| 2771 | 2737 |
| 2772 BreakAndContinueInfo break_info(stmt); | 2738 BreakAndContinueInfo break_info(stmt); |
| 2773 { BreakAndContinueScope push(&break_info, this); | 2739 { BreakAndContinueScope push(&break_info, this); |
| 2774 Visit(stmt->body()); | 2740 Visit(stmt->body()); |
| 2775 CHECK_BAILOUT; | 2741 CHECK_BAILOUT; |
| 2776 } | 2742 } |
| 2777 HBasicBlock* body_exit = | 2743 HBasicBlock* body_exit = |
| 2778 JoinContinue(stmt, current_block(), break_info.continue_block()); | 2744 JoinContinue(stmt, current_block(), break_info.continue_block()); |
| 2779 | 2745 |
| 2780 if (stmt->next() != NULL && body_exit != NULL) { | 2746 if (stmt->next() != NULL && body_exit != NULL) { |
| 2781 set_current_block(body_exit); | 2747 set_current_block(body_exit); |
| 2782 Visit(stmt->next()); | 2748 Visit(stmt->next()); |
| 2783 CHECK_BAILOUT; | 2749 CHECK_BAILOUT; |
| 2784 body_exit = current_block(); | 2750 body_exit = current_block(); |
| 2785 } | 2751 } |
| 2786 | 2752 |
| 2787 HBasicBlock* loop_exit = NULL; | 2753 HBasicBlock* loop_exit = CreateLoop(stmt, |
| 2788 if (stmt->cond() == NULL) { | 2754 loop_entry, |
| 2789 loop_exit = CreateEndless(stmt, | 2755 body_exit, |
| 2790 loop_entry, | 2756 loop_successor, |
| 2791 body_exit, | 2757 break_info.break_block()); |
| 2792 break_info.break_block()); | |
| 2793 } else { | |
| 2794 loop_exit = CreateWhile(stmt, | |
| 2795 loop_entry, | |
| 2796 cond_false, | |
| 2797 body_exit, | |
| 2798 break_info.break_block()); | |
| 2799 } | |
| 2800 set_current_block(loop_exit); | 2758 set_current_block(loop_exit); |
| 2801 } | 2759 } |
| 2802 | 2760 |
| 2803 | 2761 |
| 2804 void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) { | 2762 void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) { |
| 2805 BAILOUT("ForInStatement"); | 2763 BAILOUT("ForInStatement"); |
| 2806 } | 2764 } |
| 2807 | 2765 |
| 2808 | 2766 |
| 2809 void HGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { | 2767 void HGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2831 } | 2789 } |
| 2832 | 2790 |
| 2833 | 2791 |
| 2834 void HGraphBuilder::VisitSharedFunctionInfoLiteral( | 2792 void HGraphBuilder::VisitSharedFunctionInfoLiteral( |
| 2835 SharedFunctionInfoLiteral* expr) { | 2793 SharedFunctionInfoLiteral* expr) { |
| 2836 BAILOUT("SharedFunctionInfoLiteral"); | 2794 BAILOUT("SharedFunctionInfoLiteral"); |
| 2837 } | 2795 } |
| 2838 | 2796 |
| 2839 | 2797 |
| 2840 void HGraphBuilder::VisitConditional(Conditional* expr) { | 2798 void HGraphBuilder::VisitConditional(Conditional* expr) { |
| 2841 HSubgraph* then_graph = CreateEmptySubgraph(); | 2799 HBasicBlock* cond_true = graph()->CreateBasicBlock(); |
| 2842 HSubgraph* else_graph = CreateEmptySubgraph(); | 2800 HBasicBlock* cond_false = graph()->CreateBasicBlock(); |
| 2843 VISIT_FOR_CONTROL(expr->condition(), | 2801 VISIT_FOR_CONTROL(expr->condition(), cond_true, cond_false); |
| 2844 then_graph->entry_block(), | 2802 cond_true->SetJoinId(expr->ThenId()); |
| 2845 else_graph->entry_block()); | 2803 cond_false->SetJoinId(expr->ElseId()); |
| 2846 | 2804 |
| 2847 then_graph->entry_block()->SetJoinId(expr->ThenId()); | 2805 // TOOD(kmillikin): Visit the subexpressions in the same AST context as |
| 2848 ADD_TO_SUBGRAPH(then_graph, expr->then_expression()); | 2806 // the whole expression. |
| 2807 set_current_block(cond_true); |
| 2808 VISIT_FOR_VALUE(expr->then_expression()); |
| 2809 HBasicBlock* other = current_block(); |
| 2849 | 2810 |
| 2850 else_graph->entry_block()->SetJoinId(expr->ElseId()); | 2811 set_current_block(cond_false); |
| 2851 ADD_TO_SUBGRAPH(else_graph, expr->else_expression()); | 2812 VISIT_FOR_VALUE(expr->else_expression()); |
| 2852 | 2813 |
| 2853 set_current_block(CreateJoin(then_graph->exit_block(), | 2814 HBasicBlock* join = CreateJoin(other, current_block(), expr->id()); |
| 2854 else_graph->exit_block(), | 2815 set_current_block(join); |
| 2855 expr->id())); | |
| 2856 ast_context()->ReturnValue(Pop()); | 2816 ast_context()->ReturnValue(Pop()); |
| 2857 } | 2817 } |
| 2858 | 2818 |
| 2859 | 2819 |
| 2860 void HGraphBuilder::LookupGlobalPropertyCell(Variable* var, | 2820 void HGraphBuilder::LookupGlobalPropertyCell(Variable* var, |
| 2861 LookupResult* lookup, | 2821 LookupResult* lookup, |
| 2862 bool is_store) { | 2822 bool is_store) { |
| 2863 if (var->is_this()) { | 2823 if (var->is_this()) { |
| 2864 BAILOUT("global this reference"); | 2824 BAILOUT("global this reference"); |
| 2865 } | 2825 } |
| (...skipping 1765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4631 } else { | 4591 } else { |
| 4632 BAILOUT("delete with non-global variable"); | 4592 BAILOUT("delete with non-global variable"); |
| 4633 } | 4593 } |
| 4634 } else if (op == Token::NOT) { | 4594 } else if (op == Token::NOT) { |
| 4635 if (ast_context()->IsTest()) { | 4595 if (ast_context()->IsTest()) { |
| 4636 TestContext* context = TestContext::cast(ast_context()); | 4596 TestContext* context = TestContext::cast(ast_context()); |
| 4637 VisitForControl(expr->expression(), | 4597 VisitForControl(expr->expression(), |
| 4638 context->if_false(), | 4598 context->if_false(), |
| 4639 context->if_true()); | 4599 context->if_true()); |
| 4640 } else if (ast_context()->IsValue()) { | 4600 } else if (ast_context()->IsValue()) { |
| 4641 HSubgraph* true_graph = CreateEmptySubgraph(); | 4601 HBasicBlock* materialize_false = graph()->CreateBasicBlock(); |
| 4642 HSubgraph* false_graph = CreateEmptySubgraph(); | 4602 HBasicBlock* materialize_true = graph()->CreateBasicBlock(); |
| 4643 VISIT_FOR_CONTROL(expr->expression(), | 4603 VISIT_FOR_CONTROL(expr->expression(), |
| 4644 false_graph->entry_block(), | 4604 materialize_false, |
| 4645 true_graph->entry_block()); | 4605 materialize_true); |
| 4646 true_graph->entry_block()->SetJoinId(expr->expression()->id()); | 4606 materialize_false->SetJoinId(expr->expression()->id()); |
| 4647 true_graph->exit_block()->last_environment()->Push( | 4607 materialize_true->SetJoinId(expr->expression()->id()); |
| 4648 graph_->GetConstantTrue()); | |
| 4649 | 4608 |
| 4650 false_graph->entry_block()->SetJoinId(expr->expression()->id()); | 4609 set_current_block(materialize_false); |
| 4651 false_graph->exit_block()->last_environment()->Push( | 4610 Push(graph()->GetConstantFalse()); |
| 4652 graph_->GetConstantFalse()); | 4611 set_current_block(materialize_true); |
| 4612 Push(graph()->GetConstantTrue()); |
| 4653 | 4613 |
| 4654 set_current_block(CreateJoin(true_graph->exit_block(), | 4614 HBasicBlock* join = |
| 4655 false_graph->exit_block(), | 4615 CreateJoin(materialize_false, materialize_true, expr->id()); |
| 4656 expr->id())); | 4616 set_current_block(join); |
| 4657 ast_context()->ReturnValue(Pop()); | 4617 ast_context()->ReturnValue(Pop()); |
| 4658 } else { | 4618 } else { |
| 4659 ASSERT(ast_context()->IsEffect()); | 4619 ASSERT(ast_context()->IsEffect()); |
| 4660 VISIT_FOR_EFFECT(expr->expression()); | 4620 VisitForEffect(expr->expression()); |
| 4661 } | 4621 } |
| 4662 | 4622 |
| 4663 } else if (op == Token::BIT_NOT || op == Token::SUB) { | 4623 } else if (op == Token::BIT_NOT || op == Token::SUB) { |
| 4664 VISIT_FOR_VALUE(expr->expression()); | 4624 VISIT_FOR_VALUE(expr->expression()); |
| 4665 HValue* value = Pop(); | 4625 HValue* value = Pop(); |
| 4666 HInstruction* instr = NULL; | 4626 HInstruction* instr = NULL; |
| 4667 switch (op) { | 4627 switch (op) { |
| 4668 case Token::BIT_NOT: | 4628 case Token::BIT_NOT: |
| 4669 instr = new HBitNot(value); | 4629 instr = new HBitNot(value); |
| 4670 break; | 4630 break; |
| (...skipping 1376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6047 } | 6007 } |
| 6048 } | 6008 } |
| 6049 | 6009 |
| 6050 #ifdef DEBUG | 6010 #ifdef DEBUG |
| 6051 if (graph_ != NULL) graph_->Verify(); | 6011 if (graph_ != NULL) graph_->Verify(); |
| 6052 if (allocator_ != NULL) allocator_->Verify(); | 6012 if (allocator_ != NULL) allocator_->Verify(); |
| 6053 #endif | 6013 #endif |
| 6054 } | 6014 } |
| 6055 | 6015 |
| 6056 } } // namespace v8::internal | 6016 } } // namespace v8::internal |
| OLD | NEW |