| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 } | 430 } |
| 431 #endif | 431 #endif |
| 432 | 432 |
| 433 | 433 |
| 434 void HLoopInformation::RegisterBackEdge(HBasicBlock* block) { | 434 void HLoopInformation::RegisterBackEdge(HBasicBlock* block) { |
| 435 this->back_edges_.Add(block, block->zone()); | 435 this->back_edges_.Add(block, block->zone()); |
| 436 AddBlock(block); | 436 AddBlock(block); |
| 437 } | 437 } |
| 438 | 438 |
| 439 | 439 |
| 440 void HLoopInformation::ProcessEdge(HBasicBlock* destination) { |
| 441 HLoopInformation* target_loop = destination->current_loop(); |
| 442 if (IsNestedInThisLoop(target_loop)) return; |
| 443 |
| 444 HLoopInformation* current_loop = this; |
| 445 // TODO(mmassi) When we will support try..catch we will need to break out of |
| 446 // this loop when we meet the catch block. |
| 447 // From a correctness PoV we're safe anyway, but unnecessarily marking loops |
| 448 // as having additional exits could prevent hoisting of bounds checks. |
| 449 while (current_loop != NULL) { |
| 450 if (target_loop == current_loop) return; |
| 451 current_loop->exits_count_++; |
| 452 current_loop = current_loop->parent_loop(); |
| 453 } |
| 454 } |
| 455 |
| 456 |
| 457 void HLoopInformation::ProcessThrow() { |
| 458 HLoopInformation* current_loop = this; |
| 459 while (current_loop != NULL) { |
| 460 current_loop->exits_count_++; |
| 461 current_loop = current_loop->parent_loop(); |
| 462 } |
| 463 } |
| 464 |
| 465 |
| 440 HBasicBlock* HLoopInformation::GetLastBackEdge() const { | 466 HBasicBlock* HLoopInformation::GetLastBackEdge() const { |
| 441 int max_id = -1; | 467 int max_id = -1; |
| 442 HBasicBlock* result = NULL; | 468 HBasicBlock* result = NULL; |
| 443 for (int i = 0; i < back_edges_.length(); ++i) { | 469 for (int i = 0; i < back_edges_.length(); ++i) { |
| 444 HBasicBlock* cur = back_edges_[i]; | 470 HBasicBlock* cur = back_edges_[i]; |
| 445 if (cur->block_id() > max_id) { | 471 if (cur->block_id() > max_id) { |
| 446 max_id = cur->block_id(); | 472 max_id = cur->block_id(); |
| 447 result = cur; | 473 result = cur; |
| 448 } | 474 } |
| 449 } | 475 } |
| (...skipping 1208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1658 HGraph::HGraph(CompilationInfo* info) | 1684 HGraph::HGraph(CompilationInfo* info) |
| 1659 : isolate_(info->isolate()), | 1685 : isolate_(info->isolate()), |
| 1660 next_block_id_(0), | 1686 next_block_id_(0), |
| 1661 entry_block_(NULL), | 1687 entry_block_(NULL), |
| 1662 blocks_(8, info->zone()), | 1688 blocks_(8, info->zone()), |
| 1663 values_(16, info->zone()), | 1689 values_(16, info->zone()), |
| 1664 phi_list_(NULL), | 1690 phi_list_(NULL), |
| 1665 uint32_instructions_(NULL), | 1691 uint32_instructions_(NULL), |
| 1666 info_(info), | 1692 info_(info), |
| 1667 zone_(info->zone()), | 1693 zone_(info->zone()), |
| 1694 evaluated_relations_table_(info->zone()), |
| 1668 is_recursive_(false), | 1695 is_recursive_(false), |
| 1669 use_optimistic_licm_(false), | 1696 use_optimistic_licm_(false), |
| 1670 has_soft_deoptimize_(false), | 1697 has_soft_deoptimize_(false), |
| 1671 type_change_checksum_(0) { | 1698 type_change_checksum_(0) { |
| 1672 if (info->IsStub()) { | 1699 if (info->IsStub()) { |
| 1673 HydrogenCodeStub* stub = info->code_stub(); | 1700 HydrogenCodeStub* stub = info->code_stub(); |
| 1674 CodeStubInterfaceDescriptor* descriptor = | 1701 CodeStubInterfaceDescriptor* descriptor = |
| 1675 stub->GetInterfaceDescriptor(isolate_); | 1702 stub->GetInterfaceDescriptor(isolate_); |
| 1676 start_environment_ = | 1703 start_environment_ = |
| 1677 new(zone_) HEnvironment(zone_, descriptor->environment_length()); | 1704 new(zone_) HEnvironment(zone_, descriptor->environment_length()); |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2010 PostorderProcessor::CreateEntryProcessor(zone(), start, &visited); | 2037 PostorderProcessor::CreateEntryProcessor(zone(), start, &visited); |
| 2011 while (postorder != NULL) { | 2038 while (postorder != NULL) { |
| 2012 postorder = postorder->PerformStep(zone(), &visited, &reverse_result); | 2039 postorder = postorder->PerformStep(zone(), &visited, &reverse_result); |
| 2013 } | 2040 } |
| 2014 blocks_.Rewind(0); | 2041 blocks_.Rewind(0); |
| 2015 int index = 0; | 2042 int index = 0; |
| 2016 for (int i = reverse_result.length() - 1; i >= 0; --i) { | 2043 for (int i = reverse_result.length() - 1; i >= 0; --i) { |
| 2017 HBasicBlock* b = reverse_result[i]; | 2044 HBasicBlock* b = reverse_result[i]; |
| 2018 blocks_.Add(b, zone()); | 2045 blocks_.Add(b, zone()); |
| 2019 b->set_block_id(index++); | 2046 b->set_block_id(index++); |
| 2047 |
| 2048 HLoopInformation* loop = b->current_loop(); |
| 2049 if (loop != NULL) { |
| 2050 for (int i = 0; i < b->end()->SuccessorCount(); i++) { |
| 2051 HBasicBlock* successor = b->end()->SuccessorAt(i); |
| 2052 loop->ProcessEdge(successor); |
| 2053 } |
| 2054 |
| 2055 for (HInstruction* instruction = b->first(); |
| 2056 instruction != NULL; |
| 2057 instruction = instruction->next()) { |
| 2058 if (instruction->IsThrow()) { |
| 2059 loop->ProcessThrow(); |
| 2060 } |
| 2061 } |
| 2062 } |
| 2020 } | 2063 } |
| 2021 } | 2064 } |
| 2022 | 2065 |
| 2023 | 2066 |
| 2024 void HGraph::AssignDominators() { | 2067 void HGraph::AssignDominators() { |
| 2025 HPhase phase("H_Assign dominators", this); | 2068 HPhase phase("H_Assign dominators", this); |
| 2026 for (int i = 0; i < blocks_.length(); ++i) { | 2069 for (int i = 0; i < blocks_.length(); ++i) { |
| 2027 HBasicBlock* block = blocks_[i]; | 2070 HBasicBlock* block = blocks_[i]; |
| 2028 if (block->IsLoopHeader()) { | 2071 if (block->IsLoopHeader()) { |
| 2029 // Only the first predecessor of a loop header is from outside the loop. | 2072 // Only the first predecessor of a loop header is from outside the loop. |
| (...skipping 2374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4404 HRangeAnalysis rangeAnalysis(this); | 4447 HRangeAnalysis rangeAnalysis(this); |
| 4405 rangeAnalysis.Analyze(); | 4448 rangeAnalysis.Analyze(); |
| 4406 } | 4449 } |
| 4407 ComputeMinusZeroChecks(); | 4450 ComputeMinusZeroChecks(); |
| 4408 | 4451 |
| 4409 // Eliminate redundant stack checks on backwards branches. | 4452 // Eliminate redundant stack checks on backwards branches. |
| 4410 HStackCheckEliminator sce(this); | 4453 HStackCheckEliminator sce(this); |
| 4411 sce.Process(); | 4454 sce.Process(); |
| 4412 | 4455 |
| 4413 if (FLAG_idefs) SetupInformativeDefinitions(); | 4456 if (FLAG_idefs) SetupInformativeDefinitions(); |
| 4414 if (FLAG_array_bounds_checks_elimination && !FLAG_idefs) { | 4457 if (FLAG_array_bounds_checks_elimination) { |
| 4415 EliminateRedundantBoundsChecks(); | 4458 EliminateRedundantBoundsChecks(); |
| 4416 } | 4459 } |
| 4417 if (FLAG_array_index_dehoisting) DehoistSimpleArrayIndexComputations(); | 4460 if (FLAG_array_index_dehoisting) DehoistSimpleArrayIndexComputations(); |
| 4461 RestoreActualValues(); |
| 4418 if (FLAG_dead_code_elimination) DeadCodeElimination(); | 4462 if (FLAG_dead_code_elimination) DeadCodeElimination(); |
| 4419 | 4463 |
| 4420 RestoreActualValues(); | |
| 4421 | |
| 4422 return true; | 4464 return true; |
| 4423 } | 4465 } |
| 4424 | 4466 |
| 4425 | 4467 |
| 4426 void HGraph::SetupInformativeDefinitionsInBlock(HBasicBlock* block) { | 4468 void HGraph::SetupInformativeDefinitionsInBlock(HBasicBlock* block) { |
| 4427 for (int phi_index = 0; phi_index < block->phis()->length(); phi_index++) { | 4469 for (int phi_index = 0; phi_index < block->phis()->length(); phi_index++) { |
| 4428 HPhi* phi = block->phis()->at(phi_index); | 4470 HPhi* phi = block->phis()->at(phi_index); |
| 4429 phi->AddInformativeDefinitions(); | 4471 phi->AddInformativeDefinitions(); |
| 4430 phi->SetFlag(HValue::kIDefsProcessingDone); | 4472 phi->SetFlag(HValue::kIDefsProcessingDone); |
| 4431 // We do not support phis that "redefine just one operand". | 4473 // We do not support phis that "redefine just one operand". |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4442 | 4484 |
| 4443 // This method is recursive, so if its stack frame is large it could | 4485 // This method is recursive, so if its stack frame is large it could |
| 4444 // cause a stack overflow. | 4486 // cause a stack overflow. |
| 4445 // To keep the individual stack frames small we do the actual work inside | 4487 // To keep the individual stack frames small we do the actual work inside |
| 4446 // SetupInformativeDefinitionsInBlock(); | 4488 // SetupInformativeDefinitionsInBlock(); |
| 4447 void HGraph::SetupInformativeDefinitionsRecursively(HBasicBlock* block) { | 4489 void HGraph::SetupInformativeDefinitionsRecursively(HBasicBlock* block) { |
| 4448 SetupInformativeDefinitionsInBlock(block); | 4490 SetupInformativeDefinitionsInBlock(block); |
| 4449 for (int i = 0; i < block->dominated_blocks()->length(); ++i) { | 4491 for (int i = 0; i < block->dominated_blocks()->length(); ++i) { |
| 4450 SetupInformativeDefinitionsRecursively(block->dominated_blocks()->at(i)); | 4492 SetupInformativeDefinitionsRecursively(block->dominated_blocks()->at(i)); |
| 4451 } | 4493 } |
| 4452 | |
| 4453 for (HInstruction* i = block->first(); i != NULL; i = i->next()) { | |
| 4454 if (i->IsBoundsCheck()) { | |
| 4455 HBoundsCheck* check = HBoundsCheck::cast(i); | |
| 4456 check->ApplyIndexChange(); | |
| 4457 } | |
| 4458 } | |
| 4459 } | 4494 } |
| 4460 | 4495 |
| 4461 | 4496 |
| 4462 void HGraph::SetupInformativeDefinitions() { | 4497 void HGraph::SetupInformativeDefinitions() { |
| 4463 HPhase phase("H_Setup informative definitions", this); | 4498 HPhase phase("H_Setup informative definitions", this); |
| 4464 SetupInformativeDefinitionsRecursively(entry_block()); | 4499 SetupInformativeDefinitionsRecursively(entry_block()); |
| 4465 } | 4500 } |
| 4466 | 4501 |
| 4467 | 4502 |
| 4468 // We try to "factor up" HBoundsCheck instructions towards the root of the | 4503 // We try to "factor up" HBoundsCheck instructions towards the root of the |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4737 void Delete(BoundsCheckKey* key) { | 4772 void Delete(BoundsCheckKey* key) { |
| 4738 Remove(key, key->Hash()); | 4773 Remove(key, key->Hash()); |
| 4739 } | 4774 } |
| 4740 | 4775 |
| 4741 explicit BoundsCheckTable(Zone* zone) | 4776 explicit BoundsCheckTable(Zone* zone) |
| 4742 : ZoneHashMap(BoundsCheckKeyMatch, ZoneHashMap::kDefaultHashMapCapacity, | 4777 : ZoneHashMap(BoundsCheckKeyMatch, ZoneHashMap::kDefaultHashMapCapacity, |
| 4743 ZoneAllocationPolicy(zone)) { } | 4778 ZoneAllocationPolicy(zone)) { } |
| 4744 }; | 4779 }; |
| 4745 | 4780 |
| 4746 | 4781 |
| 4782 void HGraph::EliminateRedundantBoundsChecksUsingIdefs(HBasicBlock* bb) { |
| 4783 for (HInstruction* i = bb->first(); i != NULL; i = i->next()) { |
| 4784 if (i->IsBoundsCheck()) { |
| 4785 HBoundsCheck* check = HBoundsCheck::cast(i); |
| 4786 if (check->index()->TryGuaranteeRange(check->length(), bb)) { |
| 4787 check->set_skip_check(); |
| 4788 } |
| 4789 } |
| 4790 } |
| 4791 |
| 4792 for (int i = 0; i < bb->dominated_blocks()->length(); ++i) { |
| 4793 EliminateRedundantBoundsChecksUsingIdefs(bb->dominated_blocks()->at(i)); |
| 4794 } |
| 4795 } |
| 4796 |
| 4797 |
| 4798 void HGraph::ApplyBoundsChecksIndexChanges(HBasicBlock* bb) { |
| 4799 for (HInstruction* i = bb->first(); i != NULL; i = i->next()) { |
| 4800 if (i->IsBoundsCheck()) { |
| 4801 HBoundsCheck* check = HBoundsCheck::cast(i); |
| 4802 check->ApplyIndexChange(); |
| 4803 } |
| 4804 } |
| 4805 |
| 4806 for (int i = 0; i < bb->dominated_blocks()->length(); ++i) { |
| 4807 ApplyBoundsChecksIndexChanges(bb->dominated_blocks()->at(i)); |
| 4808 } |
| 4809 } |
| 4810 |
| 4811 |
| 4747 // Eliminates checks in bb and recursively in the dominated blocks. | 4812 // Eliminates checks in bb and recursively in the dominated blocks. |
| 4748 // Also replace the results of check instructions with the original value, if | 4813 // Also replace the results of check instructions with the original value, if |
| 4749 // the result is used. This is safe now, since we don't do code motion after | 4814 // the result is used. This is safe now, since we don't do code motion after |
| 4750 // this point. It enables better register allocation since the value produced | 4815 // this point. It enables better register allocation since the value produced |
| 4751 // by check instructions is really a copy of the original value. | 4816 // by check instructions is really a copy of the original value. |
| 4752 void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, | 4817 void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, |
| 4753 BoundsCheckTable* table) { | 4818 BoundsCheckTable* table) { |
| 4754 BoundsCheckBbData* bb_data_list = NULL; | 4819 BoundsCheckBbData* bb_data_list = NULL; |
| 4755 | 4820 |
| 4756 for (HInstruction* i = bb->first(); i != NULL; i = i->next()) { | 4821 for (HInstruction* i = bb->first(); i != NULL; i = i->next()) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4810 table->Insert(data->Key(), data->FatherInDominatorTree(), zone()); | 4875 table->Insert(data->Key(), data->FatherInDominatorTree(), zone()); |
| 4811 } else { | 4876 } else { |
| 4812 table->Delete(data->Key()); | 4877 table->Delete(data->Key()); |
| 4813 } | 4878 } |
| 4814 } | 4879 } |
| 4815 } | 4880 } |
| 4816 | 4881 |
| 4817 | 4882 |
| 4818 void HGraph::EliminateRedundantBoundsChecks() { | 4883 void HGraph::EliminateRedundantBoundsChecks() { |
| 4819 HPhase phase("H_Eliminate bounds checks", this); | 4884 HPhase phase("H_Eliminate bounds checks", this); |
| 4820 BoundsCheckTable checks_table(zone()); | 4885 if (FLAG_idefs) { |
| 4821 EliminateRedundantBoundsChecks(entry_block(), &checks_table); | 4886 EliminateRedundantBoundsChecksUsingIdefs(entry_block()); |
| 4887 ApplyBoundsChecksIndexChanges(entry_block()); |
| 4888 } else { |
| 4889 BoundsCheckTable checks_table(zone()); |
| 4890 EliminateRedundantBoundsChecks(entry_block(), &checks_table); |
| 4891 } |
| 4822 } | 4892 } |
| 4823 | 4893 |
| 4824 | 4894 |
| 4825 static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) { | 4895 static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) { |
| 4826 HValue* index = array_operation->GetKey()->ActualValue(); | 4896 HValue* index = array_operation->GetKey()->ActualValue(); |
| 4827 if (!index->representation().IsInteger32()) return; | 4897 if (!index->representation().IsInteger32()) return; |
| 4828 | 4898 |
| 4829 HConstant* constant; | 4899 HConstant* constant; |
| 4830 HValue* subexpression; | 4900 HValue* subexpression; |
| 4831 int32_t sign; | 4901 int32_t sign; |
| (...skipping 6834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11666 } | 11736 } |
| 11667 } | 11737 } |
| 11668 | 11738 |
| 11669 #ifdef DEBUG | 11739 #ifdef DEBUG |
| 11670 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11740 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 11671 if (allocator_ != NULL) allocator_->Verify(); | 11741 if (allocator_ != NULL) allocator_->Verify(); |
| 11672 #endif | 11742 #endif |
| 11673 } | 11743 } |
| 11674 | 11744 |
| 11675 } } // namespace v8::internal | 11745 } } // namespace v8::internal |
| OLD | NEW |