OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |