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 |