| 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 |