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

Side by Side Diff: src/hydrogen.cc

Issue 6604002: Remove some more uses of subgraphs and more cleanup of the graph builder. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge/build/ia32
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698