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

Side by Side Diff: src/hydrogen.cc

Issue 295543002: Perform block ordering in-place. (Closed) Base URL: git@github.com:v8/v8.git@master
Patch Set: Created 6 years, 7 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
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "hydrogen.h" 5 #include "hydrogen.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "v8.h" 9 #include "v8.h"
10 #include "allocation-site-scopes.h" 10 #include "allocation-site-scopes.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 last_environment_(NULL), 72 last_environment_(NULL),
73 argument_count_(-1), 73 argument_count_(-1),
74 first_instruction_index_(-1), 74 first_instruction_index_(-1),
75 last_instruction_index_(-1), 75 last_instruction_index_(-1),
76 deleted_phis_(4, graph->zone()), 76 deleted_phis_(4, graph->zone()),
77 parent_loop_header_(NULL), 77 parent_loop_header_(NULL),
78 inlined_entry_block_(NULL), 78 inlined_entry_block_(NULL),
79 is_inline_return_target_(false), 79 is_inline_return_target_(false),
80 is_reachable_(true), 80 is_reachable_(true),
81 dominates_loop_successors_(false), 81 dominates_loop_successors_(false),
82 is_osr_entry_(false) { } 82 is_osr_entry_(false),
83 is_ordered_(false) { }
83 84
84 85
85 Isolate* HBasicBlock::isolate() const { 86 Isolate* HBasicBlock::isolate() const {
86 return graph_->isolate(); 87 return graph_->isolate();
87 } 88 }
88 89
89 90
90 void HBasicBlock::MarkUnreachable() { 91 void HBasicBlock::MarkUnreachable() {
91 is_reachable_ = false; 92 is_reachable_ = false;
92 } 93 }
(...skipping 3230 matching lines...) Expand 10 before | Expand all | Expand 10 after
3323 public: 3324 public:
3324 // Back link (towards the stack bottom). 3325 // Back link (towards the stack bottom).
3325 PostorderProcessor* parent() {return father_; } 3326 PostorderProcessor* parent() {return father_; }
3326 // Forward link (towards the stack top). 3327 // Forward link (towards the stack top).
3327 PostorderProcessor* child() {return child_; } 3328 PostorderProcessor* child() {return child_; }
3328 HBasicBlock* block() { return block_; } 3329 HBasicBlock* block() { return block_; }
3329 HLoopInformation* loop() { return loop_; } 3330 HLoopInformation* loop() { return loop_; }
3330 HBasicBlock* loop_header() { return loop_header_; } 3331 HBasicBlock* loop_header() { return loop_header_; }
3331 3332
3332 static PostorderProcessor* CreateEntryProcessor(Zone* zone, 3333 static PostorderProcessor* CreateEntryProcessor(Zone* zone,
3333 HBasicBlock* block, 3334 HBasicBlock* block) {
3334 BitVector* visited) {
3335 PostorderProcessor* result = new(zone) PostorderProcessor(NULL); 3335 PostorderProcessor* result = new(zone) PostorderProcessor(NULL);
3336 return result->SetupSuccessors(zone, block, NULL, visited); 3336 return result->SetupSuccessors(zone, block, NULL);
3337 } 3337 }
3338 3338
3339 PostorderProcessor* PerformStep(Zone* zone, 3339 PostorderProcessor* PerformStep(Zone* zone,
3340 BitVector* visited,
3341 ZoneList<HBasicBlock*>* order) { 3340 ZoneList<HBasicBlock*>* order) {
3342 PostorderProcessor* next = 3341 PostorderProcessor* next =
3343 PerformNonBacktrackingStep(zone, visited, order); 3342 PerformNonBacktrackingStep(zone, order);
3344 if (next != NULL) { 3343 if (next != NULL) {
3345 return next; 3344 return next;
3346 } else { 3345 } else {
3347 return Backtrack(zone, visited, order); 3346 return Backtrack(zone, order);
3348 } 3347 }
3349 } 3348 }
3350 3349
3351 private: 3350 private:
3352 explicit PostorderProcessor(PostorderProcessor* father) 3351 explicit PostorderProcessor(PostorderProcessor* father)
3353 : father_(father), child_(NULL), successor_iterator(NULL) { } 3352 : father_(father), child_(NULL), successor_iterator(NULL) { }
3354 3353
3355 // Each enum value states the cycle whose state is kept by this instance. 3354 // Each enum value states the cycle whose state is kept by this instance.
3356 enum LoopKind { 3355 enum LoopKind {
3357 NONE, 3356 NONE,
3358 SUCCESSORS, 3357 SUCCESSORS,
3359 SUCCESSORS_OF_LOOP_HEADER, 3358 SUCCESSORS_OF_LOOP_HEADER,
3360 LOOP_MEMBERS, 3359 LOOP_MEMBERS,
3361 SUCCESSORS_OF_LOOP_MEMBER 3360 SUCCESSORS_OF_LOOP_MEMBER
3362 }; 3361 };
3363 3362
3364 // Each "Setup..." method is like a constructor for a cycle state. 3363 // Each "Setup..." method is like a constructor for a cycle state.
3365 PostorderProcessor* SetupSuccessors(Zone* zone, 3364 PostorderProcessor* SetupSuccessors(Zone* zone,
3366 HBasicBlock* block, 3365 HBasicBlock* block,
3367 HBasicBlock* loop_header, 3366 HBasicBlock* loop_header) {
3368 BitVector* visited) { 3367 if (block == NULL || block->IsOrdered() ||
3369 if (block == NULL || visited->Contains(block->block_id()) ||
3370 block->parent_loop_header() != loop_header) { 3368 block->parent_loop_header() != loop_header) {
3371 kind_ = NONE; 3369 kind_ = NONE;
3372 block_ = NULL; 3370 block_ = NULL;
3373 loop_ = NULL; 3371 loop_ = NULL;
3374 loop_header_ = NULL; 3372 loop_header_ = NULL;
3375 return this; 3373 return this;
3376 } else { 3374 } else {
3377 block_ = block; 3375 block_ = block;
3378 loop_ = NULL; 3376 loop_ = NULL;
3379 visited->Add(block->block_id()); 3377 block->MarkAsOrdered();
3380 3378
3381 if (block->IsLoopHeader()) { 3379 if (block->IsLoopHeader()) {
3382 kind_ = SUCCESSORS_OF_LOOP_HEADER; 3380 kind_ = SUCCESSORS_OF_LOOP_HEADER;
3383 loop_header_ = block; 3381 loop_header_ = block;
3384 InitializeSuccessors(); 3382 InitializeSuccessors();
3385 PostorderProcessor* result = Push(zone); 3383 PostorderProcessor* result = Push(zone);
3386 return result->SetupLoopMembers(zone, block, block->loop_information(), 3384 return result->SetupLoopMembers(zone, block, block->loop_information(),
3387 loop_header); 3385 loop_header);
3388 } else { 3386 } else {
3389 ASSERT(block->IsFinished()); 3387 ASSERT(block->IsFinished());
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
3432 order->Contains(block_->end()->FirstSuccessor()) || 3430 order->Contains(block_->end()->FirstSuccessor()) ||
3433 block_->end()->FirstSuccessor()->IsLoopHeader()); 3431 block_->end()->FirstSuccessor()->IsLoopHeader());
3434 ASSERT(block_->end()->SecondSuccessor() == NULL || 3432 ASSERT(block_->end()->SecondSuccessor() == NULL ||
3435 order->Contains(block_->end()->SecondSuccessor()) || 3433 order->Contains(block_->end()->SecondSuccessor()) ||
3436 block_->end()->SecondSuccessor()->IsLoopHeader()); 3434 block_->end()->SecondSuccessor()->IsLoopHeader());
3437 order->Add(block_, zone); 3435 order->Add(block_, zone);
3438 } 3436 }
3439 3437
3440 // This method is the basic block to walk up the stack. 3438 // This method is the basic block to walk up the stack.
3441 PostorderProcessor* Pop(Zone* zone, 3439 PostorderProcessor* Pop(Zone* zone,
3442 BitVector* visited,
3443 ZoneList<HBasicBlock*>* order) { 3440 ZoneList<HBasicBlock*>* order) {
3444 switch (kind_) { 3441 switch (kind_) {
3445 case SUCCESSORS: 3442 case SUCCESSORS:
3446 case SUCCESSORS_OF_LOOP_HEADER: 3443 case SUCCESSORS_OF_LOOP_HEADER:
3447 ClosePostorder(order, zone); 3444 ClosePostorder(order, zone);
3448 return father_; 3445 return father_;
3449 case LOOP_MEMBERS: 3446 case LOOP_MEMBERS:
3450 return father_; 3447 return father_;
3451 case SUCCESSORS_OF_LOOP_MEMBER: 3448 case SUCCESSORS_OF_LOOP_MEMBER:
3452 if (block()->IsLoopHeader() && block() != loop_->loop_header()) { 3449 if (block()->IsLoopHeader() && block() != loop_->loop_header()) {
3453 // In this case we need to perform a LOOP_MEMBERS cycle so we 3450 // In this case we need to perform a LOOP_MEMBERS cycle so we
3454 // initialize it and return this instead of father. 3451 // initialize it and return this instead of father.
3455 return SetupLoopMembers(zone, block(), 3452 return SetupLoopMembers(zone, block(),
3456 block()->loop_information(), loop_header_); 3453 block()->loop_information(), loop_header_);
3457 } else { 3454 } else {
3458 return father_; 3455 return father_;
3459 } 3456 }
3460 case NONE: 3457 case NONE:
3461 return father_; 3458 return father_;
3462 } 3459 }
3463 UNREACHABLE(); 3460 UNREACHABLE();
3464 return NULL; 3461 return NULL;
3465 } 3462 }
3466 3463
3467 // Walks up the stack. 3464 // Walks up the stack.
3468 PostorderProcessor* Backtrack(Zone* zone, 3465 PostorderProcessor* Backtrack(Zone* zone,
3469 BitVector* visited,
3470 ZoneList<HBasicBlock*>* order) { 3466 ZoneList<HBasicBlock*>* order) {
3471 PostorderProcessor* parent = Pop(zone, visited, order); 3467 PostorderProcessor* parent = Pop(zone, order);
3472 while (parent != NULL) { 3468 while (parent != NULL) {
3473 PostorderProcessor* next = 3469 PostorderProcessor* next =
3474 parent->PerformNonBacktrackingStep(zone, visited, order); 3470 parent->PerformNonBacktrackingStep(zone, order);
3475 if (next != NULL) { 3471 if (next != NULL) {
3476 return next; 3472 return next;
3477 } else { 3473 } else {
3478 parent = parent->Pop(zone, visited, order); 3474 parent = parent->Pop(zone, order);
3479 } 3475 }
3480 } 3476 }
3481 return NULL; 3477 return NULL;
3482 } 3478 }
3483 3479
3484 PostorderProcessor* PerformNonBacktrackingStep( 3480 PostorderProcessor* PerformNonBacktrackingStep(
3485 Zone* zone, 3481 Zone* zone,
3486 BitVector* visited,
3487 ZoneList<HBasicBlock*>* order) { 3482 ZoneList<HBasicBlock*>* order) {
3488 HBasicBlock* next_block; 3483 HBasicBlock* next_block;
3489 switch (kind_) { 3484 switch (kind_) {
3490 case SUCCESSORS: 3485 case SUCCESSORS:
3491 next_block = AdvanceSuccessors(); 3486 next_block = AdvanceSuccessors();
3492 if (next_block != NULL) { 3487 if (next_block != NULL) {
3493 PostorderProcessor* result = Push(zone); 3488 PostorderProcessor* result = Push(zone);
3494 return result->SetupSuccessors(zone, next_block, 3489 return result->SetupSuccessors(zone, next_block, loop_header_);
3495 loop_header_, visited);
3496 } 3490 }
3497 break; 3491 break;
3498 case SUCCESSORS_OF_LOOP_HEADER: 3492 case SUCCESSORS_OF_LOOP_HEADER:
3499 next_block = AdvanceSuccessors(); 3493 next_block = AdvanceSuccessors();
3500 if (next_block != NULL) { 3494 if (next_block != NULL) {
3501 PostorderProcessor* result = Push(zone); 3495 PostorderProcessor* result = Push(zone);
3502 return result->SetupSuccessors(zone, next_block, 3496 return result->SetupSuccessors(zone, next_block, block());
3503 block(), visited);
3504 } 3497 }
3505 break; 3498 break;
3506 case LOOP_MEMBERS: 3499 case LOOP_MEMBERS:
3507 next_block = AdvanceLoopMembers(); 3500 next_block = AdvanceLoopMembers();
3508 if (next_block != NULL) { 3501 if (next_block != NULL) {
3509 PostorderProcessor* result = Push(zone); 3502 PostorderProcessor* result = Push(zone);
3510 return result->SetupSuccessorsOfLoopMember(next_block, 3503 return result->SetupSuccessorsOfLoopMember(next_block,
3511 loop_, loop_header_); 3504 loop_, loop_header_);
3512 } 3505 }
3513 break; 3506 break;
3514 case SUCCESSORS_OF_LOOP_MEMBER: 3507 case SUCCESSORS_OF_LOOP_MEMBER:
3515 next_block = AdvanceSuccessors(); 3508 next_block = AdvanceSuccessors();
3516 if (next_block != NULL) { 3509 if (next_block != NULL) {
3517 PostorderProcessor* result = Push(zone); 3510 PostorderProcessor* result = Push(zone);
3518 return result->SetupSuccessors(zone, next_block, 3511 return result->SetupSuccessors(zone, next_block, loop_header_);
3519 loop_header_, visited);
3520 } 3512 }
3521 break; 3513 break;
3522 case NONE: 3514 case NONE:
3523 return NULL; 3515 return NULL;
3524 } 3516 }
3525 return NULL; 3517 return NULL;
3526 } 3518 }
3527 3519
3528 // The following two methods implement a "foreach b in successors" cycle. 3520 // The following two methods implement a "foreach b in successors" cycle.
3529 void InitializeSuccessors() { 3521 void InitializeSuccessors() {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3564 HBasicBlock* block_; 3556 HBasicBlock* block_;
3565 HBasicBlock* loop_header_; 3557 HBasicBlock* loop_header_;
3566 int loop_index; 3558 int loop_index;
3567 int loop_length; 3559 int loop_length;
3568 HSuccessorIterator successor_iterator; 3560 HSuccessorIterator successor_iterator;
3569 }; 3561 };
3570 3562
3571 3563
3572 void HGraph::OrderBlocks() { 3564 void HGraph::OrderBlocks() {
3573 CompilationPhase phase("H_Block ordering", info()); 3565 CompilationPhase phase("H_Block ordering", info());
3574 BitVector visited(blocks_.length(), zone());
3575 3566
3576 ZoneList<HBasicBlock*> reverse_result(8, zone()); 3567 #ifdef DEBUG
3577 HBasicBlock* start = blocks_[0]; 3568 // Initially the blocks must not be ordered.
3569 for (int i = 0; i < blocks_.length(); ++i) {
3570 ASSERT(!blocks_[i]->IsOrdered());
3571 }
3572 #endif
3573
3578 PostorderProcessor* postorder = 3574 PostorderProcessor* postorder =
3579 PostorderProcessor::CreateEntryProcessor(zone(), start, &visited); 3575 PostorderProcessor::CreateEntryProcessor(zone(), blocks_[0]);
3580 while (postorder != NULL) { 3576 blocks_.Rewind(0);
3581 postorder = postorder->PerformStep(zone(), &visited, &reverse_result); 3577 while (postorder) {
3578 postorder = postorder->PerformStep(zone(), &blocks_);
3582 } 3579 }
3583 blocks_.Rewind(0); 3580
3584 int index = 0; 3581 #ifdef DEBUG
3585 for (int i = reverse_result.length() - 1; i >= 0; --i) { 3582 // Now all blocks must be marked as ordered.
3586 HBasicBlock* b = reverse_result[i]; 3583 for (int i = 0; i < blocks_.length(); ++i) {
3587 blocks_.Add(b, zone()); 3584 ASSERT(blocks_[i]->IsOrdered());
3588 b->set_block_id(index++); 3585 }
3586 #endif
3587
3588 // Reverse block list and assign block IDs.
3589 for (int i = 0, j = blocks_.length(); --j >= i; ++i) {
3590 HBasicBlock* bi = blocks_[i];
3591 HBasicBlock* bj = blocks_[j];
3592 bi->set_block_id(j);
3593 bj->set_block_id(i);
3594 blocks_[i] = bj;
3595 blocks_[j] = bi;
3589 } 3596 }
3590 } 3597 }
3591 3598
3592 3599
3593 void HGraph::AssignDominators() { 3600 void HGraph::AssignDominators() {
3594 HPhase phase("H_Assign dominators", this); 3601 HPhase phase("H_Assign dominators", this);
3595 for (int i = 0; i < blocks_.length(); ++i) { 3602 for (int i = 0; i < blocks_.length(); ++i) {
3596 HBasicBlock* block = blocks_[i]; 3603 HBasicBlock* block = blocks_[i];
3597 if (block->IsLoopHeader()) { 3604 if (block->IsLoopHeader()) {
3598 // Only the first predecessor of a loop header is from outside the loop. 3605 // Only the first predecessor of a loop header is from outside the loop.
(...skipping 8205 matching lines...) Expand 10 before | Expand all | Expand 10 after
11804 if (ShouldProduceTraceOutput()) { 11811 if (ShouldProduceTraceOutput()) {
11805 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11812 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11806 } 11813 }
11807 11814
11808 #ifdef DEBUG 11815 #ifdef DEBUG
11809 graph_->Verify(false); // No full verify. 11816 graph_->Verify(false); // No full verify.
11810 #endif 11817 #endif
11811 } 11818 }
11812 11819
11813 } } // namespace v8::internal 11820 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698